aboutsummaryrefslogtreecommitdiff
path: root/node_modules/highlight.js/lib/languages/less.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/highlight.js/lib/languages/less.js')
-rw-r--r--node_modules/highlight.js/lib/languages/less.js139
1 files changed, 139 insertions, 0 deletions
diff --git a/node_modules/highlight.js/lib/languages/less.js b/node_modules/highlight.js/lib/languages/less.js
new file mode 100644
index 000000000..29d77471d
--- /dev/null
+++ b/node_modules/highlight.js/lib/languages/less.js
@@ -0,0 +1,139 @@
+module.exports = function(hljs) {
+ var IDENT_RE = '[\\w-]+'; // yes, Less identifiers may begin with a digit
+ var INTERP_IDENT_RE = '(' + IDENT_RE + '|@{' + IDENT_RE + '})';
+
+ /* Generic Modes */
+
+ var RULES = [], VALUE = []; // forward def. for recursive modes
+
+ var STRING_MODE = function(c) { return {
+ // Less strings are not multiline (also include '~' for more consistent coloring of "escaped" strings)
+ className: 'string', begin: '~?' + c + '.*?' + c
+ };};
+
+ var IDENT_MODE = function(name, begin, relevance) { return {
+ className: name, begin: begin, relevance: relevance
+ };};
+
+ var PARENS_MODE = {
+ // used only to properly balance nested parens inside mixin call, def. arg list
+ begin: '\\(', end: '\\)', contains: VALUE, relevance: 0
+ };
+
+ // generic Less highlighter (used almost everywhere except selectors):
+ VALUE.push(
+ hljs.C_LINE_COMMENT_MODE,
+ hljs.C_BLOCK_COMMENT_MODE,
+ STRING_MODE("'"),
+ STRING_MODE('"'),
+ hljs.CSS_NUMBER_MODE, // fixme: it does not include dot for numbers like .5em :(
+ {
+ begin: '(url|data-uri)\\(',
+ starts: {className: 'string', end: '[\\)\\n]', excludeEnd: true}
+ },
+ IDENT_MODE('number', '#[0-9A-Fa-f]+\\b'),
+ PARENS_MODE,
+ IDENT_MODE('variable', '@@?' + IDENT_RE, 10),
+ IDENT_MODE('variable', '@{' + IDENT_RE + '}'),
+ IDENT_MODE('built_in', '~?`[^`]*?`'), // inline javascript (or whatever host language) *multiline* string
+ { // @media features (it’s here to not duplicate things in AT_RULE_MODE with extra PARENS_MODE overriding):
+ className: 'attribute', begin: IDENT_RE + '\\s*:', end: ':', returnBegin: true, excludeEnd: true
+ },
+ {
+ className: 'meta',
+ begin: '!important'
+ }
+ );
+
+ var VALUE_WITH_RULESETS = VALUE.concat({
+ begin: '{', end: '}', contains: RULES
+ });
+
+ var MIXIN_GUARD_MODE = {
+ beginKeywords: 'when', endsWithParent: true,
+ contains: [{beginKeywords: 'and not'}].concat(VALUE) // using this form to override VALUE’s 'function' match
+ };
+
+ /* Rule-Level Modes */
+
+ var RULE_MODE = {
+ begin: INTERP_IDENT_RE + '\\s*:', returnBegin: true, end: '[;}]',
+ relevance: 0,
+ contains: [
+ {
+ className: 'attribute',
+ begin: INTERP_IDENT_RE, end: ':', excludeEnd: true,
+ starts: {
+ endsWithParent: true, illegal: '[<=$]',
+ relevance: 0,
+ contains: VALUE
+ }
+ }
+ ]
+ };
+
+ var AT_RULE_MODE = {
+ className: 'keyword',
+ begin: '@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b',
+ starts: {end: '[;{}]', returnEnd: true, contains: VALUE, relevance: 0}
+ };
+
+ // variable definitions and calls
+ var VAR_RULE_MODE = {
+ className: 'variable',
+ variants: [
+ // using more strict pattern for higher relevance to increase chances of Less detection.
+ // this is *the only* Less specific statement used in most of the sources, so...
+ // (we’ll still often loose to the css-parser unless there's '//' comment,
+ // simply because 1 variable just can't beat 99 properties :)
+ {begin: '@' + IDENT_RE + '\\s*:', relevance: 15},
+ {begin: '@' + IDENT_RE}
+ ],
+ starts: {end: '[;}]', returnEnd: true, contains: VALUE_WITH_RULESETS}
+ };
+
+ var SELECTOR_MODE = {
+ // first parse unambiguous selectors (i.e. those not starting with tag)
+ // then fall into the scary lookahead-discriminator variant.
+ // this mode also handles mixin definitions and calls
+ variants: [{
+ begin: '[\\.#:&\\[>]', end: '[;{}]' // mixin calls end with ';'
+ }, {
+ begin: INTERP_IDENT_RE, end: '{'
+ }],
+ returnBegin: true,
+ returnEnd: true,
+ illegal: '[<=\'$"]',
+ relevance: 0,
+ contains: [
+ hljs.C_LINE_COMMENT_MODE,
+ hljs.C_BLOCK_COMMENT_MODE,
+ MIXIN_GUARD_MODE,
+ IDENT_MODE('keyword', 'all\\b'),
+ IDENT_MODE('variable', '@{' + IDENT_RE + '}'), // otherwise it’s identified as tag
+ IDENT_MODE('selector-tag', INTERP_IDENT_RE + '%?', 0), // '%' for more consistent coloring of @keyframes "tags"
+ IDENT_MODE('selector-id', '#' + INTERP_IDENT_RE),
+ IDENT_MODE('selector-class', '\\.' + INTERP_IDENT_RE, 0),
+ IDENT_MODE('selector-tag', '&', 0),
+ {className: 'selector-attr', begin: '\\[', end: '\\]'},
+ {className: 'selector-pseudo', begin: /:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},
+ {begin: '\\(', end: '\\)', contains: VALUE_WITH_RULESETS}, // argument list of parametric mixins
+ {begin: '!important'} // eat !important after mixin call or it will be colored as tag
+ ]
+ };
+
+ RULES.push(
+ hljs.C_LINE_COMMENT_MODE,
+ hljs.C_BLOCK_COMMENT_MODE,
+ AT_RULE_MODE,
+ VAR_RULE_MODE,
+ RULE_MODE,
+ SELECTOR_MODE
+ );
+
+ return {
+ case_insensitive: true,
+ illegal: '[=>\'/<($"]',
+ contains: RULES
+ };
+}; \ No newline at end of file