source: node_modules/highlight.js/lib/languages/crystal.js@ e48199a

main
Last change on this file since e48199a was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

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