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();
}
}