diff --git a/components/prism-scss.js b/components/prism-scss.js new file mode 100644 index 0000000000..c51c55c317 --- /dev/null +++ b/components/prism-scss.js @@ -0,0 +1,35 @@ +Prism.languages.scss = Prism.languages.extend('css', { + 'comment': { + pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g, + lookbehind: true + }, + // aturle is just the @***, not the entire rule (to highlight var & stuffs) + // + add ability to highlight number & unit for media queries + 'atrule': /@[\w-]+(?=\s+(\(|\{|;))/gi, + // url, compassified + 'url': /([-a-z]+-)*url(?=\()/gi, + // 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 + // 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 :) + 'selector': /([^@;:\{\}\(\)]?([^@;:\{\}\(\)]|&|\#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/gm +}); + +Prism.languages.insertBefore('scss', 'atrule', { + 'keyword': /@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return)|(?=@for\s+\$[-_\w]+\s)+from/i +}); + +Prism.languages.insertBefore('scss', 'property', { + 'variable': /\$[-_\w]+/i +}); + +Prism.languages.insertBefore('scss', 'ignore', { + 'placeholder': /%[-_\w]+/i, + 'statement': /\B!(default|optional)\b/gi, + 'boolean': /\b(true|false)\b/g, + 'null': /\b(null)\b/g, + 'operator': /\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|\%)\s+/g +}); diff --git a/components/prism-scss.min.js b/components/prism-scss.min.js new file mode 100644 index 0000000000..058dbc87c6 --- /dev/null +++ b/components/prism-scss.min.js @@ -0,0 +1 @@ +Prism.languages.java=Prism.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/g,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+[e]?[\d]*[df]\b|\W\d*\.?\d+\b/gi,operator:{pattern:/([^\.]|^)([-+]{1,2}|!|=?<|=?>|={1,2}|(&){1,2}|\|?\||\?|\*|\/|%|\^|(<){2}|($gt;){2,3}|:|~)/g,lookbehind:!0}});Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g,lookbehind:!0},atrule:/@[\w-]+(?=\s+(\(|\{|;))/gi,url:/([-a-z]+-)*url(?=\()/gi,selector:/([^@;:\{\}\(\)]?([^@;:\{\}\(\)]|&|\#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/gm});Prism.languages.insertBefore("scss","atrule",{keyword:/@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return)|(?=@for\s+\$[-_\w]+\s)+from/i});Prism.languages.insertBefore("scss","property",{variable:/\$[-_\w]+/i});Prism.languages.insertBefore("scss","ignore",{placeholder:/%[-_\w]+/i,statement:/\B!(default|optional)\b/gi,"boolean":/\b(true|false)\b/g,"null":/\b(null)\b/g,operator:/\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|\%)\s+/g}); \ No newline at end of file diff --git a/examples.html b/examples.html index da51b27579..d2eeb8243e 100644 --- a/examples.html +++ b/examples.html @@ -303,6 +303,140 @@
As you can notice String keyword is not highlighted because it's not a Java language keyword (cf. Java Language Keywords). The main reason is that String is not a primitive type such as int but a class type like Integer.
+// This is a simple one line comment
+
+ $var: value;
+$bool: true;
+$nullValue: null;
+$interpolation: -vendor-#{$var};
+
+ sel {
+ ector {
+ #chi,
+ ld .ren { } inline {} * {}
+ }
+
+ &.parentSelector {
+ nested & test #{$inter}pol {}
+ }
+}
+
+ @import "compass";
+
+.class {
+ @extend %placeholder;
+}
+
+@debug $var;
+
+@warn "This is a Warning in the console";
+
+ @mixin super-mixin() {
+ @include great-mixin();
+}
+
+@function fn() {
+ @return value;
+}
+
+
+ selector {
+ background: image-url('stuff.png');
+}
+
+@font-face {
+ src: font-url('font.woff');
+}
+
+ $var: value !default;
+
+selector {
+ @extend %stuff !optional;
+}
+
+ @if(true) {
+ // ...
+}
+@else if {
+ // ...
+}
+@else {
+ // ...
+}
+
+@for $i from 1 through 3 {
+ // ...
+}
+
+@each $animal in puma, sea-slug, egret, salamander {
+ // ...
+}
+
+$i: 2;
+@while $i > 0 {
+ //...
+ $i: $i - 1; // note the operator
+ $i: 3 * 2 + $i % 5;
+}
+
+ @import "compass";
+
+@mixin mixin($param) {
+ @if($param==true) {
+ selector-#{$test}-stuff,
+ sel2 {
+ property: -moz-#{$param};
+ aze: rty;
+
+ child {
+ test: $param * 3;
+ a: bcd;
+ color: #f45f55;
+ }
+ }
+ }
+ @else {
+ property: $param + #aaa;
+ test: stupid;
+ }
+}
+
+$i: 2;
+@while $i > 0 {
+ sel#{$i}: $i * 2
+}
+
+selector {
+ @media (min-width: 800px) {
+ stuff: $thing;
+ }
+}
+
+ + This Scss syntax can be used just for CSS too since regular CSS is valid Scss too. + Highlight renders better with an appropriate theme (to customize specific tokens). +
+If you are good with regex, maybe you can help to improve this.
+There are certain edge cases where Prism will fail. diff --git a/prism.js b/prism.js index f1940348b1..106d29e1ec 100644 --- a/prism.js +++ b/prism.js @@ -492,3 +492,43 @@ Prism.languages.java = Prism.languages.extend('clike', { lookbehind: true } }); + +/* ********************************************** + Begin prism-scss.js +********************************************** */ + +Prism.languages.scss = Prism.languages.extend('css', { + 'comment': { + pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g, + lookbehind: true + }, + // aturle is just the @***, not the entire rule (to highlight var & stuffs) + // + add ability to highlight number & unit for media queries + 'atrule': /@[\w-]+(?=\s+(\(|\{|;))/gi, + // url, compassified + 'url': /([-a-z]+-)*url(?=\()/gi, + // 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 + // 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 :) + 'selector': /([^@;:\{\}\(\)]?([^@;:\{\}\(\)]|&|\#\{\$[-_\w]+\})+)(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/gm +}); + +Prism.languages.insertBefore('scss', 'atrule', { + 'keyword': /@(if|else if|else|for|each|while|import|extend|debug|warn|mixin|include|function|return)|(?=@for\s+\$[-_\w]+\s)+from/i +}); + +Prism.languages.insertBefore('scss', 'property', { + 'variable': /\$[-_\w]+/i +}); + +Prism.languages.insertBefore('scss', 'ignore', { + 'placeholder': /%[-_\w]+/i, + 'statement': /\B!(default|optional)\b/gi, + 'boolean': /\b(true|false)\b/g, + 'null': /\b(null)\b/g, + 'operator': /\s+([-+]{1,2}|={1,2}|!=|\|?\||\?|\*|\/|\%)\s+/g +});