diff options
Diffstat (limited to 'tex/context/base/luat-mac.lua')
-rw-r--r-- | tex/context/base/luat-mac.lua | 868 |
1 files changed, 434 insertions, 434 deletions
diff --git a/tex/context/base/luat-mac.lua b/tex/context/base/luat-mac.lua index 19f4d108b..c8be06b63 100644 --- a/tex/context/base/luat-mac.lua +++ b/tex/context/base/luat-mac.lua @@ -1,434 +1,434 @@ -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"
-}
-
--- Sometimes we run into situations like:
---
--- \def\foo#1{\expandafter\def\csname#1\endcsname}
---
--- As this confuses the parser, the following should be used instead:
---
--- \def\foo#1{\expandafter\normaldef\csname#1\endcsname}
-
-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 filesuffix = file.suffix
-local convertlmxstring = lmx and lmx.convertstring
-
-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("#",2^(ns-1))
- 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") + S("egx") * P("def")) -- tex
-local setter = escape * P("set") * (P("u")^-1 * S("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
-
-local definer = escape * (P("u")^-1 * S("egx")^-1 * P("def")) -- tex
-
--- 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")
------ 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 = P { leftbrace * ((identifier + V(1) + (1 - leftbrace - rightbrace))^0) * rightbrace }
-
-local function matcherror(str,pos)
- report_macros("runaway definition at: %s",sub(str,pos-30,pos))
-end
-
-local csname_endcsname = P("\\csname") * (identifier + (1 - P("\\endcsname")))^1
-
-local grammar = { "converter",
- texcode = pushlocal
- * startcode
- * spaces
- * (csname * spaces)^1 -- new: multiple, new:csname instead of name
- -- * (declaration + furthercomment + (1 - newline - space))^0
- * ((declaration * (space^0/""))^1 + furthercomment + (1 - newline - space))^0 -- accepts #a #b #c
- * V("texbody")
- * stopcode
- * poplocal,
- texbody = ( V("definition")
- + identifier
- + V("braced")
- + (1 - stopcode)
- )^0,
- definition = pushlocal
- * definer
- * spaces^0
- * escapedname
--- * (declaration + furthercomment + commentline + (1-leftbrace))^0
- * (declaration + furthercomment + commentline + csname_endcsname + (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
- + leadingcomment -- new per 2012-05-15 (message on mailing list)
- + 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 filesuffix(filename) == "mkvi" or lpegmatch(checker,str) == "mkvi" then
--- local oldsize = #str
--- str = lpegmatch(parser,str,1,true) or str
--- pushtarget("log")
--- report_macros("processed mkvi file %a, delta %s",filename,oldsize-#str)
--- poptarget("log")
--- end
--- return str
--- end
---
--- utilities.sequencers.appendaction(resolvers.openers.helpers.textfileactions,"system","resolvers.macros.processmkvi")
-
--- the document variables hack is temporary
-
-local processors = { }
-
-function processors.mkvi(str,filename)
- local oldsize = #str
- str = lpegmatch(parser,str,1,true) or str
- pushtarget("log")
- report_macros("processed mkvi file %a, delta %s",filename,oldsize-#str)
- poptarget("log")
- return str
-end
-
-function processors.mkix(str,filename) -- we could intercept earlier so that caching works better
- if not document then -- because now we hash the string as well as the
- document = { }
- end
- if not document.variables then
- document.variables = { }
- end
- local oldsize = #str
- str = convertlmxstring(str,document.variables,false) or str
- pushtarget("log")
- report_macros("processed mkix file %a, delta %s",filename,oldsize-#str)
- poptarget("log")
- return str
-end
-
-function processors.mkxi(str,filename)
- if not document then
- document = { }
- end
- if not document.variables then
- document.variables = { }
- end
- local oldsize = #str
- str = convertlmxstring(str,document.variables,false) or str
- str = lpegmatch(parser,str,1,true) or str
- pushtarget("log")
- report_macros("processed mkxi file %a, delta %s",filename,oldsize-#str)
- poptarget("log")
- return str
-end
-
-function macros.processmk(str,filename)
- if filename then
- local suffix = filesuffix(filename)
- local processor = processors[suffix] or processors[lpegmatch(checker,str)]
- if processor then
- str = processor(str,filename)
- end
- end
- return str
-end
-
-function macros.processmkvi(str,filename)
- if filename and filesuffix(filename) == "mkvi" or lpegmatch(checker,str) == "mkvi" then
- local oldsize = #str
- str = lpegmatch(parser,str,1,true) or str
- pushtarget("log")
- report_macros("processed mkvi file %a, delta %s",filename,oldsize-#str)
- poptarget("log")
- end
- return str
-end
-
-local sequencers = utilities.sequencers
-
-if sequencers then
-
- sequencers.appendaction(resolvers.openers.helpers.textfileactions,"system","resolvers.macros.processmk")
- sequencers.appendaction(resolvers.openers.helpers.textfileactions,"system","resolvers.macros.processmkvi")
-
-end
-
--- bonus
-
-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 filesuffix(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 %a, 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 !
-
-end
-
--- print(macros.preprocessed(
--- [[
--- \starttexdefinition unexpanded test #aa #bb #cc
--- test
--- \stoptexdefinition
--- ]]))
-
--- print(macros.preprocessed([[\checked \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\x[#a][#b][#c]{\setvalue{\y{#a}\z{#b}}{#c}}]]))
--- 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}
--- ]]))
---
--- print(macros.preprocessed([[
--- \def\dosomething#content{%%% {{
--- % { }{{ %%
--- \bgroup\italic#content\egroup
--- }
--- ]]))
---
--- print(macros.preprocessed([[
--- \unexpanded\def\start#tag#stoptag%
--- {\initialize{#tag}%
--- \normalexpanded
--- {\def\yes[#one]#two\csname\e!stop#stoptag\endcsname{\command_yes[#one]{#two}}%
--- \def\nop #one\csname\e!stop#stoptag\endcsname{\command_nop {#one}}}%
--- \doifnextoptionalelse\yes\nop}
--- ]]))
---
--- print(macros.preprocessed([[
--- \normalexpanded{\long\def\expandafter\noexpand\csname\e!start\v!interactionmenu\endcsname[#tag]#content\expandafter\noexpand\csname\e!stop\v!interactionmenu\endcsname}%
--- {\def\currentinteractionmenu{#tag}%
--- \expandafter\settrue\csname\??menustate\interactionmenuparameter\c!category\endcsname
--- \setinteractionmenuparameter\c!menu{#content}}
--- ]]))
---
--- Just an experiment:
---
--- \catcode\numexpr"10FF25=\commentcatcode %% > 110000 is invalid
---
--- We could have a push/pop mechanism but binding to txtcatcodes
--- is okay too.
-
-local txtcatcodes = false -- also signal and yet unknown
-
-local commentsignal = utf.char(0x10FF25)
-
-local encodecomment = P("%%") / commentsignal --
------ encodepattern = Cs(((1-encodecomment)^0 * encodecomment)) -- strips but not nice for verbatim
-local encodepattern = Cs((encodecomment + 1)^0)
-local decodecomment = P(commentsignal) / "%%%%" -- why doubles here?
-local decodepattern = Cs((decodecomment + 1)^0)
-
-function resolvers.macros.encodecomment(str)
- if txtcatcodes and tex.catcodetable == txtcatcodes then
- return lpegmatch(encodepattern,str) or str
- else
- return str
- end
-end
-
-function resolvers.macros.decodecomment(str) -- normally not needed
- return txtcatcodes and lpegmatch(decodepattern,str) or str
-end
-
--- resolvers.macros.commentsignal = commentsignal
--- resolvers.macros.encodecommentpattern = encodepattern
--- resolvers.macros.decodecommentpattern = decodepattern
-
-function resolvers.macros.enablecomment(thecatcodes)
- if not txtcatcodes then
- txtcatcodes = thecatcodes or catcodes.numbers.txtcatcodes
- utilities.sequencers.appendaction(resolvers.openers.helpers.textlineactions,"system","resolvers.macros.encodecomment")
- end
-end
+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" +} + +-- Sometimes we run into situations like: +-- +-- \def\foo#1{\expandafter\def\csname#1\endcsname} +-- +-- As this confuses the parser, the following should be used instead: +-- +-- \def\foo#1{\expandafter\normaldef\csname#1\endcsname} + +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 filesuffix = file.suffix +local convertlmxstring = lmx and lmx.convertstring + +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("#",2^(ns-1)) + 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") + S("egx") * P("def")) -- tex +local setter = escape * P("set") * (P("u")^-1 * S("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 + +local definer = escape * (P("u")^-1 * S("egx")^-1 * P("def")) -- tex + +-- 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") +----- 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 = P { leftbrace * ((identifier + V(1) + (1 - leftbrace - rightbrace))^0) * rightbrace } + +local function matcherror(str,pos) + report_macros("runaway definition at: %s",sub(str,pos-30,pos)) +end + +local csname_endcsname = P("\\csname") * (identifier + (1 - P("\\endcsname")))^1 + +local grammar = { "converter", + texcode = pushlocal + * startcode + * spaces + * (csname * spaces)^1 -- new: multiple, new:csname instead of name + -- * (declaration + furthercomment + (1 - newline - space))^0 + * ((declaration * (space^0/""))^1 + furthercomment + (1 - newline - space))^0 -- accepts #a #b #c + * V("texbody") + * stopcode + * poplocal, + texbody = ( V("definition") + + identifier + + V("braced") + + (1 - stopcode) + )^0, + definition = pushlocal + * definer + * spaces^0 + * escapedname +-- * (declaration + furthercomment + commentline + (1-leftbrace))^0 + * (declaration + furthercomment + commentline + csname_endcsname + (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 + + leadingcomment -- new per 2012-05-15 (message on mailing list) + + 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 filesuffix(filename) == "mkvi" or lpegmatch(checker,str) == "mkvi" then +-- local oldsize = #str +-- str = lpegmatch(parser,str,1,true) or str +-- pushtarget("log") +-- report_macros("processed mkvi file %a, delta %s",filename,oldsize-#str) +-- poptarget("log") +-- end +-- return str +-- end +-- +-- utilities.sequencers.appendaction(resolvers.openers.helpers.textfileactions,"system","resolvers.macros.processmkvi") + +-- the document variables hack is temporary + +local processors = { } + +function processors.mkvi(str,filename) + local oldsize = #str + str = lpegmatch(parser,str,1,true) or str + pushtarget("log") + report_macros("processed mkvi file %a, delta %s",filename,oldsize-#str) + poptarget("log") + return str +end + +function processors.mkix(str,filename) -- we could intercept earlier so that caching works better + if not document then -- because now we hash the string as well as the + document = { } + end + if not document.variables then + document.variables = { } + end + local oldsize = #str + str = convertlmxstring(str,document.variables,false) or str + pushtarget("log") + report_macros("processed mkix file %a, delta %s",filename,oldsize-#str) + poptarget("log") + return str +end + +function processors.mkxi(str,filename) + if not document then + document = { } + end + if not document.variables then + document.variables = { } + end + local oldsize = #str + str = convertlmxstring(str,document.variables,false) or str + str = lpegmatch(parser,str,1,true) or str + pushtarget("log") + report_macros("processed mkxi file %a, delta %s",filename,oldsize-#str) + poptarget("log") + return str +end + +function macros.processmk(str,filename) + if filename then + local suffix = filesuffix(filename) + local processor = processors[suffix] or processors[lpegmatch(checker,str)] + if processor then + str = processor(str,filename) + end + end + return str +end + +function macros.processmkvi(str,filename) + if filename and filesuffix(filename) == "mkvi" or lpegmatch(checker,str) == "mkvi" then + local oldsize = #str + str = lpegmatch(parser,str,1,true) or str + pushtarget("log") + report_macros("processed mkvi file %a, delta %s",filename,oldsize-#str) + poptarget("log") + end + return str +end + +local sequencers = utilities.sequencers + +if sequencers then + + sequencers.appendaction(resolvers.openers.helpers.textfileactions,"system","resolvers.macros.processmk") + sequencers.appendaction(resolvers.openers.helpers.textfileactions,"system","resolvers.macros.processmkvi") + +end + +-- bonus + +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 filesuffix(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 %a, 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 ! + +end + +-- print(macros.preprocessed( +-- [[ +-- \starttexdefinition unexpanded test #aa #bb #cc +-- test +-- \stoptexdefinition +-- ]])) + +-- print(macros.preprocessed([[\checked \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\x[#a][#b][#c]{\setvalue{\y{#a}\z{#b}}{#c}}]])) +-- 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} +-- ]])) +-- +-- print(macros.preprocessed([[ +-- \def\dosomething#content{%%% {{ +-- % { }{{ %% +-- \bgroup\italic#content\egroup +-- } +-- ]])) +-- +-- print(macros.preprocessed([[ +-- \unexpanded\def\start#tag#stoptag% +-- {\initialize{#tag}% +-- \normalexpanded +-- {\def\yes[#one]#two\csname\e!stop#stoptag\endcsname{\command_yes[#one]{#two}}% +-- \def\nop #one\csname\e!stop#stoptag\endcsname{\command_nop {#one}}}% +-- \doifnextoptionalelse\yes\nop} +-- ]])) +-- +-- print(macros.preprocessed([[ +-- \normalexpanded{\long\def\expandafter\noexpand\csname\e!start\v!interactionmenu\endcsname[#tag]#content\expandafter\noexpand\csname\e!stop\v!interactionmenu\endcsname}% +-- {\def\currentinteractionmenu{#tag}% +-- \expandafter\settrue\csname\??menustate\interactionmenuparameter\c!category\endcsname +-- \setinteractionmenuparameter\c!menu{#content}} +-- ]])) +-- +-- Just an experiment: +-- +-- \catcode\numexpr"10FF25=\commentcatcode %% > 110000 is invalid +-- +-- We could have a push/pop mechanism but binding to txtcatcodes +-- is okay too. + +local txtcatcodes = false -- also signal and yet unknown + +local commentsignal = utf.char(0x10FF25) + +local encodecomment = P("%%") / commentsignal -- +----- encodepattern = Cs(((1-encodecomment)^0 * encodecomment)) -- strips but not nice for verbatim +local encodepattern = Cs((encodecomment + 1)^0) +local decodecomment = P(commentsignal) / "%%%%" -- why doubles here? +local decodepattern = Cs((decodecomment + 1)^0) + +function resolvers.macros.encodecomment(str) + if txtcatcodes and tex.catcodetable == txtcatcodes then + return lpegmatch(encodepattern,str) or str + else + return str + end +end + +function resolvers.macros.decodecomment(str) -- normally not needed + return txtcatcodes and lpegmatch(decodepattern,str) or str +end + +-- resolvers.macros.commentsignal = commentsignal +-- resolvers.macros.encodecommentpattern = encodepattern +-- resolvers.macros.decodecommentpattern = decodepattern + +function resolvers.macros.enablecomment(thecatcodes) + if not txtcatcodes then + txtcatcodes = thecatcodes or catcodes.numbers.txtcatcodes + utilities.sequencers.appendaction(resolvers.openers.helpers.textlineactions,"system","resolvers.macros.encodecomment") + end +end |