diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-10 00:44:05 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-10 00:44:05 +0100 |
| commit | a3e3823f56606f023339cf8dc1e07798d106c453 (patch) | |
| tree | 17f6ec3da4554887b120f56b028f023f22994083 /tools/shader_editor | |
| parent | 289ee4ed692c726ed9b4497099287add9f1bc0fd (diff) | |
refactor: Improve syntax highlighting to avoid overlapping matches
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'tools/shader_editor')
| -rw-r--r-- | tools/shader_editor/index.html | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/tools/shader_editor/index.html b/tools/shader_editor/index.html index 5db06de..c7feffc 100644 --- a/tools/shader_editor/index.html +++ b/tools/shader_editor/index.html @@ -682,27 +682,34 @@ const syntaxHighlight = document.getElementById('syntax-highlight'); let composeTimeout = null; function highlightWGSL(code) { - const keywords = /\b(fn|var|let|const|struct|if|else|for|while|return|break|continue|switch|case|default|loop|continuing)\b/g; - const types = /\b(f32|i32|u32|bool|vec2|vec3|vec4|mat2x2|mat3x3|mat4x4|sampler|texture_2d|array)\b/g; - const attributes = /(@\w+)/g; - const functions = /\b([a-z_]\w*)\s*(?=\()/g; - const numbers = /\b(\d+\.?\d*)\b/g; - const comments = /(\/\/.*$)/gm; - const strings = /"([^"\\]|\\.)*"/g; - let highlighted = code .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>'); - highlighted = highlighted - .replace(comments, '<span class="hl-comment">$1</span>') - .replace(strings, '<span class="hl-string">$&</span>') - .replace(attributes, '<span class="hl-attribute">$1</span>') - .replace(keywords, '<span class="hl-keyword">$1</span>') - .replace(types, '<span class="hl-type">$1</span>') - .replace(functions, '<span class="hl-function">$1</span>') - .replace(numbers, '<span class="hl-number">$1</span>'); + // Tokenize to avoid overlapping matches + const tokens = []; + let lastIndex = 0; + + // Match comments, strings, then keywords/types/etc + const patterns = [ + { regex: /\/\/.*$/gm, className: 'hl-comment' }, + { regex: /"(?:[^"\\]|\\.)*"/g, className: 'hl-string' }, + { regex: /@\w+/g, className: 'hl-attribute' }, + { regex: /\b(?:fn|var|let|const|struct|if|else|for|while|return|break|continue|switch|case|default|loop|continuing)\b/g, className: 'hl-keyword' }, + { regex: /\b(?:f32|i32|u32|bool|vec2|vec3|vec4|mat2x2|mat3x3|mat4x4|sampler|texture_2d|array)\b/g, className: 'hl-type' }, + { regex: /\b\d+\.?\d*\b/g, className: 'hl-number' }, + { regex: /\b[a-z_]\w*(?=\s*\()/g, className: 'hl-function' }, + ]; + + // Simple sequential replacement (good enough for basic highlighting) + patterns.forEach(({ regex, className }) => { + highlighted = highlighted.replace(regex, match => { + // Don't re-highlight if already inside a span + if (/<span/.test(match)) return match; + return `<span class="${className}">${match}</span>`; + }); + }); return highlighted; } |
