namespace XFESystem.Desktop; public readonly record struct SyntaxSpan(int Start, string Text, uint Color); /// A bounded native-view lexer. The full website highlighter is separately available in document HTML previews. public static class SyntaxHighlighter { private static readonly string[] Keywords = ["using", "namespace", "public", "private", "protected", "internal", "static", "class", "struct", "record", "void", "string", "int", "bool", "var", "const", "let", "function", "return", "if", "else", "for", "while", "new", "async", "await", "true", "false", "null", "export", "import", "from", "throw", "try", "catch"]; public static SyntaxSpan[] Tokenize(string line) { if (line.Length > 4096) throw new ArgumentException("Visible source line exceeds the lexer limit.", nameof(line)); var result = new List(); int at = 0; while (at < line.Length) { int start = at; char c = line[at++]; uint color = 0xDCEAF4; if (c == '/' && at < line.Length && line[at] == '/') { at = line.Length; color = 0x739D81; } else if (c is '"' or '\'' or '`') { color = 0xD6BB80; while (at < line.Length) { char next = line[at++]; if (next == '\\' && at < line.Length) at++; else if (next == c) break; } } else if (char.IsLetter(c) || c is '_' or '$') { while (at < line.Length && (char.IsLetterOrDigit(line[at]) || line[at] is '_' or '$')) at++; string word = line[start..at]; foreach (string keyword in Keywords) if (keyword == word) { color = 0xB99AEE; break; } } else if (char.IsDigit(c)) { while (at < line.Length && (char.IsLetterOrDigit(line[at]) || line[at] is '.' or '_')) at++; color = 0x77D7CE; } result.Add(new(start, line[start..at], color)); } return result.ToArray(); } }