tex.lua (1494B)
1 local M = {_NAME = "tex"} 2 3 local l = require("lexer") 4 local P, R, S = lpeg.P, lpeg.R, lpeg.S 5 local T = l.token 6 local any = P(1) 7 local function I(s) -- Case-insensitive string match 8 local p = P(true) 9 for i = 1, #s do 10 local c = s:sub(i, i) 11 p = p * (P(c:lower()) + P(c:upper())) 12 end 13 return p 14 end 15 local function N(p, min, max) 16 max = max or min 17 return p^min - p^(max+1) 18 end 19 20 local whitespace = T("whitespace", S"\n\r\t "^1) 21 22 local comment_keyword = T("comment_keyword", I"todo" + I"xxx" + I"fixme") 23 local comment_text = T("comment_text", (any - P"\n" - comment_keyword)^1) 24 local comment = T("comment_text", P"%") * (comment_text + comment_keyword)^0 * T("whitespace", P"\n") 25 26 local upup = T("tex_upup", P"^^" * (N(R("09", "af"), 2) + any)) 27 28 local delimiter = T("delimiter", S"{}") 29 30 local math_ = T("tex_math", P"$") 31 32 local operator = T("operator", S"^_~&" + (P"#" * (R"19" + P"#" + #P"{")) + P"---" + P"--") 33 34 local command = T("function", P"\\") * (upup + T("function", (R("AZ", "az") + P"@")^1 + any)) 35 36 M._rules = { 37 {"whitespace", whitespace}, 38 {"comment", comment}, 39 {"tex_upup", upup}, 40 {"delimiter", delimiter}, 41 {"tex_math", math_}, 42 {"operator", operator}, 43 {"function", command}, 44 } 45 46 M._tokenstyles = { 47 whitespace = l.STYLE_WHITESPACE, 48 49 comment_text = l.STYLE_COMMENT, 50 comment_keyword = l.STYLE_COMMENT_KEYWORD, 51 52 tex_upup = l.STYLE_ESCAPE, 53 delimiter = l.STYLE_DELIMITER, 54 tex_math = l.STYLE_STRING, 55 operator = l.STYLE_OPERATOR, 56 57 ["function"] = l.STYLE_FUNCTION, 58 } 59 60 return M