local keywords = { "and", "break", "do", "else", "elseif", "end", --[["false",]] "for", "function", "goto", "if", "in", --[["local", "nil",]] "not", "or", "repeat", "return", "then", --[["true",]] "until", "while" } local keyword_set = {} for _, kw in ipairs(keywords) do keyword_set[kw] = true end local keyword_value_set = { ["true"] = true, ["false"] = true, ["nil"] = true, ["local"] = true, ["math.huge"] = true } local function colorize(str, color) return "" end function syntax_highlight(code) local out = "" local pos = 1 while pos <= #code do local matched = false -- Whitespace local ws_start, ws_end = code:find("^%s+", pos) if ws_start then out = out..colorize(code:sub(ws_start, ws_end), "whitespace") pos = ws_end + 1 matched = true end -- Single-line comment if not matched then local com_start, com_end = code:find("^%-%-[^\n]*", pos) if com_start then out = out..colorize(code:sub(com_start, com_end), "comment") pos = com_end + 1 matched = true end end -- String (double-quoted, simple escape handling) if not matched then local str_start, str_end = code:find('^"[^"]*"', pos) if str_start then out = out..colorize(code:sub(str_start, str_end), "string") pos = str_end + 1 matched = true end end -- String (single-quoted, similar) if not matched then local str_start, str_end = code:find("^'[^']*", pos) if str_start then out = out..colorize(code:sub(str_start, str_end), "string") pos = str_end + 1 matched = true end end -- Documentation placeholders. These aren't in Lua, but that means they -- can be highlighted without worrying about confusing alternative meanings. if not matched then local str_start, str_end = code:find('^\\?<[^>]*>', pos) if str_start then out = out..colorize(code:sub(str_start, str_end), "placeholder") pos = str_end + 1 matched = true end end -- Number (basic integer/float) if not matched then local num_start, num_end = code:find("^%d+%.?%d*[eE]?[+-]?%d*", pos) if num_start then out = out..colorize(code:sub(num_start, num_end), "number") pos = num_end + 1 matched = true end end -- Identifier/Keyword if not matched then local id_start, id_end, id_text = code:find("^([%a_][%w_]*)", pos) if id_start then if keyword_set[id_text] then out = out..colorize(id_text, "keyword") elseif keyword_value_set[id_text] then out = out..colorize(id_text, "keyword_value") else out = out..colorize(id_text, "identifier") end pos = id_end + 1 matched = true end end -- Operators/Punctuation (catch-all for non-alphanumeric) if not matched then local op_start, op_end = code:find("^[^%s%a%d_\"'{}(),%][]", pos) if op_start then local op = code:sub(op_start, op_end) out = out..colorize(op, op == "-" and code:sub(op_end +1, op_end +2):find "^%d" and "number" or "operator") pos = op_end + 1 matched = true end end -- If nothing matched, advance to avoid infinite loop (e.g., invalid char) if not matched then out = out..colorize(code:sub(pos, pos), "generic") pos = pos + 1 end end return out end