summaryrefslogtreecommitdiff
path: root/tools/shader_editor/index.html
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-10 00:44:05 +0100
committerskal <pascal.massimino@gmail.com>2026-02-10 00:44:05 +0100
commita3e3823f56606f023339cf8dc1e07798d106c453 (patch)
tree17f6ec3da4554887b120f56b028f023f22994083 /tools/shader_editor/index.html
parent289ee4ed692c726ed9b4497099287add9f1bc0fd (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/index.html')
-rw-r--r--tools/shader_editor/index.html39
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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
- 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;
}