source: node_modules/highlight.js/lib/languages/less.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: 13.3 KB
RevLine 
[d24f17c]1const MODES = (hljs) => {
2 return {
3 IMPORTANT: {
4 className: 'meta',
5 begin: '!important'
6 },
7 HEXCOLOR: {
8 className: 'number',
9 begin: '#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})'
10 },
11 ATTRIBUTE_SELECTOR_MODE: {
12 className: 'selector-attr',
13 begin: /\[/,
14 end: /\]/,
15 illegal: '$',
16 contains: [
17 hljs.APOS_STRING_MODE,
18 hljs.QUOTE_STRING_MODE
19 ]
20 }
21 };
22};
23
24const TAGS = [
25 'a',
26 'abbr',
27 'address',
28 'article',
29 'aside',
30 'audio',
31 'b',
32 'blockquote',
33 'body',
34 'button',
35 'canvas',
36 'caption',
37 'cite',
38 'code',
39 'dd',
40 'del',
41 'details',
42 'dfn',
43 'div',
44 'dl',
45 'dt',
46 'em',
47 'fieldset',
48 'figcaption',
49 'figure',
50 'footer',
51 'form',
52 'h1',
53 'h2',
54 'h3',
55 'h4',
56 'h5',
57 'h6',
58 'header',
59 'hgroup',
60 'html',
61 'i',
62 'iframe',
63 'img',
64 'input',
65 'ins',
66 'kbd',
67 'label',
68 'legend',
69 'li',
70 'main',
71 'mark',
72 'menu',
73 'nav',
74 'object',
75 'ol',
76 'p',
77 'q',
78 'quote',
79 'samp',
80 'section',
81 'span',
82 'strong',
83 'summary',
84 'sup',
85 'table',
86 'tbody',
87 'td',
88 'textarea',
89 'tfoot',
90 'th',
91 'thead',
92 'time',
93 'tr',
94 'ul',
95 'var',
96 'video'
97];
98
99const MEDIA_FEATURES = [
100 'any-hover',
101 'any-pointer',
102 'aspect-ratio',
103 'color',
104 'color-gamut',
105 'color-index',
106 'device-aspect-ratio',
107 'device-height',
108 'device-width',
109 'display-mode',
110 'forced-colors',
111 'grid',
112 'height',
113 'hover',
114 'inverted-colors',
115 'monochrome',
116 'orientation',
117 'overflow-block',
118 'overflow-inline',
119 'pointer',
120 'prefers-color-scheme',
121 'prefers-contrast',
122 'prefers-reduced-motion',
123 'prefers-reduced-transparency',
124 'resolution',
125 'scan',
126 'scripting',
127 'update',
128 'width',
129 // TODO: find a better solution?
130 'min-width',
131 'max-width',
132 'min-height',
133 'max-height'
134];
135
136// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
137const PSEUDO_CLASSES = [
138 'active',
139 'any-link',
140 'blank',
141 'checked',
142 'current',
143 'default',
144 'defined',
145 'dir', // dir()
146 'disabled',
147 'drop',
148 'empty',
149 'enabled',
150 'first',
151 'first-child',
152 'first-of-type',
153 'fullscreen',
154 'future',
155 'focus',
156 'focus-visible',
157 'focus-within',
158 'has', // has()
159 'host', // host or host()
160 'host-context', // host-context()
161 'hover',
162 'indeterminate',
163 'in-range',
164 'invalid',
165 'is', // is()
166 'lang', // lang()
167 'last-child',
168 'last-of-type',
169 'left',
170 'link',
171 'local-link',
172 'not', // not()
173 'nth-child', // nth-child()
174 'nth-col', // nth-col()
175 'nth-last-child', // nth-last-child()
176 'nth-last-col', // nth-last-col()
177 'nth-last-of-type', //nth-last-of-type()
178 'nth-of-type', //nth-of-type()
179 'only-child',
180 'only-of-type',
181 'optional',
182 'out-of-range',
183 'past',
184 'placeholder-shown',
185 'read-only',
186 'read-write',
187 'required',
188 'right',
189 'root',
190 'scope',
191 'target',
192 'target-within',
193 'user-invalid',
194 'valid',
195 'visited',
196 'where' // where()
197];
198
199// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements
200const PSEUDO_ELEMENTS = [
201 'after',
202 'backdrop',
203 'before',
204 'cue',
205 'cue-region',
206 'first-letter',
207 'first-line',
208 'grammar-error',
209 'marker',
210 'part',
211 'placeholder',
212 'selection',
213 'slotted',
214 'spelling-error'
215];
216
217const ATTRIBUTES = [
218 'align-content',
219 'align-items',
220 'align-self',
221 'animation',
222 'animation-delay',
223 'animation-direction',
224 'animation-duration',
225 'animation-fill-mode',
226 'animation-iteration-count',
227 'animation-name',
228 'animation-play-state',
229 'animation-timing-function',
230 'auto',
231 'backface-visibility',
232 'background',
233 'background-attachment',
234 'background-clip',
235 'background-color',
236 'background-image',
237 'background-origin',
238 'background-position',
239 'background-repeat',
240 'background-size',
241 'border',
242 'border-bottom',
243 'border-bottom-color',
244 'border-bottom-left-radius',
245 'border-bottom-right-radius',
246 'border-bottom-style',
247 'border-bottom-width',
248 'border-collapse',
249 'border-color',
250 'border-image',
251 'border-image-outset',
252 'border-image-repeat',
253 'border-image-slice',
254 'border-image-source',
255 'border-image-width',
256 'border-left',
257 'border-left-color',
258 'border-left-style',
259 'border-left-width',
260 'border-radius',
261 'border-right',
262 'border-right-color',
263 'border-right-style',
264 'border-right-width',
265 'border-spacing',
266 'border-style',
267 'border-top',
268 'border-top-color',
269 'border-top-left-radius',
270 'border-top-right-radius',
271 'border-top-style',
272 'border-top-width',
273 'border-width',
274 'bottom',
275 'box-decoration-break',
276 'box-shadow',
277 'box-sizing',
278 'break-after',
279 'break-before',
280 'break-inside',
281 'caption-side',
282 'clear',
283 'clip',
284 'clip-path',
285 'color',
286 'column-count',
287 'column-fill',
288 'column-gap',
289 'column-rule',
290 'column-rule-color',
291 'column-rule-style',
292 'column-rule-width',
293 'column-span',
294 'column-width',
295 'columns',
296 'content',
297 'counter-increment',
298 'counter-reset',
299 'cursor',
300 'direction',
301 'display',
302 'empty-cells',
303 'filter',
304 'flex',
305 'flex-basis',
306 'flex-direction',
307 'flex-flow',
308 'flex-grow',
309 'flex-shrink',
310 'flex-wrap',
311 'float',
312 'font',
313 'font-display',
314 'font-family',
315 'font-feature-settings',
316 'font-kerning',
317 'font-language-override',
318 'font-size',
319 'font-size-adjust',
320 'font-smoothing',
321 'font-stretch',
322 'font-style',
323 'font-variant',
324 'font-variant-ligatures',
325 'font-variation-settings',
326 'font-weight',
327 'height',
328 'hyphens',
329 'icon',
330 'image-orientation',
331 'image-rendering',
332 'image-resolution',
333 'ime-mode',
334 'inherit',
335 'initial',
336 'justify-content',
337 'left',
338 'letter-spacing',
339 'line-height',
340 'list-style',
341 'list-style-image',
342 'list-style-position',
343 'list-style-type',
344 'margin',
345 'margin-bottom',
346 'margin-left',
347 'margin-right',
348 'margin-top',
349 'marks',
350 'mask',
351 'max-height',
352 'max-width',
353 'min-height',
354 'min-width',
355 'nav-down',
356 'nav-index',
357 'nav-left',
358 'nav-right',
359 'nav-up',
360 'none',
361 'normal',
362 'object-fit',
363 'object-position',
364 'opacity',
365 'order',
366 'orphans',
367 'outline',
368 'outline-color',
369 'outline-offset',
370 'outline-style',
371 'outline-width',
372 'overflow',
373 'overflow-wrap',
374 'overflow-x',
375 'overflow-y',
376 'padding',
377 'padding-bottom',
378 'padding-left',
379 'padding-right',
380 'padding-top',
381 'page-break-after',
382 'page-break-before',
383 'page-break-inside',
384 'perspective',
385 'perspective-origin',
386 'pointer-events',
387 'position',
388 'quotes',
389 'resize',
390 'right',
391 'src', // @font-face
392 'tab-size',
393 'table-layout',
394 'text-align',
395 'text-align-last',
396 'text-decoration',
397 'text-decoration-color',
398 'text-decoration-line',
399 'text-decoration-style',
400 'text-indent',
401 'text-overflow',
402 'text-rendering',
403 'text-shadow',
404 'text-transform',
405 'text-underline-position',
406 'top',
407 'transform',
408 'transform-origin',
409 'transform-style',
410 'transition',
411 'transition-delay',
412 'transition-duration',
413 'transition-property',
414 'transition-timing-function',
415 'unicode-bidi',
416 'vertical-align',
417 'visibility',
418 'white-space',
419 'widows',
420 'width',
421 'word-break',
422 'word-spacing',
423 'word-wrap',
424 'z-index'
425 // reverse makes sure longer attributes `font-weight` are matched fully
426 // instead of getting false positives on say `font`
427].reverse();
428
429// some grammars use them all as a single group
430const PSEUDO_SELECTORS = PSEUDO_CLASSES.concat(PSEUDO_ELEMENTS);
431
432/*
433Language: Less
434Description: It's CSS, with just a little more.
435Author: Max Mikhailov <seven.phases.max@gmail.com>
436Website: http://lesscss.org
437Category: common, css
438*/
439
440/** @type LanguageFn */
441function less(hljs) {
442 const modes = MODES(hljs);
443 const PSEUDO_SELECTORS$1 = PSEUDO_SELECTORS;
444
445 const AT_MODIFIERS = "and or not only";
446 const IDENT_RE = '[\\w-]+'; // yes, Less identifiers may begin with a digit
447 const INTERP_IDENT_RE = '(' + IDENT_RE + '|@\\{' + IDENT_RE + '\\})';
448
449 /* Generic Modes */
450
451 const RULES = []; const VALUE_MODES = []; // forward def. for recursive modes
452
453 const STRING_MODE = function(c) {
454 return {
455 // Less strings are not multiline (also include '~' for more consistent coloring of "escaped" strings)
456 className: 'string',
457 begin: '~?' + c + '.*?' + c
458 };
459 };
460
461 const IDENT_MODE = function(name, begin, relevance) {
462 return {
463 className: name,
464 begin: begin,
465 relevance: relevance
466 };
467 };
468
469 const AT_KEYWORDS = {
470 $pattern: /[a-z-]+/,
471 keyword: AT_MODIFIERS,
472 attribute: MEDIA_FEATURES.join(" ")
473 };
474
475 const PARENS_MODE = {
476 // used only to properly balance nested parens inside mixin call, def. arg list
477 begin: '\\(',
478 end: '\\)',
479 contains: VALUE_MODES,
480 keywords: AT_KEYWORDS,
481 relevance: 0
482 };
483
484 // generic Less highlighter (used almost everywhere except selectors):
485 VALUE_MODES.push(
486 hljs.C_LINE_COMMENT_MODE,
487 hljs.C_BLOCK_COMMENT_MODE,
488 STRING_MODE("'"),
489 STRING_MODE('"'),
490 hljs.CSS_NUMBER_MODE, // fixme: it does not include dot for numbers like .5em :(
491 {
492 begin: '(url|data-uri)\\(',
493 starts: {
494 className: 'string',
495 end: '[\\)\\n]',
496 excludeEnd: true
497 }
498 },
499 modes.HEXCOLOR,
500 PARENS_MODE,
501 IDENT_MODE('variable', '@@?' + IDENT_RE, 10),
502 IDENT_MODE('variable', '@\\{' + IDENT_RE + '\\}'),
503 IDENT_MODE('built_in', '~?`[^`]*?`'), // inline javascript (or whatever host language) *multiline* string
504 { // @media features (it’s here to not duplicate things in AT_RULE_MODE with extra PARENS_MODE overriding):
505 className: 'attribute',
506 begin: IDENT_RE + '\\s*:',
507 end: ':',
508 returnBegin: true,
509 excludeEnd: true
510 },
511 modes.IMPORTANT
512 );
513
514 const VALUE_WITH_RULESETS = VALUE_MODES.concat({
515 begin: /\{/,
516 end: /\}/,
517 contains: RULES
518 });
519
520 const MIXIN_GUARD_MODE = {
521 beginKeywords: 'when',
522 endsWithParent: true,
523 contains: [
524 {
525 beginKeywords: 'and not'
526 }
527 ].concat(VALUE_MODES) // using this form to override VALUE’s 'function' match
528 };
529
530 /* Rule-Level Modes */
531
532 const RULE_MODE = {
533 begin: INTERP_IDENT_RE + '\\s*:',
534 returnBegin: true,
535 end: /[;}]/,
536 relevance: 0,
537 contains: [
538 {
539 begin: /-(webkit|moz|ms|o)-/
540 },
541 {
542 className: 'attribute',
543 begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b',
544 end: /(?=:)/,
545 starts: {
546 endsWithParent: true,
547 illegal: '[<=$]',
548 relevance: 0,
549 contains: VALUE_MODES
550 }
551 }
552 ]
553 };
554
555 const AT_RULE_MODE = {
556 className: 'keyword',
557 begin: '@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b',
558 starts: {
559 end: '[;{}]',
560 keywords: AT_KEYWORDS,
561 returnEnd: true,
562 contains: VALUE_MODES,
563 relevance: 0
564 }
565 };
566
567 // variable definitions and calls
568 const VAR_RULE_MODE = {
569 className: 'variable',
570 variants: [
571 // using more strict pattern for higher relevance to increase chances of Less detection.
572 // this is *the only* Less specific statement used in most of the sources, so...
573 // (we’ll still often loose to the css-parser unless there's '//' comment,
574 // simply because 1 variable just can't beat 99 properties :)
575 {
576 begin: '@' + IDENT_RE + '\\s*:',
577 relevance: 15
578 },
579 {
580 begin: '@' + IDENT_RE
581 }
582 ],
583 starts: {
584 end: '[;}]',
585 returnEnd: true,
586 contains: VALUE_WITH_RULESETS
587 }
588 };
589
590 const SELECTOR_MODE = {
591 // first parse unambiguous selectors (i.e. those not starting with tag)
592 // then fall into the scary lookahead-discriminator variant.
593 // this mode also handles mixin definitions and calls
594 variants: [
595 {
596 begin: '[\\.#:&\\[>]',
597 end: '[;{}]' // mixin calls end with ';'
598 },
599 {
600 begin: INTERP_IDENT_RE,
601 end: /\{/
602 }
603 ],
604 returnBegin: true,
605 returnEnd: true,
606 illegal: '[<=\'$"]',
607 relevance: 0,
608 contains: [
609 hljs.C_LINE_COMMENT_MODE,
610 hljs.C_BLOCK_COMMENT_MODE,
611 MIXIN_GUARD_MODE,
612 IDENT_MODE('keyword', 'all\\b'),
613 IDENT_MODE('variable', '@\\{' + IDENT_RE + '\\}'), // otherwise it’s identified as tag
614 {
615 begin: '\\b(' + TAGS.join('|') + ')\\b',
616 className: 'selector-tag'
617 },
618 IDENT_MODE('selector-tag', INTERP_IDENT_RE + '%?', 0), // '%' for more consistent coloring of @keyframes "tags"
619 IDENT_MODE('selector-id', '#' + INTERP_IDENT_RE),
620 IDENT_MODE('selector-class', '\\.' + INTERP_IDENT_RE, 0),
621 IDENT_MODE('selector-tag', '&', 0),
622 modes.ATTRIBUTE_SELECTOR_MODE,
623 {
624 className: 'selector-pseudo',
625 begin: ':(' + PSEUDO_CLASSES.join('|') + ')'
626 },
627 {
628 className: 'selector-pseudo',
629 begin: '::(' + PSEUDO_ELEMENTS.join('|') + ')'
630 },
631 {
632 begin: '\\(',
633 end: '\\)',
634 contains: VALUE_WITH_RULESETS
635 }, // argument list of parametric mixins
636 {
637 begin: '!important'
638 } // eat !important after mixin call or it will be colored as tag
639 ]
640 };
641
642 const PSEUDO_SELECTOR_MODE = {
643 begin: IDENT_RE + ':(:)?' + `(${PSEUDO_SELECTORS$1.join('|')})`,
644 returnBegin: true,
645 contains: [ SELECTOR_MODE ]
646 };
647
648 RULES.push(
649 hljs.C_LINE_COMMENT_MODE,
650 hljs.C_BLOCK_COMMENT_MODE,
651 AT_RULE_MODE,
652 VAR_RULE_MODE,
653 PSEUDO_SELECTOR_MODE,
654 RULE_MODE,
655 SELECTOR_MODE
656 );
657
658 return {
659 name: 'Less',
660 case_insensitive: true,
661 illegal: '[=>\'/<($"]',
662 contains: RULES
663 };
664}
665
666module.exports = less;
Note: See TracBrowser for help on using the repository browser.