UNPKG

4.56 kBJavaScriptView Raw
1(function(Prism) {
2 // TODO:
3 // - Add CSS highlighting inside <style> tags
4 // - Add support for multi-line code blocks
5 // - Add support for interpolation #{} and !{}
6 // - Add support for tag interpolation #[]
7 // - Add explicit support for plain text using |
8 // - Add support for markup embedded in plain text
9
10 Prism.languages.pug = {
11
12 // Multiline stuff should appear before the rest
13
14 // This handles both single-line and multi-line comments
15 'comment': {
16 pattern: /(^([\t ]*))\/\/.*(?:(?:\r?\n|\r)\2[\t ]+.+)*/m,
17 lookbehind: true
18 },
19
20 // All the tag-related part is in lookbehind
21 // so that it can be highlighted by the "tag" pattern
22 'multiline-script': {
23 pattern: /(^([\t ]*)script\b.*\.[\t ]*)(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
24 lookbehind: true,
25 inside: Prism.languages.javascript
26 },
27
28 // See at the end of the file for known filters
29 'filter': {
30 pattern: /(^([\t ]*)):.+(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
31 lookbehind: true,
32 inside: {
33 'filter-name': {
34 pattern: /^:[\w-]+/,
35 alias: 'variable'
36 }
37 }
38 },
39
40 'multiline-plain-text': {
41 pattern: /(^([\t ]*)[\w\-#.]+\.[\t ]*)(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/m,
42 lookbehind: true
43 },
44 'markup': {
45 pattern: /(^[\t ]*)<.+/m,
46 lookbehind: true,
47 inside: Prism.languages.markup
48 },
49 'doctype': {
50 pattern: /((?:^|\n)[\t ]*)doctype(?: .+)?/,
51 lookbehind: true
52 },
53
54 // This handle all conditional and loop keywords
55 'flow-control': {
56 pattern: /(^[\t ]*)(?:if|unless|else|case|when|default|each|while)\b(?: .+)?/m,
57 lookbehind: true,
58 inside: {
59 'each': {
60 pattern: /^each .+? in\b/,
61 inside: {
62 'keyword': /\b(?:each|in)\b/,
63 'punctuation': /,/
64 }
65 },
66 'branch': {
67 pattern: /^(?:if|unless|else|case|when|default|while)\b/,
68 alias: 'keyword'
69 },
70 rest: Prism.languages.javascript
71 }
72 },
73 'keyword': {
74 pattern: /(^[\t ]*)(?:block|extends|include|append|prepend)\b.+/m,
75 lookbehind: true
76 },
77 'mixin': [
78 // Declaration
79 {
80 pattern: /(^[\t ]*)mixin .+/m,
81 lookbehind: true,
82 inside: {
83 'keyword': /^mixin/,
84 'function': /\w+(?=\s*\(|\s*$)/,
85 'punctuation': /[(),.]/
86 }
87 },
88 // Usage
89 {
90 pattern: /(^[\t ]*)\+.+/m,
91 lookbehind: true,
92 inside: {
93 'name': {
94 pattern: /^\+\w+/,
95 alias: 'function'
96 },
97 rest: Prism.languages.javascript
98 }
99 }
100 ],
101 'script': {
102 pattern: /(^[\t ]*script(?:(?:&[^(]+)?\([^)]+\))*[\t ]+).+/m,
103 lookbehind: true,
104 inside: Prism.languages.javascript
105 },
106
107 'plain-text': {
108 pattern: /(^[\t ]*(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?[\t ]+).+/m,
109 lookbehind: true
110 },
111 'tag': {
112 pattern: /(^[\t ]*)(?!-)[\w\-#.]*[\w\-](?:(?:&[^(]+)?\([^)]+\))*\/?:?/m,
113 lookbehind: true,
114 inside: {
115 'attributes': [
116 {
117 pattern: /&[^(]+\([^)]+\)/,
118 inside: Prism.languages.javascript
119 },
120 {
121 pattern: /\([^)]+\)/,
122 inside: {
123 'attr-value': {
124 pattern: /(=\s*)(?:\{[^}]*\}|[^,)\r\n]+)/,
125 lookbehind: true,
126 inside: Prism.languages.javascript
127 },
128 'attr-name': /[\w-]+(?=\s*!?=|\s*[,)])/,
129 'punctuation': /[!=(),]+/
130 }
131 }
132 ],
133 'punctuation': /:/,
134 'attr-id': /#[\w\-]+/,
135 'attr-class': /\.[\w\-]+/
136 }
137 },
138 'code': [
139 {
140 pattern: /(^[\t ]*(?:-|!?=)).+/m,
141 lookbehind: true,
142 inside: Prism.languages.javascript
143 }
144 ],
145 'punctuation': /[.\-!=|]+/
146 };
147
148 var filter_pattern = /(^([\t ]*)):{{filter_name}}(?:(?:\r?\n|\r(?!\n))(?:\2[\t ]+.+|\s*?(?=\r?\n|\r)))+/.source;
149
150 // Non exhaustive list of available filters and associated languages
151 var filters = [
152 {filter:'atpl',language:'twig'},
153 {filter:'coffee',language:'coffeescript'},
154 'ejs',
155 'handlebars',
156 'less',
157 'livescript',
158 'markdown',
159 {filter:'sass',language:'scss'},
160 'stylus'
161 ];
162 var all_filters = {};
163 for (var i = 0, l = filters.length; i < l; i++) {
164 var filter = filters[i];
165 filter = typeof filter === 'string' ? {filter: filter, language: filter} : filter;
166 if (Prism.languages[filter.language]) {
167 all_filters['filter-' + filter.filter] = {
168 pattern: RegExp(filter_pattern.replace('{{filter_name}}', function () { return filter.filter; }), 'm'),
169 lookbehind: true,
170 inside: {
171 'filter-name': {
172 pattern: /^:[\w-]+/,
173 alias: 'variable'
174 },
175 rest: Prism.languages[filter.language]
176 }
177 }
178 }
179 }
180
181 Prism.languages.insertBefore('pug', 'filter', all_filters);
182
183}(Prism));