UNPKG

14 kBJavaScriptView Raw
1const MODES = (hljs) => {
2 return {
3 IMPORTANT: {
4 scope: 'meta',
5 begin: '!important'
6 },
7 BLOCK_COMMENT: hljs.C_BLOCK_COMMENT_MODE,
8 HEXCOLOR: {
9 scope: 'number',
10 begin: /#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/
11 },
12 FUNCTION_DISPATCH: {
13 className: "built_in",
14 begin: /[\w-]+(?=\()/
15 },
16 ATTRIBUTE_SELECTOR_MODE: {
17 scope: 'selector-attr',
18 begin: /\[/,
19 end: /\]/,
20 illegal: '$',
21 contains: [
22 hljs.APOS_STRING_MODE,
23 hljs.QUOTE_STRING_MODE
24 ]
25 },
26 CSS_NUMBER_MODE: {
27 scope: 'number',
28 begin: hljs.NUMBER_RE + '(' +
29 '%|em|ex|ch|rem' +
30 '|vw|vh|vmin|vmax' +
31 '|cm|mm|in|pt|pc|px' +
32 '|deg|grad|rad|turn' +
33 '|s|ms' +
34 '|Hz|kHz' +
35 '|dpi|dpcm|dppx' +
36 ')?',
37 relevance: 0
38 },
39 CSS_VARIABLE: {
40 className: "attr",
41 begin: /--[A-Za-z][A-Za-z0-9_-]*/
42 }
43 };
44};
45
46const TAGS = [
47 'a',
48 'abbr',
49 'address',
50 'article',
51 'aside',
52 'audio',
53 'b',
54 'blockquote',
55 'body',
56 'button',
57 'canvas',
58 'caption',
59 'cite',
60 'code',
61 'dd',
62 'del',
63 'details',
64 'dfn',
65 'div',
66 'dl',
67 'dt',
68 'em',
69 'fieldset',
70 'figcaption',
71 'figure',
72 'footer',
73 'form',
74 'h1',
75 'h2',
76 'h3',
77 'h4',
78 'h5',
79 'h6',
80 'header',
81 'hgroup',
82 'html',
83 'i',
84 'iframe',
85 'img',
86 'input',
87 'ins',
88 'kbd',
89 'label',
90 'legend',
91 'li',
92 'main',
93 'mark',
94 'menu',
95 'nav',
96 'object',
97 'ol',
98 'p',
99 'q',
100 'quote',
101 'samp',
102 'section',
103 'span',
104 'strong',
105 'summary',
106 'sup',
107 'table',
108 'tbody',
109 'td',
110 'textarea',
111 'tfoot',
112 'th',
113 'thead',
114 'time',
115 'tr',
116 'ul',
117 'var',
118 'video'
119];
120
121const MEDIA_FEATURES = [
122 'any-hover',
123 'any-pointer',
124 'aspect-ratio',
125 'color',
126 'color-gamut',
127 'color-index',
128 'device-aspect-ratio',
129 'device-height',
130 'device-width',
131 'display-mode',
132 'forced-colors',
133 'grid',
134 'height',
135 'hover',
136 'inverted-colors',
137 'monochrome',
138 'orientation',
139 'overflow-block',
140 'overflow-inline',
141 'pointer',
142 'prefers-color-scheme',
143 'prefers-contrast',
144 'prefers-reduced-motion',
145 'prefers-reduced-transparency',
146 'resolution',
147 'scan',
148 'scripting',
149 'update',
150 'width',
151 // TODO: find a better solution?
152 'min-width',
153 'max-width',
154 'min-height',
155 'max-height'
156];
157
158// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
159const PSEUDO_CLASSES = [
160 'active',
161 'any-link',
162 'blank',
163 'checked',
164 'current',
165 'default',
166 'defined',
167 'dir', // dir()
168 'disabled',
169 'drop',
170 'empty',
171 'enabled',
172 'first',
173 'first-child',
174 'first-of-type',
175 'fullscreen',
176 'future',
177 'focus',
178 'focus-visible',
179 'focus-within',
180 'has', // has()
181 'host', // host or host()
182 'host-context', // host-context()
183 'hover',
184 'indeterminate',
185 'in-range',
186 'invalid',
187 'is', // is()
188 'lang', // lang()
189 'last-child',
190 'last-of-type',
191 'left',
192 'link',
193 'local-link',
194 'not', // not()
195 'nth-child', // nth-child()
196 'nth-col', // nth-col()
197 'nth-last-child', // nth-last-child()
198 'nth-last-col', // nth-last-col()
199 'nth-last-of-type', //nth-last-of-type()
200 'nth-of-type', //nth-of-type()
201 'only-child',
202 'only-of-type',
203 'optional',
204 'out-of-range',
205 'past',
206 'placeholder-shown',
207 'read-only',
208 'read-write',
209 'required',
210 'right',
211 'root',
212 'scope',
213 'target',
214 'target-within',
215 'user-invalid',
216 'valid',
217 'visited',
218 'where' // where()
219];
220
221// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements
222const PSEUDO_ELEMENTS = [
223 'after',
224 'backdrop',
225 'before',
226 'cue',
227 'cue-region',
228 'first-letter',
229 'first-line',
230 'grammar-error',
231 'marker',
232 'part',
233 'placeholder',
234 'selection',
235 'slotted',
236 'spelling-error'
237];
238
239const ATTRIBUTES = [
240 'align-content',
241 'align-items',
242 'align-self',
243 'all',
244 'animation',
245 'animation-delay',
246 'animation-direction',
247 'animation-duration',
248 'animation-fill-mode',
249 'animation-iteration-count',
250 'animation-name',
251 'animation-play-state',
252 'animation-timing-function',
253 'backface-visibility',
254 'background',
255 'background-attachment',
256 'background-clip',
257 'background-color',
258 'background-image',
259 'background-origin',
260 'background-position',
261 'background-repeat',
262 'background-size',
263 'border',
264 'border-bottom',
265 'border-bottom-color',
266 'border-bottom-left-radius',
267 'border-bottom-right-radius',
268 'border-bottom-style',
269 'border-bottom-width',
270 'border-collapse',
271 'border-color',
272 'border-image',
273 'border-image-outset',
274 'border-image-repeat',
275 'border-image-slice',
276 'border-image-source',
277 'border-image-width',
278 'border-left',
279 'border-left-color',
280 'border-left-style',
281 'border-left-width',
282 'border-radius',
283 'border-right',
284 'border-right-color',
285 'border-right-style',
286 'border-right-width',
287 'border-spacing',
288 'border-style',
289 'border-top',
290 'border-top-color',
291 'border-top-left-radius',
292 'border-top-right-radius',
293 'border-top-style',
294 'border-top-width',
295 'border-width',
296 'bottom',
297 'box-decoration-break',
298 'box-shadow',
299 'box-sizing',
300 'break-after',
301 'break-before',
302 'break-inside',
303 'caption-side',
304 'caret-color',
305 'clear',
306 'clip',
307 'clip-path',
308 'clip-rule',
309 'color',
310 'column-count',
311 'column-fill',
312 'column-gap',
313 'column-rule',
314 'column-rule-color',
315 'column-rule-style',
316 'column-rule-width',
317 'column-span',
318 'column-width',
319 'columns',
320 'contain',
321 'content',
322 'content-visibility',
323 'counter-increment',
324 'counter-reset',
325 'cue',
326 'cue-after',
327 'cue-before',
328 'cursor',
329 'direction',
330 'display',
331 'empty-cells',
332 'filter',
333 'flex',
334 'flex-basis',
335 'flex-direction',
336 'flex-flow',
337 'flex-grow',
338 'flex-shrink',
339 'flex-wrap',
340 'float',
341 'flow',
342 'font',
343 'font-display',
344 'font-family',
345 'font-feature-settings',
346 'font-kerning',
347 'font-language-override',
348 'font-size',
349 'font-size-adjust',
350 'font-smoothing',
351 'font-stretch',
352 'font-style',
353 'font-synthesis',
354 'font-variant',
355 'font-variant-caps',
356 'font-variant-east-asian',
357 'font-variant-ligatures',
358 'font-variant-numeric',
359 'font-variant-position',
360 'font-variation-settings',
361 'font-weight',
362 'gap',
363 'glyph-orientation-vertical',
364 'grid',
365 'grid-area',
366 'grid-auto-columns',
367 'grid-auto-flow',
368 'grid-auto-rows',
369 'grid-column',
370 'grid-column-end',
371 'grid-column-start',
372 'grid-gap',
373 'grid-row',
374 'grid-row-end',
375 'grid-row-start',
376 'grid-template',
377 'grid-template-areas',
378 'grid-template-columns',
379 'grid-template-rows',
380 'hanging-punctuation',
381 'height',
382 'hyphens',
383 'icon',
384 'image-orientation',
385 'image-rendering',
386 'image-resolution',
387 'ime-mode',
388 'isolation',
389 'justify-content',
390 'left',
391 'letter-spacing',
392 'line-break',
393 'line-height',
394 'list-style',
395 'list-style-image',
396 'list-style-position',
397 'list-style-type',
398 'margin',
399 'margin-bottom',
400 'margin-left',
401 'margin-right',
402 'margin-top',
403 'marks',
404 'mask',
405 'mask-border',
406 'mask-border-mode',
407 'mask-border-outset',
408 'mask-border-repeat',
409 'mask-border-slice',
410 'mask-border-source',
411 'mask-border-width',
412 'mask-clip',
413 'mask-composite',
414 'mask-image',
415 'mask-mode',
416 'mask-origin',
417 'mask-position',
418 'mask-repeat',
419 'mask-size',
420 'mask-type',
421 'max-height',
422 'max-width',
423 'min-height',
424 'min-width',
425 'mix-blend-mode',
426 'nav-down',
427 'nav-index',
428 'nav-left',
429 'nav-right',
430 'nav-up',
431 'none',
432 'normal',
433 'object-fit',
434 'object-position',
435 'opacity',
436 'order',
437 'orphans',
438 'outline',
439 'outline-color',
440 'outline-offset',
441 'outline-style',
442 'outline-width',
443 'overflow',
444 'overflow-wrap',
445 'overflow-x',
446 'overflow-y',
447 'padding',
448 'padding-bottom',
449 'padding-left',
450 'padding-right',
451 'padding-top',
452 'page-break-after',
453 'page-break-before',
454 'page-break-inside',
455 'pause',
456 'pause-after',
457 'pause-before',
458 'perspective',
459 'perspective-origin',
460 'pointer-events',
461 'position',
462 'quotes',
463 'resize',
464 'rest',
465 'rest-after',
466 'rest-before',
467 'right',
468 'row-gap',
469 'scroll-margin',
470 'scroll-margin-block',
471 'scroll-margin-block-end',
472 'scroll-margin-block-start',
473 'scroll-margin-bottom',
474 'scroll-margin-inline',
475 'scroll-margin-inline-end',
476 'scroll-margin-inline-start',
477 'scroll-margin-left',
478 'scroll-margin-right',
479 'scroll-margin-top',
480 'scroll-padding',
481 'scroll-padding-block',
482 'scroll-padding-block-end',
483 'scroll-padding-block-start',
484 'scroll-padding-bottom',
485 'scroll-padding-inline',
486 'scroll-padding-inline-end',
487 'scroll-padding-inline-start',
488 'scroll-padding-left',
489 'scroll-padding-right',
490 'scroll-padding-top',
491 'scroll-snap-align',
492 'scroll-snap-stop',
493 'scroll-snap-type',
494 'shape-image-threshold',
495 'shape-margin',
496 'shape-outside',
497 'speak',
498 'speak-as',
499 'src', // @font-face
500 'tab-size',
501 'table-layout',
502 'text-align',
503 'text-align-all',
504 'text-align-last',
505 'text-combine-upright',
506 'text-decoration',
507 'text-decoration-color',
508 'text-decoration-line',
509 'text-decoration-style',
510 'text-emphasis',
511 'text-emphasis-color',
512 'text-emphasis-position',
513 'text-emphasis-style',
514 'text-indent',
515 'text-justify',
516 'text-orientation',
517 'text-overflow',
518 'text-rendering',
519 'text-shadow',
520 'text-transform',
521 'text-underline-position',
522 'top',
523 'transform',
524 'transform-box',
525 'transform-origin',
526 'transform-style',
527 'transition',
528 'transition-delay',
529 'transition-duration',
530 'transition-property',
531 'transition-timing-function',
532 'unicode-bidi',
533 'vertical-align',
534 'visibility',
535 'voice-balance',
536 'voice-duration',
537 'voice-family',
538 'voice-pitch',
539 'voice-range',
540 'voice-rate',
541 'voice-stress',
542 'voice-volume',
543 'white-space',
544 'widows',
545 'width',
546 'will-change',
547 'word-break',
548 'word-spacing',
549 'word-wrap',
550 'writing-mode',
551 'z-index'
552 // reverse makes sure longer attributes `font-weight` are matched fully
553 // instead of getting false positives on say `font`
554].reverse();
555
556/*
557Language: Stylus
558Author: Bryant Williams <b.n.williams@gmail.com>
559Description: Stylus is an expressive, robust, feature-rich CSS language built for nodejs.
560Website: https://github.com/stylus/stylus
561Category: css, web
562*/
563
564/** @type LanguageFn */
565function stylus(hljs) {
566 const modes = MODES(hljs);
567
568 const AT_MODIFIERS = "and or not only";
569 const VARIABLE = {
570 className: 'variable',
571 begin: '\\$' + hljs.IDENT_RE
572 };
573
574 const AT_KEYWORDS = [
575 'charset',
576 'css',
577 'debug',
578 'extend',
579 'font-face',
580 'for',
581 'import',
582 'include',
583 'keyframes',
584 'media',
585 'mixin',
586 'page',
587 'warn',
588 'while'
589 ];
590
591 const LOOKAHEAD_TAG_END = '(?=[.\\s\\n[:,(])';
592
593 // illegals
594 const ILLEGAL = [
595 '\\?',
596 '(\\bReturn\\b)', // monkey
597 '(\\bEnd\\b)', // monkey
598 '(\\bend\\b)', // vbscript
599 '(\\bdef\\b)', // gradle
600 ';', // a whole lot of languages
601 '#\\s', // markdown
602 '\\*\\s', // markdown
603 '===\\s', // markdown
604 '\\|',
605 '%' // prolog
606 ];
607
608 return {
609 name: 'Stylus',
610 aliases: [ 'styl' ],
611 case_insensitive: false,
612 keywords: 'if else for in',
613 illegal: '(' + ILLEGAL.join('|') + ')',
614 contains: [
615
616 // strings
617 hljs.QUOTE_STRING_MODE,
618 hljs.APOS_STRING_MODE,
619
620 // comments
621 hljs.C_LINE_COMMENT_MODE,
622 hljs.C_BLOCK_COMMENT_MODE,
623
624 // hex colors
625 modes.HEXCOLOR,
626
627 // class tag
628 {
629 begin: '\\.[a-zA-Z][a-zA-Z0-9_-]*' + LOOKAHEAD_TAG_END,
630 className: 'selector-class'
631 },
632
633 // id tag
634 {
635 begin: '#[a-zA-Z][a-zA-Z0-9_-]*' + LOOKAHEAD_TAG_END,
636 className: 'selector-id'
637 },
638
639 // tags
640 {
641 begin: '\\b(' + TAGS.join('|') + ')' + LOOKAHEAD_TAG_END,
642 className: 'selector-tag'
643 },
644
645 // psuedo selectors
646 {
647 className: 'selector-pseudo',
648 begin: '&?:(' + PSEUDO_CLASSES.join('|') + ')' + LOOKAHEAD_TAG_END
649 },
650 {
651 className: 'selector-pseudo',
652 begin: '&?:(:)?(' + PSEUDO_ELEMENTS.join('|') + ')' + LOOKAHEAD_TAG_END
653 },
654
655 modes.ATTRIBUTE_SELECTOR_MODE,
656
657 {
658 className: "keyword",
659 begin: /@media/,
660 starts: {
661 end: /[{;}]/,
662 keywords: {
663 $pattern: /[a-z-]+/,
664 keyword: AT_MODIFIERS,
665 attribute: MEDIA_FEATURES.join(" ")
666 },
667 contains: [ modes.CSS_NUMBER_MODE ]
668 }
669 },
670
671 // @ keywords
672 {
673 className: 'keyword',
674 begin: '\@((-(o|moz|ms|webkit)-)?(' + AT_KEYWORDS.join('|') + '))\\b'
675 },
676
677 // variables
678 VARIABLE,
679
680 // dimension
681 modes.CSS_NUMBER_MODE,
682
683 // functions
684 // - only from beginning of line + whitespace
685 {
686 className: 'function',
687 begin: '^[a-zA-Z][a-zA-Z0-9_\-]*\\(.*\\)',
688 illegal: '[\\n]',
689 returnBegin: true,
690 contains: [
691 {
692 className: 'title',
693 begin: '\\b[a-zA-Z][a-zA-Z0-9_\-]*'
694 },
695 {
696 className: 'params',
697 begin: /\(/,
698 end: /\)/,
699 contains: [
700 modes.HEXCOLOR,
701 VARIABLE,
702 hljs.APOS_STRING_MODE,
703 modes.CSS_NUMBER_MODE,
704 hljs.QUOTE_STRING_MODE
705 ]
706 }
707 ]
708 },
709
710 // css variables
711 modes.CSS_VARIABLE,
712
713 // attributes
714 // - only from beginning of line + whitespace
715 // - must have whitespace after it
716 {
717 className: 'attribute',
718 begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b',
719 starts: {
720 // value container
721 end: /;|$/,
722 contains: [
723 modes.HEXCOLOR,
724 VARIABLE,
725 hljs.APOS_STRING_MODE,
726 hljs.QUOTE_STRING_MODE,
727 modes.CSS_NUMBER_MODE,
728 hljs.C_BLOCK_COMMENT_MODE,
729 modes.IMPORTANT
730 ],
731 illegal: /\./,
732 relevance: 0
733 }
734 },
735 modes.FUNCTION_DISPATCH
736 ]
737 };
738}
739
740export { stylus as default };