summaryrefslogtreecommitdiff
path: root/tex/context
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/anch-pos.lua1104
-rw-r--r--tex/context/base/mkiv/back-res.lua1
-rw-r--r--tex/context/base/mkiv/buff-ini.lua37
-rw-r--r--tex/context/base/mkiv/buff-ver.lua2
-rw-r--r--tex/context/base/mkiv/buff-ver.mkiv4
-rw-r--r--tex/context/base/mkiv/cldf-ini.lua508
-rw-r--r--tex/context/base/mkiv/cldf-int.lua28
-rw-r--r--tex/context/base/mkiv/cldf-lmt.lua144
-rw-r--r--tex/context/base/mkiv/cldf-scn.lua53
-rw-r--r--tex/context/base/mkiv/colo-ini.mkxl4
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkxl2
-rw-r--r--tex/context/base/mkiv/file-mod.lua6
-rw-r--r--tex/context/base/mkiv/font-ctx.lua612
-rw-r--r--tex/context/base/mkiv/grph-chk.lua10
-rw-r--r--tex/context/base/mkiv/lpdf-ini.lua21
-rw-r--r--tex/context/base/mkiv/luat-ini.mkiv14
-rw-r--r--tex/context/base/mkiv/luat-usr.lua17
-rw-r--r--tex/context/base/mkiv/publ-aut.lua6
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin27756 -> 27704 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin253681 -> 254484 bytes
-rw-r--r--tex/context/base/mkiv/strc-itm.mklx42
-rw-r--r--tex/context/base/mkiv/strc-itm.mkvi42
-rw-r--r--tex/context/base/mkiv/syst-aux.mkxl6
-rw-r--r--tex/context/base/mkiv/syst-lua.lua10
-rw-r--r--tex/context/base/mkiv/toks-ini.lua4
-rw-r--r--tex/context/base/mkiv/toks-scn.lua211
-rw-r--r--tex/context/base/mkiv/util-str.lua86
31 files changed, 1498 insertions, 1484 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 242fe472a..380edf717 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2020.06.20 13:33}
+\newcontextversion{2020.06.25 10:55}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index bbe1f8fca..0cf1b1e6c 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.06.20 13:33}
+\edef\contextversion{2020.06.25 10:55}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua
index 2788c9d1a..da95eeb1a 100644
--- a/tex/context/base/mkiv/anch-pos.lua
+++ b/tex/context/base/mkiv/anch-pos.lua
@@ -13,16 +13,19 @@ more efficient.</p>
--ldx]]--
-- plus (extra) is obsolete but we will keep it for a while
-
+--
-- maybe replace texsp by our own converter (stay at the lua end)
-- eventually mp will have large numbers so we can use sp there too
-
--- this is one of the first modules using scanners and we need to replace
--- it by implement and friends
-
+--
+-- this is one of the first modules using scanners and we need to replace it by
+-- implement and friends
+--
-- we could have namespaces, like p, page, region, columnarea, textarea but then
-- we need virtual table accessors as well as have tag/id accessors ... we don't
-- save much here (at least not now)
+--
+-- This was the last module that got rid of directly setting scanners, with a little
+-- performance degradation but not that noticeable.
local tostring, next, setmetatable, tonumber = tostring, next, setmetatable, tonumber
local sort = table.sort
@@ -38,8 +41,7 @@ local scanstring = scanners.string
local scaninteger = scanners.integer
local scandimen = scanners.dimen
-local compilescanner = tokens.compile
-local scanners = interfaces.scanners
+local implement = interfaces.implement
local commands = commands
local context = context
@@ -124,9 +126,9 @@ local nofregular = 0
local nofspecial = 0
local splitter = lpeg.splitat(":",true)
-local pagedata = { }
-local columndata = setmetatableindex("table") -- per page
-local freedata = setmetatableindex("table") -- per page
+local pagedata = { }
+local columndata = setmetatableindex("table") -- per page
+local freedata = setmetatableindex("table") -- per page
local function initializer()
tobesaved = jobpositions.tobesaved
@@ -376,19 +378,22 @@ jobpositions.set = set
jobpositions.setspec = setspec
jobpositions.get = get
-scanners.dosaveposition = compilescanner {
+implement {
+ name = "dosaveposition",
+ arguments = { "string", "integer", "dimen", "dimen" },
actions = setall, -- name p x y
- arguments = { "string", "integer", "dimen", "dimen" }
}
-scanners.dosavepositionwhd = compilescanner { -- somehow fails
+implement {
+ name = "dosavepositionwhd",
+ arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen" },
actions = setall, -- name p x y w h d
- arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen" }
}
-scanners.dosavepositionplus = compilescanner {
+implement {
+ name = "dosavepositionplus",
+ arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen", "string" },
actions = setall, -- name p x y w h d extra
- arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen", "string" }
}
-- will become private table (could also become attribute driven but too nasty
@@ -424,29 +429,41 @@ end
jobpositions.b_column = b_column
jobpositions.e_column = e_column
-scanners.bposcolumn = function() -- tag
- local tag = scanstring()
- insert(columns,tag)
- column = tag
-end
+implement {
+ name = "bposcolumn",
+ arguments = "string",
+ actions = function(tag)
+ insert(columns,tag)
+ column = tag
+ end
+}
-scanners.bposcolumnregistered = function() -- tag
- local tag = scanstring()
- insert(columns,tag)
- column = tag
- ctx_latelua { action = b_column, tag = tag }
-end
+implement {
+ name = "bposcolumnregistered",
+ arguments = "string",
+ actions = function(tag)
+ insert(columns,tag)
+ column = tag
+ ctx_latelua { action = b_column, tag = tag }
+ end
+}
-scanners.eposcolumn = function()
- remove(columns)
- column = columns[#columns]
-end
+implement {
+ name = "eposcolumn",
+ actions = function()
+ remove(columns)
+ column = columns[#columns]
+ end
+}
-scanners.eposcolumnregistered = function()
- ctx_latelua { action = e_column }
- remove(columns)
- column = columns[#columns]
-end
+implement {
+ name = "eposcolumnregistered",
+ actions = function()
+ ctx_latelua { action = e_column }
+ remove(columns)
+ column = columns[#columns]
+ end
+}
-- regions
@@ -551,167 +568,181 @@ end
local nofparagraphs = 0
-scanners.parpos = function()
- nofparagraphs = nofparagraphs + 1
- texsetcount("global","c_anch_positions_paragraph",nofparagraphs)
- local box = getbox("strutbox")
- local w, h, d = getwhd(box)
- local t = {
- p = true,
- c = true,
- r = true,
- x = true,
- y = true,
- h = h,
- d = d,
- hs = texget("hsize"), -- never 0
- }
- local leftskip = texget("leftskip",false)
- local rightskip = texget("rightskip",false)
- local hangindent = texget("hangindent")
- local hangafter = texget("hangafter")
- local parindent = texget("parindent")
- local parshape = texget("parshape")
- if leftskip ~= 0 then
- t.ls = leftskip
- end
- if rightskip ~= 0 then
- t.rs = rightskip
- end
- if hangindent ~= 0 then
- t.hi = hangindent
- end
- if hangafter ~= 1 and hangafter ~= 0 then -- can not be zero .. so it needs to be 1 if zero
- t.ha = hangafter
- end
- if parindent ~= 0 then
- t.pi = parindent
- end
- if parshape and #parshape > 0 then
- t.ps = parshape
+implement {
+ name = "parpos",
+ actions = function()
+ nofparagraphs = nofparagraphs + 1
+ texsetcount("global","c_anch_positions_paragraph",nofparagraphs)
+ local box = getbox("strutbox")
+ local w, h, d = getwhd(box)
+ local t = {
+ p = true,
+ c = true,
+ r = true,
+ x = true,
+ y = true,
+ h = h,
+ d = d,
+ hs = texget("hsize"), -- never 0
+ }
+ local leftskip = texget("leftskip",false)
+ local rightskip = texget("rightskip",false)
+ local hangindent = texget("hangindent")
+ local hangafter = texget("hangafter")
+ local parindent = texget("parindent")
+ local parshape = texget("parshape")
+ if leftskip ~= 0 then
+ t.ls = leftskip
+ end
+ if rightskip ~= 0 then
+ t.rs = rightskip
+ end
+ if hangindent ~= 0 then
+ t.hi = hangindent
+ end
+ if hangafter ~= 1 and hangafter ~= 0 then -- can not be zero .. so it needs to be 1 if zero
+ t.ha = hangafter
+ end
+ if parindent ~= 0 then
+ t.pi = parindent
+ end
+ if parshape and #parshape > 0 then
+ t.ps = parshape
+ end
+ local name = f_p_tag(nofparagraphs)
+ tobesaved[name] = t
+ ctx_latelua { action = enhance, specification = t }
end
- local name = f_p_tag(nofparagraphs)
- tobesaved[name] = t
- ctx_latelua { action = enhance, specification = t }
-end
+}
-scanners.dosetposition = function() -- name
- local name = scanstring()
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetcount("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
-end
+implement {
+ name = "dosetposition",
+ arguments = "string",
+ actions = function(name)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetcount("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+}
-scanners.dosetpositionwhd = function() -- name w h d extra
- local name = scanstring()
- local w = scandimen()
- local h = scandimen()
- local d = scandimen()
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- w = w ~= 0 and w or nil,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetcount("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
-end
+implement {
+ name = "dosetpositionwhd",
+ arguments = { "string", "dimen", "dimen", "dimen" },
+ actions = function(name,w,h,d)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ w = w ~= 0 and w or nil,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetcount("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+}
-scanners.dosetpositionbox = function() -- name box
- local name = scanstring()
- local box = getbox(scaninteger())
- local w, h, d = getwhd(box)
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- w = w ~= 0 and w or nil,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetcount("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
-end
+implement {
+ name = "dosetpositionbox",
+ arguments = { "string", "integer" },
+ actions = function(name,n)
+ local box = getbox(n)
+ local w, h, d = getwhd(box)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ w = w ~= 0 and w or nil,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetcount("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+}
-scanners.dosetpositionplus = function() -- name w h d extra
- local name = scanstring()
- local w = scandimen()
- local h = scandimen()
- local d = scandimen()
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- w = w ~= 0 and w or nil,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- e = scanstring(),
- r2l = texgetcount("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
-end
+implement {
+ name = "dosetpositionplus",
+ arguments = { "string", "dimen", "dimen", "dimen" },
+ actions = function(name,w,h,d)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ w = w ~= 0 and w or nil,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ e = scanstring(),
+ r2l = texgetcount("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+}
-scanners.dosetpositionstrut = function() -- name
- local name = scanstring()
- local box = getbox("strutbox")
- local w, h, d = getwhd(box)
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetcount("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
-end
+implement {
+ name = "dosetpositionstrut",
+ arguments = "string",
+ actions = function(name)
+ local box = getbox("strutbox")
+ local w, h, d = getwhd(box)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetcount("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+}
-scanners.dosetpositionstrutkind = function() -- name
- local name = scanstring()
- local kind = scaninteger()
- local box = getbox("strutbox")
- local w, h, d = getwhd(box)
- local spec = {
- k = kind,
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetcount("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
-end
+implement {
+ name = "dosetpositionstrutkind",
+ arguments = { "string", "integer" },
+ actions = function(name,kind)
+ local box = getbox("strutbox")
+ local w, h, d = getwhd(box)
+ local spec = {
+ k = kind,
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetcount("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+}
function jobpositions.getreserved(tag,n)
if tag == v_column then
@@ -990,166 +1021,222 @@ jobpositions.columnofpos = columnofpos
-- interface
-scanners.replacepospxywhd = function() -- name page x y w h d
- collected[scanstring()] = {
- p = scaninteger(),
- x = scandimen(),
- y = scandimen(),
- w = scandimen(),
- h = scandimen(),
- d = scandimen(),
- }
-end
+implement {
+ name = "replacepospxywhd",
+ arguments = { "string", "integer", "dimen", "dimen", "dimen", "dimen", "dimen" },
+ actions = function(name,page,x,y,w,h,d)
+ collected[name] = {
+ p = page,
+ x = x,
+ y = y,
+ w = w,
+ h = h,
+ d = d,
+ }
+ end
+}
-scanners.copyposition = function() -- target source
- collected[scanstring()] = collected[scanstring()]
-end
+implement {
+ name = "copyposition",
+ arguments = "2 strings",
+ actions = function(target,source)
+ collected[target] = collected[source]
+ end
+}
-scanners.MPp = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local p = jpi.p
- if p and p ~= true then
- context(p)
- return
+implement {
+ name = "MPp",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local p = jpi.p
+ if p and p ~= true then
+ context(p)
+ return
+ end
end
+ context('0')
end
- context('0')
-end
+}
-scanners.MPx = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local x = jpi.x
- if x and x ~= true and x ~= 0 then
- context("%.5Fpt",x*pt)
- return
+implement {
+ name = "MPx",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local x = jpi.x
+ if x and x ~= true and x ~= 0 then
+ context("%.5Fpt",x*pt)
+ return
+ end
end
+ context('0pt')
end
- context('0pt')
-end
+}
-scanners.MPy = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local y = jpi.y
- if y and y ~= true and y ~= 0 then
- context("%.5Fpt",y*pt)
- return
+implement {
+ name = "MPy",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local y = jpi.y
+ if y and y ~= true and y ~= 0 then
+ context("%.5Fpt",y*pt)
+ return
+ end
end
+ context('0pt')
end
- context('0pt')
-end
+}
-scanners.MPw = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local w = jpi.w
- if w and w ~= 0 then
- context("%.5Fpt",w*pt)
- return
+implement {
+ name = "MPw",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local w = jpi.w
+ if w and w ~= 0 then
+ context("%.5Fpt",w*pt)
+ return
+ end
end
+ context('0pt')
end
- context('0pt')
-end
+}
-scanners.MPh = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local h = jpi.h
- if h and h ~= 0 then
- context("%.5Fpt",h*pt)
- return
+implement {
+ name = "MPh",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local h = jpi.h
+ if h and h ~= 0 then
+ context("%.5Fpt",h*pt)
+ return
+ end
end
+ context('0pt')
end
- context('0pt')
-end
+}
-scanners.MPd = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local d = jpi.d
- if d and d ~= 0 then
- context("%.5Fpt",d*pt)
- return
+implement {
+ name = "MPd",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local d = jpi.d
+ if d and d ~= 0 then
+ context("%.5Fpt",d*pt)
+ return
+ end
end
+ context('0pt')
end
- context('0pt')
-end
+}
-scanners.MPxy = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- context('(%.5Fpt,%.5Fpt)',
- jpi.x*pt,
- jpi.y*pt
- )
- else
- context('(0,0)')
+implement {
+ name = "MPxy",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ context('(%.5Fpt,%.5Fpt)',
+ jpi.x*pt,
+ jpi.y*pt
+ )
+ else
+ context('(0,0)')
+ end
end
-end
+}
-scanners.MPwhd = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local w = jpi.w or 0
- local h = jpi.h or 0
- local d = jpi.d or 0
- if w ~= 0 or h ~= 0 or d ~= 0 then
- context("%.5Fpt,%.5Fpt,%.5Fpt",w*pt,h*pt,d*pt)
- return
+implement {
+ name = "MPwhd",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local w = jpi.w or 0
+ local h = jpi.h or 0
+ local d = jpi.d or 0
+ if w ~= 0 or h ~= 0 or d ~= 0 then
+ context("%.5Fpt,%.5Fpt,%.5Fpt",w*pt,h*pt,d*pt)
+ return
+ end
end
+ context('0pt,0pt,0pt')
end
- context('0pt,0pt,0pt')
-end
+}
-scanners.MPll = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- context('(%.5Fpt,%.5Fpt)',
- jpi.x *pt,
- (jpi.y-jpi.d)*pt
- )
- else
- context('(0,0)') -- for mp only
+implement {
+ name = "MPll",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ context('(%.5Fpt,%.5Fpt)',
+ jpi.x *pt,
+ (jpi.y-jpi.d)*pt
+ )
+ else
+ context('(0,0)') -- for mp only
+ end
end
-end
+}
-scanners.MPlr = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- context('(%.5Fpt,%.5Fpt)',
- (jpi.x + jpi.w)*pt,
- (jpi.y - jpi.d)*pt
- )
- else
- context('(0,0)') -- for mp only
+implement {
+ name = "MPlr",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ context('(%.5Fpt,%.5Fpt)',
+ (jpi.x + jpi.w)*pt,
+ (jpi.y - jpi.d)*pt
+ )
+ else
+ context('(0,0)') -- for mp only
+ end
end
-end
+}
-scanners.MPur = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- context('(%.5Fpt,%.5Fpt)',
- (jpi.x + jpi.w)*pt,
- (jpi.y + jpi.h)*pt
- )
- else
- context('(0,0)') -- for mp only
+implement {
+ name = "MPur",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ context('(%.5Fpt,%.5Fpt)',
+ (jpi.x + jpi.w)*pt,
+ (jpi.y + jpi.h)*pt
+ )
+ else
+ context('(0,0)') -- for mp only
+ end
end
-end
+}
-scanners.MPul = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- context('(%.5Fpt,%.5Fpt)',
- jpi.x *pt,
- (jpi.y + jpi.h)*pt
- )
- else
- context('(0,0)') -- for mp only
+implement {
+ name = "MPul",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ context('(%.5Fpt,%.5Fpt)',
+ jpi.x *pt,
+ (jpi.y + jpi.h)*pt
+ )
+ else
+ context('(0,0)') -- for mp only
+ end
end
-end
+}
local function MPpos(id)
local jpi = collected[id]
@@ -1170,53 +1257,67 @@ local function MPpos(id)
context('0,0,0,0,0,0') -- for mp only
end
-scanners.MPpos = function() -- name
- MPpos(scanstring())
-end
+implement {
+ name = "MPpos",
+ arguments = "string",
+ actions = MPpos
+}
-scanners.MPn = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local n = jpi.n
- if n then
- context(n)
- return
+implement {
+ name = "MPn",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local n = jpi.n
+ if n then
+ context(n)
+ return
+ end
end
+ context(0)
end
- context(0)
-end
+}
-scanners.MPc = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local c = jpi.c
- if c and c ~= true then
- context(c)
- return
+implement {
+ name = "MPc",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local c = jpi.c
+ if c and c ~= true then
+ context(c)
+ return
+ end
end
+ context('0') -- okay ?
end
- context('0') -- okay ?
-end
+}
-scanners.MPr = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- local r = jpi.r
- if r and r ~= true then
- context(r)
- return
- end
- local p = jpi.p
- if p then
- context("page:" .. p)
+implement {
+ name = "MPr",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ local r = jpi.r
+ if r and r ~= true then
+ context(r)
+ return
+ end
+ local p = jpi.p
+ if p then
+ context("page:" .. p)
+ end
end
end
-end
+}
-local function MPpardata(n)
- local t = collected[n]
+local function MPpardata(id)
+ local t = collected[id]
if not t then
- local tag = f_p_tag(n)
+ local tag = f_p_tag(id)
t = collected[tag]
end
if t then
@@ -1233,157 +1334,213 @@ local function MPpardata(n)
end
end
-scanners.MPpardata = function() -- name
- MPpardata(scanstring())
-end
+implement {
+ name = "MPpardata",
+ arguments = "string",
+ actions = MPpardata
+}
-scanners.MPposset = function() -- name (special helper, used in backgrounds)
- local name = scanstring()
- local b = f_b_tag(name)
- local e = f_e_tag(name)
- local w = f_w_tag(name)
- local p = f_p_tag(getparagraph(b))
- MPpos(b) context(",") MPpos(e) context(",") MPpos(w) context(",") MPpos(p) context(",") MPpardata(p)
-end
+implement {
+ name = "MPposset",
+ arguments = "string",
+ actions = function(name)
+ local b = f_b_tag(name)
+ local e = f_e_tag(name)
+ local w = f_w_tag(name)
+ local p = f_p_tag(getparagraph(b))
+ MPpos(b) context(",") MPpos(e) context(",") MPpos(w) context(",") MPpos(p) context(",") MPpardata(p)
+ end
+}
-scanners.MPls = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- context("%.5Fpt",jpi.ls*pt)
- else
- context("0pt")
+implement {
+ name = "MPls",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ context("%.5Fpt",jpi.ls*pt)
+ else
+ context("0pt")
+ end
end
-end
+}
-scanners.MPrs = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- context("%.5Fpt",jpi.rs*pt)
- else
- context("0pt")
+implement {
+ name = "MPrs",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ context("%.5Fpt",jpi.rs*pt)
+ else
+ context("0pt")
+ end
end
-end
+}
local splitter = lpeg.tsplitat(",")
-scanners.MPplus = function() -- name n default
- local jpi = collected[scanstring()]
- local n = scaninteger()
- local default = scanstring()
- if jpi then
- local e = jpi.e
- if e then
- local split = jpi.split
- if not split then
- split = lpegmatch(splitter,jpi.e)
- jpi.split = split
+implement {
+ name = "MPplus",
+ arguments = { "string", "integer", "string" },
+ actions = function(name,n,default)
+ local jpi = collected[name]
+ if jpi then
+ local e = jpi.e
+ if e then
+ local split = jpi.split
+ if not split then
+ split = lpegmatch(splitter,jpi.e)
+ jpi.split = split
+ end
+ context(split[n] or default)
+ return
end
- context(split[n] or default)
- return
end
+ context(default)
end
- context(default)
-end
+}
-scanners.MPrest = function() -- name default
- local jpi = collected[scanstring()]
- local default = scanstring()
- context(jpi and jpi.e or default)
-end
+implement {
+ name = "MPrest",
+ arguments = { "string", "string" },
+ actions = function(name,default)
+ local jpi = collected[name]
+ context(jpi and jpi.e or default)
+ end
+}
-scanners.MPxywhd = function() -- name
- local jpi = collected[scanstring()]
- if jpi then
- context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt",
- jpi.x*pt,
- jpi.y*pt,
- jpi.w*pt,
- jpi.h*pt,
- jpi.d*pt
- )
- else
- context("0,0,0,0,0") -- for mp only
+implement {
+ name = "MPxywhd",
+ arguments = "string",
+ actions = function(name)
+ local jpi = collected[name]
+ if jpi then
+ context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt",
+ jpi.x*pt,
+ jpi.y*pt,
+ jpi.w*pt,
+ jpi.h*pt,
+ jpi.d*pt
+ )
+ else
+ context("0,0,0,0,0") -- for mp only
+ end
end
-end
+}
local doif = commands.doif
local doifelse = commands.doifelse
-scanners.doifelseposition = function() -- name
- doifelse(collected[scanstring()])
-end
-
-scanners.doifposition = function() -- name
- doif(collected[scanstring()])
-end
+implement {
+ name = "doifelseposition",
+ arguments = "string",
+ actions = function(name)
+ doifelse(collected[name])
+ end
+}
--- local ctx_iftrue = context.protected.cs.iftrue
--- local ctx_iffalse = context.protected.cs.iffalse
---
--- scanners.ifknownposition = function() -- name
--- (collected[scanstring()] and ctx_iftrue or ctx_iffalse)()
--- end
-
-scanners.doifelsepositiononpage = function() -- name page -- probably always realpageno
- local c = collected[scanstring()]
- local p = scaninteger()
- doifelse(c and c.p == p)
-end
+implement {
+ name = "doifposition",
+ arguments = "string",
+ actions = function(name)
+ doif(collected[name])
+ end
+}
-scanners.doifelseoverlapping = function() -- one two
- doifelse(overlapping(scanstring(),scanstring()))
-end
+implement {
+ name = "doifelsepositiononpage",
+ arguments = { "string", "integer" },
+ actions = function(name,p)
+ local c = collected[name]
+ doifelse(c and c.p == p)
+ end
+}
-scanners.doifelsepositionsonsamepage = function() -- list
- doifelse(onsamepage(scanstring()))
-end
+implement {
+ name = "doifelseoverlapping",
+ arguments = { "string", "string" },
+ actions = function(one,two)
+ doifelse(overlapping(one,two))
+ end
+}
-scanners.doifelsepositionsonthispage = function() -- list
- doifelse(onsamepage(scanstring(),tostring(texgetcount("realpageno"))))
-end
+implement {
+ name = "doifelsepositionsonsamepage",
+ arguments = "string",
+ actions = function(list)
+ doifelse(onsamepage(list))
+ end
+}
--- scanners.columnofpos = function()
--- context(columnofpos(scaninteger(),scandimen())
--- end
+implement {
+ name = "doifelsepositionsonthispage",
+ arguments = "string",
+ actions = function(list)
+ doifelse(onsamepage(list,tostring(texgetcount("realpageno"))))
+ end
+}
-scanners.doifelsepositionsused = function()
- doifelse(next(collected))
-end
+implement {
+ name = "doifelsepositionsused",
+ actions = function()
+ doifelse(next(collected))
+ end
+}
-scanners.markregionbox = function() -- box
- markregionbox(scaninteger())
-end
+implement {
+ name = "markregionbox",
+ arguments = "integer",
+ actions = markregionbox
+}
-scanners.setregionbox = function() -- box
- setregionbox(scaninteger())
-end
+implement {
+ name = "setregionbox",
+ arguments = "integer",
+ actions = setregionbox
+}
-scanners.markregionboxtagged = function() -- box tag
- markregionbox(scaninteger(),scanstring())
-end
+implement {
+ name = "markregionboxtagged",
+ arguments = { "integer", "string" },
+ actions = markregionbox
+}
-scanners.markregionboxtaggedn = function() -- box tag n
- markregionbox(scaninteger(),scanstring(),nil,
- nil,nil,nil,nil,nil,scaninteger())
-end
+implement {
+ name = "markregionboxtaggedn",
+ arguments = { "integer", "string", "integer" },
+ actions = function(box,tag,n)
+ markregionbox(box,tag,nil,nil,nil,nil,nil,nil,n)
+ end
+}
-scanners.setregionboxtagged = function() -- box tag
- setregionbox(scaninteger(),scanstring())
-end
+implement {
+ name = "setregionboxtagged",
+ arguments = { "integer", "string" },
+ actions = setregionbox
+}
-scanners.markregionboxcorrected = function() -- box tag
- markregionbox(scaninteger(),scanstring(),true)
-end
+implement {
+ name = "markregionboxcorrected",
+ arguments = { "integer", "string", true },
+ actions = markregionbox
+}
-scanners.markregionboxtaggedkind = function() -- box tag kind
- markregionbox(scaninteger(),scanstring(),nil,
- scaninteger(),scandimen(),scandimen(),scandimen(),scandimen())
-end
+implement {
+ name = "markregionboxtaggedkind",
+ arguments = { "integer", "string", "integer", "dimen", "dimen", "dimen", "dimen" },
+ actions = function(box,tag,n,d1,d2,d3,d4)
+ markregionbox(box,tag,nil,n,d1,d2,d3,d4)
+ end
+}
-scanners.reservedautoregiontag = function()
- nofregions = nofregions + 1
- context(f_region(nofregions))
-end
+implement {
+ name = "reservedautoregiontag",
+ actions = function()
+ nofregions = nofregions + 1
+ context(f_region(nofregions))
+ end
+}
-- statistics (at least for the moment, when testing)
@@ -1409,7 +1566,6 @@ end)
-- We support the low level positional commands too:
local newsavepos = nodes.pool.savepos
-local implement = interfaces.implement
implement { name = "savepos", actions = function() context(newsavepos()) end }
implement { name = "lastxpos", actions = function() context(gethpos()) end }
diff --git a/tex/context/base/mkiv/back-res.lua b/tex/context/base/mkiv/back-res.lua
index 2ca4a5ac8..4ee6d15d3 100644
--- a/tex/context/base/mkiv/back-res.lua
+++ b/tex/context/base/mkiv/back-res.lua
@@ -19,7 +19,6 @@ local scandimension = scanners.dimension
local scanword = scanners.word
local scanwhd = scanners.whd
-local scanners = interfaces.scanners
local implement = interfaces.implement
local constants = interfaces.constants
local variables = interfaces.variables
diff --git a/tex/context/base/mkiv/buff-ini.lua b/tex/context/base/mkiv/buff-ini.lua
index e4f01c03f..b4290f8b1 100644
--- a/tex/context/base/mkiv/buff-ini.lua
+++ b/tex/context/base/mkiv/buff-ini.lua
@@ -46,8 +46,6 @@ local getcommand = token.get_command
local getcsname = token.get_csname
local getnextchar = token.get_next_char
-local scanners = interfaces.scanners
-
local variables = interfaces.variables
local settings_to_array = utilities.parsers.settings_to_array
local formatters = string.formatters
@@ -623,21 +621,26 @@ end
tokens.pickup = pickup
-scanners.pickupbuffer = function()
- local name = scanstring()
- local start = scanstring()
- local stop = scanstring()
- local finish = scanstring()
- local catcodes = scaninteger()
- local doundent = scanboolean()
- local data = pickup(start,stop)
- if doundent or (autoundent and doundent == nil) then
- data = undent(data)
- end
- buffers.assign(name,data,catcodes)
- -- context[finish]()
- context(finish)
-end
+implement {
+ name = "pickupbuffer",
+ actions = function()
+ -- let's pickup all here (no arguments)
+ local name = scanstring()
+ local start = scanstring()
+ local stop = scanstring()
+ local finish = scanstring()
+ local catcodes = scaninteger()
+ local doundent = scanboolean()
+ -- could be a scanner:
+ local data = pickup(start,stop)
+ if doundent or (autoundent and doundent == nil) then
+ data = undent(data)
+ end
+ buffers.assign(name,data,catcodes)
+ -- context[finish]()
+ context(finish)
+ end
+}
local function savebuffer(list,name,prefix) -- name is optional
if not list or list == "" then
diff --git a/tex/context/base/mkiv/buff-ver.lua b/tex/context/base/mkiv/buff-ver.lua
index 2bf663704..ccb8ab0df 100644
--- a/tex/context/base/mkiv/buff-ver.lua
+++ b/tex/context/base/mkiv/buff-ver.lua
@@ -588,7 +588,7 @@ end
local function realign(lines,strip) -- "yes", <number>
local n
if strip == v_yes then
- n = math.huge
+ n = 0xFFFF
for i=1, #lines do
local spaces = find(lines[i],"%S") -- can be lpeg
if not spaces then
diff --git a/tex/context/base/mkiv/buff-ver.mkiv b/tex/context/base/mkiv/buff-ver.mkiv
index 24aaa57d3..a3c27977f 100644
--- a/tex/context/base/mkiv/buff-ver.mkiv
+++ b/tex/context/base/mkiv/buff-ver.mkiv
@@ -1016,4 +1016,8 @@
\stopcontextdefinitioncode
+%D This is \type {\asciimode} without the double comment hackery:
+
+\unexpanded\def\literalmode{\setcatcodetable\txtcatcodes}
+
\protect \endinput
diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua
index 8e2d6f051..9569cf357 100644
--- a/tex/context/base/mkiv/cldf-ini.lua
+++ b/tex/context/base/mkiv/cldf-ini.lua
@@ -26,7 +26,7 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- 0.651 local foo = getcount("ctxcatcodes")
-- 0.408 local foo = getcount(ctxcatcodes) -- local ctxcatcodes = tex.iscount("ctxcatcodes")
--- maybe:  (escape) or 0x2061 (apply function) or 0x2394 (software function ⎔)
+-- maybe:  (escape) or 0x2061 (apply function) or 0x2394 (software function ⎔) (old)
-- note : tex.print == line with endlinechar appended
-- todo : context("%bold{total: }%s",total)
-- todo : context.documentvariable("title")
@@ -58,6 +58,20 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- time (for the better or worse). There have been no fundamental changes for many years
-- and performance has not changed much either.
+-- The code here has evolved over time, and was already present in the early versions of
+-- mkiv. However, it got adapted when feature were added to luatex, like the ability to
+-- "print" nodes and later tokens. We use to have control over the method used (if only
+-- for testing) but the older code has been removed now. The history is in the archives.
+-- These were the controls:
+
+-- local tokenflushmode = true
+-- local nodeflushmode = true
+-- local scannerdefmode = true
+-- local maxflushnodeindex = 0x10FFFF - 1
+
+-- In earlier experiments a function tables was referred to as lua.calls and the primitive
+-- \luafunctions was \luacall and we used our own implementation of a function table (more
+-- indirectness).
local format, stripstring = string.format, string.strip
local next, type, tostring, tonumber, unpack, select, rawset = next, type, tostring, tonumber, unpack, select, rawset
@@ -85,9 +99,6 @@ local texprint = tex.print -- each arg a separate line (not last in
----- texwrite = tex.write -- all 'space' and 'character'
local texgetcount = tex.getcount
--- local function texsprint(...) print("sprint",...) tex.sprint(...) end
--- local function texprint (...) print("print", ...) tex.print (...) end
-
local isnode = node.is_node
local writenode = node.write
local copynodelist = node.copy_list
@@ -118,19 +129,6 @@ local report_cld = logs.reporter("cld","stack")
local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end)
-local tokenflushmode = true
-local nodeflushmode = true
-local scannerdefmode = true
-local maxflushnodeindex = 0x10FFFF - 1
-
--- tokenflushmode = false
--- nodeflushmode = false
--- scannerdefmode = false
-
--- In earlier experiments a function tables was referred to as lua.calls and the
--- primitive \luafunctions was \luacall and we used our own implementation of
--- a function table (more indirectness).
-
local trialtypesettingstate = createtoken("trialtypesettingstate").index
function context.trialtypesetting()
@@ -142,7 +140,9 @@ local showstackusage = false
trackers.register("context.stack",function(v) showstackusage = v end)
-local freed, nofused, noffreed = { }, 0, 0
+local freed = { }
+local nofused = 0
+local noffreed = 0
local usedstack = function()
return nofused, noffreed
@@ -208,11 +208,11 @@ local initex = environment.initex
storage.register("storage/storedfunctions", storedfunctions, "storage.storedfunctions")
local f_resolve = nil
-local p_resolve = ((1-lpegP("."))^1 / function(s) f_resolve = f_resolve[s] end * lpegP(".")^0)^1
+local p_resolve = ((1-lpegP("."))^1 / function(s) f_resolve = f_resolve[s] end * lpegP(".")^0)^1
local function resolvestoredfunction(str)
if type(str) == "string" then
- f_resolve = global
+ f_resolve = global -- namespace
lpegmatch(p_resolve,str)
return f_resolve
else
@@ -257,9 +257,11 @@ else
end
end
-local registerfunction = function(f,direct) -- either f=code or f=namespace,direct=name
- local slot, func
- if noffreed > 0 then
+local registerfunction = function(f,direct,slot) -- either f=code or f=namespace,direct=name
+ local func
+ if slot then
+ -- already used
+ elseif noffreed > 0 then
slot = freed[noffreed]
freed[noffreed] = nil
noffreed = noffreed - 1
@@ -269,12 +271,8 @@ local registerfunction = function(f,direct) -- either f=code or f=namespace,dire
end
if direct then
if initex then
- func = function(...)
- expose(slot,f,...)
- end
- if initex then
- storedfunctions[slot] = f
- end
+ func = function(...) expose(slot,f,...) end
+ storedfunctions[slot] = f
else
func = resolvestoredfunction(f)
end
@@ -357,73 +355,46 @@ do
end
--- so far
-
--- The next hack is a convenient way to define scanners at the Lua end and
--- get them available at the TeX end. There is some dirty magic needed to
--- prevent overload during format loading.
+-- The next hack is a convenient way to define scanners at the Lua end and get them
+-- available at the TeX end. There is some dirty magic needed to prevent overload
+-- during format loading. Nowadays we prefer to use the slightly less efficient way
+-- of defining interfaces using the implementer. There is a little more overhead in
+-- defining as well as runtime overhead, but we accept that.
-- interfaces.scanners.foo = function() context("[%s]",tokens.scanners.string()) end : \scan_foo
-interfaces.storedscanners = interfaces.storedscanners or { }
-local storedscanners = interfaces.storedscanners
+local storedscanners = interfaces.storedscanners or { }
+local interfacescanners = { }
+local privatenamespace = "clf_"
-storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners")
+interfaces.storedscanners = storedscanners
-local interfacescanners = setmetatablenewindex(function(t,k,v)
- rawset(t,k,v)
- if storedscanners[k] then
- -- report_cld("warning: scanner %a is already set (mode 1a)",k)
- -- os.exit()
- -- \scan_<k> is already in the format
- -- report_cld("using interface scanner: %s",k)
- elseif scannerdefmode then
- -- report_cld("installing interface scanner: %s (mode 1b)",k)
- -- local n = registerfunction(interfaces.scanners[k],true)
- local n = registerfunction("interfaces.scanners."..k,true)
- storedscanners[k] = n
- local name = "clf_" .. k
- setluatoken(name,n,"global") -- todo : protected and "protected" or ""
- else
- -- report_cld("installing interface scanner: %s (mode 1c)",k)
- storedscanners[k] = true
- context("\\installctxscanner{clf_%s}{interfaces.scanners.%s}",k,k)
- end
- -- rawset(t,k,v)
-end)
+storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners")
-function interfaces.registerscanner(name,action,protected,public,value)
+local function registerscanner(name,action,protected,public,value)
rawset(interfacescanners,name,action)
- if storedscanners[name] then
- -- report_cld("warning: scanner %a is already set (mode 2a)",name)
- -- os.exit()
- -- \scan_<k> is already in the format
- -- report_cld("using interface scanner: %s",k)
- elseif scannerdefmode then
- -- report_cld("installing interface scanner: %s (mode 2b)",name)
- -- local n = registerfunction(action,true) -- todo
- local n = registerfunction("interfaces.scanners."..name,true)
- storedscanners[name] = n
- local name = public and name or ("clf_" .. name)
- setluatoken(name,n,"global",protected and "protected" or "",value and "value" or "")
- else
- storedscanners[name] = true
- -- report_cld("installing interface scanner: %s (mode 2c)",name)
- context("\\install%sctxscanner{%s%s}{interfaces.scanners.%s}",
- protected and "protected" or "",
- public and "" or "clf_",
- name,
- name
- )
- end
- -- rawset(interfacescanners,name,action)
+ local n = storedscanners[name]
+ n = registerfunction("interfaces.scanners."..name,true,n)
+ storedscanners[name] = n
+ name = public and name or (privatenamespace .. name)
+ setluatoken(name,n,"global",protected and "protected" or "",value and "value" or "")
end
+interfaces.registerscanner = registerscanner
+
+function interfaces.knownscanner(name)
+ return interfacescanners[name]
+end
+
+setmetatablenewindex(interfacescanners, function(t,k,v)
+ report_cld("don't register scanner %a directly",k)
+ -- registerscanner(k,v)
+end)
+
interfaces.scanners = storage.mark(interfacescanners)
-interfaces._ = interfaces.scanners
context.functions = {
- register = registerfunction,
+ register = function(qualifiedname) return registerfunction(qualifiedname) end, -- only one argument
unregister = unregisterfunction,
reserve = reservefunction,
known = knownfunctions,
@@ -448,7 +419,7 @@ function commands.ctxresetter(name) -- to be checked
return function()
if storedscanners[name] then
rawset(interfacescanners,name,dummy)
- context.resetctxscanner("clf_" .. name)
+ context.resetctxscanner(privatenamespace .. name)
end
end
end
@@ -540,25 +511,11 @@ local endstripper = beginstripper * lpegP(-1)
local justaspace = space * lpegCc("")
local justanewline = newline * lpegCc("")
-local function n_content(s)
- flush(contentcatcodes,s)
-end
-
-local function n_verbose(s)
- flush(vrbcatcodes,s)
-end
-
-local function n_endofline()
- flush(currentcatcodes," \r")
-end
-
-local function n_emptyline()
- flushdirect(currentcatcodes,"\r")
-end
-
-local function n_simpleline()
- flush(currentcatcodes," \r")
-end
+local function n_content (s) flush (contentcatcodes,s ) end
+local function n_verbose (s) flush (vrbcatcodes, s ) end
+local function n_endofline () flush (currentcatcodes," \r") end
+local function n_emptyline () flushdirect(currentcatcodes,"\r" ) end
+local function n_simpleline() flush (currentcatcodes," \r") end
local n_exception = ""
@@ -646,7 +603,7 @@ function context.newverbosehandler(specification) -- a special variant for e.g.
specification = specification or { }
--
local f_line = specification.line or function() flushdirect("\r") end
- local f_space = specification.space or function() flush(" ") end
+ local f_space = specification.space or function() flush (" ") end
local f_content = specification.content or n_verbose
local f_before = specification.before
local f_after = specification.after
@@ -700,20 +657,6 @@ function context.printlines(str,raw) -- todo: see if via file is useable
end
end
--- function context.printtable(t,separator) -- todo: see if via file is useable
--- if separator == nil or separator == true then
--- separator = "\r"
--- elseif separator == "" then
--- separator = false
--- end
--- for i=1,#t do
--- context(t[i]) -- we need to go through catcode handling
--- if separator then
--- context(separator)
--- end
--- end
--- end
-
function context.printtable(t,separator) -- todo: see if via file is useable
if separator == nil or separator == true then
separator = "\r"
@@ -730,22 +673,6 @@ end
local containseol = patterns.containseol
-local s_cldl_option_b = "[\\cldl"
-local s_cldl_option_f = "[\\cldl" -- add space (not needed)
-local s_cldl_option_e = "]"
-local s_cldl_option_s = "\\cldl"
------ s_cldl_option_d = "\\cldd"
-local s_cldl_option_d = s_cldl_option_s
-local s_cldl_argument_b = "{\\cldl"
-local s_cldl_argument_f = "{\\cldl "
-local s_cldl_argument_e = "}"
-
--- local s_cldl_option_b = "["
--- local s_cldl_option_f = "" -- add space (not needed)
--- local s_cldl_option_s = ""
--- local s_cldl_argument_b = "{"
--- local s_cldl_argument_f = "{ "
-
local t_cldl_luafunction = newtoken("luafunctioncall",0)
local lua_expandable_call_token_code = token.command_id and token.command_id("lua_expandable_call")
@@ -756,17 +683,12 @@ directives.register("context.sorthash",function(v)
end)
local function writer(parent,command,...) -- already optimized before call
-
if type(command) == "string" then -- for now
flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
else
flush(command) -- todo: ctx|prt|texcatcodes
end
-
local direct = false
- -- local t = { ... }
- -- for i=1,#t do
- -- local ti = t[i]
for i=1,select("#",...) do
local ti = select(i,...)
if direct then
@@ -849,15 +771,7 @@ local function writer(parent,command,...) -- already optimized before call
local tj = ti[1]
if type(tj) == "function" then
tj = storefunction(tj)
- if tokenflushmode then
- -- if newtoken then
- flush(currentcatcodes,"[",newtoken(tj,lua_expandable_call_token_code),"]")
- -- else
- -- flush(currentcatcodes,"[",t_cldl_luafunction,tj,"]")
- -- end
- else
- flush(currentcatcodes,s_cldl_option_b,tj,s_cldl_option_e)
- end
+ flush(currentcatcodes,"[",newtoken(tj,lua_expandable_call_token_code),"]")
else
flush(currentcatcodes,"[",tj,"]")
end
@@ -867,15 +781,7 @@ local function writer(parent,command,...) -- already optimized before call
local tj = ti[j]
if type(tj) == "function" then
tj = storefunction(tj)
- if tokenflushmode then
- -- if newtoken then
- flush(currentcatcodes,"[",newtoken(tj,lua_expandable_call_token_code),j == tn and "]" or ",")
- -- else
- -- flush(currentcatcodes,"[",t_cldl_luafunction,tj,j == tn and "]" or ",")
- -- end
- else
- flush(currentcatcodes,s_cldl_option_s,tj,j == tn and "]" or ",")
- end
+ flush(currentcatcodes,"[",newtoken(tj,lua_expandable_call_token_code),j == tn and "]" or ",")
else
if j == tn then
flush(currentcatcodes,tj,"]")
@@ -888,15 +794,7 @@ local function writer(parent,command,...) -- already optimized before call
elseif typ == "function" then
-- todo: ctx|prt|texcatcodes
ti = storefunction(ti)
- if tokenflushmode then
- -- if newtoken then
- flush(currentcatcodes,"{",newtoken(ti,lua_expandable_call_token_code),"}")
- -- else
- -- flush(currentcatcodes,"{",t_cldl_luafunction,ti,"}")
- -- end
- else
- flush(currentcatcodes,s_cldl_argument_f,ti,s_cldl_argument_e)
- end
+ flush(currentcatcodes,"{",newtoken(ti,lua_expandable_call_token_code),"}")
elseif typ == "boolean" then
if ti then
flushdirect(currentcatcodes,"\r")
@@ -906,16 +804,7 @@ local function writer(parent,command,...) -- already optimized before call
elseif typ == "thread" then
report_context("coroutines not supported as we cannot yield across boundaries")
elseif isnode(ti) then -- slow | why {} here ?
- if nodeflushmode then
- local n = tonut(ti)
- if n <= maxflushnodeindex then
- flush(currentcatcodes,"{",ti,"}")
- else
- flush(currentcatcodes,s_cldl_argument_b,storenode(ti),s_cldl_argument_e)
- end
- else
- flush(currentcatcodes,s_cldl_argument_b,storenode(ti),s_cldl_argument_e)
- end
+ flush(currentcatcodes,"{",ti,"}")
else
local s = tostring(ti)
if s then
@@ -924,109 +813,47 @@ local function writer(parent,command,...) -- already optimized before call
report_context("error: %a gets a weird argument %a",command,ti)
end
end
--- else
--- local n = isnode(ti)
--- if n then
--- if nodeflushmode and n <= maxflushnodeindex then
--- flush(ti)
--- else
--- flush(currentcatcodes,s_cldl_argument_b,storenode(ti),s_cldl_argument_e)
--- end
--- else
--- report_context("error: %a gets a weird argument %a",command,ti)
--- end
--- end
+ -- else
+ -- local n = isnode(ti)
+ -- if n then
+ -- flush(ti)
+ -- else
+ -- report_context("error: %a gets a weird argument %a",command,ti)
+ -- end
end
end
end
-local core
+local toks = tokens.cache
+context.tokenizedcs = toks
-if tokenflushmode then -- combine them
-
- local toks = tokens.cache
-
- context.tokenizedcs = toks
-
- core = setmetatableindex(function(parent,k)
- local t
- local f = function(first,...)
- if not t then
- t = toks[k]
- end
- if first == nil then
- flush(t)
- else
- return writer(context,t,first,...)
- end
+local core = setmetatableindex(function(parent,k)
+ local t
+ local f = function(first,...)
+ if not t then
+ t = toks[k]
end
- parent[k] = f
- return f
- end)
-
--- core = setmetatableindex(function(parent,k)
--- local t
--- local f = function(first,...)
--- if not t then
--- t = toks[k]
--- end
--- local f = function(first,...)
--- if first == nil then
--- flush(t)
--- else
--- return writer(context,t,first,...)
--- end
--- end
--- parent[k] = f
--- if first == nil then
--- flush(t)
--- else
--- return writer(context,t,first,...)
--- end
--- end
--- parent[k] = f
--- return f
--- end)
-
- core.cs = setmetatableindex(function(parent,k)
- local t
- local f = function()
- if not t then
- t = toks[k]
- end
+ if first == nil then
flush(t)
+ else
+ return writer(context,t,first,...)
end
- parent[k] = f
- return f
- end)
-
-else
-
- context.tokenizedcs = false
-
- core = setmetatableindex(function(parent,k)
- local c = "\\" .. k
- local f = function(first,...)
- if first == nil then
- flush(currentcatcodes,c)
- else
- return writer(context,c,first,...)
- end
- end
- parent[k] = f
- return f
- end)
+ end
+ parent[k] = f
+ return f
+end)
- core.cs = setmetatableindex(function(parent,k)
- local c = "\\" .. k -- tostring(k)
- local f = function()
- flush(currentcatcodes,c)
+core.cs = setmetatableindex(function(parent,k)
+ local t
+ local f = function()
+ if not t then
+ t = toks[k]
end
- parent[k] = f
- return f
- end)
-
-end
+ flush(t)
+ end
+ parent[k] = f
+ return f
+end)
local indexer = function(parent,k)
if type(k) == "string" then
@@ -1122,15 +949,7 @@ local caller = function(parent,f,a,...)
elseif typ == "function" then
-- ignored: a ...
f = storefunction(f)
- if tokenflushmode then
- -- if newtoken then
- flush(currentcatcodes,"{",newtoken(f,lua_expandable_call_token_code),"}")
- -- else
- -- flush(currentcatcodes,"{",t_cldl_luafunction,f,"}")
- -- end
- else
- flush(currentcatcodes,s_cldl_argument_b,f,s_cldl_argument_e) -- todo: ctx|prt|texcatcodes
- end
+ flush(currentcatcodes,"{",newtoken(f,lua_expandable_call_token_code),"}")
elseif typ == "boolean" then
if f then
if a ~= nil then
@@ -1149,16 +968,7 @@ local caller = function(parent,f,a,...)
elseif typ == "thread" then
report_context("coroutines not supported as we cannot yield across boundaries")
elseif isnode(f) then -- slow
- if nodeflushmode then
- local n = tonut(f)
- if n <= maxflushnodeindex then
- flush(f)
- else
- flush(currentcatcodes,s_cldl_option_s,storenode(f)," ")
- end
- else
- flush(currentcatcodes,s_cldl_option_s,storenode(f)," ")
- end
+ flush(f)
else
local s = tostring(f)
if s then
@@ -1167,29 +977,20 @@ local caller = function(parent,f,a,...)
report_context("error: %a gets a weird argument %a","context",f)
end
end
--- else
--- local n = isnode(f)
--- if n then
--- if nodeflushmode and n <= maxflushnodeindex then
--- flush(f)
--- else
--- flush(currentcatcodes,s_cldl_option_s,storenode(f)," ")
--- end
--- else
--- report_context("error: %a gets a weird argument %a","context",f)
--- end
--- end
+ -- else
+ -- local n = isnode(f)
+ -- if n then
+ -- flush(f)
+ -- else
+ -- report_context("error: %a gets a weird argument %a","context",f)
+ -- end
end
end
context.nodes = { -- todo
store = storenode,
flush = function(n)
- if nodeflushmode and tonut(n) <= maxflushnodeindex then
- flush(n)
- else
- flush(currentcatcodes,d and s_cldl_option_d or s_cldl_option_s,storenode(n)," ")
- end
+ flush(n)
end,
}
@@ -1198,11 +999,7 @@ context.nuts = { -- todo
return storenode(tonut(n))
end,
flush = function(n,d)
- if nodeflushmode and n <= maxflushnodeindex then
- flush(tonode(n))
- else
- flush(currentcatcodes,d and s_cldl_option_d or s_cldl_option_s,storenode(tonode(n))," ")
- end
+ flush(tonode(n))
end,
}
@@ -1640,22 +1437,7 @@ function context.newindexer(catcodes,cmdcodes)
contentcatcodes = savedcatcodes
end
- if tokenflushmode then
-
- handler.cs = core.cs
-
- else
-
- handler.cs = setmetatableindex(function(parent,k)
- local c = "\\" .. k -- tostring(k)
- local f = function()
- flush(cmdcodes,c)
- end
- parent[k] = f
- return f
- end)
-
- end
+ handler.cs = core.cs
setmetatableindex(handler,indexer)
setmetatablecall (handler,caller)
@@ -1675,23 +1457,6 @@ do
-- formatted.command([catcodes,]format[,...])
--- local function formattedflush(parent,c,catcodes,fmt,...)
--- if type(catcodes) == "number" then
--- if fmt then
--- local result
--- pushcatcodes(catcodes)
--- result = writer(parent,c,formatters[fmt](...))
--- popcatcodes()
--- return result
--- else
--- -- no need to change content catcodes
--- return writer(parent,c)
--- end
--- else
--- return writer(parent,c,formatters[catcodes](fmt,...))
--- end
--- end
-
local function formattedflush(parent,c,catcodes,fmt,...)
if not catcodes then
return writer(parent,c)
@@ -1708,51 +1473,26 @@ do
end
end
- local indexer
-
- if tokenflushmode then -- combine them
-
- local toks = tokens.cache
+ local toks = tokens.cache
- indexer = function(parent,k)
- if type(k) == "string" then
- local t
- local f = function(first,...)
- if not t then
- t = toks[k]
- end
- if first == nil then
- flush(t)
- else
- return formattedflush(parent,t,first,...)
- end
+ local indexer = function(parent,k)
+ if type(k) == "string" then
+ local t
+ local f = function(first,...)
+ if not t then
+ t = toks[k]
end
- parent[k] = f
- return f
- else
- return context -- catch
- end
- end
-
- else
-
- indexer = function(parent,k)
- if type(k) == "string" then
- local c = "\\" .. k
- local f = function(first,...)
- if first == nil then
- flush(currentcatcodes,c)
- else
- return formattedflush(parent,c,first,...)
- end
+ if first == nil then
+ flush(t)
+ else
+ return formattedflush(parent,t,first,...)
end
- parent[k] = f
- return f
- else
- return context -- catch
end
+ parent[k] = f
+ return f
+ else
+ return context -- catch
end
-
end
-- formatted([catcodes,]format[,...])
diff --git a/tex/context/base/mkiv/cldf-int.lua b/tex/context/base/mkiv/cldf-int.lua
index 86420f422..d869f3154 100644
--- a/tex/context/base/mkiv/cldf-int.lua
+++ b/tex/context/base/mkiv/cldf-int.lua
@@ -313,18 +313,22 @@ else
end
function interfaces.tolist(t)
- local r = { }
- for i=1,#t do
- r[i] = t[i]
- end
- local n = #r
- for k,v in table.sortedhash(t) do
- if type(k) ~= "number" then
- n = n + 1
- r[n] = k .. "=" .. v
+ if t then
+ local r = { }
+ for i=1,#t do
+ r[i] = t[i]
+ end
+ local n = #r
+ for k,v in table.sortedhash(t) do
+ if type(k) ~= "number" then
+ n = n + 1
+ r[n] = k .. "=" .. v
+ end
end
+ return concat(r,", ")
+ else
+ return ""
end
- return concat(r,", ")
end
-- \startluacode
@@ -358,9 +362,9 @@ end
-- context.startnarrower()
-- end
--
--- local function stopmore(opt_1)
+-- local function stopmore()
-- context.stopnarrower()
--- context("stop more, options: %s",interfaces.tolist(opt_1))
+-- context("stop more")
-- context.stopnarrower()
-- end
--
diff --git a/tex/context/base/mkiv/cldf-lmt.lua b/tex/context/base/mkiv/cldf-lmt.lua
index ab25f962e..4855372fa 100644
--- a/tex/context/base/mkiv/cldf-lmt.lua
+++ b/tex/context/base/mkiv/cldf-lmt.lua
@@ -8,8 +8,9 @@ if not modules then modules = { } end modules ['cldf-lmt'] = {
local next, load = next, load
-local setmetatableindex = table.setmetatableindex
-local serialize = table.serialize
+local setmetatableindex = table.setmetatableindex
+local setmetatablenewindex = table.setmetatablenewindex
+local serialize = table.serialize
local random = math.random
local randomseed = math.randomseed
@@ -30,8 +31,12 @@ local scancardinal = scanners.luacardinal
local scannumber = scanners.luanumber
local scanargument = scanners.argument
local scantoken = scanners.token
+local scancsname = scanners.csname
+
local getindex = token.get_index
+
local texsetdimen = tex.setdimen
+local texget = tex.get
local values = tokens.values
local none_code = values.none
@@ -57,7 +62,7 @@ implement {
value = true,
actions = function(b)
local n = scanword()
- if b then
+ if b == "value" then
context("%.99g",floats[n] or 0)
else
floats[n] = scannumber(true)
@@ -72,7 +77,7 @@ implement {
value = true,
actions = function(b)
local n = scanword()
- if b then
+ if b == "value" then
context("%i",integers[n] or 0)
else
integers[n] = scaninteger(true)
@@ -86,7 +91,7 @@ implement {
value = true,
actions = function(b)
local n = scanword()
- if b then
+ if b == "value" then
return integer_code, integers[n] or 0
else
integers[n] = scancount(true)
@@ -100,7 +105,7 @@ implement {
value = true,
actions = function(b)
local n = scanword()
- if b then
+ if b == "value" then
return dimension_code, integers[n] or 0
else
integers[n] = scandimen(false,false,true)
@@ -114,8 +119,8 @@ implement {
value = true,
actions = function(b)
local n = scanword()
- if b then
- context("%d",cardinals[n] or 0)
+ if b == "value" then
+ context("%1.0f",cardinals[n] or 0)
else
cardinals[n] = scancardinal(true)
end
@@ -128,8 +133,8 @@ implement {
value = true,
actions = function(b)
local n = scanword()
- if b then
- context("%d",floats[n] or integers[n] or cardinals[n] or 0)
+ if b == "value" then
+ context("%N",floats[n] or integers[n] or cardinals[n] or 0) -- maybe %N
else
-- floats[n] = scanfloat(true)
floats[n] = scannumber(true)
@@ -142,7 +147,7 @@ implement {
public = true,
value = true,
actions = function(b)
- if b then
+ if b == "value" then
return integer_code, random(scaninteger(),scaninteger())
else
randomseed(scaninteger(true))
@@ -243,7 +248,7 @@ implement {
d = d[scaninteger()]
end
local x = scaninteger()
- if b then
+ if b == "value" then
local code = a.code
if code == float_code then
context("%.99g",d[x])
@@ -258,7 +263,6 @@ implement {
end,
}
-
implement {
name = "arrayequals",
public = true,
@@ -275,7 +279,7 @@ implement {
d = d[scaninteger()]
end
local x = scaninteger()
- if b then
+ if b == "value" then
return boolean_code, a.scanner() == d[x]
end
end
@@ -299,7 +303,7 @@ implement {
d = d[scaninteger()]
end
local x = scaninteger()
- if b then
+ if b == "value" then
local v = a.scanner()
local d = d[x]
if d < v then
@@ -379,7 +383,7 @@ implement {
public = true,
value = true,
actions = function(b)
- if b then
+ if b == "value" then
local how = scanword()
local what = scandimen()
if how then
@@ -417,7 +421,7 @@ local setdata = tokens.setdata
local report = logs.reporter("lua table")
------ ctxsprint = context.sprint
+local ctxsprint = context.sprint
-- we could have an extra one that collects all end of grouped actions
-- so that we dispose more in one go but it doesn's pay off
@@ -607,3 +611,109 @@ context.luatables = {
inspect = inspectluatable,
show = showluatables,
}
+
+-- Here's another mechanism ...
+
+local tables = { }
+local stack = setmetatableindex("table")
+
+interfaces.implement {
+ name = "droptablegroup",
+ public = true,
+ actions = function()
+ local g = texget("currentgrouplevel") -- todo: tex.getgrouplevel()
+ local s = stack[g]
+ if s then
+ for t, data in next, s do
+ for k, v in next, data do
+ t[k] = v
+ end
+ end
+ stack[g] = { }
+ end
+ end,
+}
+
+local ctx_atendofgroup = context.core.cs.atendofgroup
+local ctx_droptablegroup = context.core.cs.droptablegroup
+
+local function handletable(t,b,array)
+ if b == "value" then
+ local k = array and scaninteger() or scanargument()
+ local v = t[k]
+ if v then
+ context(v)
+ end
+ else
+ local data = scanargument()
+ data = load("return {" .. data .. "}")
+ if data then
+ data = data()
+ if data then
+ local l = t.level
+ local g = texget("currentgrouplevel") -- todo: tex.getgrouplevel()
+ local s = stack[g]
+ local d = s[t]
+ if not d then
+ d = { }
+ s[t] = d
+ ctx_atendofgroup()
+ ctx_droptablegroup()
+ end
+ for k, v in next, data do
+ if not d[k] then
+ d[k] = t[k]
+ end
+ t[k] = v
+ end
+ if b == "global" then
+ for k, v in next, stack do
+ local t = s[t]
+ if t then
+ for k, v in next, data do
+ if t[k] then
+ t[k] = nil
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local function newtable(array)
+ local name = scancsname(true)
+ if not tables[name] then
+ local t = { }
+ tables[name] = t
+ interfaces.implement {
+ name = name,
+ public = true,
+ value = true,
+ actions = function(b)
+ handletable(t,b,array)
+ end,
+ }
+ else
+ -- already defined
+ end
+end
+
+implement {
+ name = "newhashedtable",
+ protected = true,
+ public = true,
+ actions = newtable,
+}
+
+implement {
+ name = "newindexedtable",
+ protected = true,
+ public = true,
+ actions = function() newtable(true) end,
+}
+
+context.hashedtables = setmetatableindex(function(t,k) return tables[k] end)
+context.indexedtables = context.hashedtables
diff --git a/tex/context/base/mkiv/cldf-scn.lua b/tex/context/base/mkiv/cldf-scn.lua
index 1e5fe221d..fc4ea1e4a 100644
--- a/tex/context/base/mkiv/cldf-scn.lua
+++ b/tex/context/base/mkiv/cldf-scn.lua
@@ -8,32 +8,35 @@ if not modules then modules = { } end modules ['cldf-scn'] = {
local load, type, tostring = load, type, tostring
-local formatters = string.formatters
-local char = string.char
-local concat = table.concat
+local formatters = string.formatters
+local char = string.char
+local concat = table.concat
-local lpegmatch = lpeg.match
-local p_unquoted = lpeg.Cs(lpeg.patterns.unquoted)
+local lpegmatch = lpeg.match
+local p_unquoted = lpeg.Cs(lpeg.patterns.unquoted)
-local f_action_f = formatters["action%s(%s)"]
-local f_action_s = formatters["local action%s = action[%s]"]
-local f_command = formatters["local action = tokens._action\n%\nt\nreturn function(%s) return %s end"]
+local f_action_f = formatters["action%s(%s)"]
+local f_action_s = formatters["local action%s = action[%s]"]
+local f_command = formatters["local action = tokens._action\n%\nt\nreturn function(%s) return %s end"]
-local interfaces = interfaces
-local commands = commands
-local scanners = interfaces.scanners
-local register = interfaces.registerscanner
+local interfaces = interfaces
+local commands = commands
+local register = interfaces.registerscanner
+local knownscanner = interfaces.knownscanner
-local compile = tokens.compile or function() end
-local presets = tokens.presets
+local compile = tokens.compile or function() end
+local presets = tokens.presets
-local dummy = function() end
+local dummy = function() end
-local report = logs.reporter("interfaces","implementor")
+local report = logs.reporter("interfaces","implementor")
function interfaces.implement(specification)
+ local name = specification.name
+ if name == "" then
+ name = nil
+ end
local actions = specification.actions
- local name = specification.name
local arguments = specification.arguments
local private = specification.scope == "private"
local onlyonce = specification.onlyonce
@@ -45,9 +48,6 @@ function interfaces.implement(specification)
end
return
end
- if name == "" then
- name = nil
- end
local p = arguments and presets[arguments]
if p then
arguments = p
@@ -74,8 +74,8 @@ function interfaces.implement(specification)
if not name then
return scanner
end
- if scanners[name] and not specification.overload then
- report("warning: 'scanners.%s' is redefined",name)
+ if knownscanner(name) and not specification.overload then
+ report("warning: interface scanner %a is overloaded",name)
end
register(name,scanner,specification.protected,specification.public,specification.value)
if private then
@@ -160,12 +160,3 @@ interfaces.defined = tokens.defined
interfaces.setmacro = tokens.setters.macro
interfaces.setcount = tokens.setters.count
interfaces.setdimen = tokens.setters.dimen
-
-interfaces.strings = table.setmetatableindex(function(t,k)
- local v = { }
- for i=1,k do
- v[i] = "string"
- end
- t[k] = v
- return v
-end)
diff --git a/tex/context/base/mkiv/colo-ini.mkxl b/tex/context/base/mkiv/colo-ini.mkxl
index 63d29d0a6..724316629 100644
--- a/tex/context/base/mkiv/colo-ini.mkxl
+++ b/tex/context/base/mkiv/colo-ini.mkxl
@@ -250,8 +250,8 @@
%D The following command is obsolete:
-\unexpanded\def\startcolorpage {\startcolor[\ifempty\maintextcolor\defaulttextcolor\else\maintextcolor\fi]}
-\unexpanded\def\stopcolorpage {\stopcolor}
+\unexpanded\def\startcolorpage{\startcolor[\ifempty\maintextcolor\defaulttextcolor\else\maintextcolor\fi]}
+\unexpanded\def\stopcolorpage {\stopcolor}
\unexpanded\def\getcolorattributevalue#1#2% obsolete, use \thecolorattribute instead ...
{\begingroup
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index bdee367d1..3b01c297e 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2020.06.20 13:33}
+\newcontextversion{2020.06.25 10:55}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index f5d02a708..bbefc17e6 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.06.20 13:33}
+\edef\contextversion{2020.06.25 10:55}
\edef\contextkind {beta}
%D Kind of special:
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index e69d387f2..45a8e2f2f 100644
--- a/tex/context/base/mkiv/context.mkxl
+++ b/tex/context/base/mkiv/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.06.20 13:33}
+\edef\contextversion{2020.06.25 10:55}
\edef\contextkind {beta}
%D Kind of special:
diff --git a/tex/context/base/mkiv/file-mod.lua b/tex/context/base/mkiv/file-mod.lua
index 10a187178..c10e557c7 100644
--- a/tex/context/base/mkiv/file-mod.lua
+++ b/tex/context/base/mkiv/file-mod.lua
@@ -246,18 +246,16 @@ function environment.useluamodule(list)
end
end
-local strings = interfaces.strings
-
implement {
name = "usemodules",
actions = environment.usemodules,
- arguments = strings[2]
+ arguments = "2 strings",
}
implement {
name = "doifelseolderversion",
actions = function(one,two) commands.doifelse(comparedversion(one,two) >= 0) end,
- arguments = strings[2]
+ arguments = "2 strings"
}
implement {
diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua
index 9e59c66bc..3b2676667 100644
--- a/tex/context/base/mkiv/font-ctx.lua
+++ b/tex/context/base/mkiv/font-ctx.lua
@@ -1168,69 +1168,56 @@ local specifiers = { }
do -- else too many locals
- ----- ctx_setdefaultfontname = context.fntsetdefname
- ----- ctx_setsomefontname = context.fntsetsomename
- ----- ctx_setemptyfontsize = context.fntsetnopsize
- ----- ctx_setsomefontsize = context.fntsetsomesize
- ----- ctx_letvaluerelax = context.letvaluerelax
+ local starttiming = statistics.starttiming
+ local stoptiming = statistics.stoptiming
- local starttiming = statistics.starttiming
- local stoptiming = statistics.stoptiming
+ local setmacro = tokens.setters.macro
- local scanners = tokens.scanners
- local scanstring = scanners.string
- local scaninteger = scanners.integer
- local scannumber = scanners.number
- local scanboolean = scanners.boolean
-
- local setmacro = tokens.setters.macro
- local scanners = interfaces.scanners
-
- -- function commands.definefont_one(str)
-
- scanners.definefont_one = function()
- local str = scanstring()
-
- starttiming(fonts)
- if trace_defining then
- report_defining("memory usage before: %s",statistics.memused())
- report_defining("start stage one: %s",str)
- end
- local fullname, size = lpegmatch(splitpattern,str)
- local lookup, name, sub, method, detail = getspecification(fullname)
- if not name then
- report_defining("strange definition %a",str)
- -- ctx_setdefaultfontname()
- elseif name == "unknown" then
- -- ctx_setdefaultfontname()
- else
- -- ctx_setsomefontname(name)
- setmacro("somefontname",name,"global")
- end
- -- we can also use a count for the size
- if size and size ~= "" then
- local mode, size = lpegmatch(sizepattern,size)
- if size and mode then
- texsetcount("scaledfontmode",mode)
- -- ctx_setsomefontsize(size)
- setmacro("somefontsize",size)
+ implement {
+ name = "definefont_one",
+ arguments = "string",
+ actions = function(str)
+ starttiming(fonts)
+ if trace_defining then
+ report_defining("memory usage before: %s",statistics.memused())
+ report_defining("start stage one: %s",str)
+ end
+ local fullname, size = lpegmatch(splitpattern,str)
+ local lookup, name, sub, method, detail = getspecification(fullname)
+ if not name then
+ report_defining("strange definition %a",str)
+ -- ctx_setdefaultfontname()
+ elseif name == "unknown" then
+ -- ctx_setdefaultfontname()
+ else
+ -- ctx_setsomefontname(name)
+ setmacro("somefontname",name,"global")
+ end
+ -- we can also use a count for the size
+ if size and size ~= "" then
+ local mode, size = lpegmatch(sizepattern,size)
+ if size and mode then
+ texsetcount("scaledfontmode",mode)
+ -- ctx_setsomefontsize(size)
+ setmacro("somefontsize",size)
+ else
+ texsetcount("scaledfontmode",0)
+ -- ctx_setemptyfontsize()
+ end
+ elseif true then
+ -- so we don't need to check in tex
+ texsetcount("scaledfontmode",2)
+ -- ctx_setemptyfontsize()
else
texsetcount("scaledfontmode",0)
-- ctx_setemptyfontsize()
end
- elseif true then
- -- so we don't need to check in tex
- texsetcount("scaledfontmode",2)
- -- ctx_setemptyfontsize()
- else
- texsetcount("scaledfontmode",0)
- -- ctx_setemptyfontsize()
- end
- specification = definers.makespecification(str,lookup,name,sub,method,detail,size)
- if trace_defining then
- report_defining("stop stage one")
+ specification = definers.makespecification(str,lookup,name,sub,method,detail,size)
+ if trace_defining then
+ report_defining("stop stage one")
+ end
end
- end
+ }
local function nice_cs(cs)
return (gsub(cs,".->", ""))
@@ -1244,179 +1231,228 @@ do -- else too many locals
combinefeatures = v
end)
- scanners.definefont_two = function()
- local global = scanboolean() -- \ifx\fontclass\empty\s!false\else\s!true\fi
- local cs = scanstring () -- {#csname}%
- local str = scanstring () -- \somefontfile
- local size = scaninteger() -- \d_font_scaled_font_size
- local inheritancemode = scaninteger() -- \c_font_feature_inheritance_mode
- local classfeatures = scanstring () -- \m_font_class_features
- local fontfeatures = scanstring () -- \m_font_features
- local classfallbacks = scanstring () -- \m_font_class_fallbacks
- local fontfallbacks = scanstring () -- \m_font_fallbacks
- local mathsize = scaninteger() -- \fontface
- local textsize = scaninteger() -- \d_font_scaled_text_face
- local relativeid = scaninteger() -- \relativefontid
- local classgoodies = scanstring () -- \m_font_class_goodies
- local goodies = scanstring () -- \m_font_goodies
- local classdesignsize = scanstring () -- \m_font_class_designsize
- local fontdesignsize = scanstring () -- \m_font_designsize
- local scaledfontmode = scaninteger() -- \scaledfontmode
-
- if trace_defining then
- report_defining("start stage two: %s, size %s, features %a & %a, mode %a",str,size,classfeatures,fontfeatures,inheritancemode)
- end
- -- name is now resolved and size is scaled cf sa/mo
- local lookup, name, sub, method, detail = getspecification(str or "")
- -- new (todo: inheritancemode)
- local designsize = fontdesignsize ~= "" and fontdesignsize or classdesignsize or ""
- local designname = designsizefilename(name,designsize,size)
- if designname and designname ~= "" then
- if trace_defining or trace_designsize then
- report_defining("remapping name %a, specification %a, size %a, designsize %a",name,designsize,size,designname)
- end
- -- we don't catch detail here
- local o_lookup, o_name, o_sub, o_method, o_detail = getspecification(designname)
- if o_lookup and o_lookup ~= "" then lookup = o_lookup end
- if o_method and o_method ~= "" then method = o_method end
- if o_detail and o_detail ~= "" then detail = o_detail end
- name = o_name
- sub = o_sub
- end
- -- so far
- -- some settings can have been overloaded
- if lookup and lookup ~= "" then
- specification.lookup = lookup
- end
- if relativeid and relativeid ~= "" then -- experimental hook
- local id = tonumber(relativeid) or 0
- specification.relativeid = id > 0 and id
- end
- --
- specification.name = name
- specification.size = size
- specification.sub = (sub and sub ~= "" and sub) or specification.sub
- specification.mathsize = mathsize
- specification.textsize = textsize
- specification.goodies = goodies
- specification.cs = cs
- specification.global = global
- specification.scalemode = scaledfontmode -- context specific
- if detail and detail ~= "" then
- specification.method = method or "*"
- specification.detail = detail
- elseif specification.detail and specification.detail ~= "" then
- -- already set
- elseif inheritancemode == 0 then
- -- nothing
- elseif inheritancemode == 1 then
- -- fontonly
- if fontfeatures and fontfeatures ~= "" then
- specification.method = "*"
- specification.detail = fontfeatures
- end
- if fontfallbacks and fontfallbacks ~= "" then
- specification.fallbacks = fontfallbacks
- end
- elseif inheritancemode == 2 then
- -- classonly
- if classfeatures and classfeatures ~= "" then
- specification.method = "*"
- specification.detail = classfeatures
- end
- if classfallbacks and classfallbacks ~= "" then
- specification.fallbacks = classfallbacks
- end
- elseif inheritancemode == 3 then
- -- fontfirst
- if combinefeatures then
- if classfeatures and classfeatures ~= "" then
- specification.method = "*"
- if fontfeatures and fontfeatures ~= "" and fontfeatures ~= classfeatures then
- specification.detail = classfeatures .. "," .. fontfeatures
- else
- specification.detail = classfeatures
- end
- elseif fontfeatures and fontfeatures ~= "" then
- specification.method = "*"
- specification.detail = fontfeatures
+
+
+
+
+
+ implement {
+ name = "definefont_two",
+ arguments = {
+ "boolean", "string", "string", "integer", "integer", "string", "string", "string", "string",
+ "integer", "integer", "integer", "string", "string", "string", "string", "integer",
+ },
+ actions = function (
+ global, -- \ifx\fontclass\empty\s!false\else\s!true\fi
+ cs, -- {#csname}%
+ str, -- \somefontfile
+ size, -- \d_font_scaled_font_size
+ inheritancemode, -- \c_font_feature_inheritance_mode
+ classfeatures, -- \m_font_class_features
+ fontfeatures, -- \m_font_features
+ classfallbacks, -- \m_font_class_fallbacks
+ fontfallbacks, -- \m_font_fallbacks
+ mathsize, -- \fontface
+ textsize, -- \d_font_scaled_text_face
+ relativeid, -- \relativefontid
+ classgoodies, -- \m_font_class_goodies
+ goodies, -- \m_font_goodies
+ classdesignsize, -- \m_font_class_designsize
+ fontdesignsize, -- \m_font_designsize
+ scaledfontmode -- \scaledfontmode
+ )
+
+ if trace_defining then
+ report_defining("start stage two: %s, size %s, features %a & %a, mode %a",str,size,classfeatures,fontfeatures,inheritancemode)
+ end
+ -- name is now resolved and size is scaled cf sa/mo
+ local lookup, name, sub, method, detail = getspecification(str or "")
+ -- new (todo: inheritancemode)
+ local designsize = fontdesignsize ~= "" and fontdesignsize or classdesignsize or ""
+ local designname = designsizefilename(name,designsize,size)
+ if designname and designname ~= "" then
+ if trace_defining or trace_designsize then
+ report_defining("remapping name %a, specification %a, size %a, designsize %a",name,designsize,size,designname)
end
- else
+ -- we don't catch detail here
+ local o_lookup, o_name, o_sub, o_method, o_detail = getspecification(designname)
+ if o_lookup and o_lookup ~= "" then lookup = o_lookup end
+ if o_method and o_method ~= "" then method = o_method end
+ if o_detail and o_detail ~= "" then detail = o_detail end
+ name = o_name
+ sub = o_sub
+ end
+ -- so far
+ -- some settings can have been overloaded
+ if lookup and lookup ~= "" then
+ specification.lookup = lookup
+ end
+ if relativeid and relativeid ~= "" then -- experimental hook
+ local id = tonumber(relativeid) or 0
+ specification.relativeid = id > 0 and id
+ end
+ --
+ specification.name = name
+ specification.size = size
+ specification.sub = (sub and sub ~= "" and sub) or specification.sub
+ specification.mathsize = mathsize
+ specification.textsize = textsize
+ specification.goodies = goodies
+ specification.cs = cs
+ specification.global = global
+ specification.scalemode = scaledfontmode -- context specific
+ if detail and detail ~= "" then
+ specification.method = method or "*"
+ specification.detail = detail
+ elseif specification.detail and specification.detail ~= "" then
+ -- already set
+ elseif inheritancemode == 0 then
+ -- nothing
+ elseif inheritancemode == 1 then
+ -- fontonly
if fontfeatures and fontfeatures ~= "" then
specification.method = "*"
specification.detail = fontfeatures
- elseif classfeatures and classfeatures ~= "" then
+ end
+ if fontfallbacks and fontfallbacks ~= "" then
+ specification.fallbacks = fontfallbacks
+ end
+ elseif inheritancemode == 2 then
+ -- classonly
+ if classfeatures and classfeatures ~= "" then
specification.method = "*"
specification.detail = classfeatures
end
- end
- if fontfallbacks and fontfallbacks ~= "" then
- specification.fallbacks = fontfallbacks
- elseif classfallbacks and classfallbacks ~= "" then
- specification.fallbacks = classfallbacks
- end
- elseif inheritancemode == 4 then
- -- classfirst
- if combinefeatures then
- if fontfeatures and fontfeatures ~= "" then
- specification.method = "*"
- if classfeatures and classfeatures ~= "" and classfeatures ~= fontfeatures then
- specification.detail = fontfeatures .. "," .. classfeatures
- else
+ if classfallbacks and classfallbacks ~= "" then
+ specification.fallbacks = classfallbacks
+ end
+ elseif inheritancemode == 3 then
+ -- fontfirst
+ if combinefeatures then
+ if classfeatures and classfeatures ~= "" then
+ specification.method = "*"
+ if fontfeatures and fontfeatures ~= "" and fontfeatures ~= classfeatures then
+ specification.detail = classfeatures .. "," .. fontfeatures
+ else
+ specification.detail = classfeatures
+ end
+ elseif fontfeatures and fontfeatures ~= "" then
+ specification.method = "*"
specification.detail = fontfeatures
end
- elseif classfeatures and classfeatures ~= "" then
- specification.method = "*"
- specification.detail = classfeatures
+ else
+ if fontfeatures and fontfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = fontfeatures
+ elseif classfeatures and classfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = classfeatures
+ end
end
- else
- if classfeatures and classfeatures ~= "" then
- specification.method = "*"
- specification.detail = classfeatures
- elseif fontfeatures and fontfeatures ~= "" then
- specification.method = "*"
- specification.detail = fontfeatures
+ if fontfallbacks and fontfallbacks ~= "" then
+ specification.fallbacks = fontfallbacks
+ elseif classfallbacks and classfallbacks ~= "" then
+ specification.fallbacks = classfallbacks
+ end
+ elseif inheritancemode == 4 then
+ -- classfirst
+ if combinefeatures then
+ if fontfeatures and fontfeatures ~= "" then
+ specification.method = "*"
+ if classfeatures and classfeatures ~= "" and classfeatures ~= fontfeatures then
+ specification.detail = fontfeatures .. "," .. classfeatures
+ else
+ specification.detail = fontfeatures
+ end
+ elseif classfeatures and classfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = classfeatures
+ end
+ else
+ if classfeatures and classfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = classfeatures
+ elseif fontfeatures and fontfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = fontfeatures
+ end
+ end
+ if classfallbacks and classfallbacks ~= "" then
+ specification.fallbacks = classfallbacks
+ elseif fontfallbacks and fontfallbacks ~= "" then
+ specification.fallbacks = fontfallbacks
end
end
- if classfallbacks and classfallbacks ~= "" then
- specification.fallbacks = classfallbacks
- elseif fontfallbacks and fontfallbacks ~= "" then
- specification.fallbacks = fontfallbacks
- end
- end
- --
- local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?)
- --
- local lastfontid = 0
- local tfmtype = type(tfmdata)
- if tfmtype == "table" then
- -- setting the extra characters will move elsewhere
- local characters = tfmdata.characters
- local parameters = tfmdata.parameters
- local properties = tfmdata.properties
- -- we use char0 as signal; cf the spec pdf can handle this (no char in slot)
- characters[0] = nil
- -- characters[0x00A0] = { width = parameters.space }
- -- characters[0x2007] = { width = characters[0x0030] and characters[0x0030].width or parameters.space } -- figure
- -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period
--
- local fallbacks = specification.fallbacks or ""
- local mathsize = (mathsize == 1 or mathsize == 2 or mathsize == 3) and mathsize or nil -- can be unset so we test 1 2 3
- if fallbacks ~= "" and mathsize and not busy then
- busy = true
- -- We need this ugly hack in order to resolve fontnames (at the \TEX end). Originally
- -- math was done in Lua after loading (plugged into aftercopying).
+ local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?)
+ --
+ local lastfontid = 0
+ local tfmtype = type(tfmdata)
+ if tfmtype == "table" then
+ -- setting the extra characters will move elsewhere
+ local characters = tfmdata.characters
+ local parameters = tfmdata.parameters
+ local properties = tfmdata.properties
+ -- we use char0 as signal; cf the spec pdf can handle this (no char in slot)
+ characters[0] = nil
+ -- characters[0x00A0] = { width = parameters.space }
+ -- characters[0x2007] = { width = characters[0x0030] and characters[0x0030].width or parameters.space } -- figure
+ -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period
--
- -- After tl 2017 I'll also do text fallbacks this way (although backups there are done
- -- in a completely different way.)
- if trace_defining then
- report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a, step %a",
- name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,1)
- end
- mathematics.resolvefallbacks(tfmdata,specification,fallbacks)
- context(function()
- busy = false
- mathematics.finishfallbacks(tfmdata,specification,fallbacks)
+ local fallbacks = specification.fallbacks or ""
+ local mathsize = (mathsize == 1 or mathsize == 2 or mathsize == 3) and mathsize or nil -- can be unset so we test 1 2 3
+ if fallbacks ~= "" and mathsize and not busy then
+ busy = true
+ -- We need this ugly hack in order to resolve fontnames (at the \TEX end). Originally
+ -- math was done in Lua after loading (plugged into aftercopying).
+ --
+ -- After tl 2017 I'll also do text fallbacks this way (although backups there are done
+ -- in a completely different way.)
+ if trace_defining then
+ report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a, step %a",
+ name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,1)
+ end
+ mathematics.resolvefallbacks(tfmdata,specification,fallbacks)
+ context(function()
+ busy = false
+ mathematics.finishfallbacks(tfmdata,specification,fallbacks)
+ local id = definefont(tfmdata)
+ csnames[id] = specification.cs
+ properties.id = id
+ definers.register(tfmdata,id) -- to be sure, normally already done
+ texdefinefont(global,cs,id)
+ constructors.cleanuptable(tfmdata)
+ constructors.finalize(tfmdata)
+ if trace_defining then
+ report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a, step %a",
+ name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,2)
+ end
+ -- resolved (when designsize is used):
+ local size = round(tfmdata.parameters.size or 655360)
+ setmacro("somefontsize",size.."sp")
+ -- ctx_setsomefontsize(size .. "sp")
+ texsetcount("scaledfontsize",size)
+ lastfontid = id
+ --
+ if trace_defining then
+ report_defining("memory usage after: %s",statistics.memused())
+ report_defining("stop stage two")
+ end
+ --
+ texsetcount("global","lastfontid",lastfontid)
+ specifiers[lastfontid] = { str, size }
+ if not mathsize then
+ -- forget about it (can't happen here)
+ elseif mathsize == 0 then
+ -- can't happen (here)
+ else
+ -- maybe only 1 2 3 (we already test for this)
+ lastmathids[mathsize] = lastfontid
+ end
+ stoptiming(fonts)
+ end)
+ return
+ else
local id = definefont(tfmdata)
csnames[id] = specification.cs
properties.id = id
@@ -1426,7 +1462,7 @@ do -- else too many locals
constructors.finalize(tfmdata)
if trace_defining then
report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a, step %a",
- name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,2)
+ name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,"-")
end
-- resolved (when designsize is used):
local size = round(tfmdata.parameters.size or 655360)
@@ -1434,102 +1470,78 @@ do -- else too many locals
-- ctx_setsomefontsize(size .. "sp")
texsetcount("scaledfontsize",size)
lastfontid = id
- --
- if trace_defining then
- report_defining("memory usage after: %s",statistics.memused())
- report_defining("stop stage two")
- end
- --
- texsetcount("global","lastfontid",lastfontid)
- specifiers[lastfontid] = { str, size }
- if not mathsize then
- -- forget about it (can't happen here)
- elseif mathsize == 0 then
- -- can't happen (here)
- else
- -- maybe only 1 2 3 (we already test for this)
- lastmathids[mathsize] = lastfontid
- end
- stoptiming(fonts)
- end)
- return
- else
- local id = definefont(tfmdata)
- csnames[id] = specification.cs
- properties.id = id
- definers.register(tfmdata,id) -- to be sure, normally already done
- texdefinefont(global,cs,id)
- constructors.cleanuptable(tfmdata)
- constructors.finalize(tfmdata)
+ end
+ elseif tfmtype == "number" then
if trace_defining then
- report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a, step %a",
- name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,"-")
+ report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a",
+ name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize)
end
+ csnames[tfmdata] = specification.cs
+ texdefinefont(global,cs,tfmdata)
-- resolved (when designsize is used):
- local size = round(tfmdata.parameters.size or 655360)
- setmacro("somefontsize",size.."sp")
+ local size = round(fontdata[tfmdata].parameters.size or 0)
-- ctx_setsomefontsize(size .. "sp")
+ setmacro("somefontsize",size.."sp")
texsetcount("scaledfontsize",size)
- lastfontid = id
+ lastfontid = tfmdata
+ else
+ report_defining("unable to define %a as %a",name,nice_cs(cs))
+ lastfontid = -1
+ texsetcount("scaledfontsize",0)
+ -- ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one
end
- elseif tfmtype == "number" then
if trace_defining then
- report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a",
- name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize)
- end
- csnames[tfmdata] = specification.cs
- texdefinefont(global,cs,tfmdata)
- -- resolved (when designsize is used):
- local size = round(fontdata[tfmdata].parameters.size or 0)
- -- ctx_setsomefontsize(size .. "sp")
- setmacro("somefontsize",size.."sp")
- texsetcount("scaledfontsize",size)
- lastfontid = tfmdata
- else
- report_defining("unable to define %a as %a",name,nice_cs(cs))
- lastfontid = -1
- texsetcount("scaledfontsize",0)
- -- ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one
- end
- if trace_defining then
- report_defining("memory usage after: %s",statistics.memused())
- report_defining("stop stage two")
- end
- --
- texsetcount("global","lastfontid",lastfontid)
- specifiers[lastfontid] = { str, size }
- if not mathsize then
- -- forget about it
- elseif mathsize == 0 then
- -- can't happen (here)
- else
- -- maybe only 1 2 3
- lastmathids[mathsize] = lastfontid
+ report_defining("memory usage after: %s",statistics.memused())
+ report_defining("stop stage two")
+ end
+ --
+ texsetcount("global","lastfontid",lastfontid)
+ specifiers[lastfontid] = { str, size }
+ if not mathsize then
+ -- forget about it
+ elseif mathsize == 0 then
+ -- can't happen (here)
+ else
+ -- maybe only 1 2 3
+ lastmathids[mathsize] = lastfontid
+ end
+ --
+ stoptiming(fonts)
end
- --
- stoptiming(fonts)
- end
+ }
- function scanners.specifiedfontspec()
- local f = specifiers[scaninteger()]
- if f then
- context(f[1])
- end
- end
- function scanners.specifiedfontsize()
- local f = specifiers[scaninteger()]
- if f then
- context(f[2])
+ implement {
+ name = "specifiedfontspec",
+ arguments = "integer",
+ actions = function(id)
+ local f = specifiers[id]
+ if f then
+ context(f[1])
+ end
end
- end
- function scanners.specifiedfont()
- local f = specifiers[scaninteger()]
- local s = scannumber()
- if f and s then
- context("%s at %0.2p",f[1],s * f[2]) -- we round to 2 decimals (as at the tex end)
+ }
+
+ implement {
+ name = "specifiedfontsize",
+ arguments = "integer",
+ actions = function(id)
+ local f = specifiers[id]
+ if f then
+ context(f[2])
+ end
end
- end
+ }
+ implement {
+ name = "specifiedfont",
+ arguments = { "integer", "number" },
+ actions = function(id,size)
+ local f = specifiers[id]
+ if f and size then
+ context("%s at %0.2p",f[1],size * f[2]) -- we round to 2 decimals (as at the tex end)
+ end
+ end
+ }
--
local function define(specification)
diff --git a/tex/context/base/mkiv/grph-chk.lua b/tex/context/base/mkiv/grph-chk.lua
index ed78b856c..0688f46ef 100644
--- a/tex/context/base/mkiv/grph-chk.lua
+++ b/tex/context/base/mkiv/grph-chk.lua
@@ -127,9 +127,9 @@ function checkers.pdf(data)
return genericchecker(data)
end
-local function wrappedidentify(identify,filename)
+local function wrappedidentify(identify,filename,filetype)
local wrapup = function() report_inclusion("fatal error reading %a",filename) end
- local _, result = xpcall(identify,wrapup,filename)
+ local _, result = xpcall(identify,wrapup,filename,filetype)
if result then
local xsize = result.xsize or 0
local ysize = result.ysize or 0
@@ -166,7 +166,7 @@ function checkers.jpg(data)
local inject = lpdf.injectors.jpg
local found = false
request.scanimage = function(t)
- local result = wrappedidentify(identify,t.filename)
+ local result = wrappedidentify(identify,t.filename,"jpg")
found = not result.error
return {
filename = result.filename,
@@ -202,7 +202,7 @@ function checkers.jp2(data) -- idem as jpg
local inject = lpdf.injectors.jp2
local found = false
request.scanimage = function(t)
- local result = wrappedidentify(identify,t.filename)
+ local result = wrappedidentify(identify,t.filename,"jp2")
found = not result.error
return {
filename = result.filename,
@@ -238,7 +238,7 @@ function checkers.png(data) -- same as jpg (for now)
local inject = lpdf.injectors.png -- currently pdf specific
local found = false
request.scanimage = function(t)
- local result = wrappedidentify(identify,t.filename)
+ local result = wrappedidentify(identify,t.filename,"png")
found = not result.error
return {
filename = result.filename,
diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua
index 2163e8748..c6dd4765e 100644
--- a/tex/context/base/mkiv/lpdf-ini.lua
+++ b/tex/context/base/mkiv/lpdf-ini.lua
@@ -25,7 +25,6 @@ local report_finalizing = logs.reporter("backend","finalizing")
local report_blocked = logs.reporter("backend","blocked")
local implement = interfaces.implement
-local two_strings = interfaces.strings[2]
local context = context
@@ -1553,16 +1552,16 @@ end
-- interface
implement { name = "lpdf_collectedresources", actions = { lpdf.collectedresources, context } }
-implement { name = "lpdf_addtocatalog", arguments = two_strings, actions = lpdf.addtocatalog }
-implement { name = "lpdf_addtoinfo", arguments = two_strings, actions = function(a,b,c) lpdf.addtoinfo(a,b,c) end } -- gets adapted
-implement { name = "lpdf_addtonames", arguments = two_strings, actions = lpdf.addtonames }
-implement { name = "lpdf_addtopageattributes", arguments = two_strings, actions = lpdf.addtopageattributes }
-implement { name = "lpdf_addtopagesattributes", arguments = two_strings, actions = lpdf.addtopagesattributes }
-implement { name = "lpdf_addtopageresources", arguments = two_strings, actions = lpdf.addtopageresources }
-implement { name = "lpdf_adddocumentextgstate", arguments = two_strings, actions = function(a,b) lpdf.adddocumentextgstate (a,pdfverbose(b)) end }
-implement { name = "lpdf_adddocumentcolorspace", arguments = two_strings, actions = function(a,b) lpdf.adddocumentcolorspace(a,pdfverbose(b)) end }
-implement { name = "lpdf_adddocumentpattern", arguments = two_strings, actions = function(a,b) lpdf.adddocumentpattern (a,pdfverbose(b)) end }
-implement { name = "lpdf_adddocumentshade", arguments = two_strings, actions = function(a,b) lpdf.adddocumentshade (a,pdfverbose(b)) end }
+implement { name = "lpdf_addtocatalog", arguments = "2 strings", actions = lpdf.addtocatalog }
+implement { name = "lpdf_addtoinfo", arguments = "2 strings", actions = function(a,b,c) lpdf.addtoinfo(a,b,c) end } -- gets adapted
+implement { name = "lpdf_addtonames", arguments = "2 strings", actions = lpdf.addtonames }
+implement { name = "lpdf_addtopageattributes", arguments = "2 strings", actions = lpdf.addtopageattributes }
+implement { name = "lpdf_addtopagesattributes", arguments = "2 strings", actions = lpdf.addtopagesattributes }
+implement { name = "lpdf_addtopageresources", arguments = "2 strings", actions = lpdf.addtopageresources }
+implement { name = "lpdf_adddocumentextgstate", arguments = "2 strings", actions = function(a,b) lpdf.adddocumentextgstate (a,pdfverbose(b)) end }
+implement { name = "lpdf_adddocumentcolorspace", arguments = "2 strings", actions = function(a,b) lpdf.adddocumentcolorspace(a,pdfverbose(b)) end }
+implement { name = "lpdf_adddocumentpattern", arguments = "2 strings", actions = function(a,b) lpdf.adddocumentpattern (a,pdfverbose(b)) end }
+implement { name = "lpdf_adddocumentshade", arguments = "2 strings", actions = function(a,b) lpdf.adddocumentshade (a,pdfverbose(b)) end }
-- more helpers: copy from lepd to lpdf
diff --git a/tex/context/base/mkiv/luat-ini.mkiv b/tex/context/base/mkiv/luat-ini.mkiv
index d1d829be9..f059d2b85 100644
--- a/tex/context/base/mkiv/luat-ini.mkiv
+++ b/tex/context/base/mkiv/luat-ini.mkiv
@@ -121,13 +121,13 @@
%D \edef\luaescapestring#1{\!!bs#1\!!es}
%D \stoptyping
-\def\setdocumentfilename #1#2{\clf_setdocumentfilename\numexpr#1\relax{#2}}
-\def\setdocumentargument #1#2{\clf_setdocumentargument{#1}{#2}}
-\def\setdocumentargumentdefault#1#2{\clf_setdocumentdefaultargument{#1}{#2}}
-\def\getdocumentfilename #1{\clf_getdocumentfilename\numexpr#1\relax}
-\def\getdocumentargument #1{\clf_getdocumentargument{#1}{}}
-\def\setdocumentargument #1#2{\clf_setdocumentargument{#1}{#2}}
-\def\getdocumentargumentdefault#1#2{\clf_getdocumentargument{#1}{#2}}
+\normalprotected\def\setdocumentfilename #1#2{\clf_setdocumentfilename\numexpr#1\relax{#2}}
+\normalprotected\def\setdocumentargument #1#2{\clf_setdocumentargument{#1}{#2}}
+\normalprotected\def\setdocumentargumentdefault#1#2{\clf_setdocumentdefaultargument{#1}{#2}}
+ \def\getdocumentfilename #1{\clf_getdocumentfilename\numexpr#1\relax}
+ \def\getdocumentargument #1{\clf_getdocumentargument{#1}{}}
+\normalprotected\def\setdocumentargument #1#2{\clf_setdocumentargument{#1}{#2}}
+ \def\getdocumentargumentdefault#1#2{\clf_getdocumentargument{#1}{#2}}
% seldom used so no need for speedy variants:
diff --git a/tex/context/base/mkiv/luat-usr.lua b/tex/context/base/mkiv/luat-usr.lua
index b49379bbf..1756bb198 100644
--- a/tex/context/base/mkiv/luat-usr.lua
+++ b/tex/context/base/mkiv/luat-usr.lua
@@ -102,23 +102,6 @@ interfaces.implement {
arguments = "2 strings",
}
--- local scanners = interfaces.scanners
---
--- local function ctxscanner(name)
--- local scanner = scanners[name]
--- if scanner then
--- scanner()
--- else
--- report("unknown scanner: %s",name)
--- end
--- end
---
--- interfaces.implement {
--- name = "clfscanner",
--- actions = ctxscanner,
--- arguments = "string",
--- }
-
local function registername(name,message)
if not name or name == "" then
report_instance("no valid name given")
diff --git a/tex/context/base/mkiv/publ-aut.lua b/tex/context/base/mkiv/publ-aut.lua
index e74c7ee18..123a67009 100644
--- a/tex/context/base/mkiv/publ-aut.lua
+++ b/tex/context/base/mkiv/publ-aut.lua
@@ -530,9 +530,9 @@ implement {
name = "btxauthor",
actions = btxauthor,
arguments = {
- "string",
- "string",
- "string",
+ "argument",
+ "argument",
+ "argument",
{
{ "combiner" },
{ "kind" },
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 374d3b695..26777bb6d 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index a39f37412..ad3136f2a 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-itm.mklx b/tex/context/base/mkiv/strc-itm.mklx
index 2f3cc8425..3d1861d12 100644
--- a/tex/context/base/mkiv/strc-itm.mklx
+++ b/tex/context/base/mkiv/strc-itm.mklx
@@ -1321,6 +1321,7 @@
\letvalue{\??itemgroupstart\v!ran }\strc_itemgroups_start_edge
\letvalue{\??itemgroupstart\v!its }\strc_itemgroups_start_items
\letvalue{\??itemgroupstart\v!mar }\strc_itemgroups_start_margin
+\letvalue{\??itemgroupstart\v!txt }\strc_itemgroups_start_text
\def\optimizelistitemsbreak
{\ifcase\c_strc_itemgroups_column_depth
@@ -1578,6 +1579,11 @@
\appendtoks
\let\item \strc_itemgroups_start_do_item
+ \let\sub \strc_itemgroups_start_subitem
+ \let\sym \strc_itemgroups_start_symbol
+ \let\ran \strc_itemgroups_start_edge
+ \let\its \strc_itemgroups_start_items
+ \let\mar \strc_itemgroups_start_margin
\let\noitem \strc_itemgroups_start_no_item
\let\itm \strc_itemgroups_start_do_item
\let\but \strc_itemgroups_start_button
@@ -1588,27 +1594,29 @@
\let\startitem \startitemgroupitem
\let\stopitem \stopitemgroupitem
\let\starthead \startitemgrouphead
- \let\stophead \stopitemgroupitemhead
+ \let\stophead \stopitemgrouphead
\let\startspecialitem\startspecialitemgroupitem
\let\stopspecialitem \stopspecialitemgroupitem
\to \itemgroupcommands
-\ifx\currentinterface \v!english \else
-
- \appendtoks
- \expandafter\let\csname\v!item \endcsname\strc_itemgroups_start_do_item
- \expandafter\let\csname\v!sub \endcsname\strc_itemgroups_start_subitem
- \expandafter\let\csname\v!sym \endcsname\strc_itemgroups_start_symbol
- \expandafter\let\csname\v!ran \endcsname\strc_itemgroups_start_edge
- \expandafter\let\csname\v!head \endcsname\strc_itemgroups_head
- \expandafter\let\csname\v!its \endcsname\strc_itemgroups_start_items
- \expandafter\let\csname\v!mar \endcsname\strc_itemgroups_start_margin
- \expandafter\let\csname\v!txt \endcsname\strc_itemgroups_start_text
- \expandafter\let\csname\e!start\v!item\endcsname\startitemgroupitem
- \expandafter\let\csname\e!stop \v!item\endcsname\stopitemgroupitem
- \expandafter\let\csname\e!start\v!head\endcsname\startitemgrouphead
- \expandafter\let\csname\e!stop \v!head\endcsname\stopitemgrouphead
- \to \itemgroupcommands
+\ifx\currentinterface \s!english \else
+
+ \def\next#1#2{\ifcsname#1\endcsname\else\let\csname#1\endcsname#2\fi}
+
+ \etoksapp\itemgroupcommands{%
+ \next{\v!item }\strc_itemgroups_start_do_item
+ \next{\v!sub }\strc_itemgroups_start_subitem
+ \next{\v!sym }\strc_itemgroups_start_symbol
+ \next{\v!ran }\strc_itemgroups_start_edge
+ \next{\v!head }\strc_itemgroups_head
+ \next{\v!its }\strc_itemgroups_start_items
+ \next{\v!mar }\strc_itemgroups_start_margin
+ \next{\v!txt }\strc_itemgroups_start_text
+ \next{\e!start\v!item}\startitemgroupitem
+ \next{\e!stop \v!item}\stopitemgroupitem
+ \next{\e!start\v!head}\startitemgrouphead
+ \next{\e!stop \v!head}\stopitemgrouphead
+ }
\fi
diff --git a/tex/context/base/mkiv/strc-itm.mkvi b/tex/context/base/mkiv/strc-itm.mkvi
index cbbefd5db..1b306fe18 100644
--- a/tex/context/base/mkiv/strc-itm.mkvi
+++ b/tex/context/base/mkiv/strc-itm.mkvi
@@ -1321,6 +1321,7 @@
\letvalue{\??itemgroupstart\v!ran }\strc_itemgroups_start_edge
\letvalue{\??itemgroupstart\v!its }\strc_itemgroups_start_items
\letvalue{\??itemgroupstart\v!mar }\strc_itemgroups_start_margin
+\letvalue{\??itemgroupstart\v!txt }\strc_itemgroups_start_text
\def\optimizelistitemsbreak
{\ifcase\c_strc_itemgroups_column_depth \ifconditional\c_strc_itemgroups_optimize
@@ -1577,6 +1578,11 @@
\appendtoks
\let\item \strc_itemgroups_start_do_item
+ \let\sub \strc_itemgroups_start_subitem
+ \let\sym \strc_itemgroups_start_symbol
+ \let\ran \strc_itemgroups_start_edge
+ \let\its \strc_itemgroups_start_items
+ \let\mar \strc_itemgroups_start_margin
\let\noitem \strc_itemgroups_start_no_item
\let\itm \strc_itemgroups_start_do_item
\let\but \strc_itemgroups_start_button
@@ -1587,27 +1593,29 @@
\let\startitem \startitemgroupitem
\let\stopitem \stopitemgroupitem
\let\starthead \startitemgrouphead
- \let\stophead \stopitemgroupitemhead
+ \let\stophead \stopitemgrouphead
\let\startspecialitem\startspecialitemgroupitem
\let\stopspecialitem \stopspecialitemgroupitem
\to \itemgroupcommands
-\ifx\currentinterface \v!english \else
-
- \appendtoks
- \expandafter\let\csname\v!item \endcsname\strc_itemgroups_start_do_item
- \expandafter\let\csname\v!sub \endcsname\strc_itemgroups_start_subitem
- \expandafter\let\csname\v!sym \endcsname\strc_itemgroups_start_symbol
- \expandafter\let\csname\v!ran \endcsname\strc_itemgroups_start_edge
- \expandafter\let\csname\v!head \endcsname\strc_itemgroups_head
- \expandafter\let\csname\v!its \endcsname\strc_itemgroups_start_items
- \expandafter\let\csname\v!mar \endcsname\strc_itemgroups_start_margin
- \expandafter\let\csname\v!txt \endcsname\strc_itemgroups_start_text
- \expandafter\let\csname\e!start\v!item\endcsname\startitemgroupitem
- \expandafter\let\csname\e!stop \v!item\endcsname\stopitemgroupitem
- \expandafter\let\csname\e!start\v!head\endcsname\startitemgrouphead
- \expandafter\let\csname\e!stop \v!head\endcsname\stopitemgrouphead
- \to \itemgroupcommands
+\ifx\currentinterface \s!english \else
+
+ \def\next#1#2{\ifcsname#1\endcsname\else\let\csname#1\endcsname#2\fi}
+
+ \etoksapp\itemgroupcommands{%
+ \next{\v!item }\strc_itemgroups_start_do_item
+ \next{\v!sub }\strc_itemgroups_start_subitem
+ \next{\v!sym }\strc_itemgroups_start_symbol
+ \next{\v!ran }\strc_itemgroups_start_edge
+ \next{\v!head }\strc_itemgroups_head
+ \next{\v!its }\strc_itemgroups_start_items
+ \next{\v!mar }\strc_itemgroups_start_margin
+ \next{\v!txt }\strc_itemgroups_start_text
+ \next{\e!start\v!item}\startitemgroupitem
+ \next{\e!stop \v!item}\stopitemgroupitem
+ \next{\e!start\v!head}\startitemgrouphead
+ \next{\e!stop \v!head}\stopitemgrouphead
+ }
\fi
diff --git a/tex/context/base/mkiv/syst-aux.mkxl b/tex/context/base/mkiv/syst-aux.mkxl
index 956d43f89..2c84fe2c6 100644
--- a/tex/context/base/mkiv/syst-aux.mkxl
+++ b/tex/context/base/mkiv/syst-aux.mkxl
@@ -634,9 +634,9 @@
%D These are normally only used for keywords, i.e.\ strings so we can delegate
%D the work to \LUA:
-\unexpanded\def\doifelseinset#1#2{\clf_doifelseinset{#1}{#2}}
-\unexpanded\def\doifinset #1#2{\clf_doifinset {#1}{#2}}
-\unexpanded\def\doifnotinset #1#2{\clf_doifnotinset {#1}{#2}}
+%unexpanded\def\doifelseinset#1#2{\clf_doifelseinset{#1}{#2}}
+%unexpanded\def\doifinset #1#2{\clf_doifinset {#1}{#2}}
+%unexpanded\def\doifnotinset #1#2{\clf_doifnotinset {#1}{#2}}
% % \let\firstinset \clf_firstinset
% These don't accept spaces after commas:
diff --git a/tex/context/base/mkiv/syst-lua.lua b/tex/context/base/mkiv/syst-lua.lua
index 77960def7..5976e077f 100644
--- a/tex/context/base/mkiv/syst-lua.lua
+++ b/tex/context/base/mkiv/syst-lua.lua
@@ -20,11 +20,9 @@ local ctx_secondoftwoarguments = context.secondoftwoarguments
local ctx_firstofoneargument = context.firstofoneargument
local ctx_gobbleoneargument = context.gobbleoneargument
-local two_strings = interfaces.strings[2]
-
implement { -- will be overloaded later
name = "writestatus",
- arguments = two_strings,
+ arguments = "2 strings",
actions = logs.status,
}
@@ -123,7 +121,7 @@ implement {
implement {
name = "doifelsesame",
- arguments = two_strings,
+ arguments = "2 strings",
actions = function(a,b)
if a == b then
ctx_firstoftwoarguments()
@@ -135,7 +133,7 @@ implement {
implement {
name = "doifsame",
- arguments = two_strings,
+ arguments = "2 strings",
actions = function(a,b)
if a == b then
ctx_firstofoneargument()
@@ -147,7 +145,7 @@ implement {
implement {
name = "doifnotsame",
- arguments = two_strings,
+ arguments = "2 strings",
actions = function(a,b)
if a == b then
ctx_gobbleoneargument()
diff --git a/tex/context/base/mkiv/toks-ini.lua b/tex/context/base/mkiv/toks-ini.lua
index 0ac5dcc50..184a17489 100644
--- a/tex/context/base/mkiv/toks-ini.lua
+++ b/tex/context/base/mkiv/toks-ini.lua
@@ -43,6 +43,7 @@ end
local scan_toks = token.scan_toks
local scan_string = token.scan_string
local scan_argument = token.scan_argument
+local scan_delimited = token.scan_delimited
local scan_tokenlist = token.scan_tokenlist
local scan_int = token.scan_int
local scan_code = token.scan_code
@@ -55,6 +56,7 @@ local scan_keyword_cs = token.scan_keyword_cs or scan_keyword
local scan_token = token.scan_token
local scan_box = token.scan_box
local scan_word = token.scan_word
+local scan_letters = token.scan_letters or scan_word -- lmtx
local scan_key = token.scan_key
local scan_value = token.scan_value
local scan_char = token.scan_char
@@ -191,11 +193,13 @@ tokens.scanners = { -- these expand
count = scan_int,
string = scan_string,
argument = scan_argument,
+ delimited = scan_delimited,
tokenlist = scan_tokenlist,
verbatim = scan_verbatim, -- detokenize
code = scan_code,
tokencode = scan_token_code,
word = scan_word,
+ letters = scan_letters,
key = scan_key,
value = scan_value,
char = scan_char,
diff --git a/tex/context/base/mkiv/toks-scn.lua b/tex/context/base/mkiv/toks-scn.lua
index 09c3e13b2..7ef4ce603 100644
--- a/tex/context/base/mkiv/toks-scn.lua
+++ b/tex/context/base/mkiv/toks-scn.lua
@@ -22,13 +22,16 @@ local tokenbits = tokens.bits
local scanstring = scanners.string
local scanargument = scanners.argument
+local scandelimited = scanners.delimited -- lmtx
local scanverbatim = scanners.verbatim
local scantokenlist = scanners.tokenlist
+local scantoks = scanners.toks
local scaninteger = scanners.integer
local scannumber = scanners.number
local scankeyword = scanners.keyword
local scankeywordcs = scanners.keywordcs
local scanword = scanners.word
+local scanletters = scanners.letters
local scankey = scanners.key
local scancode = scanners.code
local scanboolean = scanners.boolean
@@ -113,23 +116,24 @@ local function scantable(t,data)
if not data then
data = { }
end
- local wrapped = scanopen()
- while true do
--- local key = scanword()
- local key = scanword(true)
- if key then
- local get = t[key]
- if get then
- data[key] = get()
+ if t then
+ local wrapped = scanopen()
+ while true do
+ local key = scanword(true)
+ if key then
+ local get = t[key]
+ if get then
+ data[key] = get()
+ else
+ -- catch all we can get
+ end
else
- -- catch all we can get
+ break
end
- else
- break
end
- end
- if wrapped then
- scanclose()
+ if wrapped then
+ scanclose()
+ end
end
return data
end
@@ -166,42 +170,84 @@ function scanners.whd()
end
end
+-- begin lmtx
+
+local l = utf.byte("[")
+local r = utf.byte("]")
+
+local function scanbracketed()
+ local s = scandelimited(l, r)
+ if s then
+ return s
+ else
+ report_scan("missing argument in line %i of %a", status.linenumber, status.filename)
+ return ""
+ end
+end
+
+local function scanoptional()
+ return scandelimited(l, r) or ""
+end
+
+local function scanbracketedasis()
+ return scandelimited(l, r, false)
+end
+
+local function scanargumentasis()
+ return scanargument(false)
+end
+
+scanners.bracketed = scanbracketed
+scanners.optional = scanoptional
+scanners.bracketedasis = scanbracketedasis
+scanners.argumentasis = scanargumentasis
+
+-- end lmtx
+
local shortcuts = {
- tokens = tokens,
- bits = tokenbits,
- open = open,
- close = close,
- scanners = scanners,
- scanstring = scanstring,
- scanargument = scanargument,
- scanverbatim = scanverbatim,
- scantokenlist = scantokenlist,
- scaninteger = scaninteger,
- scannumber = scannumber,
- scantable = scantable,
- scankeyword = scankeyword,
- scankeywordcs = scankeywordcs,
- scanword = scanword,
- -- scankey = scankey,
- scancode = scancode,
- scanboolean = scanboolean,
- scandimen = scandimen,
- scandimension = scandimen,
- scanbox = scanners.box,
- scanhbox = scanners.hbox,
- scanvbox = scanners.vbox,
- scanvtop = scanners.vtop,
- scanconditional = scanconditional,
- scanopen = scanopen,
- scanclose = scanclose,
- scanlist = scanlist,
- scancsname = scancsname,
- todimen = todimen,
- tonumber = tonumber,
- tostring = tostring,
- toboolean = toboolean,
- inspect = inspect,
- report = report_scan,
+ tokens = tokens,
+ bits = tokenbits,
+ open = open,
+ close = close,
+ scanners = scanners,
+ scanstring = scanstring,
+ scanargument = scanargument,
+ scanverbatim = scanverbatim,
+ scantokenlist = scantokenlist,
+ scantoks = scantoks,
+ scaninteger = scaninteger,
+ scannumber = scannumber,
+ scantable = scantable, -- not directly useable
+ scankeyword = scankeyword,
+ scankeywordcs = scankeywordcs,
+ scanword = scanword,
+ scanletters = scanletters,
+ -- scankey = scankey,
+ scancode = scancode,
+ scanboolean = scanboolean,
+ scandimen = scandimen,
+ scandimension = scandimen,
+ scanbox = scanners.box,
+ scanhbox = scanners.hbox,
+ scanvbox = scanners.vbox,
+ scanvtop = scanners.vtop,
+ scanconditional = scanconditional,
+ scanopen = scanopen,
+ scanclose = scanclose,
+ scanlist = scanlist,
+ scancsname = scancsname,
+ todimen = todimen,
+ tonumber = tonumber,
+ tostring = tostring,
+ toboolean = toboolean,
+ inspect = inspect,
+ report = report_scan,
+ -- lmtx
+ scandelimited = scandelimited, -- not directly useable
+ scanbracketed = scanbracketed,
+ scanoptional = scanoptional,
+ scanbracketedasis = scanbracketedasis,
+ scanargumentasis = scanargumentasis,
}
tokens.shortcuts = shortcuts
@@ -222,25 +268,28 @@ tokens.converters = {
toglue = "todimen",
}
--- We could just pickup a keyword but then we really need to make sure
--- that no number follows it when that is the assignment and adding
--- an optional = defeats the gain in speed. Currently we have sources
--- with no spaces (\startcontextdefinitioncode ...) so it fails there.
+-- We could just pickup a keyword but then we really need to make sure that no number
+-- follows it when that is the assignment and adding an optional = defeats the gain
+-- in speed. Currently we have sources with no spaces (\startcontextdefinitioncode
+-- ...) so it fails there.
--
--- Another drawback is that we then need to use { } instead of ending
--- with \relax (as we can do now) but that is no big deal. It's just
--- that I then need to check the TeX end. More pain than gain and a bit
--- risky too.
+-- Another drawback is that we then need to use { } instead of ending with \relax (as
+-- we can do now) but that is no big deal. It's just that I then need to check the TeX
+-- end. More pain than gain and a bit risky too. Using scanletters works better, but
+-- the gain is only some 10 percent but if we don't have keywords with numbers it might
+-- make sense in the end, some day.
local f_if = formatters[ " if scankeywordcs('%s') then data['%s'] = scan%s()"]
local f_elseif = formatters[" elseif scankeywordcs('%s') then data['%s'] = scan%s()"]
------ f_if = formatters[" local key = scanword() if key == '' then break elseif key == '%s' then data['%s'] = scan%s()"]
------ f_elseif = formatters[" elseif key == '%s' then data['%s'] = scan%s()"]
-
----- f_if_x = formatters[ " if not data['%s'] and scankeywordcs('%s') then data['%s'] = scan%s()"]
----- f_elseif_x = formatters[" elseif not data['%s'] and scankeywordcs('%s') then data['%s'] = scan%s()"]
+-- if CONTEXTLMTXMODE > 0 then
+-- f_if = formatters[" local key = scanletters() if key == '' then break elseif key == '%s' then data['%s'] = scan%s()"]
+-- f_elseif = formatters[" elseif key == '%s' then data['%s'] = scan%s()"]
+-- end
+
local f_local = formatters["local scan%s = scanners.%s"]
local f_scan = formatters["scan%s()"]
local f_shortcut = formatters["local %s = scanners.converters.%s"]
@@ -250,9 +299,11 @@ local f_elseif_c = formatters[" elseif scankeywordcs('%s') then data['%s'] = %s
local f_scan_c = formatters["%s(scan%s())"]
-- see above
---
------ f_if_c = formatters[" local key = scanword() if key == '' then break elseif key == '%s' then data['%s'] = %s(scan%s())"]
------ f_elseif_c = formatters[" elseif k == '%s' then data['%s'] = %s(scan%s())"]
+
+-- if CONTEXTLMTXMODE > 0 then
+-- f_if_c = formatters[" local key = scanletters() if key == '' then break elseif key == '%s' then data['%s'] = %s(scan%s())"]
+-- f_elseif_c = formatters[" elseif k == '%s' then data['%s'] = %s(scan%s())"]
+-- end
local f_any = formatters[" else local key = scanword(true) if key then data[key] = scan%s() else break end end"]
local f_any_c = formatters[" else local key = scanword(true) if key then data[key] = %s(scan%s()) else break end end"]
@@ -270,33 +321,6 @@ local f_action_f = formatters["action%s(%s)"]
local f_action_s = formatters["local action%s = tokens._action[%s]"]
local f_nested = formatters["local function scan%s()\n local data = { }\n%s\n return data\nend\n"]
--- local f_check = formatters[ [[
--- local wrapped = false
--- while true do
--- local c = scancode(open)
--- if c == 123 then
--- wrapped = true
--- break
--- elseif c ~= 32 then
--- break
--- end
--- end
--- while true do
--- ]] .. "%\nt\n" .. [[
--- %s
--- end
--- if wrapped then
--- while true do
--- local c = scancode(close)
--- if c == 125 then
--- break
--- elseif c ~= 32 then
--- break
--- end
--- end
--- end
--- ]] ]
-
local f_check = formatters[ [[
local wrapped = scanopen()
while true do
@@ -319,6 +343,11 @@ local presets = {
["6 strings"] = { "string", "string", "string", "string", "string", "string" },
["7 strings"] = { "string", "string", "string", "string", "string", "string", "string" },
["8 strings"] = { "string", "string", "string", "string", "string", "string", "string", "string" },
+
+ ["1 argument" ] = { "argument" },
+ ["2 arguments"] = { "argument", "argument" },
+ ["3 arguments"] = { "argument", "argument", "argument" },
+ ["4 arguments"] = { "argument", "argument", "argument", "argument" },
}
tokens.presets = presets
@@ -542,7 +571,7 @@ end
-- { "nature", "boolean" },
-- { "escape", "string" },
-- { "escape" },
--- }
+-- },
-- "boolean",
-- }
--
diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua
index aba7859c3..2d3f4d669 100644
--- a/tex/context/base/mkiv/util-str.lua
+++ b/tex/context/base/mkiv/util-str.lua
@@ -1057,76 +1057,44 @@ local format_rest = function(s)
return format("%q",s) -- catches " and \n and such
end
--- local format_extension = function(extensions,f,name)
--- local extension = extensions[name] or "tostring(%s)"
--- local f = tonumber(f) or 1
--- local w = find(extension,"%.%.%.")
--- if f == 0 then
--- if w then
--- extension = gsub(extension,"%.%.%.","")
--- end
--- return extension
--- elseif f == 1 then
--- if w then
--- extension = gsub(extension,"%.%.%.","%%s")
--- end
--- n = n + 1
--- local a = "a" .. n
--- return format(extension,a,a) -- maybe more times?
--- elseif f < 0 then
--- local a = "a" .. (n + f + 1)
--- return format(extension,a,a)
--- else
--- if w then
--- extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
--- end
--- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
--- -- cache we don't save much and there are hardly any extensions anyway
--- local t = { }
--- for i=1,f do
--- n = n + 1
--- -- t[#t+1] = "a" .. n
--- t[i] = "a" .. n
--- end
--- return format(extension,unpack(t))
--- end
--- end
-
local format_extension = function(extensions,f,name)
local extension = extensions[name] or "tostring(%s)"
local f = tonumber(f) or 1
local w = find(extension,"%.%.%.")
- if w then
- -- we have a wildcard
- if f == 0 then
+ if f == 0 then
+ if w then
extension = gsub(extension,"%.%.%.","")
- return extension
- elseif f == 1 then
+ end
+ return extension
+ elseif f == 1 then
+ if w then
extension = gsub(extension,"%.%.%.","%%s")
- n = n + 1
- local a = "a" .. n
- return format(extension,a,a) -- maybe more times?
- elseif f < 0 then
+ end
+ n = n + 1
+ local a = "a" .. n
+ return format(extension,a,a) -- maybe more times?
+ elseif f < 0 then
+ if w then
+ -- not supported
+ extension = gsub(extension,"%.%.%.","")
+ return extension
+ else
local a = "a" .. (n + f + 1)
return format(extension,a,a)
- else
- extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
- -- cache we don't save much and there are hardly any extensions anyway
- local t = { }
- for i=1,f do
- n = n + 1
- -- t[#t+1] = "a" .. n
- t[i] = "a" .. n
- end
- return format(extension,unpack(t))
end
else
- extension = gsub(extension,"%%s",function()
+ if w then
+ extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ end
+ -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we
+ -- cache we don't save much and there are hardly any extensions anyway
+ local t = { }
+ for i=1,f do
n = n + 1
- return "a" .. n
- end)
- return extension
+ -- t[#t+1] = "a" .. n
+ t[i] = "a" .. n
+ end
+ return format(extension,unpack(t))
end
end