const MODES = (hljs) => { return { IMPORTANT: { scope: 'meta', begin: '!important' }, BLOCK_COMMENT: hljs.C_BLOCK_COMMENT_MODE, HEXCOLOR: { scope: 'number', begin: /#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/ }, FUNCTION_DISPATCH: { className: "built_in", begin: /[\w-]+(?=\()/ }, ATTRIBUTE_SELECTOR_MODE: { scope: 'selector-attr', begin: /\[/, end: /\]/, illegal: '$', contains: [ hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE ] }, CSS_NUMBER_MODE: { scope: 'number', begin: hljs.NUMBER_RE + '(' + '%|em|ex|ch|rem' + '|vw|vh|vmin|vmax' + '|cm|mm|in|pt|pc|px' + '|deg|grad|rad|turn' + '|s|ms' + '|Hz|kHz' + '|dpi|dpcm|dppx' + ')?', relevance: 0 }, CSS_VARIABLE: { className: "attr", begin: /--[A-Za-z][A-Za-z0-9_-]*/ } }; }; const TAGS = [ 'a', 'abbr', 'address', 'article', 'aside', 'audio', 'b', 'blockquote', 'body', 'button', 'canvas', 'caption', 'cite', 'code', 'dd', 'del', 'details', 'dfn', 'div', 'dl', 'dt', 'em', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'mark', 'menu', 'nav', 'object', 'ol', 'p', 'q', 'quote', 'samp', 'section', 'span', 'strong', 'summary', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'ul', 'var', 'video' ]; const MEDIA_FEATURES = [ 'any-hover', 'any-pointer', 'aspect-ratio', 'color', 'color-gamut', 'color-index', 'device-aspect-ratio', 'device-height', 'device-width', 'display-mode', 'forced-colors', 'grid', 'height', 'hover', 'inverted-colors', 'monochrome', 'orientation', 'overflow-block', 'overflow-inline', 'pointer', 'prefers-color-scheme', 'prefers-contrast', 'prefers-reduced-motion', 'prefers-reduced-transparency', 'resolution', 'scan', 'scripting', 'update', 'width', // TODO: find a better solution? 'min-width', 'max-width', 'min-height', 'max-height' ]; // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes const PSEUDO_CLASSES = [ 'active', 'any-link', 'blank', 'checked', 'current', 'default', 'defined', 'dir', // dir() 'disabled', 'drop', 'empty', 'enabled', 'first', 'first-child', 'first-of-type', 'fullscreen', 'future', 'focus', 'focus-visible', 'focus-within', 'has', // has() 'host', // host or host() 'host-context', // host-context() 'hover', 'indeterminate', 'in-range', 'invalid', 'is', // is() 'lang', // lang() 'last-child', 'last-of-type', 'left', 'link', 'local-link', 'not', // not() 'nth-child', // nth-child() 'nth-col', // nth-col() 'nth-last-child', // nth-last-child() 'nth-last-col', // nth-last-col() 'nth-last-of-type', //nth-last-of-type() 'nth-of-type', //nth-of-type() 'only-child', 'only-of-type', 'optional', 'out-of-range', 'past', 'placeholder-shown', 'read-only', 'read-write', 'required', 'right', 'root', 'scope', 'target', 'target-within', 'user-invalid', 'valid', 'visited', 'where' // where() ]; // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements const PSEUDO_ELEMENTS = [ 'after', 'backdrop', 'before', 'cue', 'cue-region', 'first-letter', 'first-line', 'grammar-error', 'marker', 'part', 'placeholder', 'selection', 'slotted', 'spelling-error' ]; const ATTRIBUTES = [ 'align-content', 'align-items', 'align-self', 'all', 'animation', 'animation-delay', 'animation-direction', 'animation-duration', 'animation-fill-mode', 'animation-iteration-count', 'animation-name', 'animation-play-state', 'animation-timing-function', 'backface-visibility', 'background', 'background-attachment', 'background-blend-mode', 'background-clip', 'background-color', 'background-image', 'background-origin', 'background-position', 'background-repeat', 'background-size', 'block-size', 'border', 'border-block', 'border-block-color', 'border-block-end', 'border-block-end-color', 'border-block-end-style', 'border-block-end-width', 'border-block-start', 'border-block-start-color', 'border-block-start-style', 'border-block-start-width', 'border-block-style', 'border-block-width', 'border-bottom', 'border-bottom-color', 'border-bottom-left-radius', 'border-bottom-right-radius', 'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-image', 'border-image-outset', 'border-image-repeat', 'border-image-slice', 'border-image-source', 'border-image-width', 'border-inline', 'border-inline-color', 'border-inline-end', 'border-inline-end-color', 'border-inline-end-style', 'border-inline-end-width', 'border-inline-start', 'border-inline-start-color', 'border-inline-start-style', 'border-inline-start-width', 'border-inline-style', 'border-inline-width', 'border-left', 'border-left-color', 'border-left-style', 'border-left-width', 'border-radius', 'border-right', 'border-right-color', 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top', 'border-top-color', 'border-top-left-radius', 'border-top-right-radius', 'border-top-style', 'border-top-width', 'border-width', 'bottom', 'box-decoration-break', 'box-shadow', 'box-sizing', 'break-after', 'break-before', 'break-inside', 'caption-side', 'caret-color', 'clear', 'clip', 'clip-path', 'clip-rule', 'color', 'column-count', 'column-fill', 'column-gap', 'column-rule', 'column-rule-color', 'column-rule-style', 'column-rule-width', 'column-span', 'column-width', 'columns', 'contain', 'content', 'content-visibility', 'counter-increment', 'counter-reset', 'cue', 'cue-after', 'cue-before', 'cursor', 'direction', 'display', 'empty-cells', 'filter', 'flex', 'flex-basis', 'flex-direction', 'flex-flow', 'flex-grow', 'flex-shrink', 'flex-wrap', 'float', 'flow', 'font', 'font-display', 'font-family', 'font-feature-settings', 'font-kerning', 'font-language-override', 'font-size', 'font-size-adjust', 'font-smoothing', 'font-stretch', 'font-style', 'font-synthesis', 'font-variant', 'font-variant-caps', 'font-variant-east-asian', 'font-variant-ligatures', 'font-variant-numeric', 'font-variant-position', 'font-variation-settings', 'font-weight', 'gap', 'glyph-orientation-vertical', 'grid', 'grid-area', 'grid-auto-columns', 'grid-auto-flow', 'grid-auto-rows', 'grid-column', 'grid-column-end', 'grid-column-start', 'grid-gap', 'grid-row', 'grid-row-end', 'grid-row-start', 'grid-template', 'grid-template-areas', 'grid-template-columns', 'grid-template-rows', 'hanging-punctuation', 'height', 'hyphens', 'icon', 'image-orientation', 'image-rendering', 'image-resolution', 'ime-mode', 'inline-size', 'isolation', 'justify-content', 'left', 'letter-spacing', 'line-break', 'line-height', 'list-style', 'list-style-image', 'list-style-position', 'list-style-type', 'margin', 'margin-block', 'margin-block-end', 'margin-block-start', 'margin-bottom', 'margin-inline', 'margin-inline-end', 'margin-inline-start', 'margin-left', 'margin-right', 'margin-top', 'marks', 'mask', 'mask-border', 'mask-border-mode', 'mask-border-outset', 'mask-border-repeat', 'mask-border-slice', 'mask-border-source', 'mask-border-width', 'mask-clip', 'mask-composite', 'mask-image', 'mask-mode', 'mask-origin', 'mask-position', 'mask-repeat', 'mask-size', 'mask-type', 'max-block-size', 'max-height', 'max-inline-size', 'max-width', 'min-block-size', 'min-height', 'min-inline-size', 'min-width', 'mix-blend-mode', 'nav-down', 'nav-index', 'nav-left', 'nav-right', 'nav-up', 'none', 'normal', 'object-fit', 'object-position', 'opacity', 'order', 'orphans', 'outline', 'outline-color', 'outline-offset', 'outline-style', 'outline-width', 'overflow', 'overflow-wrap', 'overflow-x', 'overflow-y', 'padding', 'padding-block', 'padding-block-end', 'padding-block-start', 'padding-bottom', 'padding-inline', 'padding-inline-end', 'padding-inline-start', 'padding-left', 'padding-right', 'padding-top', 'page-break-after', 'page-break-before', 'page-break-inside', 'pause', 'pause-after', 'pause-before', 'perspective', 'perspective-origin', 'pointer-events', 'position', 'quotes', 'resize', 'rest', 'rest-after', 'rest-before', 'right', 'row-gap', 'scroll-margin', 'scroll-margin-block', 'scroll-margin-block-end', 'scroll-margin-block-start', 'scroll-margin-bottom', 'scroll-margin-inline', 'scroll-margin-inline-end', 'scroll-margin-inline-start', 'scroll-margin-left', 'scroll-margin-right', 'scroll-margin-top', 'scroll-padding', 'scroll-padding-block', 'scroll-padding-block-end', 'scroll-padding-block-start', 'scroll-padding-bottom', 'scroll-padding-inline', 'scroll-padding-inline-end', 'scroll-padding-inline-start', 'scroll-padding-left', 'scroll-padding-right', 'scroll-padding-top', 'scroll-snap-align', 'scroll-snap-stop', 'scroll-snap-type', 'scrollbar-color', 'scrollbar-gutter', 'scrollbar-width', 'shape-image-threshold', 'shape-margin', 'shape-outside', 'speak', 'speak-as', 'src', // @font-face 'tab-size', 'table-layout', 'text-align', 'text-align-all', 'text-align-last', 'text-combine-upright', 'text-decoration', 'text-decoration-color', 'text-decoration-line', 'text-decoration-style', 'text-emphasis', 'text-emphasis-color', 'text-emphasis-position', 'text-emphasis-style', 'text-indent', 'text-justify', 'text-orientation', 'text-overflow', 'text-rendering', 'text-shadow', 'text-transform', 'text-underline-position', 'top', 'transform', 'transform-box', 'transform-origin', 'transform-style', 'transition', 'transition-delay', 'transition-duration', 'transition-property', 'transition-timing-function', 'unicode-bidi', 'vertical-align', 'visibility', 'voice-balance', 'voice-duration', 'voice-family', 'voice-pitch', 'voice-range', 'voice-rate', 'voice-stress', 'voice-volume', 'white-space', 'widows', 'width', 'will-change', 'word-break', 'word-spacing', 'word-wrap', 'writing-mode', 'z-index' // reverse makes sure longer attributes `font-weight` are matched fully // instead of getting false positives on say `font` ].reverse(); /* Language: Stylus Author: Bryant Williams Description: Stylus is an expressive, robust, feature-rich CSS language built for nodejs. Website: https://github.com/stylus/stylus Category: css, web */ /** @type LanguageFn */ function stylus(hljs) { const modes = MODES(hljs); const AT_MODIFIERS = "and or not only"; const VARIABLE = { className: 'variable', begin: '\\$' + hljs.IDENT_RE }; const AT_KEYWORDS = [ 'charset', 'css', 'debug', 'extend', 'font-face', 'for', 'import', 'include', 'keyframes', 'media', 'mixin', 'page', 'warn', 'while' ]; const LOOKAHEAD_TAG_END = '(?=[.\\s\\n[:,(])'; // illegals const ILLEGAL = [ '\\?', '(\\bReturn\\b)', // monkey '(\\bEnd\\b)', // monkey '(\\bend\\b)', // vbscript '(\\bdef\\b)', // gradle ';', // a whole lot of languages '#\\s', // markdown '\\*\\s', // markdown '===\\s', // markdown '\\|', '%' // prolog ]; return { name: 'Stylus', aliases: [ 'styl' ], case_insensitive: false, keywords: 'if else for in', illegal: '(' + ILLEGAL.join('|') + ')', contains: [ // strings hljs.QUOTE_STRING_MODE, hljs.APOS_STRING_MODE, // comments hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE, // hex colors modes.HEXCOLOR, // class tag { begin: '\\.[a-zA-Z][a-zA-Z0-9_-]*' + LOOKAHEAD_TAG_END, className: 'selector-class' }, // id tag { begin: '#[a-zA-Z][a-zA-Z0-9_-]*' + LOOKAHEAD_TAG_END, className: 'selector-id' }, // tags { begin: '\\b(' + TAGS.join('|') + ')' + LOOKAHEAD_TAG_END, className: 'selector-tag' }, // psuedo selectors { className: 'selector-pseudo', begin: '&?:(' + PSEUDO_CLASSES.join('|') + ')' + LOOKAHEAD_TAG_END }, { className: 'selector-pseudo', begin: '&?:(:)?(' + PSEUDO_ELEMENTS.join('|') + ')' + LOOKAHEAD_TAG_END }, modes.ATTRIBUTE_SELECTOR_MODE, { className: "keyword", begin: /@media/, starts: { end: /[{;}]/, keywords: { $pattern: /[a-z-]+/, keyword: AT_MODIFIERS, attribute: MEDIA_FEATURES.join(" ") }, contains: [ modes.CSS_NUMBER_MODE ] } }, // @ keywords { className: 'keyword', begin: '\@((-(o|moz|ms|webkit)-)?(' + AT_KEYWORDS.join('|') + '))\\b' }, // variables VARIABLE, // dimension modes.CSS_NUMBER_MODE, // functions // - only from beginning of line + whitespace { className: 'function', begin: '^[a-zA-Z][a-zA-Z0-9_\-]*\\(.*\\)', illegal: '[\\n]', returnBegin: true, contains: [ { className: 'title', begin: '\\b[a-zA-Z][a-zA-Z0-9_\-]*' }, { className: 'params', begin: /\(/, end: /\)/, contains: [ modes.HEXCOLOR, VARIABLE, hljs.APOS_STRING_MODE, modes.CSS_NUMBER_MODE, hljs.QUOTE_STRING_MODE ] } ] }, // css variables modes.CSS_VARIABLE, // attributes // - only from beginning of line + whitespace // - must have whitespace after it { className: 'attribute', begin: '\\b(' + ATTRIBUTES.join('|') + ')\\b', starts: { // value container end: /;|$/, contains: [ modes.HEXCOLOR, VARIABLE, hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE, modes.CSS_NUMBER_MODE, hljs.C_BLOCK_COMMENT_MODE, modes.IMPORTANT, modes.FUNCTION_DISPATCH ], illegal: /\./, relevance: 0 } }, modes.FUNCTION_DISPATCH ] }; } module.exports = stylus;