diff --git a/components/prism-javascript.js b/components/prism-javascript.js index 863f3af82a..f4139f2a9b 100644 --- a/components/prism-javascript.js +++ b/components/prism-javascript.js @@ -11,6 +11,25 @@ Prism.languages.insertBefore('javascript', 'keyword', { } }); +Prism.languages.insertBefore('javascript', 'string', { + 'template-string': { + pattern: /`(?:\\`|\\?[^`])*`/, + inside: { + 'interpolation': { + pattern: /\$\{[^}]+\}/, + inside: { + 'interpolation-punctuation': { + pattern: /^\$\{|\}$/, + alias: 'punctuation' + }, + rest: Prism.languages.javascript + } + }, + 'string': /[\s\S]+/ + } + } +}); + if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { 'script': { diff --git a/components/prism-javascript.min.js b/components/prism-javascript.min.js index 655d780795..da70a1b4a7 100644 --- a/components/prism-javascript.min.js +++ b/components/prism-javascript.min.js @@ -1 +1 @@ -Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}}); \ No newline at end of file +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\`|\\?[^`])*`/,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}}); \ No newline at end of file diff --git a/examples/prism-javascript.html b/examples/prism-javascript.html index 213969fc2c..5bd11e3857 100644 --- a/examples/prism-javascript.html +++ b/examples/prism-javascript.html @@ -50,6 +50,24 @@

A division operator on the same line as a regex

var foo = 1/2, bar = /a/g;
 var foo = /a/, bar = 3/4;
+

ES6 features

+
// Regex "y" and "u" flags
+/[a-zA-Z]+/gimyu
+
+// for..of loops
+for(let x of y) { }
+
+// Modules: import
+import { foo as bar } from "file.js"
+
+// Template strings
+`Only on ${y} one line`
+`This template string ${x} is on
+
+multiple lines.`
+`40 + 2 = ${ 40 + 2 }`
+`The squares of the first 3 natural integers are ${[for (x of [1,2,3]) x*x].join(', ')}`
+

Known failures

There are certain edge cases where Prism will fail. There are always such cases in every regex-based syntax highlighter. @@ -61,4 +79,11 @@

Comment-like substrings

"foo /* bar */ baz"; "foo // bar";

Two quotes of the same type (i.e. both single or both double) inside a regex

-
foo = /"foo"/;
\ No newline at end of file +
foo = /"foo"/;
+ +

String interpolation containing a closing brace

+
`${ {foo:'bar'}.foo }`
+`${ '}' }`
+ +

String interpolation containing an unescaped back-tick

+
`${ '`' }`
\ No newline at end of file diff --git a/prism.js b/prism.js index 0a62921272..8e27b9fe6f 100644 --- a/prism.js +++ b/prism.js @@ -588,6 +588,25 @@ Prism.languages.insertBefore('javascript', 'keyword', { } }); +Prism.languages.insertBefore('javascript', 'string', { + 'template-string': { + pattern: /`(?:\\`|\\?[^`])*`/, + inside: { + 'interpolation': { + pattern: /\$\{[^}]+\}/, + inside: { + 'interpolation-punctuation': { + pattern: /^\$\{|\}$/, + alias: 'punctuation' + }, + rest: Prism.languages.javascript + } + }, + 'string': /[\s\S]+/ + } + } +}); + if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { 'script': {