refractor
Version:
Lightweight, robust, elegant virtual syntax highlighting using Prism
105 lines (103 loc) • 3.24 kB
JavaScript
module.exports = stylus;
stylus.displayName = 'stylus';
stylus.aliases = [];
function stylus(Prism) {
(function(Prism) {
var inside = {
url: /url\((["']?).*?\1\)/i,
string: {
pattern: /("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,
greedy: true
},
interpolation: null, // See below
func: null, // See below
important: /\B!(?:important|optional)\b/i,
keyword: {
pattern: /(^|\s+)(?:(?:if|else|for|return|unless)(?=\s+|$)|@[\w-]+)/,
lookbehind: true
},
hexcode: /#[\da-f]{3,6}/i,
number: /\b\d+(?:\.\d+)?%?/,
boolean: /\b(?:true|false)\b/,
operator: [
// We want non-word chars around "-" because it is
// accepted in property names.
/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.+|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/
],
punctuation: /[{}()\[\];:,]/
};
inside['interpolation'] = {
pattern: /\{[^\r\n}:]+\}/,
alias: 'variable',
inside: Prism.util.clone(inside)
};
inside['func'] = {
pattern: /[\w-]+\([^)]*\).*/,
inside: {
function: /^[^(]+/,
rest: Prism.util.clone(inside)
}
};
Prism.languages.stylus = {
comment: {
pattern: /(^|[^\\])(\/\*[\s\S]*?\*\/|\/\/.*)/,
lookbehind: true
},
'atrule-declaration': {
pattern: /(^\s*)@.+/m,
lookbehind: true,
inside: {
atrule: /^@[\w-]+/,
rest: inside
}
},
'variable-declaration': {
pattern: /(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:(?:\{[^}]*\}|.+)|$)/m,
lookbehind: true,
inside: {
variable: /^\S+/,
rest: inside
}
},
statement: {
pattern: /(^[ \t]*)(?:if|else|for|return|unless)[ \t]+.+/m,
lookbehind: true,
inside: {
keyword: /^\S+/,
rest: inside
}
},
// A property/value pair cannot end with a comma or a brace
// It cannot have indented content unless it ended with a semicolon
'property-declaration': {
pattern: /((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)[^{\r\n]*(?:;|[^{\r\n,](?=$)(?!(\r?\n|\r)(?:\{|\2[ \t]+)))/m,
lookbehind: true,
inside: {
property: {
pattern: /^[^\s:]+/,
inside: {
interpolation: inside.interpolation
}
},
rest: inside
}
},
// A selector can contain parentheses only as part of a pseudo-element
// It can span multiple lines.
// It must end with a comma or an accolade or have indented content.
selector: {
pattern: /(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\))?|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\))?|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t]+)))/m,
lookbehind: true,
inside: {
interpolation: inside.interpolation,
punctuation: /[{},]/
}
},
func: inside.func,
string: inside.string,
interpolation: inside.interpolation,
punctuation: /[{}()\[\];:.]/
};
})(Prism);
}
;