mindoc/static/highlight/languages/less.js

146 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
Language: Less
Author: Max Mikhailov <seven.phases.max@gmail.com>
Category: css
*/
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 (its 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 VALUEs '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...
// (well 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 its 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
};
}