Add Sass (scss) support
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
diff --git a/code.js b/code.js
index b88c9a2..984ce96 100644
--- a/code.js
+++ b/code.js
@@ -47,6 +47,10 @@ var components = {
'coffeescript': {
title: 'CoffeeScript',
require: 'javascript'
+ },
+ 'scss': {
+ title: 'Sass (Scss)',
+ require: 'css'
}
},
plugins: {
diff --git a/components/prism-scss.js b/components/prism-scss.js
new file mode 100644
index 0000000..c51c55c
--- /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 0000000..058dbc8
--- /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 4797e90..07f6695 100644
--- a/examples.html
+++ b/examples.html
@@ -303,8 +303,6 @@ public class PrismJS {
<p>As you can notice String keyword is not highlighted because it's not a Java language keyword (cf. <a href="http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html">Java Language Keywords</a>). The main reason is that String is not a primitive type such as <em>int</em> but a class type like <em>Integer</em>.</p>
</section>
-
-
<section class="language-coffeescript">
<h1>Coffeescript</h1>
@@ -370,6 +368,140 @@ class CoffeeScript extends Prism.Javascript
</code></pre>
</section>
+<section class="language-scss">
+ <h1>Sass (Scss)</h2>
+
+ <h2>Comments</h2>
+ <pre><code>// This is a simple one line comment</code></pre>
+
+ <h2>Variables</h2>
+ <pre><code>$var: value;
+$bool: true;
+$nullValue: null;
+$interpolation: -vendor-#{$var};</code></pre>
+
+ <h2>Nesting</h2>
+ <pre><code>sel {
+ ector {
+ #chi,
+ ld .ren { } inline {} * {}
+ }
+
+ &.parentSelector {
+ nested & test #{$inter}pol {}
+ }
+}</code></pre>
+
+ <h2>Directives</h2>
+ <pre><code>@import "compass";
+
+.class {
+ @extend %placeholder;
+}
+
+@debug $var;
+
+@warn "This is a Warning in the console";</code></pre>
+
+ <h2>Keywords</h2>
+ <pre><code>@mixin super-mixin() {
+ @include great-mixin();
+}
+
+@function fn() {
+ @return value;
+}
+ </code></pre>
+
+ <h2>URLs Functions (Compass Style)</h2>
+ <pre><code>selector {
+ background: image-url('stuff.png');
+}
+
+@font-face {
+ src: font-url('font.woff');
+}</code></pre>
+
+ <h2>Statements</h2>
+ <pre><code>$var: value !default;
+
+selector {
+ @extend %stuff !optional;
+}</code></pre>
+
+ <h2>Controls</h2>
+ <pre><code>@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;
+}</code></pre>
+
+ <h2>Scss full example</h2>
+ <pre><code>@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;
+ }
+}</code></pre>
+
+ <p>
+ 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).
+ </p>
+ <h2>Known issues</h2>
+ <ul>
+ <li>& keyword and interpolated variables are not highlighted in selectors.</li>
+ <li>Some control directives parameters are parsed as selectors.</li>
+ <li>Does not work very well with indented Sass syntax. That's why it's just called "scss".</li>
+ </ul>
+ <p>If you are good with regex, maybe you can help to improve this.</p>
+</section>
+
<section id="failures" class="language-javascript">
<h1>Known failures (JavaScript)</h1>
<p>There are certain edge cases where Prism will fail.
diff --git a/prism.js b/prism.js
index 239c615..3daaa40 100644
--- a/prism.js
+++ b/prism.js
@@ -501,3 +501,44 @@ Prism.languages.insertBefore('coffeescript', 'keyword', {
'attr-name': /[_?a-z-|A-Z-]+(\s*:)| @[_?$?a-z-|A-Z-]+(\s*)| /g
});
+
+/* **********************************************
+ 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
+});
+