summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/luat-mac.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/luat-mac.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/luat-mac.lua154
1 files changed, 108 insertions, 46 deletions
diff --git a/Master/texmf-dist/tex/context/base/luat-mac.lua b/Master/texmf-dist/tex/context/base/luat-mac.lua
index 0dc6593c659..75d52781c93 100644
--- a/Master/texmf-dist/tex/context/base/luat-mac.lua
+++ b/Master/texmf-dist/tex/context/base/luat-mac.lua
@@ -6,6 +6,20 @@ if not modules then modules = { } end modules ['luat-mac'] = {
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}
+
+-- todo:
+--
+-- \def\dosomething#content{%%%<= fine with “#1”
+-- % { %%% Open unbalanced brace breaks macros.
+-- }
+
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
@@ -28,7 +42,7 @@ local function set(s)
local ns = #stack
local h = hashes[ns]
if not h then
- h = rep("#",ns)
+ h = rep("#",2^(ns-1))
hashes[ns] = h
end
m = h .. n
@@ -84,8 +98,8 @@ 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
+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
@@ -112,7 +126,7 @@ local poplocal = always / pop
local declaration = variable / set
local identifier = variable / get
-local argument = leftbrace * ((identifier + (1-rightbrace))^0) * rightbrace
+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))
@@ -122,9 +136,9 @@ local grammar = { "converter",
texcode = pushlocal
* startcode
* spaces
- * name
- * spaces
- * (declaration + furthercomment + (1 - newline - space))^0
+ * (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,
@@ -230,42 +244,90 @@ 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([[\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}
---~ ]]))
+-- print(macros.preprocessed(
+-- [[
+-- \starttexdefinition unexpanded test #aa #bb #cc
+-- test
+-- \stoptexdefinition
+-- ]]))
+
+-- 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\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}
+-- ]]))
+
+-- 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