199 lines
4.5 KiB
JavaScript
199 lines
4.5 KiB
JavaScript
|
(function(Prism) {
|
||
|
// TODO:
|
||
|
// - Add CSS highlighting inside <style> tags
|
||
|
// - Add support for multi-line code blocks
|
||
|
// - Add support for interpolation #{} and !{}
|
||
|
// - Add support for tag interpolation #[]
|
||
|
// - Add explicit support for plain text using |
|
||
|
// - Add support for markup embedded in plain text
|
||
|
|
||
|
Prism.languages.pug = {
|
||
|
|
||
|
// Multiline stuff should appear before the rest
|
||
|
|
||
|
// This handles both single-line and multi-line comments
|
||
|
'comment': {
|
||
|
pattern: /(^([\t ]*))\/\/.*(?:(?:\r?\n|\r)\2[\t ]+.+)*/m,
|
||
|
lookbehind: true
|
||
|
},
|
||
|
|
||
|
// All the tag-related part is in lookbehind
|
||
|
// so that it can be highlighted by the "tag" pattern
|
||
|
'multiline-script': {
|
||
|
pattern: /(^([\t ]*)script\b.*\.[\t ]*)(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
rest: Prism.languages.javascript
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// See at the end of the file for known filters
|
||
|
'filter': {
|
||
|
pattern: /(^([\t ]*)):.+(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
'filter-name': {
|
||
|
pattern: /^:[\w-]+/,
|
||
|
alias: 'variable'
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
'multiline-plain-text': {
|
||
|
pattern: /(^([\t ]*)[\w\-#.]+\.[\t ]*)(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
|
||
|
lookbehind: true
|
||
|
},
|
||
|
'markup': {
|
||
|
pattern: /(^[\t ]*)<.+/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
rest: Prism.languages.markup
|
||
|
}
|
||
|
},
|
||
|
'doctype': {
|
||
|
pattern: /((?:^|\n)[\t ]*)doctype(?: .+)?/,
|
||
|
lookbehind: true
|
||
|
},
|
||
|
|
||
|
// This handle all conditional and loop keywords
|
||
|
'flow-control': {
|
||
|
pattern: /(^[\t ]*)(?:if|unless|else|case|when|default|each|while)\b(?: .+)?/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
'each': {
|
||
|
pattern: /^each .+? in\b/,
|
||
|
inside: {
|
||
|
'keyword': /\b(?:each|in)\b/,
|
||
|
'punctuation': /,/
|
||
|
}
|
||
|
},
|
||
|
'branch': {
|
||
|
pattern: /^(?:if|unless|else|case|when|default|while)\b/,
|
||
|
alias: 'keyword'
|
||
|
},
|
||
|
rest: Prism.languages.javascript
|
||
|
}
|
||
|
},
|
||
|
'keyword': {
|
||
|
pattern: /(^[\t ]*)(?:block|extends|include|append|prepend)\b.+/m,
|
||
|
lookbehind: true
|
||
|
},
|
||
|
'mixin': [
|
||
|
// Declaration
|
||
|
{
|
||
|
pattern: /(^[\t ]*)mixin .+/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
'keyword': /^mixin/,
|
||
|
'function': /\w+(?=\s*\(|\s*$)/,
|
||
|
'punctuation': /[(),.]/
|
||
|
}
|
||
|
},
|
||
|
// Usage
|
||
|
{
|
||
|
pattern: /(^[\t ]*)\+.+/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
'name': {
|
||
|
pattern: /^\+\w+/,
|
||
|
alias: 'function'
|
||
|
},
|
||
|
'rest': Prism.languages.javascript
|
||
|
}
|
||
|
}
|
||
|
],
|
||
|
'script': {
|
||
|
pattern: /(^[\t ]*script(?:(?:&[^(]+)?\([^)]+\))*[\t ]+).+/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
rest: Prism.languages.javascript
|
||
|
}
|
||
|
},
|
||
|
|
||
|
'plain-text': {
|
||
|
pattern: /(^[\t ]*(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?[\t ]+).+/m,
|
||
|
lookbehind: true
|
||
|
},
|
||
|
'tag': {
|
||
|
pattern: /(^[\t ]*)(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?:?/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
'attributes': [
|
||
|
{
|
||
|
pattern: /&[^(]+\([^)]+\)/,
|
||
|
inside: {
|
||
|
rest: Prism.languages.javascript
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
pattern: /\([^)]+\)/,
|
||
|
inside: {
|
||
|
'attr-value': {
|
||
|
pattern: /(=\s*)(?:\{[^}]*\}|[^,)\r\n]+)/,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
rest: Prism.languages.javascript
|
||
|
}
|
||
|
},
|
||
|
'attr-name': /[\w-]+(?=\s*!?=|\s*[,)])/,
|
||
|
'punctuation': /[!=(),]+/
|
||
|
}
|
||
|
}
|
||
|
],
|
||
|
'punctuation': /:/
|
||
|
}
|
||
|
},
|
||
|
'code': [
|
||
|
{
|
||
|
pattern: /(^[\t ]*(?:-|!?=)).+/m,
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
rest: Prism.languages.javascript
|
||
|
}
|
||
|
}
|
||
|
],
|
||
|
'punctuation': /[.\-!=|]+/
|
||
|
};
|
||
|
|
||
|
var filter_pattern = '(^([\\t ]*)):{{filter_name}}(?:(?:\\r?\\n|\\r(?!\\n))(?:\\2[\\t ]+.+|\\s*?(?=\\r?\\n|\\r)))+';
|
||
|
|
||
|
// Non exhaustive list of available filters and associated languages
|
||
|
var filters = [
|
||
|
{filter:'atpl',language:'twig'},
|
||
|
{filter:'coffee',language:'coffeescript'},
|
||
|
'ejs',
|
||
|
'handlebars',
|
||
|
'hogan',
|
||
|
'less',
|
||
|
'livescript',
|
||
|
'markdown',
|
||
|
'mustache',
|
||
|
'plates',
|
||
|
{filter:'sass',language:'scss'},
|
||
|
'stylus',
|
||
|
'swig'
|
||
|
|
||
|
];
|
||
|
var all_filters = {};
|
||
|
for (var i = 0, l = filters.length; i < l; i++) {
|
||
|
var filter = filters[i];
|
||
|
filter = typeof filter === 'string' ? {filter: filter, language: filter} : filter;
|
||
|
if (Prism.languages[filter.language]) {
|
||
|
all_filters['filter-' + filter.filter] = {
|
||
|
pattern: RegExp(filter_pattern.replace('{{filter_name}}', filter.filter), 'm'),
|
||
|
lookbehind: true,
|
||
|
inside: {
|
||
|
'filter-name': {
|
||
|
pattern: /^:[\w-]+/,
|
||
|
alias: 'variable'
|
||
|
},
|
||
|
rest: Prism.languages[filter.language]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Prism.languages.insertBefore('pug', 'filter', all_filters);
|
||
|
|
||
|
}(Prism));
|