From 77297288da8ced0eea15d940a4e9b630108d82c0 Mon Sep 17 00:00:00 2001 From: Golmote Date: Wed, 2 Sep 2015 00:47:09 +0200 Subject: [PATCH] Stylus: Rewrote the component entirely --- components/prism-stylus.js | 153 +++++++++++------- components/prism-stylus.min.js | 2 +- examples/prism-stylus.html | 10 +- .../stylus+jade/stylus_inclusion.test | 10 +- 4 files changed, 107 insertions(+), 68 deletions(-) diff --git a/components/prism-stylus.js b/components/prism-stylus.js index fd04d786cd..c80a0e48e3 100644 --- a/components/prism-stylus.js +++ b/components/prism-stylus.js @@ -1,61 +1,102 @@ -Prism.languages.stylus = { - 'comment': { - pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g, - lookbehind: true - }, - 'keyword': /(px|r?em|ex|ch|vw|vh|vmin|vmax|deg|grad|rad|turn|m?s|k?Hz|dpi|dppx|dpcm)\b|\b(is|defined|not|isnt|and|or|unless|for|in)\b/g, - 'atrule': /@[\w-]+(?=\s+\S+)/gi, - 'url': /url\((["']?).*?\1\)/gi, - 'variable': /^\s*([\w-]+)(?=\s*[+-\\]?=)/gm, - 'string': /("|')(\\\n|\\?.)*?\1/g, - 'important': /\B!important\b/gi, - 'hexcode': /#[\da-f]{3,6}/gi, - 'entity': /\\[\da-f]{1,8}/gi, - 'number': /\d+\.?\d*%?/g, - 'selector': [ - { - pattern: /::?(after|before|first-letter|first-line|selection)/g, - alias: 'pseudo-element' - },{ - pattern: /:(?:active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|in-range|invalid|lang|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-of-type|only-child|optional|out-of-range|read-only|read-write|required|root|target|valid|visited)(?:\(.*\))?/g, - alias:'pseudo-class' - },{ - pattern: /\[[\w-]+?\s*[*~$^|=]?(?:=\s*\S+)?\]/g, +(function (Prism) { + var inside = { + 'url': /url\((["']?).*?\1\)/i, + 'string': /("|')(?:[^\\\r\n]|\\(?:\r\n|[\s\S]))*?\1/, + '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: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*)/, + lookbehind: true + }, + 'atrule-declaration': { + pattern: /(^\s*)@.+/m, + lookbehind: true, inside: { - "attr-name": - { - pattern: /(\[)([\w-]+)(?=\s*[*~$^|=]{0,2})/g, - lookbehind: true - }, - "punctuation": /\[|\]/g, - "operator": /[*~$^|=]/g, - "attr-value": { - pattern: /\S+/ - }, - }, - alias: 'attr' + 'atrule': /^@[\w-]+/, + rest: inside + } }, - { - pattern: /\.[a-z-]+/i, - alias: 'class' + 'variable-declaration': { + pattern: /(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:(?:\{[^}]*\}|.+)|$)/m, + lookbehind: true, + inside: { + 'variable': /^\S+/, + rest: inside + } }, - { - pattern: /#[a-z-]+/i, - alias: 'id' + + 'statement': { + pattern: /(^[ \t]*)(?:if|else|for|return|unless)[ \t]+.+/m, + lookbehind: true, + inside: { + keyword: /^\S+/, + rest: inside + } }, - { - pattern: /\b(html|head|title|base|link|meta|style|script|noscript|template|body|section|nav|article|aside|h[1-6]|header|footer|address|main|p|hr|pre|blockquote|ol|ul|li|dl|dt|dd|figure|figcaption|div|a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|dbo|span|br|wbr|ins|del|image|iframe|embed|object|param|video|audio|source|track|canvas|map|area|sv|math|table|caption|colgroup|col|tbody|thead|tfoot|tr|td|th|form|fieldset|legeng|label|input|button|select|datalist|optgroup|option|textarea|keygen|output|progress|meter|details|summary|menuitem|menu)\b/g, - alias: 'tag' + + // 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 + } }, - ], - 'property': [ - /^\s*([a-z-]+)(?=\s+[\w\W]+|\s*:)(?!\s*\{|\r?\n)/mig, - { - pattern: /(\(\s*)([a-z-]+)(?=\s*:)/ig, - lookbehind: true - } - ], - 'function': /[-a-z0-9]+(?=\()/ig, - 'punctuation': /[\{\};:]/g, - 'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/g -} + + + + // 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)); \ No newline at end of file diff --git a/components/prism-stylus.min.js b/components/prism-stylus.min.js index ed5c27ace8..e9088e2cbb 100644 --- a/components/prism-stylus.min.js +++ b/components/prism-stylus.min.js @@ -1 +1 @@ -Prism.languages.stylus={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g,lookbehind:!0},keyword:/(px|r?em|ex|ch|vw|vh|vmin|vmax|deg|grad|rad|turn|m?s|k?Hz|dpi|dppx|dpcm)\b|\b(is|defined|not|isnt|and|or|unless|for|in)\b/g,atrule:/@[\w-]+(?=\s+\S+)/gi,url:/url\((["']?).*?\1\)/gi,variable:/^\s*([\w-]+)(?=\s*[+-\\]?=)/gm,string:/("|')(\\\n|\\?.)*?\1/g,important:/\B!important\b/gi,hexcode:/#[\da-f]{3,6}/gi,entity:/\\[\da-f]{1,8}/gi,number:/\d+\.?\d*%?/g,selector:[{pattern:/::?(after|before|first-letter|first-line|selection)/g,alias:"pseudo-element"},{pattern:/:(?:active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|in-range|invalid|lang|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-of-type|only-child|optional|out-of-range|read-only|read-write|required|root|target|valid|visited)(?:\(.*\))?/g,alias:"pseudo-class"},{pattern:/\[[\w-]+?\s*[*~$^|=]?(?:=\s*\S+)?\]/g,inside:{"attr-name":{pattern:/(\[)([\w-]+)(?=\s*[*~$^|=]{0,2})/g,lookbehind:!0},punctuation:/\[|\]/g,operator:/[*~$^|=]/g,"attr-value":{pattern:/\S+/}},alias:"attr"},{pattern:/\.[a-z-]+/i,alias:"class"},{pattern:/#[a-z-]+/i,alias:"id"},{pattern:/\b(html|head|title|base|link|meta|style|script|noscript|template|body|section|nav|article|aside|h[1-6]|header|footer|address|main|p|hr|pre|blockquote|ol|ul|li|dl|dt|dd|figure|figcaption|div|a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|dbo|span|br|wbr|ins|del|image|iframe|embed|object|param|video|audio|source|track|canvas|map|area|sv|math|table|caption|colgroup|col|tbody|thead|tfoot|tr|td|th|form|fieldset|legeng|label|input|button|select|datalist|optgroup|option|textarea|keygen|output|progress|meter|details|summary|menuitem|menu)\b/g,alias:"tag"}],property:[/^\s*([a-z-]+)(?=\s+[\w\W]+|\s*:)(?!\s*\{|\r?\n)/gim,{pattern:/(\(\s*)([a-z-]+)(?=\s*:)/gi,lookbehind:!0}],"function":/[-a-z0-9]+(?=\()/gi,punctuation:/[\{\};:]/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/g}; \ No newline at end of file +!function(n){var t={url:/url\((["']?).*?\1\)/i,string:/("|')(?:[^\\\r\n]|\\(?:\r\n|[\s\S]))*?\1/,interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:if|else|for|return|unless)(?=\s+|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,number:/\b\d+(?:\.\d+)?%?/,"boolean":/\b(?:true|false)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.+|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],punctuation:/[{}()\[\];:,]/};t.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:n.util.clone(t)},t.func={pattern:/[\w-]+\([^)]*\).*/,inside:{"function":/^[^(]+/,rest:n.util.clone(t)}},n.languages.stylus={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0},"atrule-declaration":{pattern:/(^\s*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:t}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:(?:\{[^}]*\}|.+)|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:t}},statement:{pattern:/(^[ \t]*)(?:if|else|for|return|unless)[ \t]+.+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:t}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)[^{\r\n]*(?:;|[^{\r\n,](?=$)(?!(\r?\n|\r)(?:\{|\2[ \t]+)))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:t.interpolation}},rest:t}},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:!0,inside:{interpolation:t.interpolation,punctuation:/[{},]/}},func:t.func,string:t.string,interpolation:t.interpolation,punctuation:/[{}()\[\];:.]/}}(Prism); \ No newline at end of file diff --git a/examples/prism-stylus.html b/examples/prism-stylus.html index f910de0f3a..eb5e22c515 100644 --- a/examples/prism-stylus.html +++ b/examples/prism-stylus.html @@ -29,7 +29,7 @@

Full Example

body font: 12px Helvetica, Arial, sans-serif -a.link > button#test, input[type=button], a:after() +a.link > button#test, input[type=button], a:after -webkit-border-radius: 5px -moz-border-radius: 5px border-radius: 5px @@ -81,9 +81,5 @@

Known failures

If a failure is listed here, it doesn’t mean it will never be fixed. This is more of a “known bugs” list, just with a certain type of bug.

-

Incorrect highlighting when tags like literals are used inside a string

-
add(a, b)
-	if a is a 'unit' and b is a 'unit'
-		a + b
-	else
-		(error 'a and b must be units!')
+

Comment-like substrings

+
"foo // bar";
diff --git a/tests/languages/stylus+jade/stylus_inclusion.test b/tests/languages/stylus+jade/stylus_inclusion.test index 08e4af83a0..3c7c8d2574 100644 --- a/tests/languages/stylus+jade/stylus_inclusion.test +++ b/tests/languages/stylus+jade/stylus_inclusion.test @@ -6,10 +6,12 @@ [ ["filter-stylus", [ ["filter-name", ":stylus"], - ["variable", "\r\n font-size"], - ["operator", "="], - ["number", "14"], - ["keyword", "px"] + ["variable-declaration", [ + ["variable", "font-size"], + ["operator", "="], + ["number", "14"], + "px" + ]] ]] ]