summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex')
-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-pgr.lua8
-rw-r--r--tex/context/base/mkiv/back-exp.lua39
-rw-r--r--tex/context/base/mkiv/buff-ini.lua20
-rw-r--r--tex/context/base/mkiv/char-act.mkiv15
-rw-r--r--tex/context/base/mkiv/cldf-ini.lua51
-rw-r--r--tex/context/base/mkiv/cldf-ini.mkiv1
-rw-r--r--tex/context/base/mkiv/colo-ini.lua4
-rw-r--r--tex/context/base/mkiv/colo-ini.mkiv8
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv3
-rw-r--r--tex/context/base/mkiv/data-res.lua2
-rw-r--r--tex/context/base/mkiv/file-job.mkvi13
-rw-r--r--tex/context/base/mkiv/font-chk.lua14
-rw-r--r--tex/context/base/mkiv/font-col.lua50
-rw-r--r--tex/context/base/mkiv/font-con.lua34
-rw-r--r--tex/context/base/mkiv/font-ctx.lua127
-rw-r--r--tex/context/base/mkiv/font-dsp.lua9
-rw-r--r--tex/context/base/mkiv/font-gbn.lua97
-rw-r--r--tex/context/base/mkiv/font-imp-effects.lua20
-rw-r--r--tex/context/base/mkiv/font-nod.lua48
-rw-r--r--tex/context/base/mkiv/font-osd.lua59
-rw-r--r--tex/context/base/mkiv/font-ota.lua1
-rw-r--r--tex/context/base/mkiv/font-otj.lua58
-rw-r--r--tex/context/base/mkiv/font-ots.lua52
-rw-r--r--tex/context/base/mkiv/font-sol.lua31
-rw-r--r--tex/context/base/mkiv/font-vfc.lua3
-rw-r--r--tex/context/base/mkiv/good-ctx.lua105
-rw-r--r--tex/context/base/mkiv/grph-epd.lua12
-rw-r--r--tex/context/base/mkiv/grph-inc.lua73
-rw-r--r--tex/context/base/mkiv/grph-pat.lua2
-rw-r--r--tex/context/base/mkiv/l-table.lua9
-rw-r--r--tex/context/base/mkiv/lang-dis.lua96
-rw-r--r--tex/context/base/mkiv/lang-exp.lua34
-rw-r--r--tex/context/base/mkiv/lang-hyp.lua26
-rw-r--r--tex/context/base/mkiv/lang-mis.mkiv4
-rw-r--r--tex/context/base/mkiv/lang-rep.lua7
-rw-r--r--tex/context/base/mkiv/lang-url.lua22
-rw-r--r--tex/context/base/mkiv/lang-wrd.lua16
-rw-r--r--tex/context/base/mkiv/lpdf-ano.lua65
-rw-r--r--tex/context/base/mkiv/lpdf-epa.lua751
-rw-r--r--tex/context/base/mkiv/lpdf-epd.lua470
-rw-r--r--tex/context/base/mkiv/lpdf-ini.lua21
-rw-r--r--tex/context/base/mkiv/lpdf-nod.lua21
-rw-r--r--tex/context/base/mkiv/lpdf-tag.lua39
-rw-r--r--tex/context/base/mkiv/math-act.lua40
-rw-r--r--tex/context/base/mkiv/math-dir.lua22
-rw-r--r--tex/context/base/mkiv/math-fen.mkiv78
-rw-r--r--tex/context/base/mkiv/math-ini.lua2
-rw-r--r--tex/context/base/mkiv/math-noa.lua102
-rw-r--r--tex/context/base/mkiv/math-spa.lua30
-rw-r--r--tex/context/base/mkiv/math-tag.lua173
-rw-r--r--tex/context/base/mkiv/mlib-lua.lua4
-rw-r--r--tex/context/base/mkiv/mult-aux.mkiv91
-rw-r--r--tex/context/base/mkiv/mult-fun.lua2
-rw-r--r--tex/context/base/mkiv/mult-ini.mkiv8
-rw-r--r--tex/context/base/mkiv/mult-low.lua2
-rw-r--r--tex/context/base/mkiv/mult-prm.lua4
-rw-r--r--tex/context/base/mkiv/node-acc.lua18
-rw-r--r--tex/context/base/mkiv/node-aux.lua24
-rw-r--r--tex/context/base/mkiv/node-bck.lua125
-rw-r--r--tex/context/base/mkiv/node-fin.lua465
-rw-r--r--tex/context/base/mkiv/node-fnt.lua432
-rw-r--r--tex/context/base/mkiv/node-ltp.lua9
-rw-r--r--tex/context/base/mkiv/node-met.lua122
-rw-r--r--tex/context/base/mkiv/node-mig.lua6
-rw-r--r--tex/context/base/mkiv/node-nut.lua322
-rw-r--r--tex/context/base/mkiv/node-ppt.lua277
-rw-r--r--tex/context/base/mkiv/node-pro.lua99
-rw-r--r--tex/context/base/mkiv/node-ref.lua76
-rw-r--r--tex/context/base/mkiv/node-res.lua142
-rw-r--r--tex/context/base/mkiv/node-rul.lua169
-rw-r--r--tex/context/base/mkiv/node-scn.lua23
-rw-r--r--tex/context/base/mkiv/node-shp.lua30
-rw-r--r--tex/context/base/mkiv/node-syn.lua16
-rw-r--r--tex/context/base/mkiv/node-tex.lua18
-rw-r--r--tex/context/base/mkiv/node-tra.lua35
-rw-r--r--tex/context/base/mkiv/node-tsk.lua514
-rw-r--r--tex/context/base/mkiv/pack-obj.lua11
-rw-r--r--tex/context/base/mkiv/pack-rul.lua123
-rw-r--r--tex/context/base/mkiv/page-imp.mkiv54
-rw-r--r--tex/context/base/mkiv/page-inj.mkvi2
-rw-r--r--tex/context/base/mkiv/page-lin.lua13
-rw-r--r--tex/context/base/mkiv/page-mix.lua19
-rw-r--r--tex/context/base/mkiv/scrn-ref.mkvi18
-rw-r--r--tex/context/base/mkiv/scrp-cjk.lua9
-rw-r--r--tex/context/base/mkiv/scrp-ini.lua84
-rw-r--r--tex/context/base/mkiv/spac-adj.lua67
-rw-r--r--tex/context/base/mkiv/spac-adj.mkiv51
-rw-r--r--tex/context/base/mkiv/spac-ali.lua11
-rw-r--r--tex/context/base/mkiv/spac-chr.lua116
-rw-r--r--tex/context/base/mkiv/spac-prf.lua9
-rw-r--r--tex/context/base/mkiv/spac-ver.lua59
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26106 -> 26136 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin256921 -> 257465 bytes
-rw-r--r--tex/context/base/mkiv/strc-mar.lua12
-rw-r--r--tex/context/base/mkiv/strc-reg.mkiv6
-rw-r--r--tex/context/base/mkiv/strc-ren.mkiv6
-rw-r--r--tex/context/base/mkiv/strc-sec.mkiv15
-rw-r--r--tex/context/base/mkiv/supp-box.lua8
-rw-r--r--tex/context/base/mkiv/syst-aux.mkiv29
-rw-r--r--tex/context/base/mkiv/syst-ini.mkiv10
-rw-r--r--tex/context/base/mkiv/syst-lua.mkiv36
-rw-r--r--tex/context/base/mkiv/tabl-tbl.mkiv14
-rw-r--r--tex/context/base/mkiv/task-ini.lua343
-rw-r--r--tex/context/base/mkiv/trac-jus.lua6
-rw-r--r--tex/context/base/mkiv/trac-par.lua2
-rw-r--r--tex/context/base/mkiv/trac-vis.lua86
-rw-r--r--tex/context/base/mkiv/typo-bld.lua32
-rw-r--r--tex/context/base/mkiv/typo-brk.lua10
-rw-r--r--tex/context/base/mkiv/typo-cap.lua153
-rw-r--r--tex/context/base/mkiv/typo-chr.lua26
-rw-r--r--tex/context/base/mkiv/typo-cln.lua38
-rw-r--r--tex/context/base/mkiv/typo-dha.lua6
-rw-r--r--tex/context/base/mkiv/typo-dig.lua14
-rw-r--r--tex/context/base/mkiv/typo-dir.lua10
-rw-r--r--tex/context/base/mkiv/typo-drp.lua42
-rw-r--r--tex/context/base/mkiv/typo-dua.lua14
-rw-r--r--tex/context/base/mkiv/typo-dub.lua14
-rw-r--r--tex/context/base/mkiv/typo-duc.lua14
-rw-r--r--tex/context/base/mkiv/typo-fkr.lua8
-rw-r--r--tex/context/base/mkiv/typo-fln.lua30
-rw-r--r--tex/context/base/mkiv/typo-itc.lua37
-rw-r--r--tex/context/base/mkiv/typo-krn.lua14
-rw-r--r--tex/context/base/mkiv/typo-lin.lua6
-rw-r--r--tex/context/base/mkiv/typo-mar.lua50
-rw-r--r--tex/context/base/mkiv/typo-pag.lua5
-rw-r--r--tex/context/base/mkiv/typo-pnc.lua88
-rw-r--r--tex/context/base/mkiv/typo-rep.lua10
-rw-r--r--tex/context/base/mkiv/typo-rub.lua22
-rw-r--r--tex/context/base/mkiv/typo-spa.lua8
-rw-r--r--tex/context/base/mkiv/typo-sus.lua9
-rw-r--r--tex/context/base/mkiv/typo-tal.lua18
-rw-r--r--tex/context/base/mkiv/typo-wrp.lua12
-rw-r--r--tex/context/base/mkiv/util-seq.lua201
-rw-r--r--tex/context/base/mkiv/util-str.lua11
-rw-r--r--tex/context/interface/mkiv/context-en.xml9
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin847750 -> 847896 bytes
-rw-r--r--tex/context/interface/mkiv/i-mathfence.xml3
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin61032 -> 61079 bytes
-rw-r--r--tex/context/interface/mkiv/i-register.xml10
-rw-r--r--tex/context/modules/mkiv/m-scite.mkiv9
-rw-r--r--tex/context/modules/mkiv/s-fonts-effects.mkiv59
-rw-r--r--tex/context/modules/mkiv/s-fonts-shapes.lua347
-rw-r--r--tex/context/modules/mkiv/s-fonts-shapes.mkiv17
-rw-r--r--tex/context/modules/mkiv/s-languages-hyphenation.lua7
-rw-r--r--tex/generic/context/luatex/luatex-basics-nod.lua30
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua278
-rw-r--r--tex/generic/context/luatex/luatex-test.tex12
150 files changed, 5595 insertions, 3333 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index b00d14298..16b089e82 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{2018.04.19 15:53}
+\newcontextversion{2018.05.12 00:07}
%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 118a48a35..d37888100 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{2018.04.19 15:53}
+\edef\contextversion{2018.05.12 00:07}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/anch-pgr.lua b/tex/context/base/mkiv/anch-pgr.lua
index ca5a5a8af..7b1746582 100644
--- a/tex/context/base/mkiv/anch-pgr.lua
+++ b/tex/context/base/mkiv/anch-pgr.lua
@@ -61,8 +61,6 @@ local pdfgetpos = pdf.getpos -- why not a generic name !
local a_textbackground = attributes.private("textbackground")
local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
local new_latelua = nuts.pool.latelua
local new_rule = nuts.pool.rule
@@ -82,7 +80,7 @@ local localpar_code = nodecodes.localpar
local insert_before = nuts.insert_before
local insert_after = nuts.insert_after
-local processranges = nodes.processranges
+local processranges = nuts.processranges
local unsetvalue = attributes.unsetvalue
@@ -213,10 +211,8 @@ end
nodes.handlers.textbackgrounds = function(head,where,parent) -- we have hlistdir and local dir
-- todo enable action in register
- head = tonut(head)
index = index + 1
- local head, done = processranges(a_textbackground,flush,head,parent)
- return tonode(head), done
+ return processranges(a_textbackground,flush,head,parent)
end
interfaces.implement {
diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua
index 26efe6aad..fd86217b1 100644
--- a/tex/context/base/mkiv/back-exp.lua
+++ b/tex/context/base/mkiv/back-exp.lua
@@ -129,9 +129,8 @@ local isglyph = nuts.isglyph
local getkern = nuts.getkern
local getwidth = nuts.getwidth
-
-local traverse_id = nuts.traverse_id
-local traverse_nodes = nuts.traverse
+local nexthlist = nuts.traversers.hlist
+local nextnode = nuts.traversers.node
local references = structures.references
local structurestags = structures.tags
@@ -2749,10 +2748,7 @@ end
local function collectresults(head,list,pat,pap) -- is last used (we also have currentattribute)
local p
--- for n in traverse_nodes(head) do
--- local c, id = isglyph(n) -- 14: image, 8: literal (mp)
--- if c then
- for n, id in traverse_nodes(head) do
+ for n, id in nextnode, head do
if id == glyph_code then
local c = getchar(n)
local at = getattr(n,a_tagged) or pat
@@ -3073,12 +3069,12 @@ function nodes.handlers.export(head) -- hooks into the page builder
report_export("%w<!-- stop flushing page -->",currentdepth)
end
stoptiming(treehash)
- return head, true
+ return head
end
-function builders.paragraphs.tag(head)
+function builders.paragraphs.tag(head) -- traverse_list
noftextblocks = noftextblocks + 1
- for n in traverse_id(hlist_code,tonut(head)) do
+ for n in nexthlist, head do
local subtype = getsubtype(n)
if subtype == line_code then
setattr(n,a_textblock,noftextblocks)
@@ -3089,6 +3085,22 @@ function builders.paragraphs.tag(head)
return false
end
+if LUATEXVERSION >= 1.090 then
+
+ function builders.paragraphs.tag(head) -- traverse_list
+ noftextblocks = noftextblocks + 1
+ for n, subtype in nexthlist, head do
+ if subtype == line_code then
+ setattr(n,a_textblock,noftextblocks)
+ elseif subtype == glue_code or subtype == kern_code then -- no need to set fontkerns
+ setattr(n,a_textblock,0)
+ end
+ end
+ return false
+ end
+
+end
+
do
local xmlcollected = xml.collected
@@ -3795,19 +3807,14 @@ local htmltemplate = [[
stoptiming(treehash)
end
- local appendaction = nodes.tasks.appendaction
local enableaction = nodes.tasks.enableaction
function structurestags.initializeexport()
if not exporting then
report_export("enabling export to xml")
- -- not yet known in task-ini
- appendaction("shipouts","normalizers", "nodes.handlers.export")
- -- enableaction("shipouts","nodes.handlers.export")
+ enableaction("shipouts","nodes.handlers.export")
enableaction("shipouts","nodes.handlers.accessibility")
enableaction("math", "noads.handlers.tags")
- -- appendaction("finalizers","lists","builders.paragraphs.tag")
- -- enableaction("finalizers","builders.paragraphs.tag")
luatex.registerstopactions(structurestags.finishexport)
exporting = true
end
diff --git a/tex/context/base/mkiv/buff-ini.lua b/tex/context/base/mkiv/buff-ini.lua
index 1c7912773..970042c1b 100644
--- a/tex/context/base/mkiv/buff-ini.lua
+++ b/tex/context/base/mkiv/buff-ini.lua
@@ -645,7 +645,10 @@ local function gettexbuffer(name)
end
end
-buffers.run = runbuffer
+buffers.get = getbuffer
+buffers.getmkiv = getbuffermkiv
+buffers.gettexbuffer = gettexbuffer
+buffers.run = runbuffer
implement { name = "getbufferctxlua", actions = loadcontent, arguments = "string" }
implement { name = "getbuffer", actions = getbuffer, arguments = "string" }
@@ -708,3 +711,18 @@ do
end
end
+
+-- moved here:
+
+function buffers.samplefile(name)
+ if not buffers.exists(name) then
+ buffers.assign(name,io.loaddata(resolvers.findfile(name)))
+ end
+ buffers.get(name)
+end
+
+implement {
+ name = "samplefile", -- bad name, maybe rename to injectbuffercontent
+ actions = buffers.samplefile,
+ arguments = "string"
+}
diff --git a/tex/context/base/mkiv/char-act.mkiv b/tex/context/base/mkiv/char-act.mkiv
index 6b2ca51e2..ff4dc621f 100644
--- a/tex/context/base/mkiv/char-act.mkiv
+++ b/tex/context/base/mkiv/char-act.mkiv
@@ -78,12 +78,17 @@
% \unexpanded\def\ignorepages{\catcode\formfeedasciicode \ignorecatcode}
% \unexpanded\def\ignoreeofs {\catcode\endoffileasciicode\ignorecatcode}
-\unexpanded\def\obeytabs {\catcode\tabasciicode \activecatcode\letcharcode\tabasciicode \obeyedtab }
-\unexpanded\def\obeylines {\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\obeyedline}
-\unexpanded\def\obeypages {\catcode\formfeedasciicode \activecatcode\letcharcode\formfeedasciicode \obeyedpage}
+\def\_obeyed_space_{\obeyedspace}
+\def\_obeyed_tab_ {\obeyedtab}
+\def\_obeyed_line_ {\obeyedline}
+\def\_obeyed_page_ {\obeyedpage}
-\unexpanded\def\ignoretabs {\catcode\tabasciicode \activecatcode\letcharcode\tabasciicode \obeyedspace}
-\unexpanded\def\ignorelines{\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\obeyedspace}
+\unexpanded\def\obeytabs {\catcode\tabasciicode \activecatcode\letcharcode\tabasciicode \_obeyed_tab_ }
+\unexpanded\def\obeylines {\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\_obeyed_line_}
+\unexpanded\def\obeypages {\catcode\formfeedasciicode \activecatcode\letcharcode\formfeedasciicode \_obeyed_page_}
+
+\unexpanded\def\ignoretabs {\catcode\tabasciicode \activecatcode\letcharcode\tabasciicode \_obeyed_space_}
+\unexpanded\def\ignorelines{\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\_obeyed_space_}
\unexpanded\def\ignorepages{\catcode\formfeedasciicode \ignorecatcode}
\unexpanded\def\ignoreeofs {\catcode\endoffileasciicode\ignorecatcode}
diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua
index 86dec0209..8e4f2e729 100644
--- a/tex/context/base/mkiv/cldf-ini.lua
+++ b/tex/context/base/mkiv/cldf-ini.lua
@@ -1224,34 +1224,39 @@ do
end
end
-end
-
---
-
-function context.runfile(filename)
- local foundname = resolvers.findtexfile(file.addsuffix(filename,"cld")) or ""
- if foundname ~= "" then
- local ok = dofile(foundname)
- if type(ok) == "function" then
- if trace_cld then
- report_context("begin of file %a (function call)",foundname)
- end
- ok()
- if trace_cld then
- report_context("end of file %a (function call)",foundname)
+ local findtexfile = resolvers.findtexfile
+ local findfile = resolvers.findfile
+
+ function context.runfile(filename)
+ local foundname = findtexfile(file.addsuffix(filename,"cld")) or ""
+ if foundname ~= "" then
+ local ok = dofile(foundname)
+ if type(ok) == "function" then
+ if trace_cld then
+ report_context("begin of file %a (function call)",foundname)
+ end
+ ok()
+ if trace_cld then
+ report_context("end of file %a (function call)",foundname)
+ end
+ elseif ok then
+ report_context("file %a is processed and returns true",foundname)
+ else
+ report_context("file %a is processed and returns nothing",foundname)
end
- elseif ok then
- report_context("file %a is processed and returns true",foundname)
else
- report_context("file %a is processed and returns nothing",foundname)
+ report_context("unknown file %a",filename)
end
- else
- report_context("unknown file %a",filename)
end
-end
-function context.loadfile(filename)
- context(stripstring(loaddata(resolvers.findfile(filename))))
+ function context.loadfile(filename)
+ context(stripstring(loaddata(findfile(filename))))
+ end
+
+ function context.loadviafile(filename)
+ viafile(stripstring(loaddata(findfile(filename))))
+ end
+
end
-- some functions
diff --git a/tex/context/base/mkiv/cldf-ini.mkiv b/tex/context/base/mkiv/cldf-ini.mkiv
index 27ce42aa2..0cf3b892c 100644
--- a/tex/context/base/mkiv/cldf-ini.mkiv
+++ b/tex/context/base/mkiv/cldf-ini.mkiv
@@ -49,6 +49,7 @@
\normalprotected\def\cldprocessfile#1{\directlua{context.runfile("#1")}}
\def\cldloadfile #1{\directlua{context.loadfile("#1")}}
+ \def\cldloadviafile#1{\directlua{context.loadviafile("#1")}}
\def\cldcontext #1{\directlua{context(#1)}}
\def\cldcommand #1{\directlua{context.#1}}
% \def\cldverbatim #1{\directlua{context.verbatim.#1}} % maybe make verbatim global
diff --git a/tex/context/base/mkiv/colo-ini.lua b/tex/context/base/mkiv/colo-ini.lua
index 921612b0f..f423346b4 100644
--- a/tex/context/base/mkiv/colo-ini.lua
+++ b/tex/context/base/mkiv/colo-ini.lua
@@ -43,6 +43,7 @@ local texsetattribute = tex.setattribute
local texgetattribute = tex.getattribute
local texgetcount = tex.getcount
local texgettoks = tex.gettoks
+local texgetmacro = tokens.getters.macro
local a_color = attributes.private('color')
local a_transparency = attributes.private('transparency')
@@ -698,7 +699,8 @@ local paletnamespace = getnamespace("colorpalet")
local function namedcolorattributes(name)
local space = texgetattribute(a_colormodel)
- local prefix = texgettoks("t_colo_prefix")
+ ----- prefix = texgettoks("t_colo_prefix")
+ local prefix = texgetmacro("currentcolorprefix")
local color
if prefix ~= "" then
color = valid[prefix..name]
diff --git a/tex/context/base/mkiv/colo-ini.mkiv b/tex/context/base/mkiv/colo-ini.mkiv
index daee8ada6..7ecb05d23 100644
--- a/tex/context/base/mkiv/colo-ini.mkiv
+++ b/tex/context/base/mkiv/colo-ini.mkiv
@@ -592,22 +592,22 @@
% \the\everysetuppalet
% \colo_helpers_initialize_maintextcolor}
-\newtoks\t_colo_prefix % used in mp interface
+% \newtoks\t_colo_prefix % used in mp interface
\def\colo_palets_setup[#1]%
{\edef\currentcolorpalet{#1}%
\ifx\currentcolorpalet\empty
% seems to be a reset
\let\currentcolorprefix\empty
- \t_colo_prefix\emptytoks
+ %\t_colo_prefix\emptytoks
\else\ifcsname\??paletlist\currentcolorpalet\endcsname
\edef\currentcolorprefix{#1:}%
- \t_colo_prefix\expandafter{\currentcolorprefix}%
+ %\t_colo_prefix\expandafter{\currentcolorprefix}%
\else
\colo_helpers_show_message\m!colors7\currentcolorpalet
\let\currentcolorpalet\empty
\let\currentcolorprefix\empty
- \t_colo_prefix\emptytoks
+ %\t_colo_prefix\emptytoks
\fi\fi
\the\everysetuppalet
\colo_helpers_initialize_maintextcolor}
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 9fa8f68a4..105bd1ccf 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2018.04.19 15:53}
+\newcontextversion{2018.05.12 00:07}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 24482906c..1d44fefd0 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -42,7 +42,7 @@
%D has to match \type {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2018.04.19 15:53}
+\edef\contextversion{2018.05.12 00:07}
\edef\contextkind {beta}
%D For those who want to use this:
@@ -274,7 +274,6 @@
\loadmarkfile{spac-lin}
\loadmarkfile{spac-pag}
\loadmarkfile{spac-par}
-%loadmarkfile{spac-adj} % no longer needed
\loadmarkfile{spac-def}
\loadmkvifile{spac-prf}
\loadmarkfile{spac-grd}
diff --git a/tex/context/base/mkiv/data-res.lua b/tex/context/base/mkiv/data-res.lua
index 9fb33f88d..9f5e3a8ac 100644
--- a/tex/context/base/mkiv/data-res.lua
+++ b/tex/context/base/mkiv/data-res.lua
@@ -1875,7 +1875,7 @@ function resolvers.booleanvariable(str,default)
end
function resolvers.dowithfilesintree(pattern,handle,before,after) -- will move, can be a nice iterator instead
- local hashes = instance.hashes
+ local hashes = instance.hashes
for i=1,#hashes do
local hash = hashes[i]
local blobtype = hash.type
diff --git a/tex/context/base/mkiv/file-job.mkvi b/tex/context/base/mkiv/file-job.mkvi
index e1ea405c0..f1f2d126f 100644
--- a/tex/context/base/mkiv/file-job.mkvi
+++ b/tex/context/base/mkiv/file-job.mkvi
@@ -347,12 +347,15 @@
% Bonus:
-\installcorenamespace{samplefile}
+% \installcorenamespace{samplefile}
+%
+% \unexpanded\def\samplefile#1%
+% {\ifcsname\??samplefile#1\endcsname \else
+% \setxvalue{\??samplefile#1}{\cldloadfile{#1}}%
+% \fi
+% \lastnamedcs}
\unexpanded\def\samplefile#1%
- {\ifcsname\??samplefile#1\endcsname \else
- \setxvalue{\??samplefile#1}{\cldloadfile{#1}}%
- \fi
- \lastnamedcs}
+ {\clf_samplefile{#1}}
\protect \endinput
diff --git a/tex/context/base/mkiv/font-chk.lua b/tex/context/base/mkiv/font-chk.lua
index 4e7bf939b..5bd85fe66 100644
--- a/tex/context/base/mkiv/font-chk.lua
+++ b/tex/context/base/mkiv/font-chk.lua
@@ -66,14 +66,15 @@ local hpack_node = node.hpack
local nuts = nodes.nuts
local tonut = nuts.tonut
-local tonode = nuts.tonode
local getfont = nuts.getfont
local getchar = nuts.getchar
local setchar = nuts.setchar
-local traverse_id = nuts.traverse_id
+----- traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
+
local remove_node = nuts.remove
local insert_node_after = nuts.insert_after
@@ -281,7 +282,7 @@ end
local function placeholder(font,char)
local tfmdata = fontdata[font]
- local category = chardata[char].category
+ local category = chardata[char].category or "unknown"
local fakechar = mapping[category]
local slot = getprivateslot(font,fakechar)
if not slot then
@@ -295,15 +296,14 @@ checkers.placeholder = placeholder
function checkers.missing(head)
local lastfont, characters, found = nil, nil, nil
- head = tonut(head)
- for n in traverse_id(glyph_code,head) do -- faster than while loop so we delay removal
+ for n in nextglyph, head do -- faster than while loop so we delay removal
local font = getfont(n)
local char = getchar(n)
if font ~= lastfont then
characters = fontcharacters[font]
lastfont = font
end
- if font > 0 and not characters[char] and is_character[chardata[char].category] then
+ if font > 0 and not characters[char] and is_character[chardata[char].category or "unknown"] then
if action == "remove" then
onetimemessage(font,char,"missing (will be deleted)")
elseif action == "replace" then
@@ -340,7 +340,7 @@ function checkers.missing(head)
else
-- maye write a report to the log
end
- return tonode(head), false
+ return head
end
local relevant = {
diff --git a/tex/context/base/mkiv/font-col.lua b/tex/context/base/mkiv/font-col.lua
index 8aad4d7d5..e5fd37b1b 100644
--- a/tex/context/base/mkiv/font-col.lua
+++ b/tex/context/base/mkiv/font-col.lua
@@ -19,15 +19,14 @@ local fastcopy = table.fastcopy
local formatters = string.formatters
local nuts = nodes.nuts
-local tonut = nuts.tonut
local getfont = nuts.getfont
local getchar = nuts.getchar
local setfont = nuts.setfont
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
+----- traverse_char = nuts.traverse_char
+local nextchar = nuts.traversers.char
local settings_to_hash = utilities.parsers.settings_to_hash
@@ -311,8 +310,7 @@ local function monoslot(font,char,parent,factor)
end
function collections.process(head) -- this way we keep feature processing
- local done = false
- for n in traverse_char(tonut(head)) do
+ for n in nextchar, head do
local font = getfont(n)
local vector = vectors[font]
if vector then
@@ -329,7 +327,6 @@ function collections.process(head) -- this way we keep feature processing
)
end
setfont(n,newfont,newchar)
- done = true
else
local fakemono = vector.factor
if trace_collecting then
@@ -342,11 +339,48 @@ function collections.process(head) -- this way we keep feature processing
else
setfont(n,vect)
end
- done = true
end
end
end
- return head, done
+ return head
+end
+
+if LUATEXVERSION >= 1.090 then
+
+ function collections.process(head) -- this way we keep feature processing
+ for n, char, font in nextchar, head do
+ local vector = vectors[font]
+ if vector then
+ local vect = vector[char]
+ if not vect then
+ -- keep it
+ elseif type(vect) == "table" then
+ local newfont = vect[1]
+ local newchar = vect[2]
+ if trace_collecting then
+ report_fonts("remapping character %C in font %a to character %C in font %a%s",
+ char,font,newchar,newfont,not chardata[newfont][newchar] and " (missing)" or ""
+ )
+ end
+ setfont(n,newfont,newchar)
+ else
+ local fakemono = vector.factor
+ if trace_collecting then
+ report_fonts("remapping font %a to %a for character %C%s",
+ font,vect,char,not chardata[vect][char] and " (missing)" or ""
+ )
+ end
+ if fakemono then
+ setfont(n,vect,monoslot(vect,char,font,fakemono))
+ else
+ setfont(n,vect)
+ end
+ end
+ end
+ end
+ return head
+ end
+
end
function collections.found(font,char) -- this way we keep feature processing
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index 73e9ffe22..d6fe55c65 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -768,12 +768,15 @@ function constructors.scale(tfmdata,specification)
local t = { }
for i=1,#vv do
local vvi = vv[i]
- t[i] = {
- ["start"] = (vvi["start"] or 0)*vdelta,
- ["end"] = (vvi["end"] or 0)*vdelta,
- ["advance"] = (vvi["advance"] or 0)*vdelta,
- ["extender"] = vvi["extender"],
- ["glyph"] = vvi["glyph"],
+ local s = vvi["start"] or 0
+ local e = vvi["end"] or 0
+ local a = vvi["advance"] or 0
+ t[i] = { -- zero check nicer for 5.3
+ ["start"] = s == 0 and 0 or s * vdelta,
+ ["end"] = e == 0 and 0 or e * vdelta,
+ ["advance"] = a == 0 and 0 or a * vdelta,
+ ["extender"] = vvi["extender"],
+ ["glyph"] = vvi["glyph"],
}
end
chr.vert_variants = t
@@ -783,12 +786,15 @@ function constructors.scale(tfmdata,specification)
local t = { }
for i=1,#hv do
local hvi = hv[i]
- t[i] = {
- ["start"] = (hvi["start"] or 0)*hdelta,
- ["end"] = (hvi["end"] or 0)*hdelta,
- ["advance"] = (hvi["advance"] or 0)*hdelta,
- ["extender"] = hvi["extender"],
- ["glyph"] = hvi["glyph"],
+ local s = hvi["start"] or 0
+ local e = hvi["end"] or 0
+ local a = hvi["advance"] or 0
+ t[i] = { -- zero check nicer for 5.3
+ ["start"] = s == 0 and 0 or s * hdelta,
+ ["end"] = e == 0 and 0 or e * hdelta,
+ ["advance"] = a == 0 and 0 or a * hdelta,
+ ["extender"] = hvi["extender"],
+ ["glyph"] = hvi["glyph"],
}
end
chr.horiz_variants = t
@@ -902,7 +908,7 @@ function constructors.scale(tfmdata,specification)
else
chr.commands = vc
end
- chr.index = nil
+ -- chr.index = nil
end
end
targetcharacters[unicode] = chr
@@ -912,7 +918,7 @@ function constructors.scale(tfmdata,specification)
--
constructors.aftercopyingcharacters(target,tfmdata)
--
- constructors.trytosharefont(target,tfmdata)
+ constructors.trytosharefont(target,tfmdata)
--
-- catch inconsistencies
--
diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua
index 68191143b..f24686106 100644
--- a/tex/context/base/mkiv/font-ctx.lua
+++ b/tex/context/base/mkiv/font-ctx.lua
@@ -79,6 +79,9 @@ local aglunicodes = nil -- delayed loading
local nuts = nodes.nuts
local tonut = nuts.tonut
+----- traverse_char = nuts.traverse_char
+local nextchar = nuts.traversers.char
+
local getattr = nuts.getattr
local setattr = nuts.setattr
local getprop = nuts.getprop
@@ -583,12 +586,11 @@ local function presetcontext(name,parent,features) -- will go to con and shared
features = { }
elseif type(features) == "string" then
features = normalize_features(settings_to_hash(features))
- for key, value in next, features do
- if type(value) == "string" and find(value,"=") then
- local t = settings_to_hash(value)
+ for key, value in next, features do
+ if type(value) == "string" and find(value,"[=:]") then
+ local t = settings_to_hash_colon_too(value)
if next(t) then
--- features[key] = sequenced(normalize_features(t),",")
- features[key] = t -- sequenced(normalize_features(t),",")
+ features[key] = sequenced(normalize_features(t),",")
end
end
end
@@ -2635,8 +2637,6 @@ do
local unsetvalue = attributes.unsetvalue
- local traverse_char = nuts.traverse_char
-
local a_color = attributes.private('color')
local a_colormodel = attributes.private('colormodel')
local a_state = attributes.private('state')
@@ -2660,11 +2660,14 @@ do
[states.pstf] = "font:5",
}
+ -- todo: traversers
+ -- todo: check attr_list so that we can use the same .. helper: setcolorattr
+
local function markstates(head)
if head then
head = tonut(head)
local model = getattr(head,a_colormodel) or 1
- for glyph in traverse_char(head) do
+ for glyph in nextchar, head do
local a = getprop(glyph,a_state)
if a then
local name = colornames[a]
@@ -2715,7 +2718,7 @@ do
function methods.nocolor(head,font,attr)
- for n in traverse_char(head) do
+ for n in nextchar, head do
if not font or getfont(n) == font then
setattr(n,a_color,unsetvalue)
end
@@ -3247,3 +3250,109 @@ do
}
end
+
+-- handy, for now here:
+
+function fonts.helpers.collectanchors(tfmdata)
+
+ local resources = tfmdata.resources -- todo: use shared
+
+ if not resources or resources.anchors then
+ return resources.anchors
+ end
+
+ local anchors = { }
+
+ local function set(unicode,target,class,anchor)
+ local a = anchors[unicode]
+ if not a then
+ anchors[unicode] = { [target] = { anchor } }
+ return
+ end
+ local t = a[target]
+ if not t then
+ a[target] = { anchor }
+ return
+ end
+ local x, y = anchor[1], anchor[2]
+ for k, v in next, t do
+ if v[1] == x and v[2] == y then
+ return
+ end
+ end
+ t[#t+1] = anchor
+ end
+
+ local function getanchors(steps,target)
+ for i=1,#steps do
+ local step = steps[i]
+ local coverage = step.coverage
+ for unicode, data in next, coverage do
+ local class = data[1]
+ local anchor = data[2]
+ if anchor[1] ~= 0 or anchor[2] ~= 0 then
+ set(unicode,target,class,anchor)
+ end
+ end
+ end
+ end
+
+ local function getcursives(steps)
+ for i=1,#steps do
+ local step = steps[i]
+ local coverage = step.coverage
+ for unicode, data in next, coverage do
+ local class = data[1]
+ local en = data[2]
+ local ex = data[3]
+ if en then
+ set(unicode,"entry",class,en)
+ end
+ if ex then
+ set(unicode,"exit", class,ex)
+ end
+ end
+ end
+ end
+
+ local function collect(list)
+ if list then
+ for i=1,#list do
+ local entry = list[i]
+ local steps = entry.steps
+ local kind = entry.type
+ if kind == "gpos_mark2mark" then
+ getanchors(steps,"mark")
+ elseif kind == "gpos_mark2base" then
+ getanchors(steps,"base")
+ elseif kind == "gpos_mark2ligature" then
+ getanchors(steps,"ligature")
+ elseif kind == "gpos_cursive" then
+ getcursives(steps)
+ end
+ end
+ end
+ end
+
+ collect(resources.sequences)
+ collect(resources.sublookups)
+
+ local function sorter(a,b)
+ if a[1] == b[1] then
+ return a[2] < b[2]
+ else
+ return a[1] < b[1]
+ end
+ end
+
+ for unicode, old in next, anchors do
+ for target, list in next, old do
+ sort(list,sorter)
+ end
+ end
+
+ resources.anchors = anchors
+
+ return anchors
+
+end
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index c896aa711..6279dda89 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -68,12 +68,13 @@ local reversed = table.reversed
local sort = table.sort
local insert = table.insert
local round = math.round
-local settings_to_hash_colon_too = table.settings_to_hash_colon_too
+local settings_to_hash = utilities.parsers.settings_to_hash_colon_too
local setmetatableindex = table.setmetatableindex
local formatters = string.formatters
local sortedkeys = table.sortedkeys
local sortedhash = table.sortedhash
+local sequenced = table.sequenced
local report = logs.reporter("otf reader")
@@ -324,7 +325,7 @@ end)
-- wght:400,wdth:100,ital:1
local function axistofactors(str)
- local t = settings_to_hash_colon_too(str)
+ local t = settings_to_hash(str)
for k, v in next, t do
t[k] = tonumber(v) or v -- this also normalizes numbers itself
end
@@ -349,10 +350,6 @@ function helpers.normalizedaxis(str)
return hash[str] or str
end
-local function axistofactors(str)
- return settings_to_hash_colon_too(str)
-end
-
-- contradicting spec ... (signs) so i'll check it and fix it once we have
-- proper fonts
diff --git a/tex/context/base/mkiv/font-gbn.lua b/tex/context/base/mkiv/font-gbn.lua
index 8f1acac65..e2d245860 100644
--- a/tex/context/base/mkiv/font-gbn.lua
+++ b/tex/context/base/mkiv/font-gbn.lua
@@ -47,8 +47,8 @@ local setprev = nuts.setprev
local n_ligaturing = node.ligaturing
local n_kerning = node.kerning
-local ligaturing = nuts.ligaturing
-local kerning = nuts.kerning
+local d_ligaturing = nuts.ligaturing
+local d_kerning = nuts.kerning
local basemodepass = true
@@ -69,15 +69,30 @@ function node.kerning(...)
return n_kerning(...)
end
+function nuts.ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return d_ligaturing(...)
+end
+
+function nuts.kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return d_kerning(...)
+end
+
+-- direct.ligaturing = nuts.ligaturing
+-- direct.kerning = nuts.kerning
+
function nodes.handlers.setbasemodepass(v)
basemodepass = v
end
--------- nodes.handlers.nodepass(head)
-function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
+local function nodepass(head,groupcode,size,packtype,direction)
local fontdata = fonts.hashes.identifiers
if fontdata then
- local nuthead = tonut(head)
local usedfonts = { }
local basefonts = { }
local prevfont = nil
@@ -85,7 +100,7 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
local variants = nil
local redundant = nil
local nofused = 0
- for n in traverse_id(glyph_code,nuthead) do
+ for n in traverse_id(glyph_code,head) do
local font = getfont(n)
if font ~= prevfont then
if basefont then
@@ -147,8 +162,8 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
for i=1,#redundant do
local r = redundant[i]
local p, n = getboth(r)
- if r == nuthead then
- nuthead = n
+ if r == head then
+ head = n
setprev(n)
else
setlink(p,n)
@@ -167,7 +182,7 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
flush_node(r)
end
end
- for d in traverse_id(disc_code,nuthead) do
+ for d in traverse_id(disc_code,head) do
local _, _, r = getdisc(d)
if r then
for n in traverse_id(glyph_code,r) do
@@ -205,16 +220,16 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
local start = range[1]
local stop = range[2]
if start then
- local front = nuthead == start
+ local front = head == start
local prev, next
if stop then
next = getnext(stop)
- start, stop = ligaturing(start,stop)
- start, stop = kerning(start,stop)
+ start, stop = d_ligaturing(start,stop)
+ start, stop = d_kerning(start,stop)
else
prev = getprev(start)
- start = ligaturing(start)
- start = kerning(start)
+ start = d_ligaturing(start)
+ start = d_kerning(start)
end
if prev then
setlink(prev,start)
@@ -222,41 +237,65 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
if next then
setlink(stop,next)
end
- if front and nuthead ~= start then
- head = tonode(start)
+ if front and head ~= start then
+ head = start
end
end
end
end
- return head, true
- else
- return head, false
end
+ return head
end
-function nodes.handlers.basepass(head)
+local function basepass(head)
if basemodepass then
- head = n_ligaturing(head)
- head = n_kerning(head)
+ head = d_ligaturing(head)
+ head = d_kerning(head)
end
- return head, true
+ return head
end
-local nodepass = nodes.handlers.nodepass
-local basepass = nodes.handlers.basepass
+local protectpass = node.direct.protect_glyphs
local injectpass = nodes.injections.handler
-local protectpass = nodes.handlers.protectglyphs
+
+-- This is the only official public interface and this one can be hooked into a callback (chain) and
+-- everything else can change!@ Functione being visibel doesn't mean that it's part of the api.
+
+function nodes.handlers.nodepass(head,...)
+ if head then
+ return tonode(nodepass(tonut(head),...))
+ end
+end
+
+function nodes.handlers.basepass(head)
+ if head then
+ return tonode(basepass(tonut(head)))
+ end
+end
+
+function nodes.handlers.injectpass(head)
+ if head then
+ return tonode(injectpass(tonut(head)))
+ end
+end
+
+function nodes.handlers.protectpass(head)
+ if head then
+ protectpass(tonut(head))
+ return head
+ end
+end
function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
if head then
+ head = tonut(head)
head = nodepass(head,groupcode,size,packtype,direction)
head = injectpass(head)
if not basemodepass then
head = basepass(head)
end
protectpass(head)
- return head, true
- else
- return head, false
+ head = tonode(head)
end
+ return head
end
diff --git a/tex/context/base/mkiv/font-imp-effects.lua b/tex/context/base/mkiv/font-imp-effects.lua
index cb7cf10d3..578c8bc10 100644
--- a/tex/context/base/mkiv/font-imp-effects.lua
+++ b/tex/context/base/mkiv/font-imp-effects.lua
@@ -22,8 +22,10 @@ local settings_to_hash = utilities.parsers.settings_to_hash_colon_too
local helpers = fonts.helpers
local prependcommands = helpers.prependcommands
local charcommand = helpers.commands.char
+local leftcommand = helpers.commands.left
local rightcommand = helpers.commands.right
local upcommand = helpers.commands.up
+local downcommand = helpers.commands.down
local dummycommand = helpers.commands.dummy
----- constructors = fonts.constructors
@@ -244,7 +246,8 @@ local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze
local character = characters[0x221A]
- if character then
+ if character and character.next then
+-- print("base char",0x221A,table.sequenced(character))
local char = character
local next = character.next
wdpatch(char)
@@ -253,6 +256,7 @@ local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze
char = characters[next]
wdpatch(char)
htpatch(char)
+-- print("next char",next,table.sequenced(char))
next = char.next
end
if char then
@@ -260,7 +264,9 @@ local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze
if v then
local top = v[#v]
if top then
- htpatch(characters[top.glyph])
+ local char = characters[top.glyph]
+-- print("top char",top.glyph,table.sequenced(char))
+ htpatch(char)
end
end
end
@@ -269,8 +275,9 @@ end
-- local show_effect = { "lua", function(f,c)
-- report_effect("font id %i, char %C",f,c)
+-- inspect(fonts.hashes.characters[f][c])
-- end }
---
+
-- local show_effect = { "lua", "print('!')" }
local function manipulateeffect(tfmdata)
@@ -288,7 +295,7 @@ local function manipulateeffect(tfmdata)
local ddelta = effect.ddelta * vfactor * multiplier
local vshift = effect.vshift * vfactor * multiplier
local squeeze = effect.squeeze
- local hshift = wdelta -- / 2
+ local hshift = wdelta / 2
local dx = multiplier * vfactor
local dy = vshift
local factor = (1 + effect.factor) * factor
@@ -299,7 +306,6 @@ local function manipulateeffect(tfmdata)
local oldwidth = character.width
local oldheight = character.height
local olddepth = character.depth
-
if oldwidth and oldwidth > 0 then
character.width = oldwidth + wdelta
local commands = character.commands
@@ -335,10 +341,10 @@ local function manipulateeffect(tfmdata)
end
end
if oldheight and oldheight > 0 then
- character.height = oldheight + hdelta
+ character.height = oldheight + hdelta
end
if olddepth and olddepth > 0 then
- character.depth = olddepth + ddelta
+ character.depth = olddepth + ddelta
end
end
if mathparameters then
diff --git a/tex/context/base/mkiv/font-nod.lua b/tex/context/base/mkiv/font-nod.lua
index cdceb98a2..b98534f38 100644
--- a/tex/context/base/mkiv/font-nod.lua
+++ b/tex/context/base/mkiv/font-nod.lua
@@ -32,6 +32,10 @@ nodes.tasks = tasks
local handlers = nodes.handlers or { }
nodes.handlers = handlers
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+
local injections = nodes.injections or { }
nodes.injections = injections
@@ -52,10 +56,6 @@ local kern_code = nodecodes.kern
local dir_code = nodecodes.dir
local localpar_code = nodecodes.localpar
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
-
local getfield = nuts.getfield
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -78,9 +78,11 @@ local setsubtype = nuts.setsubtype
local copy_node_list = nuts.copy_list
local hpack_node_list = nuts.hpack
local flush_node_list = nuts.flush_list
-local traverse_nodes = nuts.traverse
local protect_glyphs = nuts.protect_glyphs
+local nextnode = nuts.traversers.node
+local nextglyph = nuts.traversers.glyph
+
local nodepool = nuts.pool
local new_glyph = nodepool.glyph
@@ -101,7 +103,7 @@ local properties = nodes.properties.data
-- direct.set_properties_mode(true,true) -- default
local function freeze(h,where)
- for n in traverse_nodes(tonut(h)) do -- todo: disc but not traced anyway
+ for n in nextnode, h do -- todo: disc but not traced anyway
local p = properties[n]
if p then
local i = p.injections if i then p.injections = fastcopy(i) end
@@ -114,7 +116,6 @@ local function freeze(h,where)
end
function char_tracers.collect(head,list,tag,n)
- head = tonut(head)
n = n or 0
local ok, fn = false, nil
while head do
@@ -137,17 +138,17 @@ function char_tracers.collect(head,list,tag,n)
-- skip
-- local pre, post, replace = getdisc(head)
-- if replace then
- -- for n in traverse_id(glyph_code,replace) do
+ -- for n in nextglyph, replace do
-- l[#l+1] = { c, f }
-- end
-- end
-- if pre then
- -- for n in traverse_id(glyph_code,pre) do
+ -- for n in nextglyph, pre do
-- l[#l+1] = { c, f }
-- end
-- end
-- if post then
- -- for n in traverse_id(glyph_code,post) do
+ -- for n in nextglyph, post do
-- l[#l+1] = { c, f }
-- end
-- end
@@ -220,12 +221,12 @@ function char_tracers.start()
function handlers.characters(head)
local n = #list
char_tracers.collect(head,list,'before',n)
- local h, d = npc(tonode(head)) -- for the moment tonode
+ head = npc(head) -- for the moment tonode
char_tracers.collect(head,list,'after',n)
if #list > n then
list[#list+1] = { }
end
- return h, d
+ return head
end
function char_tracers.stop()
tracers.list['characters'] = list
@@ -391,7 +392,7 @@ function step_tracers.codes(i,command,space)
if w then
context.startcolor(colors[what])
context("%s:",what)
- for c, id in traverse_nodes(w) do
+ for c, id in nextnode, w do
if id == glyph_code then
showchar(c)
else
@@ -408,7 +409,7 @@ function step_tracers.codes(i,command,space)
if id == glyph_code then
showchar(c)
elseif id == dir_code or id == localpar_code then
- context("[%s]",getdir(c))
+ context("[%s]",getdir(c) or "unset")
elseif id == disc_code then
local pre, post, replace = getdisc(c)
if pre or post or replace then
@@ -451,13 +452,12 @@ end
function step_tracers.check(head)
if collecting then
step_tracers.reset()
- local h = tonut(head)
- local n = copy_node_list(h)
+ local n = copy_node_list(head)
freeze(n,"check")
- injections.keepcounts(n) -- one-time
+ injections.keepcounts() -- one-time
local l = injections.handler(n,"trace")
if l then -- hm, can be false
- n = tonut(l)
+ n = l
end
protect_glyphs(n)
collection[1] = n
@@ -468,13 +468,12 @@ function step_tracers.register(head)
if collecting then
local nc = #collection+1
if messages[nc] then
- local h = tonut(head)
- local n = copy_node_list(h)
+ local n = copy_node_list(head)
freeze(n,"register")
- injections.keepcounts(n) -- one-time
+ injections.keepcounts() -- one-time
local l = injections.handler(n,"trace")
if l then -- hm, can be false
- n = tonut(l)
+ n = l
end
protect_glyphs(n)
collection[nc] = n
@@ -499,10 +498,7 @@ local threshold = 65536 -- 1pt
local function toutf(list,result,nofresult,stopcriterium,nostrip)
if list then
--- for n in traverse_nodes(tonut(list)) do
--- local c, id = isglyph(n)
--- if c then
- for n, id in traverse_nodes(tonut(list)) do
+ for n, id in nextnode, tonut(list) do
if id == glyph_code then
local c = getchar(n)
local components = getcomponents(n)
diff --git a/tex/context/base/mkiv/font-osd.lua b/tex/context/base/mkiv/font-osd.lua
index 51f644ad1..32d791b48 100644
--- a/tex/context/base/mkiv/font-osd.lua
+++ b/tex/context/base/mkiv/font-osd.lua
@@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['font-osd'] = { -- script devanag
license = "see context related readme files"
}
+
+-- we need to check nbsphash (context only)
+
-- A few remarks:
--
-- This code is a partial rewrite of the code that deals with devanagari. The data
@@ -96,8 +99,6 @@ local otffeatures = fonts.constructors.features.otf
local registerotffeature = otffeatures.register
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -152,47 +153,27 @@ replace_all_nbsp = function(head) -- delayed definition
return replace_all_nbsp(head)
end
-local xprocesscharacters = nil
+local processcharacters = nil
if context then
- xprocesscharacters = function(head,font)
- xprocesscharacters = nodes.handlers.characters
- return xprocesscharacters(head,font)
+ local fontprocesses = fonts.hashes.processes
+ function processcharacters(head,font)
+ local processors = fontprocesses[font]
+ for i=1,#processors do
+ head = processors[i](head,font,0)
+ end
+ return head
end
else
- xprocesscharacters = function(head,font)
- xprocesscharacters = nodes.handlers.nodepass -- generic
- return xprocesscharacters(head,font)
+ function processcharacters(head,font)
+ local processors = fontdata[font].shared.processes
+ for i=1,#processors do
+ head = processors[i](head,font,0)
+ end
+ return head
end
end
-local function processcharacters(head,font)
- return tonut(xprocesscharacters(tonode(head))) -- can be more efficient in context, just direct call
-end
-
--- to be tested:
---
--- local processcharacters = nil
---
--- if context then
--- local fontprocesses = fonts.hashes.processes
--- function processcharacters(head,font)
--- local processors = fontprocesses[font]
--- for i=1,#processors do
--- head = processors[i](head,font,0)
--- end
--- return head, true
--- end
--- else
--- function processcharacters(head,font)
--- local processors = fontdata[font].shared.processes
--- for i=1,#processors do
--- head = processors[i](head,font,0)
--- end
--- return head, true
--- end
--- end
-
-- We can assume that script are not mixed in the source but if that is the case
-- we might need to have consonants etc per script and initialize a local table
-- pointing to the right one. But not now.
@@ -2067,7 +2048,6 @@ end
-- a lot. Common code has been synced.
local function method_one(head,font,attr)
- head = tonut(head)
local current = head
local start = true
local done = false
@@ -2262,14 +2242,13 @@ local function method_one(head,font,attr)
head = replace_all_nbsp(head)
end
- return tonode(head), done
+ return head, done
end
-- there is a good change that when we run into one with subtype < 256 that the rest is also done
-- so maybe we can omit this check (it's pretty hard to get glyphs in the stream out of the blue)
local function method_two(head,font,attr)
- head = tonut(head)
local current = head
local start = true
local done = false
@@ -2358,7 +2337,7 @@ local function method_two(head,font,attr)
head = replace_all_nbsp(head)
end
- return tonode(head), done
+ return head, done
end
for i=1,nofscripts do
diff --git a/tex/context/base/mkiv/font-ota.lua b/tex/context/base/mkiv/font-ota.lua
index de626c120..fd58a6e43 100644
--- a/tex/context/base/mkiv/font-ota.lua
+++ b/tex/context/base/mkiv/font-ota.lua
@@ -42,7 +42,6 @@ local getsubtype = nuts.getsubtype
local getchar = nuts.getchar
local ischar = nuts.is_char
-local traverse_id = nuts.traverse_id
local end_of_math = nuts.end_of_math
local nodecodes = nodes.nodecodes
diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua
index a728163ce..8d1b540be 100644
--- a/tex/context/base/mkiv/font-otj.lua
+++ b/tex/context/base/mkiv/font-otj.lua
@@ -97,8 +97,11 @@ local setlink = nuts.setlink
local setwidth = nuts.setwidth
local getwidth = nuts.getwidth
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextchar = nuts.traversers.char
+local nextglue = nuts.traversers.glue
+
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
@@ -562,7 +565,7 @@ end
local function showsub(n,what,where)
report_injections("begin subrun: %s",where)
- for n in traverse_char(n) do
+ for n in nextchar, n do
showchar(n,where)
show(n,what,where," ")
end
@@ -632,7 +635,6 @@ end
-- +D-replace +D-replace
local function inject_kerns_only(head,where)
- head = tonut(head)
if trace_injections then
trace(head,"kerns")
end
@@ -708,7 +710,7 @@ local function inject_kerns_only(head,where)
local done = false
if pre then
-- left|pre glyphs|right
- for n in traverse_char(pre) do
+ for n in nextchar, pre do
local p = rawget(properties,n)
if p then
local i = p.injections or p.preinjections
@@ -724,7 +726,7 @@ local function inject_kerns_only(head,where)
end
if post then
-- left|post glyphs|right
- for n in traverse_char(post) do
+ for n in nextchar, post do
local p = rawget(properties,n)
if p then
local i = p.injections or p.postinjections
@@ -740,7 +742,7 @@ local function inject_kerns_only(head,where)
end
if replace then
-- left|replace glyphs|right
- for n in traverse_char(replace) do
+ for n in nextchar, replace do
local p = rawget(properties,n)
if p then
local i = p.injections or p.replaceinjections
@@ -775,11 +777,10 @@ local function inject_kerns_only(head,where)
if trace_injections then
show_result(head)
end
- return tonode(head), true
+ return head
end
local function inject_positions_only(head,where)
- head = tonut(head)
if trace_injections then
trace(head,"positions")
end
@@ -882,7 +883,7 @@ local function inject_positions_only(head,where)
local done = false
if pre then
-- left|pre glyphs|right
- for n in traverse_char(pre) do
+ for n in nextchar, pre do
local p = rawget(properties,n)
if p then
local i = p.injections or p.preinjections
@@ -907,7 +908,7 @@ local function inject_positions_only(head,where)
end
if post then
-- left|post glyphs|right
- for n in traverse_char(post) do
+ for n in nextchar, post do
local p = rawget(properties,n)
if p then
local i = p.injections or p.postinjections
@@ -932,7 +933,7 @@ local function inject_positions_only(head,where)
end
if replace then
-- left|replace glyphs|right
- for n in traverse_char(replace) do
+ for n in nextchar, replace do
local p = rawget(properties,n)
if p then
local i = p.injections or p.replaceinjections
@@ -1006,7 +1007,7 @@ local function inject_positions_only(head,where)
if trace_injections then
show_result(head)
end
- return tonode(head), true
+ return head
end
local function showoffset(n,flag)
@@ -1017,7 +1018,6 @@ local function showoffset(n,flag)
end
local function inject_everything(head,where)
- head = tonut(head)
if trace_injections then
trace(head,"everything")
end
@@ -1348,7 +1348,7 @@ local function inject_everything(head,where)
local done = false
if pre then
-- left|pre glyphs|right
- for n in traverse_char(pre) do
+ for n in nextchar, pre do
local p = rawget(properties,n)
if p then
local i = p.injections or p.preinjections
@@ -1379,7 +1379,7 @@ local function inject_everything(head,where)
end
if post then
-- left|post glyphs|right
- for n in traverse_char(post) do
+ for n in nextchar, post do
local p = rawget(properties,n)
if p then
local i = p.injections or p.postinjections
@@ -1410,7 +1410,7 @@ local function inject_everything(head,where)
end
if replace then
-- left|replace glyphs|right
- for n in traverse_char(replace) do
+ for n in nextchar, replace do
local p = rawget(properties,n)
if p then
local i = p.injections or p.replaceinjections
@@ -1518,7 +1518,7 @@ local function inject_everything(head,where)
if trace_injections then
show_result(head)
end
- return tonode(head), true
+ return head
end
-- space triggers
@@ -1607,7 +1607,7 @@ end
local function injectspaces(head)
if not triggers then
- return head, false
+ return head
end
local lastfont = nil
local spacekerns = nil
@@ -1617,7 +1617,6 @@ local function injectspaces(head)
local threshold = 0
local leftkern = false
local rightkern = false
- local nuthead = tonut(head)
local function updatefont(font,trig)
leftkerns = trig.left
@@ -1627,7 +1626,7 @@ local function injectspaces(head)
factor = getthreshold(font)
end
- for n in traverse_id(glue_code,nuthead) do
+ for n in nextglue, head do
local prev, next = getspaceboth(n)
local prevchar = prev and ischar(prev)
local nextchar = next and ischar(next)
@@ -1665,12 +1664,8 @@ local function injectspaces(head)
if trace_spaces then
report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
end
- local h = insert_node_before(nuthead,n,italickern(lnew))
- if h == nuthead then
- head = tonode(h)
- nuthead = h
- end
- insert_node_after(nuthead,n,italickern(rnew))
+ head = insert_node_before(head,n,italickern(lnew))
+ insert_node_after(head,n,italickern(rnew))
else
local new = old + (leftkern + rightkern) * factor
if trace_spaces then
@@ -1685,7 +1680,7 @@ local function injectspaces(head)
if trace_spaces then
report_spaces("%C [%p + %p]",prevchar,old,new)
end
- insert_node_after(nuthead,n,italickern(new)) -- tricky with traverse but ok
+ insert_node_after(head,n,italickern(new)) -- tricky with traverse but ok
else
local new = old + leftkern * factor
if trace_spaces then
@@ -1704,7 +1699,7 @@ local function injectspaces(head)
if trace_spaces then
report_spaces("%C [%p + %p]",nextchar,old,new)
end
- insert_node_after(nuthead,n,italickern(new))
+ insert_node_after(head,n,italickern(new))
else
local new = old + rightkern * factor
if trace_spaces then
@@ -1718,7 +1713,8 @@ local function injectspaces(head)
end
triggers = false
- return head, true
+
+ return head
end
--
@@ -1744,6 +1740,6 @@ function injections.handler(head,where)
end
return inject_kerns_only(head,where)
else
- return head, false
+ return head
end
end
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index ac50ad00e..faee293f6 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -176,8 +176,6 @@ registertracker("otf.sample", "otf.steps","otf.substitutions","otf.positi
registertracker("otf.sample.silent", "otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing")
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
local getfield = nuts.getfield
local getnext = nuts.getnext
@@ -215,7 +213,7 @@ local find_node_tail = nuts.tail
local flush_node_list = nuts.flush_list
local flush_node = nuts.flush_node
local end_of_math = nuts.end_of_math
-local traverse_nodes = nuts.traverse
+----- traverse_nodes = nuts.traverse
----- traverse_id = nuts.traverse_id
local set_components = nuts.set_components
local take_components = nuts.take_components
@@ -226,6 +224,8 @@ local copy_only_glyphs = nuts.copy_only_glyphs
local setmetatable = setmetatable
local setmetatableindex = table.setmetatableindex
+local nextnode = nuts.traversers.node
+
----- zwnj = 0x200C
----- zwj = 0x200D
@@ -3430,7 +3430,7 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase
a = getattr(sub,0)
end
if not a or (a == attr) then
- for n in traverse_nodes(sub) do -- only gpos
+ for n in nextnode, sub do -- only gpos
if n == last then
break
end
@@ -3595,7 +3595,7 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase
a = getattr(sub,0)
end
if not a or (a == attr) then
- for n in traverse_nodes(sub) do -- only gpos
+ for n in nextnode, sub do -- only gpos
if n == last then
break
end
@@ -3843,8 +3843,6 @@ do
-- attr = false
-- end
- local head = tonut(head)
-
if trace_steps then
checkstep(head)
end
@@ -3852,8 +3850,7 @@ do
local initialrl = direction == "TRT" and -1 or 0
-- local initialrl = (direction == 1 or direction == "TRT") and -1 or 0
- local done = false
- -- local datasets = otf.dataset(tfmdata,font,attr)
+ -- local done = false
local datasets = otfdataset(tfmdata,font,attr)
local dirstack = { } -- could move outside function but we can have local runs
sweephead = { }
@@ -3883,9 +3880,9 @@ do
-- are not frozen as we might extend or change this. Is this used at all apart from some
-- experiments?
local h, ok = handler(head,dataset,sequence,initialrl,font,attr) -- less arguments now
- if ok then
- done = true
- end
+ -- if ok then
+ -- done = true
+ -- end
if h and h ~= head then
head = h
end
@@ -3918,7 +3915,7 @@ do
local ok
head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
if ok then
- done = true
+ -- done = true
break
end
end
@@ -3961,9 +3958,9 @@ do
if a then
local ok
head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if ok then
- done = true
- end
+ -- if ok then
+ -- done = true
+ -- end
if start then
start = getnext(start)
end
@@ -3987,9 +3984,9 @@ do
else
start, ok = comprun(start,c_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
end
- if ok then
- done = true
- end
+ -- if ok then
+ -- done = true
+ -- end
else
start = getnext(start)
end
@@ -4033,7 +4030,7 @@ do
local ok
head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
if ok then
- done = true
+ -- done = true
break
elseif not start then
-- don't ask why ... shouldn't happen
@@ -4064,9 +4061,9 @@ do
else
start, ok = comprun(start,c_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
end
- if ok then
- done = true
- end
+ -- if ok then
+ -- done = true
+ -- end
else
start = getnext(start)
end
@@ -4090,12 +4087,12 @@ do
end
nesting = nesting - 1
- head = tonode(head)
- return head, done
+ -- return head, done
+ return head
end
- -- This is not an official helpoer and used for tracing experiments. It can be changed as I like
+ -- This is not an official helper and used for tracing experiments. It can be changed as I like
-- at any moment. At some point it might be used in a module that can help font development.
function otf.datasetpositionprocessor(head,font,direction,dataset)
@@ -4129,7 +4126,6 @@ do
local steps = sequence.steps
local nofsteps = sequence.nofsteps
- local head = tonut(head)
local done = false
local dirstack = { } -- could move outside function but we can have local runs
local start = head
@@ -4192,7 +4188,7 @@ do
end
end
- return tonode(head) -- , matches
+ return head
end
-- end of experiment
diff --git a/tex/context/base/mkiv/font-sol.lua b/tex/context/base/mkiv/font-sol.lua
index 8967d88e6..73f7252d1 100644
--- a/tex/context/base/mkiv/font-sol.lua
+++ b/tex/context/base/mkiv/font-sol.lua
@@ -54,8 +54,6 @@ local settings_to_hash = utilities.parsers.settings_to_hash
local tasks = nodes.tasks
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getfield = nuts.getfield
local getnext = nuts.getnext
@@ -78,13 +76,15 @@ local find_node_tail = nuts.tail
local flush_node = nuts.flush_node
local flush_node_list = nuts.flush_list
local copy_node_list = nuts.copy_list
-local traverse_nodes = nuts.traverse
-local traverse_ids = nuts.traverse_id
local hpack_nodes = nuts.hpack
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local protect_glyphs = nuts.protect_glyphs
+local nextnode = nuts.traversers.next
+local nexthlist = nuts.traversers.hlist
+local nextwhatsit = nuts.traversers.whatsit
+
local repack_hlist = nuts.repackhlist
local nodes_to_utf = nodes.listtoutf
@@ -237,7 +237,6 @@ local function convert(featuresets,name,list)
fs = contextsetups[feature]
fn = fs and fs.number
end
--- inspect(fs)
if fn then
nofnumbers = nofnumbers + 1
numbers[nofnumbers] = fn
@@ -345,9 +344,7 @@ directives.register("builders.paragraphs.solutions.splitters.encapsulate", funct
end)
function splitters.split(head)
- -- quite fast
- head = tonut(head)
- local current, done, rlmode, start, stop, attribute = head, false, false, nil, nil, 0
+ local current, rlmode, start, stop, attribute = head, false, nil, nil, 0
cache, max_less, max_more = { }, 0, 0
local function flush() -- we can move this
local font = getfont(start)
@@ -393,7 +390,7 @@ function splitters.split(head)
local m = #solution.more
if l > max_less then max_less = l end
if m > max_more then max_more = m end
- start, stop, done = nil, nil, true
+ start, stop = nil, nil
end
while current do -- also ischar
local next = getnext(current)
@@ -439,14 +436,14 @@ function splitters.split(head)
end
nofparagraphs = nofparagraphs + 1
nofwords = nofwords + #cache
- return tonode(head), done
+ return head
end
local function collect_words(list) -- can be made faster for attributes
local words, w, word = { }, 0, nil
if encapsulate then
- for current in traverse_ids(whatsit_code,list) do
- if getsubtype(current) == userdefined_code then -- hm
+ for current, subtype in nextwhatsit, list do
+ if subtype == userdefined_code then -- hm
local user_id = getfield(current,"user_id")
if user_id == splitter_one then
word = { getfield(current,"value"), current, current }
@@ -584,21 +581,20 @@ local function doit(word,list,best,width,badness,line,set,listdir)
noftries = noftries + 1
local first = copy_node_list(original)
if not trace_colors then
- for n in traverse_nodes(first) do -- maybe fast force so no attr needed
+ for n in nextnode, first do -- maybe fast force so no attr needed
setattr(n,0,featurenumber) -- this forces dynamics
end
elseif set == "less" then
- for n in traverse_nodes(first) do
+ for n in nextnode, first do
setnodecolor(n,"font:isol") -- yellow
setattr(n,0,featurenumber)
end
else
- for n in traverse_nodes(first) do
+ for n in nextnode, first do
setnodecolor(n,"font:medi") -- green
setattr(n,0,featurenumber)
end
end
-first = tonode(first)
local font = found.font
local setdynamics = setfontdynamics[font]
if setdynamics then
@@ -610,7 +606,6 @@ first = tonode(first)
report_solutions("fatal error, no dynamics for font %a",font)
end
first = inject_kerns(first)
-first = tonut(first)
if getid(first) == whatsit_code then
local temp = first
first = getnext(first)
@@ -753,7 +748,7 @@ function splitters.optimize(head)
if trace_optimize then
report_optimizers("preroll %a, variant %a, criterium %a, cache size %a",preroll,variant,criterium,nc)
end
- for current in traverse_ids(hlist_code,tonut(head)) do
+ for current in nexthlist, head do
line = line + 1
local sign = getfield(current,"glue_sign")
local dir = getdir(current)
diff --git a/tex/context/base/mkiv/font-vfc.lua b/tex/context/base/mkiv/font-vfc.lua
index cac225de6..3e48422d6 100644
--- a/tex/context/base/mkiv/font-vfc.lua
+++ b/tex/context/base/mkiv/font-vfc.lua
@@ -50,7 +50,8 @@ end
-- todo: maybe indirect so that we can't change them
local char = setmetatableindex(function(t,k)
- local v = { "char", k }
+ -- local v = { "char", k }
+ local v = { "slot", 0, k }
t[k] = v
return v
end)
diff --git a/tex/context/base/mkiv/good-ctx.lua b/tex/context/base/mkiv/good-ctx.lua
index 00e4ed78d..c4c632ae9 100644
--- a/tex/context/base/mkiv/good-ctx.lua
+++ b/tex/context/base/mkiv/good-ctx.lua
@@ -29,14 +29,13 @@ local registerotffeature = fonts.handlers.otf.features.register
local fontgoodies = fonts.goodies or { }
-local glyph_code = nodes.nodecodes.glyph
-
local nuts = nodes.nuts
local tonut = nuts.tonut
local getfont = nuts.getfont
local getchar = nuts.getchar
local getattr = nuts.getattr
-local traverse_id = nuts.traverse_id
+
+local nextglyph = nuts.traversers.glyph
-- colorschemes
@@ -128,68 +127,9 @@ local function setcolorscheme(tfmdata,scheme)
end
local fontproperties = fonts.hashes.properties
-
local a_colorscheme = attributes.private('colorscheme')
local setnodecolor = nodes.tracers.colors.set
-
--- function colorschemes.coloring(head)
--- local lastfont, lastscheme
--- local done = false
--- for n in traverse_id(glyph_code,tonut(head)) do
--- local a = getattr(n,a_colorscheme)
--- if a then
--- local f = getfont(n)
--- if f ~= lastfont then
--- lastscheme = fontproperties[f].colorscheme
--- lastfont = f
--- end
--- if lastscheme then
--- local sc = lastscheme[getchar(n)]
--- if sc then
--- done = true
--- setnodecolor(n,"colorscheme:"..a..":"..sc) -- slow
--- end
--- end
--- end
--- end
--- return head, done
--- end
-
--- seldom used, mostly in manuals, so non critical .. anyhow, somewhat faster:
-
--- function colorschemes.coloring(head)
--- local lastfont = nil
--- local lastattr = nil
--- local lastscheme = nil
--- local lastprefix = nil
--- local done = nil
--- for n in traverse_id(glyph_code,tonut(head)) do
--- local a = getattr(n,a_colorscheme)
--- if a then
--- if a ~= lastattr then
--- lastattr = a
--- lastprefix = "colorscheme:" .. a .. ":"
--- end
--- local f = getfont(n)
--- if f ~= lastfont then
--- lastfont = f
--- lastscheme = fontproperties[f].colorscheme
--- end
--- if lastscheme then
--- local sc = lastscheme[getchar(n)]
--- if sc then
--- setnodecolor(n,lastprefix .. sc) -- slow
--- done = true
--- end
--- end
--- end
--- end
--- return head, done
--- end
-
--- ok, in case we have hundreds of pages colored:
-
-local cache = { } -- this could be a weak table
+local cache = { } -- this could be a weak table
setmetatableindex(cache,function(t,a)
local v = { }
@@ -207,8 +147,7 @@ function colorschemes.coloring(head)
local lastattr = nil
local lastcache = nil
local lastscheme = nil
- local done = nil
- for n in traverse_id(glyph_code,tonut(head)) do
+ for n in nextglyph, head do
local a = getattr(n,a_colorscheme)
if a then
local f = getfont(n)
@@ -224,16 +163,46 @@ function colorschemes.coloring(head)
local sc = lastscheme[getchar(n)]
if sc then
setnodecolor(n,lastcache[sc]) -- we could inline this one
- done = true
end
end
end
end
- return head, done
+ return head
+end
+
+if LUATEXVERSION >= 1.090 then
+
+ function colorschemes.coloring(head)
+ local lastfont = nil
+ local lastattr = nil
+ local lastcache = nil
+ local lastscheme = nil
+ for n, f, char in nextglyph, head do
+ local a = getattr(n,a_colorscheme)
+ if a then
+ if f ~= lastfont then
+ lastfont = f
+ lastscheme = fontproperties[f].colorscheme
+ end
+ if a ~= lastattr then
+ lastattr = a
+ lastcache = cache[a]
+ end
+ if lastscheme then
+ local sc = lastscheme[char]
+ if sc then
+ setnodecolor(n,lastcache[sc]) -- we could inline this one
+ end
+ end
+ end
+ end
+ return head
+ end
+
end
function colorschemes.enable()
- nodes.tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring")
+ nodes.tasks.enableaction("processors","fonts.goodies.colorschemes.coloring")
function colorschemes.enable() end
end
diff --git a/tex/context/base/mkiv/grph-epd.lua b/tex/context/base/mkiv/grph-epd.lua
index 7855ce891..ae0358b36 100644
--- a/tex/context/base/mkiv/grph-epd.lua
+++ b/tex/context/base/mkiv/grph-epd.lua
@@ -8,18 +8,18 @@ if not modules then modules = { } end modules ['grph-epd'] = {
local variables = interfaces.variables
local settings_to_hash = utilities.parsers.settings_to_hash
+local codeinjections = backends.pdf.codeinjections
--- todo: page, name, file, url
+local trace = false trackers.register("figures.merging", function(v) trace = v end)
--- I have some experimental code for including comments and fields but it's
--- unfinished and not included as it was just a proof of concept to get some idea
--- about what is needed and possible. But the placeholders are here already.
-
-local codeinjections = backends.codeinjections
+local report = logs.reporter("backend","merging")
local function mergegoodies(optionlist)
local options = settings_to_hash(optionlist)
local all = options[variables.all] or options[variables.yes]
+ if next(options) then
+ report("% t",table.sortedkeys(options))
+ end
if all or options[variables.reference] then
codeinjections.mergereferences()
end
diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua
index f2d7847eb..87afb8683 100644
--- a/tex/context/base/mkiv/grph-inc.lua
+++ b/tex/context/base/mkiv/grph-inc.lua
@@ -1371,6 +1371,7 @@ function checkers.generic(data)
local conversion = dr.conversion
local resolution = dr.resolution
local arguments = dr.arguments
+ local scanimage = dr.scanimage or scanimage
if not conversion or conversion == "" then
conversion = "default"
end
@@ -1471,6 +1472,8 @@ function includers.generic(data)
-- width = dr.width,
-- height = dr.height,
-- }
+ local copyimage = dr.copyimage or copyimage
+ local cloneimage = dr.cloneimage or cloneimage
if figure == nil then
figure = ds.private
if figure then
@@ -2038,3 +2041,73 @@ implement {
end
end
}
+
+-- This is an experiment. The following method uses Lua to handle the embedding
+-- using the epdf library. This feature will be used when we make the transition
+-- from the pre 1.10 epdf library (using an unsuported low level poppler api) to a
+-- new (lightweight, small and statically compiled) library. More on that later.
+--
+-- The method implemented below has the same performance as the hard coded inclusion
+-- but opens up some possibilities (like merhing fonts) that I will look into some
+-- day.
+
+local function pdf_checker(data)
+ local request = data.request
+ local used = data.used
+ if request and used and not request.scanimage then
+ local openpdf = lpdf.epdf.image.open
+ ----- closepdf = lpdf.epdf.image.close
+ local querypdf = lpdf.epdf.image.query
+ local copypage = lpdf.epdf.image.copy
+ request.scanimage = function(t)
+ local pdfdoc = openpdf(t.filename)
+ if pdfdoc then
+ used.pdfdoc = pdfdoc
+ -- nofpages
+ end
+ local info = querypdf(pdfdoc,request.page)
+ local bbox = info.boundingbox
+ return {
+ filename = filename,
+ -- page = 1,
+ pages = pdfdoc.nofpages,
+ width = bbox[3] - bbox[1],
+ height = bbox[4] - bbox[2],
+ depth = 0,
+ colordepth = 0,
+ xres = 0,
+ yres = 0,
+ xsize = 0,
+ ysize = 0,
+ rotation = 0,
+ orientation = 0,
+ }
+ end
+ request.copyimage = function(t)
+ return copypage(used.pdfdoc,request.page)
+ end
+ end
+ return checkers.generic(data)
+end
+
+directives.register("graphics.pdf.uselua",function(v)
+ if v then
+ report("%s Lua based PDF inclusion","enabling")
+ checkers.pdf = pdf_checker
+ else
+ report("%s Lua based PDF inclusion","disabling")
+ checkers.pdf = nil
+ end
+end)
+
+-- directives.enable("graphics.pdf.uselua")
+--
+-- local filename = "luatex.pdf"
+--
+-- for i=1,240 do
+-- context(function()
+-- context.startTEXpage()
+-- context.externalfigure( { filename }, { page = i } )
+-- context.stopTEXpage()
+-- end)
+-- end
diff --git a/tex/context/base/mkiv/grph-pat.lua b/tex/context/base/mkiv/grph-pat.lua
index 89b29906d..1b5f1fd29 100644
--- a/tex/context/base/mkiv/grph-pat.lua
+++ b/tex/context/base/mkiv/grph-pat.lua
@@ -37,7 +37,7 @@ interfaces.implement {
if not name or name == "" then
return
end
- nodes.handlers.finalize(box,"object")
+ nodes.handlers.finalizebox(number)
names[name] = lpdf.registerpattern {
number = number,
width = specification.width or box.width,
diff --git a/tex/context/base/mkiv/l-table.lua b/tex/context/base/mkiv/l-table.lua
index 788d1511f..04c318792 100644
--- a/tex/context/base/mkiv/l-table.lua
+++ b/tex/context/base/mkiv/l-table.lua
@@ -1239,13 +1239,20 @@ end
local function sequenced(t,sep,simple)
if not t then
return ""
+ elseif type(t) == "string" then
+ return t -- handy fallback
end
local n = #t
local s = { }
if n > 0 then
-- indexed
for i=1,n do
- s[i] = tostring(t[i])
+ local v = t[i]
+ if type(v) == "table" then
+ s[i] = "{" .. sequenced(v,sep,simple) .. "}"
+ else
+ s[i] = tostring(t[i])
+ end
end
else
-- hashed
diff --git a/tex/context/base/mkiv/lang-dis.lua b/tex/context/base/mkiv/lang-dis.lua
index 65a53a702..1e46cbd36 100644
--- a/tex/context/base/mkiv/lang-dis.lua
+++ b/tex/context/base/mkiv/lang-dis.lua
@@ -17,9 +17,6 @@ local nuts = nodes.nuts
local enableaction = tasks.enableaction
local setaction = tasks.setaction
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
local setfield = nuts.setfield
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -40,10 +37,11 @@ local isglyph = nuts.isglyph
local copy_node = nuts.copy
local remove_node = nuts.remove
-local traverse_id = nuts.traverse_id
local flush_list = nuts.flush_list
local flush_node = nuts.flush_node
+local nextdisc = nuts.traversers.disc
+
local new_disc = nuts.pool.disc
local nodecodes = nodes.nodecodes
@@ -69,7 +67,7 @@ local check_regular = true
local setlistcolor = nodes.tracers.colors.setlist
function languages.visualizediscretionaries(head)
- for d in traverse_id(disc_code,tonut(head)) do
+ for d in nextdisc, head do
if getattr(d,a_visualize) then
local pre, post, replace = getdisc(d)
if pre then
@@ -83,6 +81,7 @@ function languages.visualizediscretionaries(head)
end
end
end
+ return head
end
local enabled = false
@@ -129,13 +128,9 @@ end
local wiped = 0
-local flatten_discretionaries = node.flatten_discretionaries -- todo in nodes
+local flatten_discretionaries = nuts.flatten_discretionaries -- todo in nodes
-if flatten_discretionaries then
-
- -- This is not that much faster than the lua variant simply because there is
- -- seldom a replace list but it fits in the picture. See luatex-todo.w for the
- -- code.
+-- if flatten_discretionaries then
function languages.flatten(head)
local h, n = flatten_discretionaries(head)
@@ -143,45 +138,44 @@ if flatten_discretionaries then
return h, n > 0
end
-else
-
- local function wipe(head,delayed)
- local p, n = getboth(delayed)
- local _, _, h, _, _, t = getdisc(delayed,true)
- if p or n then
- if h then
- setlink(p,h)
- setlink(t,n)
- setfield(delayed,"replace")
- else
- setlink(p,n)
- end
- end
- if head == delayed then
- head = h
- end
- wiped = wiped + 1
- flush_node(delayed)
- return head
- end
-
- function languages.flatten(head)
- local nuthead = tonut(head)
- local delayed = nil
- for d in traverse_id(disc_code,nuthead) do
- if delayed then
- nuthead = wipe(nuthead,delayed)
- end
- delayed = d
- end
- if delayed then
- return tonode(wipe(nuthead,delayed)), true
- else
- return head, false
- end
- end
-
-end
+-- else
+--
+-- local function wipe(head,delayed)
+-- local p, n = getboth(delayed)
+-- local _, _, h, _, _, t = getdisc(delayed,true)
+-- if p or n then
+-- if h then
+-- setlink(p,h)
+-- setlink(t,n)
+-- setfield(delayed,"replace")
+-- else
+-- setlink(p,n)
+-- end
+-- end
+-- if head == delayed then
+-- head = h
+-- end
+-- wiped = wiped + 1
+-- flush_node(delayed)
+-- return head
+-- end
+--
+-- function languages.flatten(head)
+-- local delayed = nil
+-- for d in nextdisc, head do
+-- if delayed then
+-- head = wipe(head,delayed)
+-- end
+-- delayed = d
+-- end
+-- if delayed then
+-- return wipe(head,delayed), true
+-- else
+-- return head, false
+-- end
+-- end
+--
+-- end
function languages.nofflattened()
return wiped -- handy for testing
@@ -198,7 +192,7 @@ function nodes.handlers.flatten(head,where)
if head and (where == "box" or where == "adjusted_hbox") then
return flatten(head)
end
- return true
+ return head
end
directives.register("hyphenator.flatten",function(v)
diff --git a/tex/context/base/mkiv/lang-exp.lua b/tex/context/base/mkiv/lang-exp.lua
index 70fad48b0..e7543c4de 100644
--- a/tex/context/base/mkiv/lang-exp.lua
+++ b/tex/context/base/mkiv/lang-exp.lua
@@ -172,23 +172,23 @@ languages.expanders = expanders
----- expand_explicit = expanders and expanders[explicit_code]
----- expand_automatic = expanders and expanders[automatic_code]
-if LUATEXVERSION < 1.005 then -- not loaded any more
-
- expanded = function(head)
- local done = hyphenate(head)
- if done then
- for d in traverse_id(disc_code,tonut(head)) do
- local s = getsubtype(d)
- if s ~= discretionary_code then
- expanders[s](d,template)
- done = true
- end
- end
- end
- return head, done
- end
-
-end
+-- if LUATEXVERSION < 1.005 then -- not loaded any more
+--
+-- expanded = function(head)
+-- local done = hyphenate(head)
+-- if done then
+-- for d in traverse_id(disc_code,head) do
+-- local s = getsubtype(d)
+-- if s ~= discretionary_code then
+-- expanders[s](d,template)
+-- done = true
+-- end
+-- end
+-- end
+-- return head, done
+-- end
+--
+-- end
-- if id == disc_code then
-- if expanded then
diff --git a/tex/context/base/mkiv/lang-hyp.lua b/tex/context/base/mkiv/lang-hyp.lua
index e29446b65..d01f8b581 100644
--- a/tex/context/base/mkiv/lang-hyp.lua
+++ b/tex/context/base/mkiv/lang-hyp.lua
@@ -632,7 +632,6 @@ if context then
local regular_code = disccodes.regular
local nuts = nodes.nuts
- local tonut = nodes.tonut
local tonode = nodes.tonode
local nodepool = nuts.pool
@@ -666,7 +665,9 @@ if context then
local remove_node = nuts.remove
local end_of_math = nuts.end_of_math
local node_tail = nuts.tail
- local traverse_id = nuts.traverse_id
+
+ local nexthlist = nuts.traversers.hlist
+ local nextdisc = nuts.traversers.disc
local setcolor = nodes.tracers.colors.set
@@ -1028,9 +1029,7 @@ featureset.hyphenonly = hyphenonly == v_yes
function traditional.hyphenate(head)
- local first = tonut(head)
-
-
+ local first = head
local tail = nil
local last = nil
local current = first
@@ -1585,7 +1584,7 @@ featureset.hyphenonly = hyphenonly == v_yes
stoptiming(traditional)
- return head, true
+ return head
end
statistics.register("hyphenation",function()
@@ -1619,8 +1618,8 @@ featureset.hyphenonly = hyphenonly == v_yes
local stack = { }
local function original(head)
- local done = hyphenate(head)
- return head, done
+ hyphenate(tonode(head))
+ return head
end
local getcount = tex.getcount
@@ -1637,13 +1636,13 @@ featureset.hyphenonly = hyphenonly == v_yes
forced = false
return usedmethod(head)
else
- return head, false
+ return head
end
else
return usedmethod(head)
end
else
- return head, false
+ return head
end
end
@@ -1729,13 +1728,12 @@ featureset.hyphenonly = hyphenonly == v_yes
}
function nodes.stripdiscretionaries(head)
- local h = tonut(head)
- for l in traverse_id(hlist_code,h) do
- for d in traverse_id(disc_code,getlist(l)) do
+ for l in nexthlist, head do
+ for d in nextdisc, getlist(l) do
remove_node(h,false,true)
end
end
- return tonode(h)
+ return head
end
diff --git a/tex/context/base/mkiv/lang-mis.mkiv b/tex/context/base/mkiv/lang-mis.mkiv
index eb7dc7d80..17149b37a 100644
--- a/tex/context/base/mkiv/lang-mis.mkiv
+++ b/tex/context/base/mkiv/lang-mis.mkiv
@@ -202,8 +202,8 @@
\setnewconstant\discretionarymode\plusone
-\unexpanded\def\ignorediscretionaries
- {\discretionarymode\zerocount}
+\unexpanded\def\ignorediscretionaries{\discretionarymode\zerocount}
+\unexpanded\def\obeydiscretionaries {\discretionarymode\plusone}
\def\lang_discretionaries_command
{% if direct if, we need \relax for lookahead in math mode
diff --git a/tex/context/base/mkiv/lang-rep.lua b/tex/context/base/mkiv/lang-rep.lua
index a5c4d97c8..93509d82a 100644
--- a/tex/context/base/mkiv/lang-rep.lua
+++ b/tex/context/base/mkiv/lang-rep.lua
@@ -42,8 +42,6 @@ local report_replacement = logs.reporter("languages","replacements")
local glyph_code = nodes.nodecodes.glyph
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -217,9 +215,7 @@ local function tonodes(list,template)
end
function replacements.handler(head)
- head = tonut(head)
local current = head
- local done = false
local overload = attributes.applyoverloads
while current do
if getid(current) == glyph_code then
@@ -327,14 +323,13 @@ function replacements.handler(head)
if overload then
overload(final,getnext(precurrent),getprev(current))
end
- done = true
end
end
end
-- we're one ahead now but we need to because we handle words
current = getnext(current)
end
- return tonode(head), done
+ return head
end
local enabled = false
diff --git a/tex/context/base/mkiv/lang-url.lua b/tex/context/base/mkiv/lang-url.lua
index 95d959206..17ad15cd8 100644
--- a/tex/context/base/mkiv/lang-url.lua
+++ b/tex/context/base/mkiv/lang-url.lua
@@ -8,7 +8,6 @@ if not modules then modules = { } end modules ['lang-url'] = {
local utfcharacters, utfvalues, utfbyte, utfchar = utf.characters, utf.values, utf.byte, utf.char
local min, max = math.min, math.max
-local concat = table.concat
local context = context
@@ -77,9 +76,10 @@ urls.righthyphenmin = 3
urls.discretionary = nil
urls.packslashes = false
-directives.register("hyphenators.urls.packslashes",function(v)
- urls.packslashes = v
-end)
+directives.register("hyphenators.urls.packslashes",function(v) urls.packslashes = v end)
+
+local trace = false trackers.register("hyphenators.urls",function(v) trace = v end)
+local report = logs.reporter("hyphenators","urls")
-- local ctx_a = context.a
-- local ctx_b = context.b
@@ -153,8 +153,10 @@ local function action(hyphenatedurl,str,left,right,disc)
local pack = urls.packslashes
local length = 0
local list = utf.split(str)
+ local size = #list
+ local prev = nil
- for i=1,#list do
+ for i=1,size do
local what = nil
local dodi = false
local char = list[i]
@@ -162,7 +164,7 @@ local function action(hyphenatedurl,str,left,right,disc)
char = mapping[char] or char
if char == disc then
dodi = true
- elseif pack and char == "/" and list[i+1] == "/" then
+ elseif pack and char == "/" and (list[i+1] == "/" or prev == "/") then
what = "c"
else
local how = characters[char]
@@ -192,9 +194,13 @@ local function action(hyphenatedurl,str,left,right,disc)
else
list[i] = "\\" .. what .. "{" .. utfbyte(char) .. "}"
end
+ prev = char
+ end
+ if trace then
+ report("old : %s",str)
+ report("new : %t",list)
end
- list = concat(list)
- context(list)
+ context("%t",list)
end
-- urls.action = function(_,...) action(...) end -- sort of obsolete
diff --git a/tex/context/base/mkiv/lang-wrd.lua b/tex/context/base/mkiv/lang-wrd.lua
index 7363dbb31..9fbced2ce 100644
--- a/tex/context/base/mkiv/lang-wrd.lua
+++ b/tex/context/base/mkiv/lang-wrd.lua
@@ -31,7 +31,6 @@ local numbers = languages.numbers
local registered = languages.registered
local nuts = nodes.nuts
-local tonut = nuts.tonut
----- getfield = nuts.getfield
local getnext = nuts.getnext
@@ -43,8 +42,8 @@ local setattr = nuts.setattr
local getlang = nuts.getlang
local ischar = nuts.ischar
-local traverse_nodes = nuts.traverse
------ traverse_ids = nuts.traverse_id
+local nextnode = nuts.traversers.node
+----- nextglyph = nuts.traversers.glyph
local wordsdata = words.data
local chardata = characters.data
@@ -145,14 +144,13 @@ end
-- there is an n=1 problem somewhere in nested boxes
local function mark_words(head,whenfound) -- can be optimized and shared
- local current, language, done = tonut(head), nil, nil, 0, false
+ local current, language = head, nil, nil, 0
local str, s, nds, n = { }, 0, { }, 0 -- n could also be a table, saves calls
local function action()
if s > 0 then
local word = concat(str,"",1,s)
local mark = whenfound(language,word)
if mark then
- done = true
for i=1,n do
mark(nds[i])
end
@@ -198,7 +196,7 @@ local function mark_words(head,whenfound) -- can be optimized and shared
-- n = n + 1
-- nds[n] = current
-- --
- -- for current in traverse_ids(glyph_code,r) do
+ -- for current in nextglyph, r do
-- local code = getchar(current)
-- n = n + 1
-- nds[n] = current
@@ -217,7 +215,7 @@ local function mark_words(head,whenfound) -- can be optimized and shared
if s > 0 then
action()
end
- return head, done
+ return head
end
local methods = { }
@@ -285,7 +283,7 @@ local function sweep(language,str)
end
methods[1] = function(head)
- for n in traverse_nodes(head) do
+ for n in nextnode, head do
setattr(n,a_color,unsetvalue) -- hm, not that selective (reset color)
end
return mark_words(head,sweep)
@@ -380,7 +378,7 @@ local function sweep(language,str)
end
methods[3] = function(head)
- for n in traverse_nodes(head) do
+ for n in nextnode, head do
setattr(n,a_color,unsetvalue)
end
return mark_words(head,sweep)
diff --git a/tex/context/base/mkiv/lpdf-ano.lua b/tex/context/base/mkiv/lpdf-ano.lua
index 3a86b22ca..9fdb0913c 100644
--- a/tex/context/base/mkiv/lpdf-ano.lua
+++ b/tex/context/base/mkiv/lpdf-ano.lua
@@ -253,6 +253,9 @@ end)
local function pdfnametree(destinations)
local slices = { }
checkautoprefixes(destinations)
+ if not next(destinations) then
+ return
+ end
local sorted = table.sortedkeys(destinations)
local size = #sorted
@@ -285,18 +288,22 @@ local function pdfnametree(destinations)
}
end
local function collectkids(slices,first,last)
- local k = pdfarray()
- local d = pdfdictionary {
- Kids = k,
- Limits = pdfarray {
- slices[first].limits[1],
- slices[last ].limits[2],
- },
- }
- for i=first,last do
- k[#k+1] = slices[i].reference
+ local f = slices[first]
+ local l = slices[last]
+ if f and l then
+ local k = pdfarray()
+ local d = pdfdictionary {
+ Kids = k,
+ Limits = pdfarray {
+ f.limits[1],
+ l.limits[2],
+ },
+ }
+ for i=first,last do
+ k[#k+1] = slices[i].reference
+ end
+ return d
end
- return d
end
if #slices == 1 then
return slices[1].reference
@@ -307,14 +314,24 @@ local function pdfnametree(destinations)
local size = #slices
for i=1,size,maxslice do
local kids = collectkids(slices,i,min(i+maxslice-1,size))
- temp[#temp+1] = {
- reference = pdfreference(pdfflushobject(kids)),
- limits = kids.Limits,
- }
+ if kids then
+ temp[#temp+1] = {
+ reference = pdfreference(pdfflushobject(kids)),
+ limits = kids.Limits,
+ }
+ else
+ -- error
+ end
end
slices = temp
else
- return pdfreference(pdfflushobject(collectkids(slices,1,#slices)))
+ local kids = collectkids(slices,1,#slices)
+ if kids then
+ return pdfreference(pdfflushobject(kids))
+ else
+ -- error
+ return
+ end
end
end
end
@@ -323,7 +340,9 @@ end
local function pdfdestinationspecification()
if next(destinations) then -- safeguard
local r = pdfnametree(destinations)
- pdfaddtonames("Dests",r)
+ if r then
+ pdfaddtonames("Dests",r)
+ end
if not log_destinations then
destinations = nil
end
@@ -786,7 +805,9 @@ pdfregisterannotation = lpdf.registerannotation
function lpdf.annotationspecification()
if annotations then
local r = pdfdelayedobject(tostring(annotations)) -- delayed so okay in latelua
- pdfaddtopageattributes("Annots",pdfreference(r))
+ if r then
+ pdfaddtopageattributes("Annots",pdfreference(r))
+ end
annotations = nil
end
end
@@ -1179,11 +1200,12 @@ local function build(levels,start,parent,method,nested)
local variant = "unknown"
if reftype == "table" then
-- we're okay
- variant = "list"
- block = reference.block
+ variant = "list"
+ block = reference.block
+ realpage = reference.realpage
elseif reftype == "string" then
local resolved = references.identify("",reference)
- local realpage = resolved and structures.references.setreferencerealpage(resolved) or 0
+ realpage = resolved and structures.references.setreferencerealpage(resolved) or 0
if realpage > 0 then
variant = "realpage"
realpage = realpage
@@ -1284,7 +1306,6 @@ end
function codeinjections.addbookmarks(levels,method)
if levels and #levels > 0 then
--- inspect(levels)
local parent = pdfreserveobject()
local _, m, first, last = build(levels,1,pdfreference(parent),method or "internal",false)
local dict = pdfdictionary {
diff --git a/tex/context/base/mkiv/lpdf-epa.lua b/tex/context/base/mkiv/lpdf-epa.lua
index 89b2c6e0e..ee3b6d43d 100644
--- a/tex/context/base/mkiv/lpdf-epa.lua
+++ b/tex/context/base/mkiv/lpdf-epa.lua
@@ -6,47 +6,72 @@ if not modules then modules = { } end modules ['lpdf-epa'] = {
license = "see context related readme files"
}
--- This is a rather experimental feature and the code will probably change.
+-- Links can also have quadpoint
-local type, tonumber = type, tonumber
-local format, gsub, lower = string.format, string.gsub, string.lower
+local type, tonumber, next = type, tonumber, next
+local format, gsub, lower, find = string.format, string.gsub, string.lower, string.find
local formatters = string.formatters
+local concat, merged = table.concat, table.merged
local abs = math.abs
local expandname = file.expandname
local allocate = utilities.storage.allocate
+local bor, band = bit32.bor, bit32.band
local isfile = lfs.isfile
------ lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local trace_links = false trackers.register("figures.links", function(v) trace_links = v end)
+local trace_comments = false trackers.register("figures.comments", function(v) trace_comments = v end)
+local trace_fields = false trackers.register("figures.fields", function(v) trace_fields = v end)
+local trace_outlines = false trackers.register("figures.outlines", function(v) trace_outlines = v end)
-local trace_links = false trackers.register("figures.links", function(v) trace_links = v end)
-local trace_outlines = false trackers.register("figures.outliness", function(v) trace_outlines = v end)
+local report_link = logs.reporter("backend","link")
+local report_comment = logs.reporter("backend","comment")
+local report_field = logs.reporter("backend","field")
+local report_outline = logs.reporter("backend","outline")
-local report_link = logs.reporter("backend","link")
-local report_comment = logs.reporter("backend","comment")
-local report_field = logs.reporter("backend","field")
-local report_outline = logs.reporter("backend","outline")
+local nodeinjections = backends.pdf.nodeinjections
-local epdf = epdf
-local backends = backends
-local lpdf = lpdf
-local context = context
+local pdfarray = lpdf.array
+local pdfdictionary = lpdf.dictionary
+local pdfconstant = lpdf.constant
+local pdfreserveobject = lpdf.reserveobject
+local pdfreference = lpdf.reference
-local loadpdffile = lpdf.epdf.load
+local pdfcopyboolean = lpdf.copyboolean
+local pdfcopyunicode = lpdf.copyunicode
+local pdfcopyarray = lpdf.copyarray
+local pdfcopydictionary = lpdf.copydictionary
+local pdfcopynumber = lpdf.copynumber
+local pdfcopyinteger = lpdf.copyinteger
+local pdfcopystring = lpdf.copystring
+local pdfcopyconstant = lpdf.copyconstant
-local nameonly = file.nameonly
+local pdfgetpos = lpdf.getpos
-local variables = interfaces.variables
-local codeinjections = backends.pdf.codeinjections
------ urlescaper = lpegpatterns.urlescaper
------ utftohigh = lpegpatterns.utftohigh
-local escapetex = characters.filters.utf.private.escape
+local hpack_node = nodes.hpack
-local bookmarks = structures.bookmarks
+local epdf = epdf
+local backends = backends
+local lpdf = lpdf
+local context = context
-local maxdimen = 0x3FFFFFFF -- 2^30-1
+local loadpdffile = lpdf.epdf.load
+
+local nameonly = file.nameonly
+
+local variables = interfaces.variables
+local codeinjections = backends.pdf.codeinjections
+----- urlescaper = lpegpatterns.urlescaper
+----- utftohigh = lpegpatterns.utftohigh
+local escapetex = characters.filters.utf.private.escape
+
+local bookmarks = structures.bookmarks
+
+local maxdimen = 0x3FFFFFFF -- 2^30-1
+
+local bpfactor = number.dimenfactors.bp
local layerspec = { -- predefining saves time
- "epdflinks"
+ "epdfcontent"
}
local collected = allocate()
@@ -66,6 +91,68 @@ end
job.register('job.embedded.collected',tobesaved,initializer)
+local function validdocument(specification)
+ if figures and not specification then
+ specification = figures and figures.current()
+ specification = specification and specification.status
+ end
+ if specification then
+ local fullname = specification.fullname
+ local expanded = lower(expandname(fullname))
+ -- we could add a check for duplicate page insertion
+ tobesaved[expanded] = true
+ --- but that is messy anyway so we forget about it
+ return specification, fullname, loadpdffile(fullname) -- costs time
+ end
+end
+
+local function getmediasize(specification,pagedata)
+ local xscale = specification.xscale or 1
+ local yscale = specification.yscale or 1
+ ----- size = specification.size or "crop" -- todo
+ local mediabox = pagedata.MediaBox
+ local llx = mediabox[1]
+ local lly = mediabox[2]
+ local urx = mediabox[3]
+ local ury = mediabox[4]
+ local width = xscale * (urx - llx) -- \\overlaywidth, \\overlayheight
+ local height = yscale * (ury - lly) -- \\overlaywidth, \\overlayheight
+ return llx, lly, urx, ury, width, height, xscale, yscale
+end
+
+local function getdimensions(annotation,llx,lly,xscale,yscale,width,height,report)
+ local rectangle = annotation.Rect
+ local a_llx = rectangle[1]
+ local a_lly = rectangle[2]
+ local a_urx = rectangle[3]
+ local a_ury = rectangle[4]
+ local x = xscale * (a_llx - llx)
+ local y = yscale * (a_lly - lly)
+ local w = xscale * (a_urx - a_llx)
+ local h = yscale * (a_ury - a_lly)
+ if w > width or h > height or w < 0 or h < 0 or abs(x) > (maxdimen/2) or abs(y) > (maxdimen/2) then
+ report("broken rectangle [%.6F %.6F %.6F %.6F] (max: %.6F)",a_llx,a_lly,a_urx,a_ury,maxdimen/2)
+ return
+ end
+ return x, y, w, h, a_llx, a_lly, a_urx, a_ury
+end
+
+local layerused = false
+
+local function initializelayer(height,width)
+ if not layerused then
+ context.definelayer(layerspec, { height = height .. "bp", width = width .. "bp" })
+ layerused = true
+ end
+end
+
+function codeinjections.flushmergelayer()
+ if layerused then
+ context.flushlayer(layerspec)
+ layerused = false
+ end
+end
+
local f_namespace = formatters["lpdf-epa-%s-"]
local function makenamespace(filename)
@@ -182,79 +269,48 @@ local function link_file(x,y,w,h,document,annotation)
end
end
+-- maybe handler per subtype and then one loop but then what about order ...
+
function codeinjections.mergereferences(specification)
- if figures and not specification then
- specification = figures and figures.current()
- specification = specification and specification.status
- end
- if not specification then
- return ""
- end
- local fullname = specification.fullname
- local expanded = lower(expandname(fullname))
- -- we could add a check for duplicate page insertion
- tobesaved[expanded] = true
- --- but that is messy anyway so we forget about it
- local document = loadpdffile(fullname) -- costs time
+ local specification, fullname, document = validdocument(specification)
if not document then
return ""
end
- local pagenumber = specification.page or 1
- local xscale = specification.yscale or 1
- local yscale = specification.yscale or 1
- local size = specification.size or "crop" -- todo
+ local pagenumber = specification.page or 1
local pagedata = document.pages[pagenumber]
local annotations = pagedata and pagedata.Annots
local namespace = makenamespace(fullname)
local reference = namespace .. pagenumber
if annotations and annotations.n > 0 then
- local mediabox = pagedata.MediaBox
- local llx = mediabox[1]
- local lly = mediabox[2]
- local urx = mediabox[3]
- local ury = mediabox[4]
- local width = xscale * (urx - llx) -- \\overlaywidth, \\overlayheight
- local height = yscale * (ury - lly) -- \\overlaywidth, \\overlayheight
- context.definelayer( { "epdflinks" }, { height = height.."bp" , width = width.."bp" })
+ local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale)
+ initializelayer(height,width)
for i=1,annotations.n do
local annotation = annotations[i]
if annotation then
- local subtype = annotation.Subtype
- local rectangle = annotation.Rect
- local a_llx = rectangle[1]
- local a_lly = rectangle[2]
- local a_urx = rectangle[3]
- local a_ury = rectangle[4]
- local x = xscale * (a_llx - llx)
- local y = yscale * (a_lly - lly)
- local w = xscale * (a_urx - a_llx)
- local h = yscale * (a_ury - a_lly)
- if subtype == "Link" then
+ if annotation.Subtype == "Link" then
local a = annotation.A
if not a then
report_link("missing link annotation")
- elseif w > width or h > height or w < 0 or h < 0 or abs(x) > (maxdimen/2) or abs(y) > (maxdimen/2) then
- report_link("broken link rectangle [%.6F %.6F %.6F %.6F] (max: %.6F)",a_llx,a_lly,a_urx,a_ury,maxdimen/2)
else
- local linktype = a.S
- if linktype == "GoTo" then
- link_goto(x,y,w,h,document,annotation,pagedata,namespace)
- elseif linktype == "GoToR" then
- link_file(x,y,w,h,document,annotation)
- elseif linktype == "URI" then
- link_uri(x,y,w,h,document,annotation)
- elseif trace_links then
- report_link("unsupported link annotation %a",linktype)
+ local x, y, w, h = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_link)
+ if x then
+ local linktype = a.S
+ if linktype == "GoTo" then
+ link_goto(x,y,w,h,document,annotation,pagedata,namespace)
+ elseif linktype == "GoToR" then
+ link_file(x,y,w,h,document,annotation)
+ elseif linktype == "URI" then
+ link_uri(x,y,w,h,document,annotation)
+ elseif trace_links then
+ report_link("unsupported link annotation %a",linktype)
+ end
end
end
- elseif trace_links then
- report_link("unsupported annotation %a",subtype)
end
elseif trace_links then
report_link("broken annotation, index %a",i)
end
end
- context.flushlayer { "epdflinks" }
end
-- moved outside previous test
context.setgvalue("figurereference",reference) -- global
@@ -270,43 +326,520 @@ function codeinjections.mergeviewerlayers(specification)
if true then
return
end
- if not specification then
- specification = figures and figures.current()
- specification = specification and specification.status
+ local specification, fullname, document = validdocument(specification)
+ if not document then
+ return ""
end
- if specification then
- local fullname = specification.fullname
- local document = loadpdffile(fullname)
- if document then
- local namespace = makenamespace(fullname)
- local layers = document.layers
- if layers then
- for i=1,layers.n do
- local layer = layers[i]
- if layer then
- local tag = namespace .. gsub(layer," ",":")
- local title = tag
- if trace_links then
- report_link("using layer %a",tag)
- end
- attributes.viewerlayers.define { -- also does some cleaning
- tag = tag, -- todo: #3A or so
- title = title,
- visible = variables.start,
- editable = variables.yes,
- printable = variables.yes,
- }
- codeinjections.useviewerlayer(tag)
- elseif trace_links then
- report_link("broken layer, index %a",i)
- end
+ local namespace = makenamespace(fullname)
+ local layers = document.layers
+ if layers then
+ for i=1,layers.n do
+ local layer = layers[i]
+ if layer then
+ local tag = namespace .. gsub(layer," ",":")
+ local title = tag
+ if trace_links then
+ report_link("using layer %a",tag)
end
+ attributes.viewerlayers.define { -- also does some cleaning
+ tag = tag, -- todo: #3A or so
+ title = title,
+ visible = variables.start,
+ editable = variables.yes,
+ printable = variables.yes,
+ }
+ codeinjections.useviewerlayer(tag)
+ elseif trace_links then
+ report_link("broken layer, index %a",i)
end
end
end
end
--- new: for taco
+-- It took a bit of puzzling and playing around to come to the following
+-- implementation. In the end it looks simple but as usual it takes a while
+-- to see what the specification (and implementation) boils down to. Lots of
+-- shared properties and such. The scaling took some trial and error as
+-- viewers differ. I had to extend some low level helpers to make it more
+-- comfortable. Hm, the specification is somewhat incomplete as some fields
+-- are permitted even if not mentioned so in the end we can share more code.
+--
+-- If all works ok, we can get rid of some copies which saves time and space.
+
+local commentlike = {
+ Text = "text",
+ FreeText = "freetext",
+ Line = "line",
+ Square = "shape",
+ Circle = "shape",
+ Polygon = "poly",
+ PolyLine = "poly",
+ Highlight = "markup",
+ Underline = "markup",
+ Squiggly = "markup",
+ StrikeOut = "markup",
+ Caret = "text",
+ Stamp = "stamp",
+ Ink = "ink",
+ Popup = "popup",
+}
+
+local function copyBS(v) -- dict can be shared
+ if v then
+ -- return pdfdictionary {
+ -- Type = copypdfconstant(V.Type),
+ -- W = copypdfnumber (V.W),
+ -- S = copypdfstring (V.S),
+ -- D = copypdfarray (V.D),
+ -- }
+ return copypdfdictionary(v)
+ end
+end
+
+local function copyBE(v) -- dict can be shared
+ if v then
+ -- return pdfdictionary {
+ -- S = copypdfstring(V.S),
+ -- I = copypdfnumber(V.I),
+ -- }
+ return copypdfdictionary(v)
+ end
+end
+
+local function copyBorder(v) -- dict can be shared
+ if v then
+ -- todo
+ return copypdfarray(v)
+ end
+end
+
+local function copyPopup(v,references)
+ if v then
+ local p = references[v]
+ if p then
+ return pdfreference(p)
+ end
+ end
+end
+
+local function copyParent(v,references)
+ if v then
+ local p = references[v]
+ if p then
+ return pdfreference(p)
+ end
+ end
+end
+
+local function copyIRT(v,references)
+ if v then
+ local p = references[v]
+ if p then
+ return pdfreference(p)
+ end
+ end
+end
+
+local function copyC(v)
+ if v then
+ -- todo: check color space
+ return pdfcopyarray(v)
+ end
+end
+
+local function finalizer(d,xscale,yscale,a_llx,a_ury)
+ local q = d.QuadPoints or d.Vertices or d.CL
+ if q then
+ return function()
+ local h, v = pdfgetpos() -- already scaled
+ for i=1,#q,2 do
+ q[i] = xscale * q[i] + (h*bpfactor - xscale * a_llx)
+ q[i+1] = yscale * q[i+1] + (v*bpfactor - yscale * a_ury)
+ end
+ return d()
+ end
+ end
+ q = d.InkList or d.Path
+ if q then
+ return function()
+ local h, v = pdfgetpos() -- already scaled
+ for i=1,#q do
+ local q = q[i]
+ for i=1,#q,2 do
+ q[i] = xscale * q[i] + (h*bpfactor - xscale * a_llx)
+ q[i+1] = yscale * q[i+1] + (v*bpfactor - yscale * a_ury)
+ end
+ end
+ return d()
+ end
+ end
+ return d()
+end
+
+local validstamps = {
+ Approved = true,
+ Experimental = true,
+ NotApproved = true,
+ AsIs = true,
+ Expired = true,
+ NotForPublicRelease = true,
+ Confidential = true,
+ Final = true,
+ Sold = true,
+ Departmental = true,
+ ForComment = true,
+ TopSecret = true,
+ Draft = true,
+ ForPublicRelease = true,
+}
+
+local function validStamp(v)
+ local name = "Stamped" -- fallback
+ if v then
+ local ok = validstamps[v]
+ if ok then
+ name = ok
+ else
+ for k in next, validstamps do
+ if find(v,k.."$") then
+ name = k
+ validstamps[v] = k
+ break
+ end
+ end
+ end
+ end
+ -- we temporary return to \TEX:
+ context.predefinesymbol { name }
+ context.step()
+ -- beware, an error is not reported
+ return pdfconstant(name), codeinjections.analyzenormalsymbol(name)
+end
+
+local annotationflags = lpdf.flags.annotations
+
+local function copyF(v,lock) -- todo: bxor 24
+ if lock then
+ v = bor(v or 0,annotationflags.ReadOnly + annotationflags.Locked + annotationflags.LockedContents)
+ end
+ if v then
+ return pdfcopyinteger(v)
+ end
+end
+
+-- Speed is not really an issue so we don't optimize this code too much. In the end (after
+-- testing we end up with less code that we started with.
+
+function codeinjections.mergecomments(specification)
+ -- local specification, fullname, document = validdocument(specification)
+ -- if not document then
+ -- return ""
+ -- end
+ -- local pagenumber = specification.page or 1
+ -- local pagedata = document.pages[pagenumber]
+ -- local annotations = pagedata and pagedata.Annots
+ -- if annotations and annotations.n > 0 then
+ -- local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale)
+ -- initializelayer(height,width)
+ -- --
+ -- local lockflags = specification.lock -- todo: proper parameter
+ -- local references = { }
+ -- local usedpopups = { }
+ -- for i=1,annotations.n do
+ -- local annotation = annotations[i]
+ -- if annotation then
+ -- local subtype = annotation.Subtype
+ -- if commentlike[subtype] then
+ -- references[annotation] = pdfreserveobject()
+ -- local p = annotation.Popup
+ -- if p then
+ -- usedpopups[p] = true
+ -- end
+ -- end
+ -- end
+ -- end
+ -- --
+ -- for i=1,annotations.n do
+ -- -- we keep the order
+ -- local annotation = annotations[i]
+ -- if annotation then
+ -- local reference = references[annotation]
+ -- if reference then
+ -- local subtype = annotation.Subtype
+ -- local kind = commentlike[subtype]
+ -- if kind ~= "popup" or usedpopups[annotation] then
+ -- local x, y, w, h, a_llx, a_lly, a_urx, a_ury = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_comment)
+ -- if x then
+ -- local voffset = h
+ -- local dictionary = pdfdictionary {
+ -- Subtype = pdfconstant (subtype),
+ -- -- common (skipped: P AP AS OC AF BM StructParent)
+ -- Contents = pdfcopyunicode(annotation.Contents),
+ -- NM = pdfcopystring (annotation.NM),
+ -- M = pdfcopystring (annotation.M),
+ -- F = copyF (annotation.F,lockflags),
+ -- C = copyC (annotation.C),
+ -- ca = pdfcopynumber (annotation.ca),
+ -- CA = pdfcopynumber (annotation.CA),
+ -- Lang = pdfcopystring (annotation.Lang),
+ -- -- also common
+ -- CreationDate = pdfcopystring (annotation.CreationDate),
+ -- T = pdfcopyunicode(annotation.T),
+ -- Subj = pdfcopyunicode(annotation.Subj),
+ -- -- border
+ -- Border = pdfcopyarray (annotation.Border),
+ -- BS = copyBS (annotation.BS),
+ -- BE = copyBE (annotation.BE),
+ -- -- sort of common
+ -- Popup = copyPopup (annotation.Popup,references),
+ -- RC = pdfcopyunicode(annotation.RC) -- string or stream
+ -- }
+ -- if kind == "markup" then
+ -- dictionary.IRT = copyIRT (annotation.IRT,references)
+ -- dictionary.RT = pdfconstant (annotation.RT)
+ -- dictionary.IT = pdfcopyconstant (annotation.IT)
+ -- dictionary.QuadPoints = pdfcopyarray (annotation.QuadPoints)
+ -- -- dictionary.RD = pdfcopyarray (annotation.RD)
+ -- elseif kind == "text" then
+ -- -- somehow F fails to view : /F 24 : bit4=nozoom bit5=norotate
+ -- dictionary.F = nil
+ -- dictionary.Open = pdfcopyboolean (annotation.Open)
+ -- dictionary.Name = pdfcopyunicode (annotation.Name)
+ -- dictionary.State = pdfcopystring (annotation.State)
+ -- dictionary.StateModel = pdfcopystring (annotation.StateModel)
+ -- dictionary.IT = pdfcopyconstant (annotation.IT)
+ -- dictionary.QuadPoints = pdfcopyarray (annotation.QuadPoints)
+ -- dictionary.RD = pdfcopyarray (annotation.RD) -- caret
+ -- dictionary.Sy = pdfcopyconstant (annotation.Sy) -- caret
+ -- voffset = 0
+ -- elseif kind == "freetext" then
+ -- dictionary.DA = pdfcopystring (annotation.DA)
+ -- dictionary.Q = pdfcopyinteger (annotation.Q)
+ -- dictionary.DS = pdfcopystring (annotation.DS)
+ -- dictionary.CL = pdfcopyarray (annotation.CL)
+ -- dictionary.IT = pdfcopyconstant (annotation.IT)
+ -- dictionary.LE = pdfcopyconstant (annotation.LE)
+ -- -- dictionary.RC = pdfcopystring (annotation.RC)
+ -- elseif kind == "line" then
+ -- dictionary.LE = pdfcopyarray (annotation.LE)
+ -- dictionary.IC = pdfcopyarray (annotation.IC)
+ -- dictionary.LL = pdfcopynumber (annotation.LL)
+ -- dictionary.LLE = pdfcopynumber (annotation.LLE)
+ -- dictionary.Cap = pdfcopyboolean (annotation.Cap)
+ -- dictionary.IT = pdfcopyconstant (annotation.IT)
+ -- dictionary.LLO = pdfcopynumber (annotation.LLO)
+ -- dictionary.CP = pdfcopyconstant (annotation.CP)
+ -- dictionary.Measure = pdfcopydictionary(annotation.Measure) -- names
+ -- dictionary.CO = pdfcopyarray (annotation.CO)
+ -- voffset = 0
+ -- elseif kind == "shape" then
+ -- dictionary.IC = pdfcopyarray (annotation.IC)
+ -- -- dictionary.RD = pdfcopyarray (annotation.RD)
+ -- voffset = 0
+ -- elseif kind == "stamp" then
+ -- local name, appearance = validStamp(annotation.Name)
+ -- dictionary.Name = name
+ -- dictionary.AP = appearance
+ -- voffset = 0
+ -- elseif kind == "ink" then
+ -- dictionary.InkList = pdfcopyarray (annotation.InkList)
+ -- elseif kind == "poly" then
+ -- dictionary.Vertices = pdfcopyarray (annotation.Vertices)
+ -- -- dictionary.LE = pdfcopyarray (annotation.LE) -- todo: names in array
+ -- dictionary.IC = pdfcopyarray (annotation.IC)
+ -- dictionary.IT = pdfcopyconstant (annotation.IT)
+ -- dictionary.Measure = pdfcopydictionary(annotation.Measure)
+ -- dictionary.Path = pdfcopyarray (annotation.Path)
+ -- -- dictionary.RD = pdfcopyarray (annotation.RD)
+ -- elseif kind == "popup" then
+ -- dictionary.Open = pdfcopyboolean (annotation.Open)
+ -- dictionary.Parent = copyParent (annotation.Parent,references)
+ -- voffset = 0
+ -- end
+ -- if dictionary then
+ -- local locationspec = {
+ -- x = x .. "bp",
+ -- y = y .. "bp",
+ -- voffset = voffset .. "bp",
+ -- preset = "leftbottom",
+ -- }
+ -- local finalize = finalizer(dictionary,xscale,yscale,a_llx,a_ury)
+ -- context.setlayer(layerspec,locationspec,function()
+ -- context(hpack_node(nodeinjections.annotation(w/bpfactor,h/bpfactor,0,finalize,reference)))
+ -- end)
+ -- end
+ -- end
+ -- else
+ -- -- report_comment("skipping annotation, index %a",i)
+ -- end
+ -- end
+ -- elseif trace_comments then
+ -- report_comment("broken annotation, index %a",i)
+ -- end
+ -- end
+ -- end
+ -- return namespace
+end
+
+local widgetflags = lpdf.flags.widgets
+
+local function flagstoset(flag,flags)
+ local t = { }
+ if flags then
+ for k, v in next, flags do
+ if band(flag,v) ~= 0 then
+ t[k] = true
+ end
+ end
+ end
+ return t
+end
+
+-- BS : border style dict
+-- R : rotation 0 90 180 270
+-- BG : background array
+-- CA : caption string
+-- RC : roll over caption
+-- AC : down caption
+-- I/RI/IX : icon streams
+-- IF : fit dictionary
+-- TP : text position number
+
+-- Opt : array of texts
+-- TI : top index
+
+-- V : value
+-- DV : default value
+-- DS : default string
+-- RV : rich
+-- Q : quadding (0=left 1=middle 2=right)
+
+function codeinjections.mergefields(specification)
+ -- local specification, fullname, document = validdocument(specification)
+ -- if not document then
+ -- return ""
+ -- end
+ -- local pagenumber = specification.page or 1
+ -- local pagedata = document.pages[pagenumber]
+ -- local annotations = pagedata and pagedata.Annots
+ -- if annotations and annotations.n > 0 then
+ -- local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale)
+ -- initializelayer(height,width)
+ -- --
+ -- for i=1,annotations.n do
+ -- -- we keep the order
+ -- local annotation = annotations[i]
+ -- if annotation then
+ -- local subtype = annotation.Subtype
+ -- if subtype == "Widget" then
+ -- local parent = annotation.Parent or { }
+ -- local name = annotation.T or parent.T
+ -- local what = annotation.FT or parent.FT
+ -- if name and what then
+ -- local x, y, w, h, a_llx, a_lly, a_urx, a_ury = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_field)
+ -- if x then
+ -- x = x .. "bp"
+ -- y = y .. "bp"
+ -- local W, H = w, h
+ -- w = w .. "bp"
+ -- h = h .. "bp"
+ -- if trace_fields then
+ -- report_field("field %a, type %a, dx %s, dy %s, wd %s, ht %s",name,what,x,y,w,h)
+ -- end
+ -- local locationspec = {
+ -- x = x,
+ -- y = y,
+ -- preset = "leftbottom",
+ -- }
+ -- --
+ -- local aflags = flagstoset(annotation.F or parent.F, annotationflags)
+ -- local wflags = flagstoset(annotation.Ff or parent.Ff, widgetflags)
+ -- if what == "Tx" then
+ -- -- DA DV F FT MaxLen MK Q T V | AA OC
+ -- if wflags.MultiLine then
+ -- wflags.MultiLine = nil
+ -- what = "text"
+ -- else
+ -- what = "line"
+ -- end
+ -- -- via context
+ -- local fieldspec = {
+ -- width = w,
+ -- height = h,
+ -- offset = variables.overlay,
+ -- frame = trace_links and variables.on or variables.off,
+ -- n = annotation.MaxLen or (parent and parent.MaxLen),
+ -- type = what,
+ -- option = concat(merged(aflags,wflags),","),
+ -- }
+ -- context.setlayer (layerspec,locationspec,function()
+ -- context.definefieldbody ( { name } , fieldspec )
+ -- context.fieldbody ( { name } )
+ -- end)
+ -- --
+ -- elseif what == "Btn" then
+ -- if wflags.Radio or wflags.RadiosInUnison then
+ -- -- AP AS DA F Ff FT H MK T V | AA OC
+ -- wflags.Radio = nil
+ -- wflags.RadiosInUnison = nil
+ -- what = "radio"
+ -- elseif wflags.PushButton then
+ -- -- AP DA F Ff FT H MK T | AA OC
+ -- --
+ -- -- Push buttons only have an appearance and some associated
+ -- -- actions so they are not worth copying.
+ -- --
+ -- wflags.PushButton = nil
+ -- what = "push"
+ -- else
+ -- -- AP AS DA F Ff FT H MK T V | OC AA
+ -- what = "check"
+ -- -- direct
+ -- local AP = annotation.AP or (parent and parent.AP)
+ -- if AP then
+ -- local im = img.new { filename = fullname }
+ -- AP = img.immediatewriteobject(im,document.__xrefs__[AP])
+ -- end
+ -- local dictionary = pdfdictionary {
+ -- Subtype = pdfconstant("Widget"),
+ -- FT = pdfconstant("Btn"),
+ -- T = pdfcopyunicode(annotation.T or parent.T),
+ -- F = pdfcopyinteger(annotation.F or parent.F),
+ -- Ff = pdfcopyinteger(annotation.Ff or parent.Ff),
+ -- AS = pdfcopyconstant(annotation.AS or (parent and parent.AS)),
+ -- AP = AP and pdfreference(AP),
+ -- }
+ -- local finalize = dictionary()
+ -- context.setlayer(layerspec,locationspec,function()
+ -- context(hpack_node(nodeinjections.annotation(W/bpfactor,H/bpfactor,0,finalize)))
+ -- end)
+ -- --
+ -- end
+ -- elseif what == "Ch" then
+ -- -- F Ff FT Opt T | AA OC (rest follows)
+ -- if wflags.PopUp then
+ -- wflags.PopUp = nil
+ -- if wflags.Edit then
+ -- wflags.Edit = nil
+ -- what = "combo"
+ -- else
+ -- what = "popup"
+ -- end
+ -- else
+ -- what = "choice"
+ -- end
+ -- elseif what == "Sig" then
+ -- what = "signature"
+ -- else
+ -- what = nil
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+end
-- Beware, bookmarks can be in pdfdoc encoding or in unicode. However, in mkiv we
-- write out the strings in unicode (hex). When we read them in, we check for a bom
@@ -471,16 +1004,6 @@ function codeinjections.mergebookmarks(specification)
end
end
--- placeholders:
-
-function codeinjections.mergecomments(specification)
- report_comment("unfinished experimental code, not used yet")
-end
-
-function codeinjections.mergefields(specification)
- report_field("unfinished experimental code, not used yet")
-end
-
-- A bit more than a placeholder but in the same perspective as
-- inclusion of comments and fields:
--
diff --git a/tex/context/base/mkiv/lpdf-epd.lua b/tex/context/base/mkiv/lpdf-epd.lua
index cf02b5a22..7bfdf57bc 100644
--- a/tex/context/base/mkiv/lpdf-epd.lua
+++ b/tex/context/base/mkiv/lpdf-epd.lua
@@ -32,7 +32,7 @@ if not modules then modules = { } end modules ['lpdf-epd'] = {
-- already was unicode).
local setmetatable, rawset, rawget, type, next = setmetatable, rawset, rawget, type, next
-local tostring, tonumber = tostring, tonumber
+local tostring, tonumber, unpack = tostring, tonumber, unpack
local lower, match, char, byte, find = string.lower, string.match, string.char, string.byte, string.find
local abs = math.abs
local concat = table.concat
@@ -67,13 +67,27 @@ local xref = registry["epdf.XRef"]
local catalog = registry["epdf.Catalog"]
local pdfdoc = registry["epdf.PDFDoc"]
+if not (object and dictionary and array and xref and catalog and pdfdoc) then
+ logs.report("fatal error","invalid pdf inclusion library (%s)",1)
+ os.exit()
+end
+
local openPDF = epdf.open
+local getMajorVersion = pdfdoc.getPDFMajorVersion
+local getMinorVersion = pdfdoc.getPDFMinorVersion
+local getXRef = pdfdoc.getXRef
+local getRawCatalog = pdfdoc.getCatalog
+
+if not (openPDF and getMajorVersion and getMinorVersion and getXRef and getRawCatalog) then
+ logs.report("fatal error","invalid pdf inclusion library (%s)",2)
+ os.exit()
+end
+
local getDict = object.getDict
local getArray = object.getArray
local getReal = object.getReal
local getInt = object.getInt
-local getNum = object.getNum
local getString = object.getString
local getBool = object.getBool
local getName = object.getName
@@ -81,38 +95,60 @@ local getRef = object.getRef
local getRefNum = object.getRefNum
local getType = object.getType
-local getTypeName = object.getTypeName
+
+if not (getDict and getArray and getReal and getInt and getString and getBool and getName and getRef and getRefNum and getType) then
+ logs.report("fatal error","invalid pdf inclusion library (%s)",3)
+ os.exit()
+end
local streamReset = object.streamReset
local streamGetDict = object.streamGetDict
local streamGetChar = object.streamGetChar
+local streamGetAll = object.streamGetAll
+
+if not (streamReset and streamGetDict and streamGetChar) then
+ logs.report("fatal error","invalid pdf inclusion library (%s)",3)
+ os.exit()
+end
local dictGetLength = dictionary.getLength
local dictGetVal = dictionary.getVal
local dictGetValNF = dictionary.getValNF
local dictGetKey = dictionary.getKey
+if not (dictGetLength and dictGetVal and dictGetValNF and dictGetKey) then
+ logs.report("fatal error","invalid pdf inclusion library (%s)",4)
+ os.exit()
+end
+
local arrayGetLength = array.getLength
local arrayGetNF = array.getNF
local arrayGet = array.get
+if not (arrayGetLength and arrayGetNF and arrayGet) then
+ logs.report("fatal error","invalid pdf inclusion library (%s)",5)
+ os.exit()
+end
+
-- these are kind of weird as they can't be accessed by (root) object
local getNumPages = catalog.getNumPages
local getPageRef = catalog.getPageRef
-local getXRef = pdfdoc.getXRef
-local getRawCatalog = pdfdoc.getCatalog
-
local fetch = xref.fetch
local getCatalog = xref.getCatalog
local getDocInfo = xref.getDocInfo
+if not (getNumPages and getPageRef and fetch and getCatalog and getDocInfo) then
+ logs.report("fatal error","invalid pdf inclusion library (%s)",6)
+ os.exit()
+end
+
-- we're done with library shortcuts
local report_epdf = logs.reporter("epdf")
-local typenames = { [0] =
+local typenames = { [0] =
"boolean",
"integer",
"real",
@@ -208,30 +244,28 @@ local function prepare(document,d,t,n,k,mt,flags)
local kind = getType(v)
if kind == null_code then
-- ignore
- else
+ elseif kind then
local key = dictGetKey(d,i)
- if kind then
- if r and getType(r) == ref_code then
- local objnum = getRefNum(r)
- local cached = document.__cache__[objnum]
- if not cached then
- cached = checked_access[kind](v,document,objnum,mt)
- if cached then
- document.__cache__[objnum] = cached
- document.__xrefs__[cached] = objnum
- end
- end
- t[key] = cached
- else
- local v, flag = checked_access[kind](v,document)
- t[key] = v
- if flag and flags then
- flags[key] = flag -- flags
+ if r and getType(r) == ref_code then
+ local objnum = getRefNum(r)
+ local cached = document.__cache__[objnum]
+ if not cached then
+ cached = checked_access[kind](v,document,objnum,mt)
+ if cached then
+ document.__cache__[objnum] = cached
+ document.__xrefs__[cached] = objnum
end
end
+ t[key] = cached
else
- report_epdf("warning: nil value for key %a in dictionary",key)
+ local v, flag = checked_access[kind](v,document)
+ t[key] = v
+ if flag and flags then
+ flags[key] = flag -- flags
+ end
end
+ else
+ report_epdf("warning: nil value for key %a in dictionary",key)
end
else
fatal_error("error: invalid value at index %a in dictionary of %a",i,document.filename)
@@ -245,6 +279,42 @@ local function prepare(document,d,t,n,k,mt,flags)
return t[k]
end
+-- local function prepare(document,d,t,n,k,mt,flags)
+-- for i=1,n do
+-- local v = dictGetValNF(d,i)
+-- if v then
+-- local key = dictGetKey(d,i)
+-- local kind = getType(v)
+-- if kind == ref_code then
+-- local objnum = getRefNum(v)
+-- local cached = document.__cache__[objnum]
+-- if not cached then
+-- local v = dictGetVal(d,i)
+-- local kind = getType(v)
+-- cached = checked_access[kind](v,document,objnum,mt)
+-- if cached then
+-- document.__cache__[objnum] = cached
+-- document.__xrefs__[cached] = objnum
+-- end
+-- end
+-- t[key] = cached
+-- else
+-- local v, flag = checked_access[kind](v,document)
+-- t[key] = v
+-- if flag and flags then
+-- flags[key] = flag -- flags
+-- end
+-- end
+-- end
+-- end
+-- if mt then
+-- setmetatable(t,mt)
+-- else
+-- getmetatable(t).__index = nil
+-- end
+-- return t[k]
+-- end
+
local function some_dictionary(d,document)
local n = d and dictGetLength(d) or 0
if n > 0 then
@@ -326,6 +396,37 @@ local function prepare(document,a,t,n,k)
end
end
+-- local function prepare(document,a,t,n,k)
+-- for i=1,n do
+-- local v = arrayGetNF(a,i)
+-- if v then
+-- local kind = getType(v)
+-- if kind == ref_code then
+-- local objnum = getRefNum(v)
+-- local cached = document.__cache__[objnum]
+-- if not cached then
+-- local v = arrayGet(a,i)
+-- local kind = getType(v)
+-- cached = checked_access[kind](v,document,objnum)
+-- document.__cache__[objnum] = cached
+-- document.__xrefs__[cached] = objnum
+-- end
+-- t[i] = cached
+-- else
+-- t[i] = checked_access[kind](v,document)
+-- end
+-- end
+-- end
+-- local m = getmetatable(t)
+-- if m then
+-- m.__index = nil
+-- m.__len = nil
+-- end
+-- if k then
+-- return t[k]
+-- end
+-- end
+
local function some_array(a,document)
local n = a and arrayGetLength(a) or 0
if n > 0 then
@@ -376,23 +477,53 @@ end
-- todo: collect chunks
-local function streamaccess(s,_,what)
- if not what or what == "all" or what == "*all" then
- local t, n = { }, 0
- streamReset(s)
+-- local function streamaccess(s,_,what)
+-- if not what or what == "all" or what == "*all" then
+-- local t, n = { }, 0
+-- streamReset(s)
+-- while true do
+-- local c = streamGetChar(s)
+-- if c < 0 then
+-- break
+-- else
+-- n = n + 1
+-- t[n] = char(c)
+-- end
+-- end
+-- return concat(t,"",1,n)
+-- end
+-- end
+
+local function getstream(s)
+ streamReset(s)
+ if streamGetAll then
+ return streamGetAll(s)
+ else
+ local t, b, n = { }, { }, 0
while true do
local c = streamGetChar(s)
if c < 0 then
break
else
n = n + 1
- t[n] = char(c)
+ b[n] = c
+ end
+ if n == 2000 then
+ t[#t+1] = char(unpack(b,1,n))
+ n = 1
end
end
+ t[#t+1] = char(unpack(b,1,n))
return concat(t)
end
end
+local function streamaccess(s,_,what)
+ if not what or what == "all" or what == "*all" then
+ return getstream(s)
+ end
+end
+
local function get_stream(d,document)
if d then
streamReset(d)
@@ -562,16 +693,19 @@ end
-- with but it won't win a beauty contest.
local function getpages(document,Catalog)
- local __data__ = document.__data__
- local __xrefs__ = document.__xrefs__
- local __cache__ = document.__cache__
- local __xref__ = document.__xref__
+ local __data__ = document.__data__
+ local __xrefs__ = document.__xrefs__
+ local __cache__ = document.__cache__
+ local __xref__ = document.__xref__
+ --
+ local rawcatalog = getRawCatalog(__data__)
+ local nofpages = getNumPages(rawcatalog)
--
- local rawcatalog = getRawCatalog(__data__)
- local nofpages = getNumPages(rawcatalog)
+ local majorversion = getMajorVersion(__data__)
+ local minorversion = getMinorVersion(__data__)
--
- local pages = { }
- local metatable = { __index = Catalog.Pages } -- somewhat empty
+ local pages = { }
+ local metatable = { __index = Catalog.Pages } -- somewhat empty
--
for pagenumber=1,nofpages do
local pagereference = getPageRef(rawcatalog,pagenumber).num
@@ -580,6 +714,7 @@ local function getpages(document,Catalog)
if pagedata then
-- rawset(pagedata,"number",pagenumber)
pagedata.number = pagenumber
+ pagedata.object = pageobject
pages[pagenumber] = pagedata
__xrefs__[pagedata] = pagereference
__cache__[pagereference] = pagedata
@@ -590,7 +725,10 @@ local function getpages(document,Catalog)
--
pages.n = nofpages
--
- document.pages = pages
+ document.pages = pages
+ document.majorversion = majorversion
+ document.minorversion = minorversion
+ --
return pages
end
@@ -637,6 +775,8 @@ function lpdf_epdf.load(filename)
document.Catalog = some_dictionary(getDict(getCatalog(__xref__)),document)
document.Info = some_dictionary(getDict(getDocInfo(__xref__)),document)
setmetatableindex(document,resolve)
+ --
+ document.nofpages = getNumPages(getRawCatalog(__data__))
else
document = false
end
@@ -735,14 +875,14 @@ local fromunicode = (
P(1)
)^1 * Carg(1)
-local function analyzefonts(document,resources) -- unfinished
+local function analyzefonts(document,resources) -- unfinished, see mtx-pdf for better code
local fonts = document.__fonts__
if resources then
local fontlist = resources.Font
if fontlist then
for id, data in expanded(fontlist) do
if not fonts[id] then
- -- a quck hack ... I will look into it more detail if I find a real
+ -- a quick hack ... I will look into it more detail if I find a real
-- -application for it
local tounicode = data.ToUnicode()
if tounicode then
@@ -836,7 +976,7 @@ function lpdf_epdf.getpagecontent(document,pagenumber)
end
--- This is also an experiment. When I really neet it I can improve it, fo rinstance
+-- This is also an experiment. When I really need it I can improve it, for instance
-- with proper position calculating. It might be usefull for some search or so.
local softhyphen = utfchar(0xAD) .. "$"
@@ -925,3 +1065,247 @@ end
-- local destination = document.__data__:findDest(name)
-- return destination and destination.number
-- end
+
+-- This is experimental code that we need for testing the transition from
+-- poppler to a new lightweight library. Don't rely on this code to remain
+-- as it is now. Interesting is that performance of this variant is the same
+-- as the natural page includer.
+
+if img then do
+
+ local copydictionary = nil
+ local copyarray = nil
+
+ local ref_code = typenumbers.ref
+ local boolean_code = typenumbers.boolean
+ local integer_code = typenumbers.integer
+ local real_code = typenumbers.real
+ local string_code = typenumbers.string
+ local name_code = typenumbers.name
+ local null_code = typenumbers.null
+ local array_code = typenumbers.array
+ local dictionary_code = typenumbers.dictionary
+ local stream_code = typenumbers.stream
+ local cmd_code = typenumbers.cmd
+
+ local pdfreserveobject = lpdf.reserveobject
+ local pdfflushobject = lpdf.flushobject
+ local pdfflushstreamobject = lpdf.flushstreamobject
+ local pdfreference = lpdf.reference
+ local pdfconstant = lpdf.constant
+ local pdfarray = lpdf.array
+ local pdfdictionary = lpdf.dictionary
+ local pdfunicode = lpdf.unicode
+ local pdfstring = lpdf.string
+ local pdfnull = lpdf.null
+
+ local report = logs.reporter("backend","xobjects")
+
+ local factor = 65536 / (7200/7227) -- 1/number.dimenfactors.bp
+
+ local newimage = img.new
+
+ local function scaledbbox(b)
+ return { b[1]*factor, b[2]*factor, b[3]*factor, b[4]*factor }
+ end
+
+ local function copyobject(xref,copied,kind,r,v)
+ if kind == null_code then
+ return pdfnull()
+ elseif r and getType(r) == ref_code then
+ local objnum = getRefNum(r)
+ local r = copied[objnum]
+ if r then
+ -- report("%s object %i is reused",kind,objnum)
+ else
+ local o
+ r = pdfreserveobject()
+ copied[objnum] = r
+ if kind == array_code then
+ local a = copyarray(xref,copied,fetch(xref,objnum,0))
+ pdfflushobject(r,tostring(a))
+ elseif kind == dictionary_code then
+ local d = copydictionary(xref,copied,fetch(xref,objnum,0))
+ pdfflushobject(r,tostring(d))
+ elseif kind == stream_code then
+ local f = fetch(xref,objnum,0)
+ local d = copydictionary(xref,copied,false,streamGetDict(f))
+ local s = getstream(f)
+ --
+ d.Filter = nil
+ d.Length = nil
+ d.DecodeParms = nil
+ d.DL = nil
+ --
+ pdfflushstreamobject(s,d,true,r)
+ else
+ report("reference not done: %s", kind)
+ end
+ end
+ return pdfreference(r)
+ elseif kind == array_code then
+ return copyarray(xref,copied,v)
+ elseif kind == dictionary_code then
+ return copydictionary(xref,copied,v)
+ elseif kind == integer_code then
+ return getInt(v)
+ elseif kind == real_code then
+ return getReal(v)
+ elseif kind == name_code then
+ return pdfconstant(getName(v))
+ elseif kind == string_code then
+ local s = getString(v)
+ if not s or s == "" then
+ return ""
+ end
+ local u = lpegmatch(u_pattern,s)
+ if u then
+ return pdfunicode(s)
+ end
+ return pdfstring(s)
+ elseif kind == boolean_code then
+ return getBool(v)
+ elseif kind == stream_code then
+ -- hm ...
+ return getStream(v)
+ else
+ report("object not done: %s", kind)
+ end
+ end
+
+ copyarray = function (xref,copied,object)
+ local a = getArray(object)
+ local n = a and arrayGetLength(a) or 0
+ if n > 0 then
+ local target = pdfarray()
+ for i=1,n do
+ local v = arrayGet(a,i)
+ if v then
+ local kind = getType(v)
+ local r = arrayGetNF(a,i)
+ target[i] = copyobject(xref,copied,kind,r,v)
+ end
+ end
+ return target
+ end
+ end
+
+ copydictionary = function (xref,copied,object,d)
+ local d = d or getDict(object)
+ local n = d and dictGetLength(d) or 0
+ if n > 0 then
+ local target = pdfdictionary()
+ for i=1,n do
+ local v = dictGetVal(d,i)
+ if v then
+ local kind = getType(v)
+ local key = dictGetKey(d,i)
+ local r = dictGetValNF(d,i)
+ target[key] = copyobject(xref,copied,kind,r,v)
+ end
+ end
+ return target
+ end
+ end
+
+ local function copy_resources(pdfdoc,xref,copied,pagedata)
+ local object = pagedata.object
+ if object then
+ local d = getDict(object)
+ local n = d and dictGetLength(d) or 0
+ for i=1,n do
+ local k = dictGetKey(d,i)
+ if v and k == "Resources" then
+ local v = dictGetVal(d,i)
+ local kind = getType(v)
+ local r = dictGetValNF(d,i)
+ return copyobject(xref,copied,kind,r,v)
+ end
+ end
+ end
+ end
+
+ local function openpdf(filename)
+ local pdfdoc = lpdf_epdf.load(filename)
+ if pdfdoc then
+ pdfdoc.__copied__ = pdfdoc.__copied__ or { }
+ pdfdoc.filename = filename
+ return pdfdoc
+ end
+ end
+
+ local function closepdf(pdfdoc)
+ if pdfdoc then
+ lpdf_epdf.unload(pdfdoc.filename)
+ end
+ end
+
+ local function querypdf(pdfdoc,pagenumber)
+ if pdfdoc then
+ if not pagenumber then
+ pagenumber = 1
+ end
+ local root = pdfdoc.Catalog
+ local page = pdfdoc.pages[pagenumber]
+ if page then
+ local mediabox = page.MediaBox or { 0, 0, 0, 0 }
+ local cropbox = page.CropBox or mediabox
+ return {
+ filename = pdfdoc.filename,
+ pagenumber = pagenumber,
+ nofpages = pdfdoc.nofpages,
+ boundingbox = scaledbbox(cropbox),
+ cropbox = cropbox,
+ mediabox = mediabox,
+ bleedbox = page.BleedBox or cropbox,
+ trimbox = page.TrimBox or cropbox,
+ artbox = page.ArtBox or cropbox,
+ }
+ end
+ end
+ end
+
+ local function copypage(pdfdoc,pagenumber,attributes)
+ if pdfdoc then
+ local root = pdfdoc.Catalog
+ local page = pdfdoc.pages[pagenumber or 1]
+ local pageinfo = querypdf(pdfdoc,pagenumber)
+ local contents = page.Contents
+ local xref = pdfdoc.__xref__
+ local copied = pdfdoc.__copied__
+ --
+ local xobject = pdfdictionary {
+ Type = pdfconstant("XObject"),
+ Subtype = pdfconstant("Form"),
+ -- image attributes
+ FormType = 1,
+ BBox = pageinfo.cropbox,
+ -- MetaData = copy(xref,copied,root,"MetaData"),
+ -- Group = copy(xref,copied,page,"Group"),
+ -- LastModified = copy(xref,copied,page,"LastModified"),
+ -- Metadata = copy(xref,copied,page,"Metadata"),
+ -- PieceInfo = copy(xref,copied,page,"PieceInfo"),
+ Resources = copy_resources(pdfdoc,xref,copied,page),
+ -- SeparationInfo = copy(xref,copied,page,"SeparationInfo"),
+ }
+ if attributes then
+ for k, v in next, expand(attributes) do
+ page[k] = v -- maybe nested
+ end
+ end
+ return newimage {
+ bbox = pageinfo.boundingbox,
+ stream = contents(),
+ attr = xobject(),
+ }
+ end
+ end
+
+ lpdf_epdf.image = {
+ open = openpdf,
+ close = closepdf,
+ query = querypdf,
+ copy = copypage,
+ }
+
+end end
diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua
index 8af1fb409..89b87ed11 100644
--- a/tex/context/base/mkiv/lpdf-ini.lua
+++ b/tex/context/base/mkiv/lpdf-ini.lua
@@ -362,8 +362,10 @@ local f_key_dictionary = formatters["/%s << % t >>"]
local f_dictionary = formatters["<< % t >>"]
local f_key_array = formatters["/%s [ % t ]"]
local f_array = formatters["[ % t ]"]
-local f_key_number = formatters["/%s %F"]
-local f_tonumber = formatters["%F"]
+----- f_key_number = formatters["/%s %F"]
+local f_key_number = formatters["/%s %n"]
+----- f_tonumber = formatters["%F"]
+local f_tonumber = formatters["%n"]
local tostring_a, tostring_d
@@ -734,12 +736,13 @@ function lpdf.flushobject(name,data)
end
-function lpdf.flushstreamobject(data,dict,compressed) -- default compressed
+function lpdf.flushstreamobject(data,dict,compressed,objnum) -- default compressed
if trace_objects then
report_objects("flushing stream object of %s bytes",#data)
end
local dtype = type(dict)
return pdfdeferredobject {
+ objnum = objnum,
immediate = true,
compresslevel = compressed == false and 0 or nil,
type = "stream",
@@ -748,12 +751,13 @@ function lpdf.flushstreamobject(data,dict,compressed) -- default compressed
}
end
-function lpdf.flushstreamfileobject(filename,dict,compressed) -- default compressed
+function lpdf.flushstreamfileobject(filename,dict,compressed,objnum) -- default compressed
if trace_objects then
report_objects("flushing stream file object %a",filename)
end
local dtype = type(dict)
return pdfdeferredobject {
+ objnum = objnum,
immediate = true,
compresslevel = compressed == false and 0 or nil,
type = "stream",
@@ -905,13 +909,12 @@ if not callbacks.register("finish_pdfpage", lpdf.finalizepage) then
return head, true
end
- nodes.tasks.appendaction("shipouts","normalizers","backends.pdf.nodeinjections.finalizepage")
+ nodes.tasks.enableaction("shipouts","backends.pdf.nodeinjections.finalizepage")
end
callbacks.register("finish_pdffile", lpdf.finalizedocument)
-
do
-- some minimal tracing, handy for checking the order
@@ -1127,12 +1130,12 @@ do
return Y and format("D:%s%s%s%s%s%s%s%s'%s'",Y,M,D,h,m,s,Zs,Zh,Zm)
end
- function lpdf.id(nodate)
+ function lpdf.id(date)
local banner = environment.jobname or tex.jobname or "unknown"
- if nodate then
+ if not date then
return banner
else
- return format("%s.%s",banner,timestamp)
+ return format("%s | %s",banner,timestamp)
end
end
diff --git a/tex/context/base/mkiv/lpdf-nod.lua b/tex/context/base/mkiv/lpdf-nod.lua
index e3c1778f2..d41aa0bee 100644
--- a/tex/context/base/mkiv/lpdf-nod.lua
+++ b/tex/context/base/mkiv/lpdf-nod.lua
@@ -10,6 +10,9 @@ local type = type
local formatters = string.formatters
+local nodecodes = nodes.nodecodes
+local whatsit_code = nodecodes.whatsit
+
local whatsitcodes = nodes.whatsitcodes
local nodeinjections = backends.nodeinjections
@@ -26,16 +29,16 @@ local register = nodepool.register
local literalvalues = nodes.literalvalues
-local pdforiginliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdforiginliteral,"mode",literalvalues.origin)
-local pdfpageliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfpageliteral, "mode",literalvalues.page)
-local pdfdirectliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfdirectliteral,"mode",literalvalues.direct)
-local pdfrawliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfrawliteral, "mode",literalvalues.raw)
+local pdforiginliteral = register(new_node(whatsit_code, whatsitcodes.pdfliteral)) setfield(pdforiginliteral,"mode",literalvalues.origin)
+local pdfpageliteral = register(new_node(whatsit_code, whatsitcodes.pdfliteral)) setfield(pdfpageliteral, "mode",literalvalues.page)
+local pdfdirectliteral = register(new_node(whatsit_code, whatsitcodes.pdfliteral)) setfield(pdfdirectliteral,"mode",literalvalues.direct)
+local pdfrawliteral = register(new_node(whatsit_code, whatsitcodes.pdfliteral)) setfield(pdfrawliteral, "mode",literalvalues.raw)
-local pdfsave = register(new_node("whatsit", whatsitcodes.pdfsave))
-local pdfrestore = register(new_node("whatsit", whatsitcodes.pdfrestore))
-local pdfsetmatrix = register(new_node("whatsit", whatsitcodes.pdfsetmatrix))
------ pdfdest = register(new_node("whatsit", whatsitcodes.pdfdest)) setfield(pdfdest,"named_id",1) -- xyz_zoom untouched
------ pdfannot = register(new_node("whatsit", whatsitcodes.pdfannot))
+local pdfsave = register(new_node(whatsit_code, whatsitcodes.pdfsave))
+local pdfrestore = register(new_node(whatsit_code, whatsitcodes.pdfrestore))
+local pdfsetmatrix = register(new_node(whatsit_code, whatsitcodes.pdfsetmatrix))
+----- pdfdest = register(new_node(whatsit_code, whatsitcodes.pdfdest)) setfield(pdfdest,"named_id",1) -- xyz_zoom untouched
+----- pdfannot = register(new_node(whatsit_code, whatsitcodes.pdfannot))
local variables = interfaces.variables
diff --git a/tex/context/base/mkiv/lpdf-tag.lua b/tex/context/base/mkiv/lpdf-tag.lua
index dc7d038fe..b3d117c4b 100644
--- a/tex/context/base/mkiv/lpdf-tag.lua
+++ b/tex/context/base/mkiv/lpdf-tag.lua
@@ -51,8 +51,6 @@ local a_tagged = attributes.private('tagged')
local a_image = attributes.private('image')
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local nodepool = nuts.pool
local pdfpageliteral = nodepool.pdfpageliteral
@@ -68,9 +66,10 @@ local setlink = nuts.setlink
local setlist = nuts.setlist
local copy_node = nuts.copy
-local traverse_nodes = nuts.traverse
local tosequence = nuts.tosequence
+local nextnode = nuts.traversers.node
+
local structure_stack = { }
local structure_kids = pdfarray()
local structure_ref = pdfreserveobject()
@@ -324,10 +323,9 @@ function nodeinjections.addtags(head)
local last = nil
local ranges = { }
local range = nil
- local head = tonut(head)
local function collectranges(head,list)
- for n, id in traverse_nodes(head) do
+ for n, id in nextnode, head do
if id == glyph_code then
-- maybe also disc
local at = getattr(n,a_tagged)
@@ -441,17 +439,17 @@ function nodeinjections.addtags(head)
setlink(stop,literal)
end
--- if literal then
--- if list and getlist(list) == start then
--- setlink(literal,start)
--- setlist(list,literal)
--- else
--- setlink(getprev(start),literal,start)
--- end
--- -- use insert instead:
--- local literal = copy_node(EMCliteral)
--- setlink(stop,literal,getnext(stop))
--- end
+ -- if literal then
+ -- if list and getlist(list) == start then
+ -- setlink(literal,start)
+ -- setlist(list,literal)
+ -- else
+ -- setlink(getprev(start),literal,start)
+ -- end
+ -- -- use insert instead:
+ -- local literal = copy_node(EMCliteral)
+ -- setlink(stop,literal,getnext(stop))
+ -- end
top = taglist
noftop = noftags
@@ -459,8 +457,7 @@ function nodeinjections.addtags(head)
finishpage()
- head = tonode(head)
- return head, true
+ return head
end
@@ -471,7 +468,7 @@ end
-- local last, ranges, range = nil, { }, nil
--
-- local function collectranges(head,list)
--- for n, id in traverse_nodes(head) do
+-- for n, id in nextnode, head do
-- if id == glyph_code then
-- local at = getattr(n,a_tagged)
-- if not at then
@@ -503,7 +500,6 @@ end
--
-- initializepage()
--
--- head = tonut(head)
-- collectranges(head)
--
-- if trace_tags then
@@ -610,8 +606,7 @@ end
--
-- finishpage()
--
--- head = tonode(head)
--- return head, true
+-- return head
--
-- end
diff --git a/tex/context/base/mkiv/math-act.lua b/tex/context/base/mkiv/math-act.lua
index 77a355b22..a847b78c6 100644
--- a/tex/context/base/mkiv/math-act.lua
+++ b/tex/context/base/mkiv/math-act.lua
@@ -23,6 +23,12 @@ local mathematics = mathematics
local texsetdimen = tex.setdimen
local abs = math.abs
+local helpers = fonts.helpers
+local upcommand = helpers.commands.up
+local rightcommand = helpers.commands.right
+local charcommand = helpers.commands.char
+local prependcommands = helpers.prependcommands
+
local sequencers = utilities.sequencers
local appendgroup = sequencers.appendgroup
local appendaction = sequencers.appendaction
@@ -237,7 +243,6 @@ function mathematics.overloaddimensions(target,original,set)
local factor = parameters.factor
local hfactor = parameters.hfactor
local vfactor = parameters.vfactor
- local addprivate = fonts.helpers.addprivate
-- to be sure
target.type = "virtual"
target.properties.virtualized = true
@@ -257,7 +262,8 @@ function mathematics.overloaddimensions(target,original,set)
local height = data.height
local depth = data.depth
if trace_defining and (width or height or depth) then
- report_math("overloading dimensions of %C, width %a, height %a, depth %a",unicode,width,height,depth)
+ report_math("overloading dimensions of %C, width %p, height %p, depth %p",
+ unicode,width or 0,height or 0,depth or 0)
end
if width then character.width = width * hfactor end
if height then character.height = height * vfactor end
@@ -270,25 +276,26 @@ function mathematics.overloaddimensions(target,original,set)
if d then
xoffset = - d.boundingbox[1] * hfactor
character.width = character.width + xoffset
- xoffset = { "right", xoffset }
+ xoffset = rightcommand[xoffset]
+ else
+ xoffset = nil
end
- elseif xoffset then
- xoffset = { "right", xoffset * hfactor }
+ elseif xoffset and xoffset ~= 0 then
+ xoffset = rightcommand[xoffset * hfactor]
+ else
+ xoffset = nil
end
- if yoffset then
- yoffset = { "down", -yoffset * vfactor }
+ if yoffset and yoffset ~= 0 then
+ yoffset = upcommand[yoffset * vfactor]
+ else
+ yoffset = nil
end
if xoffset or yoffset then
- if character.commands then
- if yoffset then
- insert(character.commands,1,yoffset)
- end
- if xoffset then
- insert(character.commands,1,xoffset)
- end
+ local commands = characters.commands
+ if commands then
+ prependcommands(commands,yoffset,xoffset)
else
- -- local slot = { "slot", 1, addprivate(target,nil,fastcopy(character)) }
- local slot = { "slot", 0, addprivate(target,nil,fastcopy(character)) }
+ local slot = charcommand[unicode]
if xoffset and yoffset then
character.commands = { xoffset, yoffset, slot }
elseif xoffset then
@@ -297,7 +304,6 @@ function mathematics.overloaddimensions(target,original,set)
character.commands = { yoffset, slot }
end
end
- character.index = nil
end
elseif trace_defining then
report_math("no overloading dimensions of %C, not in font",unicode)
diff --git a/tex/context/base/mkiv/math-dir.lua b/tex/context/base/mkiv/math-dir.lua
index 759f1e797..0543937f5 100644
--- a/tex/context/base/mkiv/math-dir.lua
+++ b/tex/context/base/mkiv/math-dir.lua
@@ -60,7 +60,6 @@ local a_mathbidi = attributes.private('mathbidi')
local function processmath(head)
local current = head
- local done = false
local start = nil
local stop = nil
local function capsulate()
@@ -69,7 +68,6 @@ local function processmath(head)
if trace_directions then
report_directions("reversed: %s",nodes.listtoutf(start,false,false,stop))
end
- done = true
start = false
stop = nil
end
@@ -100,7 +98,6 @@ local function processmath(head)
if trace_directions then
report_directions("mirrored: %C to %C",char,mirror)
end
- done = true
end
end
end
@@ -108,11 +105,8 @@ local function processmath(head)
elseif not start then
-- nothing
if id == hlist_code or id == vlist_code then
- local list, d = processmath(getlist(current))
+ local list = processmath(getlist(current))
setlist(current,list)
- if d then
- done = true
- end
end
elseif start == stop then
start = nil
@@ -121,11 +115,8 @@ local function processmath(head)
-- math can pack things into hlists .. we need to make sure we don't process
-- too often: needs checking
if id == hlist_code or id == vlist_code then
- local list, d = processmath(getlist(current))
+ local list = processmath(getlist(current))
setlist(current,list)
- if d then
- done = true
- end
end
end
current = getnext(current)
@@ -137,21 +128,18 @@ local function processmath(head)
else
capsulate()
end
- return head, done
+ return head
end
local enabled = false
function directions.processmath(head) -- style, penalties
if enabled then
- local h = tonut(head)
- local a = getattr(h,a_mathbidi)
+ local a = getattr(head,a_mathbidi)
if a and a > 0 then
- local head, done = processmath(h)
- return tonode(head), done
+ return processmath(head)
end
end
- return head, false
end
function directions.setmath(n)
diff --git a/tex/context/base/mkiv/math-fen.mkiv b/tex/context/base/mkiv/math-fen.mkiv
index a32ea410e..3a32f9fb8 100644
--- a/tex/context/base/mkiv/math-fen.mkiv
+++ b/tex/context/base/mkiv/math-fen.mkiv
@@ -65,14 +65,19 @@
% we need the direct use of \Udelimiter because of { etc
-\newconditional\c_math_fenced_mirror \settrue\c_math_fenced_mirror
+\newconditional\c_math_fenced_mirror \settrue \c_math_fenced_mirror
+\newconditional\c_math_fenced_sized \setfalse\c_math_fenced_sized
\unexpanded\def\math_fenced_inject#1#2#3#4%
{\ifx#1\empty
#2.%
\else
\edef\p_mathclass{\mathfenceparameter\c!mathclass}%
- \edef\p_factor{\mathfenceparameter\c!factor}%
+ \ifconditional\c_math_fenced_sized
+ \let\p_factor\v!fixed
+ \else
+ \edef\p_factor{\mathfenceparameter\c!factor}%
+ \fi
\ifx\p_factor\empty
\ifx\p_mathclass\empty
#2%
@@ -97,7 +102,11 @@
\s!axis
% #2%
\else
- \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax
+ \ifx\p_factor\v!fixed
+ \scratchdimen\scaledpoint
+ \else
+ \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax
+ \fi
#3%
\s!height\scratchdimen
\s!depth\scratchdimen
@@ -121,16 +130,14 @@
\mathfenceparameter\c!left
\fi}%
\math_fenced_color_push
- % \normalleft\ifx\p_left\empty.\else\Udelimiter\plusfour\fam\p_left\relax\fi
\math_fenced_inject\p_left\normalleft\Uleft\plusfour
\math_fenced_color_pop}
\def\math_fenced_middle
{\edef\p_middle
- {\mathfenceparameter\c!middle}%
+ {\mathfenceparameter\c!middle}%
\mskip\thinmuskip
\math_fenced_color_push
- % \normalmiddle\ifx\p_middle\empty.\else\Udelimiter\plusfour\fam\p_middle\relax\fi
\math_fenced_inject\p_middle\normalmiddle\Umiddle\plusfour
\math_fenced_color_pop
\mskip\thinmuskip}
@@ -147,7 +154,6 @@
\mathfenceparameter\c!right
\fi}%
\math_fenced_color_push
- % \normalright \ifx\p_right\empty.\else\Udelimiter\plusfive\fam\p_right\relax\fi
\math_fenced_inject\p_right\normalright\Uright\plusfive
\math_fenced_color_pop}
@@ -194,16 +200,60 @@
\edef\currentmathfence{#1}%
\dosingleempty\math_fenced_fenced_indeed}
-\unexpanded\def\math_fenced_fenced_indeed[#1]#2%
+\def\math_fenced_force_size#1#2%
+ {\attribute\mathsizeattribute\numexpr#1*\plushundred+#2\relax}
+
+% \unexpanded\def\math_fenced_fenced_indeed[#1]#2%
+% {\iffirstargument\setupcurrentmathfence[#1]\fi
+% \math_fenced_fenced_common
+% \edef\p_size{\mathfenceparameter\c!size}%
+% \ifx\p_size\empty
+% \setfalse\c_math_fenced_sized
+% \else
+% \settrue\c_math_fenced_sized
+% \math_fenced_force_size\bigmathdelimitervariant\p_size
+% \fi
+% \math_fenced_left
+% #2%
+% \math_fenced_right
+% \stopusemathstyleparameter
+% \endgroup
+% \advance\c_math_fenced_nesting\minusone}
+
+\unexpanded\def\math_fenced_fenced_indeed[#1]%
{\iffirstargument\setupcurrentmathfence[#1]\fi
\math_fenced_fenced_common
- \math_fenced_left
- #2%
- \math_fenced_right
- \stopusemathstyleparameter
+ \edef\p_size{\mathfenceparameter\c!size}%
+ \ifx\p_size\empty
+ \expandafter\math_fenced_fenced_indeed_adapt
+ \else
+ \expandafter\math_fenced_fenced_indeed_fixed
+ \fi}
+
+\unexpanded\def\math_fenced_fenced_indeed_finish
+ {\stopusemathstyleparameter
\endgroup
\advance\c_math_fenced_nesting\minusone}
+\unexpanded\def\math_fenced_fenced_indeed_fixed#1%
+ {\math_fenced_force_size\bigmathdelimitervariant\p_size
+ \settrue\c_math_fenced_sized
+ \math_fenced_left
+ \setfalse\c_math_fenced_sized
+ #1%
+ \settrue\c_math_fenced_sized
+ \math_fenced_right
+ \setfalse\c_math_fenced_sized
+ \math_fenced_fenced_indeed_finish}
+
+\unexpanded\def\math_fenced_fenced_indeed_adapt#1%
+ {\setfalse\c_math_fenced_sized
+ \math_fenced_left
+ #1%
+ \setfalse\c_math_fenced_sized
+ \math_fenced_right
+ \math_fenced_fenced_indeed_finish}
+
\appendtoks
\let\fenced\math_fenced_fenced
\to \everymathematics
@@ -591,7 +641,7 @@
\ifcase\bigmathdelimitermethod
\math_fenced_step#2\relax
\or
- \attribute\mathsizeattribute\numexpr\bigmathdelimitervariant*\plushundred+#1\relax
+ \math_fenced_force_size\bigmathdelimitervariant{#1}\relax
\math_fenced_step#2\relax
\else
\math_fenced_step#2{\vpack to\csname\??mathbig\number#1\endcsname\bodyfontsize{}}%
@@ -621,7 +671,7 @@
\unexpanded\def\mathdelimiterstep#1#2%
{\begingroup
- \attribute\mathsizeattribute\numexpr\plushundred+#1\relax
+ \math_fenced_force_size\plusone{#1}%
\math_fenced_step#2\relax
\endgroup}
diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua
index b79ef8c8c..d301b0065 100644
--- a/tex/context/base/mkiv/math-ini.lua
+++ b/tex/context/base/mkiv/math-ini.lua
@@ -641,7 +641,7 @@ function mathematics.big(tfmdata,unicode,n,method)
end
end
end
- else
+ elseif method == 3 then
local size = 1.33^n
if method == 4 then
size = tfmdata.parameters.size * size
diff --git a/tex/context/base/mkiv/math-noa.lua b/tex/context/base/mkiv/math-noa.lua
index 20f77411e..bb0817d9a 100644
--- a/tex/context/base/mkiv/math-noa.lua
+++ b/tex/context/base/mkiv/math-noa.lua
@@ -88,7 +88,6 @@ local a_exportstatus = privateattribute("exportstatus")
local nuts = nodes.nuts
local nodepool = nuts.pool
local tonut = nuts.tonut
-local tonode = nuts.tonode
local nutstring = nuts.tostring
local setfield = nuts.setfield
@@ -102,6 +101,8 @@ local setsubtype = nuts.setsubtype
local setattr = nuts.setattr
local setattrlist = nuts.setattrlist
local setwidth = nuts.setwidth
+local setheight = nuts.setheight
+local setdepth = nuts.setdepth
local getfield = nuts.getfield
local getnext = nuts.getnext
@@ -114,6 +115,9 @@ local getfont = nuts.getfont
local getfam = nuts.getfam
local getattr = nuts.getattr
local getlist = nuts.getlist
+local getwidth = nuts.getwidth
+local getheight = nuts.getheight
+local getdepth = nuts.getdepth
local getnucleus = nuts.getnucleus
local getsub = nuts.getsub
@@ -299,7 +303,7 @@ local function process(start,what,n,parent)
start = getnext(start)
end
if not parent then
- return initial, true -- only first level -- for now
+ return initial -- only first level -- for now
end
end
@@ -376,15 +380,14 @@ local function processstep(current,process,n,id)
end
local function processnoads(head,actions,banner)
- local h, d
if trace_processing then
report_processing("start %a",banner)
- h, d = process(tonut(head),actions)
+ head = process(head,actions)
report_processing("stop %a",banner)
else
- h, d = process(tonut(head),actions)
+ head = process(head,actions)
end
- return h and tonode(h) or head, d == nil and true or d
+ return head
end
noads.process = processnoads
@@ -776,40 +779,38 @@ do
local method, size = div(a,100), a % 100
setattr(pointer,a_mathsize,0)
local delimiter = getfield(pointer,"delim")
- local chr = getfield(delimiter,"small_char")
+ local chr = getchar(delimiter)
if chr > 0 then
- local fam = getfield(delimiter,"small_fam")
+ local fam = getfam(delimiter)
local id = font_of_family(fam)
if id > 0 then
- setfield(delimiter,"small_char",mathematics.big(fontdata[id],chr,size,method))
+ local data = fontdata[id]
+ local char = mathematics.big(data,chr,size,method)
+ local ht = getfield(pointer,"height")
+ -- local ht = getheight(pointer) -- LUATEXVERSION >= 1.090
+ local dp = getfield(pointer,"depth")
+ -- local dp = getdepth(pointer) -- LUATEXVERSION >= 1.090
+ if ht == 1 or dp == 1 then -- 1 scaled point is a signal
+ local chardata = data.characters[char]
+ if ht == 1 then
+ setfield(pointer,"height",chardata.height)
+ -- setheight(pointer,chardata.height) -- LUATEXVERSION >= 1.090
+ end
+ if dp == 1 then
+ setfield(pointer,"depth",chardata.depth)
+ -- setdepth(pointer,chardata.depth) -- LUATEXVERSION >= 1.090
+ end
+ end
+ if trace_fences then
+ report_fences("replacing %C by %C using method %a and size %a",chr,char,method,size)
+ end
+ setchar(delimiter,char)
end
end
end
end
end
- -- will become:
-
- -- resize[math_fence] = function(pointer)
- -- local subtype = getsubtype(pointer)
- -- if subtype == left_fence_code or subtype == right_fence_code then
- -- local a = getattr(pointer,a_mathsize)
- -- if a and a > 0 then
- -- local method, size = div(a,100), a % 100
- -- setattr(pointer,a_mathsize,0)
- -- local delimiter = getfield(pointer,"delim")
- -- local chr = getchar(delimiter)
- -- if chr > 0 then
- -- local fam = getfam(delimiter)
- -- local id = font_of_family(fam)
- -- if id > 0 then
- -- setchar(delimiter,mathematics.big(fontdata[id],chr,size,method))
- -- end
- -- end
- -- end
- -- end
- -- end
-
function handlers.resize(head,style,penalties)
processnoads(head,resize,"resize")
return true
@@ -1038,7 +1039,7 @@ do
function handlers.autofences(head,style,penalties)
if enabled then -- tex.modes.c_math_fences_auto
-- inspect(nodes.totree(head))
- processfences(tonut(head),1)
+ processfences(head,1)
-- inspect(nodes.totree(head))
end
end
@@ -1136,7 +1137,6 @@ do
function handlers.unscript(head,style,penalties)
processnoads(head,unscript,"unscript")
- -- processnoads(head,checkers,"checkers")
return true
end
@@ -2177,7 +2177,7 @@ end
-- just for me
function handlers.showtree(head,style,penalties)
- inspect(nodes.totree(head))
+ inspect(nodes.totree(tonut(head)))
end
registertracker("math.showtree",function(v)
@@ -2192,7 +2192,7 @@ do
local visual = false
function handlers.makeup(head)
- applyvisuals(tonut(head),visual)
+ applyvisuals(head,visual)
end
registertracker("math.makeup",function(v)
@@ -2213,7 +2213,7 @@ do
-- end)
function builders.kernel.mlist_to_hlist(head,style,penalties)
- return mlist_to_hlist(head,style,force_penalties or penalties), true
+ return mlist_to_hlist(head,style,force_penalties or penalties)
end
implement {
@@ -2226,41 +2226,15 @@ do
end
--- function builders.kernel.mlist_to_hlist(head,style,penalties)
--- print("!!!!!!! BEFORE",penalties)
--- for n in node.traverse(head) do print(n) end
--- print("!!!!!!!")
--- head = mlist_to_hlist(head,style,penalties)
--- print("!!!!!!! AFTER")
--- for n in node.traverse(head) do print(n) end
--- print("!!!!!!!")
--- return head, true
--- end
-
-tasks.new {
- name = "math",
- arguments = 2,
- processor = utilities.sequencers.nodeprocessor,
- sequence = {
- "before",
- "normalizers",
- "builders",
- "after",
- },
-}
-
-tasks.freezegroup("math", "normalizers") -- experimental
-tasks.freezegroup("math", "builders") -- experimental
-
local actions = tasks.actions("math") -- head, style, penalties
local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
function processors.mlist_to_hlist(head,style,penalties)
starttiming(noads)
- local head, done = actions(head,style,penalties)
+ head = actions(head,style,penalties)
stoptiming(noads)
- return head, done
+ return head
end
callbacks.register('mlist_to_hlist',processors.mlist_to_hlist,"preprocessing math list")
diff --git a/tex/context/base/mkiv/math-spa.lua b/tex/context/base/mkiv/math-spa.lua
index 92ee662b9..69f70ded5 100644
--- a/tex/context/base/mkiv/math-spa.lua
+++ b/tex/context/base/mkiv/math-spa.lua
@@ -8,22 +8,22 @@ if not modules then modules = { } end modules ['math-spa'] = {
-- for the moment (when testing) we use a penalty 1
-local penalty_code = nodes.nodecodes.penalty
-local glue_code = nodes.nodecodes.glue
+local penalty_code = nodes.nodecodes.penalty
+local glue_code = nodes.nodecodes.glue
-local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
-local getid = nuts.getid
-local getnext = nuts.getnext
-local getwidth = nuts.getwidth
-local setglue = nuts.setglue
-local getpenalty = nuts.getpenalty
-local setpenalty = nuts.setpenalty
+local nuts = nodes.nuts
+local tonut = nodes.tonut
+local tonode = nodes.tonode
+local getid = nuts.getid
+local getnext = nuts.getnext
+local getwidth = nuts.getwidth
+local setglue = nuts.setglue
+local getpenalty = nuts.getpenalty
+local setpenalty = nuts.setpenalty
-local traverse_id = nuts.traverse_id
local get_dimensions = nuts.dimensions
+local nextglue = nuts.traversers.glue
local texsetdimen = tex.setdimen
@@ -33,9 +33,8 @@ local v_auto = interfaces.variables.auto
local method = v_none
local distance = 0
-function noads.handlers.align(l)
+function noads.handlers.align(h)
if method ~= v_none then
- local h = tonut(l)
if method == v_auto then
local s = h
while s do
@@ -56,13 +55,12 @@ function noads.handlers.align(l)
else
texsetdimen("global","d_strc_math_indent",distance)
end
- for n in traverse_id(glue_code,h) do
+ for n in nextglue, h do
setglue(n,getwidth(n),0,0)
end
else
-- texsetdimen("global","d_strc_math_indent",0)
end
- return l, true
end
interfaces.implement {
diff --git a/tex/context/base/mkiv/math-tag.lua b/tex/context/base/mkiv/math-tag.lua
index 9837dec35..868c2b661 100644
--- a/tex/context/base/mkiv/math-tag.lua
+++ b/tex/context/base/mkiv/math-tag.lua
@@ -38,7 +38,8 @@ local getsub = nuts.getsub
local getsup = nuts.getsup
local set_attributes = nuts.setattributes
-local traverse_nodes = nuts.traverse
+
+local nextnode = nuts.traversers.node
local nodecodes = nodes.nodecodes
@@ -248,101 +249,101 @@ process = function(start) -- we cannot use the processor as we have no finalizer
elseif id == math_box_code or id == hlist_code or id == vlist_code then
-- keep an eye on math_box_code and see what ends up in there
local attr = getattr(start,a_tagged)
-if not attr then
- -- just skip
-else
- local specification = taglist[attr]
- if specification then
- local tag = specification.tagname
- if tag == "formulacaption" then
- -- skip
- elseif tag == "mstacker" then
- local list = getlist(start)
- if list then
- process(list)
- end
- else
- if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then
- tag = "mtext"
- end
- local text = start_tagged(tag)
- setattr(start,a_tagged,text)
- local list = getlist(start)
- if not list then
- -- empty list
- elseif not attr then
- -- box comes from strange place
- set_attributes(list,a_tagged,text) -- only the first node ?
+ if not attr then
+ -- just skip
+ else
+ local specification = taglist[attr]
+ if specification then
+ local tag = specification.tagname
+ if tag == "formulacaption" then
+ -- skip
+ elseif tag == "mstacker" then
+ local list = getlist(start)
+ if list then
+ process(list)
+ end
else
- -- Beware, the first node in list is the actual list so we definitely
- -- need to nest. This approach is a hack, maybe I'll make a proper
- -- nesting feature to deal with this at another level. Here we just
- -- fake structure by enforcing the inner one.
- --
- -- todo: have a local list with local tags that then get appended
- --
- local tagdata = specification.taglist
- local common = #tagdata + 1
- local function runner(list,depth) -- quite inefficient
- local cache = { } -- we can have nested unboxed mess so best local to runner
- local keep = nil
- -- local keep = { } -- win case we might need to move keep outside
- for n, id in traverse_nodes(list) do
- local mth = id == math_code and getsubtype(n)
- if mth == 0 then
- -- insert(keep,text)
- keep = text
- text = start_tagged("mrow")
- common = common + 1
- end
- local aa = getattr(n,a_tagged)
- if aa then
- local ac = cache[aa]
- if not ac then
- local tagdata = taglist[aa].taglist
- local extra = #tagdata
- if common <= extra then
- for i=common,extra do
- ac = restart_tagged(tagdata[i]) -- can be made faster
- end
- for i=common,extra do
- stop_tagged() -- can be made faster
+ if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then
+ tag = "mtext"
+ end
+ local text = start_tagged(tag)
+ setattr(start,a_tagged,text)
+ local list = getlist(start)
+ if not list then
+ -- empty list
+ elseif not attr then
+ -- box comes from strange place
+ set_attributes(list,a_tagged,text) -- only the first node ?
+ else
+ -- Beware, the first node in list is the actual list so we definitely
+ -- need to nest. This approach is a hack, maybe I'll make a proper
+ -- nesting feature to deal with this at another level. Here we just
+ -- fake structure by enforcing the inner one.
+ --
+ -- todo: have a local list with local tags that then get appended
+ --
+ local tagdata = specification.taglist
+ local common = #tagdata + 1
+ local function runner(list,depth) -- quite inefficient
+ local cache = { } -- we can have nested unboxed mess so best local to runner
+ local keep = nil
+ -- local keep = { } -- win case we might need to move keep outside
+ for n, id, subtype in nextnode, list do
+ local mth = id == math_code and subtype
+ if mth == 0 then -- hm left_code
+ -- insert(keep,text)
+ keep = text
+ text = start_tagged("mrow")
+ common = common + 1
+ end
+ local aa = getattr(n,a_tagged)
+ if aa then
+ local ac = cache[aa]
+ if not ac then
+ local tagdata = taglist[aa].taglist
+ local extra = #tagdata
+ if common <= extra then
+ for i=common,extra do
+ ac = restart_tagged(tagdata[i]) -- can be made faster
+ end
+ for i=common,extra do
+ stop_tagged() -- can be made faster
+ end
+ else
+ ac = text
end
- else
- ac = text
+ cache[aa] = ac
end
- cache[aa] = ac
+ setattr(n,a_tagged,ac)
+ else
+ setattr(n,a_tagged,text)
end
- setattr(n,a_tagged,ac)
- else
- setattr(n,a_tagged,text)
- end
- if id == hlist_code or id == vlist_code then
- runner(getlist(n),depth+1)
- elseif id == glyph_code then
- -- this should not be needed (todo: use tounicode info)
- runner(getcomponents(n),depth+1)
- elseif id == disc_code then
- local pre, post, replace = getdisc(n)
- runner(pre,depth+1) -- idem
- runner(post,depth+1) -- idem
- runner(replace,depth+1) -- idem
- end
- if mth == 1 then
- stop_tagged()
- -- text = remove(keep)
- text = keep
- common = common - 1
+ if id == hlist_code or id == vlist_code then
+ runner(getlist(n),depth+1)
+ elseif id == glyph_code then
+ -- this should not be needed (todo: use tounicode info)
+ runner(getcomponents(n),depth+1)
+ elseif id == disc_code then
+ local pre, post, replace = getdisc(n)
+ runner(pre,depth+1) -- idem
+ runner(post,depth+1) -- idem
+ runner(replace,depth+1) -- idem
+ end
+ if mth == 1 then
+ stop_tagged()
+ -- text = remove(keep)
+ text = keep
+ common = common - 1
+ end
end
end
+ runner(list,0)
end
- runner(list,0)
+ stop_tagged()
end
- stop_tagged()
end
end
-end
elseif id == math_sub_code then -- normally a hbox
local list = getlist(start)
if list then
@@ -551,12 +552,10 @@ end
end
function noads.handlers.tags(head,style,penalties)
- head = tonut(head)
local v_mode = getattr(head,a_mathmode)
local v_math = start_tagged("math", { mode = v_mode == 1 and "display" or "inline" })
setattr(head,a_tagged,start_tagged("mrow"))
process(head)
stop_tagged()
stop_tagged()
- return true
end
diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua
index 189f207c7..60ad9477b 100644
--- a/tex/context/base/mkiv/mlib-lua.lua
+++ b/tex/context/base/mkiv/mlib-lua.lua
@@ -60,7 +60,7 @@ function mp._f_()
end
end
-local f_code = formatters["%s return mp._f_()"]
+local f_code = formatters["%s return mp._f_()"]
local f_numeric = formatters["%.16f"]
local f_integer = formatters["%i"]
@@ -128,6 +128,8 @@ local function mpvprint(...) -- variable print
end
end
+mp.cleaned = function(s) return lpegmatch(p,s) or s end
+
mp.print = mpprint
mp.vprint = mpvprint
diff --git a/tex/context/base/mkiv/mult-aux.mkiv b/tex/context/base/mkiv/mult-aux.mkiv
index a1aecc354..9ba09af41 100644
--- a/tex/context/base/mkiv/mult-aux.mkiv
+++ b/tex/context/base/mkiv/mult-aux.mkiv
@@ -180,6 +180,10 @@
\def\mult_check_for_assignment_indeed#1=#2#3\_end_
{\if#2@\assignmentfalse\else\assignmenttrue\fi}
+\def\mult_check_for_assignment_indeed_begin_#1=#2#3\_end_
+ {\if#2@}
+
+
\def\mult_check_for_assignment#1%
{\expandafter\mult_check_for_assignment_indeed\detokenize{#1}=@@\_end_}
@@ -389,6 +393,43 @@
\the#7%
\let#4#9}}
+% \unexpanded\def\mult_interfaces_install_define_handler#1#2#3#4#5#6#7#8#9% why is \expanded still needed in clones
+% {\ifx#4\relax\let#4\empty\fi % see \defineregister
+% \unexpanded\def#2{\dotripleempty#5}%
+% \newtoks#6%
+% \newtoks#7%
+% \unexpanded\def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child]
+% {\let#9#4%
+% \edef#4{##1}%
+% \ifthirdargument
+% \the#6% predefine
+% \edef#8{##2}%
+% \mult_check_for_parent{#1}{#3}#4#8%
+% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}%
+% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}%
+% \mult_interfaces_get_parameters{#1#4:}[##3]%
+% \else\ifsecondargument
+% \the#6% predefine
+% \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##2}=@@\_end_
+% \edef#8{##2}%
+% \mult_check_for_parent{#1}{#3}#4#8%
+% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}%
+% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}%
+% \else
+% \let#8\empty
+% \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}%
+% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}%
+% \mult_interfaces_get_parameters{#1#4:}[##2]%
+% \fi
+% \else
+% \the#6% predefine
+% \let#8\empty
+% \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}%
+% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}%
+% \fi\fi
+% \the#7%
+% \let#4#9}}
+
\unexpanded\def\installdefinehandler#1#2#3%
{\normalexpanded
{\mult_interfaces_install_define_handler
@@ -466,7 +507,7 @@
\let#3#7%
\else\iffirstargument
% \mult_check_for_assignment{##1}%
- \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=@@\_end_
+ \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=@@\_end_
\ifassignment
% \setuplayout[key=value]
\let#7#3%
@@ -496,6 +537,54 @@
#2\zerocount % mode is always zero at the end
\the#9}}
+% \unexpanded\def\mult_interfaces_install_switch_setup_handler_b#1#2#3#4#5#6#7#8#9%
+% {\newtoks#5%
+% \newconstant#2%
+% \newtoks#8%
+% \newtoks#9%
+% \ifx#6\relax\let#6\empty\fi
+% \unexpanded\def#4[##1][##2]% maybe helper
+% {\ifsecondargument % no commalist here
+% % \setuplayout[whatever][key=value]
+% \let#7#3%
+% \let#6#3%
+% \edef#3{##1}%
+% #2\doingrootsetupnamed
+% \mult_interfaces_get_parameters{#1#3:}[##2]%
+% \the#5%
+% \ifx#3#6\the#8\fi % only switchsetups if previous == current
+% \let#3#7%
+% \else\iffirstargument
+% % \mult_check_for_assignment{##1}%
+% \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##1}=@@\_end_
+% % \setuplayout[whatever]
+% \let#6#3% % previous becomes current
+% \edef#3{##1}% this will catch reset so one needs to test for it
+% #2\doingrootsetnamed
+% \the#5% % we can check for previous vs current
+% \the#8% switchsetups
+% \else
+% % \setuplayout[key=value]
+% \let#7#3%
+% \let#6#3%
+% \let#3\empty
+% #2\doingrootsetuproot
+% \mult_interfaces_get_parameters{#1:}[##1]%
+% \the#5%
+% \the#8% switchsetups
+% \let#3#7%
+% \fi
+% \else
+% % \setuplayout
+% \let#6#3% % previous becomes current
+% \let#3\empty % current becomes empty
+% #2\doingrootsetroot
+% \the#5%
+% \the#8% switchsetups
+% \fi\fi
+% #2\zerocount % mode is always zero at the end
+% \the#9}}
+
\unexpanded\def\installswitchsetuphandler#1#2%
{\normalexpanded
{\mult_interfaces_install_switch_setup_handler_a
diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua
index 9b7062605..1ee593be4 100644
--- a/tex/context/base/mkiv/mult-fun.lua
+++ b/tex/context/base/mkiv/mult-fun.lua
@@ -53,7 +53,7 @@ return {
"shadedinto", "withshadecolors",
"withshadedomain", "withshademethod", "withshadefactor", "withshadevector",
"withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform",
- "withshadestep", "withshadefraction",
+ "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin",
"cmyk", "spotcolor", "multitonecolor", "namedcolor",
"drawfill", "undrawfill",
"inverted", "uncolored", "softened", "grayed", "greyed",
diff --git a/tex/context/base/mkiv/mult-ini.mkiv b/tex/context/base/mkiv/mult-ini.mkiv
index ef9dcd249..117ac768c 100644
--- a/tex/context/base/mkiv/mult-ini.mkiv
+++ b/tex/context/base/mkiv/mult-ini.mkiv
@@ -343,17 +343,17 @@
%D These will become obsolete:
\unexpanded\def\startmessages #1 library: #2 %
- {\bgroup
+ {\begingroup
\ifcsname\m!prefix!#2\endcsname\else\setgvalue{\m!prefix!#2}{#2}\fi
- \catcode\endoflineasciicode\activecatcode
+ \catcode\endoflineasciicode\othercatcode
\doifelseinset{#1}{\currentresponses,all}\mult_messages_start_yes\mult_messages_start_nop{#2}}
\def\mult_messages_start_yes#1#2\stopmessages
{\clf_setinterfacemessages{#1}{#2}%
- \egroup}
+ \endgroup}
\def\mult_messages_start_nop#1#2\stopmessages
- {\egroup}
+ {\endgroup}
\let\stopmessages\relax
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index e10a8e6fa..f425f3a32 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -410,7 +410,7 @@ return {
"installctxscanner", "installctxscannercall",
"resetctxscanner",
"installprotectedctxscanner", "installprotectedctxscannercall",
- "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand",
+ "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand",
--
"carryoverpar",
"lastlinewidth",
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index 6351df180..1bf5bb526 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -261,6 +261,8 @@ return {
"ifincsname",
"ifprimitive",
"ignoreligaturesinfont",
+ "immediateassignment",
+ "immediateassigned",
"initcatcodetable",
"insertht",
"lastnamedcs",
@@ -826,4 +828,4 @@ return {
["xetex"]={
"XeTeXversion",
},
-} \ No newline at end of file
+}
diff --git a/tex/context/base/mkiv/node-acc.lua b/tex/context/base/mkiv/node-acc.lua
index 03f6d7476..8d9acaf9b 100644
--- a/tex/context/base/mkiv/node-acc.lua
+++ b/tex/context/base/mkiv/node-acc.lua
@@ -28,8 +28,9 @@ local setsubtype = nuts.setsubtype
local getwidth = nuts.getwidth
local setwidth = nuts.setwidth
------ traverse_nodes = nuts.traverse
-local traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
+local nextnode = nuts.traversers.node
+
----- copy_node = nuts.copy
local insert_after = nuts.insert_after
local copy_no_components = nuts.copy_no_components
@@ -77,12 +78,11 @@ local function injectspaces(head)
p = n
n = getnext(n)
end
- return head, true -- always done anyway
+ return head
end
nodes.handlers.accessibility = function(head)
- local head, done = injectspaces(tonut(head))
- return tonode(head), done
+ return injectspaces(head)
end
statistics.register("inserted spaces in output",function()
@@ -99,7 +99,7 @@ end)
--
-- local function compact(n)
-- local t = { }
--- for n in traverse_id(glyph_code,n) do
+-- for n in nextglyph, n do
-- t[#t+1] = utfchar(getchar(n)) -- check for unicode
-- end
-- return concat(t,"")
@@ -107,8 +107,7 @@ end)
--
-- local function injectspans(head)
-- local done = false
--- for n in traverse_nodes(tonuts(head)) do
--- local id = getid(n)
+-- for n, id in nextnode, tonuts(head) do
-- if id == disc then
-- local r = getfield(n,"replace")
-- local p = getfield(n,"pre")
@@ -138,8 +137,7 @@ end)
--
-- local function injectspans(head)
-- local done = false
--- for n in traverse_nodes(tonut(head)) do
--- local id = getid(n)
+-- for n, id in nextnode, tonut(head) do
-- if id == disc then
-- local a = getattr(n,a_hyphenated)
-- if a then
diff --git a/tex/context/base/mkiv/node-aux.lua b/tex/context/base/mkiv/node-aux.lua
index 5e85ead1c..cdd3403ac 100644
--- a/tex/context/base/mkiv/node-aux.lua
+++ b/tex/context/base/mkiv/node-aux.lua
@@ -51,8 +51,10 @@ local setprev = nuts.setprev
local setcomponents = nuts.setcomponents
local setattrlist = nuts.setattrlist
-local traverse_nodes = nuts.traverse
-local traverse_id = nuts.traverse_id
+----- traverse_nodes = nuts.traverse
+----- traverse_id = nuts.traverse_id
+local nextnode = nuts.traversers.node
+local nextglyph = nuts.traversers.glyph
local flush_node = nuts.flush
local flush_list = nuts.flush_list
local hpack_nodes = nuts.hpack
@@ -154,7 +156,7 @@ function nodes.repackhlist(list,...)
end
local function set_attributes(head,attr,value)
- for n, id in traverse_nodes(head) do
+ 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)
@@ -163,7 +165,7 @@ local function set_attributes(head,attr,value)
end
local function set_unset_attributes(head,attr,value)
- for n, id in traverse_nodes(head) do
+ for n, id in nextnode, head do
if not getattr(n,attr) then
setattr(n,attr,value)
end
@@ -174,7 +176,7 @@ local function set_unset_attributes(head,attr,value)
end
local function unset_attributes(head,attr)
- for n, id in traverse_nodes(head) do
+ 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)
@@ -285,7 +287,7 @@ function nuts.firstcharacter(n,untagged) -- tagged == subtype > 255
if untagged then
return first_glyph(n)
else
- for g in traverse_id(glyph_code,n) do
+ for g in nextglyph ,n do
return g
end
end
@@ -294,7 +296,7 @@ end
local function firstcharinbox(n)
local l = getlist(getbox(n))
if l then
- for g in traverse_id(glyph_code,l) do
+ for g in nextglyph, l do
return getchar(g)
end
end
@@ -428,9 +430,9 @@ nodes.link = function(list,currentfont,currentattr,head,tail)
end
local function locate(start,wantedid,wantedsubtype)
- for n, id in traverse_nodes(start) do
+ for n, id, subtype in nextnode, start do
if id == wantedid then
- if not wantedsubtype or getsubtype(n) == wantedsubtype then
+ if not wantedsubtype or subtype == wantedsubtype then
return n
end
elseif id == hlist_code or id == vlist_code then
@@ -553,7 +555,7 @@ function nuts.count_components(n,marks)
if components then
if marks then
local i = 0
- for g in traverse_id(glyph_code,components) do
+ for g in nextglyph, components do
if not marks[getchar(g)] then
i = i + 1
end
@@ -592,7 +594,7 @@ end
function nuts.copy_only_glyphs(current)
local head = nil
local previous = nil
- for n in traverse_id(glyph_code,current) do
+ for n in nextglyph, current do
n = copy_node(n)
if head then
setlink(previous,n)
diff --git a/tex/context/base/mkiv/node-bck.lua b/tex/context/base/mkiv/node-bck.lua
index 995620710..8174888ee 100644
--- a/tex/context/base/mkiv/node-bck.lua
+++ b/tex/context/base/mkiv/node-bck.lua
@@ -27,9 +27,6 @@ local cell_code = listcodes.cell
local nuts = nodes.nuts
local nodepool = nuts.pool
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
@@ -49,13 +46,15 @@ local setprop = nuts.setprop
local takebox = nuts.takebox
local findtail = nuts.tail
-local traverse = nuts.traverse
-local traverse_id = nuts.traverse_id
+local nextnode = nuts.traversers.node
+local nexthlist = nuts.traversers.hlist
+local nextlist = nuts.traversers.list
local flush_node_list = nuts.flush_list
local new_rule = nodepool.rule
local new_kern = nodepool.kern
+local new_hlist = nodepool.hlist
local privateattributes = attributes.private
local unsetvalue = attributes.unsetvalue
@@ -84,6 +83,8 @@ trackers.register("backgrounds.alignments",function(v) trace_alignment = v end)
-- For color only we can get away with it with an extra attribute flagging a row
-- but for more complex stuff we can better do as we do here now.
+local overshoot = math.floor(65781/5) -- could be an option per table (just also store it)
+
local function colored_a(current,list,template,id)
local width, height, depth = getwhd(current)
local total = height + depth
@@ -101,8 +102,8 @@ local function colored_a(current,list,template,id)
if not rule then
rule = new_rule(width,height,depth)
end
- local back = new_kern(-((id == vlist_code and total) or width))
setattributelist(rule,template)
+ local back = new_kern(-((id == vlist_code and total) or width))
return setlink(rule,back,list)
end
end
@@ -123,11 +124,16 @@ local function colored_b(current,list,template,id,indent)
end
--
if not rule then
- rule = new_rule(width-indent,height,depth)
+ rule = new_rule(width-indent,height+overshoot,depth+overshoot)
setattributelist(rule,template)
end
- local back = new_kern(-((id == vlist_code and total) or width))
- return setlink(fore,rule,back,list)
+ if overshoot == 0 then
+ local back = new_kern(-((id == vlist_code and total) or width))
+ return setlink(fore,rule,back,list)
+ else
+ rule = new_hlist(rule)
+ return setlink(fore,rule,list)
+ end
end
end
@@ -137,11 +143,11 @@ local enabled = false
local alignments = false
local function add_alignbackgrounds(head,list)
- for current in traverse_id(hlist_code,list) do
+ for current in nexthlist, list do
if getsubtype(current) == cell_code then
local list = getlist(current)
if list then
- for template in traverse_id(hlist_code,list) do
+ for template in nexthlist, list do
local background = getattr(template,a_alignbackground)
if background then
local list = colored_a(current,list,template)
@@ -166,11 +172,11 @@ end
local function add_backgrounds(head,id,list)
if list then
- for current, id in traverse(list) do
+ for current, id, subtype in nextnode, list do
if id == hlist_code or id == vlist_code then
local list = getlist(current)
if list then
- if alignments and getsubtype(current) == alignment_code then
+ if alignments and subtype == alignment_code then
local l = add_alignbackgrounds(current,list)
if l then
list = l
@@ -197,16 +203,75 @@ local function add_backgrounds(head,id,list)
end
end
+if LUATEXVERSION >= 1.090 then
+
+ -- local function add_alignbackgrounds(head,list)
+ add_alignbackgrounds = function(head,list)
+ for current, id, subtype, list in nextlist, list do
+ if list and id == hlist_code and subtype == cell_code then
+ for template in nexthlist, list do
+ local background = getattr(template,a_alignbackground)
+ if background then
+ local list = colored_a(current,list,template)
+ if list then
+ setlist(current,list)
+ end
+ setattr(template,a_alignbackground,unsetvalue) -- or property
+ end
+ break
+ end
+ end
+ end
+ local template = getprop(head,"alignmentchecked")
+ if template then
+ list = colored_b(head,list,template[1],hlist_code,template[2])
+ flush_node_list(template)
+ templates[currentrow] = false
+ return list
+ end
+ end
+
+ -- local function add_backgrounds(head,id,list)
+ add_backgrounds = function(head,id,list)
+ if list then
+ for current, id, subtype, list in nextlist, list do
+ if list then
+ if alignments and subtype == alignment_code then
+ local l = add_alignbackgrounds(current,list)
+ if l then
+ list = l
+ setlist(current,list)
+ end
+ end
+ local l = add_backgrounds(current,id,list)
+ if l then
+ list = l
+ setlist(current,l)
+ end
+ end
+ end
+ end
+ if id == hlist_code or id == vlist_code then
+ local background = getattr(head,a_background)
+ if background then
+ list = colored_a(head,list,head,id)
+ -- not needed
+ setattr(head,a_background,unsetvalue) -- or property
+ return list
+ end
+ end
+ end
+
+end
+
function nodes.handlers.backgrounds(head)
- local h = tonut(head)
- add_backgrounds(h,getid(h),getlist(h))
- return head, true
+ add_backgrounds(head,getid(head),getlist(head))
+ return head
end
function nodes.handlers.backgroundspage(head,where)
if head and where == "alignment" then
- local head = tonut(head)
- for n in traverse_id(hlist_code,head) do
+ for n in nexthlist, head do
local p = getprop(n,"alignmentchecked")
if not p and getsubtype(n) == alignment_code then
currentrow = currentrow + 1
@@ -218,25 +283,27 @@ function nodes.handlers.backgroundspage(head,where)
end
end
end
- return head, true
+ return head
end
function nodes.handlers.backgroundsvbox(head,where)
if head and where == "vbox" then
- local head = tonut(head)
- for n in traverse_id(hlist_code,getlist(head)) do
- local p = getprop(n,"alignmentchecked")
- if not p and getsubtype(n) == alignment_code then
- currentrow = currentrow + 1
- local template = templates[currentrow]
- if trace_alignment then
- report_alignment("%03i %s %s",currentrow,"vbox",template and "+" or "-")
+ local list = getlist(head)
+ if list then
+ for n in nexthlist, list do
+ local p = getprop(n,"alignmentchecked")
+ if not p and getsubtype(n) == alignment_code then
+ currentrow = currentrow + 1
+ local template = templates[currentrow]
+ if trace_alignment then
+ report_alignment("%03i %s %s",currentrow,"vbox",template and "+" or "-")
+ end
+ setprop(n,"alignmentchecked",template)
end
- setprop(n,"alignmentchecked",template)
end
end
end
- return head, true
+ return head
end
-- interfaces.implement {
diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua
index 975eb0bec..f7e2c7904 100644
--- a/tex/context/base/mkiv/node-fin.lua
+++ b/tex/context/base/mkiv/node-fin.lua
@@ -16,7 +16,6 @@ local next, type, format = next, type, string.format
local attributes, nodes, node = attributes, nodes, node
local nuts = nodes.nuts
-local tonode = nuts.tonode
local tonut = nuts.tonut
local getnext = nuts.getnext
@@ -34,6 +33,8 @@ local copy_node = nuts.copy
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
+local nextnode = nuts.traversers.node
+
local nodecodes = nodes.nodecodes
local whatcodes = nodes.whatcodes
local rulecodes = nodes.rulecodes
@@ -44,6 +45,7 @@ local glue_code = nodecodes.glue
local rule_code = nodecodes.rule
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
+local localpar_code = nodecodes.localpar
local states = attributes.states
local numbers = attributes.numbers
@@ -82,37 +84,34 @@ local finalizer = plugin.finalizer
local flusher = plugin.flusher
if not processor then
return function(head)
- return head, false
+ return head
end
elseif initializer or finalizer or resolver then
return function(head)
starttiming(attributes)
- local done, used, ok, inheritance = false, nil, false, nil
+ local used, inheritance
if resolver then
inheritance = resolver()
end
if initializer then
initializer(namespace,attribute,head)
end
- head, ok = processor(namespace,attribute,head,inheritance)
- if ok then
- if finalizer then
- head, ok, used = finalizer(namespace,attribute,head)
- if used and flusher then
- head = flusher(namespace,attribute,head,used)
- end
+ head = processor(namespace,attribute,head,inheritance)
+ if finalizer then
+ head, used = finalizer(namespace,attribute,head)
+ if used and flusher then
+ head = flusher(namespace,attribute,head,used)
end
- done = true
end
stoptiming(attributes)
- return head, done
+ return head
end
else
return function(head)
starttiming(attributes)
- local head, done = processor(namespace,attribute,head)
+ head = processor(namespace,attribute,head)
stoptiming(attributes)
- return head, done
+ return head
end
end
nodes.plugindata = nil
@@ -126,7 +125,7 @@ end
-- the injectors
local nsdata, nsnone, nslistwise, nsforced, nsselector, nstrigger
-local current, current_selector, done = 0, 0, false -- nb, stack has a local current !
+local current, current_selector = 0, 0 -- nb, stack has a local current !
local nsbegin, nsend, nsreset
function states.initialize(namespace,attribute,head)
@@ -138,7 +137,6 @@ function states.initialize(namespace,attribute,head)
nstrigger = triggering and namespace.triggering and a_trigger
current = 0
current_selector = 0
- done = false -- todo: done cleanup
nsstep = namespace.resolve_step
if nsstep then
nsreset = namespace.resolve_reset
@@ -151,7 +149,6 @@ end
function states.finalize(namespace,attribute,head) -- is this one ok?
if current > 0 and nsnone then
- head = tonut(head)
local id = getid(head)
if id == hlist_code or id == vlist_code then
local content = getlist(head)
@@ -164,20 +161,114 @@ function states.finalize(namespace,attribute,head) -- is this one ok?
else
head = insert_node_before(head,head,copy_node(nsnone))
end
- return tonode(head), true, true
+ return head, true
end
- return head, false, false
+ return head, false
end
-- we need to deal with literals too (reset as well as oval)
+-- local function process(attribute,head,inheritance,default) -- one attribute
+-- local stack = head
+-- local check = false
+-- local leader = nil
+-- while stack do
+-- local id = getid(stack)
+-- if id == glyph_code or id == disc_code then
+-- check = true -- disc no longer needed as we flatten replace
+-- elseif id == glue_code then
+-- leader = getleader(stack)
+-- if leader then
+-- check = true
+-- end
+-- elseif id == hlist_code or id == vlist_code then
+-- local content = getlist(stack)
+-- if content then
+-- -- begin nested --
+-- local list
+-- if nstrigger and getattr(stack,nstrigger) then
+-- local outer = getattr(stack,attribute)
+-- if outer ~= inheritance then
+-- list = process(attribute,content,inheritance,outer)
+-- else
+-- list = process(attribute,content,inheritance,default)
+-- end
+-- else
+-- list = process(attribute,content,inheritance,default)
+-- end
+-- if content ~= list then
+-- setlist(stack,list)
+-- end
+-- -- end nested --
+-- end
+-- elseif id == rule_code then
+-- check = getwidth(stack) ~= 0
+-- end
+-- -- much faster this way than using a check() and nested() function
+-- if check then
+-- local c = getattr(stack,attribute)
+-- if c then
+-- if default and c == inheritance then
+-- if current ~= default then
+-- head = insert_node_before(head,stack,copy_node(nsdata[default]))
+-- current = default
+-- end
+-- elseif current ~= c then
+-- head = insert_node_before(head,stack,copy_node(nsdata[c]))
+-- current = c
+-- end
+-- if leader then
+-- local savedcurrent = current
+-- local ci = getid(leader)
+-- if ci == hlist_code or ci == vlist_code then
+-- -- else we reset inside a box unneeded, okay, the downside is
+-- -- that we trigger color in each repeated box, so there is room
+-- -- for improvement here
+-- current = 0
+-- end
+-- -- begin nested --
+-- local list
+-- if nstrigger and getattr(stack,nstrigger) then
+-- local outer = getattr(stack,attribute)
+-- if outer ~= inheritance then
+-- list = process(attribute,leader,inheritance,outer)
+-- else
+-- list = process(attribute,leader,inheritance,default)
+-- end
+-- else
+-- list = process(attribute,leader,inheritance,default)
+-- end
+-- if leader ~= list then
+-- setleader(stack,list)
+-- end
+-- -- end nested --
+-- current = savedcurrent
+-- leader = false
+-- end
+-- elseif default and inheritance then
+-- if current ~= default then
+-- head = insert_node_before(head,stack,copy_node(nsdata[default]))
+-- current = default
+-- end
+-- elseif current > 0 then
+-- head = insert_node_before(head,stack,copy_node(nsnone))
+-- current = 0
+-- end
+-- check = false
+-- end
+-- stack = getnext(stack)
+-- end
+-- return head
+-- end
+--
+-- states.process = function(namespace,attribute,head,default)
+-- return process(attribute,head,default)
+-- end
+
local function process(attribute,head,inheritance,default) -- one attribute
- local stack = head
- local done = false
local check = false
local leader = nil
- while stack do
- local id = getid(stack)
+ for stack, id in nextnode, head do
if id == glyph_code or id == disc_code then
check = true -- disc no longer needed as we flatten replace
elseif id == glue_code then
@@ -189,33 +280,19 @@ local function process(attribute,head,inheritance,default) -- one attribute
local content = getlist(stack)
if content then
-- begin nested --
+ local list
if nstrigger and getattr(stack,nstrigger) then
local outer = getattr(stack,attribute)
if outer ~= inheritance then
- local list, ok = process(attribute,content,inheritance,outer)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,content,inheritance,outer)
else
- local list, ok = process(attribute,content,inheritance,default)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,content,inheritance,default)
end
else
- local list, ok = process(attribute,content,inheritance,default)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,content,inheritance,default)
+ end
+ if content ~= list then
+ setlist(stack,list)
end
-- end nested --
end
@@ -230,12 +307,10 @@ local function process(attribute,head,inheritance,default) -- one attribute
if current ~= default then
head = insert_node_before(head,stack,copy_node(nsdata[default]))
current = default
- done = true
end
elseif current ~= c then
head = insert_node_before(head,stack,copy_node(nsdata[c]))
current = c
- done = true
end
if leader then
local savedcurrent = current
@@ -247,33 +322,19 @@ local function process(attribute,head,inheritance,default) -- one attribute
current = 0
end
-- begin nested --
+ local list
if nstrigger and getattr(stack,nstrigger) then
local outer = getattr(stack,attribute)
if outer ~= inheritance then
- local list, ok = process(attribute,leader,inheritance,outer)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,leader,inheritance,outer)
else
- local list, ok = process(attribute,leader,inheritance,default)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,leader,inheritance,default)
end
else
- local list, ok = process(attribute,leader,inheritance,default)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = process(attribute,leader,inheritance,default)
+ end
+ if leader ~= list then
+ setleader(stack,list)
end
-- end nested --
current = savedcurrent
@@ -283,23 +344,19 @@ local function process(attribute,head,inheritance,default) -- one attribute
if current ~= default then
head = insert_node_before(head,stack,copy_node(nsdata[default]))
current = default
- done = true
end
elseif current > 0 then
head = insert_node_before(head,stack,copy_node(nsnone))
current = 0
- done = true
end
check = false
end
- stack = getnext(stack)
end
- return head, done
+ return head
end
states.process = function(namespace,attribute,head,default)
- local head, done = process(attribute,tonut(head),default)
- return tonode(head), done
+ return process(attribute,head,default)
end
-- we can force a selector, e.g. document wide color spaces, saves a little
@@ -308,14 +365,106 @@ end
-- state changes while the main state stays the same (like two glyphs following
-- each other with the same color but different color spaces e.g. \showcolor)
+-- local function selective(attribute,head,inheritance,default) -- two attributes
+-- local stack = head
+-- local check = false
+-- local leader = nil
+-- while stack do
+-- local id = getid(stack)
+-- if id == glyph_code or id == disc_code then
+-- check = true -- disc no longer needed as we flatten replace
+-- elseif id == glue_code then
+-- leader = getleader(stack)
+-- if leader then
+-- check = true
+-- end
+-- elseif id == hlist_code or id == vlist_code then
+-- local content = getlist(stack)
+-- if content then
+-- -- begin nested
+-- local list
+-- if nstrigger and getattr(stack,nstrigger) then
+-- local outer = getattr(stack,attribute)
+-- if outer ~= inheritance then
+-- list = selective(attribute,content,inheritance,outer)
+-- else
+-- list = selective(attribute,content,inheritance,default)
+-- end
+-- else
+-- list = selective(attribute,content,inheritance,default)
+-- end
+-- if content ~= list then
+-- setlist(stack,list)
+-- end
+-- -- end nested
+-- end
+-- elseif id == rule_code then
+-- check = getwidth(stack) ~= 0
+-- end
+--
+-- if check then
+-- local c = getattr(stack,attribute)
+-- if c then
+-- if default and c == inheritance then
+-- if current ~= default then
+-- local data = nsdata[default]
+-- head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
+-- current = default
+-- end
+-- else
+-- local s = getattr(stack,nsselector)
+-- -- local s = nsforced or getattr(stack,nsselector)
+-- if current ~= c or current_selector ~= s then
+-- local data = nsdata[c]
+-- head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector]))
+-- current = c
+-- current_selector = s
+-- end
+-- end
+-- if leader then
+-- -- begin nested
+-- local list
+-- if nstrigger and getattr(stack,nstrigger) then
+-- local outer = getattr(stack,attribute)
+-- if outer ~= inheritance then
+-- list = selective(attribute,leader,inheritance,outer)
+-- else
+-- list = selective(attribute,leader,inheritance,default)
+-- end
+-- else
+-- list = selective(attribute,leader,inheritance,default)
+-- end
+-- if leader ~= list then
+-- setleader(stack,list)
+-- end
+-- -- end nested
+-- leader = false
+-- end
+-- elseif default and inheritance then
+-- if current ~= default then
+-- local data = nsdata[default]
+-- head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
+-- current = default
+-- end
+-- elseif current > 0 then
+-- head = insert_node_before(head,stack,copy_node(nsnone))
+-- current, current_selector = 0, 0
+-- end
+-- check = false
+-- end
+-- stack = getnext(stack)
+-- end
+-- return head
+-- end
+--
+-- states.selective = function(namespace,attribute,head,default)
+-- return selective(attribute,head,default)
+-- end
+
local function selective(attribute,head,inheritance,default) -- two attributes
- -- local head = head
- local stack = head
- local done = false
local check = false
local leader = nil
- while stack do
- local id = getid(stack)
+ for stack, id in nextnode, head do
if id == glyph_code or id == disc_code then
check = true -- disc no longer needed as we flatten replace
elseif id == glue_code then
@@ -327,33 +476,19 @@ local function selective(attribute,head,inheritance,default) -- two attributes
local content = getlist(stack)
if content then
-- begin nested
+ local list
if nstrigger and getattr(stack,nstrigger) then
local outer = getattr(stack,attribute)
if outer ~= inheritance then
- local list, ok = selective(attribute,content,inheritance,outer)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,content,inheritance,outer)
else
- local list, ok = selective(attribute,content,inheritance,default)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,content,inheritance,default)
end
else
- local list, ok = selective(attribute,content,inheritance,default)
- if content ~= list then
- setlist(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,content,inheritance,default)
+ end
+ if content ~= list then
+ setlist(stack,list)
end
-- end nested
end
@@ -369,9 +504,6 @@ local function selective(attribute,head,inheritance,default) -- two attributes
local data = nsdata[default]
head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
current = default
- if ok then
- done = true
- end
end
else
local s = getattr(stack,nsselector)
@@ -379,43 +511,25 @@ local function selective(attribute,head,inheritance,default) -- two attributes
if current ~= c or current_selector ~= s then
local data = nsdata[c]
head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector]))
- -- head = insert_node_before(head,stack,copy_node(data[s or nsselector]))
current = c
current_selector = s
- if ok then
- done = true
- end
end
end
if leader then
-- begin nested
+ local list
if nstrigger and getattr(stack,nstrigger) then
local outer = getattr(stack,attribute)
if outer ~= inheritance then
- local list, ok = selective(attribute,leader,inheritance,outer)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,leader,inheritance,outer)
else
- local list, ok = selective(attribute,leader,inheritance,default)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,leader,inheritance,default)
end
else
- local list, ok = selective(attribute,leader,inheritance,default)
- if leader ~= list then
- setleader(stack,list)
- end
- if ok then
- done = true
- end
+ list = selective(attribute,leader,inheritance,default)
+ end
+ if leader ~= list then
+ setleader(stack,list)
end
-- end nested
leader = false
@@ -425,22 +539,19 @@ local function selective(attribute,head,inheritance,default) -- two attributes
local data = nsdata[default]
head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector]))
current = default
- done = true
end
elseif current > 0 then
head = insert_node_before(head,stack,copy_node(nsnone))
- current, current_selector, done = 0, 0, true
+ current, current_selector = 0, 0
end
check = false
end
- stack = getnext(stack)
end
- return head, done
+ return head
end
states.selective = function(namespace,attribute,head,default)
- local head = selective(attribute,tonut(head),default)
- return tonode(head), true
+ return selective(attribute,head,default)
end
-- Ideally the next one should be merged with the previous but keeping it separate is
@@ -454,7 +565,6 @@ end
local function stacked(attribute,head,default) -- no triggering, no inheritance, but list-wise
local stack = head
- local done = false
local current = default or 0
local depth = 0
local check = false
@@ -472,36 +582,24 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
local content = getlist(stack)
if content then
-- the problem is that broken lines gets the attribute which can be a later one
+ local list
if nslistwise then
local a = getattr(stack,attribute)
if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below
local p = current
current = a
head = insert_node_before(head,stack,copy_node(nsdata[a]))
- local list = stacked(attribute,content,current) -- two return values
- if content ~= list then
- setlist(stack,list)
- end
+ list = stacked(attribute,content,current) -- two return values
head, stack = insert_node_after(head,stack,copy_node(nsnone))
current = p
- done = true
else
- local list, ok = stacked(attribute,content,current)
- if content ~= list then
- setlist(stack,list) -- only if ok
- end
- if ok then
- done = true
- end
+ list = stacked(attribute,content,current)
end
else
- local list, ok = stacked(attribute,content,current)
- if content ~= list then
- setlist(stack,list) -- only if ok
- end
- if ok then
- done = true
- end
+ list = stacked(attribute,content,current)
+ end
+ if content ~= list then
+ setlist(stack,list) -- only if ok
end
end
elseif id == rule_code then
@@ -515,16 +613,12 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_before(head,stack,copy_node(nsdata[a]))
depth = depth + 1
current = a
- done = true
end
if leader then
- local list, ok = stacked(attribute,content,current)
+ local list = stacked(attribute,content,current)
if leader ~= list then
setleader(stack,list) -- only if ok
end
- if ok then
- done = true
- end
leader = false
end
elseif default > 0 then
@@ -533,7 +627,6 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_before(head,stack,copy_node(nsnone))
depth = depth - 1
current = 0
- done = true
end
check = false
end
@@ -543,24 +636,22 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_after(head,stack,copy_node(nsnone))
depth = depth - 1
end
- return head, done
+ return head
end
states.stacked = function(namespace,attribute,head,default)
- local head, done = stacked(attribute,tonut(head),default)
- return tonode(head), done
+ return stacked(attribute,head,default)
end
-- experimental
local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise
--- nsbegin()
+ -- nsbegin()
local stacked = false
local current = head
local previous = head
- local done = false
local attrib = default or unsetvalue
local check = false
local leader = false
@@ -576,35 +667,23 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
end
elseif id == hlist_code or id == vlist_code then
local content = getlist(current)
- if not content then
- -- skip
- elseif nslistwise then
- local a = getattr(current,attribute)
- if a and attrib ~= a and nslistwise[a] then -- viewerlayer
- head = insert_node_before(head,current,copy_node(nsdata[a]))
- local list = stacker(attribute,content,a)
- if list ~= content then
- setlist(current,list)
+ if content then
+ local list
+ if nslistwise then
+ local a = getattr(current,attribute)
+ if a and attrib ~= a and nslistwise[a] then -- viewerlayer
+ head = insert_node_before(head,current,copy_node(nsdata[a]))
+ list = stacker(attribute,content,a)
+ head, current = insert_node_after(head,current,copy_node(nsnone))
+ else
+ list = stacker(attribute,content,attrib)
end
- done = true
- head, current = insert_node_after(head,current,copy_node(nsnone))
else
- local list, ok = stacker(attribute,content,attrib)
- if content ~= list then
- setlist(current,list)
- end
- if ok then
- done = true
- end
+ list = stacker(attribute,content,default)
end
- else
- local list, ok = stacker(attribute,content,default)
if list ~= content then
setlist(current,list)
end
- if ok then
- done = true
- end
end
elseif id == rule_code then
check = getwidth(current) ~= 0
@@ -622,13 +701,9 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
head = insert_node_before(head,current,tonut(n)) -- a
end
attrib = a
- done = true
if leader then
-- tricky as a leader has to be a list so we cannot inject before
- local list, ok = stacker(attribute,leader,attrib)
- if ok then
- done = true
- end
+ local list = stacker(attribute,leader,attrib)
leader = false
end
end
@@ -647,13 +722,13 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance,
end
end
- return head, done
+ return head
end
states.stacker = function(namespace,attribute,head,default)
- local head, done = stacker(attribute,tonut(head),default)
+ local head = stacker(attribute,head,default)
nsreset()
- return tonode(head), done
+ return head
end
-- -- --
diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua
index f846f996d..044be8ca8 100644
--- a/tex/context/base/mkiv/node-fnt.lua
+++ b/tex/context/base/mkiv/node-fnt.lua
@@ -40,8 +40,6 @@ local nodecodes = nodes.nodecodes
local handlers = nodes.handlers
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getattr = nuts.getattr
local getid = nuts.getid
@@ -62,9 +60,12 @@ local setprev = nuts.setprev
local isglyph = nuts.isglyph -- unchecked
local ischar = nuts.ischar -- checked
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
-local protect_glyph = nuts.protect_glyph
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextboundary = nuts.traversers.boundary
+local nextdisc = nuts.traversers.disc
+local nextchar = nuts.traversers.char
+
local flush_node = nuts.flush
local disc_code = nodecodes.disc
@@ -172,7 +173,7 @@ local function start_trace(head)
report_fonts()
report_fonts("checking node list, run %s",run)
report_fonts()
- local n = tonut(head)
+ local n = head
while n do
local char, id = isglyph(n)
if char then
@@ -212,10 +213,8 @@ function handlers.characters(head,groupcode,size,packtype,direction)
local basefont = nil
local prevfont = nil
local prevattr = 0
- local done = false
local variants = nil
local redundant = nil
- local nuthead = tonut(head)
local lastfont = nil
local lastproc = nil
local lastnone = nil
@@ -296,7 +295,7 @@ function handlers.characters(head,groupcode,size,packtype,direction)
end
end
- for n in traverse_char(nuthead) do
+ for n in nextchar, head do
local font = getfont(n)
-- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
@@ -361,7 +360,7 @@ function handlers.characters(head,groupcode,size,packtype,direction)
-- but we need to get rid of those nodes in order to build ligatures
-- and kern (a rather context thing)
- for b in traverse_id(boundary_code,nuthead) do
+ for b in nextboundary, head do
if getsubtype(b) == word_boundary then
if redundant then
r = r + 1
@@ -379,8 +378,8 @@ function handlers.characters(head,groupcode,size,packtype,direction)
for i=1,r do
local r = redundant[i]
local p, n = getboth(r)
- if r == nuthead then
- nuthead = n
+ if r == head then
+ head = n
setprev(n)
else
setlink(p,n)
@@ -411,7 +410,7 @@ function handlers.characters(head,groupcode,size,packtype,direction)
-- basefont is not supported in disc only runs ... it would mean a lot of
-- ranges .. we could try to run basemode as a separate processor run but
-- not for now (we can consider it when the new node code is tested
- for d in traverse_id(disc_code,nuthead) do
+ for d in nextdisc, head do
-- we could use first_glyph, only doing replace is good enough because
-- pre and post are normally used for hyphens and these come from fonts
-- that part of the hyphenated word
@@ -420,7 +419,7 @@ function handlers.characters(head,groupcode,size,packtype,direction)
local prevfont = nil
local prevattr = nil
local none = false
- for n in traverse_char(r) do
+ for n in nextchar, r do
local font = getfont(n)
local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
if font ~= prevfont or attr ~= prevattr then
@@ -466,26 +465,14 @@ function handlers.characters(head,groupcode,size,packtype,direction)
elseif u == 1 then
local attr = a > 0 and 0 or false -- 0 is the savest way
for i=1,#lastproc do
- local h, d = lastproc[i](head,lastfont,attr,direction)
- if d then
- if h then
- head = h
- end
- done = true
- end
+ head = lastproc[i](head,lastfont,attr,direction)
end
else
-- local attr = a == 0 and false or 0 -- 0 is the savest way
local attr = a > 0 and 0 or false -- 0 is the savest way
for font, processors in next, usedfonts do -- unordered
for i=1,#processors do
- local h, d = processors[i](head,font,attr,direction,u)
- if d then
- if h then
- head = h
- end
- done = true
- end
+ head = processors[i](head,font,attr,direction,u)
end
end
end
@@ -495,26 +482,14 @@ function handlers.characters(head,groupcode,size,packtype,direction)
local font, dynamics = next(attrfonts)
for attribute, processors in next, dynamics do -- unordered, attr can switch in between
for i=1,#processors do
- local h, d = processors[i](head,font,attribute,direction)
- if d then
- if h then
- head = h
- end
- done = true
- end
+ head = processors[i](head,font,attribute,direction)
end
end
else
for font, dynamics in next, attrfonts do
for attribute, processors in next, dynamics do -- unordered, attr can switch in between
for i=1,#processors do
- local h, d = processors[i](head,font,attribute,direction,a)
- if d then
- if h then
- head = h
- end
- done = true
- end
+ head = processors[i](head,font,attribute,direction,a)
end
end
end
@@ -527,7 +502,7 @@ function handlers.characters(head,groupcode,size,packtype,direction)
local start = range[1]
local stop = range[2]
if (start or stop) and (start ~= stop) then
- local front = nuthead == start
+ local front = head == start
if stop then
start = ligaturing(start,stop)
start = kerning(start,stop)
@@ -535,9 +510,8 @@ function handlers.characters(head,groupcode,size,packtype,direction)
start = ligaturing(start)
start = kerning(start)
end
- if front and nuthead ~= start then
- -- nuthead = start
- head = tonode(start)
+ if front and head ~= start then
+ head = start
end
end
else
@@ -547,7 +521,7 @@ function handlers.characters(head,groupcode,size,packtype,direction)
local start = range[1]
local stop = range[2]
if start then -- and start ~= stop but that seldom happens
- local front = nuthead == start
+ local front = head == start
local prev = getprev(start)
local next = getnext(stop)
if stop then
@@ -565,19 +539,369 @@ function handlers.characters(head,groupcode,size,packtype,direction)
setlink(stop,next)
end
-- till here
- if front and nuthead ~= start then
- nuthead = start
- head = tonode(start)
+ if front and head ~= start then
+ head = start
end
end
end
end
stoptiming(nodes)
if trace_characters then
- nodes.report(head,done)
+ nodes.report(head)
+ end
+ return head
+end
+
+if LUATEXVERSION >= 1.090 then
+
+ function handlers.characters(head,groupcode,size,packtype,direction)
+ -- either next or not, but definitely no already processed list
+ starttiming(nodes)
+
+ local usedfonts = { }
+ local attrfonts = { }
+ local basefonts = { }
+ local basefont = nil
+ local prevfont = nil
+ local prevattr = 0
+ local variants = nil
+ local redundant = nil
+ local lastfont = nil
+ local lastproc = nil
+ local lastnone = nil
+
+ local a, u, b, r, e = 0, 0, 0, 0, 0
+
+ if trace_fontrun then
+ start_trace(head)
+ end
+
+ -- There is no gain in checking for a single glyph and then having a fast path. On the
+ -- metafun manual (with some 2500 single char lists) the difference is just noise.
+
+ local function protectnone()
+ protect_glyphs(firstnone,lastnone)
+ firstnone = nil
+ end
+
+ local function setnone(n)
+ if firstnone then
+ protectnone()
+ end
+ if basefont then
+ basefont[2] = getprev(n)
+ basefont = false
+ end
+ if not firstnone then
+ firstnone = n
+ end
+ lastnone = n
+ end
+
+ local function setbase(n)
+ if firstnone then
+ protectnone()
+ end
+ if force_basepass then
+ if basefont then
+ basefont[2] = getprev(n)
+ end
+ b = b + 1
+ basefont = { n, false }
+ basefonts[b] = basefont
+ end
+ end
+
+ local function setnode(n,font,attr) -- we could use prevfont and prevattr when we set then first
+ if firstnone then
+ protectnone()
+ end
+ if basefont then
+ basefont[2] = getprev(n)
+ basefont = false
+ end
+ if attr > 0 then
+ local used = attrfonts[font]
+ if not used then
+ used = { }
+ attrfonts[font] = used
+ end
+ if not used[attr] then
+ local fd = setfontdynamics[font]
+ if fd then
+ used[attr] = fd[attr]
+ a = a + 1
+ end
+ end
+ else
+ local used = usedfonts[font]
+ if not used then
+ lastfont = font
+ lastproc = fontprocesses[font]
+ if lastproc then
+ usedfonts[font] = lastproc
+ u = u + 1
+ end
+ end
+ end
+ end
+
+ for n, char, font in nextchar, head do
+ -- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
+ local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
+ if font ~= prevfont or attr ~= prevattr then
+ prevfont = font
+ prevattr = attr
+ variants = fontvariants[font]
+ local fontmode = fontmodes[font]
+ if fontmode == "none" then
+ setnone(n)
+ elseif fontmode == "base" then
+ setbase(n)
+ else
+ setnode(n,font,attr)
+ end
+ elseif firstnone then
+ lastnone = n
+ end
+ if variants then
+ if char >= 0xFE00 and (char <= 0xFE0F or (char >= 0xE0100 and char <= 0xE01EF)) then
+ local hash = variants[char]
+ if hash then
+ local p = getprev(n)
+ if p then
+ local char = ischar(p) -- checked
+ local variant = hash[char]
+ if variant then
+ if trace_variants then
+ report_fonts("replacing %C by %C",char,variant)
+ end
+ setchar(p,variant)
+ if redundant then
+ r = r + 1
+ redundant[r] = n
+ else
+ r = 1
+ redundant = { n }
+ end
+ end
+ end
+ elseif keep_redundant then
+ -- go on, can be used for tracing
+ elseif redundant then
+ r = r + 1
+ redundant[r] = n
+ else
+ r = 1
+ redundant = { n }
+ end
+ end
+ end
+ end
+
+ if firstnone then
+ protectnone()
+ end
+
+ if force_boundaryrun then
+
+ -- we can inject wordboundaries and then let the hyphenator do its work
+ -- but we need to get rid of those nodes in order to build ligatures
+ -- and kern (a rather context thing)
+
+ for b, subtype in nextboundary, head do
+ if subtype == word_boundary then
+ if redundant then
+ r = r + 1
+ redundant[r] = b
+ else
+ r = 1
+ redundant = { b }
+ end
+ end
+ end
+
+ end
+
+ if redundant then
+ for i=1,r do
+ local r = redundant[i]
+ local p, n = getboth(r)
+ if r == head then
+ head = n
+ setprev(n)
+ else
+ setlink(p,n)
+ end
+ if b > 0 then
+ for i=1,b do
+ local bi = basefonts[i]
+ local b1 = bi[1]
+ local b2 = bi[2]
+ if b1 == b2 then
+ if b1 == r then
+ bi[1] = false
+ bi[2] = false
+ end
+ elseif b1 == r then
+ bi[1] = n
+ elseif b2 == r then
+ bi[2] = p
+ end
+ end
+ end
+ flush_node(r)
+ end
+ end
+
+ if force_discrun then
+
+ -- basefont is not supported in disc only runs ... it would mean a lot of
+ -- ranges .. we could try to run basemode as a separate processor run but
+ -- not for now (we can consider it when the new node code is tested
+ for d in nextdisc, head do
+ -- we could use first_glyph, only doing replace is good enough because
+ -- pre and post are normally used for hyphens and these come from fonts
+ -- that part of the hyphenated word
+ local _, _, r = getdisc(d)
+ if r then
+ local prevfont = nil
+ local prevattr = nil
+ local none = false
+ for n, char, font in nextchar, r do
+ local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
+ if font ~= prevfont or attr ~= prevattr then
+ prevfont = font
+ prevattr = attr
+ local fontmode = fontmodes[font]
+ if fontmode == "none" then
+ setnone(n)
+ elseif fontmode == "base" then
+ setbase(n)
+ else
+ setnode(n,font,attr)
+ end
+ elseif firstnone then
+ -- lastnone = n
+ lastnone = nil
+ end
+ -- we assume one font for now (and if there are more and we get into issues then
+ -- we can always remove the break)
+ break
+ end
+ if firstnone then
+ protectnone()
+ end
+ -- elseif expanders then
+ -- local subtype = getsubtype(d)
+ -- if subtype == automatic_code or subtype == explicit_code then
+ -- expanders[subtype](d)
+ -- e = e + 1
+ -- end
+ end
+ end
+
+ end
+
+ if trace_fontrun then
+ stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders)
+ end
+
+ -- in context we always have at least 2 processors
+ if u == 0 then
+ -- skip
+ elseif u == 1 then
+ local attr = a > 0 and 0 or false -- 0 is the savest way
+ for i=1,#lastproc do
+ head = lastproc[i](head,lastfont,attr,direction)
+ end
+ else
+ -- local attr = a == 0 and false or 0 -- 0 is the savest way
+ local attr = a > 0 and 0 or false -- 0 is the savest way
+ for font, processors in next, usedfonts do -- unordered
+ for i=1,#processors do
+ head = processors[i](head,font,attr,direction,u)
+ end
+ end
+ end
+ if a == 0 then
+ -- skip
+ elseif a == 1 then
+ local font, dynamics = next(attrfonts)
+ for attribute, processors in next, dynamics do -- unordered, attr can switch in between
+ for i=1,#processors do
+ head = processors[i](head,font,attribute,direction)
+ end
+ end
+ else
+ for font, dynamics in next, attrfonts do
+ for attribute, processors in next, dynamics do -- unordered, attr can switch in between
+ for i=1,#processors do
+ head = processors[i](head,font,attribute,direction,a)
+ end
+ end
+ end
+ end
+ if b == 0 then
+ -- skip
+ elseif b == 1 then
+ -- only one font
+ local range = basefonts[1]
+ local start = range[1]
+ local stop = range[2]
+ if (start or stop) and (start ~= stop) then
+ local front = head == start
+ if stop then
+ start = ligaturing(start,stop)
+ start = kerning(start,stop)
+ elseif start then -- safeguard
+ start = ligaturing(start)
+ start = kerning(start)
+ end
+ if front and head ~= start then
+ head = start
+ end
+ end
+ else
+ -- multiple fonts
+ for i=1,b do
+ local range = basefonts[i]
+ local start = range[1]
+ local stop = range[2]
+ if start then -- and start ~= stop but that seldom happens
+ local front = head == start
+ local prev = getprev(start)
+ local next = getnext(stop)
+ if stop then
+ start, stop = ligaturing(start,stop)
+ start, stop = kerning(start,stop)
+ else
+ start = ligaturing(start)
+ start = kerning(start)
+ end
+ -- is done automatically
+ if prev then
+ setlink(prev,start)
+ end
+ if next then
+ setlink(stop,next)
+ end
+ -- till here
+ if front and head ~= start then
+ head = start
+ end
+ end
+ end
+ end
+ stoptiming(nodes)
+ if trace_characters then
+ nodes.report(head)
+ end
+ return head
end
- return head, true
+
end
-handlers.protectglyphs = function(n) protect_glyphs (tonut(n)) return n, true end
-handlers.unprotectglyphs = function(n) unprotect_glyphs(tonut(n)) return n, true end
+
+handlers.protectglyphs = protect_glyphs
+handlers.unprotectglyphs = unprotect_glyphs
diff --git a/tex/context/base/mkiv/node-ltp.lua b/tex/context/base/mkiv/node-ltp.lua
index 865f69c2c..c51298b4e 100644
--- a/tex/context/base/mkiv/node-ltp.lua
+++ b/tex/context/base/mkiv/node-ltp.lua
@@ -191,7 +191,6 @@ local parameters = fonthashes.parameters
local nuts = nodes.nuts
local tonut = nuts.tonut
-local tonode = nuts.tonode
local getfield = nuts.getfield
local getid = nuts.getid
@@ -2148,8 +2147,6 @@ local dcolor = { [0] = "red", "green", "blue", "magenta", "cyan", "gray" }
local temp_head = new_temp()
function constructors.methods.basic(head,d)
- head = tonut(head)
-
if trace_basic then
report_parbuilders("starting at %a",head)
end
@@ -2455,7 +2452,7 @@ function constructors.methods.basic(head,d)
par.best_line = par.best_bet.line_number
local asked_looseness = par.looseness
if asked_looseness == 0 then
- return tonode(wrap_up(par))
+ return wrap_up(par)
end
local r = n_active
local actual_looseness = 0
@@ -2478,7 +2475,7 @@ function constructors.methods.basic(head,d)
until r == p_active
par.best_line = par.best_bet.line_number
if actual_looseness == asked_looseness or par.final_pass then
- return tonode(wrap_up(par))
+ return wrap_up(par)
end
end
end
@@ -2498,7 +2495,7 @@ function constructors.methods.basic(head,d)
par.final_pass = true
end
end
- return tonode(wrap_up(par))
+ return wrap_up(par)
end
-- standard tex logging .. will be adapted ..
diff --git a/tex/context/base/mkiv/node-met.lua b/tex/context/base/mkiv/node-met.lua
index 4141c8b66..3ec03458d 100644
--- a/tex/context/base/mkiv/node-met.lua
+++ b/tex/context/base/mkiv/node-met.lua
@@ -88,65 +88,69 @@ end
nodes = nodes or { }
local nodes = nodes
-local nodecodes = nodes.nodecodes
-
-nodes.tostring = node.tostring or tostring
-nodes.copy = node.copy
-nodes.copy_node = node.copy
-nodes.copy_list = node.copy_list
-nodes.delete = node.delete
-nodes.dimensions = node.dimensions
-nodes.rangedimensions = node.rangedimensions
-nodes.end_of_math = node.end_of_math
-nodes.flush = node.flush_node
-nodes.flush_node = node.flush_node
-nodes.flush_list = node.flush_list
-nodes.free = node.free
-nodes.insert_after = node.insert_after
-nodes.insert_before = node.insert_before
-nodes.hpack = node.hpack
-nodes.new = node.new
-nodes.tail = node.tail
-nodes.traverse = node.traverse
-nodes.traverse_id = node.traverse_id
-nodes.traverse_char = node.traverse_char
-nodes.slide = node.slide
-nodes.vpack = node.vpack
-nodes.fields = node.fields
-nodes.is_node = node.is_node
-nodes.setglue = node.setglue
-
-nodes.first_glyph = node.first_glyph
-nodes.has_glyph = node.has_glyph or node.first_glyph
-
-nodes.current_attr = node.current_attr
-nodes.has_field = node.has_field
-nodes.last_node = node.last_node
-nodes.usedlist = node.usedlist
-nodes.protrusion_skippable = node.protrusion_skippable
-nodes.check_discretionaries = node.check_discretionaries
-nodes.write = node.write
-
-nodes.count = node.count
-nodes.length = node.length
-
-nodes.has_attribute = node.has_attribute
-nodes.set_attribute = node.set_attribute
-nodes.find_attribute = node.find_attribute
-nodes.unset_attribute = node.unset_attribute
-
-nodes.protect_glyph = node.protect_glyph
-nodes.protect_glyphs = node.protect_glyphs
-nodes.unprotect_glyph = node.unprotect_glyph
-nodes.unprotect_glyphs = node.unprotect_glyphs
-nodes.kerning = node.kerning
-nodes.ligaturing = node.ligaturing
-nodes.mlist_to_hlist = node.mlist_to_hlist
-
-nodes.effective_glue = node.effective_glue
-nodes.getglue = node.getglue
-nodes.setglue = node.setglue
-nodes.is_zero_glue = node.is_zero_glue
+local nodecodes = nodes.nodecodes
+
+nodes.tostring = node.tostring or tostring
+nodes.copy = node.copy
+nodes.copy_node = node.copy
+nodes.copy_list = node.copy_list
+nodes.delete = node.delete
+nodes.dimensions = node.dimensions
+nodes.rangedimensions = node.rangedimensions
+nodes.end_of_math = node.end_of_math
+nodes.flush = node.flush_node
+nodes.flush_node = node.flush_node
+nodes.flush_list = node.flush_list
+nodes.free = node.free
+nodes.insert_after = node.insert_after
+nodes.insert_before = node.insert_before
+nodes.hpack = node.hpack
+nodes.new = node.new
+nodes.tail = node.tail
+nodes.traverse = node.traverse
+nodes.traverse_id = node.traverse_id
+nodes.traverse_char = node.traverse_char
+nodes.traverse_glyph = node.traverse_glyph
+nodes.traverse_list = node.traverse_list
+nodes.slide = node.slide
+nodes.vpack = node.vpack
+nodes.fields = node.fields
+nodes.is_node = node.is_node
+nodes.setglue = node.setglue
+nodes.uses_font = node.uses_font
+
+nodes.first_glyph = node.first_glyph
+nodes.has_glyph = node.has_glyph or node.first_glyph
+
+nodes.current_attr = node.current_attr
+nodes.has_field = node.has_field
+nodes.last_node = node.last_node
+nodes.usedlist = node.usedlist
+nodes.protrusion_skippable = node.protrusion_skippable
+nodes.check_discretionaries = node.check_discretionaries
+nodes.write = node.write
+nodes.flatten_discretionaries = node.flatten_discretionaries
+
+nodes.count = node.count
+nodes.length = node.length
+
+nodes.has_attribute = node.has_attribute
+nodes.set_attribute = node.set_attribute
+nodes.find_attribute = node.find_attribute
+nodes.unset_attribute = node.unset_attribute
+
+nodes.protect_glyph = node.protect_glyph
+nodes.protect_glyphs = node.protect_glyphs
+nodes.unprotect_glyph = node.unprotect_glyph
+nodes.unprotect_glyphs = node.unprotect_glyphs
+nodes.kerning = node.kerning
+nodes.ligaturing = node.ligaturing
+nodes.mlist_to_hlist = node.mlist_to_hlist
+
+nodes.effective_glue = node.effective_glue
+nodes.getglue = node.getglue
+nodes.setglue = node.setglue
+nodes.is_zero_glue = node.is_zero_glue
nodes.tonode = function(n) return n end
nodes.tonut = function(n) return n end
diff --git a/tex/context/base/mkiv/node-mig.lua b/tex/context/base/mkiv/node-mig.lua
index b3820a7d8..32b09a186 100644
--- a/tex/context/base/mkiv/node-mig.lua
+++ b/tex/context/base/mkiv/node-mig.lua
@@ -89,12 +89,11 @@ local function locate(head,first,last,ni,nm)
end
function nodes.handlers.migrate(head,where)
- local done = false
if head then
if trace_migrations then
report_nodes("migration sweep %a",where)
end
- local current = tonut(head)
+ local current = head
while current do
local id = getid(current)
-- inserts_too is a temp hack, we should only do them when it concerns
@@ -124,13 +123,12 @@ function nodes.handlers.migrate(head,where)
setlink(last,n)
end
setlink(current,first)
- done = true
current = last
end
end
current = getnext(next)
end
- return head, done
+ return head
end
end
diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua
index 282a37e2e..b970a46af 100644
--- a/tex/context/base/mkiv/node-nut.lua
+++ b/tex/context/base/mkiv/node-nut.lua
@@ -96,6 +96,7 @@ local fastcopy = table.fastcopy
local nodecodes = nodes.nodecodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
+local glyph_code = nodecodes.glyph
local nuts = nodes.nuts or { }
nodes.nuts = nuts
@@ -174,17 +175,25 @@ if not direct.getdirection then
end
-if LUATEXFUNCTIONALITY < 6695 then
+if not node.direct.traverse_glyph or not node.direct.traverse_list then
- local getnext = direct.getnext
- local getid = direct.getid
+ logs.report("system","using fake node list traversers")
+
+ local getnext = node.direct.getnext
+ local getid = node.direct.getid
+ local getsubtype = node.direct.getsubtype
+ local getchar = node.direct.getchar
+ local getfont = node.direct.getfont
+ local getlist = node.direct.getlist
local function iterate(h,n)
if n then
- local n = getnext(n)
- return n, getid(n)
- elseif h then
- return h, getid(h), getnext(h)
+ n = getnext(n)
+ else
+ n = h
+ end
+ if n then
+ return n, getid(n), getsubtype(n)
end
end
@@ -192,68 +201,147 @@ if LUATEXFUNCTIONALITY < 6695 then
return iterate, h
end
+ function node.direct.traverse_id(id,h)
+ local function iterate(h,n)
+ if n then
+ n = getnext(n)
+ else
+ n = h
+ end
+ while n do
+ if getid(n) == id then
+ return n, getsubtype(n)
+ else
+ n = getnext(n)
+ end
+ end
+ end
+ return iterate, h
+ end
+
+ local function iterate(h,n)
+ if n then
+ n = getnext(n)
+ else
+ n = h
+ end
+ while n do
+ if getid(n) == glyph_code then
+ return n, getfont(n), getchar(n)
+ else
+ n = getnext(n)
+ end
+ end
+ end
+
+ function node.direct.traverse_glyph(h)
+ return iterate, h
+ end
+
+ local function iterate(h,n)
+ if n then
+ n = getnext(n)
+ else
+ n = h
+ end
+ while n do
+ if getid(n) == glyph_code and subtype(n) < 256 then
+ return n, getfont(n), getchar(n)
+ else
+ n = getnext(n)
+ end
+ end
+ end
+
+ function node.direct.traverse_char(h)
+ return iterate, h
+ end
+
+ local function iterate(h,n)
+ if n then
+ n = getnext(n)
+ else
+ n = h
+ end
+ while n do
+ local id = getid(n)
+ if id == hlist_code or id == vlist_code then
+ return n, id, getsubtype(n), getlist(n)
+ else
+ n = getnext(n)
+ end
+ end
+ end
+
+ function node.direct.traverse_list(h)
+ return iterate, h
+ end
+
end
-local nuts = nodes.nuts
-
-nuts.tostring = direct.tostring
-nuts.copy = direct.copy
-nuts.copy_node = direct.copy
-nuts.copy_list = direct.copy_list
-nuts.delete = direct.delete
-nuts.dimensions = direct.dimensions
-nuts.rangedimensions = direct.rangedimensions
-nuts.end_of_math = direct.end_of_math
-nuts.flush = direct.flush_node
-nuts.flush_node = direct.flush_node
-nuts.flush_list = direct.flush_list
-nuts.free = direct.free
-nuts.insert_after = direct.insert_after
-nuts.insert_before = direct.insert_before
-nuts.hpack = direct.hpack
-nuts.new = direct.new
-nuts.tail = direct.tail
-nuts.traverse = direct.traverse
-nuts.traverse_id = direct.traverse_id
-nuts.traverse_char = direct.traverse_char
-nuts.slide = direct.slide
-nuts.writable_spec = direct.writable_spec
-nuts.vpack = direct.vpack
-nuts.is_node = direct.is_node
-nuts.is_direct = direct.is_direct
-nuts.is_nut = direct.is_direct
-nuts.first_glyph = direct.first_glyph
-nuts.has_glyph = direct.has_glyph or direct.first_glyph
-nuts.count = direct.count
-nuts.length = direct.length
-nuts.find_attribute = direct.find_attribute
-nuts.unset_attribute = direct.unset_attribute
-
-nuts.current_attr = direct.current_attr
-nuts.has_field = direct.has_field
-nuts.last_node = direct.last_node
-nuts.usedlist = direct.usedlist
-nuts.protrusion_skippable = direct.protrusion_skippable
-nuts.check_discretionaries = direct.check_discretionaries
-nuts.write = direct.write
-
-nuts.has_attribute = direct.has_attribute
-nuts.set_attribute = direct.set_attribute
-nuts.unset_attribute = direct.unset_attribute
-
-nuts.protect_glyph = direct.protect_glyph
-nuts.protect_glyphs = direct.protect_glyphs
-nuts.unprotect_glyph = direct.unprotect_glyph
-nuts.unprotect_glyphs = direct.unprotect_glyphs
-nuts.ligaturing = direct.ligaturing
-nuts.kerning = direct.kerning
+local nuts = nodes.nuts
+
+nuts.check_discretionaries = direct.check_discretionaries
+nuts.copy = direct.copy
+nuts.copy_list = direct.copy_list
+nuts.copy_node = direct.copy
+nuts.count = direct.count
+nuts.current_attr = direct.current_attr
+nuts.delete = direct.delete
+nuts.dimensions = direct.dimensions
+nuts.end_of_math = direct.end_of_math
+nuts.find_attribute = direct.find_attribute
+nuts.first_glyph = direct.first_glyph
+nuts.flatten_discretionaries = direct.flatten_discretionaries
+nuts.flush = direct.flush_node
+nuts.flush_list = direct.flush_list
+nuts.flush_node = direct.flush_node
+nuts.free = direct.free
+nuts.get_synctex_fields = direct.get_synctex_fields
+nuts.has_attribute = direct.has_attribute
+nuts.has_field = direct.has_field
+nuts.has_glyph = direct.has_glyph or direct.first_glyph
+nuts.hpack = direct.hpack
+nuts.insert_after = direct.insert_after
+nuts.insert_before = direct.insert_before
+nuts.is_direct = direct.is_direct
+nuts.is_node = direct.is_node
+nuts.is_nut = direct.is_direct
+nuts.kerning = direct.kerning
+nuts.last_node = direct.last_node
+nuts.length = direct.length
+nuts.ligaturing = direct.ligaturing
+nuts.new = direct.new
+nuts.protect_glyph = direct.protect_glyph
+nuts.protect_glyphs = direct.protect_glyphs
+nuts.protrusion_skippable = direct.protrusion_skippable
+nuts.rangedimensions = direct.rangedimensions
+nuts.set_attribute = direct.set_attribute
+nuts.set_synctex_fields = direct.set_synctex_fields
+nuts.slide = direct.slide
+nuts.tail = direct.tail
+nuts.tostring = direct.tostring
+nuts.traverse = direct.traverse
+nuts.traverse_char = direct.traverse_char
+nuts.traverse_glyph = direct.traverse_glyph
+nuts.traverse_id = direct.traverse_id
+nuts.traverse_list = direct.traverse_list
+nuts.unprotect_glyph = direct.unprotect_glyph
+nuts.unprotect_glyphs = direct.unprotect_glyphs
+nuts.unset_attribute = direct.unset_attribute
+nuts.unset_attribute = direct.unset_attribute
+nuts.usedlist = direct.usedlist
+nuts.uses_font = direct.uses_font
+nuts.vpack = direct.vpack
+nuts.writable_spec = direct.writable_spec
+nuts.write = direct.write
if not direct.mlist_to_hlist then -- needed
local n_mlist_to_hlist = node.mlist_to_hlist
function nuts.mlist_to_hlist(head)
- return tonode(n_mlist_to_hlist(tonut(head)))
+ return n_mlist_to_hlist(tonut(head))
end
end
@@ -825,115 +913,3 @@ function nuts.copy_properties(source,target,what)
return newprops -- for checking
end
--- here:
-
-nuts.get_synctex_fields = direct.get_synctex_fields
-nuts.set_synctex_fields = direct.set_synctex_fields
-
--- for now
-
-nodes.uses_font = nodes.uses_font
-nuts.uses_font = direct.uses_font
-
-if not nuts.uses_font then
-
- local glyph_code = nodecodes.glyph
- local getdisc = nuts.getdisc
- local getfont = nuts.getfont
- local traverse_id = nuts.traverse_id
- local tonut = nodes.tonut
-
- function nuts.uses_font(n,font)
- local pre, post, replace = getdisc(n)
- if pre then
- -- traverse_char
- for n in traverse_id(glyph_code,pre) do
- if getfont(n) == font then
- return true
- end
- end
- end
- if post then
- for n in traverse_id(glyph_code,post) do
- if getfont(n) == font then
- return true
- end
- end
- end
- if replace then
- for n in traverse_id(glyph_code,replace) do
- if getfont(n) == font then
- return true
- end
- end
- end
- return false
- end
-
- function nodes.uses_font(n,font)
- return nuts.uses_font(tonut(n),font)
- end
-
-end
-
--- for the moment (pre 6380)
-
-if not nuts.unprotect_glyph then
-
- local protect_glyph = nuts.protect_glyph
- local protect_glyphs = nuts.protect_glyphs
- local unprotect_glyph = nuts.unprotect_glyph
- local unprotect_glyphs = nuts.unprotect_glyphs
-
- local getnext = nuts.getnext
- local setnext = nuts.setnext
-
- function nuts.protectglyphs(first,last)
- if first == last then
- return protect_glyph(first)
- elseif last then
- local nxt = getnext(last)
- setnext(last)
- local f, b = protect_glyphs(first)
- setnext(last,nxt)
- return f, b
- else
- return protect_glyphs(first)
- end
- end
-
- function nuts.unprotectglyphs(first,last)
- if first == last then
- return unprotect_glyph(first)
- elseif last then
- local nxt = getnext(last)
- setnext(last)
- local f, b = unprotect_glyphs(first)
- setnext(last,nxt)
- return f, b
- else
- return unprotect_glyphs(first)
- end
- end
-
-end
-
-if LUATEXFUNCTIONALITY < 6384 then -- LUATEXVERSION < 1.070
-
- local getfield = nuts.getfield
- local setfield = nuts.setfield
-
- function nuts.getboxglue(n,glue_set,glue_order,glue_sign)
- return
- getfield(n,"glue_set"),
- getfield(n,"glue_order"),
- getfield(n,"glue_sign")
- end
-
- function nuts.setboxglue(n,glue_set,glue_order,glue_sign)
- setfield(n,"glue_set", glue_set or 0)
- setfield(n,"glue_order",glue_order or 0)
- setfield(n,"glue_sign", glue_sign or 0)
- end
-
-end
diff --git a/tex/context/base/mkiv/node-ppt.lua b/tex/context/base/mkiv/node-ppt.lua
index 5ebfca87d..0124f885b 100644
--- a/tex/context/base/mkiv/node-ppt.lua
+++ b/tex/context/base/mkiv/node-ppt.lua
@@ -30,8 +30,9 @@ local getfield = nuts.getfield
local getlist = nuts.getlist
local setlist = nuts.setlist
local removenode = nuts.remove
-local traverse = nuts.traverse
-local traverse_id = nuts.traverse_id
+
+local nextnode = nuts.traversers.node
+local nextwhatsit = nuts.traversers.whatsit
local nodecodes = nodes.nodecodes
local whatsitcodes = nodes.whatsitcodes
@@ -193,7 +194,7 @@ end
-- maybe actions will get parent too
local function delayed(head,parent) -- direct based
- for target in traverse(head) do
+ for target, id in nextnode, head do
local p = propertydata[target]
if p then
-- local deferred = p.deferred -- kind of late lua (but too soon as we have no access to pdf.h/v)
@@ -244,7 +245,6 @@ local function delayed(head,parent) -- direct based
end
-- end
end
- local id = getid(target)
if id == hlist_code or id == vlist_code then
local list = getlist(target)
if list then
@@ -268,14 +268,13 @@ function properties.delayed(head) --
if nofdelayed > 0 then
-- if next(propertydata) then
starttiming(properties)
- head = delayed(tonut(head))
+ head = delayed(head)
stoptiming(properties)
- return tonode(head), true -- done in shipout anyway
-- else
-- delayed = 0
- -- end
+ -- end
end
- return head, false
+ return head
end
-- more explicit ones too
@@ -317,102 +316,203 @@ table.setmetatableindex(anchored,function(t,k)
return v
end)
-function properties.attach(head)
+-- function properties.attach(head)
+--
+-- if nofslots <= 0 then
+-- return head
+-- end
+--
+-- local last = nil
+--
+-- starttiming(properties)
+--
+-- for source in nextwhatsit, head do
+-- if getsubtype(source) == userdefined_code then
+-- if last then
+-- removenode(head,last,true)
+-- last = nil
+-- end
+-- if getfield(source,"user_id") == property_id then
+-- local slot = getfield(source,"value")
+-- local data = cache[slot]
+-- if data then
+-- cache[slot] = nil
+-- local where = data[1]
+-- local target = anchored[where](source)
+-- if target then
+-- local first = data[2]
+-- local method = type(first)
+-- local p_target = propertydata[target]
+-- local p_source = propertydata[source]
+-- if p_target then
+-- if p_source then
+-- for k, v in next, p_source do
+-- p_target[k] = v
+-- end
+-- end
+-- if method == "table" then
+-- for k, v in next, first do
+-- p_target[k] = v
+-- end
+-- elseif method == "function" then
+-- first(target,head,where,p_target,unpack(data,3))
+-- elseif method == "string" then
+-- actions[first](target,head,where,p_target,unpack(data,3))
+-- end
+-- elseif p_source then
+-- if method == "table" then
+-- propertydata[target] = p_source
+-- for k, v in next, first do
+-- p_source[k] = v
+-- end
+-- elseif method == "function" then
+-- propertydata[target] = p_source
+-- first(target,head,where,p_source,unpack(data,3))
+-- elseif method == "string" then
+-- propertydata[target] = p_source
+-- actions[first](target,head,where,p_source,unpack(data,3))
+-- end
+-- else
+-- if method == "table" then
+-- propertydata[target] = first
+-- elseif method == "function" then
+-- local t = { }
+-- propertydata[target] = t
+-- first(target,head,where,t,unpack(data,3))
+-- elseif method == "string" then
+-- local t = { }
+-- propertydata[target] = t
+-- actions[first](target,head,where,t,unpack(data,3))
+-- end
+-- end
+-- if trace_setting then
+-- report_setting("node %i, id %s, data %s",
+-- target,nodecodes[getid(target)],serialize(propertydata[target],false))
+-- end
+-- end
+-- if nofslots == 1 then
+-- nofslots = 0
+-- last = source
+-- break
+-- else
+-- nofslots = nofslots - 1
+-- end
+-- end
+-- last = source
+-- end
+-- end
+-- end
+--
+-- if last then
+-- removenode(head,last,true)
+-- end
+--
+-- stoptiming(properties)
+--
+-- return head
+--
+-- end
- if nofslots <= 0 then
- return head, false
- end
+if LUATEXVERSION >= 1.090 then
+
+ function properties.attach(head)
- local done = false
- local last = nil
- local head = tonut(head)
+ if nofslots <= 0 then
+ return head
+ end
- starttiming(properties)
+ local last = nil
- for source in traverse_id(whatsit_code,head) do
- if getsubtype(source) == userdefined_code then
- if last then
- removenode(head,last,true)
- last = nil
- end
- if getfield(source,"user_id") == property_id then
- local slot = getfield(source,"value")
- local data = cache[slot]
- if data then
- cache[slot] = nil
- local where = data[1]
- local target = anchored[where](source)
- if target then
- local first = data[2]
- local method = type(first)
- local p_target = propertydata[target]
- local p_source = propertydata[source]
- if p_target then
- if p_source then
- for k, v in next, p_source do
- p_target[k] = v
+ starttiming(properties)
+
+ for source, subtype in nextwhatsit, head do
+ if subtype == userdefined_code then
+ if last then
+ removenode(head,last,true)
+ last = nil
+ end
+ if getfield(source,"user_id") == property_id then
+ local slot = getfield(source,"value")
+ local data = cache[slot]
+ if data then
+ cache[slot] = nil
+ local where = data[1]
+ local target = anchored[where](source)
+ if target then
+ local first = data[2]
+ local method = type(first)
+ local p_target = propertydata[target]
+ local p_source = propertydata[source]
+ if p_target then
+ if p_source then
+ for k, v in next, p_source do
+ p_target[k] = v
+ end
end
- end
- if method == "table" then
- for k, v in next, first do
- p_target[k] = v
+ if method == "table" then
+ for k, v in next, first do
+ p_target[k] = v
+ end
+ elseif method == "function" then
+ first(target,head,where,p_target,unpack(data,3))
+ elseif method == "string" then
+ actions[first](target,head,where,p_target,unpack(data,3))
end
- elseif method == "function" then
- first(target,head,where,p_target,unpack(data,3))
- elseif method == "string" then
- actions[first](target,head,where,p_target,unpack(data,3))
- end
- elseif p_source then
- if method == "table" then
- propertydata[target] = p_source
- for k, v in next, first do
- p_source[k] = v
+ elseif p_source then
+ if method == "table" then
+ propertydata[target] = p_source
+ for k, v in next, first do
+ p_source[k] = v
+ end
+ elseif method == "function" then
+ propertydata[target] = p_source
+ first(target,head,where,p_source,unpack(data,3))
+ elseif method == "string" then
+ propertydata[target] = p_source
+ actions[first](target,head,where,p_source,unpack(data,3))
+ end
+ else
+ if method == "table" then
+ propertydata[target] = first
+ elseif method == "function" then
+ local t = { }
+ propertydata[target] = t
+ first(target,head,where,t,unpack(data,3))
+ elseif method == "string" then
+ local t = { }
+ propertydata[target] = t
+ actions[first](target,head,where,t,unpack(data,3))
end
- elseif method == "function" then
- propertydata[target] = p_source
- first(target,head,where,p_source,unpack(data,3))
- elseif method == "string" then
- propertydata[target] = p_source
- actions[first](target,head,where,p_source,unpack(data,3))
end
- else
- if method == "table" then
- propertydata[target] = first
- elseif method == "function" then
- local t = { }
- propertydata[target] = t
- first(target,head,where,t,unpack(data,3))
- elseif method == "string" then
- local t = { }
- propertydata[target] = t
- actions[first](target,head,where,t,unpack(data,3))
+ if trace_setting then
+ report_setting("node %i, id %s, data %s",
+ target,nodecodes[getid(target)],serialize(propertydata[target],false))
end
end
- if trace_setting then
- report_setting("node %i, id %s, data %s",
- target,nodecodes[getid(target)],serialize(propertydata[target],false))
+ if nofslots == 1 then
+ nofslots = 0
+ last = source
+ break
+ else
+ nofslots = nofslots - 1
end
end
- if nofslots == 1 then
- nofslots = 0
- last = source
- break
- else
- nofslots = nofslots - 1
- end
+ last = source
end
- last = source
end
end
- end
- if last then
- removenode(head,last,true)
- end
+ if last then
+ removenode(head,last,true)
+ end
- stoptiming(properties)
+ stoptiming(properties)
- return head, done
+ return head
+
+ end
+
+local tasks = nodes.tasks
end
@@ -420,9 +520,6 @@ local tasks = nodes.tasks
-- maybe better hard coded in-place
--- tasks.prependaction("processors","before","nodes.properties.attach")
--- tasks.appendaction("shipouts","normalizers","nodes.properties.delayed")
-
statistics.register("properties processing time", function()
return statistics.elapsedseconds(properties)
end)
@@ -430,7 +527,7 @@ end)
-- only for development
-- local function show(head,level,report)
--- for target in traverse(head) do
+-- for target in nextnode, head do
-- local p = propertydata[target]
-- if p then
-- report("level %i, node %i, id %s, data %s",
diff --git a/tex/context/base/mkiv/node-pro.lua b/tex/context/base/mkiv/node-pro.lua
index ad4553b56..ad1035bbc 100644
--- a/tex/context/base/mkiv/node-pro.lua
+++ b/tex/context/base/mkiv/node-pro.lua
@@ -35,7 +35,7 @@ do
local n = 0
local function reconstruct(head) -- we probably have a better one
- local t, n, h = { }, 0, tonut(head)
+ local t, n, h = { }, 0, head
while h do
n = n + 1
local char, id = isglyph(h)
@@ -49,7 +49,7 @@ do
return concat(t)
end
- function processors.tracer(what,state,head,groupcode,before,after,show)
+ function processors.tracer(what,head,groupcode,before,after,show)
if not groupcode then
groupcode = "unknown"
elseif groupcode == "" then
@@ -57,9 +57,9 @@ do
end
n = n + 1
if show then
- report_nodes("%s: location %a, state %a, group %a, # before %a, # after %s, stream: %s",what,n,state,groupcode,before,after,reconstruct(head))
+ report_nodes("%s: location %a, group %a, # before %a, # after %s, stream: %s",what,n,groupcode,before,after,reconstruct(head))
else
- report_nodes("%s: location %a, state %a, group %a, # before %a, # after %s",what,n,state,groupcode,before,after)
+ report_nodes("%s: location %a, group %a, # before %a, # after %s",what,n,groupcode,before,after)
end
end
@@ -74,28 +74,22 @@ do
local has_glyph = nodes.has_glyph
local count_nodes = nodes.countall
- function processors.pre_linebreak_filter(head,groupcode) -- ,size,packtype,direction
+ local function pre_linebreak_filter(head,groupcode) -- ,size,packtype,direction
local found = force_processors or has_glyph(head)
if found then
if trace_callbacks then
local before = count_nodes(head,true)
- local head, done = actions(head,groupcode) -- ,size,packtype,direction
+ head = actions(head,groupcode) -- ,size,packtype,direction
local after = count_nodes(head,true)
- if done then
- tracer("pre_linebreak","changed",head,groupcode,before,after,true)
- else
- tracer("pre_linebreak","unchanged",head,groupcode,before,after,true)
- end
- return done and head or true
+ tracer("pre_linebreak",head,groupcode,before,after,true)
else
- local head, done = actions(head,groupcode) -- ,size,packtype,direction
- return done and head or true
+ head = actions(head,groupcode) -- ,size,packtype,direction
end
elseif trace_callbacks then
local n = count_nodes(head,false)
- tracer("pre_linebreak","no chars",head,groupcode,n,n)
+ tracer("pre_linebreak",head,groupcode,n,n)
end
- return true
+ return head
end
local function hpack_filter(head,groupcode,size,packtype,direction,attributes)
@@ -103,26 +97,21 @@ do
if found then
if trace_callbacks then
local before = count_nodes(head,true)
- local head, done = actions(head,groupcode,size,packtype,direction,attributes)
+ head = actions(head,groupcode,size,packtype,direction,attributes)
local after = count_nodes(head,true)
- if done then
- tracer("hpack","changed",head,groupcode,before,after,true)
- else
- tracer("hpack","unchanged",head,groupcode,before,after,true)
- end
- return done and head or true
+ tracer("hpack",head,groupcode,before,after,true)
else
- local head, done = actions(head,groupcode,size,packtype,direction,attributes)
- return done and head or true
+ head = actions(head,groupcode,size,packtype,direction,attributes)
end
elseif trace_callbacks then
local n = count_nodes(head,false)
- tracer("hpack","no chars",head,groupcode,n,n)
+ tracer("hpack",head,groupcode,n,n)
end
- return true
+ return head
end
- processors.hpack_filter = hpack_filter
+ processors.pre_linebreak_filter = pre_linebreak_filter
+ processors.hpack_filter = hpack_filter
do
@@ -130,11 +119,8 @@ do
local hpack = nodes.hpack
function nodes.fullhpack(head,...)
- local ok = hpack_filter(head)
- if not done or done == true then
- ok = head
- end
- local hp, b = hpack(ok,...)
+ head = hpack_filter(head)
+ local hp, b = hpack(head,...)
setboth(hp)
return hp, b
end
@@ -147,54 +133,41 @@ do
local hpack = nuts.hpack
function nuts.fullhpack(head,...)
- local ok = hpack_filter(tonode(head))
- if not done or done == true then
- ok = head
- else
- ok = tonut(ok)
- end
- local hp, b = hpack(...)
+ local head = tonut(hpack_filter(tonode(head)))
+ local hp, b = hpack(head,...)
setboth(hp)
return hp, b
end
end
- callbacks.register('pre_linebreak_filter', processors.pre_linebreak_filter, "all kind of horizontal manipulations (before par break)")
- callbacks.register('hpack_filter' , processors.hpack_filter, "all kind of horizontal manipulations (before hbox creation)")
+ callbacks.register('pre_linebreak_filter', pre_linebreak_filter, "horizontal manipulations (before par break)")
+ callbacks.register('hpack_filter' , hpack_filter, "horizontal manipulations (before hbox creation)")
end
do
+ -- Beware, these are packaged boxes so no first_glyph test needed. Maybe some day I'll add a hash
+ -- with valid groupcodes. Watch out, much can pass twice, for instance vadjust passes two times,
local actions = tasks.actions("finalizers") -- head, where
local count_nodes = nodes.countall
- -- beware, these are packaged boxes so no first_glyph test
- -- maybe some day a hash with valid groupcodes
- --
- -- beware, much can pass twice, for instance vadjust passes two times
- --
- -- something weird here .. group mvl when making a vbox
-
- function processors.post_linebreak_filter(head,groupcode)
+ local function post_linebreak_filter(head,groupcode)
if trace_callbacks then
local before = count_nodes(head,true)
- local head, done = actions(head,groupcode)
+ head = actions(head,groupcode)
local after = count_nodes(head,true)
- if done then
- tracer("post_linebreak","changed",head,groupcode,before,after,true)
- else
- tracer("post_linebreak","unchanged",head,groupcode,before,after,true)
- end
- return done and head or true
+ tracer("post_linebreak",head,groupcode,before,after,true)
else
- local head, done = actions(head,groupcode)
- return done and head or true
+ head = actions(head,groupcode)
end
+ return head
end
- callbacks.register("post_linebreak_filter", processors.post_linebreak_filter,"all kind of horizontal manipulations (after par break)")
+ processors.post_linebreak_filter = post_linebreak_filter
+
+ callbacks.register("post_linebreak_filter", post_linebreak_filter,"horizontal manipulations (after par break)")
end
@@ -218,9 +191,9 @@ do
if line and getsubtype(line) == line_code then
local head = getlist(line)
if head then
- local okay, done = actions(head,groupcode,line)
- if okay and okay ~= head then
- setlist(line,okay)
+ local result = actions(head,groupcode,line)
+ if result and result ~= head then
+ setlist(line,result)
end
end
end
diff --git a/tex/context/base/mkiv/node-ref.lua b/tex/context/base/mkiv/node-ref.lua
index 1ec77e83d..287112cc8 100644
--- a/tex/context/base/mkiv/node-ref.lua
+++ b/tex/context/base/mkiv/node-ref.lua
@@ -404,8 +404,8 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
end
local list = getlist(current)
if list then
- local h, ok
- h, ok, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir)
+ local h
+ h, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir)
if h ~= current then
setlist(current,h)
end
@@ -441,48 +441,9 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
if reference and (done[reference] or 0) == 0 then
head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
end
- return head, true, pardir, txtdir
+ return head, pardir, txtdir
end
--- local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) -- singular !
--- if not pardir then
--- pardir = "==="
--- end
--- if not texdir then
--- txtdir = "==="
--- end
--- local current = head
--- while current do
--- local id = getid(current)
--- if id == hlist_code or id == vlist_code then
--- local r = getattr(current,attribute)
--- if r and not done[r] then
--- done[r] = true
--- inject_list(id,current,r,make,stack,pardir,txtdir)
--- end
--- local list = getlist(current)
--- if list then
--- local h = inject_area(list,attribute,make,stack,done,current,pardir,txtdir)
--- if h ~= current then
--- setlist(current,h)
--- end
--- end
--- elseif id == dir_code then
--- txtdir = getdir(current)
--- elseif id == localpar_code then
--- pardir = getdir(current)
--- else
--- local r = getattr(current,attribute)
--- if r and not done[r] then
--- done[r] = true
--- head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir)
--- end
--- end
--- current = getnext(current)
--- end
--- return head, true
--- end
-
-- tracing: todo: use predefined colors
local register_color = colors.register
@@ -672,11 +633,9 @@ end
function nodes.references.handler(head)
if head and topofstack > 0 then
- local head = tonut(head)
- local head, done = inject_areas(head,attribute,makereference,stack,done)
- return tonode(head), done
+ return (inject_areas(head,attribute,makereference,stack,done))
else
- return head, false
+ return head
end
end
@@ -783,21 +742,12 @@ local function makedestination(width,height,depth,reference)
end
end
--- function nodes.destinations.handler(head)
--- if head and topofstack > 0 then
--- return inject_area(head,attribute,makedestination,stack,done) -- singular
--- else
--- return head, false
--- end
--- end
function nodes.destinations.handler(head)
if head and topofstack > 0 then
- local head = tonut(head)
- local head, done = inject_areas(head,attribute,makedestination,stack,done)
- return tonode(head), done
+ return (inject_areas(head,attribute,makedestination,stack,done))
else
- return head, false
+ return head
end
end
@@ -907,15 +857,3 @@ statistics.register("interactive elements", function()
return nil
end
end)
-
-function references.enableinteraction()
- enableaction("shipouts","nodes.references.handler")
- enableaction("shipouts","nodes.destinations.handler")
- function references.enableinteraction() end
-end
-
-implement {
- name = "enableinteraction",
- actions = references.enableinteraction,
- onlyonce = true
-}
diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua
index a6211e80e..a33766d77 100644
--- a/tex/context/base/mkiv/node-res.lua
+++ b/tex/context/base/mkiv/node-res.lua
@@ -147,21 +147,22 @@ nutpool.register = register_node -- could be register_nut
-- so far
-local disc = register_nut(new_nut("disc"))
-local kern = register_nut(new_nut("kern",kerncodes.userkern))
-local fontkern = register_nut(new_nut("kern",kerncodes.fontkern))
-local italickern = register_nut(new_nut("kern",kerncodes.italiccorrection))
-local penalty = register_nut(new_nut("penalty"))
-local glue = register_nut(new_nut("glue")) -- glue.spec = nil
-local glue_spec = register_nut(new_nut("glue_spec"))
-local glyph = register_nut(new_nut("glyph",0))
+local disc = register_nut(new_nut(nodecodes.disc))
+local kern = register_nut(new_nut(nodecodes.kern,kerncodes.userkern))
+local fontkern = register_nut(new_nut(nodecodes.kern,kerncodes.fontkern))
+local italickern = register_nut(new_nut(nodecodes.kern,kerncodes.italiccorrection))
+local penalty = register_nut(new_nut(nodecodes.penalty))
+local glue = register_nut(new_nut(nodecodes.glue)) -- glue.spec = nil
+local glue_spec = register_nut(new_nut(nodecodes.gluespec))
+local glyph = register_nut(new_nut(nodecodes.glyph,0))
-local textdir = register_nut(new_nut("dir"))
-local latelua = register_nut(new_nut("whatsit",whatsitcodes.latelua))
-local special = register_nut(new_nut("whatsit",whatsitcodes.special))
+local textdir = register_nut(new_nut(nodecodes.dir))
-local user_node = new_nut("whatsit",whatsitcodes.userdefined)
+local latelua = register_nut(new_nut(nodecodes.whatsit,whatsitcodes.latelua))
+local special = register_nut(new_nut(nodecodes.whatsit,whatsitcodes.special))
+
+local user_node = new_nut(nodecodes.whatsit,whatsitcodes.userdefined)
local user_number = register_nut(copy_nut(user_node)) setfield(user_number, "type",usercodes.number)
local user_nodes = register_nut(copy_nut(user_node)) setfield(user_nodes, "type",usercodes.node)
@@ -170,40 +171,40 @@ local user_tokens = register_nut(copy_nut(user_node)) setfield(user_tokens
----- user_lua = register_nut(copy_nut(user_node)) setfield(user_lua, "type",usercodes.lua) -- in > 0.95
local user_attributes = register_nut(copy_nut(user_node)) setfield(user_attributes,"type",usercodes.attribute)
-local left_margin_kern = register_nut(new_nut("margin_kern",0))
-local right_margin_kern = register_nut(new_nut("margin_kern",1))
+local left_margin_kern = register_nut(new_nut(nodecodes.marginkern,0))
+local right_margin_kern = register_nut(new_nut(nodecodes.marginkern,1))
-local lineskip = register_nut(new_nut("glue",skipcodes.lineskip))
-local baselineskip = register_nut(new_nut("glue",skipcodes.baselineskip))
-local leftskip = register_nut(new_nut("glue",skipcodes.leftskip))
-local rightskip = register_nut(new_nut("glue",skipcodes.rightskip))
+local lineskip = register_nut(new_nut(nodecodes.glue,skipcodes.lineskip))
+local baselineskip = register_nut(new_nut(nodecodes.glue,skipcodes.baselineskip))
+local leftskip = register_nut(new_nut(nodecodes.glue,skipcodes.leftskip))
+local rightskip = register_nut(new_nut(nodecodes.glue,skipcodes.rightskip))
-local temp = register_nut(new_nut("temp",0))
+local temp = register_nut(new_nut(nodecodes.temp,0))
-local noad = register_nut(new_nut("noad"))
-local delimiter = register_nut(new_nut("delim"))
-local fence = register_nut(new_nut("fence"))
-local submlist = register_nut(new_nut("sub_mlist"))
-local accent = register_nut(new_nut("accent"))
-local radical = register_nut(new_nut("radical"))
-local fraction = register_nut(new_nut("fraction"))
-local subbox = register_nut(new_nut("sub_box"))
-local mathchar = register_nut(new_nut("math_char"))
-local mathtextchar = register_nut(new_nut("math_text_char"))
-local choice = register_nut(new_nut("choice"))
+local noad = register_nut(new_nut(nodecodes.noad))
+local delimiter = register_nut(new_nut(nodecodes.delim))
+local fence = register_nut(new_nut(nodecodes.fence))
+local submlist = register_nut(new_nut(nodecodes.submlist))
+local accent = register_nut(new_nut(nodecodes.accent))
+local radical = register_nut(new_nut(nodecodes.radical))
+local fraction = register_nut(new_nut(nodecodes.fraction))
+local subbox = register_nut(new_nut(nodecodes.subbox))
+local mathchar = register_nut(new_nut(nodecodes.mathchar))
+local mathtextchar = register_nut(new_nut(nodecodes.mathtextchar))
+local choice = register_nut(new_nut(nodecodes.choice))
-local boundary = register_nut(new_nut("boundary",boundarycodes.user))
-local wordboundary = register_nut(new_nut("boundary",boundarycodes.word))
+local boundary = register_nut(new_nut(nodecodes.boundary,boundarycodes.user))
+local wordboundary = register_nut(new_nut(nodecodes.boundary,boundarycodes.word))
local cleader = register_nut(copy_nut(glue)) setsubtype(cleader,gluecodes.cleaders) setglue(cleader,0,65536,0,2,0)
-- the dir field needs to be set otherwise crash:
-local rule = register_nut(new_nut("rule")) setdir(rule, "TLT")
-local emptyrule = register_nut(new_nut("rule",rulecodes.empty)) setdir(rule, "TLT")
-local userrule = register_nut(new_nut("rule",rulecodes.user)) setdir(rule, "TLT")
-local hlist = register_nut(new_nut("hlist")) setdir(hlist,"TLT")
-local vlist = register_nut(new_nut("vlist")) setdir(vlist,"TLT")
+local rule = register_nut(new_nut(nodecodes.rule)) setdir(rule, "TLT")
+local emptyrule = register_nut(new_nut(nodecodes.rule,rulecodes.empty)) setdir(rule, "TLT")
+local userrule = register_nut(new_nut(nodecodes.rule,rulecodes.user)) setdir(rule, "TLT")
+local hlist = register_nut(new_nut(nodecodes.hlist)) setdir(hlist,"TLT")
+local vlist = register_nut(new_nut(nodecodes.vlist)) setdir(vlist,"TLT")
function nutpool.glyph(fnt,chr)
local n = copy_nut(glyph)
@@ -388,6 +389,26 @@ function nutpool.userrule(width,height,depth,dir) -- w/h/d == nil will let them
return n
end
+if LUATEXFUNCTIONALITY > 6738 then
+
+ local outlinerule = register_nut(new_nut(nodecodes.rule,rulecodes.outline)) setdir(rule, "TLT")
+
+ function nutpool.outlinerule(width,height,depth,line,dir) -- w/h/d == nil will let them adapt
+ local n = copy_nut(outlinerule)
+ if width or height or depth then
+ setwhd(n,width,height,depth)
+ end
+ if line then
+ setfield(n,"transform",line)
+ end
+ if dir then
+ setdir(n,dir)
+ end
+ return n
+ end
+
+end
+
function nutpool.leader(width,list)
local n = copy_nut(cleader)
if width then
@@ -572,8 +593,9 @@ end
-- housekeeping
local function cleanup(nofboxes) -- todo
- if nodes.tracers.steppers then -- to be resolved
- nodes.tracers.steppers.reset() -- todo: make a registration subsystem
+ local tracers = nodes.tracers
+ if tracers and tracers.steppers then -- to be resolved
+ tracers.steppers.reset() -- todo: make a registration subsystem
end
local nl = 0
local nr = nofreserved
@@ -624,3 +646,45 @@ statistics.register("node memory usage", function() -- comes after cleanup !
end)
lua.registerfinalizer(cleanup, "cleanup reserved nodes")
+
+-- experiment
+
+do
+
+ local glyph = tonode(glyph)
+ local traverse_id = nodes.traverse_id
+
+ local traversers = table.setmetatableindex(function(t,k)
+ local v = traverse_id(type(k) == "number" and k or nodecodes[k],glyph)
+ t[k] = v
+ return v
+ end)
+
+ traversers.node = nodes.traverse (glyph)
+ traversers.char = nodes.traverse_char (glyph)
+ if nuts.traverse_glyph then traversers.glyph = nodes.traverse_glyph(glyph) end
+ if nuts.traverse_list then traversers.list = nodes.traverse_list (glyph) end
+
+ nodes.traversers = traversers
+
+end
+
+do
+
+ local glyph = glyph
+ local traverse_id = nuts.traverse_id
+
+ local traversers = table.setmetatableindex(function(t,k)
+ local v = traverse_id(type(k) == "number" and k or nodecodes[k],glyph)
+ t[k] = v
+ return v
+ end)
+
+ traversers.node = nuts.traverse (glyph)
+ traversers.char = nuts.traverse_char (glyph)
+ if nuts.traverse_glyph then traversers.glyph = nuts.traverse_glyph(glyph) end
+ if nuts.traverse_list then traversers.list = nuts.traverse_list (glyph) end
+
+ nuts.traversers = traversers
+
+end
diff --git a/tex/context/base/mkiv/node-rul.lua b/tex/context/base/mkiv/node-rul.lua
index 7c4c2c2f2..39ad1cf58 100644
--- a/tex/context/base/mkiv/node-rul.lua
+++ b/tex/context/base/mkiv/node-rul.lua
@@ -57,12 +57,13 @@ local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local find_tail = nuts.tail
local setglue = nuts.setglue
-local traverse_id = nuts.traverse_id
local list_dimensions = nuts.rangedimensions
local hpack_nodes = nuts.hpack
local current_attr = nuts.current_attr
local copy_list = nuts.copy_list
+local nexthlist = nuts.traversers.hlist
+
local nodecodes = nodes.nodecodes
local rulecodes = nodes.rulecodes
local gluecodes = nodes.gluecodes
@@ -122,8 +123,8 @@ local setmetatableindex = table.setmetatableindex
--
-local striprange = nodes.striprange
-local processwords = nodes.processwords
+local striprange = nuts.striprange
+local processwords = nuts.processwords
--
@@ -332,7 +333,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
end
end
if mp and mp ~= "" then
- local r = userrule {
+ local r = usernutrule {
width = w,
height = ht,
depth = dp,
@@ -345,7 +346,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
ca = color,
ta = transparency,
}
- inject(tonut(r),w,ht,dp)
+ inject(r,w,ht,dp)
else
local tx = d.text
if tx then
@@ -375,10 +376,8 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
return head
end
-local process = nodes.processwords
-
rules.handler = function(head)
- return process(a_ruled,data,flush_ruled,head)
+ return processwords(a_ruled,data,flush_ruled,head)
end
function rules.enable()
@@ -431,9 +430,9 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha
return head
end
-local process = nodes.processwords
-
-nodes.shifts.handler = function(head) return process(a_shifted,data,flush_shifted,head) end
+nodes.shifts.handler = function(head)
+ return processwords(a_shifted,data,flush_shifted,head)
+end
function nodes.shifts.enable()
enableaction("shipouts","nodes.shifts.handler")
@@ -461,7 +460,7 @@ local function linefiller(current,data,width,location)
local ca = data.ca
local ta = data.ta
if mp and mp ~= "" then
- return tonut(userrule {
+ return usernutrule {
width = width,
height = height,
depth = depth,
@@ -473,7 +472,7 @@ local function linefiller(current,data,width,location)
ta = ta,
option = location,
direction = getdir(current),
- })
+ }
else
local rule = new_rule(width,height,depth)
if ca then
@@ -497,7 +496,7 @@ function nodes.linefillers.filler(current,data,width,height,depth)
local ca = data.ca
local ta = data.ta
if mp and mp ~= "" then
- return tonut(userrule {
+ return usernutrule {
width = width,
height = height,
depth = depth,
@@ -509,7 +508,7 @@ function nodes.linefillers.filler(current,data,width,height,depth)
ta = ta,
option = location,
direction = getdir(current),
- })
+ }
else
local rule = new_rule(width,height,depth)
if ca then
@@ -535,9 +534,8 @@ local function find_attr(head,attr)
end
end
-function nodes.linefillers.handler(head)
--- local current = tonut(head) -- when we hook into the contributers
- for current in traverse_id(hlist_code,tonut(head)) do
+function nodes.linefillers.handler(head) -- traverse_list
+ for current in nexthlist, head do -- LUATEXVERSION >= 1.090
if getsubtype(current) == line_code then
local list = getlist(current)
if list then
@@ -661,6 +659,132 @@ function nodes.linefillers.handler(head)
return head
end
+if LUATEXVERSION >= 1.090 then
+
+ function nodes.linefillers.handler(head) -- traverse_list
+ for current, subtype, list in nexthlist, head do -- LUATEXVERSION >= 1.090
+ if list and subtype == line_code then
+ -- why doesn't leftskip take the attributes
+ -- or list[linefiller] or maybe first match (maybe we need a fast helper for that)
+ local a = getattr(current,a_linefiller)
+ if a then
+ local class = a % 1000
+ local data = data[class]
+ if data then
+ local location = data.location
+ local scope = data.scope
+ local distance = data.distance
+ local threshold = data.threshold
+ local leftlocal = false
+ local rightlocal = false
+ --
+ if scope == v_right then
+ leftlocal = true
+ elseif scope == v_left then
+ rightlocal = true
+ elseif scope == v_local then
+ leftlocal = true
+ rightlocal = true
+ end
+ --
+ if location == v_left or location == v_both then
+ local lskip = nil -- leftskip
+ local iskip = nil -- indentation
+ local head = list
+ while head do
+ local id = getid(head)
+ if id == glue_code then
+ if getsubtype(head) == leftskip_code then
+ lskip = head
+ else
+ break
+ end
+ elseif id == localpar_code or id == dir_code then
+ -- go on
+ elseif id == hlist_code then
+ if getsubtype(head) == indent_code then
+ iskip = head
+ end
+ break
+ else
+ break
+ end
+ head = getnext(head)
+ end
+ if head then
+ local indentation = iskip and getwidth(iskip) or 0
+ local leftfixed = lskip and getwidth(lskip) or 0
+ local lefttotal = lskip and effective_glue(lskip,current) or 0
+ local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance
+ if width > threshold then
+ if iskip then
+ setwidth(iskip,0)
+ end
+ if lskip then
+ setglue(lskip,leftlocal and getwidth(lskip) or nil)
+ if distance > 0 then
+ insert_node_after(list,lskip,new_kern(distance))
+ end
+ insert_node_after(list,lskip,linefiller(current,data,width,"left"))
+ else
+ insert_node_before(list,head,linefiller(current,data,width,"left"))
+ if distance > 0 then
+ insert_node_before(list,head,new_kern(distance))
+ end
+ end
+ end
+ end
+ end
+ --
+ if location == v_right or location == v_both then
+ local pskip = nil -- parfillskip
+ local rskip = nil -- rightskip
+ local tail = find_tail(list)
+ while tail and getid(tail) == glue_code do
+ local subtype = getsubtype(tail)
+ if subtype == rightskip_code then
+ rskip = tail
+ elseif subtype == parfillskip_code then
+ pskip = tail
+ else
+ break
+ end
+ tail = getprev(tail)
+ end
+ if tail then
+ local rightfixed = rskip and getwidth(rskip) or 0
+ local righttotal = rskip and effective_glue(rskip,current) or 0
+ local parfixed = pskip and getwidth(pskip) or 0
+ local partotal = pskip and effective_glue(pskip,current) or 0
+ local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance
+ if width > threshold then
+ if pskip then
+ setglue(pskip)
+ end
+ if rskip then
+ setglue(rskip,rightlocal and getwidth(rskip) or nil)
+ if distance > 0 then
+ insert_node_before(list,rskip,new_kern(distance))
+ end
+ insert_node_before(list,rskip,linefiller(current,data,width,"right"))
+ else
+ insert_node_after(list,tail,linefiller(current,data,width,"right"))
+ if distance > 0 then
+ insert_node_after(list,tail,new_kern(distance))
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return head
+ end
+
+end
+
local enable = false
function nodes.linefillers.enable()
@@ -751,8 +875,6 @@ implement {
-- We add a bonus feature here:
-local new_rule = nodes.pool.rule
-
interfaces.implement {
name = "autorule",
arguments = {
@@ -772,14 +894,15 @@ interfaces.implement {
t.height,
t.depth
)
+ setattrlist(n,current_attr())
if LUATEXFUNCTIONALITY >= 6710 then
if l then
- n.left = l
+ setfield(n,"left",l)
end
if r then
- n.right = r
+ etfield(n,"right",r)
end
end
- context(n)
+ context(tonode(n))
end
}
diff --git a/tex/context/base/mkiv/node-scn.lua b/tex/context/base/mkiv/node-scn.lua
index b294b3013..62c9fecec 100644
--- a/tex/context/base/mkiv/node-scn.lua
+++ b/tex/context/base/mkiv/node-scn.lua
@@ -12,8 +12,6 @@ local attributes = attributes
local nodes = nodes
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -97,7 +95,7 @@ local function striprange(first,last) -- todo: dir
return first, last
end
-nodes.striprange = striprange
+nuts.striprange = striprange
-- todo: order and maybe other dimensions
@@ -228,17 +226,11 @@ local function processwords(attribute,data,flush,head,parent,skip) -- we have hl
end
end
-nodes.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir
- head = tonut(head)
- if parent then
- parent = tonut(parent)
- end
- local head, done = processwords(attribute,data,flush,head,parent)
- return tonode(head), done
+nuts.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir
+ return processwords(attribute,data,flush,head,parent)
end
-- works on lines !
-
-- todo: stack because skip can change when nested
local function processranges(attribute,flush,head,parent,depth,skip)
@@ -319,11 +311,6 @@ local function processranges(attribute,flush,head,parent,depth,skip)
end
end
-nodes.processranges = function(attribute,flush,head,parent) -- we have hlistdir and local dir
- head = tonut(head)
- if parent then
- parent = tonut(parent)
- end
- local head, done = processranges(attribute,flush,head,parent,0)
- return tonode(head), done
+nuts.processranges = function(attribute,flush,head,parent) -- we have hlistdir and local dir
+ return processranges(attribute,flush,head,parent,0)
end
diff --git a/tex/context/base/mkiv/node-shp.lua b/tex/context/base/mkiv/node-shp.lua
index 2c20d9567..74f3c4da2 100644
--- a/tex/context/base/mkiv/node-shp.lua
+++ b/tex/context/base/mkiv/node-shp.lua
@@ -27,15 +27,14 @@ local whatsit_code = nodecodes.whatsit
local fulldisc_code = disccodes.discretionary
-local texgetbox = tex.getbox
-
local implement = interfaces.implement
local nuts = nodes.nuts
local tonut = nuts.tonut
local tonode = nuts.tonode
local remove_node = nuts.remove
-local traverse_nodes = nuts.traverse
+
+local nextnode = nuts.traversers.node
local setfield = nuts.setfield
local setlink = nuts.setlink
@@ -50,6 +49,9 @@ local getsubtype = nuts.getsubtype
local setlist = nuts.setlist
+local getbox = nuts.getbox
+local getboxnode = nodes.getbox
+
local removables = {
[whatsitcodes.open] = true,
[whatsitcodes.close] = true,
@@ -117,6 +119,8 @@ local function cleanup_redundant(head) -- better name is: flatten_page
return head
end
+handlers.cleanuppage = cleanup_redundant -- nut
+
local function cleanup_flushed(head) -- rough
local start = head
while start do
@@ -143,26 +147,20 @@ local function cleanup_flushed(head) -- rough
return head
end
-function handlers.cleanuppage(head)
- return tonode(cleanup_redundant(tonut(head))), true
-end
-
-function handlers.cleanupbox(head)
- return tonode(cleanup_flushed(tonut(head))), true
+function handlers.cleanupbox(box)
+ cleanup_flushed(getbox(box))
end
local actions = tasks.actions("shipouts")
-function handlers.finalize(head,where) -- problem, attr loaded before node, todo ...
- return actions(head,where)
+function handlers.finalizebox(box)
+ actions(getbox(box)) -- nut
end
--- handlers.finalize = actions
-
-- interface
-implement { name = "cleanupbox", actions = { texgetbox, cleanup_flushed }, arguments = "integer" }
-implement { name = "finalizebox", actions = { texgetbox, actions }, arguments = "integer" }
+implement { name = "cleanupbox", actions = handlers.cleanupbox, arguments = "integer" }
+implement { name = "finalizebox", actions = handlers.finalizebox, arguments = "integer" }
-- just in case we want to optimize lookups:
@@ -192,7 +190,7 @@ local function count(head,data,subcategory)
-- no components, pre, post, replace .. can maybe an option .. but
-- we use this for optimization so it makes sense to look the the
-- main node only
- for n, id in traverse_nodes(tonut(head)) do
+ for n, id in nextnode, tonut(head) do
local dn = data[nodecodes[id]] -- we could use id and then later convert to nodecodes
dn[subcategory] = dn[subcategory] + 1
if id == hlist_code or id == vlist_code then
diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua
index 9d716c44a..efac2795a 100644
--- a/tex/context/base/mkiv/node-syn.lua
+++ b/tex/context/base/mkiv/node-syn.lua
@@ -126,8 +126,6 @@ local report_system = logs.reporter("system")
local tex = tex
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getid = nuts.getid
local getlist = nuts.getlist
@@ -623,16 +621,10 @@ end
collect = collect_max
function synctex.collect(head,where)
- if enabled then
- if where == "object" then
- return head, false
- else
- local h = tonut(head)
- h = collect(h,h)
- return tonode(h), true
- end
+ if enabled and where ~= "object" then
+ return collect(head,head)
else
- return head, false
+ return head
end
end
@@ -678,7 +670,7 @@ function synctex.enable()
enabled = true
set_synctex_mode(3) -- we want details
if not used then
- nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect")
+ nodes.tasks.enableaction("shipouts","luatex.synctex.collect")
report_system("synctex functionality is enabled, expect 5-10 pct runtime overhead!")
used = true
end
diff --git a/tex/context/base/mkiv/node-tex.lua b/tex/context/base/mkiv/node-tex.lua
index c9d3091df..81ed80d15 100644
--- a/tex/context/base/mkiv/node-tex.lua
+++ b/tex/context/base/mkiv/node-tex.lua
@@ -10,9 +10,11 @@ builders = builders or { }
local kernel = builders.kernel or { }
builders.kernel = kernel
+local nuts = nodes.nuts
+
local hyphenate = lang.hyphenate
-local ligaturing = node.ligaturing
-local kerning = node.kerning
+local ligaturing = nuts.ligaturing
+local kerning = nuts.kerning
kernel.originals = {
hyphenate = hyphenate,
@@ -21,18 +23,18 @@ kernel.originals = {
}
function kernel.hyphenation(head)
- local done = hyphenate(head)
- return head, done
+ hyphenate(head)
+ return head
end
function kernel.ligaturing(head)
- local head, tail, done = ligaturing(head) -- we return 3 values indeed
- return head, done
+ local head, tail = ligaturing(head)
+ return head
end
function kernel.kerning(head)
- local head, tail, done = kerning(head) -- we return 3 values indeed
- return head, done
+ local head, tail = kerning(head)
+ return head
end
callbacks.register('hyphenate' , false, "normal hyphenation routine, called elsewhere")
diff --git a/tex/context/base/mkiv/node-tra.lua b/tex/context/base/mkiv/node-tra.lua
index a2e5a7653..077506e46 100644
--- a/tex/context/base/mkiv/node-tra.lua
+++ b/tex/context/base/mkiv/node-tra.lua
@@ -57,8 +57,9 @@ local flush_list = nuts.flush_list
local count_nodes = nuts.countall
local used_nodes = nuts.usedlist
-local traverse_by_id = nuts.traverse_id
-local traverse_nodes = nuts.traverse
+local nextnode = nuts.traversers.node
+local nextglyph = nuts.traversers.glyph
+
local d_tostring = nuts.tostring
local nutpool = nuts.pool
@@ -90,7 +91,7 @@ function nodes.showlist(head, message)
if message then
report_nodes(message)
end
- for n in traverse_nodes(tonut(head)) do
+ for n in nextnode, tonut(head) do
report_nodes(d_tostring(n))
end
end
@@ -98,7 +99,7 @@ end
function nodes.handlers.checkglyphs(head,message)
local h = tonut(head)
local t = { }
- for g in traverse_by_id(glyph_code,h) do
+ for g in nextglyph, h do
t[#t+1] = formatters["%U:%s"](getchar(g),getsubtype(g))
end
if #t > 0 then
@@ -114,8 +115,8 @@ end
function nodes.handlers.checkforleaks(sparse)
local l = { }
local q = used_nodes()
- for p in traverse_nodes(q) do
- local s = table.serialize(nodes.astable(p,sparse),nodecodes[getid(p)])
+ for p, id in nextnode, q do
+ local s = table.serialize(nodes.astable(p,sparse),nodecodes[id])
l[s] = (l[s] or 0) + 1
end
flush_list(q)
@@ -155,7 +156,12 @@ local function tosequence(start,stop,compact)
t[#t+1] = nodecodes[id]
end
elseif id == dir_code or id == localpar_code then
- t[#t+1] = "[" .. getdir(start) .. "]"
+ local d = getdir(start)
+ if d then
+ t[#t+1] = "[" .. d .. "]"
+ else
+ t[#t+1] = "[]"
+ end
elseif compact then
t[#t+1] = "[]"
else
@@ -180,13 +186,13 @@ end
nodes.tosequence = tosequence
nuts .tosequence = tosequence
-function nodes.report(t,done)
- report_nodes("output %a, changed %a, %s nodes",status.output_active,done,count_nodes(tonut(t)))
+function nodes.report(t)
+ report_nodes("output %a, %s nodes",status.output_active,count_nodes(t))
end
function nodes.packlist(head)
local t = { }
- for n in traverse_nodes(tonut(head)) do
+ for n in nextnode, tonut(head) do
t[#t+1] = d_tostring(n)
end
return t
@@ -198,9 +204,9 @@ function nodes.idstostring(head,tail)
local t = { }
local last_id = nil
local last_n = 0
- for n, id in traverse_nodes(head,tail) do -- hm, does not stop at tail
+ for n, id, subtype in nextnode, head do
if id == whatsit_code then
- id = whatcodes[getsubtype(n)]
+ id = whatcodes[subtype]
else
id = nodecodes[id]
end
@@ -353,10 +359,9 @@ local what = { [0] = "unknown", "line", "box", "indent", "row", "cell" }
local function showboxes(n,symbol,depth)
depth = depth or 0
symbol = symbol or "."
- for n, id in traverse_nodes(tonut(n)) do
+ for n, id, subtype in nextnode, tonut(n) do
if id == hlist_code or id == vlist_code then
- local s = getsubtype(n)
- report_nodes(rep(symbol,depth) .. what[s] or s)
+ report_nodes(rep(symbol,depth) .. what[subtype] or subtype)
showboxes(getlist(n),symbol,depth+1)
end
end
diff --git a/tex/context/base/mkiv/node-tsk.lua b/tex/context/base/mkiv/node-tsk.lua
index 4aec3a038..b61515aed 100644
--- a/tex/context/base/mkiv/node-tsk.lua
+++ b/tex/context/base/mkiv/node-tsk.lua
@@ -55,6 +55,7 @@ function tasks.new(specification) -- was: name,arguments,list
local sequence = specification.sequence
if name and sequence then
local tasklist = newsequencer {
+ name = name
-- we can move more to the sequencer now .. todo
}
tasksdata[name] = {
@@ -171,18 +172,26 @@ function tasks.disablegroup(name,group)
end
end
-function tasks.appendaction(name,group,action,where,kind)
+function tasks.appendaction(name,group,action,where,kind,state)
local data = validgroup(name,"append action")
if data then
- appendaction(data.list,group,action,where,kind)
+ local list = data.list
+ appendaction(list,group,action,where,kind)
+ if state == "disabled" or (state == "production" and environment.initex) then
+ disableaction(list,action)
+ end
data.runner = false
end
end
-function tasks.prependaction(name,group,action,where,kind)
+function tasks.prependaction(name,group,action,where,kind,state)
local data = validgroup(name,"prepend action")
if data then
- prependaction(data.list,group,action,where,kind)
+ local list = data.list
+ prependaction(list,group,action,where,kind)
+ if state == "disabled" or (state == "production" and environment.initex) then
+ disableaction(list,action)
+ end
data.runner = false
end
end
@@ -222,123 +231,23 @@ function tasks.actions(name) -- we optimize for the number or arguments (no ...)
if data then
local t = data.templates
if t then
+ t.name = data.name
return function(...)
total = total + 1 -- will go away
local runner = data.runner
if not runner then
created = created + 1
--- if trace_tasks then
- report_tasks("creating runner %a",name)
--- end
- runner = compile(data.list,data.processor,t)
- data.runner = runner
- end
- return runner(...)
- end
- end
- local n = data.arguments or 0
- if n == 0 then
- return function(head)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
if trace_tasks then
report_tasks("creating runner %a",name)
end
- runner = compile(data.list,data.processor,0)
- data.runner = runner
- end
- return runner(head)
- end
- elseif n == 1 then
- return function(head,one)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,1)
- end
- runner = compile(data.list,data.processor,1)
- data.runner = runner
- end
- return runner(head,one)
- end
- elseif n == 2 then
- return function(head,one,two)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,2)
- end
- runner = compile(data.list,data.processor,2)
- data.runner = runner
- end
- return runner(head,one,two)
- end
- elseif n == 3 then
- return function(head,one,two,three)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,3)
- end
- runner = compile(data.list,data.processor,3)
- data.runner = runner
- end
- return runner(head,one,two,three)
- end
- elseif n == 4 then
- return function(head,one,two,three,four)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,4)
- end
- runner = compile(data.list,data.processor,4)
- data.runner = runner
- end
- return runner(head,one,two,three,four)
- end
- elseif n == 5 then
- return function(head,one,two,three,four,five)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,5)
- end
- runner = compile(data.list,data.processor,5)
- data.runner = runner
- end
- return runner(head,one,two,three,four,five)
- end
- else
- return function(head,...)
- total = total + 1 -- will go away
- local runner = data.runner
- if not runner then
- created = created + 1
- if trace_tasks then
- report_tasks("creating runner %a with %s extra arguments",name,n)
- end
- runner = compile(data.list,data.processor,"n")
+ runner = compile(data.list,data.processor,t)
data.runner = runner
end
- return runner(head,...)
+ return runner(...)
end
end
- else
- return nil
end
+ return nil
end
function tasks.table(name) --maybe move this to task-deb.lua
@@ -368,12 +277,119 @@ function tasks.table(name) --maybe move this to task-deb.lua
end
end
--- this will move
+-- -- shipouts -- --
+
+-- the shipout handlers acts on boxes so we don't need to return something
+-- and also don't need to keep the state (done)
+
+tasks.new {
+ name = "shipouts",
+ processor = nodeprocessor,
+ sequence = {
+ "before", -- users
+ "normalizers", -- system
+ "finishers", -- system
+ "after", -- users
+ "wrapup", -- system
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead))))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead))
+]],
+
+nonut = [[
+ %action%(nuthead)
+]],
+
+ }
+}
+
+-- -- finalizers -- --
+
+tasks.new {
+ name = "finalizers",
+ sequence = {
+ "before", -- for users
+ "normalizers",
+ "fonts",
+ "lists",
+ "after", -- for users
+ },
+ processor = nodeprocessor,
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode)
+]],
+
+ }
+}
+
+-- -- processors -- --
tasks.new {
name = "processors",
- arguments = 5, -- often only the first is used, and the last three are only passed in hpack filter
--- arguments = 2,
processor = nodeprocessor,
sequence = {
"before", -- for users
@@ -383,56 +399,297 @@ tasks.new {
"fonts",
"lists",
"after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode,size,packtype,direction,attributes)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,direction,attributes)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode,size,packtype,direction,attributes)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode,size,packtype,direction,attributes)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode,size,packtype,direction,attributes)
+]],
+
}
}
tasks.new {
name = "finalizers",
- arguments = 1,
processor = nodeprocessor,
sequence = {
"before", -- for users
"normalizers",
--- "characters",
--- "finishers",
"fonts",
"lists",
"after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead))))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead))
+]],
+
+nonut = [[
+ %action%(nuthead)
+]],
+
}
}
tasks.new {
- name = "shipouts",
- arguments = 1,
- -- nostate = true, -- maybe but only for main ones so little gain
+ name = "mvlbuilders",
processor = nodeprocessor,
sequence = {
"before", -- for users
"normalizers",
- "finishers",
"after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode)
+]],
+
}
}
tasks.new {
- name = "mvlbuilders",
- arguments = 1,
+ name = "vboxbuilders",
processor = nodeprocessor,
sequence = {
"before", -- for users
"normalizers",
"after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode,size,packtype,maxdepth,direction)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode,size,packtype,maxdepth,direction)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode,size,packtype,maxdepth,direction)
+]],
+
}
+
}
tasks.new {
- name = "vboxbuilders",
- arguments = 5,
+ name = "contributers",
processor = nodeprocessor,
sequence = {
"before", -- for users
"normalizers",
"after", -- for users
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,groupcode,line)
+ local nuthead = tonut(head)
+ local nutline = tonut(line)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),groupcode,line)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,groupcode,nutline)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),groupcode,line)
+]],
+
+nonut = [[
+ %action%(nuthead,groupcode,nutline)
+]],
+
+ }
+}
+
+-- -- math -- --
+
+tasks.new {
+ name = "math",
+ processor = nodeprocessor,
+ sequence = {
+ "before",
+ "normalizers",
+ "builders",
+ "after",
+ },
+ templates = {
+
+default = [[
+return function(head)
+ return head
+end
+]],
+
+process = [[
+local tonut = nodes.tonut
+local tonode = nodes.nuts.tonode
+
+%localize%
+
+return function(head,style,penalties)
+ local nuthead = tonut(head)
+
+%actions%
+ return tonode(nuthead)
+end
+]],
+
+step = [[
+ nuthead = tonut((%action%(tonode(nuthead),style,penalties)))
+]],
+
+nut = [[
+ nuthead = %action%(nuthead,style,penalties)
+]],
+
+nohead = [[
+ %action%(tonode(nuthead),style,penalties)
+]],
+
+nonut = [[
+ %action%(nuthead,style,penalties)
+]],
+
}
}
@@ -458,18 +715,7 @@ tasks.new {
-- }
-- }
-tasks.new {
- name = "contributers",
- arguments = 2, -- [head] where parent
- processor = nodeprocessor,
- sequence = {
- "before", -- for users
- "normalizers",
- "after", -- for users
- }
-}
-
--- for now quite useless (too fuzzy0
+-- for now quite useless (too fuzzy)
--
-- tasks.new {
-- name = "listbuilders",
diff --git a/tex/context/base/mkiv/pack-obj.lua b/tex/context/base/mkiv/pack-obj.lua
index 3f2b2edfe..479c234b4 100644
--- a/tex/context/base/mkiv/pack-obj.lua
+++ b/tex/context/base/mkiv/pack-obj.lua
@@ -26,10 +26,7 @@ local new_latelua = nuts.pool.latelua
local settexdimen = tokens.setters.dimen
-local gettexbox = tokens.getters.box
-local settexbox = tokens.setters.box
-local gettexdimen = tokens.getters.dimen
-local gettexcount = tokens.getters.count
+local getcount = tex.getcount
local implement = interfaces.implement
local setmacro = interfaces.setmacro
@@ -129,7 +126,7 @@ local objects = objects
function objects.register(ns,id,b,referenced,offset,mode)
objects.n = objects.n + 1
- nodes.handlers.finalize(gettexbox(b),"object")
+ nodes.handlers.finalizebox(b)
if mode == 0 then
-- tex
data[ns][id] = {
@@ -160,7 +157,7 @@ function objects.restore(ns,id) -- why not just pass a box number here too (ok,
if status then
local list = getlist(hbox)
local page = new_latelua(function()
- saveobject(ns .. "::" .. id,index,gettexcount("realpageno"))
+ saveobject(ns .. "::" .. id,index,getcount("realpageno"))
end)
setlink(list,page)
end
@@ -191,7 +188,7 @@ function objects.reference(ns,id)
end
function objects.page(ns,id)
- return getobjectpage(ns .."::" .. id,gettexcount("realpageno"))
+ return getobjectpage(ns .."::" .. id,getcount("realpageno"))
end
function objects.found(ns,id)
diff --git a/tex/context/base/mkiv/pack-rul.lua b/tex/context/base/mkiv/pack-rul.lua
index c9771546c..a270bffe7 100644
--- a/tex/context/base/mkiv/pack-rul.lua
+++ b/tex/context/base/mkiv/pack-rul.lua
@@ -51,10 +51,12 @@ local setboxglue = nuts.setboxglue
local getboxglue = nuts.getboxglue
local hpack = nuts.hpack
-local traverse_id = nuts.traverse_id
local list_dimensions = nuts.dimensions
local flush_node = nuts.flush
+local nexthlist = nuts.traversers.hlist
+local nextvlist = nuts.traversers.vlist
+
local checkformath = false
directives.register("framed.checkmath",function(v) checkformath = v end) -- experiment
@@ -108,12 +110,12 @@ local function doreshapeframedbox(n)
end
end
local hdone = false
- for h in traverse_id(hlist_code,list) do -- no dir etc needed
+ for h in nexthlist, list do -- no dir etc needed
check(h,true)
hdone = true
end
-- local vdone = false
- for v in traverse_id(vlist_code,list) do -- no dir etc needed
+ for v in nextvlist, list do -- no dir etc needed
check(v,false)
-- vdone = true
end
@@ -121,7 +123,7 @@ local function doreshapeframedbox(n)
-- done)
elseif maxwidth ~= 0 then
if hdone then
- for h in traverse_id(hlist_code,list) do
+ for h in nexthlist, list do
local l = getlist(h)
if l then
local subtype = getsubtype(h)
@@ -142,7 +144,7 @@ local function doreshapeframedbox(n)
end
end
-- if vdone then
- -- for v in traverse_id(vlist_code,list) do
+ -- for v in nextvlist, list do
-- local width = getwidth(n)
-- if width > maxwidth then
-- setwidth(v,maxwidth)
@@ -164,7 +166,108 @@ local function doreshapeframedbox(n)
texsetdimen("global","framedaveragewidth",averagewidth)
end
-local function doanalyzeframedbox(n)
+if LUATEXVERSION >= 1.090 then
+
+ local traverse_list = node.direct.traverse_list
+
+ local nextlist = nuts.traversers.list
+
+ -- local function doreshapeframedbox(n)
+ doreshapeframedbox = function(n)
+ local box = getbox(n)
+ local noflines = 0
+ local nofnonzero = 0
+ local firstheight = nil
+ local lastdepth = nil
+ local lastlinelength = 0
+ local minwidth = 0
+ local maxwidth = 0
+ local totalwidth = 0
+ local averagewidth = 0
+ local boxwidth = getwidth(box)
+ if boxwidth ~= 0 then -- and h.subtype == vlist_code
+ local list = getlist(box)
+ if list then
+ local hdone = false
+ for n, id, subtype, list in nextlist, list do -- no dir etc needed
+ local width, height, depth = getwhd(n)
+ if not firstheight then
+ firstheight = height
+ end
+ lastdepth = depth
+ noflines = noflines + 1
+ if list then
+ if id == hlist_code then
+ if subtype == box_code or subtype == line_code then
+ lastlinelength = list_dimensions(list,getdir(n))
+ else
+ lastlinelength = width
+ end
+ hdone = true
+ else
+ lastlinelength = width
+ -- vdone = true
+ end
+ if lastlinelength > maxwidth then
+ maxwidth = lastlinelength
+ end
+ if lastlinelength < minwidth or minwidth == 0 then
+ minwidth = lastlinelength
+ end
+ if lastlinelength > 0 then
+ nofnonzero = nofnonzero + 1
+ end
+ totalwidth = totalwidth + lastlinelength
+ end
+ end
+ if not firstheight then
+ -- done)
+ elseif maxwidth ~= 0 then
+ if hdone then
+ for h, id, subtype, list in nextlist, list do
+ if list and id == hlist_code then
+ if subtype == box_code or subtype == line_code then
+ local p = hpack(list,maxwidth,'exactly',getdir(h)) -- multiple return value
+ local set, order, sign = getboxglue(p)
+ setboxglue(h,set,order,sign)
+ setlist(p)
+ flush_node(p)
+ elseif checkformath and subtype == equation_code then
+ -- display formulas use a shift
+ if nofnonzero == 1 then
+ setshift(h,0)
+ end
+ end
+ setwidth(h,maxwidth)
+ end
+ end
+ end
+ -- if vdone then
+ -- for v in nextvlist, list do
+ -- local width = getwidth(n)
+ -- if width > maxwidth then
+ -- setwidth(v,maxwidth)
+ -- end
+ -- end
+ -- end
+ setwidth(box,maxwidth)
+ averagewidth = noflines > 0 and totalwidth/noflines or 0
+ else -- e.g. empty math {$ $} or \hbox{} or ...
+ setwidth(box,0)
+ end
+ end
+ end
+ texsetcount("global","framednoflines",noflines)
+ texsetdimen("global","framedfirstheight",firstheight or 0) -- also signal
+ texsetdimen("global","framedlastdepth",lastdepth or 0)
+ texsetdimen("global","framedminwidth",minwidth)
+ texsetdimen("global","framedmaxwidth",maxwidth)
+ texsetdimen("global","framedaveragewidth",averagewidth)
+ end
+
+end
+
+local function doanalyzeframedbox(n) -- traverse_list
local box = getbox(n)
local noflines = 0
local firstheight = nil
@@ -180,10 +283,10 @@ local function doanalyzeframedbox(n)
lastdepth = depth
noflines = noflines + 1
end
- for h in traverse_id(hlist_code,list) do
+ for h in nexthlist, list do
check(h)
end
- for v in traverse_id(vlist_code,list) do
+ for v in nextvlist, list do
check(v)
end
end
@@ -228,10 +331,10 @@ local function maxboxwidth(box)
end
end
end
- for h in traverse_id(hlist_code,list) do -- no dir etc needed
+ for h in nexthlist, list do -- no dir etc needed
check(h,true)
end
- for v in traverse_id(vlist_code,list) do -- no dir etc needed
+ for v in nextvlist, list do -- no dir etc needed
check(v,false)
end
return maxwidth
diff --git a/tex/context/base/mkiv/page-imp.mkiv b/tex/context/base/mkiv/page-imp.mkiv
index c08f9856f..d4526a59f 100644
--- a/tex/context/base/mkiv/page-imp.mkiv
+++ b/tex/context/base/mkiv/page-imp.mkiv
@@ -63,9 +63,21 @@
\newbox \shipoutscratchbox
-\setnewconstant\shipoutfinalizemethod\plusone % this will be default (we will have two finalizers)
+\setnewconstant\shipoutfinalizemethod\plusone
-\unexpanded\def\installshipoutmethod#1#2% % a handler takes one argument: something to be boxed
+\unexpanded\def\shipoutrange#1#2%
+ {\begingroup
+ \scratchtoks\emptytoks
+ \dostepwiserecurse{#1}{\numexpr#2-\plusone\relax}\plusone{\etoksapp\scratchtoks{##1,}}%
+ \xdef\pagestoshipout{\the\scratchtoks,\number#2}%
+ \doglobal\appendtoks
+ \ifnum\realpageno>\numexpr#2+\plusone\relax
+ \global\everypar{\normalend}%
+ \fi
+ \to\everyaftershipout
+ \endgroup}
+
+\unexpanded\def\installshipoutmethod#1#2% % a handler takes one argument: something to be boxed
{\setgvalue{\??shipoutmethod#1}##1{#2{##1}}} % and shipped out (don't depend on the exact package)
\let\installpagehandler\installshipoutmethod % will go
@@ -73,13 +85,6 @@
\unexpanded\def\invokepagehandler#1%
{\expandnamespacevalue\??shipoutmethod{#1}\v!normal}
-% \def\page_shipouts_handle
-% {\csname\??shipoutmethod\ifcsname\??shipoutmethod\v_page_target_method\endcsname
-% \v_page_target_method
-% \else
-% \v!none
-% \fi\endcsname}
-
\def\page_shipouts_handle
{\ifcsname\??shipoutmethod\v_page_target_method\endcsname
\expandafter\lastnamedcs
@@ -112,12 +117,14 @@
\page_boxes_flush_before
\fi
\the\everybeforeshipout
- \ifcase\shipoutfinalizemethod
+ \ifcase\shipoutfinalizemethod % not nice ... needs thinking
\page_shipouts_handle{#1}%
\else
- \setbox\shipoutscratchbox\hpack{#1}% just in case there are objects there, hook for testing (will go away)
- \finalizeshipoutbox\shipoutscratchbox
- \page_shipouts_handle{\box\shipoutscratchbox}%
+ \setbox\shipoutscratchbox\hpack
+ {#1}% just in case there are objects there, hook for testing (will go away)
+ \page_shipouts_handle
+ {\finalizeshipoutbox\shipoutscratchbox
+ \box\shipoutscratchbox}%
\fi
\setnextrealpageno % so this comes before \everyaftershipout so in fact:
\the\everyaftershipout % at this point we're already on the next realpage
@@ -127,11 +134,12 @@
\def\page_shipouts_ignore#1%
{\begingroup
- \message
- {[\ifarrangingpages arranged \fi page
+ \writestatus\m!system
+ {\ifarrangingpages arranged \fi page
\ifarrangingpages\the\arrangeno\else\the\realpageno\fi\normalspace
- not flushed]}%
- \setbox\scratchbox\hpack{#1}%
+ not flushed}%
+ % \setbox\scratchbox\hpack
+ % {#1}% no finalize
\deadcycles\zerocount
\endgroup}
@@ -173,7 +181,8 @@
\normalexpanded{\doifelseinset{\the\shippedoutpages}{\pagestoshipout}}\donetrue\donefalse
\fi
\ifdone
- \setbox\shipoutscratchbox\hpack{#1}%
+ \setbox\shipoutscratchbox\hpack
+ {#1}% finalizes
\ifcase\shipoutfinalizemethod
\finalizeshipoutbox\shipoutscratchbox
\fi
@@ -190,13 +199,14 @@
\fi}
\def\page_shipouts_arrange#1%
- {% \global\advance\shippedoutpages\plusone
- \begingroup
- \setbox\scratchbox\hpack
+ {\begingroup
+ \setbox\shipoutscratchbox\hpack
+ {#1}% finalizes
+ \setbox\shipoutscratchbox\hpack
{\page_otr_flush_every_stuff
\page_otr_flush_special_content
\box\shipoutscratchbox}%
- \pusharrangedpage\scratchbox
+ \pusharrangedpage\shipoutscratchbox
\deadcycles\zerocount
\endgroup}
diff --git a/tex/context/base/mkiv/page-inj.mkvi b/tex/context/base/mkiv/page-inj.mkvi
index cabd07bac..5f48ffd13 100644
--- a/tex/context/base/mkiv/page-inj.mkvi
+++ b/tex/context/base/mkiv/page-inj.mkvi
@@ -124,7 +124,7 @@
\ifx\currentpageinjectionalternative\v!none \else % increment counter but don’t generate output
\forgetparindent
\dontcomplain
- \setconstant\shipoutfinalizemethod\zerocount
+ \setconstant\shipoutfinalizemethod\zerocount % this is messy
\page_injections_flush_indeed
\fi}
diff --git a/tex/context/base/mkiv/page-lin.lua b/tex/context/base/mkiv/page-lin.lua
index a6b6a12c4..b990cb223 100644
--- a/tex/context/base/mkiv/page-lin.lua
+++ b/tex/context/base/mkiv/page-lin.lua
@@ -79,8 +79,9 @@ local getdepth = nuts.getdepth
local setprop = nuts.setprop
local getprop = nuts.getprop
-local traverse_id = nuts.traverse_id
-local traverse = nuts.traverse
+local nexthlist = nuts.traversers.hlist
+local nextvlist = nuts.traversers.vlist
+
local copy_node = nuts.copy
----- hpack_nodes = nuts.hpack
local is_display_math = nuts.is_display_math
@@ -283,7 +284,7 @@ end
local function listisnumbered(list)
if list then
- for n in traverse_id(hlist_code,list) do
+ for n in nexthlist, list do -- LUATEXVERSION >= 1.090
if getsubtype(n) == line_code then
local a = getattr(n,a_linenumber)
if a then
@@ -383,7 +384,7 @@ function boxed.stage_one(n,nested)
local skip = false
local function check()
- for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found
+ for n in nexthlist, list do -- LUATEXVERSION >= 1.090
local subtype = getsubtype(n)
if subtype ~= line_code then
-- go on
@@ -450,7 +451,7 @@ function boxed.stage_one(n,nested)
if not list then
return
end
- for n in traverse_id(vlist_code,list) do
+ for n in nextvlist, list do -- LUATEXVERSION >= 1.090
local p = properties[n]
if p and p.columngap then
if trace_numbers then
@@ -473,7 +474,7 @@ function boxed.stage_two(n,m)
if #current_list > 0 then
m = m or lines.scratchbox
local t, tn = { }, 0
- for l in traverse_id(hlist_code,getlist(getbox(m))) do
+ for l in nexthlist, getlist(getbox(m)) do -- LUATEXVERSION >= 1.090
tn = tn + 1
t[tn] = copy_node(l) -- use take_box instead
end
diff --git a/tex/context/base/mkiv/page-mix.lua b/tex/context/base/mkiv/page-mix.lua
index 107ac1410..192b8a30a 100644
--- a/tex/context/base/mkiv/page-mix.lua
+++ b/tex/context/base/mkiv/page-mix.lua
@@ -69,8 +69,6 @@ local getpenalty = nuts.getpenalty
local getwidth = nuts.getwidth
local getheight = nuts.getheight
local getdepth = nuts.getdepth
-local traverse_id = nuts.traverse_id
-local traverse = nuts.traverse
local theprop = nuts.theprop
@@ -829,23 +827,6 @@ local function report_deltas(result,str)
report_state("%s, cycles %s, deltas % | t",str,result.cycle or 1,t)
end
--- local function xxcollectinserts(h)
--- local skips, total, order = 0, 0, 0
--- print(h)
--- if h then
--- h = getlist(h)
--- for n in traverse(h) do
--- print(tonode(n))
--- end
--- for n in traverse_id(insert_code,h) do
--- order = order + 1
--- total = total + getheight(n)
--- skips = skips + structures.notes.check_spacing(getsubtype(n),order)
--- end
--- end
--- return skips, total
--- end
-
local function setsplit(specification)
splitruns = splitruns + 1
if trace_state then
diff --git a/tex/context/base/mkiv/scrn-ref.mkvi b/tex/context/base/mkiv/scrn-ref.mkvi
index bace13312..df395e550 100644
--- a/tex/context/base/mkiv/scrn-ref.mkvi
+++ b/tex/context/base/mkiv/scrn-ref.mkvi
@@ -83,15 +83,15 @@
%D delayed ...
-\def\scrn_reference_enable_references
- {\ifproductionrun
- \clf_enableinteraction % only once anyway
- \glet\scrn_reference_enable_references\relax
- \fi}
-
-\appendtoks
- \scrn_reference_enable_references
-\to \everysetupinteraction
+% \def\scrn_reference_enable_references
+% {\ifproductionrun
+% \clf_enableinteraction % only once anyway
+% \glet\scrn_reference_enable_references\relax
+% \fi}
+%
+% \appendtoks
+% \scrn_reference_enable_references
+% \to \everysetupinteraction
\setupinteraction % start fit page and reset form
[\c!openaction=,
diff --git a/tex/context/base/mkiv/scrp-cjk.lua b/tex/context/base/mkiv/scrp-cjk.lua
index b31dc335a..faef77eec 100644
--- a/tex/context/base/mkiv/scrp-cjk.lua
+++ b/tex/context/base/mkiv/scrp-cjk.lua
@@ -15,14 +15,12 @@ if not modules then modules = { } end modules ['scrp-cjk'] = {
-- line would have to be a hard coded ones.
local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local copy_node = nuts.copy
local remove_node = nuts.remove
-local traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -509,9 +507,8 @@ scripts.installmethod {
}
function scripts.decomposehangul(head)
- local head = tonut(head)
local done = false
- for current in traverse_id(glyph_code,head) do
+ for current in nextglyph, head do
local lead_consonant, medial_vowel, tail_consonant = decomposed(getchar(current))
if lead_consonant then
setchar(current,lead_consonant)
@@ -526,7 +523,7 @@ function scripts.decomposehangul(head)
done = true
end
end
- return tonode(head), done
+ return head, done
end
-- nodes.tasks.prependaction("processors","normalizers","scripts.decomposehangul")
diff --git a/tex/context/base/mkiv/scrp-ini.lua b/tex/context/base/mkiv/scrp-ini.lua
index 9bd70e30a..0eee550ac 100644
--- a/tex/context/base/mkiv/scrp-ini.lua
+++ b/tex/context/base/mkiv/scrp-ini.lua
@@ -52,8 +52,6 @@ local enableaction = nodes.tasks.enableaction
local disableaction = nodes.tasks.disableaction
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getchar = nuts.getchar
@@ -65,8 +63,11 @@ local isglyph = nuts.isglyph
local insert_node_after = nuts.insert_after
local first_glyph = nuts.first_glyph
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
+
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextglyph = nuts.traversers.glyph
+local nextchar = nuts.traversers.char
local nodepool = nuts.pool
@@ -417,7 +418,7 @@ scripts.categorytonumber = categorytonumber
scripts.numbertocategory = numbertocategory
local function colorize(start,stop)
- for n in traverse_id(glyph_code,start) do
+ for n in nextglyph, start do
local kind = numbertocategory[getattr(n,a_scriptstatus)]
if kind then
local ac = scriptcolors[kind]
@@ -450,13 +451,12 @@ end
-- we can have a fonts.hashes.originals
function scripts.injectors.handler(head)
- head = tonut(head)
local start = first_glyph(head) -- we already have glyphs here (subtype 1)
if not start then
- return tonode(head), false
+ return head
else
local last_a, normal_process, lastfont, originals = nil, nil, nil, nil
- local done, first, last, ok = false, nil, nil, false
+ local first, last, ok = nil, nil, false
while start do
local char, id = isglyph(start)
if char then
@@ -473,7 +473,7 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- ok, done = false, true
+ ok = false
end
first, last = nil, nil
end
@@ -517,7 +517,7 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- ok, done = false, true
+ ok = false
end
first, last = nil, nil
end
@@ -532,7 +532,7 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- ok, done = false, true
+ ok = false
end
first, last = nil, nil
end
@@ -554,7 +554,7 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- first, last, ok, done = nil, nil, false, true
+ first, last, ok = nil, nil, false
elseif first then
first, last = nil, nil
end
@@ -570,16 +570,15 @@ function scripts.injectors.handler(head)
else
normal_process(head,first,last)
end
- done = true
end
- return tonode(head), done
+ return head
end
end
-- kind of experimental .. might move to it's own module
-- function scripts.splitters.handler(head)
--- return head, false
+-- return head
-- end
local function addwords(tree,data)
@@ -759,9 +758,7 @@ end
local tree, attr, proc
function splitters.handler(head) -- todo: also first_glyph test
- head = tonut(head)
local current = head
- local done = false
while current do
if getid(current) == glyph_code then
local a = getattr(current,a_scriptsplitting)
@@ -792,7 +789,6 @@ function splitters.handler(head) -- todo: also first_glyph test
end
end
head, current = proc(handler,head,current,last,1)
- done = true
else
if trace_splitdetail then
-- could be punctuation
@@ -803,7 +799,6 @@ function splitters.handler(head) -- todo: also first_glyph test
end
end
head, current = proc(handler,head,current,last,2)
- done = true
end
end
end
@@ -813,7 +808,7 @@ function splitters.handler(head) -- todo: also first_glyph test
end
current = getnext(current)
end
- return tonode(head), done
+ return head
end
local function marker(head,current,font,color) -- could become: nodes.tracers.marker
@@ -907,7 +902,7 @@ setmetatableindex(cache_nop,function(t,k) local v = { } t[k] = v return v end)
-- playing nice
function autofontfeature.handler(head)
- for n in traverse_char(tonut(head)) do
+ for n in nextchar, head do
-- if getattr(n,a_scriptinjection) then
-- -- already tagged by script feature, maybe some day adapt
-- else
@@ -951,6 +946,53 @@ function autofontfeature.handler(head)
return head
end
+if LUATEXVERSION >= 1.090 then
+
+ function autofontfeature.handler(head)
+ for n, font, char in nextchar, head do
+ -- if getattr(n,a_scriptinjection) then
+ -- -- already tagged by script feature, maybe some day adapt
+ -- else
+ local script = otfscripts[char]
+ if script then
+ local dynamic = getattr(n,0) or 0
+ if dynamic > 0 then
+ local slot = cache_yes[font]
+ local attr = slot[script]
+ if not attr then
+ attr = mergecontext(dynamic,name,2)
+ slot[script] = attr
+ if trace_scripts then
+ report_scripts("script: %s, trigger %C, dynamic: %a, variant: %a",script,char,attr,"extended")
+ end
+ end
+ if attr ~= 0 then
+ n[0] = attr
+ -- maybe set scriptinjection when associated
+ end
+ else
+ local slot = cache_nop[font]
+ local attr = slot[script]
+ if not attr then
+ attr = registercontext(font,script,2)
+ slot[script] = attr
+ if trace_scripts then
+ report_scripts("script: %s, trigger %C, dynamic: %s, variant: %a",script,char,attr,"normal")
+ end
+ end
+ if attr ~= 0 then
+ setattr(n,0,attr)
+ -- maybe set scriptinjection when associated
+ end
+ end
+ end
+ -- end
+ end
+ return head
+ end
+
+end
+
function autofontfeature.enable()
report_scripts("globally enabled")
enableaction("processors","scripts.autofontfeature.handler")
diff --git a/tex/context/base/mkiv/spac-adj.lua b/tex/context/base/mkiv/spac-adj.lua
deleted file mode 100644
index 3db59881b..000000000
--- a/tex/context/base/mkiv/spac-adj.lua
+++ /dev/null
@@ -1,67 +0,0 @@
-if not modules then modules = { } end modules ['spac-adj'] = {
- version = 1.001,
- comment = "companion to spac-adj.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- sort of obsolete code
-
-local a_vadjust = attributes.private('graphicvadjust')
-
-local nodecodes = nodes.nodecodes
-
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-
-local remove_node = nodes.remove
-local hpack_node = node.hpack
-
-local enableaction = nodes.tasks.enableaction
-
-function nodes.handlers.graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only
- if groupcode == "" then -- mvl only
- local h, p, done = head, nil, false
- while h do
- local id = h.id
- if id == hlist_code or id == vlist_code then
- local a = h[a_vadjust]
- if a then
- if p then
- local n
- head, h, n = remove_node(head,h)
- local pl = p.list
- if n.width ~= 0 then
- n = hpack_node(n,0,'exactly') -- todo: dir
- end
- if pl then
- pl.prev = n
- n.next = pl
- end
- p.list = n
- done = true
- else
- -- can't happen
- end
- else
- p = h
- h = h.next
- end
- else
- h = h.next
- end
- end
- return head, done
- else
- return head, false
- end
-end
-
-interfaces.implement {
- name = "enablegraphicvadjust",
- onlyonce = true,
- actions = function()
- enableaction("finalizers","nodes.handlers.graphicvadjust")
- end
-}
diff --git a/tex/context/base/mkiv/spac-adj.mkiv b/tex/context/base/mkiv/spac-adj.mkiv
deleted file mode 100644
index d29d15c17..000000000
--- a/tex/context/base/mkiv/spac-adj.mkiv
+++ /dev/null
@@ -1,51 +0,0 @@
-%D \module
-%D [ file=spac-adj, % moved from spac-par.mkiv
-%D version=2009.10.16, % 1997.03.31, was core-spa.tex
-%D title=\CONTEXT\ Spacing Macros,
-%D subtitle=Paragraphs,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-\writestatus{loading}{ConTeXt Spacing Macros / Adjustments}
-
-\unprotect
-
-% Very nasty but needed for margin stuff inside colored
-% paragraphs. Obsolete for while .
-
-\registerctxluafile{spac-adj}{}
-
-\definesystemattribute [graphicvadjust] [public]
-
-\unexpanded\def\enablegraphicvadjust
- {\writestatus\m!system{graphicvadjusting is no longer needed!}
- \clf_enablegraphicvadjust %once anyway
- \glet\enablegraphicvadjust\relax}
-
-\unexpanded\def\graphicvadjust % currently not enabled ... nasty bidi handling
- {\clf_enablegraphicvadjust % and probably no longer needed anyway
- \dowithnextboxcontentcs\forgetall\spac_vadjust_graphic_finish\vbox}
-
-\def\spac_vadjust_graphic_finish
- {\vadjust
- {\vbox attr \graphicvadjustattribute \plusone
- {\unvbox\nextbox
- % corrects for one line paragraphs
- \nointerlineskip
- \kern-\struttotal
- \nointerlineskip
- \verticalstrut}}}
-
-\unexpanded\def\fakedvadjust
- {\dowithnextboxcs\spac_vadjust_faked_finish\vtop}
-
-\def\spac_vadjust_faked_finish
- {\setbox\nextbox\hpack{\llap{\lower\strutdepth\box\nextbox}}%
- \smashedbox\nextbox}
-
-\protect \endinput
diff --git a/tex/context/base/mkiv/spac-ali.lua b/tex/context/base/mkiv/spac-ali.lua
index 640478d34..3da0e57f4 100644
--- a/tex/context/base/mkiv/spac-ali.lua
+++ b/tex/context/base/mkiv/spac-ali.lua
@@ -63,9 +63,8 @@ local nofrealigned = 0
-- raggedright 0 0 fil
-- raggedcenter 0 + 0 + -
-local function handler(head,leftpage,realpageno)
+local function handler(head,leftpage,realpageno) -- traverse_list
local current = head
- local done = false
while current do
local id = getid(current)
if id == hlist_code then
@@ -102,7 +101,6 @@ local function handler(head,leftpage,realpageno)
elseif trace_realign then
report_realign("invalid flushing, align %a, page %a, realpage %a",align,pageno,realpageno)
end
- done = true
nofrealigned = nofrealigned + 1
end
end
@@ -113,14 +111,11 @@ local function handler(head,leftpage,realpageno)
end
current = getnext(current)
end
- return head, done
+ return head
end
function alignments.handler(head)
- local leftpage = isleftpage()
- local realpageno = texgetcount("realpageno")
- local head, done = handler(tonut(head),leftpage,realpageno)
- return tonode(head), done
+ return handler(head,isleftpage(),texgetcount("realpageno"))
end
local enabled = false
diff --git a/tex/context/base/mkiv/spac-chr.lua b/tex/context/base/mkiv/spac-chr.lua
index 0fa639f92..20b72e1b9 100644
--- a/tex/context/base/mkiv/spac-chr.lua
+++ b/tex/context/base/mkiv/spac-chr.lua
@@ -27,9 +27,6 @@ local nodes, node = nodes, node
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
local getnext = nuts.getnext
local getprev = nuts.getprev
local getattr = nuts.getattr
@@ -48,13 +45,13 @@ local setcolor = nodes.tracers.colors.set
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local remove_node = nuts.remove
-local traverse_id = nuts.traverse_id
-local traverse_char = nuts.traverse_char
+----- traverse_id = nuts.traverse_id
+----- traverse_char = nuts.traverse_char
+local nextchar = nuts.traversers.char
+local nextglyph = nuts.traversers.glyph
local copy_node = nuts.copy
-local tasks = nodes.tasks
-
local nodepool = nuts.pool
local new_penalty = nodepool.penalty
local new_glue = nodepool.glue
@@ -101,8 +98,7 @@ local function inject_quad_space(unicode,head,current,fraction)
setattrlist(glue,current)
setattrlist(current) -- why reset all
setattr(glue,a_character,unicode)
- head, current = insert_node_after(head,current,glue)
- return head, current
+ return insert_node_after(head,current,glue)
end
local function inject_char_space(unicode,head,current,parent)
@@ -112,8 +108,7 @@ local function inject_char_space(unicode,head,current,parent)
setattrlist(glue,current)
setattrlist(current) -- why reset all
setattr(glue,a_character,unicode)
- head, current = insert_node_after(head,current,glue)
- return head, current
+ return insert_node_after(head,current,glue)
end
local function inject_nobreak_space(unicode,head,current,space,spacestretch,spaceshrink)
@@ -132,8 +127,7 @@ local function inject_nobreak_space(unicode,head,current,space,spacestretch,spac
head, current = insert_node_after(head,current,kern)
head, current = insert_node_after(head,current,penalty)
end
- head, current = insert_node_after(head,current,glue)
- return head, current
+ return insert_node_after(head,current,glue)
end
local function nbsp(head,current)
@@ -152,26 +146,12 @@ end
function characters.replacenbsp(head,original)
local head, current = nbsp(head,original)
- head = remove_node(head,original,true)
- return head, current
+ return remove_node(head,original,true)
end
--- function characters.replacenbspaces(head)
--- for current in traverse_id(glyph_code,head) do
--- if getchar(current) == 0x00A0 then
--- local h = nbsp(head,current)
--- if h then
--- head = remove_node(h,current,true)
--- end
--- end
--- end
--- return head
--- end
-
function characters.replacenbspaces(head)
- local head = tonut(head)
local wipe = false
- for current in traverse_id(glyph_code,head) do -- can be anytiem so no traverse_char
+ for current in nextglyph, head do -- can be anytime so no traverse_char
if getchar(current) == 0x00A0 then
if wipe then
head = remove_node(h,current,true)
@@ -184,15 +164,40 @@ function characters.replacenbspaces(head)
end
end
if wipe then
- head = remove_node(h,current,true)
+ head = remove_node(head,current,true)
+ end
+ return head
+end
+
+if LUATEXVERSION >= 1.090 then
+
+ function characters.replacenbspaces(head)
+ local wipe = false
+ for current, font, char in nextglyph, head do -- can be anytime so no traverse_char
+ if char == 0x00A0 then
+ if wipe then
+ head = remove_node(h,current,true)
+ wipe = false
+ end
+ local h = nbsp(head,current)
+ if h then
+ wipe = current
+ end
+ end
+ end
+ if wipe then
+ head = remove_node(head,current,true)
+ end
+ return head
end
- return tonode(head)
+
end
-- This initialization might move someplace else if we need more of it. The problem is that
-- this module depends on fonts so we have an order problem.
local nbsphash = { } setmetatableindex(nbsphash,function(t,k)
+ -- this needs checking !
for i=unicodeblocks.devanagari.first,unicodeblocks.devanagari.last do nbsphash[i] = true end
for i=unicodeblocks.kannada .first,unicodeblocks.kannada .last do nbsphash[i] = true end
setmetatableindex(nbsphash,nil)
@@ -319,9 +324,7 @@ local methods = {
characters.methods = methods
-- function characters.handler(head) -- todo: use traverse_id
--- head = tonut(head)
-- local current = head
--- local done = false
-- while current do
-- local char, id = isglyph(current)
-- if char then
@@ -335,28 +338,49 @@ characters.methods = methods
-- if h then
-- head = remove_node(h,current,true)
-- end
--- done = true
-- end
-- current = next
-- else
-- current = getnext(current)
-- end
-- end
--- return tonode(head), done
+-- return head
-- end
--- for current, char, font in traverse_char_data(head) will save 0.015 on a 300 page doc
-
-- this also works ok in math as we run over glyphs and these stay glyphs ... not sure
-- about scripts and such but that is not important anyway ... some day we can consider
-- special definitions in math
function characters.handler(head)
- local head = tonut(head)
local wipe = false
- for current in traverse_char(head) do
- local char = getchar(current)
- if char then
+ for current in nextchar, head do
+ local char = getchar(current)
+ local method = methods[char]
+ if method then
+ if wipe then
+ head = remove_node(head,wipe,true)
+ wipe = false
+ end
+ if trace_characters then
+ report_characters("replacing character %C, description %a",char,lower(chardata[char].description))
+ end
+ local h = method(head,current)
+ if h then
+ wipe = current
+ end
+ end
+ end
+ if wipe then
+ head = remove_node(head,wipe,true)
+ end
+ return head
+end
+
+if LUATEXVERSION >= 1.090 then
+
+ function characters.handler(head)
+ local wipe = false
+ for current, char in nextchar, head do
local method = methods[char]
if method then
if wipe then
@@ -370,12 +394,12 @@ function characters.handler(head)
if h then
wipe = current
end
- done = true
end
end
+ if wipe then
+ head = remove_node(head,wipe,true)
+ end
+ return head
end
- if wipe then
- head = remove_node(head,wipe,true)
- end
- return tonode(head), done
+
end
diff --git a/tex/context/base/mkiv/spac-prf.lua b/tex/context/base/mkiv/spac-prf.lua
index a28f30593..f4d452cbb 100644
--- a/tex/context/base/mkiv/spac-prf.lua
+++ b/tex/context/base/mkiv/spac-prf.lua
@@ -639,7 +639,7 @@ end
local function profilelist(line,mvl)
- local current = tonut(line)
+ local current = line
local top = nil
local bot = nil
@@ -899,9 +899,8 @@ end
--
-- function profiling.vboxhandler(head,where)
-- if head and not ignore[where] then
--- local h = tonut(head)
--- if getnext(h) then
--- profilelist(h)
+-- if getnext(head) then
+-- profilelist(head)
-- end
-- end
-- return head
@@ -911,7 +910,7 @@ function profiling.pagehandler(head)
if head then
profilelist(head,true)
end
- return head, true
+ return head
end
interfaces.implement {
diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua
index 8f2136f95..05055ef63 100644
--- a/tex/context/base/mkiv/spac-ver.lua
+++ b/tex/context/base/mkiv/spac-ver.lua
@@ -116,7 +116,6 @@ local a_snapmethod = attributes.private('snapmethod')
local a_snapvbox = attributes.private('snapvbox')
local nuts = nodes.nuts
-local tonode = nuts.tonode
local tonut = nuts.tonut
local getnext = nuts.getnext
@@ -147,15 +146,16 @@ local getdepth = nuts.getdepth
local find_node_tail = nuts.tail
local flush_node = nuts.flush_node
-local traverse_nodes = nuts.traverse
-local traverse_nodes_id = nuts.traverse_id
local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
local remove_node = nuts.remove
local count_nodes = nuts.countall
local hpack_node = nuts.hpack
local vpack_node = nuts.vpack
------ writable_spec = nuts.writable_spec
+
+local nextnode = nuts.traversers.node
+local nexthlist = nuts.traversers.hlist
+
local nodereference = nuts.reference
local theprop = nuts.theprop
@@ -290,7 +290,7 @@ local function validvbox(parentid,list)
end
end
local done = nil
- for n, id in traverse_nodes(list) do
+ for n, id in nextnode, list do
if id == vlist_code or id == hlist_code then
if done then
return nil
@@ -325,7 +325,7 @@ local function already_done(parentid,list,a_snapmethod) -- todo: done when only
return false
end
end
- for n, id in traverse_nodes(list) do
+ for n, id in nextnode, list do
if id == hlist_code or id == vlist_code then
-- local a = getattr(n,a_snapmethod)
-- if not a then
@@ -534,7 +534,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut]
if thebox and id == vlist_code then
local list = getlist(thebox)
local lw, lh, ld
- for n in traverse_nodes_id(hlist_code,list) do
+ for n in nexthlist, list do
lw, lh, ld = getwhd(n)
break
end
@@ -570,7 +570,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut]
if thebox and id == vlist_code then
local list = getlist(thebox)
local lw, lh, ld
- for n in traverse_nodes_id(hlist_code,list) do
+ for n in nexthlist, list do
lw, lh, ld = getwhd(n)
end
if lh then
@@ -1879,7 +1879,7 @@ do
trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)])
end
end
- return head, true
+ return head
end
-- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display
@@ -1910,29 +1910,25 @@ do
function vspacing.pagehandler(newhead,where)
-- local newhead = texlists.contrib_head
if newhead then
- newhead = tonut(newhead)
local newtail = find_node_tail(newhead) -- best pass that tail, known anyway
local flush = false
stackhack = true -- todo: only when grid snapping once enabled
-- todo: fast check if head = tail
- for n, id in traverse_nodes(newhead) do -- we could just look for glue nodes
+ for n, id, subtype in nextnode, newhead do -- we could just look for glue nodes
if id ~= glue_code then
flush = true
- else
- local subtype = getsubtype(n)
- if subtype == userskip_code then
- if getattr(n,a_skipcategory) then
- stackhack = true
- else
- flush = true
- end
- elseif subtype == parskip_code then
- -- if where == new_graf then ... end
- if texgetcount("c_spac_vspacing_ignore_parskip") > 0 then
--- texsetcount("c_spac_vspacing_ignore_parskip",0)
- setglue(n)
- -- maybe removenode
- end
+ elseif subtype == userskip_code then
+ if getattr(n,a_skipcategory) then
+ stackhack = true
+ else
+ flush = true
+ end
+ elseif subtype == parskip_code then
+ -- if where == new_graf then ... end
+ if texgetcount("c_spac_vspacing_ignore_parskip") > 0 then
+ -- texsetcount("c_spac_vspacing_ignore_parskip",0)
+ setglue(n)
+ -- maybe removenode
end
end
end
@@ -1953,7 +1949,7 @@ do
if trace_collect_vspacing then report("%s > flushing %s nodes: %s",where,newhead) end
-- texlists.contrib_head = newhead
end
- return tonode(newhead)
+ return newhead
else
if stackhead then
if trace_collect_vspacing then report("%s > appending %s nodes to stack (intermediate): %s",where,newhead) end
@@ -1977,11 +1973,10 @@ do
}
function vspacing.vboxhandler(head,where)
- if head and not ignore[where] then
- local h = tonut(head)
- if getnext(h) then -- what if a one liner and snapping?
- h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper
- return tonode(h)
+ if head and not ignore[where] and getnext(head) then
+ if getnext(head) then -- what if a one liner and snapping?
+ head = collapser(head,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper
+ return head
end
end
return head
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index c8ca9b98e..d2e9b687d 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 16940503b..6cf05d9b4 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-mar.lua b/tex/context/base/mkiv/strc-mar.lua
index a2cbc2ab2..bb79ac7a9 100644
--- a/tex/context/base/mkiv/strc-mar.lua
+++ b/tex/context/base/mkiv/strc-mar.lua
@@ -29,14 +29,17 @@ local getlist = nuts.getlist
local getattr = nuts.getattr
local getbox = nuts.getbox
-local traverse = nuts.traverse
-local traverse_id = nuts.traverse_id
+local nextnode = nuts.traversers.node
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
+local whatsit_code = nodecodes.whatsit
+local whatsitcodes = nodes.whatsitcodes
+local latelua_code = whatsitcodes.latelua
+
local texsetattribute = tex.setattribute
local a_marks = attributes.private("structure","marks")
@@ -116,8 +119,9 @@ end
-- identify range
local function sweep(head,first,last)
- for n, id in traverse(head) do
- if id == glyph_code then
+ for n, id, subtype in nextnode, head do
+ -- we need to handle empty heads so we test for latelua
+ if id == glyph_code or (id == whatsit_code and subtype == latelua_code) then
local a = getattr(n,a_marks)
if not a then
-- next
diff --git a/tex/context/base/mkiv/strc-reg.mkiv b/tex/context/base/mkiv/strc-reg.mkiv
index 04fdef9ad..81acb1cf3 100644
--- a/tex/context/base/mkiv/strc-reg.mkiv
+++ b/tex/context/base/mkiv/strc-reg.mkiv
@@ -835,10 +835,12 @@
\unexpanded\def\startregisterpages
{\begingroup
\dostarttagged\t!registerpages\empty
- \useregisterstyleandcolor\c!pagestyle\c!pagecolor}
+ \useregisterstyleandcolor\c!pagestyle\c!pagecolor
+ \registerparameter\c!pageleft}
\unexpanded\def\stopregisterpages
- {\dostoptagged
+ {\registerparameter\c!pageright
+ \dostoptagged
\endgroup}
\unexpanded\def\startregisterseewords
diff --git a/tex/context/base/mkiv/strc-ren.mkiv b/tex/context/base/mkiv/strc-ren.mkiv
index 89aa6f55a..9db2f23e9 100644
--- a/tex/context/base/mkiv/strc-ren.mkiv
+++ b/tex/context/base/mkiv/strc-ren.mkiv
@@ -151,7 +151,7 @@
\strc_rendering_stop_placement}
\unexpanded\def\strc_rendering_place_head_empty
- {\hbox\headreferenceattributes{\getheadsyncs}} % \hpack ?
+ {\hpack\headreferenceattributes{\getheadsyncs}}
%D \starttyping
%D \def\StretchedBox#1%
@@ -345,14 +345,14 @@
\nointerlineskip
\dosomebreak\nobreak
\fi
- \getheadsyncs
+ \getheadsyncs % a latelua, why not in the box
\else
% somehow this goes ok even when we push in the margin probably because we gobble pars
% in the process of collecting index entries etc
\strut
\flushnotes % new, here since we're in par mode
\unhbox\b_strc_rendering_head
- \getheadsyncs
+ \getheadsyncs % a latelua
\ifconditional\headissomewhere
\strc_sectioning_stay_on_this_line % test case: alternative=margintext and \startparagraph ..
\else
diff --git a/tex/context/base/mkiv/strc-sec.mkiv b/tex/context/base/mkiv/strc-sec.mkiv
index 4e5115a7d..b3e7e46f5 100644
--- a/tex/context/base/mkiv/strc-sec.mkiv
+++ b/tex/context/base/mkiv/strc-sec.mkiv
@@ -249,7 +249,7 @@
userdata {\detokenize{#3}}% will be converted to table at the lua end
\relax
\xdef\currentstructurelistnumber{\clf_currentsectiontolist}%
- % \currentstructuresynchronize has to be called someplace, since it introduces a node
+ % \currentstructuresynchronize has to be called someplace, since it introduces a node
\setstructuresynchronization\currentstructurelistnumber
\endgroup}
@@ -755,6 +755,9 @@
\setfalse\headshownumber
\fi}
+% Beware, we do need some node for anchoring marks and normally a zwnj will
+% do but it interferes so we deal with it at the \LUA\ end.
+
\newtoks\everyheadsynchronization
\appendtoks
@@ -762,8 +765,8 @@
\to \everyheadsynchronization
\unexpanded\def\theheadsynchonization
- {\the\everyheadsynchronization
- \currentstructuresynchronize}
+ {% no, interferes: \signalcharacter
+ \the\everyheadsynchronization}
% BEWARE: \marking[section]{my text} does not work as we use list indices instead
% so we need a 'keep track of raw set option' (or maybe a funny internal prefix)
@@ -983,8 +986,8 @@
\unexpanded\def\strc_rendering_place_head_section % see hidden below
{\global\setbox\b_sectioning_delayed\hpack\bgroup
\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
- \hpack\headreferenceattributes{}%
- \currentstructuresynchronize
+ \hpack\headreferenceattributes{}% also does the mark
+ \theheadsynchonization
\egroup}
\unexpanded\def\strc_rendering_place_head_hidden % maybe trialtypesetting check
@@ -994,7 +997,7 @@
{\noexpand\letgvalue{\??hiddenheadsync\currenthead}\relax
\noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}%
\hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference
- \currentstructuresynchronize}} % and it's a node anyway
+ \theheadsynchonization}} % and it's a node anyway
\def\synchronizehead #1{\csname\??hiddenheadsync#1\endcsname}
\def\theheadreferenceattributes#1{\csname\??hiddenheadattr#1\endcsname}
diff --git a/tex/context/base/mkiv/supp-box.lua b/tex/context/base/mkiv/supp-box.lua
index 3ea16dcf8..dc680cda0 100644
--- a/tex/context/base/mkiv/supp-box.lua
+++ b/tex/context/base/mkiv/supp-box.lua
@@ -62,10 +62,12 @@ local flush_list = nuts.flush_list
local copy_node = nuts.copy
local copy_list = nuts.copy_list
local find_tail = nuts.tail
-local traverse_id = nuts.traverse_id
local list_dimensions = nuts.dimensions
local hpack = nuts.hpack
+local nextdisc = nuts.traversers.disc
+local nexthlist = nuts.traversers.hlist
+
local listtoutf = nodes.listtoutf
local nodepool = nuts.pool
@@ -128,7 +130,7 @@ implement {
-- local function hyphenatedhack(head,pre)
-- pre = tonut(pre)
--- for n in traverse_id(disc_code,tonut(head)) do
+-- for n in nextdisc, tonut(head) do
-- local hyphen = getfield(n,"pre")
-- if hyphen then
-- flush_list(hyphen)
@@ -422,7 +424,7 @@ local function firstdirinbox(n)
if b then
local l = getlist(b)
if l then
- for h in traverse_id(hlist_code,l) do
+ for h in nexthlist, l do
return getdir(h)
end
end
diff --git a/tex/context/base/mkiv/syst-aux.mkiv b/tex/context/base/mkiv/syst-aux.mkiv
index ee5761af0..1b56cbd7c 100644
--- a/tex/context/base/mkiv/syst-aux.mkiv
+++ b/tex/context/base/mkiv/syst-aux.mkiv
@@ -345,6 +345,18 @@
\let\doifnextoptionalelse \doifelsenextoptional
\let\doifnextoptionalcselse\doifelsenextoptionalcs
+% fails on assignments
+%
+% \unexpanded\def\doifelsenextoptional {\afterassignment\doifelsenextoptional_n \def\m_syst_action_yes}
+% \def\doifelsenextoptional_n {\afterassignment\doifelsenextoptional_n_n\def\m_syst_action_nop}
+% \def\doifelsenextoptional_n_n {\let\if_next_blank_space_token\iffalse
+% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
+%
+% \unexpanded\def\doifelsenextoptionalcs {\afterassignment\doifelsenextoptionalcs_n \let\m_syst_action_yes}
+% \def\doifelsenextoptionalcs_n {\afterassignment\doifelsenextoptionalcs_n_n\let\m_syst_action_nop}
+% \def\doifelsenextoptionalcs_n_n{\let\if_next_blank_space_token\iffalse
+% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character}
+
\def\syst_helpers_inspect_next_optional_character
{\ifx\nexttoken\blankspace
\expandafter\syst_helpers_reinspect_next_optional_character
@@ -728,6 +740,23 @@
\expandafter\secondoftwoarguments
\fi}
+%D Slightly faster on longer arguments (0.179 downto 0.141):
+%D
+%D \testfeatureonce{100000}{\doifelse{aaaaaaaaaaaaaaa}{bbbbbbbbbbbbbbb}\relax\relax}
+
+% \unexpanded\def\doifelse
+% {\afterassignment\doifelse_n\edef\m_syst_string_one}
+%
+% \unexpanded\def\doifelse_n
+% {\afterassignment\doifelse_n_n\edef\m_syst_string_two}
+%
+% \unexpanded\def\doifelse_n_n
+% {\ifx\m_syst_string_one\m_syst_string_two
+% \expandafter\firstoftwoarguments
+% \else
+% \expandafter\secondoftwoarguments
+% \fi}
+
%D \macros
%D {doifempty,doifemptyelse,doifnotempty}
%D
diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv
index 181ec05be..ee8663293 100644
--- a/tex/context/base/mkiv/syst-ini.mkiv
+++ b/tex/context/base/mkiv/syst-ini.mkiv
@@ -214,13 +214,13 @@
\countdef \c_syst_max_allocated_read = 55 \c_syst_max_allocated_read = 16
\countdef \c_syst_min_allocated_language = 56 \c_syst_min_allocated_language = 0
\countdef \c_syst_max_allocated_language = 57 \c_syst_max_allocated_language = 255
-\countdef \c_syst_max_allocated_insert = 58 \c_syst_max_allocated_insert = 254
-\countdef \c_syst_min_allocated_insert = 59 \c_syst_min_allocated_insert = 128
+\countdef \c_syst_min_allocated_insert = 58 \c_syst_min_allocated_insert = 128
+\countdef \c_syst_max_allocated_insert = 59 \c_syst_max_allocated_insert = 254
\countdef \c_syst_min_allocated_family = 60 \c_syst_min_allocated_family = 128
\countdef \c_syst_max_allocated_family = 61 \c_syst_max_allocated_family = 255
-\countdef \c_syst_min_allocated_attribute = 62 \c_syst_min_allocated_attribute = 1024 % 127-1023 : private
-\countdef \c_syst_min_allocated_write = 63 \c_syst_min_allocated_write = 0 % luatex >= 0.82
-\countdef \c_syst_max_allocated_write = 64 \c_syst_max_allocated_write = 127 % luatex >= 0.82
+\countdef \c_syst_min_allocated_attribute = 62 \c_syst_min_allocated_attribute = 1024 % 0-1023 : private
+\countdef \c_syst_min_allocated_write = 63 \c_syst_min_allocated_write = 0
+\countdef \c_syst_max_allocated_write = 64 \c_syst_max_allocated_write = 127
\countdef \c_syst_last_allocated_count = 32 \c_syst_last_allocated_count = \c_syst_min_allocated_register
\countdef \c_syst_last_allocated_dimen = 33 \c_syst_last_allocated_dimen = \c_syst_min_allocated_register
diff --git a/tex/context/base/mkiv/syst-lua.mkiv b/tex/context/base/mkiv/syst-lua.mkiv
index ca5f9679f..3600dac34 100644
--- a/tex/context/base/mkiv/syst-lua.mkiv
+++ b/tex/context/base/mkiv/syst-lua.mkiv
@@ -19,6 +19,42 @@
\def\expdoif #1#2{\clf_doifsame {#1}{#2}}
\def\expdoifnot #1#2{\clf_doifnotsame {#1}{#2}}
+%D Here is variant using a brainwave of the 12\high{+} hour \quotation {Long Road
+%D Out of Eden}\footnote {Eden being Backo\TeX\ 2018, where the virtues of the \type
+%D {\expanded} primitive were mentioned in talks.} trip. For now I don't really see
+%D other useful applications.
+
+\ifdefined\immediateassignment
+
+ \def\expandeddoif#1#2%
+ {\immediateassignment\edef\m_syst_string_one{#1}%
+ \immediateassignment\edef\m_syst_string_two{#2}%
+ \ifx\m_syst_string_one\m_syst_string_two
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+ \def\expandeddoifnot#1#2%
+ {\immediateassignment\edef\m_syst_string_one{#1}%
+ \immediateassignment\edef\m_syst_string_two{#2}%
+ \ifx\m_syst_string_one\m_syst_string_two
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+ \def\expandeddoifelse#1#2%
+ {\immediateassignment\edef\m_syst_string_one{#1}%
+ \immediateassignment\edef\m_syst_string_two{#2}%
+ \ifx\m_syst_string_one\m_syst_string_two
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\fi
+
% \testfeatureonce{100000}{\doifelse{hello world}{here i am}{}} % 0.3
% \testfeatureonce{100000}{\expandabledoifelse{hello world}{here i am}{}} % 1.5
diff --git a/tex/context/base/mkiv/tabl-tbl.mkiv b/tex/context/base/mkiv/tabl-tbl.mkiv
index f80813eef..ff2c0f4e5 100644
--- a/tex/context/base/mkiv/tabl-tbl.mkiv
+++ b/tex/context/base/mkiv/tabl-tbl.mkiv
@@ -622,18 +622,18 @@
\tabl_tabulate_set_preamble}
\def\tabl_tabulate_set_preskip#1%
- {\doifelsenumber{#1}
- {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }
+ {\doifelsenumber{#1}%
+ {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }%
{\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}}
\def\tabl_tabulate_set_posskip#1%
- {\doifelsenumber{#1}
- {\s_tabl_tabulate_post#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }
+ {\doifelsenumber{#1}%
+ {\s_tabl_tabulate_post#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }%
{\s_tabl_tabulate_post.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}}
\def\tabl_tabulate_set_preposskip#1%
- {\doifelsenumber{#1}
- {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble }
+ {\doifelsenumber{#1}%
+ {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble }%
{\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble#1}}
\def\tabl_tabulate_set_setups#1%
@@ -1293,7 +1293,7 @@
\fi\fi}
\def\tabl_tabulate_outside_after_indeed
- {\tabulationparameter\c!after}%
+ {\tabulationparameter\c!after}
\def\tabl_tabulate_outside_inbetween_indeed
{\doifempty{\tabulationparameter\c!after}
diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua
index 27d997584..29ae69eb1 100644
--- a/tex/context/base/mkiv/task-ini.lua
+++ b/tex/context/base/mkiv/task-ini.lua
@@ -18,226 +18,130 @@ if not modules then modules = { } end modules ['task-ini'] = {
-- not apply the font handler, we can remove all checks for subtypes 255
local tasks = nodes.tasks
-local prependaction = tasks.prependaction
local appendaction = tasks.appendaction
local disableaction = tasks.disableaction
local enableaction = tasks.enableaction
local freezegroup = tasks.freezegroup
local freezecallbacks = callbacks.freeze
-appendaction("processors", "normalizers", "languages.replacements.handler") -- disabled
-
-appendaction("processors", "normalizers", "typesetters.wrappers.handler") -- disabled
-appendaction("processors", "normalizers", "typesetters.characters.handler") -- always on
-appendaction("processors", "normalizers", "fonts.collections.process") -- disabled
-appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled
-
-appendaction("processors", "characters", "scripts.autofontfeature.handler")
-appendaction("processors", "characters", "scripts.splitters.handler") -- disabled
-appendaction("processors", "characters", "typesetters.cleaners.handler") -- disabled
-appendaction("processors", "characters", "typesetters.directions.handler") -- disabled
-appendaction("processors", "characters", "typesetters.cases.handler") -- disabled
-appendaction("processors", "characters", "typesetters.breakpoints.handler") -- disabled
-appendaction("processors", "characters", "scripts.injectors.handler") -- disabled
-
-------------("processors", "words", "languages.replacements.handler") -- disabled
-appendaction("processors", "words", "languages.words.check") -- disabled -- might move up, no disc check needed then
-appendaction("processors", "words", "languages.hyphenators.handler") -- always on
-appendaction("processors", "words", "typesetters.initials.handler") -- disabled -- might move up
-appendaction("processors", "words", "typesetters.firstlines.handler") -- disabled
-
-appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split") -- experimental
-appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo
-appendaction("processors", "fonts", "nodes.injections.handler")
-appendaction("processors", "fonts", "typesetters.fontkerns.handler")
-appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nohead") -- maybe todo
-appendaction("processors", "fonts", "builders.kernel.ligaturing") -- not always on (could be selective: if only node mode)
-appendaction("processors", "fonts", "builders.kernel.kerning") -- not always on (could be selective: if only node mode)
-appendaction("processors", "fonts", "nodes.handlers.stripping") -- disabled (might move)
-------------("processors", "fonts", "typesetters.italics.handler") -- disabled (after otf/kern handling)
-appendaction("processors", "fonts", "nodes.handlers.flatten")
-
-appendaction("processors", "lists", "typesetters.rubies.check") -- disabled (maybe someplace else)
-appendaction("processors", "lists", "typesetters.characteralign.handler") -- disabled (we need to to this after otf appliance)
-appendaction("processors", "lists", "typesetters.spacings.handler") -- disabled
-appendaction("processors", "lists", "typesetters.kerns.handler") -- disabled
-appendaction("processors", "lists", "typesetters.digits.handler") -- disabled (after otf handling)
-appendaction("processors", "lists", "typesetters.italics.handler") -- disabled (after otf/kern handling)
-appendaction("processors", "lists", "languages.visualizediscretionaries") -- disabled
-
-appendaction("processors", "after", "typesetters.marksuspects")
-
-appendaction("shipouts", "normalizers", "typesetters.showsuspects")
-appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler") -- disabled
-------------("shipouts", "normalizers", "nodes.handlers.cleanuppage") -- disabled
-appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace") -- disabled
-appendaction("shipouts", "normalizers", "typesetters.alignments.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.references.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.destinations.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.rules.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.shifts.handler") -- disabled
-appendaction("shipouts", "normalizers", "structures.tags.handler") -- disabled
-appendaction("shipouts", "normalizers", "nodes.handlers.accessibility") -- disabled
-appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds") -- disabled
-------------("shipouts", "normalizers", "nodes.handlers.export") -- disabled
-appendaction("shipouts", "normalizers", "typesetters.rubies.attach") -- disabled
-
-appendaction("shipouts", "finishers", "nodes.visualizers.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.colors.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.transparencies.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.colorintents.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.negatives.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.effects.handler") -- disabled
-appendaction("shipouts", "finishers", "attributes.viewerlayers.handler") -- disabled
-
---maybe integrate relocate and families
-
-appendaction("math", "normalizers", "noads.handlers.showtree", nil, "nohead")
-
-appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nohead") -- always on (maybe disabled)
-appendaction("math", "normalizers", "noads.handlers.variants", nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.families", nil, "nohead") -- always on
-
-appendaction("math", "normalizers", "noads.handlers.render", nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.fixscripts",nil, "nohead") -- * first-- always on
-appendaction("math", "normalizers", "noads.handlers.domains", nil, "nohead") -- * last -- disabled
-appendaction("math", "normalizers", "noads.handlers.autofences",nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.resize", nil, "nohead") -- always on
-------------("math", "normalizers", "noads.handlers.respace", nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.alternates",nil, "nohead") -- always on
-appendaction("math", "normalizers", "noads.handlers.tags", nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.italics", nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.kernpairs", nil, "nohead") -- disabled
-appendaction("math", "normalizers", "noads.handlers.classes", nil, "nohead") -- disabled
-
-appendaction("math", "builders", "builders.kernel.mlist_to_hlist") -- always on
-------------("math", "builders", "noads.handlers.italics", nil, "nohead") -- disabled
-appendaction("math", "builders", "typesetters.directions.processmath") -- disabled (has to happen pretty late)
-appendaction("math", "builders", "noads.handlers.makeup", nil, "nohead") -- disabled (has to happen last)
-appendaction("math", "builders", "noads.handlers.align", nil, "nohead")
-
-appendaction("finalizers", "lists", "typesetters.paragraphs.normalize") -- moved here
-appendaction("finalizers", "lists", "typesetters.margins.localhandler") -- disabled
-appendaction("finalizers", "lists", "builders.paragraphs.keeptogether")
-------------("finalizers", "lists", "nodes.handlers.graphicvadjust") -- todo
-appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize") -- experimental
-appendaction("finalizers", "lists", "builders.paragraphs.tag")
-
--- the next can also be in contributers normalizers (when we remove the loop in the handler)
-
-appendaction("finalizers", "lists", "nodes.linefillers.handler")
-
-appendaction("contributers", "normalizers", "nodes.handlers.flattenline")
-appendaction("contributers", "normalizers", "nodes.handlers.textbackgrounds")
-
-appendaction("vboxbuilders", "normalizers", "nodes.handlers.backgroundsvbox")
-appendaction("mvlbuilders", "normalizers", "nodes.handlers.backgroundspage")
-
-appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler") -- disabled
-appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate")
-
-appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler") -- last !
-appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler") -- here !
-
-------------("vboxbuilders", "normalizers", "typesetters.margins.localhandler")
-appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler")
-appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler") -- here !
-
--- experimental too
-
-appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler")
-appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler")
-
--- rather special (this might get hardcoded):
-
-prependaction("processors", "before", "nodes.properties.attach") -- enabled but optimized for quick abort
-appendaction ("shipouts", "normalizers", "nodes.properties.delayed") -- enabled but optimized for quick abort
-
--- speedup: only kick in when used
-
-disableaction("processors", "typesetters.wrappers.handler")
-disableaction("processors", "languages.replacements.handler")
-disableaction("processors", "typesetters.characteralign.handler")
-disableaction("processors", "scripts.autofontfeature.handler")
-disableaction("processors", "scripts.splitters.handler")
-disableaction("processors", "scripts.injectors.handler") -- was enabled
-disableaction("processors", "fonts.collections.process")
-disableaction("processors", "fonts.checkers.missing")
-disableaction("processors", "chars.handle_breakpoints")
-disableaction("processors", "typesetters.cleaners.handler")
-disableaction("processors", "typesetters.cases.handler")
-disableaction("processors", "typesetters.digits.handler")
-disableaction("processors", "typesetters.breakpoints.handler")
-disableaction("processors", "typesetters.directions.handler")
-disableaction("processors", "languages.words.check")
-disableaction("processors", "typesetters.initials.handler")
-disableaction("processors", "typesetters.firstlines.handler")
-disableaction("processors", "typesetters.spacings.handler")
-disableaction("processors", "typesetters.kerns.handler")
-disableaction("processors", "typesetters.italics.handler")
-disableaction("processors", "languages.visualizediscretionaries")
-disableaction("processors", "nodes.handlers.stripping")
-disableaction("processors", "builders.paragraphs.solutions.splitters.split")
-disableaction("processors", "typesetters.rubies.check")
-disableaction("processors", "typesetters.fontkerns.handler")
-disableaction("processors", "nodes.handlers.flatten")
-disableaction("processors", "typesetters.marksuspects")
-
-disableaction("shipouts", "typesetters.showsuspects")
-disableaction("shipouts", "typesetters.margins.finalhandler")
-disableaction("shipouts", "builders.paragraphs.expansion.trace")
-disableaction("shipouts", "typesetters.alignments.handler")
-disableaction("shipouts", "nodes.rules.handler")
-disableaction("shipouts", "nodes.shifts.handler")
-disableaction("shipouts", "attributes.colors.handler")
-disableaction("shipouts", "attributes.transparencies.handler")
-disableaction("shipouts", "attributes.colorintents.handler")
-disableaction("shipouts", "attributes.effects.handler")
-disableaction("shipouts", "attributes.negatives.handler")
-disableaction("shipouts", "attributes.viewerlayers.handler")
-disableaction("shipouts", "structures.tags.handler")
-disableaction("shipouts", "nodes.visualizers.handler")
-disableaction("shipouts", "nodes.handlers.accessibility")
-disableaction("shipouts", "nodes.references.handler")
-disableaction("shipouts", "nodes.destinations.handler")
-disableaction("shipouts", "nodes.handlers.backgrounds")
--------------("shipouts", "nodes.handlers.export")
-disableaction("shipouts", "typesetters.rubies.attach")
-
-disableaction("finalizers", "typesetters.margins.localhandler")
-disableaction("finalizers", "builders.paragraphs.keeptogether")
-disableaction("finalizers", "builders.paragraphs.solutions.splitters.optimize")
--------------("finalizers", "nodes.handlers.graphicvadjust") -- sort of obsolete
-disableaction("finalizers", "builders.paragraphs.tag")
-disableaction("finalizers", "nodes.linefillers.handler")
-
-disableaction("contributers","nodes.handlers.flattenline")
-disableaction("contributers","nodes.handlers.textbackgrounds")
-
-disableaction("vboxbuilders","nodes.handlers.backgroundsvbox")
-disableaction("mvlbuilders", "nodes.handlers.backgroundspage")
-
-disableaction("math", "noads.handlers.showtree")
-disableaction("math", "noads.handlers.tags")
-disableaction("math", "noads.handlers.italics")
-disableaction("math", "noads.handlers.collapse")
-disableaction("math", "noads.handlers.kernpairs")
-disableaction("math", "noads.handlers.domains")
-disableaction("math", "noads.handlers.classes")
-disableaction("math", "noads.handlers.autofences")
-disableaction("math", "noads.handlers.makeup")
-disableaction("math", "typesetters.directions.processmath")
-
-disableaction("mvlbuilders", "typesetters.margins.globalhandler")
-disableaction("mvlbuilders", "nodes.handlers.migrate")
-disableaction("mvlbuilders", "typesetters.checkers.handler")
-disableaction("mvlbuilders", "builders.profiling.pagehandler")
-
--------------("vboxbuilders","typesetters.margins.localhandler")
-disableaction("vboxbuilders","typesetters.checkers.handler")
-disableaction("vboxbuilders","builders.profiling.vboxhandler")
+appendaction("processors", "before", "nodes.properties.attach", nil, "nut", "enabled" )
+
+appendaction("processors", "normalizers", "typesetters.periodkerns.handler", nil, "nut", "disabled" )
+appendaction("processors", "normalizers", "languages.replacements.handler", nil, "nut", "disabled" )
+appendaction("processors", "normalizers", "typesetters.wrappers.handler", nil, "nut", "disabled" )
+appendaction("processors", "normalizers", "typesetters.characters.handler", nil, "nut", "enabled" )
+appendaction("processors", "normalizers", "fonts.collections.process", nil, "nut", "disabled" )
+appendaction("processors", "normalizers", "fonts.checkers.missing", nil, "nut", "disabled" )
+
+appendaction("processors", "characters", "scripts.autofontfeature.handler", nil, "nut", "disabled" )
+appendaction("processors", "characters", "scripts.splitters.handler", nil, "nut", "disabled" )
+appendaction("processors", "characters", "typesetters.cleaners.handler", nil, "nut", "disabled" )
+appendaction("processors", "characters", "typesetters.directions.handler", nil, "nut", "disabled" )
+appendaction("processors", "characters", "typesetters.cases.handler", nil, "nut", "disabled" )
+appendaction("processors", "characters", "typesetters.breakpoints.handler", nil, "nut", "disabled" )
+appendaction("processors", "characters", "scripts.injectors.handler", nil, "nut", "disabled" )
+
+appendaction("processors", "words", "languages.words.check", nil, "nut", "disabled" )
+appendaction("processors", "words", "languages.hyphenators.handler", nil, "nut", "enabled" )
+appendaction("processors", "words", "typesetters.initials.handler", nil, "nut", "disabled" )
+appendaction("processors", "words", "typesetters.firstlines.handler", nil, "nut", "disabled" )
+
+appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split", nil, "nut", "disabled" )
+appendaction("processors", "fonts", "nodes.handlers.characters", nil, "nut", "enabled" )
+appendaction("processors", "fonts", "nodes.injections.handler", nil, "nut", "enabled" )
+appendaction("processors", "fonts", "typesetters.fontkerns.handler", nil, "nut", "disabled" )
+appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nonut", "enabled" )
+appendaction("processors", "fonts", "builders.kernel.ligaturing", nil, "nut", "disabled" )
+appendaction("processors", "fonts", "builders.kernel.kerning", nil, "nut", "disabled" )
+appendaction("processors", "fonts", "nodes.handlers.stripping", nil, "nut", "disabled" )
+appendaction("processors", "fonts", "nodes.handlers.flatten", nil, "nut", "disabled" )
+appendaction("processors", "fonts", "fonts.goodies.colorschemes.coloring", nil, "nut", "disabled" )
+
+appendaction("processors", "lists", "typesetters.rubies.check", nil, "nut", "disabled" )
+appendaction("processors", "lists", "typesetters.characteralign.handler", nil, "nut", "disabled" )
+appendaction("processors", "lists", "typesetters.spacings.handler", nil, "nut", "disabled" )
+appendaction("processors", "lists", "typesetters.kerns.handler", nil, "nut", "disabled" )
+appendaction("processors", "lists", "typesetters.digits.handler", nil, "nut", "disabled" )
+appendaction("processors", "lists", "typesetters.italics.handler", nil, "nut", "disabled" )
+appendaction("processors", "lists", "languages.visualizediscretionaries", nil, "nut", "disabled" )
+
+appendaction("processors", "after", "typesetters.marksuspects", nil, "nut", "disabled" )
+
+appendaction("shipouts", "normalizers", "typesetters.showsuspects", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler", nil, "nut", "disabled" )
+------------("shipouts", "normalizers", "nodes.handlers.cleanuppage", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "typesetters.alignments.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "nodes.references.handler", nil, "nut", "production")
+appendaction("shipouts", "normalizers", "nodes.destinations.handler", nil, "nut", "production")
+appendaction("shipouts", "normalizers", "nodes.rules.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "nodes.shifts.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "structures.tags.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "nodes.handlers.accessibility", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "typesetters.rubies.attach", nil, "nut", "disabled" )
+appendaction("shipouts", "normalizers", "nodes.properties.delayed", nil, "nut", "production")
+appendaction("shipouts", "normalizers", "backends.pdf.nodeinjections.finalizepage", nil, "nut", "production")
+
+appendaction("shipouts", "finishers", "nodes.visualizers.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "finishers", "attributes.colors.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "finishers", "attributes.transparencies.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "finishers", "attributes.colorintents.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "finishers", "attributes.negatives.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "finishers", "attributes.effects.handler", nil, "nut", "disabled" )
+appendaction("shipouts", "finishers", "attributes.viewerlayers.handler", nil, "nut", "disabled" )
+
+appendaction("shipouts", "wrapup", "nodes.handlers.export", nil, "nut", "disabled" ) -- always last
+appendaction("shipouts", "wrapup", "luatex.synctex.collect", nil, "nut", "disabled" )
+
+
+appendaction("math", "normalizers", "noads.handlers.showtree", nil, "nonut", "disabled" )
+appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.variants", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.families", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.render", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nonut", "disabled" )
+appendaction("math", "normalizers", "noads.handlers.fixscripts", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.domains", nil, "nonut", "disabled" )
+appendaction("math", "normalizers", "noads.handlers.autofences", nil, "nonut", "disabled" )
+appendaction("math", "normalizers", "noads.handlers.resize", nil, "nonut", "enabled" )
+------------("math", "normalizers", "noads.handlers.respace", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.alternates", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.tags", nil, "nonut", "disabled" )
+appendaction("math", "normalizers", "noads.handlers.italics", nil, "nonut", "disabled" )
+appendaction("math", "normalizers", "noads.handlers.kernpairs", nil, "nonut", "disabled" )
+appendaction("math", "normalizers", "noads.handlers.classes", nil, "nonut", "disabled" )
+
+appendaction("math", "builders", "builders.kernel.mlist_to_hlist", nil, "node", "enabled" ) -- mandate
+appendaction("math", "builders", "typesetters.directions.processmath", nil, "nut", "disabled" )
+appendaction("math", "builders", "noads.handlers.makeup", nil, "nonut", "disabled" )
+appendaction("math", "builders", "noads.handlers.align", nil, "nonut", "enabled" )
+
+appendaction("finalizers", "lists", "typesetters.paragraphs.normalize", nil, "nut", "disabled" )
+appendaction("finalizers", "lists", "typesetters.margins.localhandler", nil, "nut", "disabled" )
+appendaction("finalizers", "lists", "builders.paragraphs.keeptogether", nil, "nut", "disabled" )
+appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize", nil, "nut", "disabled" )
+appendaction("finalizers", "lists", "builders.paragraphs.tag", nil, "nut", "disabled" )
+appendaction("finalizers", "lists", "nodes.linefillers.handler", nil, "nut", "disabled" )
+
+appendaction("contributers", "normalizers", "nodes.handlers.flattenline", nil, "nut", "disabled" )
+appendaction("contributers", "normalizers", "nodes.handlers.textbackgrounds", nil, "nut", "disabled" )
+
+appendaction("vboxbuilders", "normalizers", "nodes.handlers.backgroundsvbox", nil, "nut", "disabled" )
+--------("vboxbuilders", "normalizers", "typesetters.margins.localhandler", nil, "nut", "disabled" )
+appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler", nil, "nut", "enabled" )
+appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler", nil, "nut", "disabled" )
+appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler", nil, "nut", "disabled" )
+
+appendaction("mvlbuilders", "normalizers", "nodes.handlers.backgroundspage", nil, "nut", "disabled" )
+appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler", nil, "nut", "disabled" )
+appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate", nil, "nut", "disabled" )
+appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler", nil, "nut", "enabled" )
+appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler", nil, "nut", "disabled" )
+appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler", nil, "nut", "disabled" )
+
+-- some protection
freezecallbacks("find_.*_file", "find file using resolver")
freezecallbacks("read_.*_file", "read file at once")
@@ -255,8 +159,12 @@ freezegroup("finalizers", "normalizers")
freezegroup("finalizers", "fonts")
freezegroup("finalizers", "lists")
+freezegroup("math", "normalizers")
+freezegroup("math", "builders")
+
freezegroup("shipouts", "normalizers")
freezegroup("shipouts", "finishers")
+freezegroup("shipouts", "wrapup")
freezegroup("mvlbuilders", "normalizers")
freezegroup("vboxbuilders", "normalizers")
@@ -269,13 +177,10 @@ freezegroup("math", "builders")
-- new: disabled here
-disableaction("processors", "builders.kernel.ligaturing")
-disableaction("processors", "builders.kernel.kerning")
-
directives.register("nodes.basepass", function(v)
if v then
- enableaction("processors", "builders.kernel.ligaturing")
- enableaction("processors", "builders.kernel.kerning")
+ enableaction("processors", "builders.kernel.ligaturing")
+ enableaction("processors", "builders.kernel.kerning")
else
disableaction("processors", "builders.kernel.ligaturing")
disableaction("processors", "builders.kernel.kerning")
diff --git a/tex/context/base/mkiv/trac-jus.lua b/tex/context/base/mkiv/trac-jus.lua
index e7a030257..0acb685ed 100644
--- a/tex/context/base/mkiv/trac-jus.lua
+++ b/tex/context/base/mkiv/trac-jus.lua
@@ -15,7 +15,6 @@ local a_alignstate = attributes.private("alignstate")
local a_justification = attributes.private("justification")
local nuts = nodes.nuts
-local tonut = nuts.tonut
local getfield = nuts.getfield
local getlist = nuts.getlist
@@ -26,7 +25,8 @@ local setlink = nuts.setlink
local getwidth = nuts.getwidth
local findtail = nuts.tail
-local traverse_id = nuts.traverse_id
+local nexthlist = nuts.traversers.hlist
+
local list_dimensions = nuts.dimensions
local copy_list = nuts.copy_list
@@ -77,7 +77,7 @@ trackers.register("visualizers.justification", function(v)
end)
function checkers.handler(head)
- for current in traverse_id(hlist_code,tonut(head)) do
+ for current in nexthlist, head do
if getattr(current,a_justification) == 1 then
setattr(current,a_justification,0) -- kind of reset
local width = getwidth(current)
diff --git a/tex/context/base/mkiv/trac-par.lua b/tex/context/base/mkiv/trac-par.lua
index 56291f8c8..f16078483 100644
--- a/tex/context/base/mkiv/trac-par.lua
+++ b/tex/context/base/mkiv/trac-par.lua
@@ -125,7 +125,7 @@ end
builders.paragraphs.expansion = builders.paragraphs.expansion or { }
function builders.paragraphs.expansion.trace(head)
- colorize(tonut(head),true)
+ colorize(head,true)
return head
end
diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua
index 91ee1cf7d..e744f84f2 100644
--- a/tex/context/base/mkiv/trac-vis.lua
+++ b/tex/context/base/mkiv/trac-vis.lua
@@ -74,11 +74,12 @@ local copy_list = nuts.copy_list
local flush_node_list = nuts.flush_list
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
-local traverse_nodes = nuts.traverse
local apply_to_nodes = nuts.apply
local find_tail = nuts.tail
local effectiveglue = nuts.effective_glue
+local nextnode = nuts.traversers.node
+
local hpack_string = nuts.typesetters.tohpack
local texgetattribute = tex.getattribute
@@ -188,7 +189,8 @@ end
-- we can preset a bunch of bits
-local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
+local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
+local outlinerule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
local function enable()
if not usedfont then
@@ -233,6 +235,9 @@ local function enable()
if not userrule then
userrule = nuts.rules.userrule
end
+ if not outlinerule then
+ outlinerule = nuts.pool.outlinerule
+ end
end
local function setvisual(n,a,what,list) -- this will become more efficient when we have the bit lib linked in
@@ -700,7 +705,7 @@ local ruledbox do
local wd, ht, dp = getwhd(current)
if wd ~= 0 then
local shift = getshift(current)
- local dir = getdir(current)
+ -- local dir = getdir(current)
-- if dir == "LTL" or dir == "RRT" then
-- wd, ht, dp = ht + dp, wd, 0
-- end
@@ -761,7 +766,7 @@ local ruledbox do
--
local info = setlink(
this and copy_list(this) or nil,
- userrule {
+ (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
width = wd,
height = ht,
depth = dp,
@@ -772,7 +777,7 @@ local ruledbox do
)
--
setlisttransparency(info,c_text)
- info = new_hlist(info)
+ -- info = new_hlist(info)
--
setattr(info,a_layer,layer)
if vertical then
@@ -849,10 +854,10 @@ local ruledglyph do
-- local wd = chardata[getfont(current)][getchar(current)].width
if wd ~= 0 then
local wd, ht, dp = getwhd(current)
- -- local dir = getdir(current)
- -- if dir == "LTL" or dir = "RTT" then
- -- wd, ht, dp = ht + dp, wd, 0
- -- end
+ -- local dir = getdir(current)
+ -- if dir == "LTL" or dir = "RTT" then
+ -- wd, ht, dp = ht + dp, wd, 0
+ -- end
local next = getnext(current)
local prev = previous
setboth(current)
@@ -895,7 +900,7 @@ local ruledglyph do
-- userrules:
--
info = setlink(
- userrule {
+ (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
width = wd,
height = ht,
depth = dp,
@@ -1198,6 +1203,8 @@ do
local listcodes = nodes.listcodes
local line_code = listcodes.line
+ local cache
+
local function visualize(head,vertical,forced,parent)
local trace_hbox = false
local trace_vbox = false
@@ -1225,6 +1232,58 @@ do
local prev_trace_fontkern = nil
local prev_trace_italic = nil
local prev_trace_expansion = nil
+
+ -- local function setthem(t,k)
+ -- local v_trace_hbox = band(k, 1) ~= 0
+ -- local v_trace_vbox = band(k, 2) ~= 0
+ -- local v_trace_vtop = band(k, 4) ~= 0
+ -- local v_trace_kern = band(k, 8) ~= 0
+ -- local v_trace_glue = band(k, 16) ~= 0
+ -- local v_trace_penalty = band(k, 32) ~= 0
+ -- local v_trace_fontkern = band(k, 64) ~= 0
+ -- local v_trace_strut = band(k, 128) ~= 0
+ -- local v_trace_whatsit = band(k, 256) ~= 0
+ -- local v_trace_glyph = band(k, 512) ~= 0
+ -- local v_trace_simple = band(k, 1024) ~= 0
+ -- local v_trace_user = band(k, 2048) ~= 0
+ -- local v_trace_math = band(k, 4096) ~= 0
+ -- local v_trace_italic = band(k, 8192) ~= 0
+ -- local v_trace_origin = band(k, 16384) ~= 0
+ -- local v_trace_discretionary = band(k, 32768) ~= 0
+ -- local v_trace_expansion = band(k, 65536) ~= 0
+ -- local v_trace_line = band(k,131072) ~= 0
+ -- local v_trace_space = band(k,262144) ~= 0
+ -- local v_trace_depth = band(k,524288) ~= 0
+ -- local v = function()
+ -- trace_hbox = v_trace_hbox
+ -- trace_vbox = v_trace_vbox
+ -- trace_vtop = v_trace_vtop
+ -- trace_kern = v_trace_kern
+ -- trace_glue = v_trace_glue
+ -- trace_penalty = v_trace_penalty
+ -- trace_fontkern = v_trace_fontkern
+ -- trace_strut = v_trace_strut
+ -- trace_whatsit = v_trace_whatsit
+ -- trace_glyph = v_trace_glyph
+ -- trace_simple = v_trace_simple
+ -- trace_user = v_trace_user
+ -- trace_math = v_trace_math
+ -- trace_italic = v_trace_italic
+ -- trace_origin = v_trace_origin
+ -- trace_discretionary = v_trace_discretionary
+ -- trace_expansion = v_trace_expansion
+ -- trace_line = v_trace_line
+ -- trace_space = v_trace_space
+ -- trace_depth = v_trace_depth
+ -- end
+ -- t[k] = v
+ -- return v
+ -- end
+ --
+ -- if not cache then
+ -- cache = setmetatableindex(setthem)
+ -- end
+
while current do
local id = getid(current)
local a = forced or getattr(current,a_visual) or unsetvalue
@@ -1254,6 +1313,7 @@ do
trace_space = false
trace_depth = false
else -- dead slow:
+ -- cache[a]()
trace_hbox = band(a, 1) ~= 0
trace_vbox = band(a, 2) ~= 0
trace_vtop = band(a, 4) ~= 0
@@ -1390,9 +1450,9 @@ do
local function handler(head)
if usedfont then
starttiming(visualizers)
- head = visualize(tonut(head),true)
+ head = visualize(head,true)
stoptiming(visualizers)
- return tonode(head), true
+ return head, true
else
return head, false
end
@@ -1433,7 +1493,7 @@ do
}
local function markfonts(list)
- for n, id in traverse_nodes(list) do
+ for n, id in nextnode, list do
if id == glyph_code then
local font = getfont(n)
local okay = used[font]
diff --git a/tex/context/base/mkiv/typo-bld.lua b/tex/context/base/mkiv/typo-bld.lua
index 8d349f3a6..d3dddc990 100644
--- a/tex/context/base/mkiv/typo-bld.lua
+++ b/tex/context/base/mkiv/typo-bld.lua
@@ -264,19 +264,18 @@ end
-- do
--
--- local nuts = nodes.nuts
--- local tonut = nodes.tonut
--- local tonode = nuts.tonode
--- local getglue = tex.getglue
--- local getwhd = nuts.getwhd
--- local new_b_skip = nuts.pool.baselineskip
--- local new_l_skip = nuts.pool.lineskip
--- local find_tail = nuts.tail
--- local setlink = nuts.setlink
+-- local nuts = nodes.nuts
+-- local getglue = tex.getglue
+-- local getwhd = nuts.getwhd
+-- local new_b_skip = nuts.pool.baselineskip
+-- local new_l_skip = nuts.pool.lineskip
+-- local find_tail = nuts.tail
+-- local setlink = nuts.setlink
+-- local is_mirrored = nodes.is_mirrored
--
--- function nodes.setprevdepth(box,prevdepth) -- this will become a helper
--- local head = tonut(box)
+-- function nuts.setprevdepth(head,prevdepth) -- this will become a helper
-- local wd, ht, dp = getwhd(head)
+-- local mirrored = false -- getid(box) == hlist_code and is_mirrored(getdir(box)) -- never mirrored
-- if prevdepth > -65536000 then
-- local b_width, b_stretch, b_shrink = getglue("baselineskip")
-- local l_width, l_stretch, l_shrink = getglue("lineskip")
@@ -287,7 +286,16 @@ end
-- head = setlink(new_b_skip(correction,b_stretch,b_shrink),head)
-- end
-- end
--- return tonode(head), mirrored and ht or dp
+-- return head, mirrored and ht or dp
+-- end
+--
+-- function nodes.setprevdepth(box,prevdepth)
+-- local h, p = nodes.prepend_prevdepth(box,prevdepth)
+-- if h then
+-- return h, p
+-- else
+-- return head, prevdepth
+-- end
-- end
--
-- end
diff --git a/tex/context/base/mkiv/typo-brk.lua b/tex/context/base/mkiv/typo-brk.lua
index 51760bbf4..34d4071aa 100644
--- a/tex/context/base/mkiv/typo-brk.lua
+++ b/tex/context/base/mkiv/typo-brk.lua
@@ -23,7 +23,6 @@ local settings_to_array = utilities.parsers.settings_to_array
local nuts = nodes.nuts
local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -241,10 +240,9 @@ end
function breakpoints.handler(head)
local done = false
- local nead = tonut(head)
local attr = nil
local map = nil
- local current = nead
+ local current = head
while current do
local char, id = isglyph(current)
if char then
@@ -313,7 +311,7 @@ function breakpoints.handler(head)
end
end
if not done then
- return head, false
+ return head
end
-- we have hits
local numbers = languages.numbers
@@ -383,13 +381,13 @@ function breakpoints.handler(head)
if nright == cright then
local method = methods[smap.type]
if method then
- nead, start = method(nead,start,stop,smap,kern)
+ head, start = method(head,start,stop,smap,kern)
end
end
-- end
end
end
- return tonode(nead), true
+ return head
end
local enabled = false
diff --git a/tex/context/base/mkiv/typo-cap.lua b/tex/context/base/mkiv/typo-cap.lua
index 4dffd1c49..4383dc6b9 100644
--- a/tex/context/base/mkiv/typo-cap.lua
+++ b/tex/context/base/mkiv/typo-cap.lua
@@ -18,8 +18,6 @@ local report_casing = logs.reporter("typesetting","casing")
local nodes, node = nodes, node
local nuts = nodes.nuts
-local tonode = nuts.tonode
-local tonut = nuts.tonut
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -37,10 +35,11 @@ local setfont = nuts.setfont
local copy_node = nuts.copy
local end_of_math = nuts.end_of_math
-local traverse_id = nuts.traverse_id
local insert_after = nuts.insert_after
local find_attribute = nuts.find_attribute
+local nextglyph = nuts.traversers.glyph
+
local nodecodes = nodes.nodecodes
local skipcodes = nodes.skipcodes
local kerncodes = nodes.kerncodes
@@ -149,13 +148,11 @@ local function replacer(start,codes)
insert_after(start,start,g)
end
end
- return start, true
elseif ifc[dc] then
setchar(start,dc)
- return start, true
end
end
- return start, false
+ return start
end
local registered, n = { }, 0
@@ -191,9 +188,9 @@ local function Words(start,attr,lastfont,n,count,where,first) -- looks quite com
end
if count == 1 and where ~= "post" then
replacer(first or start,uccodes)
- return start, true, true
+ return start, true
else
- return start, false, true
+ return start, true
end
end
@@ -203,9 +200,9 @@ local function Word(start,attr,lastfont,n,count,where,first)
end
local function camel(start,attr,lastfont,n,count,where,first)
- local _, done_1 = word(start,attr,lastfont,n,count,where,first)
- local _, done_2 = Words(start,attr,lastfont,n,count,where,first)
- return start, done_1 or done_2, true
+ word(start,attr,lastfont,n,count,where,first)
+ Words(start,attr,lastfont,n,count,where,first)
+ return start, true
end
-- local function mixed(start,attr,lastfont,n,count,where,first)
@@ -216,19 +213,16 @@ end
-- local char = getchar(first)
-- local dc = uccodes[char]
-- if not dc then
--- return start, false, true
+-- -- quit
-- elseif dc == char then
-- local lfa = lastfont[n]
-- if lfa then
-- setfont(first,lfa)
--- return start, true, true
--- else
--- return start, false, true
-- end
-- else
-- replacer(first or start,uccodes)
--- return start, true, true
-- end
+-- return start, true
-- end
local function mixed(start,attr,lastfont,n,count,where,first)
@@ -239,38 +233,33 @@ local function mixed(start,attr,lastfont,n,count,where,first)
local char = getchar(used)
local dc = uccodes[char]
if not dc then
- return start, false, true
+ -- quit
elseif dc == char then
local lfa = lastfont[n]
if lfa then
setfont(used,lfa)
- return start, true, true
- else
- return start, false, true
end
- else
- if check_kerns then
- local p = getprev(used)
- if p and getid(p) == glyph_code then
- local c = lccodes[char]
- local c = type(c) == "table" and c[1] or c
- replacer(used,uccodes)
- local fp = getfont(p)
- local fc = getfont(used)
- if fp ~= fc then
- local k = fonts.getkern(fontdata[fp],getchar(p),c)
- if k ~= 0 then
- insert_after(p,p,newkern(k))
- end
+ elseif check_kerns then
+ local p = getprev(used)
+ if p and getid(p) == glyph_code then
+ local c = lccodes[char]
+ local c = type(c) == "table" and c[1] or c
+ replacer(used,uccodes)
+ local fp = getfont(p)
+ local fc = getfont(used)
+ if fp ~= fc then
+ local k = fonts.getkern(fontdata[fp],getchar(p),c)
+ if k ~= 0 then
+ insert_after(p,p,newkern(k))
end
- else
- replacer(used,uccodes)
end
else
replacer(used,uccodes)
end
- return start, true, true
+ else
+ replacer(used,uccodes)
end
+ return start, true
end
local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3
@@ -284,11 +273,11 @@ local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3
end
end
end
- local s, d, c = replacer(first or start,uccodes)
+ local s, c = replacer(first or start,uccodes)
if once then
lastfont[n] = false -- here
end
- return start, d, c
+ return start, c
end
local function capital(start,attr,lastfont,n,where,count,first,count) -- 4
@@ -296,7 +285,7 @@ local function capital(start,attr,lastfont,n,where,count,first,count) -- 4
end
local function none(start,attr,lastfont,n,count,where,first)
- return start, false, true
+ return start, true
end
local function randomized(start,attr,lastfont,n,count,where,first)
@@ -311,7 +300,7 @@ local function randomized(start,attr,lastfont,n,count,where,first)
local n = getrandom("capital lu",0x41,0x5A)
if tfm[n] then -- this also intercepts tables
setchar(used,n)
- return start, true
+ return start
end
end
elseif kind == "ll" then
@@ -319,11 +308,11 @@ local function randomized(start,attr,lastfont,n,count,where,first)
local n = getrandom("capital ll",0x61,0x7A)
if tfm[n] then -- this also intercepts tables
setchar(used,n)
- return start, true
+ return start
end
end
end
- return start, false
+ return start
end
register(variables.WORD, WORD) -- 1
@@ -341,10 +330,9 @@ register(variables.cap, variables.capital) -- clone
register(variables.Cap, variables.Capital) -- clone
function cases.handler(head) -- not real fast but also not used on much data
- local start = tonut(head)
+ local start = head
local lastfont = { }
local lastattr = nil
- local done = false
local count = 0
local previd = nil
local prev = nil
@@ -367,10 +355,7 @@ function cases.handler(head) -- not real fast but also not used on much data
end
local action = actions[n] -- map back to low number
if action then
- start, ok = action(start,attr,lastfont,n,count)
- if ok then
- done = true
- end
+ start = action(start,attr,lastfont,n,count)
if trace_casing then
report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,ok)
end
@@ -396,32 +381,38 @@ function cases.handler(head) -- not real fast but also not used on much data
local pre, post, replace = getdisc(start)
if replace then
local cnt = count
- for g in traverse_id(glyph_code,replace) do
+ for g in nextglyph, replace do
cnt = cnt + 1
takeattr(g,a_cases)
-- setattr(g,a_cases,unsetvalue)
- local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g)
- if quit then break end
+ local h, quit = action(start,attr,lastfont,n,cnt,"replace",g)
+ if quit then
+ break
+ end
end
end
if pre then
local cnt = count
- for g in traverse_id(glyph_code,pre) do
+ for g in nextglyph, pre do
cnt = cnt + 1
takeattr(g,a_cases)
-- setattr(g,a_cases,unsetvalue)
- local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g)
- if quit then break end
+ local h, quit = action(start,attr,lastfont,n,cnt,"pre",g)
+ if quit then
+ break
+ end
end
end
if post then
local cnt = count
- for g in traverse_id(glyph_code,post) do
+ for g in nextglyph, post do
cnt = cnt + 1
takeattr(g,a_cases)
-- setattr(g,a_cases,unsetvalue)
- local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g)
- if quit then break end
+ local h, quit = action(start,attr,lastfont,n,cnt,"post",g)
+ if quit then
+ break
+ end
end
end
end
@@ -441,17 +432,16 @@ function cases.handler(head) -- not real fast but also not used on much data
start = getnext(start)
end
end
- return head, done
+ return head
end
-- function cases.handler(head) -- not real fast but also not used on much data
--- local attr, start = find_attribute(tonut(head),a_cases)
+-- local attr, start = find_attribute(head,a_cases)
-- if not start then
-- return head, false
-- end
-- local lastfont = { }
-- local lastattr = nil
--- local done = false
-- local count = 0
-- local previd = nil
-- local prev = nil
@@ -475,10 +465,7 @@ end
-- end
-- local action = actions[n] -- map back to low number
-- if action then
--- start, ok = action(start,attr,lastfont,n,count)
--- if ok then
--- done = true
--- end
+-- start = action(start,attr,lastfont,n,count)
-- if trace_casing then
-- report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,ok)
-- end
@@ -504,32 +491,38 @@ end
-- local pre, post, replace = getdisc(start)
-- if replace then
-- local cnt = count
--- for g in traverse_id(glyph_code,replace) do
+-- for g in glyph_code, replace do
-- cnt = cnt + 1
-- takeattr(g,a_cases)
-- -- setattr(g,a_cases,unsetvalue)
--- local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g)
--- if quit then break end
+-- local h, quit = action(start,attr,lastfont,n,cnt,"replace",g)
+-- if quit then
+-- break
+-- end
-- end
-- end
-- if pre then
-- local cnt = count
--- for g in traverse_id(glyph_code,pre) do
+-- for g in nextglyph, pre do
-- cnt = cnt + 1
-- takeattr(g,a_cases)
-- -- setattr(g,a_cases,unsetvalue)
--- local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g)
--- if quit then break end
+-- local h, quit = action(start,attr,lastfont,n,cnt,"pre",g)
+-- if quit then
+-- break
+-- end
-- end
-- end
-- if post then
-- local cnt = count
--- for g in traverse_id(glyph_code,post) do
+-- for g in nextglyph, post do
-- cnt = cnt + 1
-- takeattr(g,a_cases)
-- -- setattr(g,a_cases,unsetvalue)
--- local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g)
--- if quit then break end
+-- local h, quit = action(start,attr,lastfont,n,cnt,"post",g)
+-- if quit then
+-- break
+-- end
-- end
-- end
-- end
@@ -555,26 +548,22 @@ end
-- attr, start = find_attribute(start,a_cases)
-- end
-- end
--- return head, done
+-- return head
-- end
-- function cases.handler(head) -- let's assume head doesn't change ... no reason
--- local done = false
-- local lastfont = { }
--- for first, last, size, attr in nuts.words(tonut(head),a_cases) do
+-- for first, last, size, attr in nuts.words(head,a_cases) do
-- local n, id, m = get(attr)
-- if lastfont[n] == nil then
-- lastfont[n] = id
-- end
-- local action = actions[n]
-- if action then
--- local _, ok = action(first,attr,lastfont,n)
--- if ok then
--- done = true
--- end
+-- action(first,attr,lastfont,n)
-- end
-- end
--- return head, done
+-- return head
-- end
local enabled = false
diff --git a/tex/context/base/mkiv/typo-chr.lua b/tex/context/base/mkiv/typo-chr.lua
index 80497a492..1aa84f5ab 100644
--- a/tex/context/base/mkiv/typo-chr.lua
+++ b/tex/context/base/mkiv/typo-chr.lua
@@ -17,16 +17,13 @@ if not modules then modules = { } end modules ['typo-chr'] = {
-- local nuts = nodes.nuts
-- local pool = nuts.pool
--
--- local tonut = nuts.tonut
--- local tonode = nuts.tonode
-- local getid = nuts.getid
-- local getprev = nuts.getprev
--- local getsubtype = nuts.getsubtype
-- local getchar = nuts.getchar
-- local getfield = nuts.getfield
--
-- local remove_node = nuts.remove
--- local traverse_by_id = nuts.traverse_id
+-- local nextwhatsit = nuts.traversers.whatsit
--
-- local signal = pool.userids.signal
--
@@ -36,10 +33,8 @@ if not modules then modules = { } end modules ['typo-chr'] = {
-- removepunctuation = function(head,n)
-- local prev = getprev(n)
-- if prev then
--- if getid(prev) == glyph_code then
--- if is_punctuation[getchar(prev)] then
--- head = remove_node(head,prev,true)
--- end
+-- if getid(prev) == glyph_code and is_punctuation[getchar(prev)] then
+-- head = remove_node(head,prev,true)
-- end
-- end
-- return head
@@ -51,23 +46,18 @@ if not modules then modules = { } end modules ['typo-chr'] = {
-- typesetters.signals = { }
--
-- function typesetters.signals.handler(head)
--- local h = tonut(head)
-- local done = false
--- for n in traverse_by_id(whatsit_code,h) do
--- if getsubtype(n) == user_code and getfield(n,"user_id") == signal and getfield(n,"type") == 115 then
+-- for n, subtype in nextwhatsit, head do
+-- if subtype == user_code and getfield(n,"user_id") == signal and getfield(n,"type") == 115 then
-- local action = actions[getfield(n,"value")]
-- if action then
--- h = action(h,n)
+-- head = action(h,n)
-- end
--- h = remove_node(h,n,true)
+-- head = remove_node(head,n,true)
-- done = true
-- end
-- end
--- if done then
--- return tonode(h), true
--- else
--- return head
--- end
+-- return head, done
-- end
--
-- local enabled = false
diff --git a/tex/context/base/mkiv/typo-cln.lua b/tex/context/base/mkiv/typo-cln.lua
index b7187eaeb..0d5e3eb5e 100644
--- a/tex/context/base/mkiv/typo-cln.lua
+++ b/tex/context/base/mkiv/typo-cln.lua
@@ -31,7 +31,6 @@ local enableaction = nodes.tasks.enableaction
local texsetattribute = tex.setattribute
local nuts = nodes.nuts
-local tonut = nuts.tonut
local getchar = nuts.getchar
local getattr = nuts.getattr
@@ -39,7 +38,7 @@ local setattr = nuts.setattr
local setchar = nuts.setchar
-local traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
local unsetvalue = attributes.unsetvalue
@@ -58,8 +57,8 @@ local resetter = { -- this will become an entry in char-def
-- cleaning comes first.
function cleaners.handler(head)
- local inline, done = false, false
- for n in traverse_id(glyph_code,tonut(head)) do
+ local inline = false
+ for n in nextglyph, head do
local char = getchar(n)
if resetter[char] then
inline = false
@@ -71,7 +70,6 @@ function cleaners.handler(head)
-- some day, not much change that \SS ends up here
else
setchar(n,upper)
- done = true
if trace_autocase then
report_autocase("")
end
@@ -80,7 +78,35 @@ function cleaners.handler(head)
inline = true
end
end
- return head, done
+ return head
+end
+
+if LUATEXVERSION >= 1.090 then
+
+ function cleaners.handler(head)
+ local inline = false
+ for n, font, char in nextglyph, head do
+ if resetter[char] then
+ inline = false
+ elseif not inline then
+ local a = getattr(n,a_cleaner)
+ if a == 1 then -- currently only one cleaner so no need to be fancy
+ local upper = uccodes[char]
+ if type(upper) == "table" then
+ -- some day, not much change that \SS ends up here
+ else
+ setchar(n,upper)
+ if trace_autocase then
+ report_autocase("")
+ end
+ end
+ end
+ inline = true
+ end
+ end
+ return head
+ end
+
end
-- see typo-cap for a more advanced settings handler .. not needed now
diff --git a/tex/context/base/mkiv/typo-dha.lua b/tex/context/base/mkiv/typo-dha.lua
index af01f0f0d..c12541175 100644
--- a/tex/context/base/mkiv/typo-dha.lua
+++ b/tex/context/base/mkiv/typo-dha.lua
@@ -46,8 +46,6 @@ local trace_directions = false trackers.register("typesetters.directions.defa
local report_directions = logs.reporter("typesetting","text directions")
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -136,7 +134,7 @@ end
local function process(start)
- local head = tonut(start) -- we have a global head
+ local head = start
local current = head
local autodir = 0
local embedded = 0
@@ -443,7 +441,7 @@ local function process(start)
end
end
- return tonode(head), done
+ return head
end
diff --git a/tex/context/base/mkiv/typo-dig.lua b/tex/context/base/mkiv/typo-dig.lua
index 61e96c6b6..51ed247fe 100644
--- a/tex/context/base/mkiv/typo-dig.lua
+++ b/tex/context/base/mkiv/typo-dig.lua
@@ -20,8 +20,6 @@ local report_digits = logs.reporter("typesetting","digits")
local nodes, node = nodes, node
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -111,23 +109,21 @@ actions[1] = function(head,start,attr)
attr%100,div(attr,100),char,unic,newwidth-oldwidth)
end
head, start = nodes.aligned(head,start,start,newwidth,"middle")
- return head, start, true
+ return head, start
end
end
- return head, start, false
+ return head, start
end
function digits.handler(head)
- head = tonut(head)
- local done, current, ok = false, head, false
+ local current = head
while current do
if getid(current) == glyph_code then
local attr = takeattr(current,a_digits)
if attr and attr > 0 then
local action = actions[attr%100] -- map back to low number
if action then
- head, current, ok = action(head,current,attr)
- done = done and ok
+ head, current = action(head,current,attr)
elseif trace_digits then
report_digits("unknown digit trigger %a",attr)
end
@@ -137,7 +133,7 @@ function digits.handler(head)
current = getnext(current)
end
end
- return tonode(head), done
+ return head
end
local m, enabled = 0, false -- a trick to make neighbouring ranges work
diff --git a/tex/context/base/mkiv/typo-dir.lua b/tex/context/base/mkiv/typo-dir.lua
index 7fbf5f6d3..e405a39e8 100644
--- a/tex/context/base/mkiv/typo-dir.lua
+++ b/tex/context/base/mkiv/typo-dir.lua
@@ -168,21 +168,21 @@ local stoptiming = statistics.stoptiming
function directions.handler(head,_,_,_,direction)
local only_one = not getnext(head)
if only_one and not one_too then
- return head, false
+ return head
end
local attr = getattr(head,a_directions)
if not attr or attr == 0 then
- return head, false
+ return head
end
local method = getmethod(attr)
local handler = handlers[method]
if not handler then
- return head, false
+ return head
end
starttiming(directions)
- local head, done = handler(head,direction,only_one)
+ head = handler(head,direction,only_one)
stoptiming(directions)
- return head, done
+ return head
end
statistics.register("text directions", function()
diff --git a/tex/context/base/mkiv/typo-drp.lua b/tex/context/base/mkiv/typo-drp.lua
index 1e142280f..33c5fbdc9 100644
--- a/tex/context/base/mkiv/typo-drp.lua
+++ b/tex/context/base/mkiv/typo-drp.lua
@@ -28,14 +28,11 @@ local enableaction = tasks.enableaction
local disableaction = tasks.disableaction
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
local getchar = nuts.getchar
local getid = nuts.getid
-local getsubtype = nuts.getsubtype
local getattr = nuts.getattr
local getwhd = nuts.getwhd
@@ -59,8 +56,9 @@ local new_kern = nodepool.kern
local insert_before = nuts.insert_before
local insert_after = nuts.insert_after
local remove_node = nuts.remove
-local traverse_id = nuts.traverse_id
-local traverse = nuts.traverse
+
+local nextnode = nuts.traversers.node
+local nextglyph = nuts.traversers.glyph
local variables = interfaces.variables
local v_default = variables.default
@@ -139,7 +137,6 @@ interfaces.implement {
-- a page so this has a low priority
actions[v_default] = function(head,setting)
- local done = false
local id = getid(head)
if id == localpar_code then
-- begin of par
@@ -173,7 +170,7 @@ actions[v_default] = function(head,setting)
-- 1 char | n chars | skip first quote | ignore punct | keep punct
--
if getattr(first,a_initial) then
- for current in traverse(getnext(first)) do
+ for current in nextnode, getnext(first) do
if getattr(current,a_initial) then
last = current
else
@@ -189,10 +186,10 @@ actions[v_default] = function(head,setting)
local next = getnext(first)
if not next then
-- don't start with a quote or so
- return head, false
+ return head
end
last = nil
- for current in traverse_id(glyph_code,next) do
+ for current in nextglyph, next do
head, first = remove_node(head,first,true)
first = current
last = first
@@ -200,21 +197,21 @@ actions[v_default] = function(head,setting)
end
if not last then
-- no following glyph or so
- return head, false
+ return head
end
else
-- keep quote etc with initial
local next = getnext(first)
if not next then
-- don't start with a quote or so
- return head, false
+ return head
end
- for current in traverse_id(glyph_code,next) do
+ for current in nextglyph, next do
last = current
break
end
if last == first then
- return head, false
+ return head
end
end
elseif kind == "pf" then
@@ -225,7 +222,7 @@ actions[v_default] = function(head,setting)
-- maybe also: get all A. B. etc
local next = getnext(first)
if next then
- for current in traverse_id(glyph_code,next) do
+ for current in nextglyph, next do
local char = getchar(current)
local kind = category(char)
if kind == "po" then
@@ -241,7 +238,7 @@ actions[v_default] = function(head,setting)
end
end
else
- for current in traverse_id(glyph_code,first) do
+ for current in nextglyph, first do
last = current
if length <= 1 then
break
@@ -265,12 +262,12 @@ actions[v_default] = function(head,setting)
end
-- apply font
--- local g = nodes.copy(tonode(current))
+-- local g = nuts.copy(current)
-- g.subtype = 0
-- nodes.handlers.characters(g)
-- nodes.handlers.protectglyphs(g)
-- setchar(current,g.char)
--- nodes.flush_node(g)
+-- nuts.flush_node(g)
-- can be a helper
if ca and ca > 0 then
@@ -319,7 +316,7 @@ actions[v_default] = function(head,setting)
end
--
local hoffset = width + hoffset + distance + (indent and parindent or 0)
- for current in traverse_id(glyph_code,first) do
+ for current in nextglyph, first do
setoffsets(current,-hoffset,-voffset) -- no longer - height here
if current == last then
break
@@ -347,14 +344,12 @@ actions[v_default] = function(head,setting)
if indent then
insert_after(first,first,new_kern(-parindent))
end
- done = true
end
end
- return head, done
+ return head
end
function initials.handler(head)
- head = tonut(head)
local start = head
local attr = nil
while start do
@@ -377,9 +372,8 @@ function initials.handler(head)
if trace_initials then
report_initials("processing initials, alternative %a",alternative)
end
- local head, done = action(head,settings)
- return tonode(head), done
+ return action(head,settings)
end
end
- return tonode(head), false
+ return head
end
diff --git a/tex/context/base/mkiv/typo-dua.lua b/tex/context/base/mkiv/typo-dua.lua
index 1e48dfb91..9aaa536c9 100644
--- a/tex/context/base/mkiv/typo-dua.lua
+++ b/tex/context/base/mkiv/typo-dua.lua
@@ -68,8 +68,6 @@ local directiondata = characters.directions
local mirrordata = characters.mirrors
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getid = nuts.getid
@@ -730,7 +728,6 @@ end
local function apply_to_list(list,size,head,pardir)
local index = 1
local current = head
- local done = false
while current do
if index > size then
report_directions("fatal error, size mismatch")
@@ -760,7 +757,6 @@ local function apply_to_list(list,size,head,pardir)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
enddir = false
- done = true
end
elseif begindir then
if id == localpar_code then
@@ -770,7 +766,6 @@ local function apply_to_list(list,size,head,pardir)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
begindir = nil
- done = true
end
end
if begindir then
@@ -778,7 +773,6 @@ local function apply_to_list(list,size,head,pardir)
setprop(d,"directions",true)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
- done = true
end
local skip = entry.skip
if skip and skip > 0 then
@@ -792,24 +786,21 @@ local function apply_to_list(list,size,head,pardir)
setprop(d,"directions",true)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
- done = true
end
if not entry.remove then
current = getnext(current)
elseif remove_controls then
-- X9
head, current = remove_node(head,current,true)
- done = true
else
current = getnext(current)
end
index = index + 1
end
- return head, done
+ return head
end
local function process(head)
- head = tonut(head)
local list, size = build_list(head)
local baselevel, pardir, dirfound = get_baselevel(head,list,size) -- we always have an inline dir node in context
if not dirfound and trace_details then
@@ -825,8 +816,7 @@ local function process(head)
report_directions("after : %s",show_list(list,size,"direction"))
report_directions("result : %s",show_done(list,size))
end
- local head, done = apply_to_list(list,size,head,pardir)
- return tonode(head), done
+ return apply_to_list(list,size,head,pardir)
end
directions.installhandler(interfaces.variables.one,process)
diff --git a/tex/context/base/mkiv/typo-dub.lua b/tex/context/base/mkiv/typo-dub.lua
index d0747ae6c..206cfd9ae 100644
--- a/tex/context/base/mkiv/typo-dub.lua
+++ b/tex/context/base/mkiv/typo-dub.lua
@@ -55,8 +55,6 @@ local mirrordata = characters.mirrors
local textclassdata = characters.textclasses
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getid = nuts.getid
@@ -930,7 +928,6 @@ end
local function apply_to_list(list,size,head,pardir)
local index = 1
local current = head
- local done = false
if trace_list then
report_directions("start run")
end
@@ -973,7 +970,6 @@ local function apply_to_list(list,size,head,pardir)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
enddir = false
- done = true
end
elseif begindir then
if id == localpar_code then
@@ -983,7 +979,6 @@ local function apply_to_list(list,size,head,pardir)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
begindir = nil
- done = true
end
end
if begindir then
@@ -991,7 +986,6 @@ local function apply_to_list(list,size,head,pardir)
setprop(d,"directions",true)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
- done = true
end
local skip = entry.skip
if skip and skip > 0 then
@@ -1005,14 +999,12 @@ local function apply_to_list(list,size,head,pardir)
setprop(d,"directions",true)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
- done = true
end
if not entry.remove then
current = getnext(current)
elseif remove_controls then
-- X9
head, current = remove_node(head,current,true)
- done = true
else
current = getnext(current)
end
@@ -1021,11 +1013,10 @@ local function apply_to_list(list,size,head,pardir)
if trace_list then
report_directions("stop run")
end
- return head, done
+ return head
end
local function process(head)
- head = tonut(head)
-- for the moment a whole paragraph property
local attr = getattr(head,a_directions)
local analyze_fences = getfences(attr)
@@ -1045,8 +1036,7 @@ local function process(head)
report_directions("after : %s",show_list(list,size,"direction"))
report_directions("result : %s",show_done(list,size))
end
- local head, done = apply_to_list(list,size,head,pardir)
- return tonode(head), done
+ return apply_to_list(list,size,head,pardir)
end
directions.installhandler(interfaces.variables.two,process)
diff --git a/tex/context/base/mkiv/typo-duc.lua b/tex/context/base/mkiv/typo-duc.lua
index 520740190..60191bf83 100644
--- a/tex/context/base/mkiv/typo-duc.lua
+++ b/tex/context/base/mkiv/typo-duc.lua
@@ -58,8 +58,6 @@ local mirrordata = characters.mirrors
local textclassdata = characters.textclasses
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getid = nuts.getid
@@ -977,7 +975,6 @@ end
local function apply_to_list(list,size,head,pardir)
local index = 1
local current = head
- local done = false
if trace_list then
report_directions("start run")
end
@@ -1020,7 +1017,6 @@ local function apply_to_list(list,size,head,pardir)
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
enddir = false
- done = true
end
elseif begindir then
if id == localpar_code then
@@ -1030,7 +1026,6 @@ local function apply_to_list(list,size,head,pardir)
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
begindir = nil
- done = true
end
end
if begindir then
@@ -1038,7 +1033,6 @@ local function apply_to_list(list,size,head,pardir)
local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
-- setattrlist(d,current)
head = insert_node_before(head,current,d)
- done = true
end
local skip = entry.skip
if skip and skip > 0 then
@@ -1052,14 +1046,12 @@ local function apply_to_list(list,size,head,pardir)
local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end
-- setattrlist(d,current)
head, current = insert_node_after(head,current,d)
- done = true
end
if not entry.remove then
current = getnext(current)
elseif remove_controls then
-- X9
head, current = remove_node(head,current,true)
- done = true
else
current = getnext(current)
end
@@ -1068,7 +1060,7 @@ local function apply_to_list(list,size,head,pardir)
if trace_list then
report_directions("stop run")
end
- return head, done
+ return head
end
-- If needed we can optimize for only_one. There is no need to do anything
@@ -1078,7 +1070,6 @@ end
-- do have a glyph!
local function process(head,direction,only_one)
- head = tonut(head)
-- for the moment a whole paragraph property
local attr = getattr(head,a_directions)
local analyze_fences = getfences(attr)
@@ -1096,8 +1087,7 @@ local function process(head,direction,only_one)
report_directions("after : %s",show_list(list,size,"direction"))
report_directions("result : %s",show_done(list,size))
end
- local head, done = apply_to_list(list,size,head,pardir)
- return tonode(head), done
+ return apply_to_list(list,size,head,pardir)
end
directions.installhandler(interfaces.variables.three,process)
diff --git a/tex/context/base/mkiv/typo-fkr.lua b/tex/context/base/mkiv/typo-fkr.lua
index a1135d0f3..7fe848ade 100644
--- a/tex/context/base/mkiv/typo-fkr.lua
+++ b/tex/context/base/mkiv/typo-fkr.lua
@@ -7,7 +7,6 @@ if not modules then modules = { } end modules ['typo-fkr'] = {
}
local nuts = nodes.nuts
-local tonut = nuts.tonut
local getid = nuts.getid
local getnext = nuts.getnext
local getchar = nuts.getchar
@@ -32,13 +31,10 @@ local a_extrakern = attributes.private("extrafontkern")
typesetters.fontkerns = { }
function typesetters.fontkerns.handler(head)
- local kepthead = head
- local head = tonut(head)
local current = head
local lastfont = nil
local lastchar = nil
local lastdata = nil
- local done = false
while current do
local id = getid(current)
if id == glyph_code then
@@ -64,7 +60,6 @@ function typesetters.fontkerns.handler(head)
end
if kern ~= 0 then
head, current = insert_before(head,current,new_kern(kern))
- done = true
end
lastdata = data
else
@@ -77,7 +72,6 @@ function typesetters.fontkerns.handler(head)
local kern = getkernpair(lastdata,lastchar,char)
if kern ~= 0 then
head, current = insert_before(head,current,new_kern(kern))
- done = true
end
end
lastchar = char
@@ -94,7 +88,7 @@ function typesetters.fontkerns.handler(head)
end
current = getnext(current)
end
- return kepthead, done
+ return head
end
if context then
diff --git a/tex/context/base/mkiv/typo-fln.lua b/tex/context/base/mkiv/typo-fln.lua
index 4fb82ce44..e105b5a11 100644
--- a/tex/context/base/mkiv/typo-fln.lua
+++ b/tex/context/base/mkiv/typo-fln.lua
@@ -30,7 +30,6 @@ local context = context
local implement = interfaces.implement
local nuts = nodes.nuts
-local tonut = nuts.tonut
local tonode = nuts.tonode
local getnext = nuts.getnext
@@ -38,7 +37,6 @@ local getprev = nuts.getprev
local getboth = nuts.getboth
local setboth = nuts.setboth
local getid = nuts.getid
-local getsubtype = nuts.getsubtype
local getwidth = nuts.getwidth
local getlist = nuts.getlist
local setlist = nuts.setlist
@@ -58,7 +56,9 @@ local glue_code = nodecodes.glue
local spaceskip_code = nodes.gluecodes.spaceskip
-local traverse_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
+local nextdisc = nuts.traversers.disc
+
local flush_node_list = nuts.flush_list
local flush_node = nuts.flush_node
local copy_node_list = nuts.copy_list
@@ -136,7 +136,7 @@ actions[v_line] = function(head,setting)
local linebreaks = { }
local function set(head)
- for g in traverse_id(glyph_code,head) do
+ for g in nextglyph, head do
if dynamic > 0 then
setattr(g,0,dynamic)
end
@@ -146,7 +146,7 @@ actions[v_line] = function(head,setting)
set(temp)
- for g in traverse_id(disc_code,temp) do
+ for g in nextdisc, temp do
local pre, post, replace = getdisc(g)
if pre then
set(pre)
@@ -173,14 +173,12 @@ actions[v_line] = function(head,setting)
local function list_dimensions(list,start)
local temp = copy_node_list(list,start)
- temp = tonode(temp)
temp = nodes.handlers.characters(temp)
temp = nodes.injections.handler(temp)
-- temp = typesetters.fontkerns.handler(temp) -- maybe when enabled
- -- nodes.handlers.protectglyphs(temp) -- not needed as we discard
+ -- nodes.handlers.protectglyphs(temp) -- not needed as we discard
-- temp = typesetters.spacings.handler(temp) -- maybe when enabled
-- temp = typesetters.kerns.handler(temp) -- maybe when enabled
- temp = tonut(temp)
temp = hpack_node_list(temp)
local width = getwidth(temp)
flush_node_list(temp)
@@ -264,7 +262,7 @@ actions[v_line] = function(head,setting)
if linebreak == n then
local p, n = getboth(start)
if pre then
- for current in traverse_id(glyph_code,pre) do
+ for current in nextglyph, pre do
update(current)
end
setlink(pretail,n)
@@ -284,7 +282,7 @@ actions[v_line] = function(head,setting)
else
local p, n = getboth(start)
if replace then
- for current in traverse_id(glyph_code,replace) do
+ for current in nextglyph, replace do
update(current)
end
setlink(replacetail,n)
@@ -314,7 +312,7 @@ actions[v_line] = function(head,setting)
end
end
- return head, true
+ return head
end
actions[v_word] = function(head,setting)
@@ -359,13 +357,12 @@ actions[v_word] = function(head,setting)
end
start = getnext(start)
end
- return head, true
+ return head
end
actions[v_default] = actions[v_line]
function firstlines.handler(head)
- head = tonut(head)
local start = head
local attr = nil
while start do
@@ -388,11 +385,10 @@ function firstlines.handler(head)
if trace_firstlines then
report_firstlines("processing firstlines, alternative %a",alternative)
end
- local head, done = action(head,settings)
- return tonode(head), done
+ return action(head,settings)
end
end
- return tonode(head), false
+ return head
end
-- goodie
@@ -401,7 +397,7 @@ local function applytofirstcharacter(box,what)
local tbox = getbox(box) -- assumes hlist
local list = getlist(tbox)
local done = nil
- for n in traverse_id(glyph_code,list) do
+ for n in nextglyph, list do
list = remove_node(list,n)
done = n
break
diff --git a/tex/context/base/mkiv/typo-itc.lua b/tex/context/base/mkiv/typo-itc.lua
index 328bf1406..b85a2847e 100644
--- a/tex/context/base/mkiv/typo-itc.lua
+++ b/tex/context/base/mkiv/typo-itc.lua
@@ -29,9 +29,6 @@ local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
local nodepool = nuts.pool
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
local getprev = nuts.getprev
local getnext = nuts.getnext
local getid = nuts.getid
@@ -177,7 +174,7 @@ local textokay = false
local enablemath = false
local enabletext = false
-local function domath(head,current, done)
+local function domath(head,current)
current = end_of_math(current)
local next = getnext(current)
if next then
@@ -212,7 +209,6 @@ local function domath(head,current, done)
report_italics("%s italic between math %C and punctuation %C","removing",i,c,char)
end
setkern(kern,0) -- or maybe a small value or half the ic
- done = true
end
elseif i == 0 then
local d = chardata[f][c]
@@ -226,7 +222,6 @@ local function domath(head,current, done)
if trace_italics then
report_italics("%s italic %p between math %C and punctuation %C","setting",i,c,char)
end
- done = true
end
elseif trace_italics then
report_italics("%s italic %p between math %C and punctuation %C","keeping",k,c,char)
@@ -251,34 +246,31 @@ local function domath(head,current, done)
report_italics("%s italic %p between math %C and non punctuation %C","adding",a,getchar(glyph),char)
end
insert_node_after(head,glyph,correction_kern(a,glyph))
- done = true
end
end
end
end
end
end
- return current, done
+ return current
end
local function mathhandler(head)
- local nuthead = tonut(head)
- local current = nuthead
- local done = false
+ local current = head
while current do
if getid(current) == math_code then
- current, done = domath(nuthead,current,done)
+ current = domath(head,current)
end
current = getnext(current)
end
- return head, done
+ return head
end
local function texthandler(head)
local prev = nil
local prevchar = nil
- local prevhead = tonut(head)
+ local prevhead = head
local previtalic = 0
local previnserted = nil
@@ -300,7 +292,6 @@ local function texthandler(head)
local replaceinserted = nil
local current = prevhead
- local done = false
local lastfont = nil
local lastattr = nil
@@ -313,7 +304,6 @@ local function texthandler(head)
if previtalic ~= 0 then
if okay(data,current,font,prevchar,previtalic,char,"glyph") then
insert_node_after(prevhead,prev,correction_kern(previtalic,current))
- done = true
end
elseif previnserted and data then
if trace_italics then
@@ -325,7 +315,6 @@ local function texthandler(head)
if replaceitalic ~= 0 then
if okay(data,replace,font,replacechar,replaceitalic,char,"replace") then
insert_node_after(replacehead,replace,correction_kern(replaceitalic,current))
- done = true
end
replaceitalic = 0
elseif replaceinserted and data then
@@ -338,7 +327,6 @@ local function texthandler(head)
if postitalic ~= 0 then
if okay(data,post,font,postchar,postitalic,char,"post") then
insert_node_after(posthead,post,correction_kern(postitalic,current))
- done = true
end
postitalic = 0
elseif postinserted and data then
@@ -479,7 +467,6 @@ local function texthandler(head)
end
previnserted = correction_glue(previtalic,current) -- maybe just add ? else problem with penalties
previtalic = 0
- done = true
insert_node_after(prevhead,prev,previnserted)
else
if replaceitalic ~= 0 then
@@ -488,7 +475,6 @@ local function texthandler(head)
end
replaceinserted = correction_kern(replaceitalic,current) -- needs to be a kern
replaceitalic = 0
- done = true
insert_node_after(replacehead,replace,replaceinserted)
end
if postitalic ~= 0 then
@@ -497,7 +483,6 @@ local function texthandler(head)
end
postinserted = correction_kern(postitalic,current) -- needs to be a kern
postitalic = 0
- done = true
insert_node_after(posthead,post,postinserted)
end
end
@@ -510,7 +495,7 @@ local function texthandler(head)
postinserted = nil
postitalic = 0
if mathokay then
- current, done = domath(head,current,done)
+ current = domath(head,current)
else
current = end_of_math(current)
end
@@ -526,7 +511,6 @@ local function texthandler(head)
replaceitalic = 0
postinserted = nil
postitalic = 0
- done = true
else
if replaceitalic ~= 0 then
if trace_italics then
@@ -539,7 +523,6 @@ local function texthandler(head)
replaceitalic = 0
postinserted = nil
postitalic = 0
- done = true
end
if postitalic ~= 0 then
if trace_italics then
@@ -552,7 +535,6 @@ local function texthandler(head)
replaceitalic = 0
postinserted = nil
postitalic = 0
- done = true
end
end
end
@@ -564,25 +546,22 @@ local function texthandler(head)
report_italics("inserting %p between %s italic %C and end of list",previtalic,"glyph",prevchar)
end
insert_node_after(prevhead,prev,correction_kern(previtalic,current))
- done = true
else
if replaceitalic ~= 0 then
if trace_italics then
report_italics("inserting %p between %s italic %C and end of list",replaceitalic,"replace",replacechar)
end
insert_node_after(replacehead,replace,correction_kern(replaceitalic,current))
- done = true
end
if postitalic ~= 0 then
if trace_italics then
report_italics("inserting %p between %s italic %C and end of list",postitalic,"post",postchar)
end
insert_node_after(posthead,post,correction_kern(postitalic,current))
- done = true
end
end
end
- return head, done
+ return head
end
function italics.handler(head)
diff --git a/tex/context/base/mkiv/typo-krn.lua b/tex/context/base/mkiv/typo-krn.lua
index 71d9736a4..5e4792f62 100644
--- a/tex/context/base/mkiv/typo-krn.lua
+++ b/tex/context/base/mkiv/typo-krn.lua
@@ -21,9 +21,6 @@ local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
local nodepool = nuts.pool
-local tonode = nuts.tonode
-local tonut = nuts.tonut
-
-- check what is used
local find_node_tail = nuts.tail
@@ -364,9 +361,7 @@ local function closest_bound(b,get)
end
function kerns.handler(head)
- local head = tonut(head)
local start = head
- local done = false
local lastfont = nil
local keepligature = kerns.keepligature
local keeptogether = kerns.keeptogether
@@ -418,7 +413,6 @@ function kerns.handler(head)
if inject then
-- not yet ok, as injected kerns can be overlays (from node-inj.lua)
setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code)
- done = true
end
end
elseif previd == glyph_code then
@@ -430,11 +424,9 @@ function kerns.handler(head)
local kerns = data and data.kerns
local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn
insert_node_before(head,start,kern_injector(fillup,kern))
- done = true
end
else
insert_node_before(head,start,kern_injector(fillup,quaddata[font]*krn))
- done = true
end
end
prev = start
@@ -514,7 +506,6 @@ function kerns.handler(head)
end
if indeed then
setdisc(start,pre,post,replace)
- done = true
end
bound = false
elseif id == kern_code then
@@ -536,7 +527,6 @@ function kerns.handler(head)
-- shrink_order = 1 ?
end
setglue(start,w,stretch,shrink,stretch_order,shrink_order)
- done = true
end
end
bound = false
@@ -547,12 +537,10 @@ function kerns.handler(head)
local b, f = closest_bound(start,getprev)
if b then
insert_node_before(head,start,kern_injector(fillup,quaddata[f]*krn))
- done = true
end
local b, f = closest_bound(start,getnext)
if b then
insert_node_after(head,start,kern_injector(fillup,quaddata[f]*krn))
- done = true
end
end
bound = false
@@ -573,7 +561,7 @@ function kerns.handler(head)
start = getnext(start)
end
end
- return tonode(head), done
+ return head
end
local enabled = false
diff --git a/tex/context/base/mkiv/typo-lin.lua b/tex/context/base/mkiv/typo-lin.lua
index ebf748a82..9d7ee359e 100644
--- a/tex/context/base/mkiv/typo-lin.lua
+++ b/tex/context/base/mkiv/typo-lin.lua
@@ -73,7 +73,7 @@ local parfillskip_code = gluecodes.parfillskip
local tonut = nodes.tonut
local tonode = nodes.tonode
-local traverse_id = nuts.traverse_id
+local nexthlist = nuts.traversers.hlist
local insert_before = nuts.insert_before
local insert_after = nuts.insert_after
local find_tail = nuts.tail
@@ -252,7 +252,7 @@ function paragraphs.normalize(head,islocal)
if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then
local last = nil -- a nut
local done = false
- for line in traverse_id(hlist_code,tonut(head)) do
+ for line in nexthlist, head do -- LUATEXVERSION >= 1.090
if getsubtype(line) == line_code and not getprop(line,"line") then
if done then
last = line
@@ -280,7 +280,7 @@ function paragraphs.normalize(head,islocal)
end
end
-- normalizer
- for line in traverse_id(hlist_code,tonut(head)) do
+ for line in nexthlist, head do -- LUATEXVERSION >= 1.090
if getsubtype(line) == line_code and not getprop(line,"line") then
normalize(line)
if done then
diff --git a/tex/context/base/mkiv/typo-mar.lua b/tex/context/base/mkiv/typo-mar.lua
index bc9c408c1..813993a99 100644
--- a/tex/context/base/mkiv/typo-mar.lua
+++ b/tex/context/base/mkiv/typo-mar.lua
@@ -62,7 +62,6 @@ local nuts = nodes.nuts
local nodepool = nuts.pool
local tonode = nuts.tonode
-local tonut = nuts.tonut
local hpack_nodes = nuts.hpack
local traverse_id = nuts.traverse_id
@@ -113,7 +112,7 @@ local texgetcount = tex.getcount
local texget = tex.get
local isleftpage = layouts.status.isleftpage
-local registertogether = builders.paragraphs.registertogether -- tonode
+local registertogether = builders.paragraphs.registertogether
local paragraphs = typesetters.paragraphs
local addtoline = paragraphs.addtoline
@@ -812,9 +811,8 @@ local function handler(scope,head,group)
if trace_margindata then
report_margindata("flushing stage one, stored %s, scope %s, delayed %s, group %a",nofstored,scope,nofdelayed,group)
end
- head = tonut(head)
local current = head
- local done = false
+ local done = false -- for tracing only
while current do
local id = getid(current)
if (id == vlist_code or id == hlist_code) and getprop(current,"margindata") == nil then
@@ -839,11 +837,9 @@ local function handler(scope,head,group)
report_margindata("flushing stage one, nothing done, %s left",nofstored)
end
end
-resetstacked()
- return tonode(head), done
- else
- return head, false
+ resetstacked()
end
+ return head
end
local trialtypesetting = context.trialtypesetting
@@ -854,7 +850,7 @@ local trialtypesetting = context.trialtypesetting
function margins.localhandler(head,group) -- sometimes group is "" which is weird
if trialtypesetting() then
- return head, false
+ return head
end
local inhibit = conditionals.inhibitmargindata
@@ -862,15 +858,15 @@ function margins.localhandler(head,group) -- sometimes group is "" which is weir
if trace_margingroup then
report_margindata("ignored 3, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
end
- return head, false
- elseif nofstored > 0 then
+ return head
+ end
+ if nofstored > 0 then
return handler(v_local,head,group)
- else
- if trace_margingroup then
- report_margindata("ignored 4, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
- end
- return head, false
end
+ if trace_margingroup then
+ report_margindata("ignored 4, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
+ end
+ return head
end
function margins.globalhandler(head,group) -- check group
@@ -884,7 +880,7 @@ function margins.globalhandler(head,group) -- check group
if trace_margingroup then
report_margindata("ignored 1, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
end
- return head, false
+ return head
elseif group == "hmode_par" then
return handler(v_global,head,group)
elseif group == "vmode_par" then -- experiment (for alignments)
@@ -899,22 +895,20 @@ function margins.globalhandler(head,group) -- check group
if trace_margingroup then
report_margindata("ignored 2, group %a, stored %s, inhibit %a",group,nofstored,inhibit)
end
- return head, false
+ return head
end
end
local function finalhandler(head)
if nofdelayed > 0 then
local current = head
- local done = false
- while current and nofdelayed > 0 do
+ while current and nofdelayed > 0 do -- traverse_list
local id = getid(current)
if id == hlist_code then -- only lines?
local a = getprop(current,"margindata")
if not a then
finalhandler(getlist(current))
elseif realigned(current,a) then
- done = true
if nofdelayed == 0 then
return head, true
end
@@ -924,10 +918,8 @@ local function finalhandler(head)
end
current = getnext(current)
end
- return head, done
- else
- return head, false
end
+ return head
end
function margins.finalhandler(head)
@@ -935,16 +927,12 @@ function margins.finalhandler(head)
if trace_margindata then
report_margindata("flushing stage two, instore: %s, delayed: %s",nofstored,nofdelayed)
end
- head = tonut(head)
- local head, done = finalhandler(head)
--- resetstacked(true)
-resetstacked(nofdelayed==0)
- head = tonode(head)
- return head, done
+ head = finalhandler(head)
+ resetstacked(nofdelayed==0)
else
resetstacked()
- return head, false
end
+ return head
end
-- Somehow the vbox builder (in combinations) gets pretty confused and decides to
diff --git a/tex/context/base/mkiv/typo-pag.lua b/tex/context/base/mkiv/typo-pag.lua
index b5759a097..05513e20c 100644
--- a/tex/context/base/mkiv/typo-pag.lua
+++ b/tex/context/base/mkiv/typo-pag.lua
@@ -26,7 +26,6 @@ local unsetvalue = attributes.unsetvalue
local a_keeptogether = attributes.private("keeptogether")
local nuts = nodes.nuts
-local tonut = nuts.tonut
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -187,8 +186,8 @@ end
-- also look at first non glue/kern node e.g for a dropped caps
function parbuilders.keeptogether(head)
- local done = false
- local current = tonut(head)
+ local done = false
+ local current = head
while current do
if getid(current) == hlist_code then
local a = takeattr(current,a_keeptogether)
diff --git a/tex/context/base/mkiv/typo-pnc.lua b/tex/context/base/mkiv/typo-pnc.lua
index 1ed8d9940..1ffff991f 100644
--- a/tex/context/base/mkiv/typo-pnc.lua
+++ b/tex/context/base/mkiv/typo-pnc.lua
@@ -9,7 +9,6 @@ if not modules then modules = { } end modules ['typo-pnc'] = {
local nodes = nodes
local fonts = fonts
-local prependaction = nodes.tasks.prependaction
local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
@@ -23,7 +22,8 @@ local spaceskip_code = gluecodes.spaceskip
local new_kern = nuts.pool.kern
local insert_after = nuts.insert_after
-local traverse_id = nuts.traverse_id
+
+local nextglyph = nuts.traversers.glyph
local getchar = nuts.getchar
local getfont = nuts.getfont
@@ -68,9 +68,7 @@ local mapping = periodkerns.mapping
local factors = periodkerns.factors
function periodkerns.handler(head)
- local done = false
- local hnut = tonut(head)
- for current in traverse_id(glyph_code,tonut(hnut)) do
+ for current in nextglyph, head do
if getchar(current) == period then
local a = getattr(current,a_periodkern)
if a then
@@ -91,11 +89,10 @@ function periodkerns.handler(head)
if factor ~= 0 then
fontspace = parameters[getfont(current)].space -- can be sped up
inserted = factor * fontspace
- insert_after(hnut,current,new_kern(inserted))
+ insert_after(head,current,new_kern(inserted))
if trace then
report("inserting space at %C . [%p] %C .",pchar,inserted,nchar)
end
- done = true
end
local next3 = getnext(next2)
if next3 and getid(next3) == glue_code and getsubtype(next3) == spaceskip_code then
@@ -115,7 +112,6 @@ function periodkerns.handler(head)
end
end
setwidth(next3,space)
- done = true
else
if trace then
if inserted then
@@ -136,7 +132,80 @@ function periodkerns.handler(head)
end
end
end
- return head, done
+ return head
+end
+
+if LUATEXVERSION >= 1.090 then
+
+ function periodkerns.handler(head)
+ for current, font, char in nextglyph, head do
+ if char == period then
+ local a = getattr(current,a_periodkern)
+ if a then
+ local factor = mapping[a]
+ if factor then
+ local prev, next = getboth(current)
+ if prev and next and getid(prev) == glyph_code and getid(next) == glyph_code then
+ local pchar = getchar(prev)
+ local pcode = categories[getchar(prev)]
+ if pcode == "lu" or pcode == "ll" then
+ local nchar = getchar(next)
+ local ncode = categories[getchar(next)]
+ if ncode == "lu" or ncode == "ll" then
+ local next2 = getnext(next)
+ if next2 and getid(next2) == glyph_code and getchar(next2) == period then
+ -- A.B.
+ local fontspace, inserted
+ if factor ~= 0 then
+ fontspace = parameters[getfont(current)].space -- can be sped up
+ inserted = factor * fontspace
+ insert_after(head,current,new_kern(inserted))
+ if trace then
+ report("inserting space at %C . [%p] %C .",pchar,inserted,nchar)
+ end
+ end
+ local next3 = getnext(next2)
+ if next3 and getid(next3) == glue_code and getsubtype(next3) == spaceskip_code then
+ local width = getwidth(next3)
+ local space = fontspace or parameters[getfont(current)].space -- can be sped up
+ if width > space then -- space + extraspace
+ local next4 = getnext(next3)
+ if next4 and getid(next4) == glyph_code then
+ local fchar = getchar(next4)
+ if categories[fchar] ~= "lu" then
+ -- A.B.<glue>X
+ if trace then
+ if inserted then
+ report("reverting space at %C . [%p] %C . [%p->%p] %C",pchar,inserted,nchar,width,space,fchar)
+ else
+ report("reverting space at %C . %C . [%p->%p] %C",pchar,nchar,width,space,fchar)
+ end
+ end
+ setwidth(next3,space)
+ else
+ if trace then
+ if inserted then
+ report("keeping space at %C . [%p] %C . [%p] %C",pchar,inserted,nchar,width,fchar)
+ else
+ report("keeping space at %C . %C . [%p] %C",pchar,nchar,width,fchar)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return head
+ end
+
+
end
local enabled = false
@@ -144,7 +213,6 @@ local enabled = false
function periodkerns.set(factor)
factor = tonumber(factor) or 0
if not enabled then
- prependaction("processors","normalizers","typesetters.periodkerns.handler")
enableaction("processors","typesetters.periodkerns.handler")
enabled = true
end
diff --git a/tex/context/base/mkiv/typo-rep.lua b/tex/context/base/mkiv/typo-rep.lua
index b6aae0cae..d29eb17b8 100644
--- a/tex/context/base/mkiv/typo-rep.lua
+++ b/tex/context/base/mkiv/typo-rep.lua
@@ -21,8 +21,6 @@ local nodes = nodes
local enableaction = nodes.tasks.enableaction
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getchar = nuts.getchar
@@ -81,9 +79,8 @@ local function process(what,head,current,char)
return head, current
end
-function nodes.handlers.stripping(head)
- head = tonut(head)
- local current, done = head, false
+function nodes.handlers.stripping(head) -- use loop
+ local current = head
while current do
local char, id = isglyph(current)
if char then
@@ -93,7 +90,6 @@ function nodes.handlers.stripping(head)
local what = glyphs[char]
if what then
head, current = process(what,head,current,char)
- done = true
else -- handling of spacing etc has to be done elsewhere
current = getnext(current)
end
@@ -104,7 +100,7 @@ function nodes.handlers.stripping(head)
current = getnext(current)
end
end
- return tonode(head), done
+ return head
end
local enabled = false
diff --git a/tex/context/base/mkiv/typo-rub.lua b/tex/context/base/mkiv/typo-rub.lua
index 8c41a5611..f1f3f0403 100644
--- a/tex/context/base/mkiv/typo-rub.lua
+++ b/tex/context/base/mkiv/typo-rub.lua
@@ -33,8 +33,6 @@ local v_auto = variables.auto
local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
local getid = nuts.getid
local getsubtype = nuts.getsubtype
local getattr = nuts.getattr
@@ -53,7 +51,9 @@ local setwidth = nuts.setwidth
local hpack = nuts.hpack
local insert_after = nuts.insert_after
local takebox = nuts.takebox
-local traverse_id = nuts.traverse_id
+
+local nexthlist = nuts.traversers.hlist
+local nextvlist = nuts.traversers.vlist
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
@@ -194,7 +194,6 @@ do
end
function rubies.check(head)
- local head = tonut(head)
local current = head
local start = nil
local stop = nil
@@ -260,7 +259,7 @@ function rubies.check(head)
if found then
flush("flush 5")
end
- return tonode(head), true
+ return head, true
end
local attach
@@ -371,20 +370,17 @@ local function whatever(current)
end
end
-attach = function(head)
- for current in traverse_id(hlist_code,head) do
+attach = function(head) -- traverse_list
+ for current in nexthlist, head do
whatever(current)
end
- for current in traverse_id(vlist_code,head) do
+ for current in nextvlist, head do
whatever(current)
end
- return head, true
+ return head
end
-function rubies.attach(head)
- local h, d = attach(tonut(head))
- return tonode(h), d
-end
+rubies.attach = attach
-- for now there is no need to be compact
diff --git a/tex/context/base/mkiv/typo-spa.lua b/tex/context/base/mkiv/typo-spa.lua
index bda139719..c49897f87 100644
--- a/tex/context/base/mkiv/typo-spa.lua
+++ b/tex/context/base/mkiv/typo-spa.lua
@@ -23,8 +23,6 @@ local unsetvalue = attributes.unsetvalue
local v_reset = interfaces.variables.reset
local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -73,8 +71,6 @@ end
-- todo cache lastattr
function spacings.handler(head)
- head = tonut(head)
- local done = false
local start = head
-- head is always begin of par (whatsit), so we have at least two prev nodes
-- penalty followed by glue
@@ -122,7 +118,6 @@ function spacings.handler(head)
end
insert_node_before(head,start,new_penalty(10000))
insert_node_before(head,start,new_glue(left*quad))
- done = true
end
end
local next = getnext(start)
@@ -159,7 +154,6 @@ function spacings.handler(head)
end
insert_node_after(head,start,new_glue(right*quad))
insert_node_after(head,start,new_penalty(10000))
- done = true
end
end
end
@@ -172,7 +166,7 @@ function spacings.handler(head)
start = getnext(start)
end
end
- return tonode(head), done
+ return head
end
local enabled = false
diff --git a/tex/context/base/mkiv/typo-sus.lua b/tex/context/base/mkiv/typo-sus.lua
index 2d3037bdc..6c02b9291 100644
--- a/tex/context/base/mkiv/typo-sus.lua
+++ b/tex/context/base/mkiv/typo-sus.lua
@@ -40,8 +40,6 @@ local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
local getid = nuts.getid
local getprev = nuts.getprev
@@ -164,7 +162,6 @@ local colors = {
local found = 0
function typesetters.marksuspects(head)
- local head = tonut(head)
local current = head
local lastdone = nil
while current do
@@ -254,7 +251,7 @@ function typesetters.marksuspects(head)
current = getnext(current)
end
end
- return tonode(head), found > 0
+ return head
end
local function showsuspects(head)
@@ -289,9 +286,9 @@ end
function typesetters.showsuspects(head)
if found > 0 then
- return tonode(showsuspects(tonut(head))), true
+ return showsuspects(head)
else
- return head, false
+ return head
end
end
diff --git a/tex/context/base/mkiv/typo-tal.lua b/tex/context/base/mkiv/typo-tal.lua
index 870d006cc..413c249fa 100644
--- a/tex/context/base/mkiv/typo-tal.lua
+++ b/tex/context/base/mkiv/typo-tal.lua
@@ -34,7 +34,6 @@ local v_number = variables.number
local nuts = nodes.nuts
local tonut = nuts.tonut
-local tonode = nuts.tonode
local getnext = nuts.getnext
local getprev = nuts.getprev
@@ -50,7 +49,7 @@ local setchar = nuts.setchar
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
-local traverse_list_by_id = nuts.traverse_id
+local nextglyph = nuts.traversers.glyph
local list_dimensions = nuts.dimensions
local first_glyph = nuts.first_glyph
@@ -171,23 +170,22 @@ local function traced_kern(w)
return tracedrule(w,nil,nil,"darkgray")
end
-function characteralign.handler(originalhead,where)
+function characteralign.handler(head,where)
if not datasets then
- return originalhead, false
+ return head
end
- local head = tonut(originalhead)
-- local first = first_glyph(head) -- we could do that once
local first
- for n in traverse_list_by_id(glyph_code,head) do
+ for n in nextglyph, head do
first = n
break
end
if not first then
- return originalhead, false
+ return head
end
local a = getattr(first,a_characteralign)
if not a or a == 0 then
- return originalhead, false
+ return head
end
local column = div(a,0xFFFF)
local row = a % 0xFFFF
@@ -336,7 +334,7 @@ function characteralign.handler(originalhead,where)
before = before,
after = after,
}
- return tonode(head), true
+ return head, true
end
if not dataset.collected then
-- print("[maxbefore] [maxafter]")
@@ -404,5 +402,5 @@ function characteralign.handler(originalhead,where)
insert_node_after(head,c,new_kern(maxafter))
end
end
- return tonode(head), true
+ return head
end
diff --git a/tex/context/base/mkiv/typo-wrp.lua b/tex/context/base/mkiv/typo-wrp.lua
index 07e34cd6c..13bb5a0cc 100644
--- a/tex/context/base/mkiv/typo-wrp.lua
+++ b/tex/context/base/mkiv/typo-wrp.lua
@@ -16,8 +16,6 @@ local parfill_skip_code = nodes.gluecodes.parfillskip
local user_penalty_code = nodes.penaltycodes.userpenalty
local nuts = nodes.nuts
-local tonut = nodes.tonut
-local tonode = nodes.tonode
local find_node_tail = nuts.tail
local getprev = nuts.getprev
@@ -51,22 +49,20 @@ local function remove_dangling_crlf(head,tail)
report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno)
end
remove(head,tail,true)
- return head, tail, true
+ return head, tail
end
end
end
end
- return head, tail, false
+ return head, tail
end
function wrappers.handler(head)
- local head = tonut(head)
if head then
local tail = find_node_tail(head)
- local done = false
- head, tail, done = remove_dangling_crlf(head,tail) -- will be action chain
+ head, tail = remove_dangling_crlf(head,tail) -- will be action chain
end
- return head, true
+ return head
end
interfaces.implement {
diff --git a/tex/context/base/mkiv/util-seq.lua b/tex/context/base/mkiv/util-seq.lua
index ec6ed2ceb..08f762b6a 100644
--- a/tex/context/base/mkiv/util-seq.lua
+++ b/tex/context/base/mkiv/util-seq.lua
@@ -27,6 +27,15 @@ local allocate = utilities.storage.allocate
local formatters = string.formatters
local replacer = utilities.templates.replacer
+local trace_used = false
+local trace_detail = false
+local report = logs.reporter("sequencer")
+local usedcount = 0
+local usednames = { }
+
+trackers.register("sequencers.used", function(v) trace_used = true end)
+trackers.register("sequencers.detail",function(v) trace_detail = true end)
+
local sequencers = { }
utilities.sequencers = sequencers
@@ -38,6 +47,8 @@ local replacevalue = tables.replacevalue
local insertaftervalue = tables.insertaftervalue
local insertbeforevalue = tables.insertbeforevalue
+local usedsequences = { }
+
local function validaction(action)
if type(action) == "string" then
local g = _G
@@ -211,9 +222,19 @@ local function localize(str)
end
local function construct(t)
- local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip
- local arguments, returnvalues, results = t.arguments or "...", t.returnvalues, t.results
- local variables, calls, n = { }, { }, 0
+ local list = t.list
+ local order = t.order
+ local kind = t.kind
+ local gskip = t.gskip
+ local askip = t.askip
+ local name = t.name or "?"
+ local arguments = t.arguments or "..."
+ local returnvalues = t.returnvalues
+ local results = t.results
+ local variables = { }
+ local calls = { }
+ local n = 0
+ usedcount = usedcount + 1
for i=1,#order do
local group = order[i]
if not gskip[group] then
@@ -221,6 +242,11 @@ local function construct(t)
for i=1,#actions do
local action = actions[i]
if not askip[action] then
+ if trace_used then
+ local action = tostring(action)
+ report("%02i: category %a, group %a, action %a",usedcount,name,group,action)
+ usednames[action] = true
+ end
local localized
if type(action) == "function" then
local name = localize(tostring(action))
@@ -261,17 +287,16 @@ end
sequencers.tostring = construct
sequencers.localize = localize
-compile = function(t,compiler,n) -- already referred to in sequencers.new
+compile = function(t,compiler,...) -- already referred to in sequencers.new
local compiled
if not t or type(t) == "string" then
- -- weird ... t.compiled = t .. so
return false
end
if compiler then
- compiled = compiler(t,n)
+ compiled = compiler(t,...)
t.compiled = compiled
else
- compiled = construct(t,n)
+ compiled = construct(t,...)
end
local runner
if compiled == "" then
@@ -285,114 +310,46 @@ end
sequencers.compile = compile
--- we used to deal with tail as well but now that the lists are always
--- double linked and the kernel function no longer expect tail as
--- argument we stick to head and done (done can probably also go
--- as luatex deals with return values efficiently now .. in the
--- past there was some copying involved, but no longer)
-
--- todo: use sequencer (can have arguments and returnvalues etc now)
-
-local template_yes_state = [[
-%s
-return function(head%s)
- local ok, done = false, false
-%s
- return head, done
-end]]
-
-local template_yes_nostate = [[
-%s
-return function(head%s)
-%s
- return head, true
-end]]
-
-local template_nop = [[
-return function()
- return false, false
-end]]
-
-local function nodeprocessor(t,nofarguments) -- todo: handle 'kind' in plug into tostring
- local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip
- local nostate = t.nostate
- local vars, calls, args, n = { }, { }, nil, 0
- if nofarguments == 0 then
- args = ""
- elseif nofarguments == 1 then
- args = ",one"
- elseif nofarguments == 2 then
- args = ",one,two"
- elseif nofarguments == 3 then -- from here on probably slower than ...
- args = ",one,two,three"
- elseif nofarguments == 4 then
- args = ",one,two,three,four"
- elseif nofarguments == 5 then
- args = ",one,two,three,four,five"
- else
- args = ",..."
- end
- for i=1,#order do
- local group = order[i]
- if not gskip[group] then
- local actions = list[group]
- for i=1,#actions do
- local action = actions[i]
- if not askip[action] then
- local localized = localize(action)
- n = n + 1
- vars[n] = formatters["local %s = %s"](localized,action)
- -- only difference with tostring is kind and rets (why no return)
- if nostate then
- if kind[action] == "nohead" then
- calls[n] = formatters[" %s(head%s)"](localized,args)
- else
- calls[n] = formatters[" head = %s(head%s)"](localized,args)
- end
- else
- if kind[action] == "nohead" then
- calls[n] = formatters[" ok = %s(head%s) if ok then done = true end"](localized,args)
- else
- calls[n] = formatters[" head, ok = %s(head%s) if ok then done = true end"](localized,args)
- end
- end
- end
- end
- end
- end
- local processor = #calls > 0 and formatters[nostate and template_yes_nostate or template_yes_state](concat(vars,"\n"),args,concat(calls,"\n")) or template_nop
- -- print(processor)
- return processor
-end
-
function sequencers.nodeprocessor(t,nofarguments)
- local kind = type(nofarguments)
- if kind == "number" then
- return nodeprocessor(t,nofarguments)
- elseif kind ~= "table" then
- return
- end
--
local templates = nofarguments
- local process = templates.process
- local step = templates.step
--
- if not process or not step then
+ if type(templates) ~= "table" then
+ return ""
+ end
+ --
+ local replacers = { }
+ for k, v in next, templates do
+ replacers[k] = replacer(v)
+ end
+ --
+ local construct = replacers.process
+ local step = replacers.step
+ if not construct or not step then
return ""
end
--
- local construct = replacer(process)
- local newaction = replacer(step)
local calls = { }
local aliases = { }
- local n = 0
+ local ncalls = 0
+ local naliases = 0
+ local f_alias = formatters["local %s = %s"]
--
local list = t.list
local order = t.order
local kind = t.kind
local gskip = t.gskip
local askip = t.askip
+ local name = t.name or "?"
+ local steps = 0
+ usedcount = usedcount + 1
--
+ if trace_detail then
+ naliases = naliases + 1
+ aliases[naliases] = formatters["local report = logs.reporter('sequencer',%q)"](name)
+ ncalls = ncalls + 1
+ calls[ncalls] = [[report("start")]]
+ end
for i=1,#order do
local group = order[i]
if not gskip[group] then
@@ -400,20 +357,48 @@ function sequencers.nodeprocessor(t,nofarguments)
for i=1,#actions do
local action = actions[i]
if not askip[action] then
+ steps = steps + 1
+ if trace_used or trace_detail then
+ local action = tostring(action)
+ report("%02i: category %a, group %a, action %a",usedcount,name,group,action)
+ usednames[action] = true
+ end
+ if trace_detail then
+ ncalls = ncalls + 1
+ calls[ncalls] = formatters[ [[report(" step %a, action %a")]] ](steps,tostring(action))
+ end
local localized = localize(action)
- n = n + 1
- aliases[n] = formatters["local %s = %s"](localized,action)
- calls[n] = newaction { action = localized }
+ local onestep = replacers[kind[action]] or step
+ naliases = naliases + 1
+ ncalls = ncalls + 1
+ aliases[naliases] = f_alias(localized,action)
+ calls [ncalls] = onestep { action = localized }
end
end
end
end
- if n == 0 then
- return templates.default or construct { }
+ local processor
+ if steps == 0 then
+ processor = templates.default or construct { }
+ else
+ if trace_detail then
+ ncalls = ncalls + 1
+ calls[ncalls] = [[report("stop")]]
+ end
+ processor = construct {
+ localize = concat(aliases,"\n"),
+ actions = concat(calls,"\n"),
+ }
end
- local processor = construct {
- localize = concat(aliases,"\n"),
- actions = concat(calls,"\n"),
- }
+
+ -- processor = "print('running : " .. (t.name or "?") .. "')\n" .. processor
+ -- print(processor)
+
return processor
end
+
+statistics.register("used sequences",function()
+ if next(usednames) then
+ return table.concat(table.sortedkeys(usednames)," ")
+ end
+end)
diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua
index 56c5b011c..42f126687 100644
--- a/tex/context/base/mkiv/util-str.lua
+++ b/tex/context/base/mkiv/util-str.lua
@@ -869,7 +869,12 @@ local format_L = function()
return format("(a%s and 'TRUE' or 'FALSE')",n)
end
-local format_N = function() -- strips leading zeros
+local format_n = function() -- strips leading and trailing zeros and removes .0
+ n = n + 1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+end
+
+local format_N = function() -- strips leading and trailing zeros (also accepst string)
n = n + 1
return format("tostring(tonumber(a%s) or a%s)",n,n)
end
@@ -999,6 +1004,7 @@ local builder = Cs { "start",
+ V("C")
+ V("S") -- new
+ V("Q") -- new
+ + V("n") -- new
+ V("N") -- new
+ V("k") -- new
--
@@ -1042,7 +1048,8 @@ local builder = Cs { "start",
--
["S"] = (prefix_any * P("S")) / format_S, -- %S => %s (tostring)
["Q"] = (prefix_any * P("Q")) / format_Q, -- %Q => %q (tostring)
- ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading zeros)
+ ["n"] = (prefix_any * P("n")) / format_n, -- %n => tonumber (strips leading and trailing zeros, as well as .0, expects number)
+ ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading and trailing zeros, also takes string)
["k"] = (prefix_sub * P("k")) / format_k, -- %k => like f but with n.m
["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular)
["C"] = (prefix_any * P("C")) / format_C, -- %c => U+.... utf character
diff --git a/tex/context/interface/mkiv/context-en.xml b/tex/context/interface/mkiv/context-en.xml
index 67d229f4e..1d66d20df 100644
--- a/tex/context/interface/mkiv/context-en.xml
+++ b/tex/context/interface/mkiv/context-en.xml
@@ -22423,6 +22423,9 @@
<cd:parameter name="method">
<cd:constant type="auto"/>
</cd:parameter>
+ <cd:parameter name="size">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
<cd:parameter name="factor">
<cd:constant type="none"/>
<cd:constant type="auto"/>
@@ -33091,6 +33094,12 @@
<cd:parameter name="pagecolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="pageleft">
+ <cd:resolve name="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="pageright">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
<cd:parameter name="n">
<cd:constant type="cd:number"/>
</cd:parameter>
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 30f792944..38ba5c02c 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-mathfence.xml b/tex/context/interface/mkiv/i-mathfence.xml
index 76151fae4..5e1abec2b 100644
--- a/tex/context/interface/mkiv/i-mathfence.xml
+++ b/tex/context/interface/mkiv/i-mathfence.xml
@@ -43,6 +43,9 @@
<cd:parameter name="method">
<cd:constant type="auto"/>
</cd:parameter>
+ <cd:parameter name="size">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
<cd:parameter name="factor">
<cd:constant type="none"/>
<cd:constant type="auto"/>
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index d0e8abe4a..d776f503d 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-register.xml b/tex/context/interface/mkiv/i-register.xml
index 4d8010559..66570dd3b 100644
--- a/tex/context/interface/mkiv/i-register.xml
+++ b/tex/context/interface/mkiv/i-register.xml
@@ -162,6 +162,12 @@
<cd:parameter name="pagecolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="pageleft">
+ <cd:resolve name="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="pageright">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
<cd:parameter name="n">
<cd:constant type="cd:number"/>
</cd:parameter>
@@ -544,7 +550,7 @@
</cd:keywords>
<cd:index list="yes"/>
</cd:arguments>
- </cd:command>
+ </cd:command>
<cd:command name="stopregister" level="document" category="structure" file="strc-reg.mkiv">
<cd:arguments>
@@ -664,4 +670,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
diff --git a/tex/context/modules/mkiv/m-scite.mkiv b/tex/context/modules/mkiv/m-scite.mkiv
index 48f1022ad..92a498b37 100644
--- a/tex/context/modules/mkiv/m-scite.mkiv
+++ b/tex/context/modules/mkiv/m-scite.mkiv
@@ -332,6 +332,7 @@ visualizers.register("sql", visualizer)
{\scitespaceskip\interwordspace % \fontcharwd\font`0\relax % brrrrr
\let\slxb\gobbleoneargument
\let\slxe\space
+ \let\slxbreak\relax
\let\installscitecommandsinline\relax}
\unexpanded\def\installscitecommandsdisplay
@@ -342,10 +343,12 @@ visualizers.register("sql", visualizer)
\clf_sciteinstallcommands
-\installscitecommandsinline
+\let\slxb \gobbleoneargument
+\let\slxe \space
+\let\slxbreak\relax
-\let\slxS\buff_scite_slxs
-\let\slxF\buff_scite_slxf
+\let\slxS \buff_scite_slxs
+\let\slxF \buff_scite_slxf
\def\module_scite_inherit_typing
{\buff_verbatim_initialize_typing_one
diff --git a/tex/context/modules/mkiv/s-fonts-effects.mkiv b/tex/context/modules/mkiv/s-fonts-effects.mkiv
new file mode 100644
index 000000000..9b712938b
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-effects.mkiv
@@ -0,0 +1,59 @@
+%D \module
+%D [ file=s-fonts-basics, % was s-fnt-01,
+%D version=2006.10.10, % guess
+%D title=\CONTEXT\ Style File,
+%D subtitle=Listing Glyphs in Large Fonts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module is just a check for \type {luatex-basics-prepare}.
+
+\startmodule[fonts-effects]
+
+\startluacode
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.effects = moduledata.fonts.effects or { }
+
+function moduledata.fonts.effects.showfonteffect()
+ local effect = fonts.hashes.properties[true].effect
+ if effect then
+ local context = context
+ local BC, NC, EQ, NR = context.BC, context.NC, context.EQ, context.NR
+ context.starttabulate { "||||||||" }
+ BC() context("id") EQ() context(font.current())
+ BC() context("factor") EQ() context(effect.factor)
+ BC() context("wdelta") EQ() context(effect.wdelta)
+ NC() NR()
+ BC() context("effect") EQ() context(effect.effect)
+ BC() context("hfactor") EQ() context(effect.hfactor)
+ BC() context("hdelta") EQ() context(effect.hdelta)
+ NC() NR()
+ BC() context("width") EQ() context(effect.width)
+ BC() context("vfactor") EQ() context(effect.vfactor)
+ BC() context("ddelta") EQ() context(effect.ddelta)
+ NC() NR()
+ context.stoptabulate()
+ end
+end
+\stopluacode
+
+\installmodulecommandluasingle \showfonteffect {moduledata.fonts.effects.showfonteffect}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-effects.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \definedfont[Serif*default,boldened] An example.
+
+ \showfonteffect
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/s-fonts-shapes.lua b/tex/context/modules/mkiv/s-fonts-shapes.lua
index 748c5a92a..2c4cd445f 100644
--- a/tex/context/modules/mkiv/s-fonts-shapes.lua
+++ b/tex/context/modules/mkiv/s-fonts-shapes.lua
@@ -107,220 +107,177 @@ end
local descriptions = nil
local characters = nil
+
local function showglyphshape(specification)
- specification = interfaces.checkedspecification(specification)
- local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>")
- local tfmdata = fontdata[id]
- local charnum = tonumber(specification.character) or fonts.helpers.nametoslot(specification.character)
- local characters = tfmdata.characters
- local descriptions = tfmdata.descriptions
- local parameters = tfmdata.parameters
- local c = characters[charnum]
- local d = descriptions[charnum]
- if d then
- local factor = (parameters.size/parameters.units)*((7200/7227)/65536)
- local llx, lly, urx, ury = unpack(d.boundingbox)
- llx, lly, urx, ury = llx*factor, lly*factor, urx*factor, ury*factor
- local width, italic = (d.width or 0)*factor, (d.italic or 0)*factor
- local top_accent, bot_accent = (d.top_accent or 0)*factor, (d.bot_accent or 0)*factor
- local anchors, math = d.anchors, d.math
- context.start()
- context.dontleavehmode()
- context.obeyMPboxdepth()
- context.startMPcode()
- context("numeric lw ; lw := .125bp ;")
- context("pickup pencircle scaled lw ;")
- if width < 0.01 then
- -- catches zero width marks
- context('picture p ; p := textext.drt("\\hskip5sp\\getuvalue{%s}\\gray\\char%s"); draw p ;',cs,charnum)
- else
- context('picture p ; p := textext.drt("\\getuvalue{%s}\\gray\\char%s"); draw p ;',cs,charnum)
- end
- context('draw (%s,%s)--(%s,%s)--(%s,%s)--(%s,%s)--cycle withcolor green ;',llx,lly,urx,lly,urx,ury,llx,ury)
- context('draw (%s,%s)--(%s,%s) withcolor green ;',llx,0,urx,0)
- context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
- context("defaultscale := 0.05 ; ")
- -- inefficient but non critical
- local slant = {
- function(v,dx,dy,txt,xsign,ysign,loc,labloc)
- local n = #v
- if n > 0 then
- local l = { }
- for i=1,n do
- local c = v[i]
- local h = c.height or 0
- local k = c.kern or 0
- l[i] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy)
- end
- context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[1].kern*factor,lly,dx,dy,l[1])
--- context("draw laddered (%s) withcolor .5white ;",table.concat(l,".."))
- context("draw laddered (%..t) withcolor .5white ;",l)
- context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[#v].kern*factor,ury,dx,dy,l[#l])
- for i=1,n do
- context("draw %s withcolor blue withpen pencircle scaled 2lw ;",l[i])
- end
- end
- end,
- function(v,dx,dy,txt,xsign,ysign,loc,labloc)
- local n = #v
- if n > 0 then
- local l = { }
- for i=1,n do
- local c = v[i]
- local h = c.height or 0
- local k = c.kern or 0
- l[i] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy)
- end
- if loc == "top" then
- context('label.%s("\\type{%s}",%s shifted (0,-1bp)) ;',loc,txt,l[n])
- else
- context('label.%s("\\type{%s}",%s shifted (0,2bp)) ;',loc,txt,l[1])
- end
- for i=1,n do
- local c = v[i]
- local h = c.height or 0
- local k = c.kern or 0
- context('label.top("(%s,%s)",%s shifted (0,-2bp));',k,h,l[i])
+ --
+ local specification = interfaces.checkedspecification(specification)
+ local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>")
+ local tfmdata = fontdata[id]
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local parameters = tfmdata.parameters
+ local anchors = fonts.helpers.collectanchors(tfmdata)
+
+ local function showonecharacter(unicode)
+ local c = characters [unicode]
+ local d = descriptions[unicode]
+ if c and d then
+ local factor = (parameters.size/parameters.units)*((7200/7227)/65536)
+ local llx, lly, urx, ury = unpack(d.boundingbox)
+ llx, lly, urx, ury = llx*factor, lly*factor, urx*factor, ury*factor
+ local width = (d.width or 0)*factor
+ context.start()
+ context.dontleavehmode()
+ context.obeyMPboxdepth()
+ context.startMPcode()
+ context("numeric lw ; lw := .125bp ;")
+ context("pickup pencircle scaled lw ;")
+ if width < 0.01 then
+ -- catches zero width marks
+ context('picture p ; p := textext.drt("\\hskip5sp\\getuvalue{%s}\\gray\\char%s"); draw p ;',cs,unicode)
+ else
+ context('picture p ; p := textext.drt("\\getuvalue{%s}\\gray\\char%s"); draw p ;',cs,unicode)
+ end
+ context('draw (%s,%s)--(%s,%s)--(%s,%s)--(%s,%s)--cycle withcolor green ;',llx,lly,urx,lly,urx,ury,llx,ury)
+ context('draw (%s,%s)--(%s,%s) withcolor green ;',llx,0,urx,0)
+ context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
+ context("defaultscale := 0.05 ; ")
+ -- inefficient but non critical
+ local slant = {
+ function(v,dx,dy,txt,xsign,ysign,loc,labloc)
+ local n = #v
+ if n > 0 then
+ local l = { }
+ for i=1,n do
+ local c = v[i]
+ local h = c.height or 0
+ local k = c.kern or 0
+ l[i] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy)
+ end
+ context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[1].kern*factor,lly,dx,dy,l[1])
+ context("draw laddered (%..t) withcolor .5white ;",l)
+ context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[#v].kern*factor,ury,dx,dy,l[#l])
+ for i=1,n do
+ context("draw %s withcolor blue withpen pencircle scaled 2lw ;",l[i])
+ end
end
- end
- end,
- }
- if math then
- local kerns = math.kerns
- if kerns then
- for i=1,#slant do
- local s = slant[i]
- for k, v in next, kerns do
- if k == "topright" then
- s(v,width+italic,0,k,1,1,"top","ulft")
- elseif k == "bottomright" then
- s(v,width,0,k,1,1,"bot","lrt")
- elseif k == "topleft" then
- s(v,0,0,k,-1,1,"top","ulft")
- elseif k == "bottomleft" then
- s(v,0,0,k,-1,1,"bot","lrt")
+ end,
+ function(v,dx,dy,txt,xsign,ysign,loc,labloc)
+ local n = #v
+ if n > 0 then
+ local l = { }
+ for i=1,n do
+ local c = v[i]
+ local h = c.height or 0
+ local k = c.kern or 0
+ l[i] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy)
+ end
+ if loc == "top" then
+ context('label.%s("\\type{%s}",%s shifted (0,-1bp)) ;',loc,txt,l[n])
+ else
+ context('label.%s("\\type{%s}",%s shifted (0,2bp)) ;',loc,txt,l[1])
+ end
+ for i=1,n do
+ local c = v[i]
+ local h = c.height or 0
+ local k = c.kern or 0
+ context('label.top("(%s,%s)",%s shifted (0,-2bp));',k,h,l[i])
end
end
- end
- end
- end
- local function show(x,y,txt)
- local xx, yy = x*factor, y*factor
- context("draw (%s,%s) withcolor blue withpen pencircle scaled 2lw ;",xx,yy)
- context('label.top("\\type{%s}",(%s,%s-2bp)) ;',txt,xx,yy)
- context('label.bot("(%s,%s)",(%s,%s+2bp)) ;',x,y,xx,yy)
- end
- if anchors then
- local a = anchors.baselig
- if a then
- for k, v in next, a do
- for i=1,#v do
- local p = v[i]
- show(p[1],p[2],k .. ":" .. i)
+ end,
+ }
+ --
+ local math = d.math
+ if math then
+ local kerns = math.kerns
+ if kerns then
+ for i=1,#slant do
+ local s = slant[i]
+ for k, v in next, kerns do
+ if k == "topright" then
+ -- s(v,width+italic,0,k,1,1,"top","ulft")
+ s(v,width,0,k,1,1,"top","ulft")
+ elseif k == "bottomright" then
+ s(v,width,0,k,1,1,"bot","lrt")
+ elseif k == "topleft" then
+ s(v,0,0,k,-1,1,"top","ulft")
+ elseif k == "bottomleft" then
+ s(v,0,0,k,-1,1,"bot","lrt")
+ end
+ end
end
end
- end
- local a = anchors.mark
- if a then
- for k, v in next, a do
- show(v[1],v[2],k)
- end
- end
- local a = anchors.basechar
- if a then
- for k, v in next, a do
- show(v[1],v[2],k)
+ local accent = math.accent
+ if accent and accent ~= 0 then
+ local a = accent * factor
+ context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',a,ury,a,ury)
+ context('label.bot("\\type{%s}",(%s,%s+1bp));',"accent",a,ury)
+ context('label.top("%s",(%s,%s-1bp));',math.accent,a,ury)
end
end
- local ba = anchors.centry
- if a then
- for k, v in next, a do
- show(v[1],v[2],k)
+ --
+ local anchordata = anchors[unicode]
+ if anchordata then
+ local function show(txt,list)
+ if list then
+ for i=1,#list do
+ local li = list[i]
+ local x, y = li[1], li[2]
+ local xx, yy = x*factor, y*factor
+ context("draw (%s,%s) withcolor blue withpen pencircle scaled 2lw ;",xx,yy)
+ context('label.top("\\infofont %s",(%s,%s-2.75bp)) ;',txt .. i,xx,yy)
+ context('label.bot("\\infofont (%s,%s)",(%s,%s+2.75bp)) ;',x,y,xx,yy)
+ end
+ end
end
+ --
+ show("b",anchordata.base)
+ show("m",anchordata.mark)
+ show("l",anchordata.ligature)
+ show("e",anchordata.entry)
+ show("x",anchordata.exit)
end
- local a = anchors.cexit
- if a then
- for k, v in next, a do
- show(v[1],v[2],k)
- end
+ --
+ local italic = d.italic
+ if italic and italic ~= 0 then
+ local i = italic * factor
+ context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width,ury,width,ury)
+ context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width+i,ury,width+i,ury)
+ context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue ;',width,ury,width+i,ury)
+ context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,ury)
+ context('label.rt("%s",(%s-2bp,%s-1bp));',italic,width+i,ury)
end
+ context('draw origin withcolor red withpen pencircle scaled 2lw;')
+ context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
+ context("currentpicture := currentpicture scaled 8 ;")
+ context.stopMPcode()
+ context.stop()
end
- if italic ~= 0 then
- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width,ury,width,ury)
- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width+italic,ury,width+italic,ury)
- context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue ;',width,ury,width+italic,ury)
- context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,ury)
- context('label.rt("%s",(%s-2bp,%s-1bp));',d.italic,width+italic,ury)
- end
- if top_accent ~= 0 then
- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,ury)
- context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,ury)
- context('label.top("%s",(%s,%s-1bp));',d.top_accent,top_accent,ury)
- end
- if bot_accent ~= 0 then
- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,lly)
- context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,ury)
- context('label.bot("%s",(%s,%s+1bp));',d.bot_accent,bot_accent,lly)
- end
- context('draw origin withcolor red withpen pencircle scaled 2lw;')
- context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
- context("currentpicture := currentpicture scaled 8 ;")
- context.stopMPcode()
- context.stop()
- -- elseif c then
- -- lastdata, lastunicode = nil, nil
- -- local factor = (7200/7227)/65536
- -- context.startMPcode()
- -- context("pickup pencircle scaled .25bp ; ")
- -- context('picture p ; p := image(draw textext.drt("\\gray\\char%s");); draw p ;',charnum)
- -- context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
- -- context("defaultscale := 0.05 ; ")
- -- local italic, top_accent, bot_accent = (c.italic or 0)*factor, (c.top_accent or 0)*factor, (c.bot_accent or 0)*factor
- -- local width, height, depth = (c.width or 0)*factor, (c.height or 0)*factor, (c.depth or 0)*factor
- -- local ury = height
- -- if italic ~= 0 then
- -- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width,ury,width,ury)
- -- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width+italic,ury,width+italic,ury)
- -- context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue;',width,ury,width+italic,height)
- -- context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,height)
- -- context('label.rt("%6.3f bp",(%s-2bp,%s-1bp));',italic,width+italic,height)
- -- end
- -- if top_accent ~= 0 then
- -- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,height)
- -- context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,height)
- -- context('label.top("%6.3f bp",(%s,%s-1bp));',top_accent,top_accent,height)
- -- end
- -- if bot_accent ~= 0 then
- -- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,height)
- -- context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,height)
- -- context('label.bot("%6.3f bp",(%s,%s+1bp));',bot_accent,bot_accent,height)
- -- end
- -- context('draw origin withcolor red withpen pencircle scaled 1bp;')
- -- context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
- -- context("currentpicture := currentpicture scaled 8 ;")
- -- context.stopMPcode()
- else
- -- lastdata, lastunicode = nil, nil
- -- context("no such shape: 0x%05X",charnum)
end
-end
-moduledata.fonts.shapes.showglyphshape = showglyphshape
+ local unicode = tonumber(specification.character) or
+ fonts.helpers.nametoslot(specification.character)
-function moduledata.fonts.shapes.showallglypshapes(specification)
- specification = interfaces.checkedspecification(specification)
- local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>")
- local descriptions = fontdata[id].descriptions
- for unicode, description in fonts.iterators.descriptions(tfmdata) do
- if unicode >= 0x110000 then
- break
+ if unicode then
+ showonecharacter(unicode)
+ else
+ context.modulefontsstartshowglyphshapes()
+ for unicode, description in fonts.iterators.descriptions(tfmdata) do
+ if unicode >= 0x110000 then
+ break
+ end
+ context.modulefontsstartshowglyphshape(unicode,description.name or "",description.index or 0)
+ showonecharacter(unicode)
+ context.modulefontsstopshowglyphshape()
end
- context.modulefontsstartshowglyphshape(unicode,description.name or "",description.index or 0)
- showglyphshape { number = id, character = unicode }
- context.modulefontsstopshowglyphshape()
+ context.modulefontsstopshowglyphshapes()
end
+
end
+moduledata.fonts.shapes.showglyphshape = showglyphshape
+moduledata.fonts.shapes.showallglypshapes = showglyphshape
+
function moduledata.fonts.shapes.showlastglyphshapefield(unicode,name)
if not descriptions then
-- bad news
diff --git a/tex/context/modules/mkiv/s-fonts-shapes.mkiv b/tex/context/modules/mkiv/s-fonts-shapes.mkiv
index 53ed1b426..d05438f3d 100644
--- a/tex/context/modules/mkiv/s-fonts-shapes.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-shapes.mkiv
@@ -30,7 +30,7 @@
\startsetups module:showallglyphshapes:start
\unexpanded\def\modulefontsstartshowglyphshape##1##2##3{
- \startTEXpage[\c!offset=\exheight]
+ \startTEXpage[\c!offset=\exheight,\c!frame=\v!on]
\edef\lastshownglyphshapefieldunicode{##1}%
\edef\lastshownglyphshapefieldname {##2}%
\edef\lastshownglyphshapefieldindex {##3}%
@@ -58,6 +58,15 @@
\stopsetups
+\startsetups module:showallglyphshapes:stop
+
+ % nothing
+
+\stopsetups
+
+\unexpanded\def\modulefontsstartshowglyphshapes{\setups[module:showallglyphshapes:start]}
+\unexpanded\def\modulefontsstopshowglyphshapes {\setups[module:showallglyphshapes:stop]}
+
\protect
% downward compatibility:
@@ -109,10 +118,12 @@
% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D45D}\stopTEXpage
% \page
-\startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0xF034A}\stopTEXpage
-\startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0x006DD}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0xF034A}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0x006DD}\stopTEXpage
+\startTEXpage[offset=0pt]\ShowGlyphShape{file:arabtype.ttf}{50bp}{0x0FCA1}\stopTEXpage
% \showallglyphshapes[name=name:cambria-math,size=100bp]
+% \showallglyphshapes[name=name:arabtype,size=100bp]
% \showallglyphshapes[name=file:husayninotebold.ttf,size=100bp]
% \showallglyphshapes[name=name:dejavuserif,size=100bp]
diff --git a/tex/context/modules/mkiv/s-languages-hyphenation.lua b/tex/context/modules/mkiv/s-languages-hyphenation.lua
index 6d3cf3d3e..65fd1ab14 100644
--- a/tex/context/modules/mkiv/s-languages-hyphenation.lua
+++ b/tex/context/modules/mkiv/s-languages-hyphenation.lua
@@ -29,7 +29,8 @@ local newrule = nodepool.rule
local newglue = nodepool.glue
local insert_node_after = nuts.insert_after
-local traverse_by_id = nuts.traverse_id
+
+local nextglyph = nuts.traversers.glyph
local tonut = nodes.tonut
local tonode = nodes.tonode
@@ -129,7 +130,7 @@ end
local function getlanguage(head,l,left,right)
local t = { }
- for n in traverse_by_id(glyph_code,tonut(head)) do
+ for n in nextglyph, tonut(head) do
t[n] = {
getlang(n),
getfield(n,"left"),
@@ -148,7 +149,7 @@ function moduledata.languages.hyphenation.showhyphens(head)
local marked = { }
local cached = { }
-- somehow assigning -1 fails
- for n in traverse_by_id(glyph_code,tonut(head)) do
+ for n in nextglyph, tonut(head) do
cached[n] = {
getlang(n),
getfield(n,"left"),
diff --git a/tex/generic/context/luatex/luatex-basics-nod.lua b/tex/generic/context/luatex/luatex-basics-nod.lua
index 40fb9ee4e..462b665fb 100644
--- a/tex/generic/context/luatex/luatex-basics-nod.lua
+++ b/tex/generic/context/luatex/luatex-basics-nod.lua
@@ -11,8 +11,9 @@ if context then
os.exit()
end
--- Don't depend on code here as it is only needed to complement the
--- font handler code.
+-- Don't depend on code here as it is only needed to complement the font handler
+-- code. I will move some to another namespace as I don't see other macro packages
+-- use the context logic. It's a subset anyway.
-- Attributes:
@@ -74,8 +75,8 @@ local flush_node = node.flush_node
local remove_node = node.remove
local traverse_id = node.traverse_id
-nodes.handlers.protectglyphs = node.protect_glyphs
-nodes.handlers.unprotectglyphs = node.unprotect_glyphs
+nodes.handlers.protectglyphs = node.protect_glyphs -- beware: nodes!
+nodes.handlers.unprotectglyphs = node.unprotect_glyphs -- beware: nodes!
local math_code = nodecodes.math
local end_of_math = node.end_of_math
@@ -285,6 +286,7 @@ nuts.end_of_math = direct.end_of_math
nuts.traverse = direct.traverse
nuts.traverse_id = direct.traverse_id
nuts.traverse_char = direct.traverse_char
+nuts.traverse_glyph = direct.traverse_glyph
nuts.ligaturing = direct.ligaturing
nuts.kerning = direct.kerning
nuts.new = direct.new
@@ -480,3 +482,23 @@ if not nuts.uses_font then
end
end
+--
+do
+
+ -- another poor mans substitute ... i will move these to a more protected
+ -- namespace .. experimental hack
+
+ local dummy = tonut(node.new("glyph"))
+
+ nuts.traversers = {
+ glyph = nuts.traverse_id(nodecodes.glyph,dummy),
+ glue = nuts.traverse_id(nodecodes.glue,dummy),
+ disc = nuts.traverse_id(nodecodes.disc,dummy),
+ boundary = nuts.traverse_id(nodecodes.boundary,dummy),
+
+ char = nuts.traverse_char(dummy),
+
+ node = nuts.traverse(dummy),
+ }
+
+end
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index f2cbe59d8..6b530e252 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 : 04/19/18 15:53:45
+-- merge date : 05/12/18 00:07:56
do -- begin closure to overcome local limits and interference
@@ -2011,12 +2011,19 @@ end
local function sequenced(t,sep,simple)
if not t then
return ""
+ elseif type(t)=="string" then
+ return t
end
local n=#t
local s={}
if n>0 then
for i=1,n do
- s[i]=tostring(t[i])
+ local v=t[i]
+ if type(v)=="table" then
+ s[i]="{"..sequenced(v,sep,simple).."}"
+ else
+ s[i]=tostring(t[i])
+ end
end
else
n=0
@@ -4324,6 +4331,10 @@ local format_L=function()
n=n+1
return format("(a%s and 'TRUE' or 'FALSE')",n)
end
+local format_n=function()
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+end
local format_N=function()
n=n+1
return format("tostring(tonumber(a%s) or a%s)",n,n)
@@ -4424,6 +4435,7 @@ local builder=Cs { "start",
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
++V("n")
+V("N")
+V("k")
+V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w")
@@ -4453,6 +4465,7 @@ local builder=Cs { "start",
["o"]=(prefix_any*P("o"))/format_o,
["S"]=(prefix_any*P("S"))/format_S,
["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
["N"]=(prefix_any*P("N"))/format_N,
["k"]=(prefix_sub*P("k"))/format_k,
["c"]=(prefix_any*P("c"))/format_c,
@@ -5350,8 +5363,8 @@ nodes.disccodes=disccodes
local flush_node=node.flush_node
local remove_node=node.remove
local traverse_id=node.traverse_id
-nodes.handlers.protectglyphs=node.protect_glyphs
-nodes.handlers.unprotectglyphs=node.unprotect_glyphs
+nodes.handlers.protectglyphs=node.protect_glyphs
+nodes.handlers.unprotectglyphs=node.unprotect_glyphs
local math_code=nodecodes.math
local end_of_math=node.end_of_math
function node.end_of_math(n)
@@ -5527,6 +5540,7 @@ nuts.end_of_math=direct.end_of_math
nuts.traverse=direct.traverse
nuts.traverse_id=direct.traverse_id
nuts.traverse_char=direct.traverse_char
+nuts.traverse_glyph=direct.traverse_glyph
nuts.ligaturing=direct.ligaturing
nuts.kerning=direct.kerning
nuts.new=direct.new
@@ -5694,6 +5708,17 @@ if not nuts.uses_font then
return false
end
end
+do
+ local dummy=tonut(node.new("glyph"))
+ nuts.traversers={
+ glyph=nuts.traverse_id(nodecodes.glyph,dummy),
+ glue=nuts.traverse_id(nodecodes.glue,dummy),
+ disc=nuts.traverse_id(nodecodes.disc,dummy),
+ boundary=nuts.traverse_id(nodecodes.boundary,dummy),
+ char=nuts.traverse_char(dummy),
+ node=nuts.traverse(dummy),
+ }
+end
end -- closure
@@ -9570,10 +9595,13 @@ function constructors.scale(tfmdata,specification)
local t={}
for i=1,#vv do
local vvi=vv[i]
- t[i]={
- ["start"]=(vvi["start"] or 0)*vdelta,
- ["end"]=(vvi["end"] or 0)*vdelta,
- ["advance"]=(vvi["advance"] or 0)*vdelta,
+ local s=vvi["start"] or 0
+ local e=vvi["end"] or 0
+ local a=vvi["advance"] or 0
+ t[i]={
+ ["start"]=s==0 and 0 or s*vdelta,
+ ["end"]=e==0 and 0 or e*vdelta,
+ ["advance"]=a==0 and 0 or a*vdelta,
["extender"]=vvi["extender"],
["glyph"]=vvi["glyph"],
}
@@ -9585,10 +9613,13 @@ function constructors.scale(tfmdata,specification)
local t={}
for i=1,#hv do
local hvi=hv[i]
- t[i]={
- ["start"]=(hvi["start"] or 0)*hdelta,
- ["end"]=(hvi["end"] or 0)*hdelta,
- ["advance"]=(hvi["advance"] or 0)*hdelta,
+ local s=hvi["start"] or 0
+ local e=hvi["end"] or 0
+ local a=hvi["advance"] or 0
+ t[i]={
+ ["start"]=s==0 and 0 or s*hdelta,
+ ["end"]=e==0 and 0 or e*hdelta,
+ ["advance"]=a==0 and 0 or a*hdelta,
["extender"]=hvi["extender"],
["glyph"]=hvi["glyph"],
}
@@ -9699,7 +9730,6 @@ function constructors.scale(tfmdata,specification)
else
chr.commands=vc
end
- chr.index=nil
end
end
targetcharacters[unicode]=chr
@@ -11061,7 +11091,7 @@ function helpers.appendcommands(commands,...)
return commands
end
local char=setmetatableindex(function(t,k)
- local v={ "char",k }
+ local v={ "slot",0,k }
t[k]=v
return v
end)
@@ -16011,11 +16041,12 @@ local reversed=table.reversed
local sort=table.sort
local insert=table.insert
local round=math.round
-local settings_to_hash_colon_too=table.settings_to_hash_colon_too
+local settings_to_hash=utilities.parsers.settings_to_hash_colon_too
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local sortedkeys=table.sortedkeys
local sortedhash=table.sortedhash
+local sequenced=table.sequenced
local report=logs.reporter("otf reader")
local readers=fonts.handlers.otf.readers
local streamreader=readers.streamreader
@@ -16171,7 +16202,7 @@ local lookupflags=setmetatableindex(function(t,k)
return v
end)
local function axistofactors(str)
- local t=settings_to_hash_colon_too(str)
+ local t=settings_to_hash(str)
for k,v in next,t do
t[k]=tonumber(v) or v
end
@@ -16190,9 +16221,6 @@ helpers.cleanname=cleanname
function helpers.normalizedaxis(str)
return hash[str] or str
end
-local function axistofactors(str)
- return settings_to_hash_colon_too(str)
-end
local function getaxisscale(segments,minimum,default,maximum,user)
if not minimum or not default or not maximum then
return false
@@ -22624,8 +22652,8 @@ local setkern=nuts.setkern
local setlink=nuts.setlink
local setwidth=nuts.setwidth
local getwidth=nuts.getwidth
-local traverse_id=nuts.traverse_id
-local traverse_char=nuts.traverse_char
+local nextchar=nuts.traversers.char
+local nextglue=nuts.traversers.glue
local insert_node_before=nuts.insert_before
local insert_node_after=nuts.insert_after
local properties=nodes.properties.data
@@ -23033,7 +23061,7 @@ local function show(n,what,nested,symbol)
end
local function showsub(n,what,where)
report_injections("begin subrun: %s",where)
- for n in traverse_char(n) do
+ for n in nextchar,n do
showchar(n,where)
show(n,what,where," ")
end
@@ -23092,7 +23120,6 @@ local function show_result(head)
report_injections()
end
local function inject_kerns_only(head,where)
- head=tonut(head)
if trace_injections then
trace(head,"kerns")
end
@@ -23161,7 +23188,7 @@ local function inject_kerns_only(head,where)
pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
local done=false
if pre then
- for n in traverse_char(pre) do
+ for n in nextchar,pre do
local p=rawget(properties,n)
if p then
local i=p.injections or p.preinjections
@@ -23176,7 +23203,7 @@ local function inject_kerns_only(head,where)
end
end
if post then
- for n in traverse_char(post) do
+ for n in nextchar,post do
local p=rawget(properties,n)
if p then
local i=p.injections or p.postinjections
@@ -23191,7 +23218,7 @@ local function inject_kerns_only(head,where)
end
end
if replace then
- for n in traverse_char(replace) do
+ for n in nextchar,replace do
local p=rawget(properties,n)
if p then
local i=p.injections or p.replaceinjections
@@ -23223,10 +23250,9 @@ local function inject_kerns_only(head,where)
if trace_injections then
show_result(head)
end
- return tonode(head),true
+ return head
end
local function inject_positions_only(head,where)
- head=tonut(head)
if trace_injections then
trace(head,"positions")
end
@@ -23324,7 +23350,7 @@ local function inject_positions_only(head,where)
pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
local done=false
if pre then
- for n in traverse_char(pre) do
+ for n in nextchar,pre do
local p=rawget(properties,n)
if p then
local i=p.injections or p.preinjections
@@ -23348,7 +23374,7 @@ local function inject_positions_only(head,where)
end
end
if post then
- for n in traverse_char(post) do
+ for n in nextchar,post do
local p=rawget(properties,n)
if p then
local i=p.injections or p.postinjections
@@ -23372,7 +23398,7 @@ local function inject_positions_only(head,where)
end
end
if replace then
- for n in traverse_char(replace) do
+ for n in nextchar,replace do
local p=rawget(properties,n)
if p then
local i=p.injections or p.replaceinjections
@@ -23443,7 +23469,7 @@ local function inject_positions_only(head,where)
if trace_injections then
show_result(head)
end
- return tonode(head),true
+ return head
end
local function showoffset(n,flag)
local x,y=getoffsets(n)
@@ -23452,7 +23478,6 @@ local function showoffset(n,flag)
end
end
local function inject_everything(head,where)
- head=tonut(head)
if trace_injections then
trace(head,"everything")
end
@@ -23691,7 +23716,7 @@ local function inject_everything(head,where)
pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
local done=false
if pre then
- for n in traverse_char(pre) do
+ for n in nextchar,pre do
local p=rawget(properties,n)
if p then
local i=p.injections or p.preinjections
@@ -23721,7 +23746,7 @@ local function inject_everything(head,where)
end
end
if post then
- for n in traverse_char(post) do
+ for n in nextchar,post do
local p=rawget(properties,n)
if p then
local i=p.injections or p.postinjections
@@ -23751,7 +23776,7 @@ local function inject_everything(head,where)
end
end
if replace then
- for n in traverse_char(replace) do
+ for n in nextchar,replace do
local p=rawget(properties,n)
if p then
local i=p.injections or p.replaceinjections
@@ -23852,7 +23877,7 @@ local function inject_everything(head,where)
if trace_injections then
show_result(head)
end
- return tonode(head),true
+ return head
end
local triggers=false
function nodes.injections.setspacekerns(font,sequence)
@@ -23899,7 +23924,7 @@ function injections.installgetspaceboth(gb)
end
local function injectspaces(head)
if not triggers then
- return head,false
+ return head
end
local lastfont=nil
local spacekerns=nil
@@ -23909,7 +23934,6 @@ local function injectspaces(head)
local threshold=0
local leftkern=false
local rightkern=false
- local nuthead=tonut(head)
local function updatefont(font,trig)
leftkerns=trig.left
rightkerns=trig.right
@@ -23917,7 +23941,7 @@ local function injectspaces(head)
threshold,
factor=getthreshold(font)
end
- for n in traverse_id(glue_code,nuthead) do
+ for n in nextglue,head do
local prev,next=getspaceboth(n)
local prevchar=prev and ischar(prev)
local nextchar=next and ischar(next)
@@ -23955,12 +23979,8 @@ local function injectspaces(head)
if trace_spaces then
report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
end
- local h=insert_node_before(nuthead,n,italickern(lnew))
- if h==nuthead then
- head=tonode(h)
- nuthead=h
- end
- insert_node_after(nuthead,n,italickern(rnew))
+ head=insert_node_before(head,n,italickern(lnew))
+ insert_node_after(head,n,italickern(rnew))
else
local new=old+(leftkern+rightkern)*factor
if trace_spaces then
@@ -23975,7 +23995,7 @@ local function injectspaces(head)
if trace_spaces then
report_spaces("%C [%p + %p]",prevchar,old,new)
end
- insert_node_after(nuthead,n,italickern(new))
+ insert_node_after(head,n,italickern(new))
else
local new=old+leftkern*factor
if trace_spaces then
@@ -23994,7 +24014,7 @@ local function injectspaces(head)
if trace_spaces then
report_spaces("%C [%p + %p]",nextchar,old,new)
end
- insert_node_after(nuthead,n,italickern(new))
+ insert_node_after(head,n,italickern(new))
else
local new=old+rightkern*factor
if trace_spaces then
@@ -24007,7 +24027,7 @@ local function injectspaces(head)
end
end
triggers=false
- return head,true
+ return head
end
function injections.handler(head,where)
if triggers then
@@ -24029,7 +24049,7 @@ function injections.handler(head,where)
end
return inject_kerns_only(head,where)
else
- return head,false
+ return head
end
end
@@ -24066,7 +24086,6 @@ local getfont=nuts.getfont
local getsubtype=nuts.getsubtype
local getchar=nuts.getchar
local ischar=nuts.is_char
-local traverse_id=nuts.traverse_id
local end_of_math=nuts.end_of_math
local nodecodes=nodes.nodecodes
local disc_code=nodecodes.disc
@@ -24475,8 +24494,6 @@ registertracker("otf.actions","otf.substitutions","otf.positions")
registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing")
registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing")
local nuts=nodes.nuts
-local tonode=nuts.tonode
-local tonut=nuts.tonut
local getfield=nuts.getfield
local getnext=nuts.getnext
local setnext=nuts.setnext
@@ -24511,7 +24528,6 @@ local find_node_tail=nuts.tail
local flush_node_list=nuts.flush_list
local flush_node=nuts.flush_node
local end_of_math=nuts.end_of_math
-local traverse_nodes=nuts.traverse
local set_components=nuts.set_components
local take_components=nuts.take_components
local count_components=nuts.count_components
@@ -24519,6 +24535,7 @@ local copy_no_components=nuts.copy_no_components
local copy_only_glyphs=nuts.copy_only_glyphs
local setmetatable=setmetatable
local setmetatableindex=table.setmetatableindex
+local nextnode=nuts.traversers.node
local nodecodes=nodes.nodecodes
local glyphcodes=nodes.glyphcodes
local disccodes=nodes.disccodes
@@ -27183,7 +27200,7 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase
a=getattr(sub,0)
end
if not a or (a==attr) then
- for n in traverse_nodes(sub) do
+ for n in nextnode,sub do
if n==last then
break
end
@@ -27336,7 +27353,7 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase
a=getattr(sub,0)
end
if not a or (a==attr) then
- for n in traverse_nodes(sub) do
+ for n in nextnode,sub do
if n==last then
break
end
@@ -27436,12 +27453,10 @@ do
nesting=nesting-1
return head,false
end
- local head=tonut(head)
if trace_steps then
checkstep(head)
end
local initialrl=direction=="TRT" and -1 or 0
- local done=false
local datasets=otfdataset(tfmdata,font,attr)
local dirstack={}
sweephead={}
@@ -27459,10 +27474,7 @@ do
local nofsteps=sequence.nofsteps
local skiphash=sequence.skiphash
if not steps then
- local h,ok=handler(head,dataset,sequence,initialrl,font,attr)
- if ok then
- done=true
- end
+ local h,ok=handler(head,dataset,sequence,initialrl,font,attr)
if h and h~=head then
head=h
end
@@ -27488,7 +27500,6 @@ do
local ok
head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
if ok then
- done=true
break
end
end
@@ -27531,9 +27542,6 @@ do
if a then
local ok
head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if ok then
- done=true
- end
if start then
start=getnext(start)
end
@@ -27556,9 +27564,6 @@ do
else
start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
end
- if ok then
- done=true
- end
else
start=getnext(start)
end
@@ -27599,7 +27604,6 @@ do
local ok
head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
if ok then
- done=true
break
elseif not start then
break
@@ -27628,9 +27632,6 @@ do
else
start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
end
- if ok then
- done=true
- end
else
start=getnext(start)
end
@@ -27651,8 +27652,7 @@ do
end
end
nesting=nesting-1
- head=tonode(head)
- return head,done
+ return head
end
function otf.datasetpositionprocessor(head,font,direction,dataset)
currentfont=font
@@ -27673,7 +27673,6 @@ do
local handler=handlers[typ]
local steps=sequence.steps
local nofsteps=sequence.nofsteps
- local head=tonut(head)
local done=false
local dirstack={}
local start=head
@@ -27725,7 +27724,7 @@ do
start=getnext(start)
end
end
- return tonode(head)
+ return head
end
end
local plugins={}
@@ -28011,8 +28010,6 @@ local methods=fonts.analyzers.methods
local otffeatures=fonts.constructors.features.otf
local registerotffeature=otffeatures.register
local nuts=nodes.nuts
-local tonode=nuts.tonode
-local tonut=nuts.tonut
local getnext=nuts.getnext
local getprev=nuts.getprev
local getboth=nuts.getboth
@@ -28054,21 +28051,25 @@ replace_all_nbsp=function(head)
end
return replace_all_nbsp(head)
end
-local xprocesscharacters=nil
+local processcharacters=nil
if context then
- xprocesscharacters=function(head,font)
- xprocesscharacters=nodes.handlers.characters
- return xprocesscharacters(head,font)
+ local fontprocesses=fonts.hashes.processes
+ function processcharacters(head,font)
+ local processors=fontprocesses[font]
+ for i=1,#processors do
+ head=processors[i](head,font,0)
+ end
+ return head
end
else
- xprocesscharacters=function(head,font)
- xprocesscharacters=nodes.handlers.nodepass
- return xprocesscharacters(head,font)
+ function processcharacters(head,font)
+ local processors=fontdata[font].shared.processes
+ for i=1,#processors do
+ head=processors[i](head,font,0)
+ end
+ return head
end
end
-local function processcharacters(head,font)
- return tonut(xprocesscharacters(tonode(head)))
-end
local indicgroups=characters and characters.indicgroups
if not indicgroups and characters then
local indic={
@@ -29657,7 +29658,6 @@ local function analyze_next_chars_two(c,font)
end
end
local function method_one(head,font,attr)
- head=tonut(head)
local current=head
local start=true
local done=false
@@ -29836,10 +29836,9 @@ local function method_one(head,font,attr)
if nbspaces>0 then
head=replace_all_nbsp(head)
end
- return tonode(head),done
+ return head,done
end
local function method_two(head,font,attr)
- head=tonut(head)
local current=head
local start=true
local done=false
@@ -29918,7 +29917,7 @@ local function method_two(head,font,attr)
if nbspaces>0 then
head=replace_all_nbsp(head)
end
- return tonode(head),done
+ return head,done
end
for i=1,nofscripts do
methods[scripts_one[i]]=method_one
@@ -33926,8 +33925,10 @@ local settings_to_hash=utilities.parsers.settings_to_hash_colon_too
local helpers=fonts.helpers
local prependcommands=helpers.prependcommands
local charcommand=helpers.commands.char
+local leftcommand=helpers.commands.left
local rightcommand=helpers.commands.right
local upcommand=helpers.commands.up
+local downcommand=helpers.commands.down
local dummycommand=helpers.commands.dummy
local report_effect=logs.reporter("fonts","effect")
local report_slant=logs.reporter("fonts","slant")
@@ -34115,7 +34116,7 @@ local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze
end
end
local character=characters[0x221A]
- if character then
+ if character and character.next then
local char=character
local next=character.next
wdpatch(char)
@@ -34131,7 +34132,8 @@ local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze
if v then
local top=v[#v]
if top then
- htpatch(characters[top.glyph])
+ local char=characters[top.glyph]
+ htpatch(char)
end
end
end
@@ -34152,7 +34154,7 @@ local function manipulateeffect(tfmdata)
local ddelta=effect.ddelta*vfactor*multiplier
local vshift=effect.vshift*vfactor*multiplier
local squeeze=effect.squeeze
- local hshift=wdelta
+ local hshift=wdelta/2
local dx=multiplier*vfactor
local dy=vshift
local factor=(1+effect.factor)*factor
@@ -36369,8 +36371,8 @@ local setlink=nuts.setlink
local setprev=nuts.setprev
local n_ligaturing=node.ligaturing
local n_kerning=node.kerning
-local ligaturing=nuts.ligaturing
-local kerning=nuts.kerning
+local d_ligaturing=nuts.ligaturing
+local d_kerning=nuts.kerning
local basemodepass=true
local function l_warning() texio.write_nl("warning: node.ligaturing called directly") l_warning=nil end
local function k_warning() texio.write_nl("warning: node.kerning called directly") k_warning=nil end
@@ -36386,13 +36388,24 @@ function node.kerning(...)
end
return n_kerning(...)
end
+function nuts.ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return d_ligaturing(...)
+end
+function nuts.kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return d_kerning(...)
+end
function nodes.handlers.setbasemodepass(v)
basemodepass=v
end
-function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
+local function nodepass(head,groupcode,size,packtype,direction)
local fontdata=fonts.hashes.identifiers
if fontdata then
- local nuthead=tonut(head)
local usedfonts={}
local basefonts={}
local prevfont=nil
@@ -36400,7 +36413,7 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
local variants=nil
local redundant=nil
local nofused=0
- for n in traverse_id(glyph_code,nuthead) do
+ for n in traverse_id(glyph_code,head) do
local font=getfont(n)
if font~=prevfont then
if basefont then
@@ -36461,8 +36474,8 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
for i=1,#redundant do
local r=redundant[i]
local p,n=getboth(r)
- if r==nuthead then
- nuthead=n
+ if r==head then
+ head=n
setprev(n)
else
setlink(p,n)
@@ -36481,7 +36494,7 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
flush_node(r)
end
end
- for d in traverse_id(disc_code,nuthead) do
+ for d in traverse_id(disc_code,head) do
local _,_,r=getdisc(d)
if r then
for n in traverse_id(glyph_code,r) do
@@ -36519,16 +36532,16 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
local start=range[1]
local stop=range[2]
if start then
- local front=nuthead==start
+ local front=head==start
local prev,next
if stop then
next=getnext(stop)
- start,stop=ligaturing(start,stop)
- start,stop=kerning(start,stop)
+ start,stop=d_ligaturing(start,stop)
+ start,stop=d_kerning(start,stop)
else
prev=getprev(start)
- start=ligaturing(start)
- start=kerning(start)
+ start=d_ligaturing(start)
+ start=d_kerning(start)
end
if prev then
setlink(prev,start)
@@ -36536,40 +36549,57 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
if next then
setlink(stop,next)
end
- if front and nuthead~=start then
- head=tonode(start)
+ if front and head~=start then
+ head=start
end
end
end
end
- return head,true
- else
- return head,false
end
+ return head
end
-function nodes.handlers.basepass(head)
+local function basepass(head)
if basemodepass then
- head=n_ligaturing(head)
- head=n_kerning(head)
+ head=d_ligaturing(head)
+ head=d_kerning(head)
end
- return head,true
+ return head
end
-local nodepass=nodes.handlers.nodepass
-local basepass=nodes.handlers.basepass
+local protectpass=node.direct.protect_glyphs
local injectpass=nodes.injections.handler
-local protectpass=nodes.handlers.protectglyphs
+function nodes.handlers.nodepass(head,...)
+ if head then
+ return tonode(nodepass(tonut(head),...))
+ end
+end
+function nodes.handlers.basepass(head)
+ if head then
+ return tonode(basepass(tonut(head)))
+ end
+end
+function nodes.handlers.injectpass(head)
+ if head then
+ return tonode(injectpass(tonut(head)))
+ end
+end
+function nodes.handlers.protectpass(head)
+ if head then
+ protectpass(tonut(head))
+ return head
+ end
+end
function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
if head then
+ head=tonut(head)
head=nodepass(head,groupcode,size,packtype,direction)
head=injectpass(head)
if not basemodepass then
head=basepass(head)
end
protectpass(head)
- return head,true
- else
- return head,false
+ head=tonode(head)
end
+ return head
end
end -- closure
diff --git a/tex/generic/context/luatex/luatex-test.tex b/tex/generic/context/luatex/luatex-test.tex
index 2aa4f22d9..d472e8db6 100644
--- a/tex/generic/context/luatex/luatex-test.tex
+++ b/tex/generic/context/luatex/luatex-test.tex
@@ -147,6 +147,18 @@ $\sin{x}$
\egroup
+\bgroup
+
+ \font\boldera=lmroman10-regular:mode=node;liga=yes;kern=yes;
+ \font\bolderb=lmroman10-regular:mode=node;liga=yes;kern=yes;effect=0.1;
+ \font\bolderc=lmroman10-regular:mode=node;liga=yes;kern=yes;effect={width=0.1,auto=yes};
+
+ \boldera Just a line. \par
+ \bolderb Just a line. \par
+ \bolderc Just a line. \par
+
+\egroup
+
% \font\amiri=file:amiri-regular.ttf:%
% mode=node;analyze=yes;language=dflt;script=arab;ccmp=yes;%
% init=yes;medi=yes;fina=yes;isol=yes;%