diff options
Diffstat (limited to 'tex/context/base/luat-mac.lua')
-rw-r--r-- | tex/context/base/luat-mac.lua | 140 |
1 files changed, 108 insertions, 32 deletions
diff --git a/tex/context/base/luat-mac.lua b/tex/context/base/luat-mac.lua index 1b9e09951..775e8a3b5 100644 --- a/tex/context/base/luat-mac.lua +++ b/tex/context/base/luat-mac.lua @@ -6,13 +6,15 @@ if not modules then modules = { } end modules ['luat-mac'] = { license = "see context related readme files" } -local P, V, S, R, C, Cs, Cmt = lpeg.P, lpeg.V, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs, lpeg.Cmt +local P, V, S, R, C, Cs, Cmt, Carg = lpeg.P, lpeg.V, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs, lpeg.Cmt, lpeg.Carg local lpegmatch, patterns = lpeg.match, lpeg.patterns local insert, remove = table.insert, table.remove local rep, sub = string.rep, string.sub local setmetatable = setmetatable +local pushtarget, poptarget = logs.pushtarget, logs.poptarget + local report_macros = logs.reporter("interface","macros") local stack, top, n, hashes = { }, nil, 0, { } @@ -37,8 +39,17 @@ local function set(s) end local function get(s) - local m = top and top[s] or s - return m + if not top then + report_macros("keeping #%s, no stack",s) + return "#" .. s -- can be lua + end + local m = top[s] + if m then + return m + else + report_macros("keeping #%s, not on stack",s) + return "#" .. s -- quite likely an error + end end local function push() @@ -64,24 +75,44 @@ local spaces = space^1 local newline = patterns.newline local nobrace = 1 - leftbrace - rightbrace -local longleft = leftbrace -- P("(") -local longright = rightbrace -- P(")") -local nolong = 1 - longleft - longright - -local name = R("AZ","az")^1 -- @?! -- utf? -local longname = (longleft/"") * (nolong^1) * (longright/"") -local variable = P("#") * Cs(name + longname) -local escapedname = escape * name -local definer = escape * (P("def") + P("egdx") * P("def")) -local startcode = P("\\starttexdefinition") -local stopcode = P("\\stoptexdefinition") -local anything = patterns.anything -local always = patterns.alwaysmatched - -local pushlocal = always / push -local poplocal = always / pop -local declaration = variable / set -local identifier = variable / get +local longleft = leftbrace -- P("(") +local longright = rightbrace -- P(")") +local nolong = 1 - longleft - longright + +local name = R("AZ","az")^1 +local csname = (R("AZ","az") + S("@?!_"))^1 +local longname = (longleft/"") * (nolong^1) * (longright/"") +local variable = P("#") * Cs(name + longname) +local escapedname = escape * csname +local definer = escape * (P("def") + P("egx") * P("def")) -- tex +local setter = escape * P("set") * (P("u")^-1 * P("egx")^-1) * P("value") -- context specific +--- + escape * P("install") * (1-P("handler"))^1 * P("handler") -- context specific +local startcode = P("\\starttexdefinition") -- context specific +local stopcode = P("\\stoptexdefinition") -- context specific +local anything = patterns.anything +local always = patterns.alwaysmatched + +-- The comment nilling can become an option but it nicely compensates the Lua +-- parsing here with less parsing at the TeX end. We keep lines so the errors +-- get reported all right, but comments are never seen there anyway. We keep +-- comment that starts inline as it can be something special with a % (at some +-- point we can do that as well, esp if we never use \% or `% somewhere +-- unpredictable). We need to skip comments anyway. Hm, too tricky, this +-- stripping as we can have Lua code etc. + +local commenttoken = P("%") +local crorlf = S("\n\r") +local commentline = commenttoken * ((Carg(1) * C((1-crorlf)^0))/function(strip,s) return strip and "" or s end) +local commentline = commenttoken * ((1-crorlf)^0) +local leadingcomment = (commentline * crorlf^1)^1 +local furthercomment = (crorlf^1 * commentline)^1 + +local pushlocal = always / push +local poplocal = always / pop +local declaration = variable / set +local identifier = variable / get + +local argument = leftbrace * ((identifier + (1-rightbrace))^0) * rightbrace local function matcherror(str,pos) report_macros("runaway definition at: %s",sub(str,pos-30,pos)) @@ -93,7 +124,7 @@ local grammar = { "converter", * spaces * name * spaces - * (declaration + (1 - newline - space))^0 + * (declaration + furthercomment + (1 - newline - space))^0 * V("texbody") * stopcode * poplocal, @@ -105,20 +136,33 @@ local grammar = { "converter", definition = pushlocal * definer * escapedname - * (declaration + (1-leftbrace))^0 + * (declaration + furthercomment + commentline + (1-leftbrace))^0 + * V("braced") + * poplocal, + setcode = pushlocal + * setter + * argument + * (declaration + furthercomment + commentline + (1-leftbrace))^0 * V("braced") * poplocal, braced = leftbrace * ( V("definition") + identifier + + V("setcode") + V("texcode") + V("braced") + + furthercomment + nobrace )^0 -- * rightbrace^-1, -- the -1 catches errors * (rightbrace + Cmt(always,matcherror)), - pattern = V("definition") + V("texcode") + anything, + pattern = leadingcomment + + V("definition") + + V("setcode") + + V("texcode") + + furthercomment + + anything, converter = V("pattern")^1, } @@ -132,8 +176,8 @@ local checker = P("%") * (1 - newline - P("macros"))^0 local macros = { } resolvers.macros = macros -function macros.preprocessed(str) - return lpegmatch(parser,str) +function macros.preprocessed(str,strip) + return lpegmatch(parser,str,1,strip) end function macros.convertfile(oldname,newname) -- beware, no testing on oldname == newname @@ -148,7 +192,11 @@ end function macros.processmkvi(str,filename) if (filename and file.suffix(filename) == "mkvi") or lpegmatch(checker,str) == "mkvi" then - return lpegmatch(parser,str) or str + local result = lpegmatch(parser,str,1,true) or str + pushtarget("log") + report_macros("processed file '%s', delta %s",filename,#str-#result) + poptarget("log") + return result else return str end @@ -160,9 +208,17 @@ if resolvers.schemes then local hashed = url.hashed(name) local path = hashed.path if path and path ~= "" then - local data = resolvers.loadtexfile(path) - data = lpegmatch(parser,data) or "" - io.savedata(cachename,data) + local str = resolvers.loadtexfile(path) + if file.suffix(path) == "mkvi" or lpegmatch(checker,str) == "mkvi" then + -- already done automatically + io.savedata(cachename,str) + else + local result = lpegmatch(parser,str,1,true) or str + pushtarget("log") + report_macros("processed scheme '%s', delta %s",filename,#str-#result) + poptarget("log") + io.savedata(cachename,result) + end end return cachename end @@ -174,12 +230,32 @@ if resolvers.schemes then end +--~ print(macros.preprocessed([[\def\bla#bla{bla#{bla}}]])) +--~ print(macros.preprocessed([[\def\bla#bla{#{bla}bla}]])) --~ print(macros.preprocessed([[\def\blä#{blá}{blà:#{blá}}]])) --~ print(macros.preprocessed([[\def\blä#bla{blà:#bla}]])) ---~ print(macros.preprocessed([[\def\bla#bla{bla:#bla}]])) +--~ print(macros.preprocessed([[\setvalue{xx}#bla{blà:#bla}]])) +--~ print(macros.preprocessed([[\def\foo#bar{\setvalue{xx#bar}{#bar}}]])) +--~ print(macros.preprocessed([[\def\bla#bla{bla:#{bla}}]])) +--~ print(macros.preprocessed([[\def\bla_bla#bla{bla:#bla}]])) --~ print(macros.preprocessed([[\def\test#oeps{test:#oeps}]])) +--~ print(macros.preprocessed([[\def\test_oeps#oeps{test:#oeps}]])) --~ print(macros.preprocessed([[\def\test#oeps{test:#{oeps}}]])) --~ print(macros.preprocessed([[\def\test#{oeps:1}{test:#{oeps:1}}]])) --~ print(macros.preprocessed([[\def\test#{oeps}{test:#oeps}]])) ---~ macros.preprocessed([[\def\test#{oeps}{test:#oeps \halign{##\cr #oeps\cr}]]) +--~ print(macros.preprocessed([[\def\test#{oeps}{test:#oeps \halign{##\cr #oeps\cr}]])) --~ print(macros.preprocessed([[\def\test#{oeps}{test:#oeps \halign{##\cr #oeps\cr}}]])) +--~ print(macros.preprocessed([[% test +--~ \def\test#oeps{#oeps} % {test} +--~ % test +--~ +--~ % test +--~ two +--~ %test]])) +--~ print(macros.preprocessed([[ +--~ \def\scrn_button_make_normal#namespace#current#currentparameter#text% +--~ {\ctxlua{structures.references.injectcurrentset(nil,nil)}% +--~ % \hbox attr \referenceattribute \lastreferenceattribute {\localframed[#namespace:#current]{#text}}} +--~ \hbox attr \referenceattribute \lastreferenceattribute {\directlocalframed[#namespace:#current]{#text}}} +--~ ]])) + |