source: node_modules/highlight.js/lib/languages/perl.js

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

Initial commit

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/**
2 * @param {string} value
3 * @returns {RegExp}
4 * */
5
6/**
7 * @param {RegExp | string } re
8 * @returns {string}
9 */
10function source(re) {
11 if (!re) return null;
12 if (typeof re === "string") return re;
13
14 return re.source;
15}
16
17/**
18 * @param {...(RegExp | string) } args
19 * @returns {string}
20 */
21function concat(...args) {
22 const joined = args.map((x) => source(x)).join("");
23 return joined;
24}
25
26/**
27 * Any of the passed expresssions may match
28 *
29 * Creates a huge this | this | that | that match
30 * @param {(RegExp | string)[] } args
31 * @returns {string}
32 */
33function either(...args) {
34 const joined = '(' + args.map((x) => source(x)).join("|") + ")";
35 return joined;
36}
37
38/*
39Language: Perl
40Author: Peter Leonov <gojpeg@yandex.ru>
41Website: https://www.perl.org
42Category: common
43*/
44
45/** @type LanguageFn */
46function perl(hljs) {
47 const KEYWORDS = [
48 'abs',
49 'accept',
50 'alarm',
51 'and',
52 'atan2',
53 'bind',
54 'binmode',
55 'bless',
56 'break',
57 'caller',
58 'chdir',
59 'chmod',
60 'chomp',
61 'chop',
62 'chown',
63 'chr',
64 'chroot',
65 'close',
66 'closedir',
67 'connect',
68 'continue',
69 'cos',
70 'crypt',
71 'dbmclose',
72 'dbmopen',
73 'defined',
74 'delete',
75 'die',
76 'do',
77 'dump',
78 'each',
79 'else',
80 'elsif',
81 'endgrent',
82 'endhostent',
83 'endnetent',
84 'endprotoent',
85 'endpwent',
86 'endservent',
87 'eof',
88 'eval',
89 'exec',
90 'exists',
91 'exit',
92 'exp',
93 'fcntl',
94 'fileno',
95 'flock',
96 'for',
97 'foreach',
98 'fork',
99 'format',
100 'formline',
101 'getc',
102 'getgrent',
103 'getgrgid',
104 'getgrnam',
105 'gethostbyaddr',
106 'gethostbyname',
107 'gethostent',
108 'getlogin',
109 'getnetbyaddr',
110 'getnetbyname',
111 'getnetent',
112 'getpeername',
113 'getpgrp',
114 'getpriority',
115 'getprotobyname',
116 'getprotobynumber',
117 'getprotoent',
118 'getpwent',
119 'getpwnam',
120 'getpwuid',
121 'getservbyname',
122 'getservbyport',
123 'getservent',
124 'getsockname',
125 'getsockopt',
126 'given',
127 'glob',
128 'gmtime',
129 'goto',
130 'grep',
131 'gt',
132 'hex',
133 'if',
134 'index',
135 'int',
136 'ioctl',
137 'join',
138 'keys',
139 'kill',
140 'last',
141 'lc',
142 'lcfirst',
143 'length',
144 'link',
145 'listen',
146 'local',
147 'localtime',
148 'log',
149 'lstat',
150 'lt',
151 'ma',
152 'map',
153 'mkdir',
154 'msgctl',
155 'msgget',
156 'msgrcv',
157 'msgsnd',
158 'my',
159 'ne',
160 'next',
161 'no',
162 'not',
163 'oct',
164 'open',
165 'opendir',
166 'or',
167 'ord',
168 'our',
169 'pack',
170 'package',
171 'pipe',
172 'pop',
173 'pos',
174 'print',
175 'printf',
176 'prototype',
177 'push',
178 'q|0',
179 'qq',
180 'quotemeta',
181 'qw',
182 'qx',
183 'rand',
184 'read',
185 'readdir',
186 'readline',
187 'readlink',
188 'readpipe',
189 'recv',
190 'redo',
191 'ref',
192 'rename',
193 'require',
194 'reset',
195 'return',
196 'reverse',
197 'rewinddir',
198 'rindex',
199 'rmdir',
200 'say',
201 'scalar',
202 'seek',
203 'seekdir',
204 'select',
205 'semctl',
206 'semget',
207 'semop',
208 'send',
209 'setgrent',
210 'sethostent',
211 'setnetent',
212 'setpgrp',
213 'setpriority',
214 'setprotoent',
215 'setpwent',
216 'setservent',
217 'setsockopt',
218 'shift',
219 'shmctl',
220 'shmget',
221 'shmread',
222 'shmwrite',
223 'shutdown',
224 'sin',
225 'sleep',
226 'socket',
227 'socketpair',
228 'sort',
229 'splice',
230 'split',
231 'sprintf',
232 'sqrt',
233 'srand',
234 'stat',
235 'state',
236 'study',
237 'sub',
238 'substr',
239 'symlink',
240 'syscall',
241 'sysopen',
242 'sysread',
243 'sysseek',
244 'system',
245 'syswrite',
246 'tell',
247 'telldir',
248 'tie',
249 'tied',
250 'time',
251 'times',
252 'tr',
253 'truncate',
254 'uc',
255 'ucfirst',
256 'umask',
257 'undef',
258 'unless',
259 'unlink',
260 'unpack',
261 'unshift',
262 'untie',
263 'until',
264 'use',
265 'utime',
266 'values',
267 'vec',
268 'wait',
269 'waitpid',
270 'wantarray',
271 'warn',
272 'when',
273 'while',
274 'write',
275 'x|0',
276 'xor',
277 'y|0'
278 ];
279
280 // https://perldoc.perl.org/perlre#Modifiers
281 const REGEX_MODIFIERS = /[dualxmsipngr]{0,12}/; // aa and xx are valid, making max length 12
282 const PERL_KEYWORDS = {
283 $pattern: /[\w.]+/,
284 keyword: KEYWORDS.join(" ")
285 };
286 const SUBST = {
287 className: 'subst',
288 begin: '[$@]\\{',
289 end: '\\}',
290 keywords: PERL_KEYWORDS
291 };
292 const METHOD = {
293 begin: /->\{/,
294 end: /\}/
295 // contains defined later
296 };
297 const VAR = {
298 variants: [
299 {
300 begin: /\$\d/
301 },
302 {
303 begin: concat(
304 /[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,
305 // negative look-ahead tries to avoid matching patterns that are not
306 // Perl at all like $ident$, @ident@, etc.
307 `(?![A-Za-z])(?![@$%])`
308 )
309 },
310 {
311 begin: /[$%@][^\s\w{]/,
312 relevance: 0
313 }
314 ]
315 };
316 const STRING_CONTAINS = [
317 hljs.BACKSLASH_ESCAPE,
318 SUBST,
319 VAR
320 ];
321 const REGEX_DELIMS = [
322 /!/,
323 /\//,
324 /\|/,
325 /\?/,
326 /'/,
327 /"/, // valid but infrequent and weird
328 /#/ // valid but infrequent and weird
329 ];
330 /**
331 * @param {string|RegExp} prefix
332 * @param {string|RegExp} open
333 * @param {string|RegExp} close
334 */
335 const PAIRED_DOUBLE_RE = (prefix, open, close = '\\1') => {
336 const middle = (close === '\\1')
337 ? close
338 : concat(close, open);
339 return concat(
340 concat("(?:", prefix, ")"),
341 open,
342 /(?:\\.|[^\\\/])*?/,
343 middle,
344 /(?:\\.|[^\\\/])*?/,
345 close,
346 REGEX_MODIFIERS
347 );
348 };
349 /**
350 * @param {string|RegExp} prefix
351 * @param {string|RegExp} open
352 * @param {string|RegExp} close
353 */
354 const PAIRED_RE = (prefix, open, close) => {
355 return concat(
356 concat("(?:", prefix, ")"),
357 open,
358 /(?:\\.|[^\\\/])*?/,
359 close,
360 REGEX_MODIFIERS
361 );
362 };
363 const PERL_DEFAULT_CONTAINS = [
364 VAR,
365 hljs.HASH_COMMENT_MODE,
366 hljs.COMMENT(
367 /^=\w/,
368 /=cut/,
369 {
370 endsWithParent: true
371 }
372 ),
373 METHOD,
374 {
375 className: 'string',
376 contains: STRING_CONTAINS,
377 variants: [
378 {
379 begin: 'q[qwxr]?\\s*\\(',
380 end: '\\)',
381 relevance: 5
382 },
383 {
384 begin: 'q[qwxr]?\\s*\\[',
385 end: '\\]',
386 relevance: 5
387 },
388 {
389 begin: 'q[qwxr]?\\s*\\{',
390 end: '\\}',
391 relevance: 5
392 },
393 {
394 begin: 'q[qwxr]?\\s*\\|',
395 end: '\\|',
396 relevance: 5
397 },
398 {
399 begin: 'q[qwxr]?\\s*<',
400 end: '>',
401 relevance: 5
402 },
403 {
404 begin: 'qw\\s+q',
405 end: 'q',
406 relevance: 5
407 },
408 {
409 begin: '\'',
410 end: '\'',
411 contains: [ hljs.BACKSLASH_ESCAPE ]
412 },
413 {
414 begin: '"',
415 end: '"'
416 },
417 {
418 begin: '`',
419 end: '`',
420 contains: [ hljs.BACKSLASH_ESCAPE ]
421 },
422 {
423 begin: /\{\w+\}/,
424 relevance: 0
425 },
426 {
427 begin: '-?\\w+\\s*=>',
428 relevance: 0
429 }
430 ]
431 },
432 {
433 className: 'number',
434 begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
435 relevance: 0
436 },
437 { // regexp container
438 begin: '(\\/\\/|' + hljs.RE_STARTERS_RE + '|\\b(split|return|print|reverse|grep)\\b)\\s*',
439 keywords: 'split return print reverse grep',
440 relevance: 0,
441 contains: [
442 hljs.HASH_COMMENT_MODE,
443 {
444 className: 'regexp',
445 variants: [
446 // allow matching common delimiters
447 { begin: PAIRED_DOUBLE_RE("s|tr|y", either(...REGEX_DELIMS)) },
448 // and then paired delmis
449 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\(", "\\)") },
450 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\[", "\\]") },
451 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\{", "\\}") }
452 ],
453 relevance: 2
454 },
455 {
456 className: 'regexp',
457 variants: [
458 {
459 // could be a comment in many languages so do not count
460 // as relevant
461 begin: /(m|qr)\/\//,
462 relevance: 0
463 },
464 // prefix is optional with /regex/
465 { begin: PAIRED_RE("(?:m|qr)?", /\//, /\//)},
466 // allow matching common delimiters
467 { begin: PAIRED_RE("m|qr", either(...REGEX_DELIMS), /\1/)},
468 // allow common paired delmins
469 { begin: PAIRED_RE("m|qr", /\(/, /\)/)},
470 { begin: PAIRED_RE("m|qr", /\[/, /\]/)},
471 { begin: PAIRED_RE("m|qr", /\{/, /\}/)}
472 ]
473 }
474 ]
475 },
476 {
477 className: 'function',
478 beginKeywords: 'sub',
479 end: '(\\s*\\(.*?\\))?[;{]',
480 excludeEnd: true,
481 relevance: 5,
482 contains: [ hljs.TITLE_MODE ]
483 },
484 {
485 begin: '-\\w\\b',
486 relevance: 0
487 },
488 {
489 begin: "^__DATA__$",
490 end: "^__END__$",
491 subLanguage: 'mojolicious',
492 contains: [
493 {
494 begin: "^@@.*",
495 end: "$",
496 className: "comment"
497 }
498 ]
499 }
500 ];
501 SUBST.contains = PERL_DEFAULT_CONTAINS;
502 METHOD.contains = PERL_DEFAULT_CONTAINS;
503
504 return {
505 name: 'Perl',
506 aliases: [
507 'pl',
508 'pm'
509 ],
510 keywords: PERL_KEYWORDS,
511 contains: PERL_DEFAULT_CONTAINS
512 };
513}
514
515module.exports = perl;
Note: See TracBrowser for help on using the repository browser.