]> luflow.net public git repositories - flow-web.git/blob - static/highlight/languages/crystal.js
Initial commit.
[flow-web.git] / static / highlight / languages / crystal.js
1 /*! `crystal` grammar compiled for Highlight.js 11.11.1 */
2 (function(){
3 var hljsGrammar = (function () {
4 'use strict';
5
6 /*
7 Language: Crystal
8 Author: TSUYUSATO Kitsune <make.just.on@gmail.com>
9 Website: https://crystal-lang.org
10 Category: system
11 */
12
13 /** @type LanguageFn */
14 function crystal(hljs) {
15 const INT_SUFFIX = '(_?[ui](8|16|32|64|128))?';
16 const FLOAT_SUFFIX = '(_?f(32|64))?';
17 const CRYSTAL_IDENT_RE = '[a-zA-Z_]\\w*[!?=]?';
18 const CRYSTAL_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|[=!]~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~|]|//|//=|&[-+*]=?|&\\*\\*|\\[\\][=?]?';
19 const CRYSTAL_PATH_RE = '[A-Za-z_]\\w*(::\\w+)*(\\?|!)?';
20 const CRYSTAL_KEYWORDS = {
21 $pattern: CRYSTAL_IDENT_RE,
22 keyword:
23 'abstract alias annotation as as? asm begin break case class def do else elsif end ensure enum extend for fun if '
24 + 'include instance_sizeof is_a? lib macro module next nil? of out pointerof private protected rescue responds_to? '
25 + 'return require select self sizeof struct super then type typeof union uninitialized unless until verbatim when while with yield '
26 + '__DIR__ __END_LINE__ __FILE__ __LINE__',
27 literal: 'false nil true'
28 };
29 const SUBST = {
30 className: 'subst',
31 begin: /#\{/,
32 end: /\}/,
33 keywords: CRYSTAL_KEYWORDS
34 };
35 // borrowed from Ruby
36 const VARIABLE = {
37 // negative-look forward attemps to prevent false matches like:
38 // @ident@ or $ident$ that might indicate this is not ruby at all
39 className: "variable",
40 begin: '(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])' + `(?![A-Za-z])(?![@$?'])`
41 };
42 const EXPANSION = {
43 className: 'template-variable',
44 variants: [
45 {
46 begin: '\\{\\{',
47 end: '\\}\\}'
48 },
49 {
50 begin: '\\{%',
51 end: '%\\}'
52 }
53 ],
54 keywords: CRYSTAL_KEYWORDS
55 };
56
57 function recursiveParen(begin, end) {
58 const
59 contains = [
60 {
61 begin: begin,
62 end: end
63 }
64 ];
65 contains[0].contains = contains;
66 return contains;
67 }
68 const STRING = {
69 className: 'string',
70 contains: [
71 hljs.BACKSLASH_ESCAPE,
72 SUBST
73 ],
74 variants: [
75 {
76 begin: /'/,
77 end: /'/
78 },
79 {
80 begin: /"/,
81 end: /"/
82 },
83 {
84 begin: /`/,
85 end: /`/
86 },
87 {
88 begin: '%[Qwi]?\\(',
89 end: '\\)',
90 contains: recursiveParen('\\(', '\\)')
91 },
92 {
93 begin: '%[Qwi]?\\[',
94 end: '\\]',
95 contains: recursiveParen('\\[', '\\]')
96 },
97 {
98 begin: '%[Qwi]?\\{',
99 end: /\}/,
100 contains: recursiveParen(/\{/, /\}/)
101 },
102 {
103 begin: '%[Qwi]?<',
104 end: '>',
105 contains: recursiveParen('<', '>')
106 },
107 {
108 begin: '%[Qwi]?\\|',
109 end: '\\|'
110 },
111 {
112 begin: /<<-\w+$/,
113 end: /^\s*\w+$/
114 }
115 ],
116 relevance: 0
117 };
118 const Q_STRING = {
119 className: 'string',
120 variants: [
121 {
122 begin: '%q\\(',
123 end: '\\)',
124 contains: recursiveParen('\\(', '\\)')
125 },
126 {
127 begin: '%q\\[',
128 end: '\\]',
129 contains: recursiveParen('\\[', '\\]')
130 },
131 {
132 begin: '%q\\{',
133 end: /\}/,
134 contains: recursiveParen(/\{/, /\}/)
135 },
136 {
137 begin: '%q<',
138 end: '>',
139 contains: recursiveParen('<', '>')
140 },
141 {
142 begin: '%q\\|',
143 end: '\\|'
144 },
145 {
146 begin: /<<-'\w+'$/,
147 end: /^\s*\w+$/
148 }
149 ],
150 relevance: 0
151 };
152 const REGEXP = {
153 begin: '(?!%\\})(' + hljs.RE_STARTERS_RE + '|\\n|\\b(case|if|select|unless|until|when|while)\\b)\\s*',
154 keywords: 'case if select unless until when while',
155 contains: [
156 {
157 className: 'regexp',
158 contains: [
159 hljs.BACKSLASH_ESCAPE,
160 SUBST
161 ],
162 variants: [
163 {
164 begin: '//[a-z]*',
165 relevance: 0
166 },
167 {
168 begin: '/(?!\\/)',
169 end: '/[a-z]*'
170 }
171 ]
172 }
173 ],
174 relevance: 0
175 };
176 const REGEXP2 = {
177 className: 'regexp',
178 contains: [
179 hljs.BACKSLASH_ESCAPE,
180 SUBST
181 ],
182 variants: [
183 {
184 begin: '%r\\(',
185 end: '\\)',
186 contains: recursiveParen('\\(', '\\)')
187 },
188 {
189 begin: '%r\\[',
190 end: '\\]',
191 contains: recursiveParen('\\[', '\\]')
192 },
193 {
194 begin: '%r\\{',
195 end: /\}/,
196 contains: recursiveParen(/\{/, /\}/)
197 },
198 {
199 begin: '%r<',
200 end: '>',
201 contains: recursiveParen('<', '>')
202 },
203 {
204 begin: '%r\\|',
205 end: '\\|'
206 }
207 ],
208 relevance: 0
209 };
210 const ATTRIBUTE = {
211 className: 'meta',
212 begin: '@\\[',
213 end: '\\]',
214 contains: [ hljs.inherit(hljs.QUOTE_STRING_MODE, { className: 'string' }) ]
215 };
216 const CRYSTAL_DEFAULT_CONTAINS = [
217 EXPANSION,
218 STRING,
219 Q_STRING,
220 REGEXP2,
221 REGEXP,
222 ATTRIBUTE,
223 VARIABLE,
224 hljs.HASH_COMMENT_MODE,
225 {
226 className: 'class',
227 beginKeywords: 'class module struct',
228 end: '$|;',
229 illegal: /=/,
230 contains: [
231 hljs.HASH_COMMENT_MODE,
232 hljs.inherit(hljs.TITLE_MODE, { begin: CRYSTAL_PATH_RE }),
233 { // relevance booster for inheritance
234 begin: '<' }
235 ]
236 },
237 {
238 className: 'class',
239 beginKeywords: 'lib enum union',
240 end: '$|;',
241 illegal: /=/,
242 contains: [
243 hljs.HASH_COMMENT_MODE,
244 hljs.inherit(hljs.TITLE_MODE, { begin: CRYSTAL_PATH_RE })
245 ]
246 },
247 {
248 beginKeywords: 'annotation',
249 end: '$|;',
250 illegal: /=/,
251 contains: [
252 hljs.HASH_COMMENT_MODE,
253 hljs.inherit(hljs.TITLE_MODE, { begin: CRYSTAL_PATH_RE })
254 ],
255 relevance: 2
256 },
257 {
258 className: 'function',
259 beginKeywords: 'def',
260 end: /\B\b/,
261 contains: [
262 hljs.inherit(hljs.TITLE_MODE, {
263 begin: CRYSTAL_METHOD_RE,
264 endsParent: true
265 })
266 ]
267 },
268 {
269 className: 'function',
270 beginKeywords: 'fun macro',
271 end: /\B\b/,
272 contains: [
273 hljs.inherit(hljs.TITLE_MODE, {
274 begin: CRYSTAL_METHOD_RE,
275 endsParent: true
276 })
277 ],
278 relevance: 2
279 },
280 {
281 className: 'symbol',
282 begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\?)?:',
283 relevance: 0
284 },
285 {
286 className: 'symbol',
287 begin: ':',
288 contains: [
289 STRING,
290 { begin: CRYSTAL_METHOD_RE }
291 ],
292 relevance: 0
293 },
294 {
295 className: 'number',
296 variants: [
297 { begin: '\\b0b([01_]+)' + INT_SUFFIX },
298 { begin: '\\b0o([0-7_]+)' + INT_SUFFIX },
299 { begin: '\\b0x([A-Fa-f0-9_]+)' + INT_SUFFIX },
300 { begin: '\\b([1-9][0-9_]*[0-9]|[0-9])(\\.[0-9][0-9_]*)?([eE]_?[-+]?[0-9_]*)?' + FLOAT_SUFFIX + '(?!_)' },
301 { begin: '\\b([1-9][0-9_]*|0)' + INT_SUFFIX }
302 ],
303 relevance: 0
304 }
305 ];
306 SUBST.contains = CRYSTAL_DEFAULT_CONTAINS;
307 EXPANSION.contains = CRYSTAL_DEFAULT_CONTAINS.slice(1); // without EXPANSION
308
309 return {
310 name: 'Crystal',
311 aliases: [ 'cr' ],
312 keywords: CRYSTAL_KEYWORDS,
313 contains: CRYSTAL_DEFAULT_CONTAINS
314 };
315 }
316
317 return crystal;
318
319 })();
320
321 hljs.registerLanguage('crystal', hljsGrammar);
322 })();