diff --git a/components/prism-scss.js b/components/prism-scss.js index b7a872ac1e..837844f7d9 100644 --- a/components/prism-scss.js +++ b/components/prism-scss.js @@ -1,50 +1,60 @@ Prism.languages.scss = Prism.languages.extend('css', { 'comment': { - pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/, + pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/, lookbehind: true }, 'atrule': { - pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+(\{|;))/i, + pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/, inside: { 'rule': /@[\w-]+/ // See rest below } }, // url, compassified - 'url': /([-a-z]+-)*url(?=\()/i, + 'url': /(?:[-a-z]+-)*url(?=\()/i, // CSS selector regex is not appropriate for Sass // since there can be lot more things (var, @ directive, nesting..) // a selector must start at the end of a property or after a brace (end of other rules or nesting) - // it can contain some caracters that aren't used for defining rules or end of selector, & (parent selector), or interpolated variable + // it can contain some characters that aren't used for defining rules or end of selector, & (parent selector), or interpolated variable // the end of a selector is found when there is no rules in it ( {} or {\s}) or if there is a property (because an interpolated var // can "pass" as a selector- e.g: proper#{$erty}) - // this one was ard to do, so please be careful if you edit this one :) + // this one was hard to do, so please be careful if you edit this one :) 'selector': { - pattern: /([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m, + // Initial look-ahead is used to prevent matching of blank selectors + pattern: /(?=\S)[^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m, inside: { - 'placeholder': /%[-_\w]+/i + 'placeholder': /%[-_\w]+/ } } }); Prism.languages.insertBefore('scss', 'atrule', { - 'keyword': /@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i + 'keyword': [ + /@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i, + { + pattern: /( +)(?:from|through)(?= )/, + lookbehind: true + } + ] }); Prism.languages.insertBefore('scss', 'property', { // var and interpolated vars - 'variable': /((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i + 'variable': /\$[-_\w]+|#\{\$[-_\w]+\}/ }); Prism.languages.insertBefore('scss', 'function', { 'placeholder': { - pattern: /%[-_\w]+/i, + pattern: /%[-_\w]+/, alias: 'selector' }, - 'statement': /\B!(default|optional)\b/i, - 'boolean': /\b(true|false)\b/, - 'null': /\b(null)\b/, - 'operator': /\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/ + 'statement': /\B!(?:default|optional)\b/i, + 'boolean': /\b(?:true|false)\b/, + 'null': /\bnull\b/, + 'operator': { + pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/, + lookbehind: true + } }); Prism.languages.scss['atrule'].inside.rest = Prism.util.clone(Prism.languages.scss); \ No newline at end of file diff --git a/components/prism-scss.min.js b/components/prism-scss.min.js index d8837a441e..7cf5ad407b 100644 --- a/components/prism-scss.min.js +++ b/components/prism-scss.min.js @@ -1 +1 @@ -Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/,lookbehind:!0},atrule:{pattern:/@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+(\{|;))/i,inside:{rule:/@[\w-]+/}},url:/([-a-z]+-)*url(?=\()/i,selector:{pattern:/([^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m,inside:{placeholder:/%[-_\w]+/i}}}),Prism.languages.insertBefore("scss","atrule",{keyword:/@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)|(?=@for\s+\$[-_\w]+\s)+from/i}),Prism.languages.insertBefore("scss","property",{variable:/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i}),Prism.languages.insertBefore("scss","function",{placeholder:{pattern:/%[-_\w]+/i,alias:"selector"},statement:/\B!(default|optional)\b/i,"boolean":/\b(true|false)\b/,"null":/\b(null)\b/,operator:/\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|%)\s+/}),Prism.languages.scss.atrule.inside.rest=Prism.util.clone(Prism.languages.scss); \ No newline at end of file +Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)*url(?=\()/i,selector:{pattern:/(?=\S)[^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m,inside:{placeholder:/%[-_\w]+/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","property",{variable:/\$[-_\w]+|#\{\$[-_\w]+\}/}),Prism.languages.insertBefore("scss","function",{placeholder:{pattern:/%[-_\w]+/,alias:"selector"},statement:/\B!(?:default|optional)\b/i,"boolean":/\b(?:true|false)\b/,"null":/\bnull\b/,operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.util.clone(Prism.languages.scss); \ No newline at end of file diff --git a/tests/languages/scss+haml/scss_inclusion.test b/tests/languages/scss+haml/scss_inclusion.test index 0fe4f2582a..3f52393c64 100644 --- a/tests/languages/scss+haml/scss_inclusion.test +++ b/tests/languages/scss+haml/scss_inclusion.test @@ -14,7 +14,7 @@ [ ["filter-scss", [ ["filter-name", ":scss"], - ["selector", ["\r\n\t#main "]], + ["selector", ["#main "]], ["punctuation", "{"], ["property", "width"], ["punctuation", ":"], @@ -25,7 +25,7 @@ ["punctuation", "~"], ["filter-scss", [ ["filter-name", ":scss"], - ["selector", ["\r\n\t #main "]], + ["selector", ["#main "]], ["punctuation", "{"], ["property", "width"], ["punctuation", ":"],