(line: string, lang: string, t: Theme)
| 73 | const TOKEN_RE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*`|\b\d+(?:\.\d+)?\b|[A-Za-z_$][\w$]*/g |
| 74 | |
| 75 | export function highlightLine(line: string, lang: string, t: Theme): Token[] { |
| 76 | const spec = resolve(lang) |
| 77 | |
| 78 | if (!spec) { |
| 79 | return [['', line]] |
| 80 | } |
| 81 | |
| 82 | if (spec.comment && line.trimStart().startsWith(spec.comment)) { |
| 83 | return [[t.color.muted, line]] |
| 84 | } |
| 85 | |
| 86 | const tokens: Token[] = [] |
| 87 | let last = 0 |
| 88 | |
| 89 | for (const m of line.matchAll(TOKEN_RE)) { |
| 90 | const start = m.index ?? 0 |
| 91 | |
| 92 | if (start > last) { |
| 93 | tokens.push(['', line.slice(last, start)]) |
| 94 | } |
| 95 | |
| 96 | const tok = m[0] |
| 97 | const ch = tok[0]! |
| 98 | |
| 99 | if (ch === '"' || ch === "'" || ch === '`') { |
| 100 | tokens.push([t.color.accent, tok]) |
| 101 | } else if (ch >= '0' && ch <= '9') { |
| 102 | tokens.push([t.color.text, tok]) |
| 103 | } else if (spec.keywords.has(tok)) { |
| 104 | tokens.push([t.color.border, tok]) |
| 105 | } else { |
| 106 | tokens.push(['', tok]) |
| 107 | } |
| 108 | |
| 109 | last = start + tok.length |
| 110 | } |
| 111 | |
| 112 | if (last < line.length) { |
| 113 | tokens.push(['', line.slice(last)]) |
| 114 | } |
| 115 | |
| 116 | return tokens |
| 117 | } |
no test coverage detected