From ca70a793ff39fe8ff58803d0b2eb419d1416aafa Mon Sep 17 00:00:00 2001 From: Arif Date: Sat, 27 Dec 2025 10:49:23 +0600 Subject: [PATCH 01/13] feat: enhance CSS parsing with modern features and improved regex patterns --- examples/languages/test.css | 414 ++++++++++++++++++++++++++++++++++-- src/languages/css.js | 55 ++--- 2 files changed, 427 insertions(+), 42 deletions(-) diff --git a/examples/languages/test.css b/examples/languages/test.css index a50982c..ce8dd27 100644 --- a/examples/languages/test.css +++ b/examples/languages/test.css @@ -1,20 +1,404 @@ -@import "my-styles.css"; +/* TODO Test Modern CSS Features */ +@charset "UTF-8"; -p > a, -.class, -#id { - color: blue; - text-decoration: underline; +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap"); +@import "animations.css" layer(animations); + +@layer reset, base, components, utilities; + +@namespace url(http://www.w3.org/1999/xhtml); +@namespace svg url(http://www.w3.org/2000/svg); + +@font-face { + font-family: "CustomFont"; + src: url("font.woff2") format("woff2"), + url("font.woff") format("woff"); + font-weight: 100 900; + font-display: swap; +} + +@property --gradient-angle { + syntax: ""; + initial-value: 0deg; + inherits: false; +} + +@property --my-color { + syntax: ""; + initial-value: #c0ffee; + inherits: true; +} + +@counter-style custom-counter { + system: cyclic; + symbols: ◉ ◌ ◎; + suffix: " "; +} + +:root { + --primary: oklch(0.7 0.2 200); + --secondary: color-mix(in oklch, var(--primary) 80%, white); + --spacing-xs: 0.25rem; + --spacing-sm: clamp(0.5rem, 2vw, 1rem); + --grid-gap: max(1rem, 2%); + --border-radius: round(up, 12px, 4px); +} + +@supports (container-type: inline-size) { + .card { + container-type: inline-size; + container-name: card; + } +} + +/* Nesting & Scoping */ +.container * { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); + gap: var(--grid-gap); + + & > .item { + background: light-dark(white, #1a1a1a); + padding: var(--spacing-sm); + border: 1px solid color-mix(in srgb, currentColor 20%, transparent); + + &:hover { + scale: 1.05; + rotate: 2deg; + translate: 0 -5px; + } + + &:has(> img) { + aspect-ratio: 16 / 9; + } + + @media (width >= 768px) { + padding: calc(var(--spacing-sm) * 2); + } + } +} + +/* Container Queries */ +@container card (min-width: 400px) { + .card-title { + font-size: clamp(1.5rem, 4cqw, 2.5rem); + } +} + +/* Advanced Selectors */ +:is(article, section, aside):has(> h2) { + margin-block: 2rem; +} + +:where(.button, .link):not(:disabled, [aria-disabled="true"]) { + cursor: pointer; + + &:focus-visible { + outline: 2px solid var(--primary); + outline-offset: 2px; + } +} + +/* Cascade Layers */ +@layer components { + .button { + all: unset; + padding: 0.5em 1em; + background: linear-gradient(135deg, var(--primary), var(--secondary)); + color: white; + border-radius: var(--border-radius); + + &[data-variant="ghost"] { + background: none; + color: var(--primary); + border: 1px solid currentColor; + } + } +} + +/* Complex Animations */ +@keyframes spin-colors { + from { + --gradient-angle: 0deg; + filter: hue-rotate(0deg); + } + to { + --gradient-angle: 360deg; + filter: hue-rotate(360deg); + } +} + +@keyframes slide-fade { + 0% { + opacity: 0; + translate: -100% 0; + } + 50% { + opacity: 0.5; + } + 100% { + opacity: 1; + translate: 0 0; + } +} + +/* Scroll-driven Animations */ +@supports (animation-timeline: scroll()) { + .parallax { + animation: parallax linear; + animation-timeline: scroll(); + } + + @keyframes parallax { + to { + translate: 0 -50%; + } + } +} + +/* View Transitions */ +@view-transition { + navigation: auto; +} + +::view-transition-old(root), +::view-transition-new(root) { + animation-duration: 0.3s; +} + +/* Complex Functions & Calculations */ +.complex-layout { + width: calc(100% - var(--spacing-sm) * 2); + height: max(50vh, 400px); + padding: clamp(1rem, 5vw, 3rem); + margin-inline: auto; + + background: + linear-gradient( + calc(var(--gradient-angle) + 45deg), + oklch(0.7 0.2 calc(var(--gradient-angle) * 1)), + oklch(0.5 0.3 calc(var(--gradient-angle) * 2)) + ); + + clip-path: polygon( + 0 0, + 100% 0, + 100% calc(100% - 2rem), + calc(100% - 2rem) 100%, + 0 100% + ); + + box-shadow: + 0 1px 2px hsl(0 0% 0% / 0.1), + 0 4px 8px hsl(0 0% 0% / 0.1), + 0 12px 24px hsl(0 0% 0% / 0.1); +} + +/* Subgrid */ +.grid-parent { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 1rem; + + & .grid-child { + display: grid; + grid-template-columns: subgrid; + grid-column: span 4; + } +} + +/* Logical Properties */ +.card { + padding-block: 2rem; + padding-inline: 1.5rem; + margin-block-end: var(--spacing-sm); + border-inline-start: 4px solid var(--primary); + inset-block-start: 0; + inset-inline-end: 0; } -/*TODO comment*/ -@page :left { - color: #2222; - margin-left: 4cm; - margin-right: 3cm; - background: url(test.jpg); - color: rgb(5, 5, 5); +/* Media Queries */ +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } } -@media print { - body { font-size: 10pt } + +@media (prefers-color-scheme: dark) { + :root { + --primary: oklch(0.8 0.2 200); + } +} + +@media (orientation: landscape) and (min-width: 1024px) { + .hero { + aspect-ratio: 21 / 9; + } +} + +@media (hover: hover) and (pointer: fine) { + .interactive:hover { + transform: scale(1.1) rotate(5deg); + } +} + +/* Custom Media Queries (future) */ +@custom-media --mobile (width < 768px); +@custom-media --desktop (width >= 1024px); + +/* Feature Queries */ +@supports (backdrop-filter: blur(10px)) { + .glass { + background: rgb(255 255 255 / 0.1); + backdrop-filter: blur(10px) saturate(180%); + -webkit-backdrop-filter: blur(10px) saturate(180%); + } +} + +@supports selector(:has(> img)) { + .card:has(img) { + padding: 0; + } +} + +/* Anchor Positioning */ +.tooltip { + position: absolute; + position-anchor: --trigger; + bottom: anchor(top); + left: anchor(center); + translate: -50% -8px; +} + +/* Advanced Pseudo-classes */ +input:user-invalid { + border-color: red; +} + +dialog:modal { + max-width: 90vw; + max-height: 90vh; +} + +:target-within { + background: color-mix(in srgb, yellow 20%, transparent); +} + +/* Color Functions */ +.color-demo { + background: oklch(0.7 0.2 200 / 0.8); + border-color: lch(50% 50 200); + color: lab(60% 40 30); + box-shadow: 0 4px 12px hwb(200 20% 20% / 0.5); + + &::before { + background: color-mix(in oklch, red 30%, blue); + } + + &::after { + background: color-contrast( + wheat vs tan, sienna, var(--primary), #d2691e + ); + } +} + +/* Relative Colors */ +.relative-colors { + --base: oklch(0.7 0.2 200); + background: oklch(from var(--base) calc(l * 0.8) c h); + border: 1px solid oklch(from var(--base) l calc(c * 1.5) h / 0.5); +} + +/* Math Functions */ +.math { + width: round(nearest, 34.6%, 10%); + height: mod(100vh, 50px); + padding: rem(18px, 16px); + gap: hypot(3em, 4em); + rotate: atan2(1, 1); +} + +/* Trigonometry */ +.trig { + transform: rotate(calc(sin(45deg) * 360deg)); + width: calc(cos(60deg) * 100%); + translate: calc(tan(30deg) * 1rem) 0; +} + +/* Advanced Grid */ +.masonry { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + grid-template-rows: masonry; + align-tracks: start; +} + +/* Scroll Snap */ +.carousel { + scroll-snap-type: x mandatory; + scroll-padding-inline: 1rem; + scrollbar-width: thin; + scrollbar-color: var(--primary) transparent; + overscroll-behavior-x: contain; + + & > * { + scroll-snap-align: start; + scroll-snap-stop: always; + } +} + +/* Text Styling */ +.text { + text-wrap: balance; + text-box-trim: both; + text-box-edge: cap alphabetic; + hanging-punctuation: first last; + initial-letter: 3 2; + + &::first-line { + font-variant: small-caps; + letter-spacing: 0.05em; + } +} + +/* Filters & Blend Modes */ +.effects { + filter: + blur(4px) + brightness(1.2) + contrast(1.1) + drop-shadow(0 4px 12px rgb(0 0 0 / 0.3)) + grayscale(0.2) + hue-rotate(45deg) + invert(0.1) + saturate(1.5); + + mix-blend-mode: multiply; + background-blend-mode: overlay, soft-light; +} + +/* Masks */ +.mask { + mask-image: + linear-gradient(to bottom, black 50%, transparent), + url("mask.svg"); + mask-composite: intersect; + mask-mode: alpha, luminance; + mask-size: 100% 100%, contain; +} + +/* Multiple Backgrounds */ +.multi-bg { + background: + url("pattern.svg") repeat, + linear-gradient(135deg, var(--primary), transparent), + radial-gradient(circle at 30% 50%, color-mix(in srgb, red 20%, transparent), transparent 70%), + conic-gradient(from 90deg at 50% 50%, red, yellow, green, cyan, blue, magenta, red); + background-size: 50px 50px, cover, cover, cover; + background-position: 0 0, center, center, center; + background-blend-mode: overlay, normal, screen, hue; } \ No newline at end of file diff --git a/src/languages/css.js b/src/languages/css.js index 1d6761c..679f535 100644 --- a/src/languages/css.js +++ b/src/languages/css.js @@ -1,56 +1,57 @@ export default [ { - match: /\/\*((?!\*\/)[^])*(\*\/)?/g, + match: /\/\*[\s\S]*?\*\/|\/\/.*/g, sub: 'todo' }, { expand: 'str' }, + { + match: /url\((?:(['"])(?:(?!\1).)*\1|[^)]*)\)/g, + sub: [ + { type: 'func', match: /^url/g }, + { type: 'str', match: /[^()]+/g } + ] + }, + { + type: 'type', + match: /@[\w-]+\b/g + }, { type: 'kwd', - match: /@\w+\b|\b(and|not|only|or)\b|\b[a-z-]+(?=[^{}]*{)/g + match: /!important\b/g }, { type: 'var', - match: /\b[\w-]+(?=\s*:)|(::?|\.)[\w-]+(?=[^{}]*{)/g + match: /--[\w-]+/g }, { - type: 'func', - match: /#[\w-]+(?=[^{}]*{)/g + type: 'var', + match: /[\w-]+(?=\s*(?::|<=|>=|<|>|=))/g }, { type: 'num', - match: /#[\da-f]{3,8}/g + match: /#[\da-fA-F]{3,8}\b/g }, { type: 'num', - match: /\d+(\.\d+)?(cm|mm|in|px|pt|pc|em|ex|ch|rem|vm|vh|vmin|vmax|%)?/g, - sub: [ - { - type: 'var', - match: /[a-z]+|%/g - } - ] + match: /-?(?:\d+\.?\d*|\.\d+)(?:(?:cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|deg|rad|grad|turn|s|ms|fr|dpi|dpcm|dppx|q|lh|rlh|vi|vb|cqw|cqh|cqi|cqb|cqmin|cqmax|dvw|dvh|lvw|lvh|svw|svh)\b|%(?!\w))/gi }, { - match: /url\([^)]*\)/g, - sub: [ - { - type: 'func', - match: /url(?=\()/g - }, - { - type: 'str', - match: /[^()]+/g - } - ] + type: 'num', + match: /-?(?:\d+\.?\d*|\.\d+)(?!\w)/g }, { type: 'func', - match: /\b[a-zA-Z]\w*(?=\s*\()/g + match: /[\w-]+(?=\()/g }, { - type: 'num', - match: /\b[a-z-]+\b/g + type: 'bool', + match: /\b(auto|inherit|initial|unset|revert|revert-layer|none|normal|all|both|transparent|currentColor|true|false|block|inline|flex|grid|subgrid|contents|table|list-item|run-in|ruby|flexbox|absolute|relative|fixed|sticky|static|left|right|top|bottom|center|middle|start|end|space-between|space-around|space-evenly|baseline|stretch|bold|bolder|lighter|italic|oblique|underline|overline|line-through|uppercase|lowercase|capitalize|pre|nowrap|wrap|break-word|clip|ellipsis|solid|dashed|dotted|double|groove|ridge|inset|outset|hidden|and|not|only|or|from|to)(?:-[\w-]+)?\b/g + }, + { + + type: 'type', + match: /(?:\.|#|::?)[a-zA-Z0-9_-]+|(? Date: Sat, 27 Dec 2025 19:43:58 +0600 Subject: [PATCH 02/13] Fix --- examples/languages/test.css | 6 +++--- src/languages/css.js | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/languages/test.css b/examples/languages/test.css index ce8dd27..bc74635 100644 --- a/examples/languages/test.css +++ b/examples/languages/test.css @@ -52,17 +52,17 @@ } /* Nesting & Scoping */ -.container * { +container h2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); gap: var(--grid-gap); - & > .item { + & > h2 { background: light-dark(white, #1a1a1a); padding: var(--spacing-sm); border: 1px solid color-mix(in srgb, currentColor 20%, transparent); - &:hover { + &:hover h2 { scale: 1.05; rotate: 2deg; translate: 0 -5px; diff --git a/src/languages/css.js b/src/languages/css.js index 679f535..317cac8 100644 --- a/src/languages/css.js +++ b/src/languages/css.js @@ -27,7 +27,7 @@ export default [ }, { type: 'var', - match: /[\w-]+(?=\s*(?::|<=|>=|<|>|=))/g + match: /[\w-]+(?=\s*:(?:\s|$))/g }, { type: 'num', @@ -50,8 +50,7 @@ export default [ match: /\b(auto|inherit|initial|unset|revert|revert-layer|none|normal|all|both|transparent|currentColor|true|false|block|inline|flex|grid|subgrid|contents|table|list-item|run-in|ruby|flexbox|absolute|relative|fixed|sticky|static|left|right|top|bottom|center|middle|start|end|space-between|space-around|space-evenly|baseline|stretch|bold|bolder|lighter|italic|oblique|underline|overline|line-through|uppercase|lowercase|capitalize|pre|nowrap|wrap|break-word|clip|ellipsis|solid|dashed|dotted|double|groove|ridge|inset|outset|hidden|and|not|only|or|from|to)(?:-[\w-]+)?\b/g }, { - type: 'type', - match: /(?:\.|#|::?)[a-zA-Z0-9_-]+|(? Date: Sat, 27 Dec 2025 22:12:35 +0600 Subject: [PATCH 03/13] Fix --- src/languages/css.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/languages/css.js b/src/languages/css.js index 317cac8..ebd074e 100644 --- a/src/languages/css.js +++ b/src/languages/css.js @@ -27,7 +27,7 @@ export default [ }, { type: 'var', - match: /[\w-]+(?=\s*:(?:\s|$))/g + match: /(?<=^[\s\t]*|[;{(]\s*|\*\/[\s\n\r]*)[\w-]+(?=\s*(?::(?:\s|\n|$|(?=.*[;}]))|<=|>=|<|>|=))/gm }, { type: 'num', @@ -47,10 +47,14 @@ export default [ }, { type: 'bool', - match: /\b(auto|inherit|initial|unset|revert|revert-layer|none|normal|all|both|transparent|currentColor|true|false|block|inline|flex|grid|subgrid|contents|table|list-item|run-in|ruby|flexbox|absolute|relative|fixed|sticky|static|left|right|top|bottom|center|middle|start|end|space-between|space-around|space-evenly|baseline|stretch|bold|bolder|lighter|italic|oblique|underline|overline|line-through|uppercase|lowercase|capitalize|pre|nowrap|wrap|break-word|clip|ellipsis|solid|dashed|dotted|double|groove|ridge|inset|outset|hidden|and|not|only|or|from|to)(?:-[\w-]+)?\b/g + match: /\b(in|from|to|at|vs|nearest|up|down|always|stable|both|none|auto|inherit|initial|unset|revert|normal|all|transparent|currentColor|true|false|block|inline|flex|grid|subgrid|contents|table|flexbox|absolute|relative|fixed|sticky|static|left|right|top|bottom|center|middle|start|end|baseline|stretch|bold|bolder|lighter|italic|oblique|underline|overline|pre|nowrap|wrap|clip|ellipsis|solid|dashed|dotted|double|groove|ridge|inset|outset|hidden|and|not|only|or)(?:-[\w-]+)?\b/g }, + { + type: 'section', + match: /::?[\w-]+\b/g + }, { type: 'type', match: /(?:\.|#|::?)[\w-]+|(? Date: Sat, 27 Dec 2025 22:15:58 +0600 Subject: [PATCH 04/13] fix --- examples/languages/test.css | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/languages/test.css b/examples/languages/test.css index bc74635..32e282f 100644 --- a/examples/languages/test.css +++ b/examples/languages/test.css @@ -30,6 +30,7 @@ } @counter-style custom-counter { + /* test */ system: cyclic; symbols: ◉ ◌ ◎; suffix: " "; From e33d845a70160861b18f8b454ea9fd5200296c07 Mon Sep 17 00:00:00 2001 From: Arif Date: Sun, 28 Dec 2025 16:38:26 +0600 Subject: [PATCH 05/13] feat: enhance Bash language parsing with improved regex patterns and structure --- src/languages/bash.js | 115 ++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 48 deletions(-) diff --git a/src/languages/bash.js b/src/languages/bash.js index 173bf90..9000b3e 100644 --- a/src/languages/bash.js +++ b/src/languages/bash.js @@ -1,51 +1,70 @@ -let variable = { - type: 'var', - match: /\$\w+|\${[^}]*}|\$\([^)]*\)/g +const subRules = [ + { + type: 'func', + match: /\b(echo|date|pwd|ls|command|grep|sed|awk|diff|cat|sudo|cd|mkdir|rm|cp|mv|comm|sort|printf)\b/g + }, + { type: 'num', match: /\b\d+(\.\d+)?\b/g }, + { + type: 'kwd', + match: /\b(in|let|local|declare|export|do|done|then|fi|if|for|while|return|exit|case|esac)\b/g + }, + { type: 'oper', match: /[!@%*?#:-]|[\[\]]|[=+\-*/<>|&!^]+/g }, + { type: 'var', match: /[a-zA-Z_][a-zA-Z0-9_]*/g } +]; + +const variable = { + type: 'var', + match: /\$\w+|\$\{(?:[^}\\]|\\.)*\}|\$\((?:[^)(]|\([^)(]*\))*\)|\$\(\(.*\)\)/g, + sub: subRules +}; + +const doubleQuoteStr = { + type: 'str', + match: /"(\\[\s\S]|[^"\\])*"/g, + sub: [ variable ] }; +const singleQuoteStr = { type: 'str', match: /'[^']*'/g }; + +subRules.push(doubleQuoteStr); +subRules.push(singleQuoteStr); + export default [ - { - sub: 'todo', - match: /#.*/g - }, - { - type: 'str', - match: /(["'])((?!\1)[^\r\n\\]|\\[^])*\1?/g, - sub: [ variable ] - }, - { - // relative or absolute path - type: "oper", - match: /(?<=\s|^)\.*\/[a-z/_.-]+/gi, - }, - { - type: 'kwd', - match: /\s-[a-zA-Z]+|$<|[&|;]+|\b(unset|readonly|shift|export|if|fi|else|elif|while|do|done|for|until|case|esac|break|continue|exit|return|trap|wait|eval|exec|then|declare|enable|local|select|typeset|time|add|remove|install|update|delete)(?=\s|$)/g - }, - { - expand: 'num' - }, - { - // command - type: 'func', - match: /(?<=(^|\||\&\&|\;)\s*)[a-z_.-]+(?=\s|$)/gmi - }, - { - type: 'bool', - match: /(?<=\s|^)(true|false)(?=\s|$)/g - }, - // { - // // function definition - // type: 'func', - // match: /(?<=\s|^)[a-z_]+(?=\s*\()/g - // }, - { - type: 'oper', - match: /[=(){}<>!]+/g - }, - { - type: 'var', - match: /(?<=\s|^)[\w_]+(?=\s*=)/g - }, - variable -] + { type: 'kwd', match: /^#!.*/g }, + { type: 'cmnt', match: /(^|\s)#.*/g }, + + { type: 'str', match: /<<\s*(['"])([a-zA-Z_][\w-]*)\1[\s\S]*?^\2$/gm }, + { type: 'str', match: /<<-?\s*([a-zA-Z_][\w-]*)[\s\S]*?^\1$/gm, sub: [ variable ] }, + + singleQuoteStr,doubleQuoteStr, + + { type: 'oper', match: /<(?=\()/g }, + + { type: 'var', match: /(?<=^|\s|[|&;])[a-zA-Z_][a-zA-Z0-9_]*(?==)/g }, + + variable, + + { + type: 'kwd', + match: /\b(function|local|unset|readonly|shift|export|if|fi|else|elif|while|do|done|for|until|case|esac|break|continue|exit|return|trap|wait|eval|exec|then|declare|enable|select|typeset|time|EOF|EXPECTED|let|in)\b/g + }, + + { type: 'kwd', match: /(?<=^|\s|\[)--?[a-zA-Z0-9-]+(?=\s|$|\])/g }, + { type: 'bool', match: /(?<=^|\s)(true|false)(?=\s|$)/g }, + + { + type: 'oper', + match: /\(\([\s\S]*?\)\)|\[\[[\s\S]*?\]\]|[=(){}<>!|&]+/g, + sub: [...subRules, variable] + }, + + { type: 'func', match: /(?<=function\s+)[a-z_][a-z0-9_.-]*/gmi }, + { type: 'func', match: /(?<=^|\s)[a-z_][a-z0-9_.-]*(?=\s*\(\))/gmi }, + + { + type: 'func', + match: /(?<=^|\||&&|;|do\s+|then\s+)\b(?!(?:if|fi|else|elif|while|do|done|for|until|case|esac|break|continue|exit|return|then|local|declare|in|let)\b)[a-z_][a-z0-9_.-]*\b/gm + }, + + { type: 'num', match: /\b\d+\b/g } +]; \ No newline at end of file From 9506e464a2cc0823e7e5e58e7e3ac8485c9b87e0 Mon Sep 17 00:00:00 2001 From: Arif Date: Tue, 30 Dec 2025 17:00:12 +0600 Subject: [PATCH 06/13] feat: Add JavaScript language definition with JSDoc, regex, and template literal sub-languages. --- examples/languages/test.js | 105 ++++++++++++++++++-------- src/languages/js.js | 84 ++++++++++++++++++--- src/languages/js_template_literals.js | 29 +++---- src/languages/jsdoc.js | 4 +- src/languages/regex.js | 24 ++++-- 5 files changed, 179 insertions(+), 67 deletions(-) diff --git a/examples/languages/test.js b/examples/languages/test.js index d7d4017..5a70db1 100644 --- a/examples/languages/test.js +++ b/examples/languages/test.js @@ -1,34 +1,75 @@ -/* Multiline FIX - Comment */ /** -* js doc CHANGED x -* @param {String} param -* @return nothing -*/ -const listener = Deno.listen({ port: 8000 }); -console.log(.8 * 0. * (0.8 * .e8) * 0.e8 * 0x849, 0d0101, 0o987, 8_987_654.1789) -console?.log(`http://localhost:${PORT}/`.match(/:[0-9]{2,4}^/g)); -// TODO other comment -for await (const conn of listener) { - if (false) - break; - (async () => { - const requests = Deno.serveHttp(conn); - for await (const { respondWith } of this.requests.new) { - respondWith(new Response('Hello\ - world')); - } - })(); -} -function test(test) { - let test = () => { console.log(test) }; - return test; + * DataProcessor v2.1.0 + * Tests regex, private fields, async generators, and complex nesting. + */ +import { EventEmitter } from 'events'; + +const CONFIG_SYMBOL = Symbol('orchestrator_config'); + +export default class DataOrchestrator extends EventEmitter { + #internalState = 'idle'; // Private class field + static MAX_RETRIES = 3; + + constructor(options = {}) { + super(); + this[CONFIG_SYMBOL] = { + timeout: 5000, + ...options + }; + } + + /** + * Processes an incoming data stream with a regex filter. + * @param {Array} rawData + */ + async process(rawData) { + this.#internalState = 'processing'; + const regex = /data-id_([0-9a-fA-F]{8})/gi; // Complex Regex + + try { + const results = await Promise.all( + rawData.map(async (item, index) => { + // Template literal with nested expression + const logMsg = `Item #${index + 1}: ${item.toUpperCase()}`; + + if (regex.test(item)) { + return { id: item.match(regex)[0], status: 'valid' }; + } + + return { id: null, status: 'invalid' }; + }) + ); + + this.emit('complete', { + timestamp: Date.now(), + count: results.length + }); + + } catch (error) { + console.error(`Error code: ${error.code ?? 'UNKNOWN_ERR'}`); + } finally { + this.#internalState = 'idle'; + } + } + + // Async Generator for memory-efficient streaming + async *streamResults(items) { + for (const item of items) { + yield new Promise(resolve => + setTimeout(() => resolve(`Processed: ${item}`), 100) + ); + } + } } -export default { - jsonData: a > 5, - match: /test/g, - type: `test - ${'test'}hello - ${test + 2.5}hello`, - 'Hello world': true -} \ No newline at end of file + +// Function demonstrating destructuring and default parameters +const init = ({ host = 'localhost', port = 8080 } = {}) => { + const orchestrator = new DataOrchestrator({ host }); + console.log(`Server running at ${host}:${port}`); + return orchestrator; +}; + +/* Block comment test: + Math: 10 / 2 * (5 + 5) +*/ +const instance = init(); \ No newline at end of file diff --git a/src/languages/js.js b/src/languages/js.js index 3189f12..3f33fb4 100644 --- a/src/languages/js.js +++ b/src/languages/js.js @@ -11,27 +11,91 @@ export default [ expand: 'str' }, { - match: /`((?!`)[^]|\\[^])*`?/g, + match: new class { + exec(str) { + let i = this.lastIndex; + for (; i < str.length; i++) { + if (str[i] === '`') { + let start = i, stack = 0; + while (++i < str.length) { + if (str[i] === '\\') i++; + else if (str[i] === '$' && str[i + 1] === '{') { stack++; i++; } + else if (stack > 0 && str[i] === '{') stack++; + else if (stack > 0 && str[i] === '}') stack--; + else if (stack === 0 && str[i] === '`') { i++; break; } + } + this.lastIndex = i; + return { index: start, 0: str.slice(start, i) }; + } + } + return null; + } + }(), sub: 'js_template_literals' }, + { + type: 'var', + match: /\b(?!(?:true|false|null|undefined|NaN|Infinity|this|default)\b)[a-zA-Z_$][\w$]*\b(?=\s*:(?!\s*[:=]))/g + }, { type: 'kwd', - match: /=>|\b(this|set|get|as|async|await|break|case|catch|class|const|constructor|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|if|implements|import|in|instanceof|interface|let|var|of|new|package|private|protected|public|return|static|super|switch|throw|throws|try|typeof|void|while|with|yield)\b/g + match: /=>|(?|function\b))/g + }, + { + type: 'kwd', + match: /\bstatic\b(?=\s*\{)/g + }, + { + type: 'var', + match: /\b[a-zA-Z$_][\w$_]*(?=\s*=\s*)/g }, { - expand: 'num' + type: 'var', + match: /(?\+*\-\/%^~]|\b(?:case|else|do|return|throw|typeof|void|yield|await|new|in|instanceof))\s*)\/(?!\s)(?:\\.|\[(?:\\.|\[(?:\\.|[^\]])*\]|[^\]])*\]|(?!\/)[^\r\n\\])+\/[dgimsuyv]*/g, + sub: 'regex' }, { type: 'num', - match: /\b(NaN|null|undefined|[A-Z][A-Z_]*)\b/g + match: /(0[bB][01]+(?:_[01]+)*|0[oO][0-7]+(?:_[0-7]+)*|0[xX][0-9a-fA-F]+(?:_[0-9a-fA-F]+)*|(?:\d+_)*\d+(?:\.(?:\d+_)*\d+)?(?:[eE][+-]?(?:\d+_)*\d+)?)n?/g }, { - type: 'bool', - match: /\b(true|false)\b/g + type: 'var', + match: /#[\w$_]+/g }, { type: 'oper', @@ -40,9 +104,5 @@ export default [ { type: 'class', match: /\b[A-Z][\w_]*\b/g - }, - { - type: 'func', - match: /[a-zA-Z$_][\w$_]*(?=\s*((\?\.)?\s*\(|=\s*(\(?[\w,{}\[\])]+\)? =>|function\b)))/g } ] diff --git a/src/languages/js_template_literals.js b/src/languages/js_template_literals.js index 62675b4..fa49a04 100644 --- a/src/languages/js_template_literals.js +++ b/src/languages/js_template_literals.js @@ -2,21 +2,22 @@ export default [ { match: new class { exec(str) { - let i = this.lastIndex, - j, - f = _ => { - while (++i < str.length - 2) - if (str[i] == '{') f(); - else if (str[i] == '}') return; - }; - for (; i < str.length; ++i) - if (str[i - 1] != '\\' && str[i] == '$' && str[i + 1] == '{') { - j = i++; - f(i); - this.lastIndex = i + 1; - return { index: j, 0: str.slice(j, i + 1) }; + let i = this.lastIndex, j; + for (; i < str.length; ++i) { + if (str[i - 1] !== '\\' && str[i] === '$' && str[i + 1] === '{') { + j = i; i += 2; + let stack = 1; + while (i < str.length && stack > 0) { + if (str[i] === '\\') i++; + else if (str[i] === '{') stack++; + else if (str[i] === '}') stack--; + i++; + } + this.lastIndex = i; + return { index: j, 0: str.slice(j, i) }; + } } - return null; + return null; } }(), sub: [ diff --git a/src/languages/jsdoc.js b/src/languages/jsdoc.js index b519807..9c542ac 100644 --- a/src/languages/jsdoc.js +++ b/src/languages/jsdoc.js @@ -6,8 +6,8 @@ export default [ match: /@\w+/g }, { - type: 'class', - match: /{[\w\s|<>,.@\[\]]+}/g + type: 'type', + match: /{(?:[^}{]|\{(?:[^}{]|\{[^}{]*\})*\})*}/g }, { type: 'var', diff --git a/src/languages/regex.js b/src/languages/regex.js index 1e707dc..f616cbb 100644 --- a/src/languages/regex.js +++ b/src/languages/regex.js @@ -1,19 +1,29 @@ export default [ - { - match: /^(?!\/).*/gm, - sub: 'todo' - }, { type: 'num', - match: /\[((?!\])[^\\]|\\.)*\]/g + match: new class { + exec(str) { + let i = this.lastIndex; + if (str[i] !== '[') return null; + let start = i, stack = 1; + while (++i < str.length && stack > 0) { + if (str[i] === '\\') i++; + else if (str[i] === '[') stack++; + else if (str[i] === ']') stack--; + } + this.lastIndex = i; + return { index: start, 0: str.slice(start, i) }; + } + }(), + sub: 'regex' }, { type: 'kwd', - match: /\||\^|\$|\\.|\w+($|\r|\n)/g + match: /\\.|\||\^|\$|\\[bcdDfnrsStvwWv]|\\p\{[a-zA-Z0-9_=]+\}|\\u\{[a-fA-F0-9]+\}|\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}|\w+($|\r|\n)/g }, { type: 'var', - match: /\*|\+|\{\d+,\d+\}/g + match: /\*|\+|\?|\.|\{\d+(?:,\d*)?\}|\\(?=[()])/g } ]; export let type = 'oper'; From 662a3bb458ef359249a966383c76e888e68d5bee Mon Sep 17 00:00:00 2001 From: Arif Date: Tue, 30 Dec 2025 17:05:59 +0600 Subject: [PATCH 07/13] feat: Enhance HTML and XML language definitions with improved regex patterns and structure --- src/languages/html.js | 90 ++++++++++++++++++++++++++++++++++++++++--- src/languages/xml.js | 1 - 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/languages/html.js b/src/languages/html.js index a4998af..5e69671 100644 --- a/src/languages/html.js +++ b/src/languages/html.js @@ -1,4 +1,83 @@ -import xml, { properties, xmlElement } from './xml.js' +import xml, { name, properties, xmlElement } from './xml.js' + +export const htmlElement = { + match: RegExp(`<[\/!?]?${name}${properties}[\/!?]?>`, 'g'), + sub: [ + { + type: 'var', + match: RegExp(`^<[\/!?]?${name}`, 'g'), + sub: [ + { + type: 'oper', + match: /^<[\/!?]?/g + } + ] + }, + { + match: /style\s*=\s*('[^']*'|"[^"]*")/gi, + sub: [ + { + match: /^style\s*=\s*/gi, + sub: [ + { + type: 'class', + match: /^style/gi + }, + { + type: 'oper', + match: /=/g + } + ] + }, + { + match: /('[^']*'|"[^"]*")/g, + sub: [ + { + type: 'str', // quotes + match: /^['"]|['"]$/g + }, + { + match: /[^"']+/g, + sub: 'css' + } + ] + } + ] + }, + { + match: /on\w+\s*=\s*('[^']*'|"[^"]*")/gi, + sub: [ + { + match: /^on\w+\s*=\s*/gi, + sub: [ + { + type: 'class', + match: /^on\w+/gi + }, + { + type: 'oper', + match: /=/g + } + ] + }, + { + match: /('[^']*'|"[^"]*")/g, + sub: [ + { + type: 'str', // quotes + match: /^['"]|['"]$/g + }, + { + match: /[^"']+/g, + sub: 'js' + } + ] + } + ] + }, + ...xmlElement.sub + ] +}; export default [ { @@ -24,13 +103,13 @@ export default [ sub: [ { match: RegExp(`^`, 'g'), - sub: xmlElement.sub + sub: htmlElement.sub }, { match: RegExp(`${xmlElement.match}|[^]*(?=$)`, 'g'), sub: 'css' }, - xmlElement + htmlElement ] }, { @@ -38,14 +117,15 @@ export default [ sub: [ { match: RegExp(`^`, 'g'), - sub: xmlElement.sub + sub: htmlElement.sub }, { match: RegExp(`${xmlElement.match}|[^]*(?=$)`, 'g'), sub: 'js' }, - xmlElement + htmlElement ] }, + htmlElement, ...xml ] diff --git a/src/languages/xml.js b/src/languages/xml.js index 5cecd1e..c6067e1 100644 --- a/src/languages/xml.js +++ b/src/languages/xml.js @@ -48,7 +48,6 @@ export default [ match: //gi }, xmlElement, - // https://github.com/speed-highlight/core/issues/49 { type: 'str', match: RegExp(`<\\?${name}([^?]|\\?[^?>])*\\?+>`, 'g'), From 04456b4b5b8375578f953ec9f4818b020eca4112 Mon Sep 17 00:00:00 2001 From: Arif Date: Tue, 30 Dec 2025 17:07:19 +0600 Subject: [PATCH 08/13] feat: Add SVG language definition with regex patterns for elements and attributes --- src/languages/svg.js | 91 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/languages/svg.js diff --git a/src/languages/svg.js b/src/languages/svg.js new file mode 100644 index 0000000..9f51873 --- /dev/null +++ b/src/languages/svg.js @@ -0,0 +1,91 @@ +import html, { htmlElement } from './html.js'; +import { name, properties } from './xml.js'; + +const svgElement = { + match: RegExp(`<[\/!?]?${name}${properties}[\/!?]?>`, 'g'), + sub: [ + { + type: 'var', + match: RegExp(`^<[\/!?]?${name}`, 'g'), + sub: [ + { + type: 'oper', + match: /^<[\/!?]?/g + } + ] + }, + { + match: /d\s*=\s*('[^']*'|"[^"]*")/gi, + sub: [ + { + match: /^d\s*=\s*/gi, + sub: [ + { + type: 'class', + match: /^d/gi + }, + { + type: 'oper', + match: /=/g + } + ] + }, + { + match: /('[^']*'|"[^"]*")/g, + sub: [ + { + type: 'str', // quotes + match: /^['"]|['"]$/g + }, + { + type: 'kwd', // commands + match: /[MmZzLlHhVvCcSsQqTtAa]/g + }, + { + type: 'num', // coordinates + match: /-?\d*\.?\d+(?:e[+-]?\d+)?/gi + }, + { + type: 'oper', // separators + match: /[,]/g + } + ] + } + ] + }, + { + match: /viewBox\s*=\s*('[^']*'|"[^"]*")/gi, + sub: [ + { + match: /^viewBox\s*=\s*/gi, + sub: [ + { + type: 'class', + match: /^viewBox/gi + }, + { + type: 'oper', + match: /=/g + } + ] + }, + { + match: /('[^']*'|"[^"]*")/g, + sub: [ + { + type: 'str', // quotes + match: /^['"]|['"]$/g + }, + { + type: 'num', // coordinates + match: /-?\d*\.?\d+/g + } + ] + } + ] + }, + ...htmlElement.sub + ] +}; + +export default html.map(rule => rule === htmlElement ? svgElement : rule); From 0b3d8e85dc5a16a4b63f71adb7ce2000233a4b9c Mon Sep 17 00:00:00 2001 From: Arif Date: Tue, 30 Dec 2025 19:03:09 +0600 Subject: [PATCH 09/13] revert back bash --- src/languages/bash.js | 115 ++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 67 deletions(-) diff --git a/src/languages/bash.js b/src/languages/bash.js index 9000b3e..4c6fa54 100644 --- a/src/languages/bash.js +++ b/src/languages/bash.js @@ -1,70 +1,51 @@ -const subRules = [ - { - type: 'func', - match: /\b(echo|date|pwd|ls|command|grep|sed|awk|diff|cat|sudo|cd|mkdir|rm|cp|mv|comm|sort|printf)\b/g - }, - { type: 'num', match: /\b\d+(\.\d+)?\b/g }, - { - type: 'kwd', - match: /\b(in|let|local|declare|export|do|done|then|fi|if|for|while|return|exit|case|esac)\b/g - }, - { type: 'oper', match: /[!@%*?#:-]|[\[\]]|[=+\-*/<>|&!^]+/g }, - { type: 'var', match: /[a-zA-Z_][a-zA-Z0-9_]*/g } -]; - -const variable = { - type: 'var', - match: /\$\w+|\$\{(?:[^}\\]|\\.)*\}|\$\((?:[^)(]|\([^)(]*\))*\)|\$\(\(.*\)\)/g, - sub: subRules -}; - -const doubleQuoteStr = { - type: 'str', - match: /"(\\[\s\S]|[^"\\])*"/g, - sub: [ variable ] +let variable = { + type: 'var', + match: /\$\w+|\${[^}]*}|\$\([^)]*\)/g }; -const singleQuoteStr = { type: 'str', match: /'[^']*'/g }; - -subRules.push(doubleQuoteStr); -subRules.push(singleQuoteStr); - export default [ - { type: 'kwd', match: /^#!.*/g }, - { type: 'cmnt', match: /(^|\s)#.*/g }, - - { type: 'str', match: /<<\s*(['"])([a-zA-Z_][\w-]*)\1[\s\S]*?^\2$/gm }, - { type: 'str', match: /<<-?\s*([a-zA-Z_][\w-]*)[\s\S]*?^\1$/gm, sub: [ variable ] }, - - singleQuoteStr,doubleQuoteStr, - - { type: 'oper', match: /<(?=\()/g }, - - { type: 'var', match: /(?<=^|\s|[|&;])[a-zA-Z_][a-zA-Z0-9_]*(?==)/g }, - - variable, - - { - type: 'kwd', - match: /\b(function|local|unset|readonly|shift|export|if|fi|else|elif|while|do|done|for|until|case|esac|break|continue|exit|return|trap|wait|eval|exec|then|declare|enable|select|typeset|time|EOF|EXPECTED|let|in)\b/g - }, - - { type: 'kwd', match: /(?<=^|\s|\[)--?[a-zA-Z0-9-]+(?=\s|$|\])/g }, - { type: 'bool', match: /(?<=^|\s)(true|false)(?=\s|$)/g }, - - { - type: 'oper', - match: /\(\([\s\S]*?\)\)|\[\[[\s\S]*?\]\]|[=(){}<>!|&]+/g, - sub: [...subRules, variable] - }, - - { type: 'func', match: /(?<=function\s+)[a-z_][a-z0-9_.-]*/gmi }, - { type: 'func', match: /(?<=^|\s)[a-z_][a-z0-9_.-]*(?=\s*\(\))/gmi }, - - { - type: 'func', - match: /(?<=^|\||&&|;|do\s+|then\s+)\b(?!(?:if|fi|else|elif|while|do|done|for|until|case|esac|break|continue|exit|return|then|local|declare|in|let)\b)[a-z_][a-z0-9_.-]*\b/gm - }, - - { type: 'num', match: /\b\d+\b/g } -]; \ No newline at end of file + { + sub: 'todo', + match: /#.*/g + }, + { + type: 'str', + match: /(["'])((?!\1)[^\r\n\\]|\\[^])*\1?/g, + sub: [ variable ] + }, + { + // relative or absolute path + type: "oper", + match: /(?<=\s|^)\.*\/[a-z/_.-]+/gi, + }, + { + type: 'kwd', + match: /\s-[a-zA-Z]+|$<|[&|;]+|\b(unset|readonly|shift|export|if|fi|else|elif|while|do|done|for|until|case|esac|break|continue|exit|return|trap|wait|eval|exec|then|declare|enable|local|select|typeset|time|add|remove|install|update|delete)(?=\s|$)/g + }, + { + expand: 'num' + }, + { + // command + type: 'func', + match: /(?<=(^|\||\&\&|\;)\s*)[a-z_.-]+(?=\s|$)/gmi + }, + { + type: 'bool', + match: /(?<=\s|^)(true|false)(?=\s|$)/g + }, + // { + // // function definition + // type: 'func', + // match: /(?<=\s|^)[a-z_]+(?=\s*\()/g + // }, + { + type: 'oper', + match: /[=(){}<>!]+/g + }, + { + type: 'var', + match: /(?<=\s|^)[\w_]+(?=\s*=)/g + }, + variable +] \ No newline at end of file From 030167ec6f56856d246f9b45c7c45af04b57118b Mon Sep 17 00:00:00 2001 From: Arif Date: Wed, 31 Dec 2025 13:25:37 +0600 Subject: [PATCH 10/13] feat: Improve line number calculation and add pre-load language function --- src/index.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 93e69e5..b5dccdc 100644 --- a/src/index.js +++ b/src/index.js @@ -129,7 +129,7 @@ export async function highlightText(src, lang, multiline = true, opt = {}) { await tokenize(src, lang, (str, type) => tmp += toSpan(sanitize(str), type)) return multiline - ? `
${'
'.repeat(!opt.hideLineNumbers && src.split('\n').length)}
${tmp}
` + ? `
${'
'.repeat(!opt.hideLineNumbers && (src.match(/\n/g) || []).length + 1)}
${tmp}
` : tmp; } @@ -145,7 +145,7 @@ export async function highlightText(src, lang, multiline = true, opt = {}) { */ export async function highlightElement(elm, lang = elm.className.match(/shj-lang-([\w-]+)/)?.[1], mode, opt) { let txt = elm.textContent; - mode ??= `${elm.tagName == 'CODE' ? 'in' : (txt.split('\n').length < 2 ? 'one' : 'multi')}line`; + mode ??= `${elm.tagName == 'CODE' ? 'in' : (txt.includes('\n') ? 'multi' : 'one')}line`; elm.dataset.lang = lang; elm.className = `${[...elm.classList].filter(className => !className.startsWith('shj-')).join(' ')} shj-lang-${lang} shj-${mode}`; elm.innerHTML = await highlightText(txt, lang, mode == 'multiline', opt); @@ -184,3 +184,17 @@ export let highlightAll = async (opt) => export let loadLanguage = (languageName, language) => { langs[languageName] = language; } + +/** + * Pre-load one or more languages + * + * @async + * @function preLoadLanguage + * @param {...string} languageNames The names of the languages to load + * @returns {Promise} A promise that resolves when all languages have been preloaded + */ +export let preLoadLanguage = async (...languageNames) => { + await Promise.all( + languageNames.map(lang => langs[lang] ? Promise.resolve() : import(`./languages/${lang}.js`).then(module => langs[lang] = module)) + ); +} \ No newline at end of file From 41991095c5ae81f5a1e5cd71eca40e3c433d4028 Mon Sep 17 00:00:00 2001 From: Arif Date: Wed, 14 Jan 2026 22:20:51 +0600 Subject: [PATCH 11/13] fix: Correct regex pattern for JavaScript language definition --- src/languages/js.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/js.js b/src/languages/js.js index 3f33fb4..62a3a19 100644 --- a/src/languages/js.js +++ b/src/languages/js.js @@ -86,7 +86,7 @@ export default [ match: /:/g }, { - match: /(?<=(?:^|[=(,:[!&|?{};<>\+*\-\/%^~]|\b(?:case|else|do|return|throw|typeof|void|yield|await|new|in|instanceof))\s*)\/(?!\s)(?:\\.|\[(?:\\.|\[(?:\\.|[^\]])*\]|[^\]])*\]|(?!\/)[^\r\n\\])+\/[dgimsuyv]*/g, + match: /(?<=(?:^|[=(,:[!&|?{};<>\+*\-\/%^~]|\b(?:case|else|do|return|throw|typeof|void|yield|await|new|in|instanceof))\s*)\/(?:\\.|\[(?:\\.|\[(?:\\.|[^\]])*\]|[^\]])*\]|(?!\/)[^\r\n\\])+\/[dgimsuyv]*/g, sub: 'regex' }, { From ce89d28b6f56e171d91da289eaf534890254e357 Mon Sep 17 00:00:00 2001 From: Arif Date: Thu, 15 Jan 2026 12:01:16 +0600 Subject: [PATCH 12/13] fix: Extend regex pattern for boolean values in CSS language definition --- src/languages/css.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/css.js b/src/languages/css.js index ebd074e..26a90c3 100644 --- a/src/languages/css.js +++ b/src/languages/css.js @@ -47,7 +47,7 @@ export default [ }, { type: 'bool', - match: /\b(in|from|to|at|vs|nearest|up|down|always|stable|both|none|auto|inherit|initial|unset|revert|normal|all|transparent|currentColor|true|false|block|inline|flex|grid|subgrid|contents|table|flexbox|absolute|relative|fixed|sticky|static|left|right|top|bottom|center|middle|start|end|baseline|stretch|bold|bolder|lighter|italic|oblique|underline|overline|pre|nowrap|wrap|clip|ellipsis|solid|dashed|dotted|double|groove|ridge|inset|outset|hidden|and|not|only|or)(?:-[\w-]+)?\b/g + match: /\b(in|from|to|at|vs|nearest|up|down|always|stable|both|none|auto|inherit|initial|unset|revert|normal|all|transparent|currentColor|true|false|block|inline|flex|grid|subgrid|contents|table|absolute|relative|fixed|sticky|static|left|right|top|bottom|center|middle|start|end|baseline|stretch|bold|bolder|lighter|italic|oblique|underline|overline|pre|nowrap|wrap|clip|ellipsis|solid|dashed|dotted|double|groove|ridge|inset|outset|hidden|and|not|only|or|cover|contain|x|y|scroll|visible|pointer|default|zoom|row|column|ease|linear|step|overlay|safe|unsafe|self|first|last|legacy|dense|min|max|fit|available|border|list|flow|ruby|separate|collapse|mix|multiply|screen|darken|lighten|difference|exclusion|hue|saturation|luminosity)(?:-[\w-]+)?\b/g }, { type: 'section', From 93a53ff9ab532cafe9fa900fca75a98fa21d14ce Mon Sep 17 00:00:00 2001 From: Arif Date: Wed, 18 Feb 2026 15:13:15 +0600 Subject: [PATCH 13/13] fix: Update regex for boolean values in CSS to prevent negative matches --- src/languages/css.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/css.js b/src/languages/css.js index 26a90c3..af80fc6 100644 --- a/src/languages/css.js +++ b/src/languages/css.js @@ -47,7 +47,7 @@ export default [ }, { type: 'bool', - match: /\b(in|from|to|at|vs|nearest|up|down|always|stable|both|none|auto|inherit|initial|unset|revert|normal|all|transparent|currentColor|true|false|block|inline|flex|grid|subgrid|contents|table|absolute|relative|fixed|sticky|static|left|right|top|bottom|center|middle|start|end|baseline|stretch|bold|bolder|lighter|italic|oblique|underline|overline|pre|nowrap|wrap|clip|ellipsis|solid|dashed|dotted|double|groove|ridge|inset|outset|hidden|and|not|only|or|cover|contain|x|y|scroll|visible|pointer|default|zoom|row|column|ease|linear|step|overlay|safe|unsafe|self|first|last|legacy|dense|min|max|fit|available|border|list|flow|ruby|separate|collapse|mix|multiply|screen|darken|lighten|difference|exclusion|hue|saturation|luminosity)(?:-[\w-]+)?\b/g + match: /(?