summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/context/documents/general/manuals/luametatex.pdfbin1219871 -> 1219852 bytes
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex.tex4
-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/cont-new.mkiv5
-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/font-cff.lua47
-rw-r--r--tex/context/base/mkiv/font-con.lua2
-rw-r--r--tex/context/base/mkiv/font-ctx.lua9
-rw-r--r--tex/context/base/mkiv/font-def.lua2
-rw-r--r--tex/context/base/mkiv/node-aux.lmt396
-rw-r--r--tex/context/base/mkiv/node-aux.lua9
-rw-r--r--tex/context/base/mkiv/node-ini.lmt287
-rw-r--r--tex/context/base/mkiv/node-ini.mkiv6
-rw-r--r--tex/context/base/mkiv/node-met.lua2
-rw-r--r--tex/context/base/mkiv/node-nut.lmt572
-rw-r--r--tex/context/base/mkiv/node-nut.lua24
-rw-r--r--tex/context/base/mkiv/node-res.lua5
-rw-r--r--tex/context/base/mkiv/node-snp.lmt4
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin28100 -> 28150 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin256148 -> 256232 bytes
-rw-r--r--tex/context/base/mkiv/trac-inf.lmt26
-rw-r--r--tex/context/base/mkiv/trac-tim.lmt1
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua54
25 files changed, 1381 insertions, 82 deletions
diff --git a/doc/context/documents/general/manuals/luametatex.pdf b/doc/context/documents/general/manuals/luametatex.pdf
index d1e920204..25bd874ae 100644
--- a/doc/context/documents/general/manuals/luametatex.pdf
+++ b/doc/context/documents/general/manuals/luametatex.pdf
Binary files differ
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex.tex b/doc/context/sources/general/manuals/luametatex/luametatex.tex
index e1e22c482..debfdb358 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex.tex
@@ -50,9 +50,7 @@
% Thanks to sebastian.miele@gmail.com for close reading the manual and
% sending fixes.
-% \enabledirectives[system.usage]
-
-% \enabletrackers[*]
+\enabletrackers[system.usage=summary]
\environment luametatex-style
\environment luametatex-private
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 3d592f4ed..20642a907 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.08.25 19:56}
+\newcontextversion{2020.08.27 19:25}
%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 7c22b1c87..16de426df 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.08.25 19:56}
+\edef\contextversion{2020.08.27 19:25}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 40c3c3272..fc27b0538 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.08.25 19:56}
+\newcontextversion{2020.08.27 19:25}
%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
@@ -21,6 +21,9 @@
%D so old that I need to remind myself to check it occasionally, so here is the
%D reminder).
+% \enabletrackers[pages.timing]
+% \enabletrackers[system.usage=summary]
+
\unprotect
\writestatus\m!system{beware: some patches loaded from cont-new.mkiv}
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 092b16960..5164ea5dd 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.08.25 19:56}
+\edef\contextversion{2020.08.27 19:25}
%D Kind of special:
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index 5c6ded5c9..e7d0ffdfd 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.08.25 19:56}
+\edef\contextversion{2020.08.27 19:25}
%D Kind of special:
diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua
index c2cf0e699..b7d45392d 100644
--- a/tex/context/base/mkiv/font-cff.lua
+++ b/tex/context/base/mkiv/font-cff.lua
@@ -610,15 +610,15 @@ do
+ p_unsupported
)^1
- parsedictionaries = function(data,dictionaries,what)
+ parsedictionaries = function(data,dictionaries,version)
stack = { }
strings = data.strings
if trace_charstrings then
- report("charstring format %a",what)
+ report("charstring format %a",version)
end
for i=1,#dictionaries do
top = 0
- result = what == "cff" and {
+ result = version == "cff" and {
monospaced = false,
italicangle = 0,
underlineposition = -100,
@@ -2265,8 +2265,8 @@ do
end
-local function readglobals(f,data)
- local routines = readlengths(f)
+local function readglobals(f,data,version)
+ local routines = readlengths(f,version == "cff2")
for i=1,#routines do
routines[i] = readbytetable(f,routines[i])
end
@@ -2324,14 +2324,14 @@ local function readprivates(f,data)
end
end
-local function readlocals(f,data,dictionary)
+local function readlocals(f,data,dictionary,version)
local header = data.header
local private = dictionary.private
if private then
local subroutineoffset = private.data.subroutines
if subroutineoffset ~= 0 then
setposition(f,header.offset+private.offset+subroutineoffset)
- local subroutines = readlengths(f)
+ local subroutines = readlengths(f,version == "cff2")
for i=1,#subroutines do
subroutines[i] = readbytetable(f,subroutines[i])
end
@@ -2348,7 +2348,7 @@ end
-- These charstrings are little programs and described in: Technical Note #5177. A truetype
-- font has only one dictionary.
-local function readcharstrings(f,data,what)
+local function readcharstrings(f,data,version)
local header = data.header
local dictionaries = data.dictionaries
local dictionary = dictionaries[1]
@@ -2359,7 +2359,7 @@ local function readcharstrings(f,data,what)
elseif stringtype == 2 then
setposition(f,header.offset+offset)
-- could be a metatable .. delayed loading
- local charstrings = readlengths(f,what=="cff2")
+ local charstrings = readlengths(f,version=="cff2")
local nofglyphs = #charstrings
for i=1,nofglyphs do
charstrings[i] = readstring(f,charstrings[i])
@@ -2394,7 +2394,8 @@ readers.parsecharstrings = parsecharstrings -- used in font-onr.lua (type 1)
local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionaries = data.dictionaries
local dictionary = dictionaries[1]
- readglobals(f,data)
+ local cid = not dictionary.private and dictionary.cid
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version == "cff2" then
dictionary.charset = nil
@@ -2402,9 +2403,27 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
readencodings(f,data)
readcharsets(f,data,dictionary)
end
+ if cid then
+ local fdarray = cid.fdarray
+ if fdarray then
+ setposition(f,data.header.offset + fdarray)
+ local dictionaries = readlengths(f,version=="cff2")
+ local nofdictionaries = #dictionaries
+ if nofdictionaries > 0 then
+ for i=1,nofdictionaries do
+ dictionaries[i] = readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ dictionary.private = dictionaries[1].private
+ if nofdictionaries > 1 then
+ report("ignoring dictionaries > 1 in cid font")
+ end
+ end
+ end
+ end
readprivates(f,data)
parseprivates(data,data.dictionaries)
- readlocals(f,data,dictionary)
+ readlocals(f,data,dictionary,version)
startparsing(fontdata,data,streams)
parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
stopparsing(fontdata,data)
@@ -2416,7 +2435,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionary = dictionaries[1]
local cid = dictionary.cid
local cidselect = cid and cid.fdselect
- readglobals(f,data)
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version ~= "cff2" then
readencodings(f,data)
@@ -2462,7 +2481,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local cidarray = cid.fdarray
if cidarray then
setposition(f,header.offset+cidarray)
- local dictionaries = readlengths(f)
+ local dictionaries = readlengths(f,version == "cff2")
for i=1,#dictionaries do
dictionaries[i] = readstring(f,dictionaries[i])
end
@@ -2470,7 +2489,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
cid.dictionaries = dictionaries
readcidprivates(f,data)
for i=1,#dictionaries do
- readlocals(f,data,dictionaries[i])
+ readlocals(f,data,dictionaries[i],version)
end
startparsing(fontdata,data,streams)
for i=1,#charstrings do
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index 495148341..7162338c6 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -451,6 +451,7 @@ function constructors.scale(tfmdata,specification)
target.format = properties.format
target.cache = constructors.cacheintex and "yes" or "renew"
--
+ local original = properties.original or tfmdata.original
local fontname = properties.fontname or tfmdata.fontname
local fullname = properties.fullname or tfmdata.fullname
local filename = properties.filename or tfmdata.filename
@@ -462,6 +463,7 @@ function constructors.scale(tfmdata,specification)
--
local psname, psfixed = fixedpsname(psname,fontname or fullname or file.nameonly(filename))
--
+ target.original = original
target.fontname = fontname
target.fullname = fullname
target.filename = filename
diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua
index e6ed58492..eec967c1c 100644
--- a/tex/context/base/mkiv/font-ctx.lua
+++ b/tex/context/base/mkiv/font-ctx.lua
@@ -1221,6 +1221,7 @@ do -- else too many locals
-- ctx_setemptyfontsize()
end
specification = definers.makespecification(str,lookup,name,sub,method,detail,size)
+-- specification.original = str
if trace_defining then
report_defining("stop stage one")
end
@@ -1239,11 +1240,6 @@ do -- else too many locals
combinefeatures = v
end)
-
-
-
-
-
implement {
name = "definefont_two",
arguments = {
@@ -1269,7 +1265,6 @@ do -- else too many locals
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
@@ -1424,6 +1419,7 @@ do -- else too many locals
context(function()
busy = false
mathematics.finishfallbacks(tfmdata,specification,fallbacks)
+tfmdata.original = specification.specification
local id = definefont(tfmdata)
csnames[id] = specification.cs
properties.id = id
@@ -1461,6 +1457,7 @@ do -- else too many locals
end)
return
else
+tfmdata.original = specification.specification
local id = definefont(tfmdata)
csnames[id] = specification.cs
properties.id = id
diff --git a/tex/context/base/mkiv/font-def.lua b/tex/context/base/mkiv/font-def.lua
index 09f2e2c32..b752b3258 100644
--- a/tex/context/base/mkiv/font-def.lua
+++ b/tex/context/base/mkiv/font-def.lua
@@ -489,7 +489,9 @@ function definers.read(specification,size,id) -- id can be optional, name can al
end
else
tfmdata = definers.loadfont(specification) -- can be overloaded
+-- put in properties instead
if tfmdata then
+ tfmdata.original = specification.specification
if trace_defining then
report_defining("loaded and hashed: %s",hash)
end
diff --git a/tex/context/base/mkiv/node-aux.lmt b/tex/context/base/mkiv/node-aux.lmt
new file mode 100644
index 000000000..9e7c02028
--- /dev/null
+++ b/tex/context/base/mkiv/node-aux.lmt
@@ -0,0 +1,396 @@
+if not modules then modules = { } end modules ['node-aux'] = {
+ version = 1.001,
+ comment = "companion to node-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- todo: n1 .. n2 : __concat metatable
+
+local type, tostring = type, tostring
+
+local nodes = nodes
+local context = context
+
+local utfvalues = utf.values
+
+local nodecodes = nodes.nodecodes
+
+local glyph_code = nodecodes.glyph
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local attributelist_code = nodecodes.attributelist -- temporary
+local localpar_code = nodecodes.localpar
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+local vianuts = nuts.vianuts
+
+local getbox = nuts.getbox
+local getnext = nuts.getnext
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getlist = nuts.getlist
+local getattr = nuts.getattr
+local getboth = nuts.getboth
+local getprev = nuts.getprev
+local getwidth = nuts.getwidth
+local setwidth = nuts.setwidth
+local getboxglue = nuts.getboxglue
+local setboxglue = nuts.setboxglue
+
+local setfield = nuts.setfield
+local setattr = nuts.setattr
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local setnext = nuts.setnext
+local setprev = nuts.setprev
+local setattrlist = nuts.setattrlist
+
+local traversers = nuts.traversers
+local nextnode = traversers.node
+local nextglyph = traversers.glyph
+
+local flush_node = nuts.flush
+local flush_list = nuts.flush_list
+local hpack_nodes = nuts.hpack
+local unset_attribute = nuts.unset_attribute
+local first_glyph = nuts.first_glyph
+local copy_node = nuts.copy
+local find_tail = nuts.tail
+local getbox = nuts.getbox
+local count = nuts.count
+local isglyph = nuts.isglyph
+
+local nodepool = nuts.pool
+local new_glue = nodepool.glue
+local new_glyph = nodepool.glyph
+
+local unsetvalue = attributes.unsetvalue
+
+local current_font = font.current
+
+local texsetbox = tex.setbox
+
+local report_error = logs.reporter("node-aux:error")
+
+local function takebox(id)
+ local box = getbox(id)
+ if box then
+ local list = getlist(box)
+ setlist(box,nil)
+ local copy = copy_node(box)
+ if list then
+ setlist(copy,list)
+ end
+ texsetbox(id,false)
+ return copy
+ end
+end
+
+function nodes.takebox(id)
+ local b = takebox(id)
+ if b then
+ return tonode(b)
+ end
+end
+
+local splitbox = tex.splitbox
+nodes.splitbox = splitbox
+
+function nuts.splitbox(id,height)
+ return tonut(splitbox(id,height))
+end
+
+-- function nodes.takelist(n)
+-- -- when we need it
+-- end
+
+function nuts.takelist(n)
+ local l = getlist(n)
+ setlist(n)
+ flush_node(n)
+ return l
+end
+
+nuts.takebox = takebox
+tex.takebox = nodes.takebox -- sometimes more clear
+
+-- so far
+
+local function repackhlist(list,...)
+ local temp, b = hpack_nodes(list,...)
+ list = getlist(temp)
+ setlist(temp)
+ flush_node(temp)
+ return list, b
+end
+
+nuts.repackhlist = repackhlist
+
+function nodes.repackhlist(list,...)
+ local list, b = repackhlist(tonut(list),...)
+ return tonode(list), b
+end
+
+local function set_attributes(head,attr,value)
+ for n, id in nextnode, head do
+ setattr(n,attr,value)
+ if id == hlist_node or id == vlist_node then
+ set_attributes(getlist(n),attr,value)
+ end
+ end
+end
+
+local function set_unset_attributes(head,attr,value)
+ for n, id in nextnode, head do
+ if not getattr(n,attr) then
+ setattr(n,attr,value)
+ end
+ if id == hlist_code or id == vlist_code then
+ set_unset_attributes(getlist(n),attr,value)
+ end
+ end
+end
+
+local function unset_attributes(head,attr)
+ for n, id in nextnode, head do
+ setattr(n,attr,unsetvalue)
+ if id == hlist_code or id == vlist_code then
+ unset_attributes(getlist(n),attr)
+ end
+ end
+end
+
+-- for old times sake
+
+nuts.setattribute = nuts.setattr nodes.setattribute = nodes.setattr
+nuts.getattribute = nuts.getattr nodes.getattribute = nodes.getattr
+nuts.unsetattribute = nuts.unset_attribute nodes.unsetattribute = nodes.unset_attribute
+nuts.has_attribute = nuts.has_attribute nodes.has_attribute = nodes.has_attribute
+nuts.firstglyph = nuts.first_glyph nodes.firstglyph = nodes.first_glyph
+
+nuts.setattributes = set_attributes nodes.setattributes = vianuts(set_attributes)
+nuts.setunsetattributes = set_unset_attributes nodes.setunsetattributes = vianuts(set_unset_attributes)
+nuts.unsetattributes = unset_attributes nodes.unsetattributes = vianuts(unset_attributes)
+
+function nuts.firstcharacter(n,untagged) -- tagged == subtype > 255
+ if untagged then
+ return first_glyph(n)
+ else
+ for g in nextglyph ,n do
+ return g
+ end
+ end
+end
+
+local function firstcharinbox(n)
+ local l = getlist(getbox(n))
+ if l then
+ for g, c in nextglyph, l do
+ return c
+ end
+ end
+ return 0
+end
+
+nuts .firstcharinbox = firstcharinbox
+nodes.firstcharinbox = firstcharinbox -- hm, ok ?
+nodes.firstcharacter = vianuts(firstcharacter)
+
+interfaces.implement {
+ name = "buildtextaccent",
+ arguments = "integer",
+ actions = function(n) -- Is this crap really used? Or was it an experiment?
+ local char = firstcharinbox(n)
+ if char > 0 then
+ -- context.accent(false,char)
+ context([[\accent%s\relax]],char)
+ end
+ end
+}
+
+-- this depends on fonts, so we have a funny dependency ... will be
+-- sorted out .. we could make tonodes a plugin into this
+
+local function tonodes(str,fnt,attr) -- (str,template_glyph) -- moved from blob-ini
+ if not str or str == "" then
+ return
+ end
+ local head, tail, space, fnt, template = nil, nil, nil, nil, nil
+ if not fnt then
+ fnt = current_font()
+ elseif type(fnt) ~= "number" and getid(fnt) == glyph_code then -- so it has to be a real node
+ fnt, template = nil, tonut(fnt)
+ end
+ for s in utfvalues(str) do
+ local n
+ if s == 32 then
+ if space then
+ n = copy_node(space)
+ elseif fonts then -- depedency
+ local parameters = fonts.hashes.identifiers[fnt].parameters
+ space = new_glue(parameters.space,parameters.space_stretch,parameters.space_shrink)
+ n = space
+ end
+ elseif template then
+ n = copy_node(template)
+ setvalue(n,"char",s)
+ else
+ n = new_glyph(fnt,s)
+ end
+ if attr then -- normally false when template
+ setattrlist(n,attr)
+ end
+ if head then
+ setlink(tail,n)
+ else
+ head = n
+ end
+ tail = n
+ end
+ return head, tail
+end
+
+nuts.tonodes = tonodes
+
+nodes.tonodes = function(str,fnt,attr)
+ local head, tail = tonodes(str,fnt,attr)
+ return tonode(head), tonode(tail)
+end
+
+local function link(list,currentfont,currentattr,head,tail) -- an oldie, might be replaced
+ for i=1,#list do
+ local n = list[i]
+ if n then
+ local tn = type(n)
+ if tn == "string" then
+ if #tn > 0 then
+ if not currentfont then
+ currentfont = current_font()
+ end
+ local h, t = tonodes(n,currentfont,currentattr)
+ if not h then
+ -- skip
+ elseif not head then
+ head, tail = h, t
+ else
+ setnext(tail,h)
+ setprev(h,t)
+ tail = t
+ end
+ end
+ elseif tn == "table" then
+ if #tn > 0 then
+ if not currentfont then
+ currentfont = current_font()
+ end
+ head, tail = link(n,currentfont,currentattr,head,tail)
+ end
+ elseif not head then
+ head = n
+ tail = find_tail(n)
+ elseif getid(n) == attributelist_code then
+ -- weird case
+ report_error("weird node type in list at index %s:",i)
+ for i=1,#list do
+ local l = list[i]
+ report_error("%3i: %s %S",i,getid(l) == attributelist_code and "!" or ">",l)
+ end
+ os.exit()
+ else
+ setlink(tail,n)
+ if getnext(n) then
+ tail = find_tail(n)
+ else
+ tail = n
+ end
+ end
+ else
+ -- permitting nil is convenient
+ end
+ end
+ return head, tail
+end
+
+nuts.link = link
+
+nodes.link = function(list,currentfont,currentattr,head,tail)
+ local head, tail = link(list,currentfont,currentattr,tonut(head),tonut(tail))
+ return tonode(head), tonode(tail)
+end
+
+local function locate(start,wantedid,wantedsubtype)
+ for n, id, subtype in nextnode, start do
+ if id == wantedid then
+ if not wantedsubtype or subtype == wantedsubtype then
+ return n
+ end
+ elseif id == hlist_code or id == vlist_code then
+ local found = locate(getlist(n),wantedid,wantedsubtype)
+ if found then
+ return found
+ end
+ end
+ end
+end
+
+nuts.locate = locate
+
+function nodes.locate(start,wantedid,wantedsubtype)
+ local found = locate(tonut(start),wantedid,wantedsubtype)
+ return found and tonode(found)
+end
+
+local function rehpack(n,width)
+ local head = getlist(n)
+ local size = width or getwidth(n)
+ local temp = hpack_nodes(head,size,"exactly")
+ setwidth(n,size)
+ local set, order, sign = getboxglue(temp)
+ setboxglue(n,set,order,sign)
+ setlist(temp)
+ flush_node(temp)
+ return n
+end
+
+nuts.rehpack = rehpack
+
+function nodes.rehpack(n,...)
+ rehpack(tonut(n),...)
+end
+
+do
+
+ local localparcodes = nodes.localparcodes
+ local hmodepar_code = localparcodes.vmode_par
+ local vmodepar_code = localparcodes.hmode_par
+
+ local getnest = tex.getnest
+ local getsubtype = nuts.getsubtype
+
+ function nuts.setparproperty(action,...)
+ local tail = tonut(getnest().tail)
+ while tail do
+ if getid(tail) == localpar_code then
+ local s = getsubtype(tail)
+ if s == hmodepar_code or s == vmodepar_code then
+ return action(tail,...)
+ else
+ -- something is wrong here
+ end
+ end
+ tail = getprev(tail)
+ end
+ end
+
+ local getsubtype = nodes.getsubtype
+
+ function nodes.start_of_par(n)
+ local s = getsubtype(n)
+ return s == hmodepar_code or s == vmodepar_code
+ end
+
+end
diff --git a/tex/context/base/mkiv/node-aux.lua b/tex/context/base/mkiv/node-aux.lua
index 407ebb09c..aa7dc0292 100644
--- a/tex/context/base/mkiv/node-aux.lua
+++ b/tex/context/base/mkiv/node-aux.lua
@@ -413,10 +413,7 @@ do
end
--- Currently only in luametatex ... experimental anyway .. if it doesn't end
--- up in luatex I'll move this to a different module.
-
-do
+if not nuts.getnormalizedline then
local nextnode = traversers.glue
local findfail = nuts.tail
@@ -459,9 +456,7 @@ do
nuts.find_node = find_node
- -- if CONTEXTLMTXMODE then ... end
-
- nuts.getnormalizedline = direct.getnormalizedline or function(h)
+ function nuts.getnormalizedline(h)
if getid(h) == hlist_code and getsubtype(h) == line_code then
local ls, rs = 0, 0
local lh, rh = 0, 0
diff --git a/tex/context/base/mkiv/node-ini.lmt b/tex/context/base/mkiv/node-ini.lmt
new file mode 100644
index 000000000..2f0b98e88
--- /dev/null
+++ b/tex/context/base/mkiv/node-ini.lmt
@@ -0,0 +1,287 @@
+if not modules then modules = { } end modules ['node-ini'] = {
+ version = 1.001,
+ comment = "companion to node-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Most of the code that had accumulated here is now separated in modules.</p>
+--ldx]]--
+
+local next, type, tostring = next, type, tostring
+local gsub = string.gsub
+local concat, remove = table.concat, table.remove
+local sortedhash, sortedkeys, swapped = table.sortedhash, table.sortedkeys, table.swapped
+
+--[[ldx--
+<p>Access to nodes is what gives <l n='luatex'/> its power. Here we implement a
+few helper functions. These functions are rather optimized.</p>
+--ldx]]--
+
+nodes = nodes or { }
+local nodes = nodes
+nodes.handlers = nodes.handlers or { }
+
+local mark = utilities.storage.mark
+local allocate = utilities.storage.allocate
+local formatcolumns = utilities.formatters.formatcolumns
+
+local getsubtypes = node.subtypes
+local getvalues = node.values
+
+tex.magicconstants = { -- we use tex.constants for something else
+ running = -1073741824, -- null_flag
+ maxdimen = 1073741823, -- max_dimen
+ trueinch = 4736286,
+}
+
+local listcodes = mark(getsubtypes("list"))
+local rulecodes = mark(getsubtypes("rule"))
+local dircodes = mark(getsubtypes("dir"))
+local glyphcodes = mark(getsubtypes("glyph"))
+local disccodes = mark(getsubtypes("disc"))
+local gluecodes = mark(getsubtypes("glue"))
+local leadercodes = mark(getsubtypes("leader"))
+local fillcodes = mark(getsubtypes("fill"))
+local boundarycodes = mark(getsubtypes("boundary"))
+local penaltycodes = mark(getsubtypes("penalty"))
+local kerncodes = mark(getsubtypes("kern"))
+local mathcodes = mark(getsubtypes("math"))
+local noadcodes = mark(getsubtypes("noad"))
+local radicalcodes = mark(getsubtypes("radical"))
+local accentcodes = mark(getsubtypes("accent"))
+local fencecodes = mark(getsubtypes("fence"))
+----- fractioncodes = mark(getsubtypes("fraction"))
+local localparcodes = CONTEXTLMTXMODE > 0 and mark(getsubtypes("localpar"))
+
+if not localparcodes then
+ localparcodes = allocate { [0] = "new_graf", "local_box", "hmode_par", "penalty", "math" }
+end
+
+local function simplified(t)
+ local r = { }
+ for k, v in next, t do
+ r[k] = gsub(v,"_","")
+ end
+ return r
+end
+
+local nodecodes = simplified(node.types())
+local whatcodes = simplified(node.whatsits and node.whatsits() or { })
+
+local dirvalues = mark(getvalues("dir"))
+local gluevalues = mark(getvalues("glue"))
+
+local whatcodes = {
+ literal = 0x1, [0x1] = "literal",
+ latelua = 0x2, [0x2] = "latelua",
+ userdefined = 0x3, [0x3] = "userdefined",
+ savepos = 0x4, [0x4] = "savepos",
+ save = 0x5, [0x5] = "save",
+ restore = 0x6, [0x6] = "restore",
+ setmatrix = 0x7, [0x7] = "setmatrix",
+ open = 0x8, [0x8] = "open",
+ close = 0x9, [0x9] = "close",
+ write = 0xA, [0xA] = "write",
+}
+
+local usercodes = allocate {
+ [ 97] = "attribute", -- a
+ [100] = "number", -- d
+ [102] = "float", -- f
+ [108] = "lua", -- l
+ [110] = "node", -- n
+ [115] = "string", -- s
+ [116] = "token" -- t
+}
+
+local noadoptions = allocate {
+ set = 0x08,
+ unused_1 = 0x00 + 0x08,
+ unused_2 = 0x01 + 0x08,
+ axis = 0x02 + 0x08,
+ no_axis = 0x04 + 0x08,
+ exact = 0x10 + 0x08,
+ left = 0x11 + 0x08,
+ middle = 0x12 + 0x08,
+ right = 0x14 + 0x08,
+}
+
+local literalvalues = allocate {
+ [0] = "origin",
+ [1] = "page",
+ [2] = "always",
+ [3] = "raw",
+ [4] = "text",
+ [5] = "font",
+ [6] = "special",
+}
+
+gluecodes = allocate(swapped(gluecodes,gluecodes))
+dircodes = allocate(swapped(dircodes,dircodes))
+boundarycodes = allocate(swapped(boundarycodes,boundarycodes))
+noadcodes = allocate(swapped(noadcodes,noadcodes))
+radicalcodes = allocate(swapped(radicalcodes,radicalcodes))
+nodecodes = allocate(swapped(nodecodes,nodecodes))
+whatcodes = allocate(swapped(whatcodes,whatcodes))
+listcodes = allocate(swapped(listcodes,listcodes))
+glyphcodes = allocate(swapped(glyphcodes,glyphcodes))
+kerncodes = allocate(swapped(kerncodes,kerncodes))
+penaltycodes = allocate(swapped(penaltycodes,penaltycodes))
+mathcodes = allocate(swapped(mathcodes,mathcodes))
+fillcodes = allocate(swapped(fillcodes,fillcodes))
+disccodes = allocate(swapped(disccodes,disccodes))
+accentcodes = allocate(swapped(accentcodes,accentcodes))
+fencecodes = allocate(swapped(fencecodes,fencecodes))
+localparcodes = allocate(swapped(localparcodes,localparcodes))
+rulecodes = allocate(swapped(rulecodes,rulecodes))
+leadercodes = allocate(swapped(leadercodes,leadercodes))
+usercodes = allocate(swapped(usercodes,usercodes))
+noadoptions = allocate(swapped(noadoptions,noadoptions))
+dirvalues = allocate(swapped(dirvalues,dirvalues))
+gluevalues = allocate(swapped(gluevalues,gluevalues))
+literalvalues = allocate(swapped(literalvalues,literalvalues))
+
+nodes.gluecodes = gluecodes
+nodes.dircodes = dircodes
+nodes.boundarycodes = boundarycodes
+nodes.noadcodes = noadcodes
+nodes.nodecodes = nodecodes
+nodes.whatcodes = whatcodes
+nodes.listcodes = listcodes
+nodes.glyphcodes = glyphcodes
+nodes.kerncodes = kerncodes
+nodes.penaltycodes = penaltycodes
+nodes.mathcodes = mathcodes
+nodes.fillcodes = fillcodes
+nodes.disccodes = disccodes
+nodes.accentcodes = accentcodes
+nodes.radicalcodes = radicalcodes
+nodes.fencecodes = fencecodes
+nodes.localparcodes = localparcodes
+nodes.rulecodes = rulecodes
+nodes.leadercodes = leadercodes
+nodes.usercodes = usercodes
+nodes.noadoptions = noadoptions
+nodes.dirvalues = dirvalues
+nodes.gluevalues = gluevalues
+nodes.literalvalues = literalvalues
+
+nodes.subtypes = allocate {
+ [nodecodes.accent] = accentcodes,
+ [nodecodes.boundary] = boundarycodes,
+ [nodecodes.dir] = dircodes,
+ [nodecodes.disc] = disccodes,
+ [nodecodes.fence] = fencecodes,
+ [nodecodes.glue] = gluecodes,
+ [nodecodes.glyph] = glyphcodes,
+ [nodecodes.hlist] = listcodes,
+ [nodecodes.kern] = kerncodes,
+ [nodecodes.localpar] = localparcodes,
+ [nodecodes.math] = mathcodes,
+ [nodecodes.noad] = noadcodes,
+ [nodecodes.penalty] = penaltycodes,
+ [nodecodes.radical] = radicalcodes,
+ [nodecodes.rule] = rulecodes,
+ -- [nodecodes.user] = usercodes,
+ [nodecodes.vlist] = listcodes,
+ [nodecodes.whatsit] = whatcodes,
+}
+
+table.setmetatableindex(nodes.subtypes,function(t,k)
+ local v = { }
+ t[k] = v
+ return v
+end)
+
+-- a few more friendly aliases:
+
+nodes.skipcodes = gluecodes
+nodes.directioncodes = dircodes
+nodes.whatsitcodes = whatcodes
+nodes.discretionarycodes = disccodes
+nodes.directionvalues = dirvalues
+nodes.skipvalues = gluevalues
+nodes.literalvalues = literalvalues
+
+glyphcodes.glyph = glyphcodes.character
+
+localparcodes.vmode_par = localparcodes.new_graf
+
+listcodes.row = listcodes.alignment
+listcodes.column = listcodes.alignment
+
+kerncodes.kerning = kerncodes.fontkern
+kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new
+
+literalvalues.direct = literalvalues.always
+
+nodes.codes = allocate { -- mostly for listing
+ glue = skipcodes,
+ boundary = boundarycodes,
+ noad = noadcodes,
+ node = nodecodes,
+ hlist = listcodes,
+ vlist = listcodes,
+ glyph = glyphcodes,
+ kern = kerncodes,
+ penalty = penaltycodes,
+ math = mathnodes,
+ fill = fillcodes,
+ disc = disccodes,
+ whatsit = whatcodes,
+ accent = accentcodes,
+ fence = fencecodes,
+ rule = rulecodes,
+ leader = leadercodes,
+ user = usercodes,
+ noadoptions = noadoptions,
+}
+
+nodes.noadoptions = {
+ set = 0x08,
+ unused_1 = 0x00 + 0x08,
+ unused_2 = 0x01 + 0x08,
+ axis = 0x02 + 0x08,
+ no_axis = 0x04 + 0x08,
+ exact = 0x10 + 0x08,
+ left = 0x11 + 0x08,
+ middle = 0x12 + 0x08,
+ right = 0x14 + 0x08,
+}
+
+local report_codes = logs.reporter("nodes","codes")
+
+function nodes.showcodes()
+ local t = { }
+ for name, codes in sortedhash(nodes.codes) do
+ local sorted = sortedkeys(codes)
+ for i=1,#sorted do
+ local s = sorted[i]
+ if type(s) ~= "number" then
+ t[#t+1] = { name, s, codes[s] }
+ end
+ end
+ end
+ formatcolumns(t)
+ for k=1,#t do
+ report_codes (t[k])
+ end
+end
+
+trackers.register("system.showcodes", nodes.showcodes)
+
+-- We use the real node code numbers.
+
+local texchardef = tex.chardef
+
+for i=0,nodecodes.glyph do
+ texchardef(nodecodes[i] .. "nodecode",i)
+end
+for i=0,#gluecodes do
+ texchardef(gluecodes[i] .. "subtypecode",i)
+end
+
+-- tex.set("internalcodesmode",1) -- obsolete
diff --git a/tex/context/base/mkiv/node-ini.mkiv b/tex/context/base/mkiv/node-ini.mkiv
index 2ecef4a54..8a3aa65df 100644
--- a/tex/context/base/mkiv/node-ini.mkiv
+++ b/tex/context/base/mkiv/node-ini.mkiv
@@ -21,12 +21,12 @@
\registerctxluafile{node-cmp}{autosuffix}
\fi
-\registerctxluafile{node-ini}{}
+\registerctxluafile{node-ini}{autosuffix}
\registerctxluafile{node-met}{}
-\registerctxluafile{node-nut}{}
+\registerctxluafile{node-nut}{autosuffix}
\registerctxluafile{node-res}{}
%registerctxluafile{node-ppt}{} % experimental, not used so probably useless
-\registerctxluafile{node-aux}{}
+\registerctxluafile{node-aux}{autosuffix}
\registerctxluafile{node-gcm}{autosuffix}
\registerctxluafile{node-tst}{}
\registerctxluafile{node-tra}{} % we might split it off (module)
diff --git a/tex/context/base/mkiv/node-met.lua b/tex/context/base/mkiv/node-met.lua
index f472d31a9..feaff70eb 100644
--- a/tex/context/base/mkiv/node-met.lua
+++ b/tex/context/base/mkiv/node-met.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['node-nut'] = {
+if not modules then modules = { } end modules ['node-MET'] = {
version = 1.001,
comment = "companion to node-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
diff --git a/tex/context/base/mkiv/node-nut.lmt b/tex/context/base/mkiv/node-nut.lmt
new file mode 100644
index 000000000..004729a3c
--- /dev/null
+++ b/tex/context/base/mkiv/node-nut.lmt
@@ -0,0 +1,572 @@
+if not modules then modules = { } end modules ['node-nut'] = {
+ version = 1.001,
+ comment = "companion to node-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Some comments anbout going nuts can be found in the mkiv file with the
+-- suffix "lua", including some timing and musings. We copy the direct table
+-- (1) because that's what we did while things evolved and (2) because we
+-- also add some more helpers.
+
+local type, rawget = type, rawget
+
+local nodes = nodes
+local direct = node.direct
+
+local fastcopy = table.fastcopy
+
+local nodecodes = nodes.nodecodes
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local glyph_code = nodecodes.glyph
+
+local tonode = direct.tonode
+local tonut = direct.todirect
+
+local is_node = direct.is_node
+local is_nut = direct.is_direct
+
+local d_remove_node = direct.remove
+local d_flush_node = direct.flush_node
+local d_getnext = direct.getnext
+local d_getprev = direct.getprev
+local d_getid = direct.getid
+local d_getlist = direct.getlist
+local d_find_tail = direct.tail
+local d_insert_after = direct.insert_after
+local d_insert_before = direct.insert_before
+local d_slide = direct.slide
+local d_traverse = direct.traverse
+local d_setlink = direct.setlink
+local d_getboth = direct.getboth
+
+local nuts = {
+ check_discretionaries = direct.check_discretionaries,
+ copy = direct.copy,
+ copy_list = direct.copy_list,
+ copy_node = direct.copy,
+ copy_only = direct.copy_only or direct.copy,
+ count = direct.count,
+ current_attr = direct.current_attr,
+ delete = direct.delete,
+ dimensions = direct.dimensions,
+ effective_glue = direct.effective_glue,
+ end_of_math = direct.end_of_math,
+ exchange = direct.exchange,
+ find_attribute = direct.find_attribute,
+ first_glyph = direct.first_glyph,
+ flatten_discretionaries = direct.flatten_discretionaries,
+ flush = d_flush_node,
+ flush_components = direct.flush_components,
+ flush_list = direct.flush_list,
+ flush_node = direct.flush_node,
+ free = direct.free,
+ get_synctex_fields = direct.get_synctex_fields,
+ getattr = direct.get_attribute,
+ getattributelist = direct.getattributelist,
+ getattrlist = direct.getattributelist,
+ getboth = d_getboth,
+ getbox = direct.getbox,
+ getboxglue = direct.getglue,
+ getchar = direct.getchar,
+ getcomponents = direct.getcomponents,
+ getdata = direct.getdata,
+ getdepth = direct.getdepth,
+ getdir = direct.getdir,
+ getdirection = direct.getdirection,
+ getdisc = direct.getdisc,
+ getdiscretionary = direct.getdisc,
+ getexpansion = direct.getexpansion,
+ getfam = direct.getfam,
+ getfield = direct.getfield,
+ getfont = direct.getfont,
+ getglue = direct.getglue,
+ getglyphdata = direct.getglyphdata,
+ getheight = direct.getheight,
+ getid = d_getid,
+ getkern = direct.getkern,
+ getlang = direct.getlang,
+ getlanguage = direct.getlang,
+ getleader = direct.getleader,
+ getlist = d_getlist,
+ getnext = d_getnext,
+ getnormalizedline = direct.getnormalizedline,
+ getnucleus = direct.getnucleus,
+ getoffsets = direct.getoffsets,
+ getorientation = direct.getorientation,
+ getpenalty = direct.getpenalty,
+ getpost = direct.getpost,
+ getpre = direct.getpre,
+ getprev = d_getprev,
+ getreplace = direct.getreplace,
+ getruledata = direct.getglyphdata,
+ getscript = direct.setscript,
+ getshift = direct.getshift,
+ getstate = direct.getstate,
+ getsub = direct.getsub,
+ getsubpre = direct.getsubpre,
+ getsubtype = direct.getsubtype,
+ getsup = direct.getsup,
+ getsuppre = direct.getsuppre,
+ getsurround = direct.getkern,
+ gettotal = direct.gettotal,
+ getvalue = direct.getdata, -- obsolete
+ getwhd = direct.getwhd,
+ getwidth = direct.getwidth,
+ has_attribute = direct.has_attribute,
+ has_dimensions = direct.has_dimensions,
+ has_field = direct.has_field,
+ has_glyph = direct.has_glyph or direct.first_glyph,
+ hpack = direct.hpack,
+ hyphenating = direct.hyphenating,
+ insert_after = d_insert_after,
+ insert_before = d_insert_before,
+ is_direct = is_direct,
+ is_node = is_node,
+ is_nut = direct.is_direct,
+ is_zero_glue = direct.is_zero_glue,
+ ischar = direct.is_char,
+ isglyph = direct.is_glyph,
+ kerning = direct.kerning,
+ last_node = direct.last_node,
+ length = direct.length,
+ ligaturing = direct.ligaturing,
+ migrate = direct.migrate,
+ mlist_to_hlist = direct.mlist_to_hlist,
+ new = direct.new,
+ protect_glyph = direct.protect_glyph,
+ protect_glyphs = direct.protect_glyphs,
+ protrusion_skippable = direct.protrusion_skippable,
+ rangedimensions = direct.rangedimensions,
+ remove = d_remove_node,
+ reverse = direct.reverse,
+ set_attribute = direct.set_attribute,
+ set_synctex_fields = direct.set_synctex_fields,
+ setattr = direct.set_attribute,
+ setattributelist = direct.setattributelist,
+ setattrlist = direct.setattributelist,
+ setboth = direct.setboth,
+ setbox = direct.setbox,
+ setboxglue = direct.setglue,
+ setchar = direct.setchar,
+ setcomponents = direct.setcomponents,
+ setdata = direct.setdata,
+ setdepth = direct.setdepth,
+ setdir = direct.setdir,
+ setdirection = direct.setdirection,
+ setdisc = direct.setdisc,
+ setdiscretionary = direct.setdisc,
+ setexpansion = direct.setexpansion,
+ setfam = direct.setfam,
+ setfield = direct.setfield,
+ setfont = direct.setfont,
+ setglue = direct.setglue,
+ setglyphdata = direct.setglyphdata,
+ setheight = direct.setheight,
+ setkern = direct.setkern,
+ setlang = direct.setlang,
+ setlanguage = direct.setlang,
+ setleader = direct.setleader,
+ setlink = d_setlink,
+ setlist = direct.setlist,
+ setnext = direct.setnext,
+ setnucleus = direct.setnucleus,
+ setoffsets = direct.setoffsets,
+ setorientation = direct.setorientation,
+ setpenalty = direct.setpenalty,
+ setpost = direct.setpost,
+ setpre = direct.setpre,
+ setprev = direct.setprev,
+ setreplace = direct.setreplace,
+ setruledata = direct.setglyphdata,
+ setscript = direct.getscript,
+ setshift = direct.setshift,
+ setsplit = direct.setsplit,
+ setstate = direct.setstate,
+ setsub = direct.setsub,
+ setsubpre = direct.setsubpre,
+ setsubtype = direct.setsubtype,
+ setsup = direct.setsup,
+ setsuppre = direct.setsuppre,
+ setsurround = direct.setkern,
+ setvalue = direct.setdata, -- obsolete
+ setwhd = direct.setwhd,
+ setwidth = direct.setwidth,
+ slide = d_slide,
+ start_of_par = direct.start_of_par,
+ tail = d_find_tail,
+ takeattr = direct.unset_attribute, -- ?
+ tonode = tonode,
+ tonut = tonut,
+ tostring = direct.tostring,
+ traverse = d_traverse,
+ traverse_char = direct.traverse_char,
+ traverse_glyph = direct.traverse_glyph,
+ traverse_id = direct.traverse_id,
+ traverse_list = direct.traverse_list,
+ unprotect_glyph = direct.unprotect_glyph,
+ unprotect_glyphs = direct.unprotect_glyphs,
+ unset_attribute = direct.unset_attribute,
+ usedlist = direct.usedlist,
+ uses_font = direct.uses_font,
+ vpack = direct.vpack,
+ writable_spec = direct.writable_spec,
+ write = direct.write,
+}
+
+
+nodes.nuts = nuts
+
+nodes.is_node = is_node
+nodes.is_direct = is_nut
+nodes.is_nut = is_nut
+
+nodes.tonode = tonode
+nodes.tonut = tonut
+
+function nuts.delete(head,current)
+ return d_remove_node(head,current,true)
+end
+
+function nuts.replace(head,current,new) -- no head returned if false
+ if not new then
+ head, current, new = false, head, current
+ end
+ local prev, next = d_getboth(current)
+ if prev or next then
+ d_setlink(prev,new,next)
+ end
+ if head then
+ if head == current then
+ head = new
+ end
+ d_flush_node(current)
+ return head, new
+ else
+ d_flush_node(current)
+ return new
+ end
+end
+
+local function countall(stack,flat)
+ local n = 0
+ while stack do
+ local id = d_getid(stack)
+ if not flat and id == hlist_code or id == vlist_code then
+ local list = d_getlist(stack)
+ if list then
+ n = n + 1 + countall(list) -- self counts too
+ else
+ n = n + 1
+ end
+ else
+ n = n + 1
+ end
+ stack = d_getnext(stack)
+ end
+ return n
+end
+
+nuts.countall = countall
+
+function nodes.countall(stack,flat)
+ return countall(tonut(stack),flat)
+end
+
+function nuts.append(head,current,...)
+ for i=1,select("#",...) do
+ head, current = d_insert_after(head,current,(select(i,...)))
+ end
+ return head, current
+end
+
+function nuts.prepend(head,current,...)
+ for i=1,select("#",...) do
+ head, current = d_insert_before(head,current,(select(i,...)))
+ end
+ return head, current
+end
+
+function nuts.linked(...) -- slides !
+ local head, last
+ for i=1,select("#",...) do
+ local next = select(i,...)
+ if next then
+ if head then
+ d_setlink(last,next)
+ else
+ head = next
+ end
+ last = d_find_tail(next) -- we could skip the last one
+ end
+ end
+ return head
+end
+
+function nuts.concat(list) -- consider tail instead of slide
+ local head, tail
+ for i=1,#list do
+ local li = list[i]
+ if li then
+ if head then
+ d_setlink(tail,li)
+ else
+ head = li
+ end
+ tail = d_slide(li)
+ end
+ end
+ return head, tail
+end
+
+function nuts.reference(n)
+ return n or "<none>"
+end
+
+function nuts.vianuts (f) return function(n,...) return tonode(f(tonut (n),...)) end end
+function nuts.vianodes(f) return function(n,...) return tonut (f(tonode(n),...)) end end
+
+nodes.vianuts = nuts.vianuts
+nodes.vianodes = nuts.vianodes
+
+function nodes.insert_list_after(h,c,n)
+ local t = n_tail(n)
+ if c then
+ local cn = n_getnext(c)
+ if cn then
+ -- no setboth here yet
+ n_setfield(t,"next",cn)
+ n_setfield(cn,"prev",t)
+ else
+ n_setfield(t,"next",nil)
+ end
+ n_setfield(c,"next",n)
+ n_setfield(n,"prev",c)
+ return h, n
+ end
+ return n, t
+end
+
+function nuts.insert_list_after(h,c,n)
+ local t = d_tail(n)
+ if c then
+ local cn = d_getnext(c)
+ if cn then
+ d_setlink(t,cn)
+ else
+ d_setnext(t)
+ end
+ d_setlink(c,n)
+ return h, n
+ end
+ return n, t
+end
+
+-- test code only
+
+-- collectranges and mix
+
+local report = logs.reporter("sliding")
+
+local function message(detail,head,current,previous)
+ report("error: %s, current: %s:%s, previous: %s:%s, list: %s, text: %s",
+ detail,
+ nodecodes[d_getid(current)],
+ current,
+ nodecodes[d_getid(previous)],
+ previous,
+ nodes.idstostring(head),
+ nodes.listtoutf(head)
+ )
+ utilities.debugger.showtraceback(report)
+end
+
+local function warn()
+ report()
+ report("warning: the slide tracer is enabled")
+ report()
+ warn = false
+end
+
+local function tracedslide(head)
+ if head then
+ if warn then
+ warn()
+ end
+ local next = d_getnext(head)
+ if next then
+ local prev = head
+ for n in d_traverse(next) do
+ local p = d_getprev(n)
+ if not p then
+ message("unset",head,n,prev)
+ -- break
+ elseif p ~= prev then
+ message("wrong",head,n,prev)
+ -- break
+ end
+ prev = n
+ end
+ end
+ return d_slide(head)
+ end
+end
+
+local function nestedtracedslide(head,level) -- no sliding !
+ if head then
+ if warn then
+ warn()
+ end
+ local id = d_getid(head)
+ local next = d_getnext(head)
+ if next then
+ report("%whead:%s",level or 0,nodecodes[id])
+ local prev = head
+ for n in d_traverse(next) do
+ local p = d_getprev(n)
+ if not p then
+ message("unset",head,n,prev)
+ -- break
+ elseif p ~= prev then
+ message("wrong",head,n,prev)
+ -- break
+ end
+ prev = n
+ local id = d_getid(n)
+ if id == hlist_code or id == vlist_code then
+ nestedtracedslide(d_getlist(n),(level or 0) + 1)
+ end
+ end
+ elseif id == hlist_code or id == vlist_code then
+ report("%wlist:%s",level or 0,nodecodes[id])
+ nestedtracedslide(d_getlist(head),(level or 0) + 1)
+ end
+ -- return d_slide(head)
+ end
+end
+
+local function untracedslide(head)
+ if head then
+ if warn then
+ warn()
+ end
+ local next = d_getnext(head)
+ if next then
+ local prev = head
+ for n in d_traverse(next) do
+ local p = d_getprev(n)
+ if not p then
+ return "unset", d_getid(n)
+ elseif p ~= prev then
+ return "wrong", d_getid(n)
+ end
+ prev = n
+ end
+ end
+ return d_slide(head)
+ end
+end
+
+nuts.tracedslide = tracedslide
+nuts.untracedslide = untracedslide
+nuts.nestedtracedslide = nestedtracedslide
+
+-- this might move
+
+local propertydata = direct.get_properties_table(true)
+
+local getattr = nuts.getattr
+local setattr = nuts.setattr
+
+nodes.properties = {
+ data = propertydata,
+}
+
+-- experimental code with respect to copying attributes has been removed
+-- as it doesn't pay of (most attributes are only accessed once anyway)
+
+function nuts.getprop(n,k)
+ local p = propertydata[n]
+ if p then
+ if k then
+ return p[k]
+ else
+ return p
+ end
+ end
+end
+
+function nuts.rawprop(n,k)
+ local p = rawget(propertydata,n)
+ if p then
+ if k then
+ return p[k]
+ else
+ return p
+ end
+ end
+end
+
+function nuts.setprop(n,k,v)
+ local p = propertydata[n]
+ if p then
+ p[k] = v
+ else
+ propertydata[n] = { [k] = v }
+ end
+end
+
+function nuts.theprop(n)
+ local p = propertydata[n]
+ if not p then
+ p = { }
+ propertydata[n] = p
+ end
+ return p
+end
+
+
+function nuts.isdone(n,k)
+ local p = propertydata[n]
+ if not p then
+ propertydata[n] = { [k] = true }
+ return false
+ end
+ local v = p[k]
+ if v == nil then
+ propertydata[n] = { [k] = true }
+ return false
+ end
+ return v
+end
+
+function nuts.copy_properties(source,target,what)
+ local newprops = propertydata[source]
+ if not newprops then
+ -- nothing to copy
+ return
+ end
+ if what then
+ -- copy one category
+ newprops = rawget(source,what)
+ if newprops then
+ newprops = fastcopy(newprops)
+ local p = rawget(propertydata,target)
+ if p then
+ p[what] = newprops
+ else
+ propertydata[target] = {
+ [what] = newprops,
+ }
+ end
+ end
+ else
+ -- copy all properties
+ newprops = fastcopy(newprops)
+ propertydata[target] = newprops
+ end
+ return newprops -- for checking
+end
diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua
index 80335e933..68d238b1a 100644
--- a/tex/context/base/mkiv/node-nut.lua
+++ b/tex/context/base/mkiv/node-nut.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['node-met'] = {
+if not modules then modules = { } end modules ['node-nut'] = {
version = 1.001,
comment = "companion to node-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -396,7 +396,7 @@ local d_setlink = direct.setlink
local d_setboth = direct.setboth
local d_getboth = direct.getboth
-local remove = CONTEXTLMTXMODE > 0 and d_remove_node or function(head,current,free_too)
+local remove = function(head,current,free_too)
if current then
local h, c = d_remove_node(head,current)
if free_too then
@@ -812,8 +812,6 @@ nuts.tracedslide = tracedslide
nuts.untracedslide = untracedslide
nuts.nestedtracedslide = nestedtracedslide
--- nuts.slide = tracedslide
-
-- this might move
local propertydata = direct.get_properties_table(true)
@@ -877,17 +875,7 @@ local getstate = direct.getstate
local setstate = direct.setstate
if not setstate or not getstate then
- -- setstate = function(n,v)
- -- setprop(n,"state",v)
- -- end
- -- getstate = function(n,v)
- -- local s = getprop(n,"state")
- -- if v then
- -- return s == v
- -- else
- -- return s
- -- end
- -- end
+
setstate = function(n,v)
local p = propertydata[n]
if p then
@@ -896,6 +884,7 @@ if not setstate or not getstate then
propertydata[n] = { state = v }
end
end
+
getstate = function(n,v)
local p = propertydata[n]
if p then
@@ -919,7 +908,7 @@ local setscript = direct.setscript or function(n,v) end -- elsewhere
nuts.setscript = getscript
nuts.getscript = setscript
-nuts.isdone = function(n,k)
+function nuts.isdone(n,k)
local p = propertydata[n]
if not p then
propertydata[n] = { [k] = true }
@@ -933,9 +922,6 @@ nuts.isdone = function(n,k)
return v
end
--- nodes.setprop = nodes.setproperty
--- nodes.getprop = nodes.getproperty
-
function nuts.copy_properties(source,target,what)
local newprops = propertydata[source]
if not newprops then
diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua
index 9b76fed54..c27059003 100644
--- a/tex/context/base/mkiv/node-res.lua
+++ b/tex/context/base/mkiv/node-res.lua
@@ -584,12 +584,17 @@ local usage = CONTEXTLMTXMODE > 0 and node.inuse or function()
return t
end
+local stock = CONTEXTLMTXMODE > 0 and node.instock or { }
+
nutpool .cleanup = cleanup
nodepool.cleanup = cleanup
nutpool .usage = usage
nodepool.usage = usage
+nutpool .stock = stock
+nodepool.stock = stock
+
-- end
statistics.register("cleaned up reserved nodes", function()
diff --git a/tex/context/base/mkiv/node-snp.lmt b/tex/context/base/mkiv/node-snp.lmt
index d058a142a..8c0237a5c 100644
--- a/tex/context/base/mkiv/node-snp.lmt
+++ b/tex/context/base/mkiv/node-snp.lmt
@@ -16,6 +16,7 @@ nodes.snapshots = snapshots
local status = status
local nodeusage = nodes.pool and nodes.pool.usage
+local nodestock = nodes.pool and nodes.pool.stock
local clock = os.gettimeofday or os.clock -- should go in environment
local lasttime = clock()
local samples = { }
@@ -25,6 +26,7 @@ function snapshots.takesample(comment)
local c = clock()
samples[#samples+1] = {
nodes = nodeusage(),
+ stock = nodestock(),
texcallbacks = status.getcallbackstate(),
mpcallbacks = mplib.getcallbackstate(),
backendcallbacks = backends.getcallbackstate(),
@@ -51,6 +53,8 @@ function snapshots.takesample(comment)
read = status.getreadstate(),
font = status.getfontstate(),
language = status.getlanguagestate(),
+ mark = status.getmarkstate(),
+ sparse = status.getsparsestate(),
},
}
end
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 41c6c2f60..56e1600c9 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 5d19ce520..1b46f8863 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/trac-inf.lmt b/tex/context/base/mkiv/trac-inf.lmt
index 1729c87e5..80bb3b2f6 100644
--- a/tex/context/base/mkiv/trac-inf.lmt
+++ b/tex/context/base/mkiv/trac-inf.lmt
@@ -289,20 +289,20 @@ function statistics.showusage(when)
local list = {
"stringstate", "poolstate",
"hashstate", "lookupstate",
- "nodestate", "tokenstate",
+ "nodestate", "extrastate", "tokenstate",
"bufferstate", "inputstate", "filestate",
"neststate", "parameterstate", "savestate",
- "fontstate", "languagestate",
+ "fontstate", "languagestate", "markstate", "sparsestate",
}
local fields = { "max", "min", "set", "stp", false, "mem", "all", false, "ini", "ptr", "top" }
- local line = rep("-",172)
+ local line = rep("-",190)
do
local t = { }
for i=1,#list do
t[i] = gsub(list[i],"state","")
end
report("%w%s",2,line)
- report("%w%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s",5,unpack(t))
+ report("%w%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s",5,unpack(t))
report("%w%s",2,line)
end
for i=1,#fields do
@@ -311,9 +311,9 @@ function statistics.showusage(when)
local t = { }
for i=1,#list do
local n = s[list[i]][f]
- t[i] = n < 0 and formatters["%w"](12) or formatters["%12i"](n)
+ t[i] = n < 0 and formatters["%w"](11) or formatters["%11i"](n)
end
- report(" %3s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s%12s",f,unpack(t))
+ report(" %3s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s%11s",f,unpack(t))
else
report("")
end
@@ -363,8 +363,18 @@ local enabled = false
trackers.register("system.usage", function(v)
if v and not registered then
logs.private.enablepagetiming()
- luatex.registerpageactions(function() if enabled then statistics.showusage("page") end end)
- luatex.registerstopactions(function() if enabled then statistics.showusage("finish") end end)
+ if v ~= "summary" then
+ luatex.registerpageactions(function()
+ if enabled then
+ statistics.showusage("page")
+ end
+ end)
+ end
+ luatex.registerstopactions(function()
+ if enabled then
+ statistics.showusage("finish")
+ end
+ end)
registered = true
end
enabled = v
diff --git a/tex/context/base/mkiv/trac-tim.lmt b/tex/context/base/mkiv/trac-tim.lmt
index ce61c7440..fcba7f132 100644
--- a/tex/context/base/mkiv/trac-tim.lmt
+++ b/tex/context/base/mkiv/trac-tim.lmt
@@ -123,6 +123,7 @@ local function convert(name)
end
collect("nodes")
+ collect("stock")
collect("memories")
collect("variables")
collect("texvariables")
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index aaea6ff2f..ff1b629b8 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2020-08-25 19:56
+-- merge date : 2020-08-27 19:25
do -- begin closure to overcome local limits and interference
@@ -9131,12 +9131,14 @@ function constructors.scale(tfmdata,specification)
target.cidinfo=properties.cidinfo
target.format=properties.format
target.cache=constructors.cacheintex and "yes" or "renew"
+ local original=properties.original or tfmdata.original
local fontname=properties.fontname or tfmdata.fontname
local fullname=properties.fullname or tfmdata.fullname
local filename=properties.filename or tfmdata.filename
local psname=properties.psname or tfmdata.psname
local name=properties.name or tfmdata.name
local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
+ target.original=original
target.fontname=fontname
target.fullname=fullname
target.filename=filename
@@ -13275,15 +13277,15 @@ do
local p_dictionary=(
p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
)^1
- parsedictionaries=function(data,dictionaries,what)
+ parsedictionaries=function(data,dictionaries,version)
stack={}
strings=data.strings
if trace_charstrings then
- report("charstring format %a",what)
+ report("charstring format %a",version)
end
for i=1,#dictionaries do
top=0
- result=what=="cff" and {
+ result=version=="cff" and {
monospaced=false,
italicangle=0,
underlineposition=-100,
@@ -14658,8 +14660,8 @@ do
processshape(tab,index-1)
end
end
-local function readglobals(f,data)
- local routines=readlengths(f)
+local function readglobals(f,data,version)
+ local routines=readlengths(f,version=="cff2")
for i=1,#routines do
routines[i]=readbytetable(f,routines[i])
end
@@ -14713,14 +14715,14 @@ local function readprivates(f,data)
private.data=readstring(f,private.size)
end
end
-local function readlocals(f,data,dictionary)
+local function readlocals(f,data,dictionary,version)
local header=data.header
local private=dictionary.private
if private then
local subroutineoffset=private.data.subroutines
if subroutineoffset~=0 then
setposition(f,header.offset+private.offset+subroutineoffset)
- local subroutines=readlengths(f)
+ local subroutines=readlengths(f,version=="cff2")
for i=1,#subroutines do
subroutines[i]=readbytetable(f,subroutines[i])
end
@@ -14733,7 +14735,7 @@ local function readlocals(f,data,dictionary)
dictionary.subroutines={}
end
end
-local function readcharstrings(f,data,what)
+local function readcharstrings(f,data,version)
local header=data.header
local dictionaries=data.dictionaries
local dictionary=dictionaries[1]
@@ -14742,7 +14744,7 @@ local function readcharstrings(f,data,what)
if type(offset)~="number" then
elseif stringtype==2 then
setposition(f,header.offset+offset)
- local charstrings=readlengths(f,what=="cff2")
+ local charstrings=readlengths(f,version=="cff2")
local nofglyphs=#charstrings
for i=1,nofglyphs do
charstrings[i]=readstring(f,charstrings[i])
@@ -14772,7 +14774,8 @@ readers.parsecharstrings=parsecharstrings
local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionaries=data.dictionaries
local dictionary=dictionaries[1]
- readglobals(f,data)
+ local cid=not dictionary.private and dictionary.cid
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version=="cff2" then
dictionary.charset=nil
@@ -14780,9 +14783,27 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
readencodings(f,data)
readcharsets(f,data,dictionary)
end
+ if cid then
+ local fdarray=cid.fdarray
+ if fdarray then
+ setposition(f,data.header.offset+fdarray)
+ local dictionaries=readlengths(f,version=="cff2")
+ local nofdictionaries=#dictionaries
+ if nofdictionaries>0 then
+ for i=1,nofdictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ dictionary.private=dictionaries[1].private
+ if nofdictionaries>1 then
+ report("ignoring dictionaries > 1 in cid font")
+ end
+ end
+ end
+ end
readprivates(f,data)
parseprivates(data,data.dictionaries)
- readlocals(f,data,dictionary)
+ readlocals(f,data,dictionary,version)
startparsing(fontdata,data,streams)
parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
stopparsing(fontdata,data)
@@ -14793,7 +14814,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionary=dictionaries[1]
local cid=dictionary.cid
local cidselect=cid and cid.fdselect
- readglobals(f,data)
+ readglobals(f,data,version)
readcharstrings(f,data,version)
if version~="cff2" then
readencodings(f,data)
@@ -14837,7 +14858,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local cidarray=cid.fdarray
if cidarray then
setposition(f,header.offset+cidarray)
- local dictionaries=readlengths(f)
+ local dictionaries=readlengths(f,version=="cff2")
for i=1,#dictionaries do
dictionaries[i]=readstring(f,dictionaries[i])
end
@@ -14845,7 +14866,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
cid.dictionaries=dictionaries
readcidprivates(f,data)
for i=1,#dictionaries do
- readlocals(f,data,dictionaries[i])
+ readlocals(f,data,dictionaries[i],version)
end
startparsing(fontdata,data,streams)
for i=1,#charstrings do
@@ -35924,8 +35945,9 @@ function definers.read(specification,size,id)
report_defining("already hashed: %s",hash)
end
else
- tfmdata=definers.loadfont(specification)
+ tfmdata=definers.loadfont(specification)
if tfmdata then
+ tfmdata.original=specification.specification
if trace_defining then
report_defining("loaded and hashed: %s",hash)
end