diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2011-06-01 08:54:21 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2011-06-01 08:54:21 +0000 |
commit | d7ccb42582f85acf30568913610ccf4d602023fb (patch) | |
tree | 7292e3545a420676878e7451b68892d360c62cb6 /Master/texmf-dist/tex/context/base/luat-mac.lua | |
parent | 2d62a6fe9b80def59c392268022f1f9a2d6e358f (diff) |
commit context 2011.05.18
git-svn-id: svn://tug.org/texlive/trunk@22719 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/luat-mac.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/luat-mac.lua | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/luat-mac.lua b/Master/texmf-dist/tex/context/base/luat-mac.lua new file mode 100644 index 00000000000..0dc6593c659 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/luat-mac.lua @@ -0,0 +1,271 @@ +if not modules then modules = { } end modules ['luat-mac'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +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, { } + +local function set(s) + if top then + n = n + 1 + if n > 9 then + report_macros("number of arguments > 9, ignoring %s",s) + else + local ns = #stack + local h = hashes[ns] + if not h then + h = rep("#",ns) + hashes[ns] = h + end + m = h .. n + top[s] = m + return m + end + end +end + +local function get(s) + 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() + top = { } + n = 0 + local s = stack[#stack] + if s then + setmetatable(top,{ __index = s }) + end + insert(stack,top) +end + +local function pop() + top = remove(stack) +end + +local leftbrace = P("{") -- will be in patterns +local rightbrace = P("}") +local escape = P("\\") + +local space = patterns.space +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 +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)) +end + +local grammar = { "converter", + texcode = pushlocal + * startcode + * spaces + * name + * spaces + * (declaration + furthercomment + (1 - newline - space))^0 + * V("texbody") + * stopcode + * poplocal, + texbody = ( V("definition") + + identifier + + V("braced") + + (1 - stopcode) + )^0, + definition = pushlocal + * definer + * escapedname + * (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 = leadingcomment + + V("definition") + + V("setcode") + + V("texcode") + + furthercomment + + anything, + + converter = V("pattern")^1, +} + +local parser = Cs(grammar) + +local checker = P("%") * (1 - newline - P("macros"))^0 + * P("macros") * space^0 * P("=") * space^0 * C(patterns.letter^1) + +-- maybe namespace + +local macros = { } resolvers.macros = macros + +function macros.preprocessed(str,strip) + return lpegmatch(parser,str,1,strip) +end + +function macros.convertfile(oldname,newname) -- beware, no testing on oldname == newname + local data = resolvers.loadtexfile(oldname) + data = interfaces.preprocessed(data) or "" + io.savedata(newname,data) +end + +function macros.version(data) + return lpegmatch(checker,data) +end + +function macros.processmkvi(str,filename) + if (filename and file.suffix(filename) == "mkvi") or lpegmatch(checker,str) == "mkvi" then + 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 +end + +if resolvers.schemes then + + local function handler(protocol,name,cachename) + local hashed = url.hashed(name) + local path = hashed.path + if path and path ~= "" then + 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 + + resolvers.schemes.install('mkvi',handler,1) -- this will cache ! + + utilities.sequencers.appendaction(resolvers.openers.helpers.textfileactions,"system","resolvers.macros.processmkvi") + -- utilities.sequencers.disableaction(resolvers.openers.helpers.textfileactions,"resolvers.macros.processmkvi") + +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([[\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}]])) +--~ 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}}} +--~ ]])) +--~ +--~ print(macros.preprocessed([[ +--~ \def\definefoo[#name]% +--~ {\setvalue{start#name}{\dostartfoo{#name}}} +--~ \def\dostartfoo#name% +--~ {\def\noexpand\next#content\expandafter\noexpand\csname stop#name\endcsname{#name : #content}% +--~ \next} +--~ \def\dostartfoo#name% +--~ {\normalexpanded{\def\noexpand\next#content\expandafter\noexpand\csname stop#name\endcsname}{#name : #content}% +--~ \next} +--~ ]])) |