if not modules then modules = { } end modules ['mtx-check'] = { version = 1.001, comment = "companion to mtxrun.lua", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } local helpinfo = [[ --convert check tex file for errors ]] local application = logs.application { name = "mtx-check", banner = "Basic ConTeXt Syntax Checking 0.10", helpinfo = helpinfo, } local report = application.report scripts = scripts or { } scripts.checker = scripts.checker or { } local validator = { } validator.n = 1 validator.errors = { } validator.trace = false validator.direct = false validator.printer = print validator.tracer = print local message = function(position, kind) local ve = validator.errors ve[#ve+1] = { kind, position, validator.n } if validator.direct then validator.printer(string.format("%s error at position %s (line %s)", kind, position, validator.n)) end end local progress = function(position, data, kind) if validator.trace then validator.tracer(string.format("%s at position %s: %s", kind, position, data or "")) end end local P, R, S, V, C, CP, CC = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cp, lpeg.Cc local i_m, d_m = P("$"), P("$$") local l_s, r_s = P("["), P("]") local l_g, r_g = P("{"), P("}") local okay = lpeg.P("{[}") + lpeg.P("{]}") local esc = P("\\") local cr = P("\r") local lf = P("\n") local crlf = P("\r\n") local space = S(" \t\f\v") local newline = crlf + cr + lf local line = newline / function() validator.n = validator.n + 1 end -- local grammar = P { "tokens", -- ["tokens"] = (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + V("errors") + 1)^0, -- ["whatever"] = line + esc * 1 + C(P("%") * (1-line)^0), -- ["grouped"] = CP() * C(l_g * (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_g - r_g))^0 * r_g) * CC("group") / progress, -- ["setup"] = CP() * C(l_s * (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_s - r_s))^0 * r_s) * CC("setup") / progress, -- ["display"] = CP() * C(d_m * (V("whatever") + V("grouped") + (1 - d_m))^0 * d_m) * CC("display") / progress, -- ["inline"] = CP() * C(i_m * (V("whatever") + V("grouped") + (1 - i_m))^0 * i_m) * CC("inline") / progress, -- ["errors"] = (V("gerror") + V("serror") + V("derror") + V("ierror")) * true, -- ["gerror"] = CP() * (l_g + r_g) * CC("grouping") / message, -- ["serror"] = CP() * (l_s + r_g) * CC("setup error") / message, -- ["derror"] = CP() * d_m * CC("display math error") / message, -- ["ierror"] = CP() * i_m * CC("inline math error") / message, -- } local startluacode = P("\\startluacode") local stopluacode = P("\\stopluacode") local somecode = startluacode * (1-stopluacode)^1 * stopluacode local grammar = P { "tokens", ["tokens"] = (V("ignore") + V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + V("errors") + 1)^0, ["whatever"] = line + esc * 1 + C(P("%") * (1-line)^0), ["grouped"] = l_g * (V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_g - r_g))^0 * r_g, ["setup"] = l_s * (okay + V("whatever") + V("grouped") + V("setup") + V("display") + V("inline") + (1 - l_s - r_s))^0 * r_s, ["display"] = d_m * (V("whatever") + V("grouped") + (1 - d_m))^0 * d_m, ["inline"] = i_m * (V("whatever") + V("grouped") + (1 - i_m))^0 * i_m, ["errors"] = (V("gerror")+ V("serror") + V("derror") + V("ierror")), ["gerror"] = CP() * (l_g + r_g) * CC("grouping") / message, ["serror"] = CP() * (l_s + r_g) * CC("setup error") / message, ["derror"] = CP() * d_m * CC("display math error") / message, ["ierror"] = CP() * i_m * CC("inline math error") / message, ["ignore"] = somecode, } function validator.check(str) validator.n = 1 validator.errors = { } grammar:match(str) end --~ str = [[ --~ a{oeps {oe\{\}ps} } --~ test { oeps \} \[\] oeps \setupxxx[oeps=bla]} --~ test $$ \hbox{$ oeps \} \[\] oeps $} $$ --~ {$x\$xx$ $ --~ ]] --~ str = string.rep(str,10) function scripts.checker.check(filename) local str = io.loaddata(filename) if str then validator.check(str) local errors = validator.errors if #errors > 0 then for k=1,#errors do local v = errors[k] local kind, position, line = v[1], v[2], v[3] local data = str:sub(position-30,position+30) data = data:gsub("(.)", { ["\n"] = " ", ["\r"] = " ", ["\t"] = " ", }) data = data:gsub("^ *","") print(string.format("% 5i %-10s %s", line, kind, data)) end else print("no error") end else print("no file") end end if environment.argument("check") then scripts.checker.check(environment.files[1]) elseif environment.argument("help") then application.help() elseif environment.files[1] then scripts.checker.check(environment.files[1]) else application.help() end