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"
+ ]]
]]
]