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 @@

Simple class example

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.

+
+

Sass (Scss)

+ +

Comments

+
// This is a simple one line comment
+ +

Variables

+
$var: value;
+$bool: true;
+$nullValue: null;
+$interpolation: -vendor-#{$var};
+ +

Nesting

+
sel {
+	ector {
+		#chi,
+		ld .ren { } inline {} * {}
+	}
+	
+	&.parentSelector {
+		nested & test #{$inter}pol {}
+	}
+}
+ +

Directives

+
@import "compass";
+
+.class {
+	@extend %placeholder;
+}
+
+@debug $var;
+
+@warn "This is a Warning in the console";
+ +

Keywords

+
@mixin super-mixin() {
+	@include great-mixin();
+}
+
+@function fn() {
+	@return value;
+}
+	
+ +

URLs Functions (Compass Style)

+
selector {
+	background: image-url('stuff.png');
+}
+
+@font-face {
+	src: font-url('font.woff');
+}
+ +

Statements

+
$var: value !default;
+
+selector {
+	@extend %stuff !optional;
+}
+ +

Controls

+
@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;
+}
+ +

Scss full example

+
@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). +

+

Known issues

+ +

If you are good with regex, maybe you can help to improve this.

+
+

Known failures (JavaScript)

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 +});