diff --git a/components.js b/components.js index 86da6f0738..44001f23aa 100644 --- a/components.js +++ b/components.js @@ -501,6 +501,11 @@ var components = { "require": "previewer-base", "owner": "Golmote" }, + "autoloader": { + "title": "Autoloader", + "owner": "Golmote", + "noCSS": true + }, "keep-markup": { "title": "Keep Markup", "owner": "Golmote", diff --git a/components/prism-clike.js b/components/prism-clike.js index 5745341f7d..08dccaf304 100644 --- a/components/prism-clike.js +++ b/components/prism-clike.js @@ -9,7 +9,7 @@ Prism.languages.clike = { lookbehind: true } ], - 'string': /("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 'class-name': { pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, lookbehind: true, diff --git a/components/prism-clike.min.js b/components/prism-clike.min.js index b437bab33b..dddc16e784 100644 --- a/components/prism-clike.min.js +++ b/components/prism-clike.min.js @@ -1 +1 @@ -Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/}; \ No newline at end of file +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/}; \ No newline at end of file diff --git a/components/prism-handlebars.js b/components/prism-handlebars.js index bc8714f0e4..d6eb8e9551 100644 --- a/components/prism-handlebars.js +++ b/components/prism-handlebars.js @@ -73,7 +73,8 @@ } for (var i = 0, t; t = env.tokenStack[i]; i++) { - env.highlightedCode = env.highlightedCode.replace('___HANDLEBARS' + (i + 1) + '___', Prism.highlight(t, env.grammar, 'handlebars')); + // The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns + env.highlightedCode = env.highlightedCode.replace('___HANDLEBARS' + (i + 1) + '___', Prism.highlight(t, env.grammar, 'handlebars').replace(/\$/g, '$$$$')); } env.element.innerHTML = env.highlightedCode; diff --git a/components/prism-handlebars.min.js b/components/prism-handlebars.min.js index b970bfbcfb..bb27b6169f 100644 --- a/components/prism-handlebars.min.js +++ b/components/prism-handlebars.min.js @@ -1 +1 @@ -!function(e){var a=/\{\{\{[\w\W]+?\}\}\}|\{\{[\w\W]+?\}\}/g;e.languages.handlebars=e.languages.extend("markup",{handlebars:{pattern:a,inside:{delimiter:{pattern:/^\{\{\{?|\}\}\}?$/i,alias:"punctuation"},string:/(["'])(\\?.)*?\1/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?)\b/,"boolean":/\b(true|false)\b/,block:{pattern:/^(\s*~?\s*)[#\/]\S+?(?=\s*~?\s*$|\s)/i,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\w\W]+/}},punctuation:/[!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~\s]+/}}}),e.languages.insertBefore("handlebars","tag",{"handlebars-comment":{pattern:/\{\{![\w\W]*?\}\}/,alias:["handlebars","comment"]}}),e.hooks.add("before-highlight",function(e){"handlebars"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(a,function(a){return e.tokenStack.push(a),"___HANDLEBARS"+e.tokenStack.length+"___"}))}),e.hooks.add("before-insert",function(e){"handlebars"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),e.hooks.add("after-highlight",function(a){if("handlebars"===a.language){for(var n,t=0;n=a.tokenStack[t];t++)a.highlightedCode=a.highlightedCode.replace("___HANDLEBARS"+(t+1)+"___",e.highlight(n,a.grammar,"handlebars"));a.element.innerHTML=a.highlightedCode}})}(Prism); \ No newline at end of file +!function(e){var a=/\{\{\{[\w\W]+?\}\}\}|\{\{[\w\W]+?\}\}/g;e.languages.handlebars=e.languages.extend("markup",{handlebars:{pattern:a,inside:{delimiter:{pattern:/^\{\{\{?|\}\}\}?$/i,alias:"punctuation"},string:/(["'])(\\?.)*?\1/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?)\b/,"boolean":/\b(true|false)\b/,block:{pattern:/^(\s*~?\s*)[#\/]\S+?(?=\s*~?\s*$|\s)/i,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\w\W]+/}},punctuation:/[!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~\s]+/}}}),e.languages.insertBefore("handlebars","tag",{"handlebars-comment":{pattern:/\{\{![\w\W]*?\}\}/,alias:["handlebars","comment"]}}),e.hooks.add("before-highlight",function(e){"handlebars"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(a,function(a){return e.tokenStack.push(a),"___HANDLEBARS"+e.tokenStack.length+"___"}))}),e.hooks.add("before-insert",function(e){"handlebars"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),e.hooks.add("after-highlight",function(a){if("handlebars"===a.language){for(var n,t=0;n=a.tokenStack[t];t++)a.highlightedCode=a.highlightedCode.replace("___HANDLEBARS"+(t+1)+"___",e.highlight(n,a.grammar,"handlebars").replace(/\$/g,"$$$$"));a.element.innerHTML=a.highlightedCode}})}(Prism); \ No newline at end of file diff --git a/components/prism-php.js b/components/prism-php.js index 846fa00741..ae1e97ef0d 100644 --- a/components/prism-php.js +++ b/components/prism-php.js @@ -85,7 +85,8 @@ if (Prism.languages.markup) { } for (var i = 0, t; t = env.tokenStack[i]; i++) { - env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php')); + // The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns + env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$')); } env.element.innerHTML = env.highlightedCode; diff --git a/components/prism-php.min.js b/components/prism-php.min.js index e592fe22df..6bb305ab05 100644 --- a/components/prism-php.min.js +++ b/components/prism-php.min.js @@ -1 +1 @@ -Prism.languages.php=Prism.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0}}),Prism.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),Prism.languages.insertBefore("php","keyword",{delimiter:/\?>|<\?(?:php)?/i,variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),Prism.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(e){"php"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi,function(n){return e.tokenStack.push(n),"{{{PHP"+e.tokenStack.length+"}}}"}))}),Prism.hooks.add("before-insert",function(e){"php"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),Prism.hooks.add("after-highlight",function(e){if("php"===e.language){for(var n,a=0;n=e.tokenStack[a];a++)e.highlightedCode=e.highlightedCode.replace("{{{PHP"+(a+1)+"}}}",Prism.highlight(n,e.grammar,"php"));e.element.innerHTML=e.highlightedCode}}),Prism.hooks.add("wrap",function(e){"php"===e.language&&"markup"===e.type&&(e.content=e.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g,'$1'))}),Prism.languages.insertBefore("php","comment",{markup:{pattern:/<[^?]\/?(.*?)>/,inside:Prism.languages.markup},php:/\{\{\{PHP[0-9]+\}\}\}/})); \ No newline at end of file +Prism.languages.php=Prism.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0}}),Prism.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),Prism.languages.insertBefore("php","keyword",{delimiter:/\?>|<\?(?:php)?/i,variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),Prism.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(e){"php"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi,function(a){return e.tokenStack.push(a),"{{{PHP"+e.tokenStack.length+"}}}"}))}),Prism.hooks.add("before-insert",function(e){"php"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),Prism.hooks.add("after-highlight",function(e){if("php"===e.language){for(var a,n=0;a=e.tokenStack[n];n++)e.highlightedCode=e.highlightedCode.replace("{{{PHP"+(n+1)+"}}}",Prism.highlight(a,e.grammar,"php").replace(/\$/g,"$$$$"));e.element.innerHTML=e.highlightedCode}}),Prism.hooks.add("wrap",function(e){"php"===e.language&&"markup"===e.type&&(e.content=e.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g,'$1'))}),Prism.languages.insertBefore("php","comment",{markup:{pattern:/<[^?]\/?(.*?)>/,inside:Prism.languages.markup},php:/\{\{\{PHP[0-9]+\}\}\}/})); \ No newline at end of file diff --git a/components/prism-sass.js b/components/prism-sass.js index 4609ac0ab3..0a34c00e74 100644 --- a/components/prism-sass.js +++ b/components/prism-sass.js @@ -21,7 +21,13 @@ var variable = /((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i; - var operator = /[-+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/; + var operator = [ + /[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/, + { + pattern: /(\s+)-(?=\s)/, + lookbehind: true + } + ]; Prism.languages.insertBefore('sass', 'property', { // We want to consume the whole line diff --git a/components/prism-sass.min.js b/components/prism-sass.min.js index 085ead833a..326df18844 100644 --- a/components/prism-sass.min.js +++ b/components/prism-sass.min.js @@ -1 +1 @@ -!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var a=/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i,t=/[-+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/;e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:a,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:a,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,delete e.languages.sass.selector,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism); \ No newline at end of file +!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var a=/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:a,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:a,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,delete e.languages.sass.selector,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism); \ No newline at end of file diff --git a/components/prism-smarty.js b/components/prism-smarty.js index 40209cee48..c013796569 100644 --- a/components/prism-smarty.js +++ b/components/prism-smarty.js @@ -117,7 +117,8 @@ } for (var i = 0, t; t = env.tokenStack[i]; i++) { - env.highlightedCode = env.highlightedCode.replace('___SMARTY' + (i + 1) + '___', Prism.highlight(t, env.grammar, 'smarty')); + // The replace prevents $$, $&, $`, $', $n, $nn from being interpreted as special patterns + env.highlightedCode = env.highlightedCode.replace('___SMARTY' + (i + 1) + '___', Prism.highlight(t, env.grammar, 'smarty').replace(/\$/g, '$$$$')); } env.element.innerHTML = env.highlightedCode; diff --git a/components/prism-smarty.min.js b/components/prism-smarty.min.js index defe855d0f..cd0ea1965e 100644 --- a/components/prism-smarty.min.js +++ b/components/prism-smarty.min.js @@ -1 +1 @@ -!function(e){var t=/\{\*[\w\W]+?\*\}|\{[\w\W]+?\}/g,a="{literal}",n="{/literal}",o=!1;e.languages.smarty=e.languages.extend("markup",{smarty:{pattern:t,inside:{delimiter:{pattern:/^\{|\}$/i,alias:"punctuation"},string:/(["'])(?:\\?.)*?\1/,number:/\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee][-+]?\d+)?)\b/,variable:[/\$(?!\d)\w+/,/#(?!\d)\w+#/,{pattern:/(\.|->)(?!\d)\w+/,lookbehind:!0},{pattern:/(\[)(?!\d)\w+(?=\])/,lookbehind:!0}],"function":[{pattern:/(\|\s*)@?(?!\d)\w+/,lookbehind:!0},/^\/?(?!\d)\w+/,/(?!\d)\w+(?=\()/],"attr-name":{pattern:/\w+\s*=\s*(?:(?!\d)\w+)?/,inside:{variable:{pattern:/(=\s*)(?!\d)\w+/,lookbehind:!0},operator:/=/}},punctuation:[/[\[\]().,:`]|\->/],operator:[/[+\-*\/%]|==?=?|[!<>]=?|&&|\|\|?/,/\bis\s+(?:not\s+)?(?:div|even|odd)(?:\s+by)?\b/,/\b(?:eq|neq?|gt|lt|gt?e|lt?e|not|mod|or|and)\b/],keyword:/\b(?:false|off|on|no|true|yes)\b/}}}),e.languages.insertBefore("smarty","tag",{"smarty-comment":{pattern:/\{\*[\w\W]*?\*\}/,alias:["smarty","comment"]}}),e.hooks.add("before-highlight",function(e){"smarty"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(t,function(t){return t===n&&(o=!1),o?t:(t===a&&(o=!0),e.tokenStack.push(t),"___SMARTY"+e.tokenStack.length+"___")}))}),e.hooks.add("before-insert",function(e){"smarty"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),e.hooks.add("after-highlight",function(t){if("smarty"===t.language){for(var a,n=0;a=t.tokenStack[n];n++)t.highlightedCode=t.highlightedCode.replace("___SMARTY"+(n+1)+"___",e.highlight(a,t.grammar,"smarty"));t.element.innerHTML=t.highlightedCode}})}(Prism); \ No newline at end of file +!function(e){var t=/\{\*[\w\W]+?\*\}|\{[\w\W]+?\}/g,a="{literal}",n="{/literal}",o=!1;e.languages.smarty=e.languages.extend("markup",{smarty:{pattern:t,inside:{delimiter:{pattern:/^\{|\}$/i,alias:"punctuation"},string:/(["'])(?:\\?.)*?\1/,number:/\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee][-+]?\d+)?)\b/,variable:[/\$(?!\d)\w+/,/#(?!\d)\w+#/,{pattern:/(\.|->)(?!\d)\w+/,lookbehind:!0},{pattern:/(\[)(?!\d)\w+(?=\])/,lookbehind:!0}],"function":[{pattern:/(\|\s*)@?(?!\d)\w+/,lookbehind:!0},/^\/?(?!\d)\w+/,/(?!\d)\w+(?=\()/],"attr-name":{pattern:/\w+\s*=\s*(?:(?!\d)\w+)?/,inside:{variable:{pattern:/(=\s*)(?!\d)\w+/,lookbehind:!0},operator:/=/}},punctuation:[/[\[\]().,:`]|\->/],operator:[/[+\-*\/%]|==?=?|[!<>]=?|&&|\|\|?/,/\bis\s+(?:not\s+)?(?:div|even|odd)(?:\s+by)?\b/,/\b(?:eq|neq?|gt|lt|gt?e|lt?e|not|mod|or|and)\b/],keyword:/\b(?:false|off|on|no|true|yes)\b/}}}),e.languages.insertBefore("smarty","tag",{"smarty-comment":{pattern:/\{\*[\w\W]*?\*\}/,alias:["smarty","comment"]}}),e.hooks.add("before-highlight",function(e){"smarty"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(t,function(t){return t===n&&(o=!1),o?t:(t===a&&(o=!0),e.tokenStack.push(t),"___SMARTY"+e.tokenStack.length+"___")}))}),e.hooks.add("before-insert",function(e){"smarty"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),e.hooks.add("after-highlight",function(t){if("smarty"===t.language){for(var a,n=0;a=t.tokenStack[n];n++)t.highlightedCode=t.highlightedCode.replace("___SMARTY"+(n+1)+"___",e.highlight(a,t.grammar,"smarty").replace(/\$/g,"$$$$"));t.element.innerHTML=t.highlightedCode}})}(Prism); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 51af93c33f..25757dba5c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -18,7 +18,8 @@ var gulp = require('gulp'), 'plugins/file-highlight/prism-file-highlight.js' ], plugins: ['plugins/**/*.js', '!plugins/**/*.min.js'], - showLanguagePlugin: 'plugins/show-language/prism-show-language.js' + showLanguagePlugin: 'plugins/show-language/prism-show-language.js', + autoloaderPlugin: 'plugins/autoloader/prism-autoloader.js' }; gulp.task('components', function() { @@ -37,7 +38,7 @@ gulp.task('build', function() { .pipe(gulp.dest('./')); }); -gulp.task('plugins', ['show-language-plugin'], function() { +gulp.task('plugins', ['languages-plugins'], function() { return gulp.src(paths.plugins) .pipe(uglify()) .pipe(rename({ suffix: '.min' })) @@ -49,7 +50,7 @@ gulp.task('watch', function() { gulp.watch(paths.plugins, ['plugins', 'build']); }); -gulp.task('show-language-plugin', function (cb) { +gulp.task('languages-plugins', function (cb) { fs.readFile(paths.componentsFile, { encoding: 'utf-8' }, function (err, data) { @@ -59,6 +60,7 @@ gulp.task('show-language-plugin', function (cb) { data = JSON.parse(data); var languagesMap = {}; + var dependenciesMap = {}; for (var p in data.languages) { if (p !== 'meta') { var title = data.languages[p].displayTitle || data.languages[p].title; @@ -66,18 +68,41 @@ gulp.task('show-language-plugin', function (cb) { if (title !== ucfirst) { languagesMap[p] = title; } + + if(data.languages[p].require) { + dependenciesMap[p] = data.languages[p].require; + } } } - var jsonLanguages = JSON.stringify(languagesMap); - var stream = gulp.src(paths.showLanguagePlugin) - .pipe(replace( - /\/\*languages_placeholder\[\*\/[\s\S]*?\/\*\]\*\//, - '/*languages_placeholder[*/' + jsonLanguages + '/*]*/' - )) - .pipe(gulp.dest(paths.showLanguagePlugin.substring(0, paths.showLanguagePlugin.lastIndexOf('/')))); - stream.on('error', cb); - stream.on('end', cb); + var jsonLanguagesMap = JSON.stringify(languagesMap); + var jsonDependenciesMap = JSON.stringify(dependenciesMap); + + var tasks = [ + {plugin: paths.showLanguagePlugin, map: jsonLanguagesMap}, + {plugin: paths.autoloaderPlugin, map: jsonDependenciesMap} + ]; + + var cpt = 0; + var l = tasks.length; + var done = function() { + cpt++; + if(cpt === l) { + cb && cb(); + } + }; + + tasks.forEach(function(task) { + var stream = gulp.src(task.plugin) + .pipe(replace( + /\/\*languages_placeholder\[\*\/[\s\S]*?\/\*\]\*\//, + '/*languages_placeholder[*/' + task.map + '/*]*/' + )) + .pipe(gulp.dest(task.plugin.substring(0, task.plugin.lastIndexOf('/')))); + + stream.on('error', done); + stream.on('end', done); + }); } catch (e) { cb(e); diff --git a/plugins/autoloader/index.html b/plugins/autoloader/index.html new file mode 100644 index 0000000000..11fb8ec816 --- /dev/null +++ b/plugins/autoloader/index.html @@ -0,0 +1,106 @@ + + +
+ + + +Automatically loads the needed languages to highlight the code blocks.
+
+ The default usage does not require anything to be done. The plugin will automatically handle missing grammars and load them for you.
+ However, a couple of options are available through the configuration object Prism.plugins.autoloader
.
+
+ By default, the plugin will look for the missing grammars in the components
folder.
+ If your files are in a different location, you can specify it using the languages_path
option:
+
Prism.plugins.autoloader.languages_path = 'path/to/grammars/';
+
+
+ By default, the plugin uses the minified versions of the grammars.
+ If you wish to use the development versions instead, you can set the use_minified
option to false:
+
Prism.plugins.autoloader.use_minified = false;
+
+
+ All default dependencies are already included in the plugin.
+ However, there are some cases where you might want to load an additional dependency for a specific code block.
+ To do so, just add a data-dependencies
attribute on you <code>
or <pre>
tags,
+ containing a list of comma-separated language aliases.
+
<pre><code class="language-jade" data-dependencies="less">
+:less
+ foo {
+ color: @red;
+ }
+</code><pre>
+
+
+ The plugin usually don't reload a grammar if it already exists.
+ In some very specific cases, you might however want to do so.
+ If you add an exclamation mark after an alias in the data-dependencies
attribute,
+ this language will be reloaded.
+
<pre class="language-markup" data-dependencies="markup,css!"><code>
+
+Note that no languages are loaded on this page by default.
+ +Basic usage with some Perl code:
+my ($class, $filename) = @_;
+
+ The Less filter used in Jade:
+:less
+ foo {
+ color: @red;
+ }
+
+ or tags
+ var deps = elt.getAttribute('data-dependencies');
+ if (!deps && elt.parentNode && elt.parentNode.tagName.toLowerCase() === 'pre') {
+ deps = elt.parentNode.getAttribute('data-dependencies');
+ }
+
+ if (deps) {
+ deps = deps.split(/\s*,\s*/g);
+ } else {
+ deps = [];
+ }
+
+ loadLanguages(deps, function () {
+ loadLanguage(lang, function () {
+ Prism.highlightElement(elt);
+ });
+ });
+ };
+
+ /**
+ * Sequentially loads an array of grammars.
+ * @param {string[]|string} langs
+ * @param {function=} success
+ * @param {function=} error
+ */
+ var loadLanguages = function (langs, success, error) {
+ if (typeof langs === 'string') {
+ langs = [langs];
+ }
+ var i = 0;
+ var l = langs.length;
+ var f = function () {
+ if (i < l) {
+ loadLanguage(langs[i], function () {
+ i++;
+ f();
+ }, function () {
+ error && error(langs[i]);
+ });
+ } else if (i === l) {
+ success && success(langs);
+ }
+ };
+ f();
+ };
+
+ /**
+ * Load a grammar with its dependencies
+ * @param {string} lang
+ * @param {function=} success
+ * @param {function=} error
+ */
+ var loadLanguage = function (lang, success, error) {
+ var load = function () {
+ var force = false;
+ // Do we want to force reload the grammar?
+ if (lang.indexOf('!') >= 0) {
+ force = true;
+ lang = lang.replace('!', '');
+ }
+
+ var data = lang_data[lang];
+ if (!data) {
+ data = lang_data[lang] = {};
+ }
+ if (success) {
+ if (!data.success_callbacks) {
+ data.success_callbacks = [];
+ }
+ data.success_callbacks.push(success);
+ }
+ if (error) {
+ if (!data.error_callbacks) {
+ data.error_callbacks = [];
+ }
+ data.error_callbacks.push(error);
+ }
+
+ if (!force && Prism.languages[lang]) {
+ languageSuccess(lang);
+ } else if (!force && data.error) {
+ languageError(lang);
+ } else if (force || !data.loading) {
+ data.loading = true;
+ var src = getLanguagePath(lang);
+ script(src, function () {
+ data.loading = false;
+ languageSuccess(lang);
+
+ }, function () {
+ data.loading = false;
+ data.error = true;
+ languageError(lang);
+ });
+ }
+ };
+ var dependencies = lang_dependencies[lang];
+ if(dependencies && dependencies.length) {
+ loadLanguages(dependencies, load);
+ } else {
+ load();
+ }
+ };
+
+ /**
+ * Runs all success callbacks for this language.
+ * @param {string} lang
+ */
+ var languageSuccess = function (lang) {
+ if (lang_data[lang] && lang_data[lang].success_callbacks && lang_data[lang].success_callbacks.length) {
+ lang_data[lang].success_callbacks.forEach(function (f) {
+ f(lang);
+ });
+ }
+ };
+
+ /**
+ * Runs all error callbacks for this language.
+ * @param {string} lang
+ */
+ var languageError = function (lang) {
+ if (lang_data[lang] && lang_data[lang].error_callbacks && lang_data[lang].error_callbacks.length) {
+ lang_data[lang].error_callbacks.forEach(function (f) {
+ f(lang);
+ });
+ }
+ };
+
+ Prism.hooks.add('complete', function (env) {
+ if (env.element && env.language && !env.grammar) {
+ registerElement(env.language, env.element);
+ }
+ });
+
+}());
\ No newline at end of file
diff --git a/plugins/autoloader/prism-autoloader.min.js b/plugins/autoloader/prism-autoloader.min.js
new file mode 100644
index 0000000000..dd4c43e293
--- /dev/null
+++ b/plugins/autoloader/prism-autoloader.min.js
@@ -0,0 +1 @@
+!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={javascript:"clike",actionscript:"javascript",aspnet:"markup",bash:"clike",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript","css-extras":"css",d:"clike",dart:"clike",fsharp:"clike",glsl:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup",jade:"javascript",java:"clike",less:"css",markdown:"markup",objectivec:"c",php:"clike","php-extras":"php",processing:"clike",qore:["clike"],jsx:["markup","javascript"],ruby:"clike",sass:"css",scss:"css",scala:"java",smarty:"markup",swift:"clike",textile:"markup",twig:"markup",typescript:"javascript",wiki:"markup"},c={},a=Prism.plugins.autoloader={languages_path:"components/",use_minified:!0},s=function(e,c,a){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),c&&c()},s.onerror=function(){document.body.removeChild(s),a&&a()},document.body.appendChild(s)},r=function(e){return a.languages_path+"prism-"+e+(a.use_minified?".min":"")+".js"},n=function(e,a){var s=c[e];s||(s=c[e]={});var r=a.getAttribute("data-dependencies");!r&&a.parentNode&&"pre"===a.parentNode.tagName.toLowerCase()&&(r=a.parentNode.getAttribute("data-dependencies")),r=r?r.split(/\s*,\s*/g):[],i(r,function(){t(e,function(){Prism.highlightElement(a)})})},i=function(e,c,a){"string"==typeof e&&(e=[e]);var s=0,r=e.length,n=function(){r>s?t(e[s],function(){s++,n()},function(){a&&a(e[s])}):s===r&&c&&c(e)};n()},t=function(a,n,t){var u=function(){var e=!1;a.indexOf("!")>=0&&(e=!0,a=a.replace("!",""));var i=c[a];if(i||(i=c[a]={}),n&&(i.success_callbacks||(i.success_callbacks=[]),i.success_callbacks.push(n)),t&&(i.error_callbacks||(i.error_callbacks=[]),i.error_callbacks.push(t)),!e&&Prism.languages[a])l(a);else if(!e&&i.error)o(a);else if(e||!i.loading){i.loading=!0;var u=r(a);s(u,function(){i.loading=!1,l(a)},function(){i.loading=!1,i.error=!0,o(a)})}},p=e[a];p&&p.length?i(p,u):u()},l=function(e){c[e]&&c[e].success_callbacks&&c[e].success_callbacks.length&&c[e].success_callbacks.forEach(function(c){c(e)})},o=function(e){c[e]&&c[e].error_callbacks&&c[e].error_callbacks.length&&c[e].error_callbacks.forEach(function(c){c(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&n(e.language,e.element)})}}();
\ No newline at end of file
diff --git a/prism.js b/prism.js
index 7f72314e70..802b653b1d 100644
--- a/prism.js
+++ b/prism.js
@@ -564,7 +564,7 @@ Prism.languages.clike = {
lookbehind: true
}
],
- 'string': /("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
+ 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
'class-name': {
pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
lookbehind: true,
diff --git a/tests/languages/sass/property-line_feature.test b/tests/languages/sass/property-line_feature.test
index 077f19a383..499f223a97 100644
--- a/tests/languages/sass/property-line_feature.test
+++ b/tests/languages/sass/property-line_feature.test
@@ -1,6 +1,7 @@
foo: bar
color: $color !important
-moz-border-radius: 10px
+transition-timing-function: ease-in-out
:color #{$color}
:font-size 0.5em + 3em
@@ -24,6 +25,11 @@ foo: bar
["punctuation", ":"],
" 10px"
]],
+ ["property-line", [
+ ["property", "transition-timing-function"],
+ ["punctuation", ":"],
+ " ease-in-out"
+ ]],
["property-line", [
["punctuation", ":"],
["property", "color"],