summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2021-12-24 19:46:30 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2021-12-24 19:46:30 +0100
commit1cc6c316feae649d3c8b64ef0c980dfd792c2347 (patch)
treed2153ed2d05808a40963f095fb2d29c4f5e5c4c8 /tex
parent19750b667c23a9f276032837d6c517063376bd0c (diff)
downloadcontext-1cc6c316feae649d3c8b64ef0c980dfd792c2347.tar.gz
2021-12-24 19:09:00
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.lua23
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/file-lib.lua30
-rw-r--r--tex/context/base/mkiv/mult-prm.lua2
-rw-r--r--tex/context/base/mkiv/page-one.mkiv8
-rw-r--r--tex/context/base/mkiv/publ-ini.lua4
-rw-r--r--tex/context/base/mkiv/spac-ver.lua5
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin24763 -> 24314 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin257684 -> 236799 bytes
-rw-r--r--tex/context/base/mkxl/anch-bck.mklx2
-rw-r--r--tex/context/base/mkxl/anch-pgr.lmt29
-rw-r--r--tex/context/base/mkxl/anch-pos.lmt58
-rw-r--r--tex/context/base/mkxl/anch-pos.mkxl13
-rw-r--r--tex/context/base/mkxl/attr-ini.lmt352
-rw-r--r--tex/context/base/mkxl/attr-ini.mkxl3
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl6
-rw-r--r--tex/context/base/mkxl/file-job.lmt2
-rw-r--r--tex/context/base/mkxl/file-mod.mklx1
-rw-r--r--tex/context/base/mkxl/luat-run.lmt21
-rw-r--r--tex/context/base/mkxl/math-ali.lmt84
-rw-r--r--tex/context/base/mkxl/math-ali.mkxl107
-rw-r--r--tex/context/base/mkxl/node-aux.lmt136
-rw-r--r--tex/context/base/mkxl/node-bck.lmt84
-rw-r--r--tex/context/base/mkxl/node-bck.mkxl2
-rw-r--r--tex/context/base/mkxl/node-ext.lmt12
-rw-r--r--tex/context/base/mkxl/node-ini.lmt122
-rw-r--r--tex/context/base/mkxl/node-ini.mkxl1
-rw-r--r--tex/context/base/mkxl/node-pro.lmt6
-rw-r--r--tex/context/base/mkxl/node-ref.lmt4
-rw-r--r--tex/context/base/mkxl/node-rul.lmt938
-rw-r--r--tex/context/base/mkxl/node-rul.mkxl265
-rw-r--r--tex/context/base/mkxl/node-scn.lmt141
-rw-r--r--tex/context/base/mkxl/node-ser.lmt37
-rw-r--r--tex/context/base/mkxl/node-tra.lmt2
-rw-r--r--tex/context/base/mkxl/node-tsk.lmt21
-rw-r--r--tex/context/base/mkxl/pack-box.mkxl2
-rw-r--r--tex/context/base/mkxl/page-imp.mkxl3
-rw-r--r--tex/context/base/mkxl/page-one.mkxl12
-rw-r--r--tex/context/base/mkxl/page-sid.mkxl20
-rw-r--r--tex/context/base/mkxl/spac-ali.mkxl56
-rw-r--r--tex/context/base/mkxl/spac-ver.lmt95
-rw-r--r--tex/context/base/mkxl/supp-box.lmt470
-rw-r--r--tex/context/base/mkxl/supp-box.mkxl8
-rw-r--r--tex/context/base/mkxl/tabl-tbl.mkxl21
-rw-r--r--tex/context/base/mkxl/trac-deb.lmt1
-rw-r--r--tex/context/base/mkxl/typo-bld.lmt43
-rw-r--r--tex/context/base/mkxl/typo-brk.lmt3
-rw-r--r--tex/context/base/mkxl/typo-cap.lmt305
-rw-r--r--tex/context/base/mkxl/typo-rub.lmt5
-rw-r--r--tex/context/base/mkxl/typo-rub.mkxl8
-rw-r--r--tex/context/modules/mkiv/m-matrix.mkiv5
-rw-r--r--tex/context/modules/mkiv/m-punk.mkiv2
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
57 files changed, 2053 insertions, 1539 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index bbd1c93f6..648915909 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{2021.12.14 19:16}
+\newcontextversion{2021.12.24 19: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 560c4107c..9d4bcc772 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{2021.12.14 19:16}
+\edef\contextversion{2021.12.24 19: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 e822f12b4..8681239c9 100644
--- a/tex/context/base/mkiv/anch-pgr.lua
+++ b/tex/context/base/mkiv/anch-pgr.lua
@@ -81,7 +81,6 @@ local nodecodes = nodes.nodecodes
local par_code = nodecodes.par
local startofpar = nuts.startofpar
-
local insertbefore = nuts.insertbefore
local insertafter = nuts.insertafter
@@ -102,6 +101,7 @@ local enabled = false
-- many pages but for an arbitrary background shape that is not so common.
local function check(specification)
+ --
local a = specification.attribute
local index = specification.index
local depth = specification.depth
@@ -208,21 +208,6 @@ local function registerbackground(name)
end
end
--- local function collectbackgrounds(r,n)
--- if enabled then
--- local parent = getbox(n)
--- local head = getlist(parent)
--- realpage = r
--- processranges(a_textbackground,flush,head) -- ,parent)
--- end
--- end
---
--- interfaces.implement {
--- name = "collectbackgrounds",
--- actions = collectbackgrounds,
--- arguments = { "integer", "integer" }
--- }
-
nodes.handlers.textbackgrounds = function(head,where,parent) -- we have hlistdir and local dir
-- todo enable action in register
index = index + 1
@@ -785,9 +770,7 @@ local function calculatemultipar(tag)
for i=bindex+1,eindex-1 do
br = f_tag_two(btag,i)
local r = collected[br]
- if not r then
- report_graphics("invalid middle for %a",br)
- else
+ if r then
local rp = r.p -- page
local pp = list[rp]
local mp = middlepart(b,e,p,rp,r,left,right)
@@ -796,6 +779,8 @@ local function calculatemultipar(tag)
else
list[rp] = { mp }
end
+ else
+ report_graphics("invalid middle for %a",br)
end
end
local ep = e.p -- page
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index d61d0887e..98dbc868f 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.12.14 19:16}
+\newcontextversion{2021.12.24 19:07}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 4675386c8..bc37c8aab 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -49,7 +49,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.12.14 19:16}
+\edef\contextversion{2021.12.24 19:07}
%D Kind of special:
diff --git a/tex/context/base/mkiv/file-lib.lua b/tex/context/base/mkiv/file-lib.lua
index 9b0679e25..50ac5e1db 100644
--- a/tex/context/base/mkiv/file-lib.lua
+++ b/tex/context/base/mkiv/file-lib.lua
@@ -18,10 +18,11 @@ local report_library = logs.reporter("files","library")
----- report_files = logs.reporter("files","readfile")
local removesuffix = file.removesuffix
+local collapsepath = file.collapsepath
local getreadfilename = resolvers.getreadfilename
-local loaded = { }
+local libraries = table.setmetatableindex("table")
local defaultpatterns = { "%s" }
local function defaultaction(name,foundname)
@@ -46,6 +47,7 @@ function resolvers.uselibrary(specification) -- todo: reporter
local foundname = getreadfilename("any",".",somename) -- maybe some day also an option not to backtrack .. and ../.. (or block global)
return foundname ~= "" and foundname
end
+ local loaded = libraries[patterns]
for i=1,#files do
local filename = files[i]
if not loaded[filename] then
@@ -76,17 +78,25 @@ function resolvers.uselibrary(specification) -- todo: reporter
end
end
end
- if not loaded[foundname] then
- if foundname then
- action(name,foundname)
+ if type(foundname) == "string" then
+ if not loaded[foundname] then
+ if foundname then
+ foundname = collapsepath(foundname)
+ -- this way we can run a module (nil when making a format):
+ local inputname = environment.inputfilename
+ if not inputname or collapsepath(inputname) ~= foundname then
+ action(name,foundname)
+ end
+ -- afterwards:
+ if onlyonce then
+ loaded[foundname] = true -- todo: base this on return value
+ end
+ elseif failure then
+ failure(name)
+ end
if onlyonce then
- loaded[foundname] = true -- todo: base this on return value
+ loaded[filename] = true -- todo: base this on return value
end
- elseif failure then
- failure(name)
- end
- if onlyonce then
- loaded[filename] = true -- todo: base this on return value
end
end
end
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index 87c52de04..0249b906b 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -312,6 +312,7 @@ return {
"efcode",
"endlocalcontrol",
"enforced",
+ "etoks",
"etoksapp",
"etokspre",
"everybeforepar",
@@ -552,6 +553,7 @@ return {
"wordboundary",
"wrapuppar",
"xdefcsname",
+ "xtoks",
"xtoksapp",
"xtokspre",
},
diff --git a/tex/context/base/mkiv/page-one.mkiv b/tex/context/base/mkiv/page-one.mkiv
index dbed7429a..567a19884 100644
--- a/tex/context/base/mkiv/page-one.mkiv
+++ b/tex/context/base/mkiv/page-one.mkiv
@@ -372,13 +372,13 @@
\def\page_one_command_flush_bottom_insertions_indeed
{\ifgridsnapping
- % \floatparameter\c!bottombefore
+ % \rootfloatparameter\c!bottombefore
\snaptogrid\hbox{\box\namedinsertionnumber\s!bottomfloat}%
- % \floatparameter\c!bottomafter
+ % \rootfloatparameter\c!bottomafter
\else
- \floatparameter\c!bottombefore
+ \rootfloatparameter\c!bottombefore
\unvbox\namedinsertionnumber\s!bottomfloat
- \floatparameter\c!bottomafter
+ \rootfloatparameter\c!bottomafter
\fi}
\unexpanded\def\page_one_command_flush_floats
diff --git a/tex/context/base/mkiv/publ-ini.lua b/tex/context/base/mkiv/publ-ini.lua
index bc0a9106f..9d43f69f4 100644
--- a/tex/context/base/mkiv/publ-ini.lua
+++ b/tex/context/base/mkiv/publ-ini.lua
@@ -2408,6 +2408,10 @@ do
s = k
break
end
+ -- weird
+ if type(s) == "table" then
+ return citevariants.default
+ end
end
if s then
s = specifications[s]
diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua
index 9e0bc2dd8..8baf25184 100644
--- a/tex/context/base/mkiv/spac-ver.lua
+++ b/tex/context/base/mkiv/spac-ver.lua
@@ -2005,10 +2005,7 @@ do
function vspacing.vboxhandler(head,where)
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
+ head = collapser(head,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper
end
return head
end
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 708b6ffd2..64c9917b6 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 10f855c72..38d788622 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/mkxl/anch-bck.mklx b/tex/context/base/mkxl/anch-bck.mklx
index 5c9382a7b..818fade98 100644
--- a/tex/context/base/mkxl/anch-bck.mklx
+++ b/tex/context/base/mkxl/anch-bck.mklx
@@ -245,7 +245,7 @@
\carryoverpar\endgroup}
\def\anch_backgrounds_text_start_txt
- {\ifvmode \dontleavehmode \fi
+ {\ifvmode\dontleavehmode\fi
\begingroup
\c_anch_backgrounds_pos_state\plusone
\usetextbackgroundstyleandcolor\c!style\c!color
diff --git a/tex/context/base/mkxl/anch-pgr.lmt b/tex/context/base/mkxl/anch-pgr.lmt
index 8a329fd13..5261a2afa 100644
--- a/tex/context/base/mkxl/anch-pgr.lmt
+++ b/tex/context/base/mkxl/anch-pgr.lmt
@@ -106,13 +106,12 @@ local jobpositions = job.positions
local getpos = jobpositions.getpos
local getfree = jobpositions.getfree
-local data = { }
local realpage = 1
-local recycle = 1000 -- only tables can overflow this
local enabled = false
--- Freeing the data is somewhat tricky as we can have backgrounds spanning
--- many pages but for an arbitrary background shape that is not so common.
+-- Freeing the data is somewhat tricky as we can have backgrounds spanning many
+-- pages but for an arbitrary background shape that is not so common but we use
+-- a different trick anyway in lmtx.
local function check(specification)
--
@@ -170,8 +169,11 @@ end
local index = 0
+local registervalue = attributes.registervalue
+local getvalue = attributes.getvalue
+
local function flush(head,f,l,a,parent,depth)
- local d = data[a]
+ local d = getvalue(a_textbackground,a)
if d then
local ix = index
local ht = getheight(parent)
@@ -193,18 +195,11 @@ local function flush(head,f,l,a,parent,depth)
end
local function registerbackground(name)
- local n = #data + 1
- if n > recycle then
- -- we could also free all e: that are beyond a page but we don't always
- -- know the page so a recycle is nicer and the s lists are kept anyway
- -- so the amount of kept data is not that large
- n = 1
- end
local b = jobpositions.tobesaved["b:"..name]
if b then
local s = setmetatableindex("table")
b.s = s
- data[n] = {
+ local t = {
bpos = b,
name = name,
n = n,
@@ -212,7 +207,7 @@ local function registerbackground(name)
count = 0,
sindex = 0,
}
- texsetattribute(a_textbackground,n)
+ texsetattribute(a_textbackground,registervalue(a_textbackground,t))
if not enabled then
enableaction("contributers", "nodes.handlers.textbackgrounds")
enabled = true
@@ -784,9 +779,7 @@ local function calculatemultipar(tag)
for i=bindex+1,eindex-1 do
br = f_tag_two(btag,i)
local r = collected[br]
- if not r then
- report_graphics("invalid middle for %a",br)
- else
+ if r then
local rp = r.p -- page
local pp = list[rp]
local mp = middlepart(b,e,p,rp,r,left,right)
@@ -795,6 +788,8 @@ local function calculatemultipar(tag)
else
list[rp] = { mp }
end
+ else
+ report_graphics("invalid middle for %a",br)
end
end
local ep = e.p -- page
diff --git a/tex/context/base/mkxl/anch-pos.lmt b/tex/context/base/mkxl/anch-pos.lmt
index 4900df683..5a9ffaa3d 100644
--- a/tex/context/base/mkxl/anch-pos.lmt
+++ b/tex/context/base/mkxl/anch-pos.lmt
@@ -102,7 +102,7 @@ local formatters = string.formatters
local collected = allocate()
local tobesaved = allocate()
-local positionsused = false
+local positionsused = nil
local jobpositions = {
collected = collected,
@@ -145,7 +145,7 @@ local f_tag_two = formatters["%s:%s"]
-- Because positions are set with a delay we cannot yet make the tree -- so that
-- is a finalizer step. But, we already have a dual split.
--- local treemode = false
+local treemode = false
local treemode = true
local function checkshapes(s)
@@ -231,12 +231,14 @@ if treemode then
columndone = false
local deltapacking = true -- so we can see the difference
+-- local deltapacking = false -- so we can see the difference
local function checkcommondata(v,common)
if common then
local i = v.i
local t = common[i]
if t then
+v.i = nil
local m = t.mt
if not m then
setmetatable(t,default)
@@ -289,7 +291,8 @@ if treemode then
local v = list[one] or false
if v then
if prefix == "p" then
- if deltapacking and type(v) == "number" then
+ -- if deltapacking and type(v) == "number" then
+ if type(v) == "number" then
for i=one,1,-1 do
local l = list[i]
if type(l) ~= "number" then
@@ -312,7 +315,7 @@ if treemode then
if not getmetatable(l) then
checkcommondata(l,x_y_w_h_list)
end
- v = setmetatable({ p = p }, { __index = l })
+ v = setmetatable({ p = v }, { __index = l })
list[one] = v
break
end
@@ -433,17 +436,6 @@ if treemode then
t[category] = tc
return tc
end)
- --
- for k, v in next, collected do
- if k ~= "shared" and next(v) then
- positionsused = true
- break
- end
- end
- end
-
- function jobpositions.used()
- return positionsused
end
local function finalizer()
@@ -822,6 +814,19 @@ else
end
+function jobpositions.used()
+ if positionsused == nil then
+ positionsused = false
+ for k, v in next, collected do
+ if k ~= "shared" and next(v) then
+ positionsused = true
+ break
+ end
+ end
+ end
+ return positionsused
+end
+
function jobpositions.getfree(page)
return freedata[page]
end
@@ -1489,7 +1494,12 @@ function jobpositions.copy(target,source)
end
function jobpositions.replace(id,p,x,y,w,h,d)
- collected[id] = { p = p, x = x, y = y, w = w, h = h, d = d } -- c g
+ local c = collected[id]
+ if c then
+ c.p = p ; c.x = x ; c.y = y ; c.w = w ; c.h = h ; c.d = d ; -- c g
+ else
+ collected[i] = { p = p, x = x, y = y, w = w, h = h, d = d } -- c g
+ end
end
local function getpage(id)
@@ -1751,14 +1761,12 @@ implement {
public = true,
protected = true,
actions = function(name,page,x,y,w,h,d)
- collected[name] = {
- p = page,
- x = x,
- y = y,
- w = w,
- h = h,
- d = d,
- }
+ local c = collected[name]
+ if c then
+ c.p = page ; c.x = x ; c.y = y ; c.w = w ; c.h = h ; c.d = d ;
+ else
+ collected[name] = { p = page, x = x, y = y, w = w, h = h, d = d }
+ end
end
}
@@ -2249,7 +2257,7 @@ implement {
public = true,
protected = true,
actions = function()
- doifelse(positionsused)
+ doifelse(jobpositions.used())
end
}
diff --git a/tex/context/base/mkxl/anch-pos.mkxl b/tex/context/base/mkxl/anch-pos.mkxl
index 70197e93e..fef8e54f6 100644
--- a/tex/context/base/mkxl/anch-pos.mkxl
+++ b/tex/context/base/mkxl/anch-pos.mkxl
@@ -419,7 +419,6 @@
\global\positioningtrue}
\permanent\protected\lettonothing\disableparpositions
-
\permanent\protected\lettonothing\registerparoptions % hooks into everypar
\permanent\protected\def\doregisterparoptions
@@ -432,16 +431,22 @@
\def\anch_positions_register_par_options_traced
{\anch_positions_register_par_options_normal
- \smashedhbox to \zeropoint
+ \begingroup
+ \setbox\scratchbox\hpack
{\hss
\startcolor[blue]%
- \llap{\infofont\number\c_anch_positions_paragraph}%
+ \hpack \s!yoffset -2\onepoint to \zeropoint
+ {\hss\infofont\number\c_anch_positions_paragraph\hskip2\onepoint}%
\vrule
\s!width 4\onepoint
\s!height2\onepoint
\s!depth 2\onepoint
\stopcolor
- \hss}}
+ \hss}%
+ \smashbox\scratchbox
+ \boxxoffset\scratchbox-2\onepoint
+ \box\scratchbox
+ \endgroup}
\let\anch_positions_register_par_options\anch_positions_register_par_options_normal
diff --git a/tex/context/base/mkxl/attr-ini.lmt b/tex/context/base/mkxl/attr-ini.lmt
new file mode 100644
index 000000000..ca21365cb
--- /dev/null
+++ b/tex/context/base/mkxl/attr-ini.lmt
@@ -0,0 +1,352 @@
+if not modules then modules = { } end modules ['attr-ini'] = {
+ version = 1.001,
+ comment = "companion to attr-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next, type = next, type
+local osexit = os.exit
+local sortedhash = table.sortedhash
+
+--[[ldx--
+<p>We start with a registration system for atributes so that we can use the
+symbolic names later on.</p>
+--ldx]]--
+
+local nodes = nodes
+local context = context
+local storage = storage
+local commands = commands
+
+local implement = interfaces.implement
+
+attributes = attributes or { }
+local attributes = attributes
+
+local sharedstorage = storage.shared
+
+local texsetattribute = tex.setattribute
+
+attributes.names = attributes.names or { }
+attributes.numbers = attributes.numbers or { }
+attributes.list = attributes.list or { }
+attributes.values = attributes.values or { }
+attributes.counts = attributes.counts or { }
+attributes.handlers = attributes.handlers or { }
+attributes.states = attributes.states or { }
+attributes.unsetvalue = -0x7FFFFFFF
+
+local currentfont = font.current
+local currentattributes = nodes and nodes. currentattributes or node.currentattributes
+local getusedattributes = nodes and nodes.nuts and nodes.nuts.getusedattributes or node.direct.getusedattributes
+
+local names = attributes.names
+local numbers = attributes.numbers
+local list = attributes.list
+local values = attributes.values
+local counts = attributes.counts
+
+storage.register("attributes/names", names, "attributes.names")
+storage.register("attributes/numbers", numbers, "attributes.numbers")
+storage.register("attributes/list", list, "attributes.list")
+storage.register("attributes/values", values, "attributes.values")
+storage.register("attributes/counts", counts, "attributes.counts")
+
+local report_attribute = logs.reporter("attributes")
+local report_value = logs.reporter("attributes","values")
+
+local trace_values = false
+
+trackers.register("attributes.values", function(v) trace_values = v end)
+
+-- function attributes.define(name,number) -- at the tex end
+-- if not numbers[name] then
+-- numbers[name] = number
+-- names[number] = name
+-- list[number] = { }
+-- end
+-- end
+
+--[[ldx--
+<p>We reserve this one as we really want it to be always set (faster).</p>
+--ldx]]--
+
+names[0], numbers["fontdynamic"] = "fontdynamic", 0
+
+--[[ldx--
+<p>private attributes are used by the system and public ones are for users. We use dedicated
+ranges of numbers for them. Of course a the <l n='context'/> end a private attribute can be
+accessible too, so a private attribute can have a public appearance.</p>
+--ldx]]--
+
+sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or 15 -- very private
+sharedstorage.attributes_last_public = sharedstorage.attributes_last_public or 1024 -- less private
+
+function attributes.private(name) -- at the lua end (hidden from user)
+ local number = numbers[name]
+ if not number then
+ local last = sharedstorage.attributes_last_private
+ if last < 1023 then
+ last = last + 1
+ sharedstorage.attributes_last_private = last
+ else
+ report_attribute("no more room for private attributes")
+ osexit()
+ end
+ number = last
+ numbers[name], names[number], list[number] = number, name, { }
+ end
+ return number
+end
+
+function attributes.public(name) -- at the lua end (hidden from user)
+ local number = numbers[name]
+ if not number then
+ local last = sharedstorage.attributes_last_public
+ if last < 65535 then
+ last = last + 1
+ sharedstorage.attributes_last_public = last
+ else
+ report_attribute("no more room for public attributes")
+ osexit()
+ end
+ number = last
+ numbers[name], names[number], list[number] = number, name, { }
+ end
+ return number
+end
+
+attributes.system = attributes.private
+
+function attributes.define(name,category)
+ return (attributes[category or "public"] or attributes["public"])(name)
+end
+
+-- tracers
+
+local function showlist(what,list)
+ if list then
+ local a = list.next
+ local i = 0
+ while a do
+ local number = a.index
+ local value = a.value
+ i = i + 1
+ report_attribute("%S %2i: attribute %3i, value %4i, name %a",what,i,number,value,names[number])
+ a = a.next
+ end
+ end
+end
+
+function attributes.showcurrent()
+ showlist("current",currentattributes())
+end
+
+function attributes.ofnode(n)
+ showlist(n,n.attr)
+end
+
+-- rather special (can be optimized)
+
+local store = { }
+
+function attributes.save(name)
+ name = name or ""
+ local n = currentattributes()
+ n = n and n.next
+ local t = { }
+ while n do
+ t[n.index] = n.value
+ n = n.next
+ end
+ store[name] = {
+ attr = t,
+ font = currentfont(),
+ }
+end
+
+function attributes.restore(name)
+ name = name or ""
+ local t = store[name]
+ if t then
+ local attr = t.attr
+ local font = t.font
+ if attr then
+ for k, v in next, attr do
+ texsetattribute(k,v)
+ end
+ end
+ if font then
+ -- tex.font = font
+ -- context.getvalue(fonts.hashes.csnames[font])
+ currentfont(font)
+ end
+ end
+ -- store[name] = nil
+end
+
+-- value manager
+
+local cleaners = { }
+
+-- function attributes.registervalue(index,value)
+-- local list = values[index]
+-- local last
+-- if list then
+-- last = counts[index] + 1
+-- list[last] = value
+-- else
+-- last = 1
+-- values[index] = { value }
+-- end
+-- counts[index] = last
+-- return last
+-- end
+
+function attributes.registervalue(index,value)
+ local list = values[index]
+ local last
+ if list then
+ local c = counts[index]
+ if c and c[2] > 0 then
+ -- this can be an option
+ for i=c[1],c[2] do
+ if list[i] == nil then
+ if trace_values then
+ report_value("reusing slot %i for attribute %i in range (%i,%i)",i,index,c[1],c[2])
+ end
+ c[1] = i
+ list[i] = value
+ return i
+ end
+ end
+ else
+ c = { 0, 0 }
+ end
+ last = c[2] + 1
+ list[last] = value
+ c[1] = last
+ c[2] = last
+ if trace_values then
+ report_value("expanding to slot %i for attribute %i",last,index)
+ end
+ else
+ last = 1
+ values[index] = { value }
+ counts[index] = { last, last }
+ if trace_values then
+ report_value("starting at slot %i for attribute %i",last,index)
+ end
+ end
+ return last
+end
+
+function attributes.getvalue(index,value)
+ local list = values[index]
+ return list and list[value] or nil
+end
+
+function attributes.hasvalues(index)
+ local list = values[index]
+ return list and next(list) and true or false
+end
+
+function attributes.setcleaner(index,cleaner)
+ cleaners[index] = cleaner
+end
+
+function attributes.checkvalues()
+-- if true then
+-- report_value("no checking done")
+-- return
+-- end
+ if next(values) then
+ local active = getusedattributes()
+ if trace_values then
+ -- sorted
+ for index, list in sortedhash(values) do
+ local b = active[index]
+ if b then
+ local cleaner = cleaners[index]
+ for k in sortedhash(list) do
+ if b[k] then
+ report_value("keeping value %i for attribute %i",k,index)
+ else
+ report_value("wiping value %i for attribute %i",k,index)
+ if cleaner then
+ cleaner(list[k])
+ end
+ list[k] = nil
+ end
+ end
+ if next(list) then
+ counts[index][1] = 0
+ goto continue
+ end
+ end
+ report_value("no more values for attribute %i",index)
+ values[index] = nil
+ counts[index] = nil
+ ::continue::
+ end
+ else
+ for index, list in next, values do
+ local b = active[index]
+ if b then
+ local cleaner = cleaners[index]
+ for k in next, list do
+ if not b[k] then
+ if cleaner then
+ cleaner(list[k])
+ end
+ list[k] = nil
+ end
+ end
+ if next(list) then
+ counts[index][1] = 0
+ goto continue
+ end
+ end
+ values[index] = nil
+ counts[index] = { 0, 0 }
+ ::continue::
+ end
+ end
+ elseif trace_values then
+ report_value("no check needed")
+ end
+end
+
+implement {
+ name = "cleanupattributes",
+ -- public = true, -- some day ... but then also \shipoutpage
+ protected = true,
+ actions = attributes.checkvalues,
+}
+
+-- interface
+
+implement {
+ name = "defineattribute",
+ arguments = "2 strings",
+ actions = { attributes.define, context }
+}
+
+implement {
+ name = "showattributes",
+ actions = attributes.showcurrent
+}
+
+implement {
+ name = "savecurrentattributes",
+ arguments = "string",
+ actions = attributes.save
+}
+
+implement {
+ name = "restorecurrentattributes",
+ arguments = "string",
+ actions = attributes.restore
+}
diff --git a/tex/context/base/mkxl/attr-ini.mkxl b/tex/context/base/mkxl/attr-ini.mkxl
index 23a38eb12..e3538cf3d 100644
--- a/tex/context/base/mkxl/attr-ini.mkxl
+++ b/tex/context/base/mkxl/attr-ini.mkxl
@@ -15,7 +15,7 @@
\unprotect
-\registerctxluafile{attr-ini}{}
+\registerctxluafile{attr-ini}{autosuffix}
\installcorenamespace{attributecount} % the counter representing the attribute (attrdef'd)
\installcorenamespace{attributeid} % the internal number
@@ -125,7 +125,6 @@
\definesystemattribute [layoutcomponent] [public]
\definesystemattribute [internal] [public]
\definesystemattribute [ruled] [public]
-\definesystemattribute [ruledextra] [public]
\definesystemattribute [shifted] [public]
\definesystemattribute [checkedbreak] [public]
\definesystemattribute [alternate] [public]
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 28c8d3bf6..b30d8996a 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.12.14 19:16}
+\newcontextversion{2021.12.24 19:07}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 93c7f1d69..33bb1971a 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2021.12.14 19:16}
+\immutable\edef\contextversion{2021.12.24 19:07}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
@@ -219,7 +219,7 @@
\loadmkxlfile{colo-grp} % optional
\loadmkxlfile{colo-ext}
-\loadmkxlfile{node-bck} % overloads anch-pgr (experimental and undocumented)
+% \loadmkxlfile{node-bck} % overloads anch-pgr (experimental and undocumented)
\loadmkxlfile{pack-cut}
@@ -502,6 +502,8 @@
\loadmkxlfile{phys-dim}
\loadmkxlfile{node-rul} % beware, defined \underbar so after math
+\loadmkxlfile{node-bck} % overloads anch-pgr (experimental and undocumented)
+
\loadmklxfile{font-sol} % font solutions
\loadmklxfile{strc-not}
diff --git a/tex/context/base/mkxl/file-job.lmt b/tex/context/base/mkxl/file-job.lmt
index 84186a2d0..367ec4562 100644
--- a/tex/context/base/mkxl/file-job.lmt
+++ b/tex/context/base/mkxl/file-job.lmt
@@ -192,7 +192,7 @@ implement {
-- moved from tex to lua:
local texpatterns = { "%s.mklx", "%s.mkxl", "%s.mkvi", "%s.mkiv", "%s.tex" }
-local luapatterns = { "%s" .. utilities.lua.suffixes.luc, "%s.lua", "%s.lmt" }
+local luapatterns = { "%s" .. utilities.lua.suffixes.luc, "%s.lmt", "%s.lua" }
local cldpatterns = { "%s.cld" }
local xmlpatterns = { "%s.xml" }
diff --git a/tex/context/base/mkxl/file-mod.mklx b/tex/context/base/mkxl/file-mod.mklx
index ddcbcba3f..3a966894f 100644
--- a/tex/context/base/mkxl/file-mod.mklx
+++ b/tex/context/base/mkxl/file-mod.mklx
@@ -56,6 +56,7 @@
\edef\currentmoduleparameters{#name}%
\else
\edef\currentmodulecategory {#category}%
+ \edef\currentmodulecategory {#category}%
\edef\currentmodule {#name}%
\let \currentmoduleparameters\empty
\fi
diff --git a/tex/context/base/mkxl/luat-run.lmt b/tex/context/base/mkxl/luat-run.lmt
index fa3336d4b..f6b2ea063 100644
--- a/tex/context/base/mkxl/luat-run.lmt
+++ b/tex/context/base/mkxl/luat-run.lmt
@@ -41,6 +41,8 @@ function luatex.registerstopactions (...) insert(stopactions, ...) end
function luatex.registerdumpactions (...) insert(dumpactions, ...) end
function luatex.registerpageactions (...) insert(pageactions, ...) end
+local setexitcode = lua.setexitcode or status.setexitcode or function() end
+
local function start_run()
if logs.start_run then
logs.start_run()
@@ -51,7 +53,7 @@ local function start_run()
end
end
-local function stop_run()
+local function stop_run(badrun)
for i=1,#stopactions do
stopactions[i]()
end
@@ -68,15 +70,14 @@ local function stop_run()
end
end
if quit then
- local setexitcode = lua.setexitcode or status.setexitcode
- if setexitcode then
- setexitcode(1)
- if type(quit) == "table" then
- logs.newline()
- report_tex("quitting due to: %, t",quit)
- logs.newline()
- end
+ setexitcode(1)
+ if type(quit) == "table" then
+ logs.newline()
+ report_tex("quitting due to: %, t",quit)
+ logs.newline()
end
+ elseif badrun and badrun > 0 then
+ setexitcode(1)
end
if logs.stop_run then
logs.stop_run()
@@ -147,6 +148,7 @@ end
function luatex.abort()
cleanup_run()
+ setexitcode(1)
osexit(1)
end
@@ -289,6 +291,7 @@ callback.register("handle_overload", function(fatal,overload,csname,flags)
logs.newline()
if fatal then
cleanup_run()
+ setexitcode(1)
osexit(1)
end
end
diff --git a/tex/context/base/mkxl/math-ali.lmt b/tex/context/base/mkxl/math-ali.lmt
new file mode 100644
index 000000000..a84d5a4c4
--- /dev/null
+++ b/tex/context/base/mkxl/math-ali.lmt
@@ -0,0 +1,84 @@
+if not modules then modules = { } end modules ['math-ali'] = {
+ version = 1.001,
+ comment = "companion to math-ali.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local unpack = unpack
+local gsub = string.gsub
+local lpegmatch = lpeg.match
+local settings_to_array = utilities.parsers.settings_to_array
+
+local rows = utilities.parsers.groupedsplitat(";")
+local cols = utilities.parsers.groupedsplitat(",")
+
+local context = context
+
+local actions = {
+ transpose = function(m)
+ local t = { }
+ for j=1,#m[1] do
+ local r = { }
+ for i=1,#m do
+ r[i] = m[i][j]
+ end
+ t[j] = r
+ end
+ return t
+ end,
+ negate = function(m)
+ for i=1,#m do
+ local mi = m[i]
+ for j=1,#mi do
+ mi[j] = - mi[j]
+ end
+ end
+ return m
+ end,
+ scale = function(m,s)
+ s = tonumber(s)
+ if s then
+ for i=1,#m do
+ local mi = m[i]
+ for j=1,#mi do
+ mi[j] = s*mi[j]
+ end
+ end
+ end
+ return m
+ end,
+}
+
+local useractions = {
+}
+
+interfaces.implement {
+ name = "simplematrix",
+ arguments = "2 strings",
+ actions = function(method,data)
+ local m = lpegmatch(rows,(gsub(data,"%s+"," ")))
+ for i=1,#m do
+ m[i] = lpegmatch(cols,m[i])
+ end
+ local methods = settings_to_array(method)
+ for i=1,#methods do
+ local detail = settings_to_array(methods[i])
+ local method = detail[1]
+ local action = actions[method] or useractions[method]
+ if action then
+ m = action(m,unpack(detail,2)) or m
+ end
+ end
+ for i=1,#m do
+ context("\\NC %{ \\NC }t \\NR",m[i])
+ end
+ end
+}
+
+function mathematics.registersimplematrix(name,action)
+ if type(action) == "function" then
+ useractions[name] = action
+ end
+end
diff --git a/tex/context/base/mkxl/math-ali.mkxl b/tex/context/base/mkxl/math-ali.mkxl
index cf941b586..30f5c0524 100644
--- a/tex/context/base/mkxl/math-ali.mkxl
+++ b/tex/context/base/mkxl/math-ali.mkxl
@@ -15,6 +15,8 @@
\unprotect
+\registerctxluafile{math-ali}{autosuffix}
+
%D The code here has been moved from other files. Beware: the \MKII\ and \MKIV\ code
%D is not gathered in files with the same name. In the meantime this code has been
%D adapted to \MKIV\ but more is possible. The code is somewhat complicated by the
@@ -368,6 +370,14 @@
% \begingroup not permitted ($$...assignments...\halign... ).. check in luametatex
+% \definemathmatrix
+% [pmatrix]
+% [matrix:parentheses]
+% % [align=1:right]
+% [align=all:right]
+% % [align=2:right]
+% % [align={1:left,2:middle,3:right}]
+
\permanent\tolerant\protected\def\math_alignment_start[#1]#*[#2]%
{\edef\currentmathalignment{#1}%
\ifarguments\or\or
@@ -399,8 +409,8 @@
\installcommandhandler \??mathalignment {mathalignment} \??mathalignment
\appendtoks
- \frozen\instance\setuevalue{\e!start\currentmathalignment}{\math_alignment_start[\currentmathalignment]}%
- \frozen\instance\setvalue {\e!stop \currentmathalignment}{\math_alignment_stop}% can this be protected now?
+ \frozen\protected\instance\edefcsname\e!start\currentmathalignment\endcsname{\math_alignment_start[\currentmathalignment]}%
+ \noaligned\frozen\protected\instance \defcsname\e!stop \currentmathalignment\endcsname{\math_alignment_stop}% can this be protected now?
\to \everydefinemathalignment
% to be tested
@@ -481,14 +491,28 @@
\dostoptagged % finish cell
\dostarttagged\t!mtablecell\empty}
+% \def\math_left_of_eqalign
+% {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
+% \ifcase\lastnamedcs \or \relax \or \hfill \or \hfill \fi
+% \fi}
+
+% \def\math_right_of_eqalign
+% {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
+% \ifcase\lastnamedcs \or \hfill \or \relax \or \hfill \fi
+% \fi}
+
\def\math_left_of_eqalign
{\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
\ifcase\lastnamedcs \or \relax \or \hfill \or \hfill \fi
+ \orelse\ifcsname\??mathalignmentvariant\number\zerocount\endcsname
+ \ifcase\lastnamedcs \or \relax \or \hfill \or \hfill \fi
\fi}
\def\math_right_of_eqalign
{\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
\ifcase\lastnamedcs \or \hfill \or \relax \or \hfill \fi
+ \orelse\ifcsname\??mathalignmentvariant\number\zerocount\endcsname
+ \ifcase\lastnamedcs \or \hfill \or \relax \or \hfill \fi
\fi}
\newconditional\c_math_alignment_local_number % not used but when true puts in front (todo)
@@ -513,9 +537,29 @@
\fi
\fi}
-\def\math_eqalign_set_column#1% we could just add to the preamble (as with other alignments)
- {\expandafter\chardef\csname\??mathalignmentvariant\number\c_math_eqalign_column\expandafter\expandafter\expandafter\endcsname
- \ifcsname\??mathalignmentvariant#1\endcsname\lastnamedcs\else\zerocount\fi\relax}
+% \def\math_eqalign_set_column#1% we could just add to the preamble (as with other alignments)
+% {\expandafter\chardef\csname\??mathalignmentvariant\number\c_math_eqalign_column\expandafter\expandafter\expandafter\endcsname
+% \ifcsname\??mathalignmentvariant#1\endcsname\lastnamedcs\else\zerocount\fi\relax}
+
+% \def\math_eqalign_set_column_indeed[#1:#2:#3]% we don't really check for all (so * will do too) ... yet
+% {\expandafter\chardef\csname\??mathalignmentvariant\number
+% \ifcstok{#2}\emptytoks\c_math_eqalign_column\orelse\ifchknum#1\or#1\else\zerocount\fi
+% \endcsname
+% \ifcsname\??mathalignmentvariant#2\endcsname\lastnamedcs\else\zerocount\fi\relax}
+
+\def\math_eqalign_set_column_indeed[#1:#2:#3]% we don't really check for all (so * will do too) ... yet
+ {\ifcstok{#2}\emptytoks
+ % current counter
+ \orelse\ifchknum#1\or
+ \c_math_eqalign_column#1\relax
+ \else
+ \c_math_eqalign_column\zerocount
+ \fi
+ \chardef\csname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
+ \ifcsname\??mathalignmentvariant#2\endcsname\lastnamedcs\else\zerocount\fi\relax}
+
+\def\math_eqalign_set_column#1%
+ {\normalexpanded{\math_eqalign_set_column_indeed[#1::]}}
\letcsname\??mathalignmentvariant\v!normal\endcsname\zerocount
\letcsname\??mathalignmentvariant\v!left \endcsname\plusone
@@ -1384,21 +1428,56 @@
%D The following code is derived from Aditya's simplematrix prototype but adapted to
%D regular mathmatrices:
-\def\math_matrix_simple_row#1%
- {\rawprocesscommalist[#1]\math_matrix_simple_col
- \toksapp\scratchtoks{\NR}}
+% We keep this as reference:
+%
+% \def\math_matrix_simple_row#1%
+% {\rawprocesscommalist[#1]\math_matrix_simple_col
+% \toksapp\scratchtoks{\NR}}
+%
+% \def\math_matrix_simple_col#1%
+% {\toksapp\scratchtoks{\NC#1}}
+%
+% \permanent\tolerant\protected\def\math_matrix_simple[#1]#*[#2]#:#3%
+% {\begingroup
+% \edef\currentmathmatrix{#1}%
+% \setupcurrentmathmatrix[#2]%
+% \scratchtoks\emptytoks
+% \processlist[];\math_matrix_simple_row[#3]%
+% \math_matrix_start[\currentmathmatrix]%
+% \the\scratchtoks
+% \math_matrix_stop
+% \endgroup}
-\def\math_matrix_simple_col#1%
- {\toksapp\scratchtoks{\NC#1}}
+%D With a little help from \LUA\ we now have this:
+%D
+%D \startbuffer
+%D \definemathmatrix [Pmatrix] [matrix:parentheses]
+%D [align={all:right},
+%D simplecommand=Pmatrix]
+%D
+%D \definemathmatrix [Tmatrix] [Pmatrix]
+%D [action=transpose,
+%D simplecommand=Tmatrix]
+%D
+%D \definemathmatrix [Nmatrix] [Pmatrix]
+%D [action=negate,
+%D simplecommand=Nmatrix]
+%D
+%D \startformula
+%D \Pmatrix{ -1, 2, 3; 4,-5, 6; 7, 8,-9 } \neq
+%D \Tmatrix{ -1, 2, 3; 4,-5, 6; 7, 8,-9 } \neq
+%D \Nmatrix{ -1, 2, 3; 4,-5, 6; 7, 8,-9 }
+%D \stopformula
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
\permanent\tolerant\protected\def\math_matrix_simple[#1]#*[#2]#:#3%
{\begingroup
\edef\currentmathmatrix{#1}%
\setupcurrentmathmatrix[#2]%
- \scratchtoks\emptytoks
- \processlist[];\math_matrix_simple_row[#3]%
\math_matrix_start[\currentmathmatrix]%
- \the\scratchtoks
+ \clf_simplematrix{\mathmatrixparameter\c!action}{#3}%
\math_matrix_stop
\endgroup}
@@ -1407,7 +1486,7 @@
\appendtoks
\edef\p_simplecommand{\mathmatrixparameter\c!simplecommand}%
\ifempty\p_simplecommand\else
- \frozen\instance\setuevalue{\p_simplecommand}{\math_matrix_simple[\currentmathmatrix]}%
+ \frozen\protected\instance\edefcsname\p_simplecommand\endcsname{\math_matrix_simple[\currentmathmatrix]}%
\fi
\to \everydefinemathmatrix
diff --git a/tex/context/base/mkxl/node-aux.lmt b/tex/context/base/mkxl/node-aux.lmt
index 0c9bfc837..5915f5985 100644
--- a/tex/context/base/mkxl/node-aux.lmt
+++ b/tex/context/base/mkxl/node-aux.lmt
@@ -10,72 +10,72 @@ if not modules then modules = { } end modules ['node-aux'] = {
local type, tostring = type, tostring
-local nodes = nodes
-local context = context
-
-local utfvalues = utf.values
-
-local nodecodes = nodes.nodecodes
-
-local glyph_code = nodecodes.glyph
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local attributelist_code = nodecodes.attributelist -- temporary
-local par_code = nodecodes.par
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
-local vianuts = nuts.vianuts
-
-local getbox = nuts.getbox
-local getnext = nuts.getnext
-local getid = nuts.getid
-local getsubtype = nuts.getsubtype
-local getlist = nuts.getlist
-local getattr = nuts.getattr
-local getboth = nuts.getboth
-local getprev = nuts.getprev
-local getwidth = nuts.getwidth
-local setwidth = nuts.setwidth
-local getboxglue = nuts.getboxglue
-local setboxglue = nuts.setboxglue
-
-local setfield = nuts.setfield
-local setattr = nuts.setattr
-local setlink = nuts.setlink
-local setlist = nuts.setlist
-local setnext = nuts.setnext
-local setprev = nuts.setprev
-local setattrlist = nuts.setattrlist
-
-local traversers = nuts.traversers
-local nextnode = traversers.node
-local nextglyph = traversers.glyph
-
-local flushnode = nuts.flush
-local flushlist = nuts.flushlist
-local hpack_nodes = nuts.hpack
-local vpack_nodes = nuts.vpack
-local unsetattribute = nuts.unsetattribute
-local firstglyph = nuts.firstglyph
-local copy_node = nuts.copy
-local find_tail = nuts.tail
-local getbox = nuts.getbox
-local count = nuts.count
-local isglyph = nuts.isglyph
-
-local nodepool = nuts.pool
-local new_glue = nodepool.glue
-local new_glyph = nodepool.glyph
-
-local unsetvalue = attributes.unsetvalue
-
-local current_font = font.current
-
-local texsetbox = tex.setbox
-
-local report_error = logs.reporter("node-aux:error")
+local nodes = nodes
+local context = context
+
+local utfvalues = utf.values
+
+local nodecodes = nodes.nodecodes
+
+local glyph_code = nodecodes.glyph
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local attribute_code = nodecodes.attribute -- temporary
+local par_code = nodecodes.par
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+local vianuts = nuts.vianuts
+
+local getbox = nuts.getbox
+local getnext = nuts.getnext
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getlist = nuts.getlist
+local getattr = nuts.getattr
+local getboth = nuts.getboth
+local getprev = nuts.getprev
+local getwidth = nuts.getwidth
+local setwidth = nuts.setwidth
+local getboxglue = nuts.getboxglue
+local setboxglue = nuts.setboxglue
+
+local setfield = nuts.setfield
+local setattr = nuts.setattr
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local setnext = nuts.setnext
+local setprev = nuts.setprev
+local setattrlist = nuts.setattrlist
+
+local traversers = nuts.traversers
+local nextnode = traversers.node
+local nextglyph = traversers.glyph
+
+local flushnode = nuts.flush
+local flushlist = nuts.flushlist
+local hpack_nodes = nuts.hpack
+local vpack_nodes = nuts.vpack
+local unsetattribute = nuts.unsetattribute
+local firstglyph = nuts.firstglyph
+local copy_node = nuts.copy
+local find_tail = nuts.tail
+local getbox = nuts.getbox
+local count = nuts.count
+local isglyph = nuts.isglyph
+
+local nodepool = nuts.pool
+local new_glue = nodepool.glue
+local new_glyph = nodepool.glyph
+
+local unsetvalue = attributes.unsetvalue
+
+local current_font = font.current
+
+local texsetbox = tex.setbox
+
+local report_error = logs.reporter("node-aux:error")
local function takebox(id)
local box = getbox(id)
@@ -281,12 +281,12 @@ local function link(list,currentfont,currentattr,head,tail) -- an oldie, might b
elseif not head then
head = n
tail = find_tail(n)
- elseif getid(n) == attributelist_code then
+ elseif getid(n) == attribute_code then
-- weird case
report_error("weird node type in list at index %s:",i)
for i=1,#list do
local l = list[i]
- report_error("%3i: %s %S",i,getid(l) == attributelist_code and "!" or ">",l)
+ report_error("%3i: %s %S",i,getid(l) == attribute_code and "!" or ">",l)
end
os.exit()
else
diff --git a/tex/context/base/mkxl/node-bck.lmt b/tex/context/base/mkxl/node-bck.lmt
index ba0e508b6..ff48ff8b5 100644
--- a/tex/context/base/mkxl/node-bck.lmt
+++ b/tex/context/base/mkxl/node-bck.lmt
@@ -83,7 +83,7 @@ trackers.register("backgrounds.alignments",function(v) trace_alignment = v end)
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 function colored_a(current,list,template,id,data)
local width, height, depth = getwhd(current)
local total = height + depth
if width > 0 and total > 0 then
@@ -91,7 +91,7 @@ local function colored_a(current,list,template,id)
--
local a = getattr(template,a_linefiller)
if a then
- local d = linefillers.data[a%1000]
+ local d = data[a]
if d then
rule = linefillers.filler(template,d,width,height,depth)
end
@@ -106,7 +106,7 @@ local function colored_a(current,list,template,id)
end
end
-local function colored_b(current,list,template,id,indent)
+local function colored_b(current,list,template,id,indent,data)
local width, height, depth = getwhd(current)
local total = height + depth
if width > 0 and total > 0 then
@@ -115,7 +115,7 @@ local function colored_b(current,list,template,id,indent)
--
local a = getattr(template,a_linefiller)
if a then
- local d = linefillers.data[a%1000]
+ local d = data[a]
if d then
rule = linefillers.filler(template,d,width-indent,height,depth)
end
@@ -140,13 +140,13 @@ local currentrow = 0
local enabled = false
local alignments = false
-local function add_alignbackgrounds(head,list)
+local function add_alignbackgrounds(head,list,data)
for current, id, subtype, list in nextlist, list do
if list and id == hlist_code and subtype == celllist_code then
for template in nexthlist, list do
local background = getattr(template,a_alignbackground)
if background then
- local list = colored_a(current,list,template)
+ local list = colored_a(current,list,template,data)
if list then
setlist(current,list)
end
@@ -158,25 +158,25 @@ local function add_alignbackgrounds(head,list)
end
local template = getprop(head,"alignmentchecked")
if template then
- list = colored_b(head,list,template[1],hlist_code,template[2])
+ list = colored_b(head,list,template[1],hlist_code,template[2],data)
flushnodelist(template)
templates[currentrow] = false
return list
end
end
-local function add_backgrounds(head,id,list)
+local function add_backgrounds(head,id,list,data)
if list then
for current, id, subtype, list in nextlist, list do
if list then
if alignments and subtype == alignmentlist_code then
- local l = add_alignbackgrounds(current,list)
+ local l = add_alignbackgrounds(current,list,data)
if l then
list = l
setlist(current,list)
end
end
- local l = add_backgrounds(current,id,list)
+ local l = add_backgrounds(current,id,list,data)
if l then
list = l
setlist(current,l)
@@ -187,7 +187,7 @@ local function add_backgrounds(head,id,list)
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)
+ list = colored_a(head,list,head,id,data)
-- not needed
setattr(head,a_background,unsetvalue) -- or property -- todo
return list
@@ -196,21 +196,27 @@ local function add_backgrounds(head,id,list)
end
function nodes.handlers.backgrounds(head)
- add_backgrounds(head,getid(head),getlist(head))
+ local data = attributes.values[a_linefiller]
+ if data then
+ add_backgrounds(head,getid(head),getlist(head),data)
+ end
return head
end
function nodes.handlers.backgroundspage(head,where)
- if head and where == "alignment" then
- for n in nexthlist, head do
- local p = getprop(n,"alignmentchecked")
- if not p and getsubtype(n) == alignmentlist_code then
- currentrow = currentrow + 1
- local template = templates[currentrow]
- if trace_alignment then
- report_alignment("%03i %s %s",currentrow,"page",template and "+" or "-")
+ local data = attributes.values[a_linefiller]
+ if data then
+ if head and where == "alignment" then
+ for n in nexthlist, head do
+ local p = getprop(n,"alignmentchecked")
+ if not p and getsubtype(n) == alignmentlist_code then
+ currentrow = currentrow + 1
+ local template = templates[currentrow]
+ if trace_alignment then
+ report_alignment("%03i %s %s",currentrow,"page",template and "+" or "-")
+ end
+ setprop(n,"alignmentchecked",template)
end
- setprop(n,"alignmentchecked",template)
end
end
end
@@ -218,18 +224,21 @@ function nodes.handlers.backgroundspage(head,where)
end
function nodes.handlers.backgroundsvbox(head,where)
- if head and where == "vbox" then
- local list = getlist(head)
- if list then
- for n in nexthlist, list do
- local p = getprop(n,"alignmentchecked")
- if not p and getsubtype(n) == alignmentlist_code then
- currentrow = currentrow + 1
- local template = templates[currentrow]
- if trace_alignment then
- report_alignment("%03i %s %s",currentrow,"vbox",template and "+" or "-")
+ local data = attributes.values[a_linefiller]
+ if data then
+ if head and where == "vbox" then
+ local list = getlist(head)
+ if list then
+ for n in nexthlist, list do
+ local p = getprop(n,"alignmentchecked")
+ if not p and getsubtype(n) == alignmentlist_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
@@ -237,15 +246,6 @@ function nodes.handlers.backgroundsvbox(head,where)
return head
end
--- interfaces.implement {
--- name = "enablebackgroundboxes",
--- onlyonce = true,
--- actions = enableaction,
--- arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" }
--- }
---
--- doing it in the shipout works as well but this is nicer
-
local function enable(alignmentstoo)
if not enabled then
enabled = true
@@ -274,7 +274,7 @@ interfaces.implement {
interfaces.implement {
name = "setbackgroundrowdata",
- arguments = { "integer", "integer", "dimension" },
+ arguments = { "integer", "integer", "dimension" }, -- todo: "box"
actions = function(row,box,indent)
row = row -1 -- better here than in tex
if box == 0 then
diff --git a/tex/context/base/mkxl/node-bck.mkxl b/tex/context/base/mkxl/node-bck.mkxl
index b456313df..3c2fa015c 100644
--- a/tex/context/base/mkxl/node-bck.mkxl
+++ b/tex/context/base/mkxl/node-bck.mkxl
@@ -26,6 +26,8 @@
% \backgroundvbox[red] {\input knuth } \par
% \backgroundhbox[yellow]{\rotate[rotation=45]{hello world}} \par
+% todo: use new register feature (but not used that much so ...)
+
\permanent\def\colorattr#1%
{\ifcsname\??colorattribute\currentcolorprefix#1\endcsname
\node_backgrounds_thecolorattr{\currentcolorprefix#1}%
diff --git a/tex/context/base/mkxl/node-ext.lmt b/tex/context/base/mkxl/node-ext.lmt
index fa15b9d19..de2e8fa54 100644
--- a/tex/context/base/mkxl/node-ext.lmt
+++ b/tex/context/base/mkxl/node-ext.lmt
@@ -133,14 +133,10 @@ do
end
function backends.latelua(current,pos_h,pos_v) -- todo: pass pos_h and pos_v (more efficient in lmtx)
- local p = nodeproperties[current]
- if p then
- data = p.data
- else
- data = getdata(current)
- end
- noflatelua = noflatelua + 1
+ local prop = nodeproperties[current]
+ local data = prop and prop.data or getdata(current)
local kind = type(data)
+ noflatelua = noflatelua + 1
if kind == "table" then
data.action(data.specification or data)
elseif kind == "function" then
@@ -149,7 +145,7 @@ do
if kind ~= "string" then
data = serialize(data)
end
- if #data ~= "" then
+ if data and #data ~= "" then
local code = loadstring(data)
if code then
code()
diff --git a/tex/context/base/mkxl/node-ini.lmt b/tex/context/base/mkxl/node-ini.lmt
index 06e36147c..1ec0932ab 100644
--- a/tex/context/base/mkxl/node-ini.lmt
+++ b/tex/context/base/mkxl/node-ini.lmt
@@ -47,27 +47,28 @@ do
tex.magicconstants = table.setmetatableindex(t,c)
end
-local listcodes = mark(getsubtypes("list"))
-local rulecodes = mark(getsubtypes("rule"))
-local dircodes = mark(getsubtypes("dir"))
-local markcodes = mark(getsubtypes("mark"))
-local glyphcodes = mark(getsubtypes("glyph"))
-local disccodes = mark(getsubtypes("disc"))
-local gluecodes = mark(getsubtypes("glue"))
-local boundarycodes = mark(getsubtypes("boundary"))
-local penaltycodes = mark(getsubtypes("penalty"))
-local kerncodes = mark(getsubtypes("kern"))
-local mathcodes = mark(getsubtypes("math"))
-local noadcodes = mark(getsubtypes("noad"))
-local radicalcodes = mark(getsubtypes("radical"))
-local accentcodes = mark(getsubtypes("accent"))
-local fencecodes = mark(getsubtypes("fence"))
------ fractioncodes = mark(getsubtypes("fraction"))
-local parcodes = mark(getsubtypes("par"))
-
-local fillvalues = mark(getvalues("fill"))
-local dirvalues = mark(getvalues("dir"))
-local mathvalues = mark(getvalues("math"))
+local listcodes = mark(getsubtypes("list"))
+local rulecodes = mark(getsubtypes("rule"))
+local dircodes = mark(getsubtypes("dir"))
+local markcodes = mark(getsubtypes("mark"))
+local glyphcodes = mark(getsubtypes("glyph"))
+local disccodes = mark(getsubtypes("disc"))
+local gluecodes = mark(getsubtypes("glue"))
+local boundarycodes = mark(getsubtypes("boundary"))
+local penaltycodes = mark(getsubtypes("penalty"))
+local kerncodes = mark(getsubtypes("kern"))
+local mathcodes = mark(getsubtypes("math"))
+local noadcodes = mark(getsubtypes("noad"))
+local radicalcodes = mark(getsubtypes("radical"))
+local accentcodes = mark(getsubtypes("accent"))
+local fencecodes = mark(getsubtypes("fence"))
+----- fractioncodes = mark(getsubtypes("fraction"))
+local parcodes = mark(getsubtypes("par"))
+local attributecodes = mark(getsubtypes("attribute"))
+
+local fillvalues = mark(getvalues("fill"))
+local dirvalues = mark(getvalues("dir"))
+local mathvalues = mark(getvalues("math"))
local function simplified(t)
local r = { }
@@ -91,45 +92,47 @@ local noadoptions = allocate {
local nodecodes = simplified(node.types())
-gluecodes = allocate(swapped(gluecodes,gluecodes))
-dircodes = allocate(swapped(dircodes,dircodes))
-markcodes = allocate(swapped(markcodes,markcodes))
-boundarycodes = allocate(swapped(boundarycodes,boundarycodes))
-noadcodes = allocate(swapped(noadcodes,noadcodes))
-radicalcodes = allocate(swapped(radicalcodes,radicalcodes))
-nodecodes = allocate(swapped(nodecodes,nodecodes))
-listcodes = allocate(swapped(listcodes,listcodes))
-glyphcodes = allocate(swapped(glyphcodes,glyphcodes))
-kerncodes = allocate(swapped(kerncodes,kerncodes))
-penaltycodes = allocate(swapped(penaltycodes,penaltycodes))
-mathcodes = allocate(swapped(mathcodes,mathcodes))
-disccodes = allocate(swapped(disccodes,disccodes))
-accentcodes = allocate(swapped(accentcodes,accentcodes))
-fencecodes = allocate(swapped(fencecodes,fencecodes))
-parcodes = allocate(swapped(parcodes,parcodes))
-rulecodes = allocate(swapped(rulecodes,rulecodes))
-noadoptions = allocate(swapped(noadoptions,noadoptions))
-
-dirvalues = allocate(swapped(dirvalues,dirvalues))
-fillvalues = allocate(swapped(fillvalues,fillvalues))
-mathvalues = allocate(swapped(mathvalues,mathvalues))
-
-nodes.gluecodes = gluecodes
-nodes.dircodes = dircodes
+gluecodes = allocate(swapped(gluecodes,gluecodes))
+dircodes = allocate(swapped(dircodes,dircodes))
+markcodes = allocate(swapped(markcodes,markcodes))
+boundarycodes = allocate(swapped(boundarycodes,boundarycodes))
+noadcodes = allocate(swapped(noadcodes,noadcodes))
+radicalcodes = allocate(swapped(radicalcodes,radicalcodes))
+nodecodes = allocate(swapped(nodecodes,nodecodes))
+listcodes = allocate(swapped(listcodes,listcodes))
+glyphcodes = allocate(swapped(glyphcodes,glyphcodes))
+kerncodes = allocate(swapped(kerncodes,kerncodes))
+penaltycodes = allocate(swapped(penaltycodes,penaltycodes))
+mathcodes = allocate(swapped(mathcodes,mathcodes))
+disccodes = allocate(swapped(disccodes,disccodes))
+accentcodes = allocate(swapped(accentcodes,accentcodes))
+fencecodes = allocate(swapped(fencecodes,fencecodes))
+parcodes = allocate(swapped(parcodes,parcodes))
+attributecodes = allocate(swapped(attributecodes,attributecodes))
+rulecodes = allocate(swapped(rulecodes,rulecodes))
+noadoptions = allocate(swapped(noadoptions,noadoptions))
+
+dirvalues = allocate(swapped(dirvalues,dirvalues))
+fillvalues = allocate(swapped(fillvalues,fillvalues))
+mathvalues = allocate(swapped(mathvalues,mathvalues))
+
+nodes.gluecodes = gluecodes
+nodes.dircodes = dircodes
nodes.markcodes = markcodes
-nodes.boundarycodes = boundarycodes
-nodes.noadcodes = noadcodes
-nodes.listcodes = listcodes
-nodes.glyphcodes = glyphcodes
-nodes.kerncodes = kerncodes
-nodes.penaltycodes = penaltycodes
-nodes.mathcodes = mathcodes
-nodes.disccodes = disccodes
-nodes.accentcodes = accentcodes
-nodes.radicalcodes = radicalcodes
-nodes.fencecodes = fencecodes
-nodes.parcodes = parcodes
-nodes.rulecodes = rulecodes
+nodes.boundarycodes = boundarycodes
+nodes.noadcodes = noadcodes
+nodes.listcodes = listcodes
+nodes.glyphcodes = glyphcodes
+nodes.kerncodes = kerncodes
+nodes.penaltycodes = penaltycodes
+nodes.mathcodes = mathcodes
+nodes.disccodes = disccodes
+nodes.accentcodes = accentcodes
+nodes.radicalcodes = radicalcodes
+nodes.fencecodes = fencecodes
+nodes.parcodes = parcodes
+nodes.attributecodes = attributecodes
+nodes.rulecodes = rulecodes
nodes.noadoptions = noadoptions
nodes.fillvalues = fillvalues
@@ -154,6 +157,7 @@ local subtypes = allocate {
radical = radicalcodes,
fence = fencecodes,
par = parcodes,
+ attribute = attributecodes,
rule = rulecodes,
vlist = listcodes,
diff --git a/tex/context/base/mkxl/node-ini.mkxl b/tex/context/base/mkxl/node-ini.mkxl
index 101f55c05..ef5c85c5b 100644
--- a/tex/context/base/mkxl/node-ini.mkxl
+++ b/tex/context/base/mkxl/node-ini.mkxl
@@ -36,6 +36,7 @@
\registerctxluafile{node-acc}{autosuffix} % experimental
%registerctxluafile{node-prp}{} % makes no sense (yet)
\registerctxluafile{node-scn}{autosuffix}
+\registerctxluafile{node-scn}{autosuffix}
\registerctxluafile{node-par}{autosuffix}
\registerctxluafile{node-bwc}{autosuffix} % for a while
diff --git a/tex/context/base/mkxl/node-pro.lmt b/tex/context/base/mkxl/node-pro.lmt
index f38e8280b..ab40dc0c1 100644
--- a/tex/context/base/mkxl/node-pro.lmt
+++ b/tex/context/base/mkxl/node-pro.lmt
@@ -102,9 +102,9 @@ do
----- texnest = tex.nest
----- getnest = tex.getnest
- local getlist = nuts.getlist
- local setlist = nuts.setlist
- local getsubtype = nuts.getsubtype
+ local getlist = nodes.getlist -- still nodes !
+ local setlist = nodes.setlist
+ local getsubtype = nodes.getsubtype
local linelist_code = nodes.listcodes.line
diff --git a/tex/context/base/mkxl/node-ref.lmt b/tex/context/base/mkxl/node-ref.lmt
index 269b2e749..36715c067 100644
--- a/tex/context/base/mkxl/node-ref.lmt
+++ b/tex/context/base/mkxl/node-ref.lmt
@@ -528,6 +528,8 @@ local nofreferences = 0
do
+ -- here we can't use attributes.registervalue etc (afaiks)
+
local stack = { }
local done = { }
local attribute = attributes.private('reference')
@@ -667,6 +669,8 @@ local nofdestinations = 0
do
+ -- here we can use attributes.registervalue etc
+
local stack = { }
local done = { }
local attribute = attributes.private('destination')
diff --git a/tex/context/base/mkxl/node-rul.lmt b/tex/context/base/mkxl/node-rul.lmt
index 0d1a9548e..3bf18ccf3 100644
--- a/tex/context/base/mkxl/node-rul.lmt
+++ b/tex/context/base/mkxl/node-rul.lmt
@@ -104,7 +104,6 @@ local implement = interfaces.implement
local privateattributes = attributes.private
local a_ruled = privateattributes('ruled')
-local a_ruledextra = privateattributes('ruledextra')
local a_runningtext = privateattributes('runningtext')
local a_color = privateattributes('color')
local a_transparency = privateattributes('transparency')
@@ -112,6 +111,10 @@ local a_colormodel = privateattributes('colormodel')
local a_linefiller = privateattributes("linefiller")
local a_viewerlayer = privateattributes("viewerlayer")
+local registervalue = attributes.registervalue
+local getvalue = attributes.getvalue
+local texsetattribute = tex.setattribute
+
local v_both = variables.both
local v_left = variables.left
local v_right = variables.right
@@ -134,229 +137,234 @@ local processwords = nuts.processwords
local setcoloring = nuts.colors.set
-local rules = nodes.rules or { }
-nodes.rules = rules
-rules.data = rules.data or { }
-
-local nutrules = nuts.rules or { }
-nuts.rules = nutrules -- not that many
+do
-storage.register("nodes/rules/data", rules.data, "nodes.rules.data")
+ local rules = nodes.rules or { }
+ nodes.rules = rules
+ -- rules.data = rules.data or { }
-local data = rules.data
+ local nutrules = nuts.rules or { }
+ nuts.rules = nutrules -- not that many
--- we implement user rules here as it takes less code this way
+ -- we implement user rules here as it takes less code this way
-local function usernutrule(t,noattributes)
- local r = new_userrule(t.width or 0,t.height or 0,t.depth or 0)
- if noattributes == false or noattributes == nil then
- -- avoid fuzzy ones
- else
- setattrlist(r,true)
+ local function usernutrule(t,noattributes)
+ local r = new_userrule(t.width or 0,t.height or 0,t.depth or 0)
+ if noattributes == false or noattributes == nil then
+ -- avoid fuzzy ones
+ else
+ setattrlist(r,true)
+ end
+ properties[r] = t
+ return r
end
- properties[r] = t
- return r
-end
-nutrules.userrule = usernutrule
+ nutrules.userrule = usernutrule
-local function userrule(t,noattributes)
- return tonode(usernutrule(t,noattributes))
-end
+ local function userrule(t,noattributes)
+ return tonode(usernutrule(t,noattributes))
+ end
-rules.userrule = userrule
-local ruleactions = { }
+ rules.userrule = userrule
+ local ruleactions = { }
-rules .ruleactions = ruleactions
-nutrules.ruleactions = ruleactions -- convenient
+ rules .ruleactions = ruleactions
+ nutrules.ruleactions = ruleactions -- convenient
-local function mathaction(n,h,v,what)
- local font = getruledata(n)
- local actions = fontresources[font].mathruleactions
- if actions then
- local action = actions[what]
- if action then
- action(n,h,v,font)
+ local function mathaction(n,h,v,what)
+ local font = getruledata(n)
+ local actions = fontresources[font].mathruleactions
+ if actions then
+ local action = actions[what]
+ if action then
+ action(n,h,v,font)
+ end
end
end
-end
-local function mathradical(n,h,v)
- mathaction(n,h,v,"radicalaction")
-end
+ local function mathradical(n,h,v)
+ mathaction(n,h,v,"radicalaction")
+ end
-local function mathrule(n,h,v)
- mathaction(n,h,v,"hruleaction")
-end
+ local function mathrule(n,h,v)
+ mathaction(n,h,v,"hruleaction")
+ end
-local x
+ local x
-local function useraction(n,h,v)
- local p = properties[n]
- if p then
- local i = p.type or "draw"
- local a = ruleactions[i]
- if a then
- a(p,h,v,i,n)
+ local function useraction(n,h,v)
+ local p = properties[n]
+ if p then
+ local i = p.type or "draw"
+ local a = ruleactions[i]
+ if a then
+ a(p,h,v,i,n)
+ end
end
end
-end
-local subtypeactions = {
- [rulecodes.user] = useraction,
- [rulecodes.over] = mathrule,
- [rulecodes.under] = mathrule,
- [rulecodes.fraction] = mathrule,
- [rulecodes.radical] = mathradical,
-}
+ local subtypeactions = {
+ [rulecodes.user] = useraction,
+ [rulecodes.over] = mathrule,
+ [rulecodes.under] = mathrule,
+ [rulecodes.fraction] = mathrule,
+ [rulecodes.radical] = mathradical,
+ }
-function rules.process(n,h,v)
- local n = tonut(n) -- already a nut
- local s = getsubtype(n)
- local a = subtypeactions[s]
- if a then
- a(n,h,v)
+ function rules.process(n,h,v)
+ local n = tonut(n) -- already a nut
+ local s = getsubtype(n)
+ local a = subtypeactions[s]
+ if a then
+ a(n,h,v)
+ end
end
-end
---
+ local trace_ruled = false trackers.register("nodes.rules", function(v) trace_ruled = v end)
+ local report_ruled = logs.reporter("nodes","rules")
+ local enabled = false
-local trace_ruled = false trackers.register("nodes.rules", function(v) trace_ruled = v end)
-local report_ruled = logs.reporter("nodes","rules")
-
-function rules.define(settings)
- local nofdata = #data + 1
- data[nofdata] = settings
- local text = settings.text
- if text then
- local b = nuts.takebox(text)
- if b then
- nodepool.register(b)
- settings.text = getlist(b)
- else
- settings.text = nil
+ local texgetattribute = tex.getattribute
+ local unsetvalue = attributes.unsetvalue
+
+ -- The setter is now the performance bottleneck but it is no longer
+ -- limited to a certain number of cases before we cycle resources.
+
+ function rules.set(settings)
+ if not enabled then
+ enableaction("shipouts","nodes.rules.handler")
+ enabled = true
+ end
+ local text = settings.text
+ if text then
+ settings.text = tonut(text)
+ -- nodepool.register(text) -- todo: have a cleanup hook
+ end
+ -- todo: only when explicitly enabled
+ local attr = texgetattribute(a_ruled)
+ if attr ~= unsetvalue then
+ settings.nestingvalue = attr
+ settings.nestingdata = getvalue(a_ruled,attr) -- so still accessible when we wipe
end
+ texsetattribute(a_ruled,registervalue(a_ruled,settings))
end
- return nofdata
-end
-local extrarules = false
-local extra = false
+ attributes.setcleaner(a_ruled,function(t)
+ local text = t.text
+ if text then
+ flushlist(text)
+ end
+ end)
-function rules.enableextra()
- extrarules = true
-end
+ -- we could check the passed level on the real one ... (no need to pass level)
-local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose
- local font = nil
- local char, id = isglyph(f)
- if char then
- font = id
- elseif id == hlist_code then
- font = getattr(f,a_runningtext)
- end
- if not font then
- -- saveguard ... we need to deal with rules and so (math)
- return head
- end
- local r, m
- if strip then
- if trace_ruled then
- local before = n_tosequence(f,l,true)
- f, l = striprange(f,l)
- local after = n_tosequence(f,l,true)
- report_ruled("range stripper, before %a, after %a",before,after)
- else
- f, l = striprange(f,l)
+ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose
+ local level = d.stack or d.level or 1
+ if level > d.max then
+ -- todo: trace message
+ return head
end
- end
- if not f then
- return head
- end
- local wd, ht, dp = getrangedimensions(parent,f,getnext(l))
- local method = d.method
- local empty = d.empty == v_yes
- local offset = d.offset
- local dy = d.dy
- local order = d.order
- local max = d.max
- local mp = d.mp
- local rulethickness = d.rulethickness
- local unit = d.unit
- local ma = d.ma
- local ca = d.ca
- local ta = d.ta
- local colorspace = ma > 0 and ma or getattr(f,a_colormodel) or 1
- local color = ca > 0 and ca or getattr(f,a_color)
- local transparency = ta > 0 and ta or getattr(f,a_transparency)
- local foreground = order == v_foreground
- local layer = getattr(f,a_viewerlayer)
- local e = dimenfactor(unit,font) -- what if no glyph node
- local rt = tonumber(rulethickness)
- if rt then
- rulethickness = e * rulethickness / 2
- else
- local n, u = splitdimen(rulethickness)
- if n and u then -- we need to intercept ex and em and % and ...
- rulethickness = n * dimenfactor(u,fontdata[font]) / 2
- else
- rulethickness = 1/5
+ local font = nil
+ local char, id = isglyph(f)
+ if char then
+ font = id
+ elseif id == hlist_code then
+ font = getattr(f,a_runningtext)
end
- end
- --
- if level > max then
- level = max
- end
- if method == 0 then -- center
- offset = 2*offset
- m = (offset+(level-1)*dy)*e/2 + rulethickness/2
- else
- m = 0
- end
-
- local function inject(r,wd,ht,dp)
- if layer then
- setattr(r,a_viewerlayer,layer)
+ if not font then
+ -- saveguard ... we need to deal with rules and so (math)
+ return head
+ end
+ local r, m
+ if strip then
+ if trace_ruled then
+ local before = n_tosequence(f,l,true)
+ f, l = striprange(f,l)
+ local after = n_tosequence(f,l,true)
+ report_ruled("range stripper, before %a, after %a",before,after)
+ else
+ f, l = striprange(f,l)
+ end
+ end
+ if not f then
+ return head
end
- if empty then
- head = insertnodebefore(head,f,r)
- setlink(r,getnext(l))
- setprev(f)
- setnext(l)
- flushlist(f)
+ local wd, ht, dp = getrangedimensions(parent,f,getnext(l))
+ local method = d.method
+ local empty = d.empty == v_yes
+ local offset = d.offset
+ local dy = d.dy
+ local order = d.order
+ local max = d.max
+ local mp = d.mp
+ local rulethickness = d.rulethickness
+ local unit = d.unit
+ local ma = d.ma
+ local ca = d.ca
+ local ta = d.ta
+ local colorspace = ma > 0 and ma or getattr(f,a_colormodel) or 1
+ local color = ca > 0 and ca or getattr(f,a_color)
+ local transparency = ta > 0 and ta or getattr(f,a_transparency)
+ local foreground = order == v_foreground
+ local layer = getattr(f,a_viewerlayer)
+ local e = dimenfactor(unit,font) -- what if no glyph node
+ local rt = tonumber(rulethickness)
+ if rt then
+ rulethickness = e * rulethickness / 2
else
- local k = new_kern(-wd)
- if foreground then
- insertnodeafter(head,l,k)
- insertnodeafter(head,k,r)
- l = r
+ local n, u = splitdimen(rulethickness)
+ if n and u then -- we need to intercept ex and em and % and ...
+ rulethickness = n * dimenfactor(u,fontdata[font]) / 2
else
- head = insertnodebefore(head,f,r)
- insertnodeafter(head,r,k)
+ rulethickness = 1/5
end
end
- if trace_ruled then
- report_ruled("level %a, width %p, height %p, depth %p, nodes %a, text %a",
- level,wd,ht,dp,n_tostring(f,l),n_tosequence(f,l,true))
+ --
+ if level > max then
+ level = max
+ end
+ if method == 0 then -- center
+ offset = 2*offset
+ m = (offset+(level-1)*dy)*e/2 + rulethickness/2
+ else
+ m = 0
end
- end
-
- local first = 1
- local last = level
- if extra then
- first = level
- end
+ local function inject(r,wd,ht,dp)
+ if layer then
+ setattr(r,a_viewerlayer,layer)
+ end
+ if empty then
+ head = insertnodebefore(head,f,r)
+ setlink(r,getnext(l))
+ setprev(f)
+ setnext(l)
+ flushlist(f)
+ else
+ local k = new_kern(-wd)
+ if foreground then
+ insertnodeafter(head,l,k)
+ insertnodeafter(head,k,r)
+ l = r
+ else
+ head = insertnodebefore(head,f,r)
+ insertnodeafter(head,r,k)
+ end
+ end
+ if trace_ruled then
+ report_ruled("level %a, width %p, height %p, depth %p, nodes %a, text %a",
+ level,wd,ht,dp,n_tostring(f,l),n_tosequence(f,l,true))
+ end
+ end
- if mp and mp ~= "" then
- for i=first,last do
+ if mp and mp ~= "" then
local r = usernutrule {
width = wd,
height = ht,
depth = dp,
type = "mp",
factor = e,
- offset = offset - (i-1)*dy,
+ offset = offset - (level-1)*dy, -- br ... different direction
line = rulethickness,
data = mp,
ma = colorspace,
@@ -364,364 +372,332 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a
ta = transparency,
}
inject(r,wd,ht,dp)
- end
- else
- local tx = d.text
- if tx then
- local l = copylist(tx)
- if d["repeat"] == v_yes then
- l = new_leader(wd,l)
- setattrlist(l,tx)
- end
- l = hpack_nodes(l,wd,"exactly")
- inject(l,wd,ht,dp)
else
- for i=first,last do
- local hd = (offset+(i-1)*dy)*e - m
+ local tx = d.text
+ if tx then
+ local l = copylist(tx)
+ if d["repeat"] == v_yes then
+ l = new_leader(wd,l)
+ setattrlist(l,tx)
+ end
+ l = hpack_nodes(l,wd,"exactly")
+ inject(l,wd,ht,dp)
+ else
+ local hd = (offset+(level-1)*dy)*e - m
local ht = hd + rulethickness
local dp = -hd + rulethickness
inject(setcoloring(new_rule(wd,ht,dp),colorspace,color,transparency),wd,ht,dp)
end
end
+ return head
end
- return head
-end
+ rules.handler = function(head)
+ local data = attributes.values[a_ruled]
+ if data then
+ head = processwords(a_ruled,data,flush_ruled,head)
-rules.handler = function(head)
- extra = false
- head = processwords(a_ruled,data,flush_ruled,head)
- if extrarules then
- extra = true
- head = processwords(a_ruledextra,data,flush_ruled,head)
+ end
+ return head
end
- return head
-end
-function rules.enable()
- enableaction("shipouts","nodes.rules.handler")
-end
-
-local trace_shifted = false trackers.register("nodes.shifting", function(v) trace_shifted = v end)
-
-local report_shifted = logs.reporter("nodes","shifting")
-
-local a_shifted = attributes.private('shifted')
+ implement {
+ name = "setrule",
+ actions = rules.set,
+ arguments = {
+ {
+ { "continue" },
+ { "unit" },
+ { "order" },
+ { "level", "integer" },
+ { "stack", "integer" },
+ { "method", "integer" },
+ { "offset", "number" },
+ { "rulethickness" },
+ { "dy", "number" },
+ { "max", "number" },
+ { "ma", "integer" },
+ { "ca", "integer" },
+ { "ta", "integer" },
+ { "mp" },
+ { "empty" },
+ { "text", "box" },
+ { "repeat" },
+ }
+ }
+ }
-local shifts = nodes.shifts or { }
-nodes.shifts = shifts
-shifts.data = shifts.data or { }
+end
-storage.register("nodes/shifts/data", shifts.data, "nodes.shifts.data")
+do
-local data = shifts.data
+ local trace_shifted = false trackers.register("nodes.shifting", function(v) trace_shifted = v end)
+ local report_shifted = logs.reporter("nodes","shifting")
+ local a_shifted = attributes.private('shifted')
+ local enabled = false
-function shifts.define(settings)
- local nofdata = #data + 1
- data[nofdata] = settings
- return nofdata
-end
+ local shifts = nodes.shifts or { }
+ nodes.shifts = shifts
-local function flush_shifted(head,first,last,data,level,parent,strip) -- not that fast but acceptable for this purpose
- if true then
- first, last = striprange(first,last)
- end
- local prev = getprev(first)
- local next = getnext(last)
- setprev(first)
- setnext(last)
- local width, height, depth = getrangedimensions(parent,first,next)
- local list = hpack_nodes(first,width,"exactly") -- we can use a simple pack
- if first == head then
- head = list
- end
- if prev then
- setlink(prev,list)
+ function shifts.set(settings)
+ if not enabled then
+ -- we could disable when no more found
+ enableaction("shipouts","nodes.shifts.handler")
+ enabled = true
+ end
+ texsetattribute(a_shifted,registervalue(a_shifted,settings))
end
- if next then
- setlink(list,next)
+
+ local function flush_shifted(head,first,last,data,level,parent,strip) -- not that fast but acceptable for this purpose
+ if true then
+ first, last = striprange(first,last)
+ end
+ local prev = getprev(first)
+ local next = getnext(last)
+ setprev(first)
+ setnext(last)
+ local width, height, depth = getrangedimensions(parent,first,next)
+ local list = hpack_nodes(first,width,"exactly") -- we can use a simple pack
+ if first == head then
+ head = list
+ end
+ if prev then
+ setlink(prev,list)
+ end
+ if next then
+ setlink(list,next)
+ end
+ local raise = data.dy * dimenfactor(data.unit,fontdata[getfont(first)])
+ setshift(list,raise)
+ setwhd(list,width,height,depth)
+ if trace_shifted then
+ report_shifted("width %p, nodes %a, text %a",width,n_tostring(first,last),n_tosequence(first,last,true))
+ end
+ return head
end
- local raise = data.dy * dimenfactor(data.unit,fontdata[getfont(first)])
- setshift(list,raise)
- setwhd(list,width,height,depth)
- if trace_shifted then
- report_shifted("width %p, nodes %a, text %a",width,n_tostring(first,last),n_tosequence(first,last,true))
+
+ shifts.handler = function(head)
+ local data = attributes.values[a_shifted]
+ if data then
+ head = processwords(a_shifted,data,flush_shifted,head)
+ end
+ return head
end
- return head
-end
-shifts.handler = function(head)
- return processwords(a_shifted,data,flush_shifted,head)
-end
+ implement {
+ name = "setshift",
+ actions = shifts.set,
+ arguments = {
+ {
+ { "continue" },
+ { "unit" },
+ { "method", "integer" },
+ { "dy", "number" },
+ }
+ }
+ }
-function shifts.enable()
- enableaction("shipouts","nodes.shifts.handler")
end
-- linefillers
-local linefillers = nodes.linefillers or { }
-nodes.linefillers = linefillers
-linefillers.data = linefillers.data or { }
+do
-storage.register("nodes/linefillers/data", linefillers.data, "nodes.linefillers.data")
+ local linefillers = nodes.linefillers or { }
+ nodes.linefillers = linefillers
+ local enabled = false
-local data = linefillers.data
+ local usernutrule = nuts.rules.userrule
-function linefillers.define(settings)
- local nofdata = #data + 1
- data[nofdata] = settings
- return nofdata
-end
+ function linefillers.set(settings)
+ if not enabled then
+ enableaction("finalizers","nodes.linefillers.handler")
+ enabled = true
+ end
+ texsetattribute(a_linefiller,registervalue(a_linefiller,settings))
+ end
-local function linefiller(current,data,width,location)
- local height = data.height
- local depth = data.depth
- local mp = data.mp
- local ma = data.ma
- local ca = data.ca
- local ta = data.ta
- if mp and mp ~= "" then
- return usernutrule {
- width = width,
- height = height,
- depth = depth,
- type = "mp",
- line = data.rulethickness,
- data = mp,
- ma = ma,
- ca = ca,
- ta = ta,
- option = location,
- direction = getdirection(current),
- }
- else
- return setcoloring(new_rule(width,height,depth),ma,ca,ta)
+ local function linefiller(current,data,width,location)
+ local height = data.height
+ local depth = data.depth
+ local mp = data.mp
+ local ma = data.ma
+ local ca = data.ca
+ local ta = data.ta
+ if mp and mp ~= "" then
+ return usernutrule {
+ width = width,
+ height = height,
+ depth = depth,
+ type = "mp",
+ line = data.rulethickness,
+ data = mp,
+ ma = ma,
+ ca = ca,
+ ta = ta,
+ option = location,
+ direction = getdirection(current),
+ }
+ else
+ return setcoloring(new_rule(width,height,depth),ma,ca,ta)
+ end
end
-end
-function linefillers.filler(current,data,width,height,depth)
- if width and width > 0 then
- local height = height or data.height or 0
- local depth = depth or data.depth or 0
- if (height + depth) ~= 0 then
- local mp = data.mp
- local ma = data.ma
- local ca = data.ca
- local ta = data.ta
- if mp and mp ~= "" then
- return usernutrule {
- width = width,
- height = height,
- depth = depth,
- type = "mp",
- line = data.rulethickness,
- data = mp,
- ma = ma,
- ca = ca,
- ta = ta,
- option = location,
- direction = getdirection(current),
- }
- else
- return setcoloring(new_rule(width,height,depth),ma,ca,ta)
+ function linefillers.filler(current,data,width,height,depth)
+ if width and width > 0 then
+ local height = height or data.height or 0
+ local depth = depth or data.depth or 0
+ if (height + depth) ~= 0 then
+ local mp = data.mp
+ local ma = data.ma
+ local ca = data.ca
+ local ta = data.ta
+ if mp and mp ~= "" then
+ return usernutrule {
+ width = width,
+ height = height,
+ depth = depth,
+ type = "mp",
+ line = data.rulethickness,
+ data = mp,
+ ma = ma,
+ ca = ca,
+ ta = ta,
+ option = location,
+ direction = getdirection(current),
+ }
+ else
+ return setcoloring(new_rule(width,height,depth),ma,ca,ta)
+ end
end
end
end
-end
-local function getskips(list) -- this could be a helper
- local ls = nil
- local rs = nil
- local is = nil
- local pl = nil
- local pr = nil
- local ok = false
- for n, subtype in nextglue, list do
- if subtype == rightskip_code then
- rs = n
- elseif subtype == parfillrightskip_code then
- pr = n
- elseif subtype == leftskip_code then
- ls = n
- elseif subtype == indentskip_code then
- is = n
- elseif subtype == parfillleftskip_code then
- pl = n
+ local function getskips(list) -- this could be a helper
+ local ls = nil
+ local rs = nil
+ local is = nil
+ local pl = nil
+ local pr = nil
+ local ok = false
+ for n, subtype in nextglue, list do
+ if subtype == rightskip_code then
+ rs = n
+ elseif subtype == parfillrightskip_code then
+ pr = n
+ elseif subtype == leftskip_code then
+ ls = n
+ elseif subtype == indentskip_code then
+ is = n
+ elseif subtype == parfillleftskip_code then
+ pl = n
+ end
end
+ return is, ls, pl, pr, rs
end
- return is, ls, pl, pr, rs
-end
-function linefillers.handler(head)
- -- we have a normalized line ..
- for current, id, subtype, list in nextlist, head do
- if subtype == linelist_code and list then
- 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
- --
- local is, ls, pl, pr, rs = getskips(list)
- if ls and rs then
- if location == v_left or location == v_both then
- local indentation = is and getwidth(is) or 0
- local leftfixed = ls and getwidth(ls) or 0
- local lefttotal = ls and effectiveglue(ls,current) or 0
- local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance
- if width > threshold then
- if is then
- setwidth(is,0)
- end
- setglue(ls,leftlocal and getwidth(ls) or nil)
- if distance > 0 then
- insertnodeafter(list,ls,new_kern(distance))
- end
- insertnodeafter(list,ls,linefiller(current,data,width,"left"))
+ linefillers.handler = function(head)
+ local data = attributes.values[a_linefiller]
+ if data then
+ -- we have a normalized line ..
+ for current, id, subtype, list in nextlist, head do
+ if subtype == linelist_code and list then
+ local a = getattr(current,a_linefiller)
+ if a then
+ local data = data[a]
+ 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
- end
- --
- if location == v_right or location == v_both then
- local rightfixed = rs and getwidth(rs) or 0
- local righttotal = rs and effectiveglue(rs,current) or 0
- local parfixed = pr and getwidth(pr) or 0
- local partotal = pr and effectiveglue(pr,current) or 0
- local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance
- if width > threshold then
- if pr then
- setglue(pr)
+ --
+ local is, ls, pl, pr, rs = getskips(list)
+ if ls and rs then
+ if location == v_left or location == v_both then
+ local indentation = is and getwidth(is) or 0
+ local leftfixed = ls and getwidth(ls) or 0
+ local lefttotal = ls and effectiveglue(ls,current) or 0
+ local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance
+ if width > threshold then
+ if is then
+ setwidth(is,0)
+ end
+ setglue(ls,leftlocal and getwidth(ls) or nil)
+ if distance > 0 then
+ insertnodeafter(list,ls,new_kern(distance))
+ end
+ insertnodeafter(list,ls,linefiller(current,data,width,"left"))
+ end
end
- setglue(rs,rightlocal and getwidth(rs) or nil)
- if distance > 0 then
- insertnodebefore(list,rs,new_kern(distance))
+ --
+ if location == v_right or location == v_both then
+ local rightfixed = rs and getwidth(rs) or 0
+ local righttotal = rs and effectiveglue(rs,current) or 0
+ local parfixed = pr and getwidth(pr) or 0
+ local partotal = pr and effectiveglue(pr,current) or 0
+ local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance
+ if width > threshold then
+ if pr then
+ setglue(pr)
+ end
+ setglue(rs,rightlocal and getwidth(rs) or nil)
+ if distance > 0 then
+ insertnodebefore(list,rs,new_kern(distance))
+ end
+ insertnodebefore(list,rs,linefiller(current,data,width,"right"))
+ end
end
- insertnodebefore(list,rs,linefiller(current,data,width,"right"))
+ else
+ -- error, not a properly normalized line
end
end
- else
- -- error, not a properly normalized line
end
end
end
end
+ return head
end
- return head
-end
-
-local enable = false
-
-function linefillers.enable()
- if not enable then
- -- we could now nil it
- enableaction("finalizers","nodes.linefillers.handler")
- enable = true
- end
-end
-
--- interface
-
-implement {
- name = "definerule",
- actions = { rules.define, context },
- arguments = {
- {
- { "continue" },
- { "unit" },
- { "order" },
- { "method", "integer" },
- { "offset", "number" },
- { "rulethickness" },
- { "dy", "number" },
- { "max", "number" },
- { "ma", "integer" },
- { "ca", "integer" },
- { "ta", "integer" },
- { "mp" },
- { "empty" },
- { "text", "integer" },
- { "repeat" },
- }
- }
-}
-
-implement {
- name = "enablerules",
- onlyonce = true,
- actions = rules.enable
-}
-implement {
- name = "enableextrarules",
- onlyonce = true,
- actions = rules.enableextra
-}
-
-implement {
- name = "defineshift",
- actions = { shifts.define, context },
- arguments = {
- {
- { "continue" },
- { "unit" },
- { "method", "integer" },
- { "dy", "number" },
- }
- }
-}
-
-implement {
- name = "enableshifts",
- onlyonce = true,
- actions = shifts.enable
-}
-
-implement {
- name = "definelinefiller",
- actions = { linefillers.define, context },
- arguments = {
- {
- { "method", "integer" },
- { "location", "string" },
- { "scope", "string" },
- { "mp", "string" },
- { "ma", "integer" },
- { "ca", "integer" },
- { "ta", "integer" },
- { "depth", "dimension" },
- { "height", "dimension" },
- { "distance", "dimension" },
- { "threshold", "dimension" },
- { "rulethickness", "dimension" },
+ implement {
+ name = "setlinefiller",
+ actions = linefillers.set,
+ arguments = {
+ {
+ { "method", "integer" },
+ { "location", "string" },
+ { "scope", "string" },
+ { "mp", "string" },
+ { "ma", "integer" },
+ { "ca", "integer" },
+ { "ta", "integer" },
+ { "depth", "dimension" },
+ { "height", "dimension" },
+ { "distance", "dimension" },
+ { "threshold", "dimension" },
+ { "rulethickness", "dimension" },
+ }
}
}
-}
-implement {
- name = "enablelinefillers",
- onlyonce = true,
- actions = linefillers.enable
-}
+end
-- We add a bonus feature here (experiment):
interfaces.implement {
name = "autorule",
+ protected = true,
+ public = true,
arguments = {
{
{ "width", "dimension" },
diff --git a/tex/context/base/mkxl/node-rul.mkxl b/tex/context/base/mkxl/node-rul.mkxl
index 5f9eef7cb..231a2f32b 100644
--- a/tex/context/base/mkxl/node-rul.mkxl
+++ b/tex/context/base/mkxl/node-rul.mkxl
@@ -74,76 +74,20 @@
\registerctxluafile{node-rul}{autosuffix,optimize}
\installcorenamespace{bar}
-% \installcorenamespace{barindex}
-\installcorenamespace{barattribute}
\installcorenamespace{barstack}
\installcommandhandler \??bar {bar} \??bar
-\newtoks\t_node_rules_checklist
-
-\mutable\let\c_node_rules_index\relax % temporary synonym (can be shared)
-\mutable\let\p_node_rules_color\empty
+\mutable\let\p_node_color \empty % of just \p_*
+\mutable\let\p_node_text \empty
+\mutable\let\p_node_offset\empty
\aliased\let\setupbars\setupbar
\appendtoks
- \ifempty\currentbar
- \the\t_node_rules_checklist
- \else
- \node_rules_define
- \fi
-\to \everysetupbar
-
-\appendtoks
-% \ifcsname\??barindex\currentbar\endcsname
-% \lastnamedcs\zerocount
-% \else
-% \expandafter\newcount\csname\??barindex\currentbar\endcsname
-% \fi
- % \normalexpanded{\t_node_rules_checklist{\node_rules_redefine{\currentbar}\the\t_node_rules_checklist}}%
- \normalexpanded{\t_node_rules_checklist{\the\t_node_rules_checklist\relax\node_rules_redefine{\currentbar}}}%
- % \etoksapp\t_node_rules_checklist{\node_rules_redefine{\currentbar}}%
- \node_rules_define
- \frozen\instance\setuevalue\currentbar{\node_rules_direct{\currentbar}}%
+ \frozen\protected\instance\edefcsname\currentbar\endcsname{\node_rules_direct{\currentbar}}%
\to \everydefinebar
-\newbox\b_node_rules
-
-% todo: delay mp graphic
-
-\protected\def\node_rules_define
- {\edef\p_node_rules_color{\barparameter\c!color}%
- \edef\p_node_text{\barparameter\c!text}%
- \ifempty\p_node_text\else
- \setbox\b_node_rules\hbox{\p_node_text}%
- \fi
- \expandafter\integerdef\csname\??barattribute\currentbar\endcsname
- \clf_definerule
- continue {\barparameter\c!continue}%
- unit {\barparameter\c!unit}%
- order {\barparameter\c!order}%
- rulethickness {\barparameter\c!rulethickness}%
- method \barparameter\c!method
- max \barparameter\c!max\space % number
- mp {\includeMPgraphic{\barparameter\c!mp}}
- ma \c_attr_colormodel
- ca \rawcolorattribute\p_node_rules_color
- ta \rawtransparencyattribute\p_node_rules_color
- offset \barparameter\c!offset\space % number
- dy \barparameter\c!dy\space % number
- empty {\barparameter\c!empty}%
- \ifempty\p_node_text\else
- % not that useful and efficient, more for testing something
- text \b_node_rules
- repeat {\barparameter\c!repeat}%
- \fi
- \relax
- \relax}
-
-\protected\def\node_rules_redefine#1%
- {\def\currentbar{#1}\node_rules_define}
-
\protected\def\node_rules_direct#1%
{\groupedcommand
{\node_rules_set{#1}\barparameter\c!left}%
@@ -152,25 +96,6 @@
\permanent\protected\def\inlinebar[#1]%
{\node_rules_direct{#1}}
-% \protected\def\inlinecurrentbar
-% {\node_rules_direct{\currentbar}}
-
-% store in properties
-
-% \permanent\protected\def\node_rules_set#1% maybe reverse the 1000 (also maybe use more attributes instead of settings)
-% {\edef\currentbar{#1}%
-% \usebarstyleandcolor\c!foregroundstyle\c!foregroundcolor
-% % maybe: \usebarstyleandcolor\c!textgroundstyle\c!textcolor
-% % todo: move this to lua .. we callout anyway
-% \expandafter\let\expandafter\c_node_rules_index\csname\??barindex#1\endcsname
-% \advance\c_node_rules_index\plusone
-% \clf_enablerules % will be relaxed
-% \c_attr_ruled\numexpr
-% \plusthousand*\c_node_rules_index
-% % optimizing this one needs testing
-% +\csname\??barattribute#1\ifcsname\??bar#1:\number\c_node_rules_index\s!parent\endcsname:\number\c_node_rules_index\fi\endcsname
-% \relax}
-
%D \overbar{Ãœber} \underbar{Unterstrich \underbar{steigt \overbar{auf} den \underbar{Unterberg}}}.
%D
%D \underbar {\underbar {\samplefile{tufte}}}\par
@@ -181,49 +106,44 @@
%D \underbar {\underdots{\samplefile{tufte}}}\par
%D \underdots{\underdots{\samplefile{tufte}}}\par
-\newcount \c_node_rules_index
-\integerdef \c_node_rules_used \zerocount
-\mutable\let\m_node_rules_previous_bar\empty
+\newcount\c_node_rules_nesting % todo: same as colors
+\newcount\c_node_rules_level
+\newcount\c_node_rules_up
+\newcount\c_node_rules_down
-\permanent\protected\def\node_rules_set#1% maybe reverse the 1000 (also maybe use more attributes instead of settings)
- {\let\m_node_rules_previous_bar\currentbar
- \edef\currentbar{#1}%
+\permanent\protected\def\node_rules_set#1%
+ {\edef\currentbar{#1}%
+ \advance\c_node_rules_level\plusone
\usebarstyleandcolor\c!foregroundstyle\c!foregroundcolor
- % maybe: \usebarstyleandcolor\c!textgroundstyle\c!textcolor
- % todo: move this to lua .. we callout anyway
- % \expandafter\let\expandafter\c_node_rules_index\csname\??barindex#1\endcsname
- \advance\c_node_rules_index\plusone
- \clf_enablerules % will be relaxed
- \edef\p_level{\barparameter\c!level}%
- \ifx\p_level\v!yes
- \integerdef\c_node_rules_used\c_node_rules_index
- \c_attr_ruled
- \orelse\ifx\p_level\v!auto
- \integerdef\c_node_rules_used\c_node_rules_index
- \ifempty\m_node_rules_previous_bar
- \c_attr_ruled
- \orelse\ifx\m_node_rules_previous_bar\currentbar
- \c_attr_ruled
- \else
- \clf_enableextrarules % will be relaxed
- \c_attr_ruledextra
+ \edef\p_node_color {\barparameter\c!color}% todo
+ \edef\p_node_text {\barparameter\c!text}%
+ \edef\p_node_offset{\barparameter\c!offset}%
+ % better is a dedicated key: up/down .. todo
+ \advance\ifdim\p_node_offset\onepoint<\zeropoint\c_node_rules_down\else\c_node_rules_up\fi\plusone
+ \clf_setrule
+ continue {\barparameter\c!continue}%
+ unit {\barparameter\c!unit}%
+ order {\barparameter\c!order}%
+ level \c_node_rules_level
+ stack \ifdim\p_node_offset\onepoint<\zeropoint\c_node_rules_down\else\c_node_rules_up\fi
+ rulethickness {\barparameter\c!rulethickness}%
+ method \barparameter\c!method
+ max \barparameter\c!max\space % number
+ mp {\includeMPgraphic{\barparameter\c!mp}}
+ ma \c_attr_colormodel
+ ca \rawcolorattribute\p_node_color
+ ta \rawtransparencyattribute\p_node_color
+ offset \p_node_offset\space % number
+ dy \barparameter\c!dy\space % number, also fraction
+ empty {\barparameter\c!empty}%
+ \ifempty\p_node_text\else
+ text \hbox{\p_node_text}%
+ repeat {\barparameter\c!repeat}%
\fi
- \orelse\ifchknum\p_level\or
- \integerdef\c_node_rules_used\p_level
- \c_attr_ruled
- \else
- \integerdef\c_node_rules_used\c_node_rules_index
- \c_attr_ruled
- \fi
- \numexpr
- \plusthousand*\c_node_rules_used
- % optimizing this one needs testing
- +\csname\??barattribute#1\ifcsname\??bar#1:\number\c_node_rules_index\s!parent\endcsname:\number\c_node_rules_used\fi\endcsname
\relax}
\permanent\protected\def\resetbar
- {\c_attr_ruled \attributeunsetvalue
- \c_attr_ruledextra\attributeunsetvalue}
+ {\c_attr_ruled\attributeunsetvalue}
\permanent\protected\def\nobar
{\groupedcommand
@@ -248,13 +168,11 @@
% ungrouped % todo: use the lua based stacker
-\newcount\c_node_rules_nesting % todo: same as colors
-
\permanent\protected\def\pushbar[#1]%
{\global\advance\c_node_rules_nesting\plusone
\edefcsname\??barstack\number\c_node_rules_nesting\endcsname
- {\c_attr_ruled \the\c_attr_ruled
- \c_attr_ruledextra\the\c_attr_ruledextra}%
+ {\c_node_rules_level\the\c_node_rules_level
+ \c_attr_ruled \the\c_attr_ruled}%
\node_rules_set{#1}}
\permanent\protected\def\popbar
@@ -415,59 +333,25 @@
%D This will move: (a bit duplicated)
\installcorenamespace{shift}
-\installcorenamespace{shiftindex}
-\installcorenamespace{shiftattribute}
\installcommandhandler \??shift {shift} \??shift
-\newtoks\t_node_shifts_checklist
-
-\mutable\let\c_node_shifts_index\relax % temporary synonym (can be shared)
-
\let\setupshifts\setupshift
\appendtoks
- \ifempty\currentshift
- \the\t_node_shifts_checklist
- \else
- \node_shifts_define
- \fi
-\to \everysetupshift
-
-\appendtoks
- \ifcsname\??shiftindex\currentshift\endcsname
- \lastnamedcs\zerocount
- \else
- \expandafter\newcount\csname\??shiftindex\currentshift\endcsname
- \fi
- \normalexpanded{\t_node_shifts_checklist{\the\t_node_shifts_checklist\node_shifts_redefine{\currentshift}}}% order ?
- \node_shifts_define
- \frozen\instance\setuevalue\currentshift{\node_shifts_direct{\currentshift}}%
+ \frozen\protected\instance\edefcsname\currentshift\endcsname{\node_shifts_direct{\currentshift}}%
\to \everydefineshift
-\protected\def\node_shifts_define
- {\edefcsname\??shiftattribute\currentshift\endcsname{\number
- \clf_defineshift
- continue {\shiftparameter\c!continue}%
- unit {\shiftparameter\c!unit}%
- method \shiftparameter\c!method
- dy \shiftparameter\c!dy % number
- \relax}}
-
-\protected\def\node_shifts_redefine#1%
- {\def\currentshift{#1}\node_shifts_define}
-
\protected\def\node_shifts_set#1% todo: check parent ! todo: move attr etc to lua
{\def\currentshift{#1}%
- \expandafter\let\expandafter\c_node_shifts_index\csname\??shiftindex#1\endcsname
- \advance\c_node_shifts_index\plusone
- \clf_enableshifts % will be relaxed
- \c_attr_shifted\numexpr
- \plusthousand*\c_node_shifts_index
- +\csname\??shiftattribute#1\ifcsname\??shift#1:\number\c_node_shifts_index\s!parent\endcsname:\number\c_node_shifts_index\fi\endcsname
- \relax
\useshiftstyleandcolor\c!style\c!color
- \dosetupisolatedalign{\shiftparameter\c!align}} % weird feature that i probably needed once
+ \dosetupisolatedalign{\shiftparameter\c!align}% a weird feature that i probably needed once
+ \clf_setshift
+ continue {\shiftparameter\c!continue}%
+ unit {\shiftparameter\c!unit}%
+ method \shiftparameter\c!method
+ dy \shiftparameter\c!dy % number
+ \relax}
\permanent\protected\def\startshift[#1]%
{\begingroup
@@ -497,8 +381,8 @@
% we want these always so ...
-\expandafter\let\expandafter\shiftup \csname\v!shiftup \endcsname
-\expandafter\let\expandafter\shiftdown \csname\v!shiftdown \endcsname
+\expandafter\let\expandafter\shiftup \csname\v!shiftup \endcsname
+\expandafter\let\expandafter\shiftdown\csname\v!shiftdown\endcsname
% This is a weird helper.. these might go away:
@@ -522,67 +406,29 @@
% Phillips on drums). The Amsterdam concert is equally energizing.
\installcorenamespace{linefiller}
-\installcorenamespace{linefillerindex}
-\installcorenamespace{linefillerattribute}
\installcommandhandler \??linefiller {linefiller} \??linefiller
\definesystemattribute[linefiller][public]
-\newtoks\t_node_linefiller_checklist
-
-\mutable\let\c_node_linefiller_index\relax % temporary synonym (can be shared)
-
\aliased\let\setuplinefillers\setuplinefiller
-\appendtoks
- \ifempty\currentlinefiller
- \the\t_node_linefiller_checklist
- \else
- \node_linefiller_define
- \fi
-\to \everysetuplinefiller
-
-\appendtoks
- \ifcsname\??linefillerindex\currentlinefiller\endcsname
- \lastnamedcs\zerocount
- \else
- \expandafter\newcount\csname\??linefillerindex\currentlinefiller\endcsname
- \fi
- \etoksapp\t_node_linefiller_checklist{\t_node_linefiller_checklist\node_linefiller_redefine{\currentlinefiller}}%
- \node_linefiller_define
-\to \everydefinelinefiller
-
-\protected\def\node_linefiller_define
- {\edef\p_node_rules_color{\linefillerparameter\c!color}%
- \expandafter\integerdef\csname\??linefillerattribute\currentlinefiller\endcsname
- \clf_definelinefiller
+\protected\def\node_linefiller_set#1% todo: check parent ! todo: move attr etc to lua
+ {\def\currentlinefiller{#1}%
+ \edef\p_node_color{\linefillerparameter\c!color}%
+ \clf_setlinefiller
%method \linefillerparameter\c!method
location {\linefillerparameter\c!location}%
scope {\linefillerparameter\c!scope}%
mp {\includeMPgraphic{\linefillerparameter\c!mp}}%
ma \c_attr_colormodel
- ca \rawcolorattribute\p_node_rules_color
- ta \rawtransparencyattribute\p_node_rules_color
+ ca \rawcolorattribute\p_node_color
+ ta \rawtransparencyattribute\p_node_color
height \dimexpr\linefillerparameter\c!height\relax
depth \dimexpr\linefillerparameter\c!depth\relax
distance \dimexpr\linefillerparameter\c!distance\relax
threshold \dimexpr\linefillerparameter\c!threshold\relax
rulethickness \dimexpr\linefillerparameter\c!rulethickness\relax
- \relax
- \relax}
-
-\protected\def\node_linefiller_redefine#1%
- {\def\currentlinefiller{#1}\node_linefiller_define}
-
-\protected\def\node_linefiller_set#1% todo: check parent ! todo: move attr etc to lua
- {\def\currentlinefiller{#1}%
- \expandafter\let\expandafter\c_node_linefiller_index\csname\??linefillerindex#1\endcsname
- \advance\c_node_linefiller_index\plusone
- \clf_enablelinefillers
- \c_attr_linefiller\numexpr
- \plusthousand*\c_node_linefiller_index
- +\csname\??linefillerattribute#1\ifcsname\??linefiller#1:\number\c_node_linefiller_index\s!parent\endcsname:\number\c_node_linefiller_index\fi\endcsname
\relax}
\permanent\tolerant\protected\def\startlinefiller[#1]#*[#2]%
@@ -653,7 +499,6 @@
\node_linefiller_set{#3}% already sets the attribute
#1%
attr \backgroundattribute \plusone
- % attr \linefillerattribute \the\c_attr_linefiller
{\box\nextbox}%
\egroup}%
#2}
@@ -664,6 +509,6 @@
%D Bonus:
-\permanent\protected\def\autorule{\clf_autorule} % todo: public implementor
+% \autorule : defined at the lua end
\protect \endinput
diff --git a/tex/context/base/mkxl/node-scn.lmt b/tex/context/base/mkxl/node-scn.lmt
index 947b9e25c..1530174c2 100644
--- a/tex/context/base/mkxl/node-scn.lmt
+++ b/tex/context/base/mkxl/node-scn.lmt
@@ -41,6 +41,8 @@ local userskip_code = gluecodes.userskip
local spaceskip_code = gluecodes.spaceskip
local xspaceskip_code = gluecodes.xspaceskip
local leaders_code = gluecodes.leaders
+local rightfillskip_code = gluecodes.rightparfillskip
+local righthangskip_code = gluecodes.righthangskip
local fontkern_code = kerncodes.fontkern
@@ -111,13 +113,15 @@ nuts.striprange = striprange
-- todo: switching inside math
--- handlers
+-- handlers (some are very specialized and demanding)
-local function processwords(attribute,data,flush,head,parent,skip) -- we have hlistdir and local dir
+local maxlevel = 1
+
+local function processwords(nesting,attribute,data,flush,head,parent,skip) -- we have hlistdir and local dir
local n = head
if n then
- local f, l, a, d, i, class
- local continue, leaders, strip, level = false, false, false, true, -1
+ local f, l, a, d, class
+ local continue, leaders, strip, level = false, false, true, -1
while n do
local id = getid(n)
if id == glyph_code
@@ -127,6 +131,36 @@ local function processwords(attribute,data,flush,head,parent,skip) -- we have hl
or id == boundary_code
then
local aa = getattr(n,attribute)
+ -- new approach
+ local dd, ll
+ if aa then
+ dd = data[aa]
+ ll = dd.level or 1
+ if nesting == 1 and ll > maxlevel then
+ maxlevel = ll
+ end
+ if ll == nesting then
+ -- we're okay
+ else
+ while true do
+ local nestingvalue = dd.nestingvalue
+ if nestingvalue then
+ dd = dd.nestingdata
+ ll = dd.level
+ if ll == nesting then
+ aa = nestingvalue
+ break
+ end
+ else
+ -- no matching level found
+ aa = nil
+ dd = nil
+ break
+ end
+ end
+ end
+ end
+ -- old approach
if aa and aa ~= skip then
if aa == a then
if not f then -- ?
@@ -134,99 +168,121 @@ local function processwords(attribute,data,flush,head,parent,skip) -- we have hl
end
l = n
else
- -- possible extensions: when in same class then keep spanning
- local newlevel, newclass = floor(aa/1000), aa%1000 -- will be configurable
- -- strip = not continue or level == 1 -- 0
if f then
- if class == newclass then -- and newlevel > level then
- head = flush(head,f,l,d,level,parent,false), true
+ if class == aa then -- and newlevel > level then
+ head = flush(head,f,l,d,level,parent,false)
else
- head = flush(head,f,l,d,level,parent,strip), true
+ head = flush(head,f,l,d,level,parent,strip)
end
end
f, l, a = n, n, aa
- level, class = newlevel, newclass
- d = data[class]
+ d = dd
+ class = aa
if d then
- local c = d.continue
- leaders = c == v_all
- continue = leaders or c == v_yes
+ continue = d.continue
+ level = d.level or 1
+ leaders = continue == v_all
+ continue = leaders or continue == v_yes
else
continue = true
+ level = 1
+ leaders = false
end
end
else
if f then
- head = flush(head,f,l,d,level,parent,strip), true
+ head = flush(head,f,l,d,level,parent,strip)
end
f, l, a = nil, nil, nil
end
if id == hlist_code then
local list = getlist(n)
if list then
- setlist(n,processwords(attribute,data,flush,list,n,aa))
+ setlist(n,processwords(nesting,attribute,data,flush,list,n,aa))
end
end
--- elseif id == disc_code or id == boundary_code then
--- if f then
--- l = n
--- end
- elseif id == kern_code and getsubtype(n) == fontkern_code then
- if f then
- l = n
+ goto next
+ -- elseif id == disc_code or id == boundary_code then
+ -- if f then
+ -- l = n
+ -- end
+ -- goto next
+ elseif id == kern_code then
+ if getsubtype(n) == fontkern_code then
+ if f then
+ l = n
+ end
+ goto next
+ else
+ goto rest
end
elseif id == math_code then
-- otherwise not consistent: a $b$ c vs a $b+c$ d etc
-- we need a special (optional) go over math variant
if f then
- head = flush(head,f,l,d,level,parent,strip), true
+ head = flush(head,f,l,d,level,parent,strip)
f, l, a = nil, nil, nil
end
+ goto next
elseif id == hlist_code or id == vlist_code then
if f then
- head = flush(head,f,l,d,level,parent,strip), true
+ head = flush(head,f,l,d,level,parent,strip)
f, l, a = nil, nil, nil
end
local list = getlist(n)
if list then
- setlist(n,processwords(attribute,data,flush,list,n,skip))
+ setlist(n,processwords(nesting,attribute,data,flush,list,n,skip))
end
+ goto next
elseif id == dir_code then -- only changes in dir, we assume proper boundaries
if f then
l = n
end
- elseif f then
+ goto next
+ end
+ ::rest::
+ if f then
if continue then
if id == penalty_code then
l = n
+ goto next
-- elseif id == kern_code then
-- l = n
+ -- goto next
elseif id == glue_code then
-- catch \underbar{a} \underbar{a} (subtype test is needed)
local subtype = getsubtype(n)
if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leaders_code)) then
l = n
else
- head = flush(head,f,l,d,level,parent,strip), true
+ head = flush(head,f,l,d,level,parent,strip)
f, l, a = nil, nil, nil
end
end
else
- head = flush(head,f,l,d,level,parent,strip), true
+ head = flush(head,f,l,d,level,parent,strip)
f, l, a = nil, nil, nil
end
end
+ ::next::
n = getnext(n)
end
if f then
- head = flush(head,f,l,d,level,parent,strip), true
+ head = flush(head,f,l,d,level,parent,strip)
end
end
return head
end
nuts.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir
- return processwords(attribute,data,flush,head,parent)
+ -- print("processing words at level "..1)io.flush()
+ maxlevel = 1
+ head = processwords(1,attribute,data,flush,head,parent)
+ for i=2,maxlevel do
+ -- print("processing words at level "..i)io.flush()
+ head = processwords(i,attribute,data,flush,head,parent)
+ end
+ return head
end
-- works on lines !
@@ -240,7 +296,7 @@ local function processranges(attribute,flush,head,parent,depth,skip)
local id = getid(n)
if id == glyph_code or id == rule_code then
local aa = getattr(n,attribute)
--- if aa and (not skip or aa ~= skip) then
+ -- if aa and (not skip or aa ~= skip) then
if aa then
if aa == a then
if not f then
@@ -249,13 +305,13 @@ local function processranges(attribute,flush,head,parent,depth,skip)
l = n
else
if f then
- head = flush(head,f,l,a,parent,depth), true
+ head = flush(head,f,l,a,parent,depth)
end
f, l, a = n, n, aa
end
else
if f then
- head = flush(head,f,l,a,parent,depth), true
+ head = flush(head,f,l,a,parent,depth)
end
f, l, a = nil, nil, nil
end
@@ -265,16 +321,21 @@ local function processranges(attribute,flush,head,parent,depth,skip)
else
-- weird
end
- elseif id == kern_code and getsubtype(n) == fontkern_code then
- if f then
- l = n
+ elseif id == kern_code then
+ if getsubtype(n) == fontkern_code then
+ if f then
+ l = n
+ end
end
-- elseif id == penalty_code then
elseif id == glue_code then
-- todo: leaders
+-- if getsubtype(n) == rightfillskip_code or getsubtype(n) == righthangskip_code then
+-- break
+-- end
elseif id == hlist_code or id == vlist_code then
local aa = getattr(n,attribute)
--- if aa and (not skip or aa ~= skip) then
+ -- if aa and (not skip or aa ~= skip) then
if aa then
if aa == a then
if not f then
@@ -301,7 +362,7 @@ local function processranges(attribute,flush,head,parent,depth,skip)
n = getnext(n)
end
if f then
- head = flush(head,f,l,a,parent,depth), true
+ head = flush(head,f,l,a,parent,depth)
end
end
return head
diff --git a/tex/context/base/mkxl/node-ser.lmt b/tex/context/base/mkxl/node-ser.lmt
index 333784803..089009260 100644
--- a/tex/context/base/mkxl/node-ser.lmt
+++ b/tex/context/base/mkxl/node-ser.lmt
@@ -39,12 +39,11 @@ local canbezero = {
}
local canbelist = {
- attribute = "<attribute>",
- node = "<node>",
- token = "<token>",
- attribute_list = "<attributes>",
- node_list = "<nodes>",
- token_list = "<tokens>",
+ attribute = "<attribute>",
+ node = "<node>",
+ token = "<token>",
+ node_list = "<nodes>",
+ token_list = "<tokens>",
}
local canbeignored = {
@@ -68,10 +67,12 @@ nodes.fieldtypes = fieldtypes
local function astable(n)
n = tonode(n)
if n then
- local fields = fieldtypes[n.id]
+ local id = n.id
+ local fields = fieldtypes[id]
if fields then
- local result = { }
- for field, fieldtype in sortedhash(fields) do
+ local subtype = n.subtype
+ local result = { }
+ for field, fieldtype in sortedhash(fields) do -- no need to sort
local value = n[field]
if value then
if canbeignored[field] then
@@ -86,16 +87,12 @@ local function astable(n)
end
end
end
- local id = n.id
- if id then
- id = nodecodes[id]
- result.id = id
- local subtype = n.subtype
- if subtype then
- local subtypes = subtypes[id]
- if subtypes then
- result.subtype = subtypes[subtype]
- end
+ id = nodecodes[id]
+ result.id = id
+ if subtype then
+ local subtypes = subtypes[id]
+ if subtypes then
+ result.subtype = subtypes[subtype]
end
end
return result
@@ -119,7 +116,7 @@ local function to_table(n,flat,verbose,noattributes,done)
for field, fieldtype in sortedhash(fields) do
local value = n[field]
if value then
- if fieldtype == "attributelist" or fieldtype == "attribute" or fieldtype == "attribute_list" then
+ if fieldtype == "attribute" then
if noattributes then
result[value] = canbeignored[value]
else
diff --git a/tex/context/base/mkxl/node-tra.lmt b/tex/context/base/mkxl/node-tra.lmt
index 214c8a27c..1ef1bb8ad 100644
--- a/tex/context/base/mkxl/node-tra.lmt
+++ b/tex/context/base/mkxl/node-tra.lmt
@@ -481,6 +481,8 @@ end
number.todimen = numbertodimen
nodes .todimen = nodetodimen
+-- todo: dk
+
function number.topoints (n,fmt) return numbertodimen(n,"pt",fmt) end
function number.toinches (n,fmt) return numbertodimen(n,"in",fmt) end
function number.tocentimeters (n,fmt) return numbertodimen(n,"cm",fmt) end
diff --git a/tex/context/base/mkxl/node-tsk.lmt b/tex/context/base/mkxl/node-tsk.lmt
index ca18c9c3b..c1cdf91a4 100644
--- a/tex/context/base/mkxl/node-tsk.lmt
+++ b/tex/context/base/mkxl/node-tsk.lmt
@@ -679,17 +679,32 @@ return function(head)
end
]],
+-- process = [[
+-- local tonut = nodes.tonut
+-- local tonode = nodes.nuts.tonode
+--
+-- %localize%
+--
+-- return function(head,groupcode)
+-- local nuthead = tonut(head)
+--
+-- return function(nuthead,groupcode)
+--
+-- %actions%
+-- return tonode(nuthead)
+-- end
+-- ]],
+
process = [[
local tonut = nodes.tonut
local tonode = nodes.nuts.tonode
%localize%
-return function(head,groupcode)
- local nuthead = tonut(head)
+return function(nuthead,groupcode)
%actions%
- return tonode(nuthead)
+ return nuthead
end
]],
diff --git a/tex/context/base/mkxl/pack-box.mkxl b/tex/context/base/mkxl/pack-box.mkxl
index 77b0bbc69..43934f7f7 100644
--- a/tex/context/base/mkxl/pack-box.mkxl
+++ b/tex/context/base/mkxl/pack-box.mkxl
@@ -465,7 +465,7 @@
\permanent\tolerant\protected\def\ornamenttext[#1]#*[#2]% takes another argument
{\bgroup
- \doifelseassignment{#1}
+ \doifelseassignment{#1}%
{\letdummyparameter\c!alternative\v!a
\getdummyparameters[#1]%
\doifelse{\directdummyparameter\c!alternative}\v!a
diff --git a/tex/context/base/mkxl/page-imp.mkxl b/tex/context/base/mkxl/page-imp.mkxl
index 8271d7aad..4ef318985 100644
--- a/tex/context/base/mkxl/page-imp.mkxl
+++ b/tex/context/base/mkxl/page-imp.mkxl
@@ -189,7 +189,8 @@
\fi
\clf_shipoutpage#1\relax
\global\setbox#1\emptybox
- \global\deadcycles\zerocount}
+ \global\deadcycles\zerocount
+ \clf_cleanupattributes}
\def\page_shipouts_normal#1%
{\global\advance\shippedoutpages\plusone
diff --git a/tex/context/base/mkxl/page-one.mkxl b/tex/context/base/mkxl/page-one.mkxl
index e8f873422..61f9172ea 100644
--- a/tex/context/base/mkxl/page-one.mkxl
+++ b/tex/context/base/mkxl/page-one.mkxl
@@ -363,7 +363,7 @@
\noffloatinserts\zerocount
\let\totaltopinserted\!!zeropoint
\page_one_command_set_top_insertions_indeed
- \ifnum\rootfloatparameter\c!nbottom=\zerocount
+ \ifnum\rootfloatparameter\c!nbottom=\zerocount % \ifnum\c_page_floats_n_of_bottom=\zerocount
\ifnum\rootfloatparameter\c!nlines>\zerocount
\ifdim\totaltopinserted>\zeropoint\relax
\ifdim\dimexpr\rootfloatparameter\c!nlines\lineheight+\totaltopinserted\relax>\textheight
@@ -440,7 +440,6 @@
\page_one_command_set_bottom_insertions_indeed}
\protected\def\page_one_command_flush_top_insertions
-% {\ifvoid\namedinsertionnumber\s!topfloat\else
{\ifzeropt\page_inserts_get_height\namedinsertionnumber\s!topfloat\else
\page_one_command_flush_top_insertions_indeed % less tracing
\fi
@@ -463,7 +462,6 @@
\fi}
\protected\def\page_one_command_flush_bottom_insertions
-% {\ifvoid\namedinsertionnumber\s!bottomfloat\else
{\ifzeropt\page_inserts_get_height\namedinsertionnumber\s!bottomfloat\else
\page_one_command_flush_bottom_insertions_indeed
\fi
@@ -472,13 +470,13 @@
\def\page_one_command_flush_bottom_insertions_indeed
{\ifgridsnapping
- % \floatparameter\c!bottombefore
+ % \rootfloatparameter\c!bottombefore
\snaptogrid\hbox{\page_inserts_get_boxed\namedinsertionnumber\s!bottomfloat}%
- % \floatparameter\c!bottomafter
+ % \rootfloatparameter\c!bottomafter
\else
- \floatparameter\c!bottombefore
+ \rootfloatparameter\c!bottombefore
\page_inserts_get_unboxed\namedinsertionnumber\s!bottomfloat
- \floatparameter\c!bottomafter
+ \rootfloatparameter\c!bottomafter
\fi}
\protected\def\page_one_command_flush_floats
diff --git a/tex/context/base/mkxl/page-sid.mkxl b/tex/context/base/mkxl/page-sid.mkxl
index 052b3ee11..fb1022c2a 100644
--- a/tex/context/base/mkxl/page-sid.mkxl
+++ b/tex/context/base/mkxl/page-sid.mkxl
@@ -429,16 +429,28 @@
% \fi
% \page_otr_command_set_vsize} % new
+% test case:
+%
+% \starttext
+% \strut\vskip180mm \input ward
+% \subject{Test}
+% \placefigure[right,none]{none}{\blackrule[width=4cm,height=3cm]} test
+% \stoptext
+
\protected\def\page_sides_force_depth
{\iftracesidefloats
\enabletrackers[otr.forcestrutdepth]% \c_page_force_strut_depth_trace_mode\plusone
\fi
% flush what we have and check
\forcestrutdepth
- % trigger pagebuilder
- % \penalty\zerocount
- \pageboundary
- % catch up
+ % trigger pagebuilder, \pageboundary gives nicer tracing
+ \iffalse
+ \penalty\zerocount % works too
+ \else
+ %\tracingpages\plusone \tracingonline\plustwo
+ \pageboundary % becomes a penalty (after triggering the callback) (experimental!)
+ %\tracingpages\zerocount
+ \fi
\page_otr_command_set_vsize} % new, no longer really needed
\def\page_sides_flush_floats
diff --git a/tex/context/base/mkxl/spac-ali.mkxl b/tex/context/base/mkxl/spac-ali.mkxl
index 6e16614aa..085ed143a 100644
--- a/tex/context/base/mkxl/spac-ali.mkxl
+++ b/tex/context/base/mkxl/spac-ali.mkxl
@@ -570,28 +570,58 @@
\c_spac_align_state_direction \zerocount % what is default ?
\c_spac_align_state_page \zerocount
\c_spac_align_state_par_fill \zerocount
- \ifcsname\??aligncommand\m_spac_align_asked\endcsname
+ \ifcsname\??aligncommand\m_spac_align_named\endcsname
\lastnamedcs
\else
\rawprocesscommacommand[\m_spac_align_asked]\spac_align_collect
\fi
- \normalexpanded{\t_spac_align_collected
- {\setfalse\raggedonelinerstate % bad
- \the\t_spac_align_collected
- \spac_align_flush_horizontal
- \spac_align_flush_vertical
- \spac_align_flush_direction
- \spac_align_flush_page
- \spac_align_flush_parfill
- }}% kept, nice for tracing
+ % % kept, nice for tracing
+ %
+ % \normalexpanded{\t_spac_align_collected
+ % {\setfalse\raggedonelinerstate % bad
+ % \the\t_spac_align_collected
+ % \spac_align_flush_horizontal
+ % \spac_align_flush_vertical
+ % \spac_align_flush_direction
+ % \spac_align_flush_page
+ % \spac_align_flush_parfill
+ % }}%
+ %
+ % \etoksapp\t_spac_align_collected
+ % {\spac_align_flush_horizontal
+ % \spac_align_flush_vertical
+ % \spac_align_flush_direction
+ % \spac_align_flush_page
+ % \spac_align_flush_parfill}%
+ % \etokspre\t_spac_align_collected
+ % {\setfalse\raggedonelinerstate}% bad
+ %
+ \etoks\t_spac_align_collected
+ {\setfalse\raggedonelinerstate % bad
+ \the\t_spac_align_collected
+ \spac_align_flush_horizontal
+ \spac_align_flush_vertical
+ \spac_align_flush_direction
+ \spac_align_flush_page
+ \spac_align_flush_parfill}%
+ %
\enforced\permanent\protected\edef\raggedcommand {\the\t_spac_align_collected }%
\enforced\permanent\protected\edef\updateraggedskips{\spac_align_flush_horizontal}%
- \enforced\aliased\gletcsname\??alignmentnormalcache\m_spac_align_asked\endcsname\raggedcommand
- \enforced\aliased\gletcsname\??alignmentraggedcache\m_spac_align_asked\endcsname\updateraggedskips}
+ \enforced\aliased\gletcsname\??alignmentnormalcache\m_spac_align_named\endcsname\raggedcommand
+ \enforced\aliased\gletcsname\??alignmentraggedcache\m_spac_align_named\endcsname\updateraggedskips}
+
+\mutable\def\m_spac_align_named{\m_spac_align_asked}
\def\spac_align_collect#1%
{\csname\??aligncommand#1\endcsname}
+\permanent\protected\tolerant\def\definealign[#1]#*[#2]%
+ {\pushmacro\m_spac_align_named
+ \edef\m_spac_align_named{#1}%
+ \edef\m_spac_align_asked{#2}%
+ \spac_align_add_to_cache
+ \popmacro\m_spac_align_named}
+
% The local (key driven) setter:
\permanent\protected\def\spac_align_prepare#1% deferred
@@ -655,7 +685,7 @@
% Maybe we need something different in columns.
\permanent\protected\def\installalign#1#2% beware: commands must be unexpandable!
- {\ifcsname\??aligncommand#1\endcsname \else
+ {\ifcsname\??aligncommand#1\endcsname \else % : so maybe we should use \etoksapp
\defcsname\??aligncommand#1\endcsname{\toksapp\t_spac_align_collected{#2}}%
\fi}
diff --git a/tex/context/base/mkxl/spac-ver.lmt b/tex/context/base/mkxl/spac-ver.lmt
index 3faa15c77..955d65f4f 100644
--- a/tex/context/base/mkxl/spac-ver.lmt
+++ b/tex/context/base/mkxl/spac-ver.lmt
@@ -98,7 +98,6 @@ local v_blines = variables.blines
local trace_vbox_vspacing = false trackers.register("vspacing.vbox", function(v) trace_vbox_vspacing = v end)
local trace_page_vspacing = false trackers.register("vspacing.page", function(v) trace_page_vspacing = v end)
-local trace_page_builder = false trackers.register("builders.page", function(v) trace_page_builder = v end)
local trace_collect_vspacing = false trackers.register("vspacing.collect", function(v) trace_collect_vspacing = v end)
local trace_vspacing = false trackers.register("vspacing.spacing", function(v) trace_vspacing = v end)
local trace_vsnapping = false trackers.register("vspacing.snapping", function(v) trace_vsnapping = v end)
@@ -128,6 +127,8 @@ local getlist = nuts.getlist
local setlist = nuts.setlist
local getattr = nuts.getattr
local setattr = nuts.setattr
+local setattrs = nuts.setattrs
+local getattrs = nuts.getattrs
local getsubtype = nuts.getsubtype
local getbox = nuts.getbox
local getwhd = nuts.getwhd
@@ -185,6 +186,7 @@ local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local rule_code = nodecodes.rule
local par_code = nodecodes.par
+local boundary_code = nodecodes.boundary
local userskip_code = gluecodes.userskip
local lineskip_code = gluecodes.lineskip
@@ -735,28 +737,57 @@ storage.register("builders/vspacing/data/skip", vspacingdata.skip, "builders.vsp
local setspecification, getspecification
--- attributes : more overhead : feels faster than properties
--- properties : more natural : feels slower than attributes
--- data : more native : is little faster than attributes
+-- 1 statepool : 2 : more overhead : a bit slower than properties
+-- 2 attributes : 1 : more overhead : feels faster than properties
+-- 3 properties : 3 : more natural : feels slower than attributes
+-- 4 data : 1 : more native : is little faster than attributes (limited penalty)
-if true then
--- if false then
+-- testfile: t:/bugs/bottomfloats-001.tex
- -- quite okay but more memory due to attributes (not many)
+local method = 1 -- better tracing
+-- local method = 2
+-- local method = 3
+-- local method = 4
+
+if method == 1 then
+
+ local registervalue = attributes.registervalue
+ local getvalue = attributes.getvalue
+ local values = attributes.values
+
+ setspecification = function(n,category,penalty,order)
+ local detail = { category, penalty, order or 1 }
+ local value = registervalue(a_skipcategory,detail)
+ setattr(n,a_skipcategory,value)
+ end
+
+ getspecification = function(n)
+ local value = getattr(n,a_skipcategory)
+ if value then
+ local detail = getvalue(a_skipcategory,value)
+ -- local detail = attributes.values[a_skipcategory][value]
+ -- local detail = values[a_skipcategory][value]
+ if detail then
+ return detail[1], detail[2], detail[3]
+ end
+ end
+ return false, false, 1
+ end
+
+elseif method == 2 then
- local setattrs = nuts.setattrs
- local getattrs = nuts.getattrs
+ -- quite okay but more memory due to attributes (not many)
setspecification = function(n,category,penalty,order)
- setattrs(n,false,a_skipcategory,category,a_skippenalty,penalty,a_skiporder,order or 1)
+ setattrs(n,false,a_skipcategory,category or nil,a_skippenalty,penalty or nil,a_skiporder,order or 1)
end
getspecification = function(n)
- return getattrs(n,a_skipcategory,a_skippenalty,a_skiporder)
+ local c, p, o = getattrs(n,a_skipcategory,a_skippenalty,a_skiporder)
+ return c or false, p or false, o or 1
end
--- elseif true then
-elseif false then
+elseif method == 3 then
-- more natural as we stay in lua
@@ -776,7 +807,7 @@ elseif false then
end
end
-else
+elseif method == 4 then
-- quite efficient but needs testing because we limit values
@@ -1460,7 +1491,11 @@ do
return remove_node(head,current,true)
end
+ -- where -> scope
+ -- what -> where (original context)
+
local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also pass tail
+
if trace then
reset_tracing(head)
end
@@ -1483,10 +1518,11 @@ do
local pagetail
--
-- todo: keep_together: between headers
+ -- todo: make this nicer in the engine
--
local function getpagelist()
if not pagehead then
- pagehead = texlists.pagehead
+ pagehead = texlists.pagehead -- pagehead, pagetail = tex.getlist("pagehead")
if pagehead then
pagehead = tonut(pagehead)
pagetail = find_node_tail(pagehead) -- no texlists.page_tail yet-- no texlists.page_tail yet
@@ -1494,6 +1530,12 @@ do
end
end
--
+ -- local function getpagelist()
+ -- if not pagehead then
+ -- pagehead, pagetail = texgetlist("pagehead")
+ -- end
+ -- end
+ --
local function compensate(n)
local g = 0
while n and getid(n) == glue_code do
@@ -1971,7 +2013,7 @@ do
local next = getnext(current)
-- if next and getattr(next,a_skipcategory) == notopskip then
if next and getspecification(next) == notopskip then
- nuts.setglue(current) -- zero
+ setglue(current) -- zero
end
if snap then
local s = getattr(current,a_snapmethod)
@@ -2084,7 +2126,7 @@ do
glue_data = nil
elseif tail then
setlink(tail,glue_data)
-setnext(glue_data)
+ setnext(glue_data)
else
head = glue_data
end
@@ -2115,6 +2157,8 @@ setnext(glue_data)
-- ugly code: we get partial lists (check if this stack is still okay) ... and we run
-- into temp nodes (sigh)
+ -- this really need a rework
+
local forceflush = false
function vspacing.pagehandler(newhead,where)
@@ -2122,7 +2166,7 @@ setnext(glue_data)
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, subtype in nextnode, newhead do -- we could just look for glue nodes
if id ~= glue_code then
flush = true
@@ -2198,18 +2242,15 @@ setnext(glue_data)
forceflush = true
end
- local ignore = table.tohash {
- "split_keep",
- "split_off",
- -- "vbox",
+ local ignored = table.tohash {
+ "splitkeep",
+ "splitoff",
+-- "insert",
}
function vspacing.vboxhandler(head,where)
- 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
+ if head and not ignored[where] and getnext(head) then
+ head = collapser(head,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper
end
return head
end
diff --git a/tex/context/base/mkxl/supp-box.lmt b/tex/context/base/mkxl/supp-box.lmt
index 8a290b5ae..93b97b48e 100644
--- a/tex/context/base/mkxl/supp-box.lmt
+++ b/tex/context/base/mkxl/supp-box.lmt
@@ -169,213 +169,221 @@ implement {
end
}
-local function applytochars(current,doaction,noaction,nested)
- while current do
- local id = getid(current)
- if nested and (id == hlist_code or id == vlist_code) then
- context.beginhbox()
- applytochars(getlist(current),doaction,noaction,nested)
- context.endhbox()
- elseif id ~= glyph_code then
- noaction(tonode(copy_node(current)))
- else
- doaction(tonode(copy_node(current)))
+do
+
+ local function applytochars(current,doaction,noaction,nested)
+ while current do
+ local id = getid(current)
+ if nested and (id == hlist_code or id == vlist_code) then
+ context.beginhbox()
+ applytochars(getlist(current),doaction,noaction,nested)
+ context.endhbox()
+ elseif id ~= glyph_code then
+ noaction(tonode(copy_node(current)))
+ else
+ doaction(tonode(copy_node(current)))
+ end
+ current = getnext(current)
end
- current = getnext(current)
end
-end
-local function applytowords(current,doaction,noaction,nested)
- local start
- while current do
- local id = getid(current)
- if id == glue_code then
- if start then
- doaction(tonode(copylist(start,current)))
- start = nil
+ local function applytowords(current,doaction,noaction,nested)
+ local start
+ while current do
+ local id = getid(current)
+ if id == glue_code then
+ if start then
+ doaction(tonode(copylist(start,current)))
+ start = nil
+ end
+ noaction(tonode(copy_node(current)))
+ elseif nested and (id == hlist_code or id == vlist_code) then
+ context.beginhbox()
+ applytowords(getlist(current),doaction,noaction,nested)
+ context.egroup()
+ elseif not start then
+ start = current
end
- noaction(tonode(copy_node(current)))
- elseif nested and (id == hlist_code or id == vlist_code) then
- context.beginhbox()
- applytowords(getlist(current),doaction,noaction,nested)
- context.egroup()
- elseif not start then
- start = current
+ current = getnext(current)
+ end
+ if start then
+ doaction(tonode(copylist(start)))
end
- current = getnext(current)
- end
- if start then
- doaction(tonode(copylist(start)))
end
-end
-local methods = {
- char = applytochars,
- characters = applytochars,
- word = applytowords,
- words = applytowords,
-}
+ local methods = {
+ char = applytochars,
+ characters = applytochars,
+ word = applytowords,
+ words = applytowords,
+ }
-implement {
- name = "applytobox",
- arguments = {
- {
- { "box", "integer" },
- { "command" },
- { "method" },
- { "nested", "boolean" },
- }
- },
- actions = function(specification)
- local list = checkedlist(specification.box)
- local action = methods[specification.method or "char"]
- if list and action then
- action(list,context[specification.command or "ruledhbox"],context,specification.nested)
- end
- end
-}
+ implement {
+ name = "applytobox",
+ arguments = {
+ {
+ { "box", "integer" },
+ { "command" },
+ { "method" },
+ { "nested", "boolean" },
+ }
+ },
+ actions = function(specification)
+ local list = checkedlist(specification.box)
+ local action = methods[specification.method or "char"]
+ if list and action then
+ action(list,context[specification.command or "ruledhbox"],context,specification.nested)
+ end
+ end
+ }
-local split_char = lpeg.Ct(lpeg.C(1)^0)
-local split_word = lpeg.tsplitat(lpeg.patterns.space)
-local split_line = lpeg.tsplitat(lpeg.patterns.eol)
-
-local function processsplit(specification)
- local str = specification.data or ""
- local command = specification.command or "ruledhbox"
- local method = specification.method or "word"
- local spaced = specification.spaced
- if command then
- command = context[command]
- end
- if method == "char" or method == "character" then
- if spaced then
- spaced = context.space
+ local split_char = lpeg.Ct(lpeg.C(1)^0)
+ local split_word = lpeg.tsplitat(lpeg.patterns.space)
+ local split_line = lpeg.tsplitat(lpeg.patterns.eol)
+
+ local function processsplit(specification)
+ local str = specification.data or ""
+ local command = specification.command or "ruledhbox"
+ local method = specification.method or "word"
+ local spaced = specification.spaced
+ if command then
+ command = context[command]
end
- local words = lpegmatch(split_char,str)
- for i=1,#words do
- local word = words[i]
- if word == " " then
- if spaced then
- spaced()
+ if method == "char" or method == "character" then
+ if spaced then
+ spaced = context.space
+ end
+ local words = lpegmatch(split_char,str)
+ for i=1,#words do
+ local word = words[i]
+ if word == " " then
+ if spaced then
+ spaced()
+ end
+ elseif command then
+ command(word)
+ else
+ context(word)
end
- elseif command then
- command(word)
- else
- context(word)
end
- end
- elseif method == "word" then
- if spaced then
- spaced = context.space
- end
- local words = lpegmatch(split_word,str)
- for i=1,#words do
- local word = words[i]
- if spaced and i > 1 then
- spaced()
+ elseif method == "word" then
+ if spaced then
+ spaced = context.space
end
- if command then
- command(word)
- else
- context(word)
+ local words = lpegmatch(split_word,str)
+ for i=1,#words do
+ local word = words[i]
+ if spaced and i > 1 then
+ spaced()
+ end
+ if command then
+ command(word)
+ else
+ context(word)
+ end
end
- end
- elseif method == "line" then
- if spaced then
- spaced = context.par
- end
- local words = lpegmatch(split_line,str)
- for i=1,#words do
- local word = words[i]
- if spaced and i > 1 then
- spaced()
+ elseif method == "line" then
+ if spaced then
+ spaced = context.par
end
- if command then
- command(word)
- else
- context(word)
+ local words = lpegmatch(split_line,str)
+ for i=1,#words do
+ local word = words[i]
+ if spaced and i > 1 then
+ spaced()
+ end
+ if command then
+ command(word)
+ else
+ context(word)
+ end
end
+ else
+ context(str)
end
- else
- context(str)
end
-end
-implement {
- name = "processsplit",
- actions = processsplit,
- arguments = {
- {
- { "data" },
- { "command" },
- { "method" },
- { "spaced", "boolean" },
+ implement {
+ name = "processsplit",
+ actions = processsplit,
+ arguments = {
+ {
+ { "data" },
+ { "command" },
+ { "method" },
+ { "spaced", "boolean" },
+ }
}
}
-}
-local a_vboxtohboxseparator = attributes.private("vboxtohboxseparator")
+end
-implement {
- name = "vboxlisttohbox",
- arguments = { "integer", "integer", "dimen" },
- actions = function(original,target,inbetween)
- local current = getlist(getbox(original))
- local head = nil
- local tail = nil
- while current do
- local id = getid(current)
- local next = getnext(current)
- if id == hlist_code then
- local list = getlist(current)
- if head then
- if inbetween > 0 then
- local n = new_glue(0,0,inbetween)
- setlink(tail,n)
- tail = n
- end
- setlink(tail,list)
- else
- head = list
- end
- tail = find_tail(list)
- -- remove last separator
- if getid(tail) == hlist_code and getattribute(tail,a_vboxtohboxseparator) == 1 then
- local temp = tail
- local prev = getprev(tail)
- if next then
- local list = getlist(tail)
- setlink(prev,list)
- setlist(tail)
- tail = find_tail(list)
+do
+
+ local a_vboxtohboxseparator = attributes.private("vboxtohboxseparator")
+
+ implement {
+ name = "vboxlisttohbox",
+ arguments = { "integer", "integer", "dimen" },
+ actions = function(original,target,inbetween)
+ local current = getlist(getbox(original))
+ local head = nil
+ local tail = nil
+ while current do
+ local id = getid(current)
+ local next = getnext(current)
+ if id == hlist_code then
+ local list = getlist(current)
+ if head then
+ if inbetween > 0 then
+ local n = new_glue(0,0,inbetween)
+ setlink(tail,n)
+ tail = n
+ end
+ setlink(tail,list)
else
- tail = prev
+ head = list
+ end
+ tail = find_tail(list)
+ -- remove last separator
+ if getid(tail) == hlist_code and getattribute(tail,a_vboxtohboxseparator) == 1 then
+ local temp = tail
+ local prev = getprev(tail)
+ if next then
+ local list = getlist(tail)
+ setlink(prev,list)
+ setlist(tail)
+ tail = find_tail(list)
+ else
+ tail = prev
+ end
+ flushnode(temp)
end
- flushnode(temp)
+ -- done
+ setnext(tail)
+ setlist(current)
end
- -- done
- setnext(tail)
- setlist(current)
+ current = next
end
- current = next
+ local result = new_hlist()
+ setlist(result,head)
+ setbox(target,result)
+ -- setbox(target,new_hlist(head))
end
- local result = new_hlist()
- setlist(result,head)
- setbox(target,result)
- -- setbox(target,new_hlist(head))
- end
-}
+ }
-implement {
- name = "hboxtovbox",
- arguments = "integer",
- actions = function(n)
- local b = getbox(n)
- local factor = texget("baselineskip",false) / texget("hsize")
- setdepth(b,0)
- setheight(b,getwidth(b) * factor)
- end
-}
+ implement {
+ name = "hboxtovbox",
+ arguments = "integer",
+ actions = function(n)
+ local b = getbox(n)
+ local factor = texget("baselineskip",false) / texget("hsize")
+ setdepth(b,0)
+ setheight(b,getwidth(b) * factor)
+ end
+ }
+
+end
implement {
name = "boxtostring",
@@ -386,39 +394,14 @@ implement {
end
}
-local function getnaturaldimensions(n)
- local w = 0
- local h = 0
- local d = 0
- local l = getlist(getbox(n))
- if l then
- w, h, d = getdimensions(l)
- end
- texsetdimen("lastnaturalboxwd",w)
- texsetdimen("lastnaturalboxht",h)
- texsetdimen("lastnaturalboxdp",d)
- return w, h, d
-end
+do
-implement {
- name = "getnaturaldimensions",
- arguments = "integer",
- actions = getnaturaldimensions
-}
+ -- we can now move this to the tex end
-implement {
- name = "naturalwd",
- arguments = "integer",
- actions = function(n)
- getnaturaldimensions(n)
- context.lastnaturalboxwd(false)
- end
-}
+ local values = tokens.values
+ local dimension_value = values.dimension
-implement {
- name = "getnaturalwd",
- arguments = "integer",
- actions = function(n)
+ local function getnaturaldimensions(n)
local w = 0
local h = 0
local d = 0
@@ -426,25 +409,64 @@ implement {
if l then
w, h, d = getdimensions(l)
end
- context("\\dimexpr%i\\scaledpoint\\relax",w)
+ texsetdimen("lastnaturalboxwd",w)
+ texsetdimen("lastnaturalboxht",h)
+ texsetdimen("lastnaturalboxdp",d)
+ return w, h, d
end
-}
-local function setboxtonaturalwd(n)
- local old = takebox(n)
- local new = hpack(getlist(old))
- setlist(old,nil)
- flushnode(old)
- setbox(n,new)
-end
+ local function setboxtonaturalwd(n)
+ local old = takebox(n)
+ local new = hpack(getlist(old))
+ setlist(old,nil)
+ flushnode(old)
+ setbox(n,new)
+ end
-implement {
- name = "setnaturalwd",
- arguments = "integer",
- actions = setboxtonaturalwd
-}
+ implement {
+ name = "getnaturaldimensions",
+ arguments = "integer",
+ public = true,
+ protected = true,
+ untraced = true,
+ actions = getnaturaldimensions
+ }
+
+ implement {
+ name = "naturalwd",
+ arguments = "integer",
+ usage = "value",
+ public = true,
+ protected = true,
+ actions = function(n)
+ return dimension_value, (getnaturaldimensions(n))
+ end
+ }
-nodes.setboxtonaturalwd = setboxtonaturalwd
+ implement {
+ name = "getnaturalwd",
+ arguments = "integer",
+ usage = "value",
+ public = true,
+ protected = true,
+ actions = function(n)
+ local l = getlist(getbox(n))
+ return dimension_value, l and getdimensions(l) or 0
+ end
+ }
+
+ implement {
+ name = "setnaturalwd",
+ arguments = "integer",
+ public = true,
+ protected = true,
+ untraced = true,
+ actions = setboxtonaturalwd
+ }
+
+ nodes.setboxtonaturalwd = setboxtonaturalwd
+
+end
local doifelse = commands.doifelse
@@ -1433,7 +1455,7 @@ end
do
- function setsplitlisthtdp(n,ht,dp)
+ local function setsplitlisthtdp(n,ht,dp)
local box = getbox(n)
if box then
local head = getlist(box)
diff --git a/tex/context/base/mkxl/supp-box.mkxl b/tex/context/base/mkxl/supp-box.mkxl
index 2ad067002..8e5b38365 100644
--- a/tex/context/base/mkxl/supp-box.mkxl
+++ b/tex/context/base/mkxl/supp-box.mkxl
@@ -2728,11 +2728,11 @@
%D We can define these public in lua:
-\aliased\let\getnaturaldimensions\clf_getnaturaldimensions % sets three dimensions
-\aliased\let\naturalwd \clf_naturalwd % calculates and returns wd
+% \aliased\let\getnaturaldimensions\clf_getnaturaldimensions % sets three dimensions
+% \aliased\let\naturalwd \clf_naturalwd % calculates and returns wd
-\aliased\let\getnaturalwd\clf_getnaturalwd % no intermediate
-\aliased\let\setnaturalwd\clf_setnaturalwd % no intermediate
+% \aliased\let\getnaturalwd\clf_getnaturalwd % no intermediate
+% \aliased\let\setnaturalwd\clf_setnaturalwd % no intermediate
\permanent\protected\def\doifelserighttoleftinbox{\clf_doifelserighttoleftinbox}
diff --git a/tex/context/base/mkxl/tabl-tbl.mkxl b/tex/context/base/mkxl/tabl-tbl.mkxl
index e329da268..959ef4617 100644
--- a/tex/context/base/mkxl/tabl-tbl.mkxl
+++ b/tex/context/base/mkxl/tabl-tbl.mkxl
@@ -183,15 +183,21 @@
\newconditional \c_tabl_tabulate_nopbreak
\newconditional \c_tabl_tabulate_firstflushed
\newconditional \c_tabl_tabulate_equal
-\newconditional \c_tabl_tabulate_split \settrue\c_tabl_tabulate_split
+\newconditional \c_tabl_tabulate_split
\newconditional \c_tabl_tabulate_automode
-\newconditional \c_tabl_tabulate_handlepbreak \settrue\c_tabl_tabulate_handlepbreak
-\newconditional \c_tabl_tabulate_autorulespacing \settrue\c_tabl_tabulate_autorulespacing
+\newconditional \c_tabl_tabulate_handlepbreak
+\newconditional \c_tabl_tabulate_autorulespacing
\newconditional \c_tabl_tabulate_someamble
\newconditional \c_tabl_tabulate_tolerant_break
\newconditional \c_tabl_tabulate_splitoff_whitespace
\newconditional \c_tabl_tabulate_pwidth_set
\newconditional \c_tabl_tabulate_reshape
+\newconditional \c_tabl_tabulate_no_blank_in_paragraphs % can become always on
+
+\settrue\c_tabl_tabulate_split
+\settrue\c_tabl_tabulate_handlepbreak
+\settrue\c_tabl_tabulate_autorulespacing
+\settrue\c_tabl_tabulate_no_blank_in_paragraphs
\newdimen \d_tabl_tabulate_width_p
\newdimen \d_tabl_tabulate_width_w
@@ -1993,7 +1999,11 @@
\fi}
\protected\def\tabl_tabulate_eskip_second
- {\par\egroup
+ {\par
+ \ifconditional\c_tabl_tabulate_no_blank_in_paragraphs
+ \removelastskip
+ \fi
+ \egroup
\tabl_tabulate_pheight_set
\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes
\tabl_tabulate_splitoff_box}
@@ -2003,6 +2013,9 @@
% first line
\global\setbox\b_tabl_tabulate_current\c_tabl_tabulate_column\vbox
\bgroup
+ \ifconditional\c_tabl_tabulate_no_blank_in_paragraphs
+ \inhibitblank
+ \fi
\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop
\ifconditional\c_tabl_tabulate_automode\hsize\d_tabl_tabulate_width\fi
% \begstrut % interferes with pre-\pars
diff --git a/tex/context/base/mkxl/trac-deb.lmt b/tex/context/base/mkxl/trac-deb.lmt
index 9cf122d32..195a7cb8e 100644
--- a/tex/context/base/mkxl/trac-deb.lmt
+++ b/tex/context/base/mkxl/trac-deb.lmt
@@ -163,6 +163,7 @@ local function processerror(offset,errortype)
if job and type(job.disablesave) == "function" then
job.disablesave()
end
+ lua.setexitcode(1)
end
directives.register("system.quitonerror",function(v)
diff --git a/tex/context/base/mkxl/typo-bld.lmt b/tex/context/base/mkxl/typo-bld.lmt
index 9c83adede..ae644d297 100644
--- a/tex/context/base/mkxl/typo-bld.lmt
+++ b/tex/context/base/mkxl/typo-bld.lmt
@@ -34,11 +34,12 @@ constructors.attribute = a_parbuilder
local unsetvalue = attributes.unsetvalue
local texsetattribute = tex.setattribute
local texnest = tex.nest
-local texlists = tex.lists
-
local texget = tex.get
local texset = tex.set
+local getspeciallist = nodes.nuts.getspeciallist
+local setspeciallist = nodes.nuts.setspeciallist
+
local texgetdimen = tex.getdimen
local nodes = nodes
@@ -216,46 +217,32 @@ end
local pageactions = nodes.tasks.actions("mvlbuilders")
----- lineactions = nodes.tasks.actions("linebuilders")
-local function report(groupcode,head)
- report_page_builder("trigger: %s",groupcode)
+local function report(pagecontext,head)
+ report_page_builder("trigger: %s at level %i",pagecontext,texnest.ptr)
report_page_builder(" vsize : %p",texget("vsize"))
report_page_builder(" pagegoal : %p",texget("pagegoal"))
report_page_builder(" pagetotal: %p",texget("pagetotal"))
report_page_builder(" list : %s",head and nodeidstostring(head) or "<empty>")
end
--- check why box is called before after_linebreak .. maybe make categories and
--- call 'm less
-
--- this will be split into contribute_filter for these 4 so at some point
--- the check can go away
+-- Watch out: contributehead can be any head (kind of) not per se the page one
+-- but that needs to be intercepted when needed by groupcode and level. At some
+-- point this one might be split by group.
--- Todo: contrib_head can be any head (kind of) not per se the page one so maybe I will
--- intercept that in the engine with contributehead or so.
-
-function builders.buildpage_filter(groupcode)
- local head = texlists.contributehead
+function builders.buildpage_filter(pagecontext)
+ local head, tail = getspeciallist("contributehead")
if head then
- local done = false
- -- called quite often ... maybe time to remove timing
- starttiming(builders)
if trace_page_builder then
- report(groupcode,head)
+ report(pagecontext,head)
end
- head, done = pageactions(head,groupcode)
+ starttiming(builders)
+ head = pageactions(head,pagecontext) -- todo: tail
stoptiming(builders)
- -- -- doesn't work here (not passed on?)
- -- texset("pagegoal,texget("vsize") - texgetdimen("d_page_floats_inserted_top") - texgetdimen("d_page_floats_inserted_bottom")
- texlists.contributehead = head or nil -- needs checking
- -- tex.setlist("contributehead",head,head and nodes.tail(head))
- return done and head or true -- no return value needed
+ setspeciallist("contributehead", head)
else
- -- happens quite often
if trace_page_builder then
- report(groupcode)
+ report(pagecontext)
end
--- return nil, false -- no return value needed
- return nil
end
end
diff --git a/tex/context/base/mkxl/typo-brk.lmt b/tex/context/base/mkxl/typo-brk.lmt
index f9c255608..3a7b69db9 100644
--- a/tex/context/base/mkxl/typo-brk.lmt
+++ b/tex/context/base/mkxl/typo-brk.lmt
@@ -397,9 +397,6 @@ function breakpoints.handler(head)
-- end
end
end
- if done then
--- unsetattributes(a_breakpoints, head)
- end
end
return head
end
diff --git a/tex/context/base/mkxl/typo-cap.lmt b/tex/context/base/mkxl/typo-cap.lmt
index 02a2c1aaf..4a55c410f 100644
--- a/tex/context/base/mkxl/typo-cap.lmt
+++ b/tex/context/base/mkxl/typo-cap.lmt
@@ -19,96 +19,83 @@ local report_casing = logs.reporter("typesetting","casing")
local nodes, node = nodes, node
-local nuts = nodes.nuts
+local nuts = nodes.nuts
-local getnext = nuts.getnext
-local getid = nuts.getid
-local getattr = nuts.getattr
-local getcharspec = nuts.getcharspec
-local getsubtype = nuts.getsubtype
-local getchar = nuts.getchar
-local isglyph = nuts.isglyph
-local getdisc = nuts.getdisc
+local getnext = nuts.getnext
+local getid = nuts.getid
+local getattr = nuts.getattr
+local getcharspec = nuts.getcharspec
+local getsubtype = nuts.getsubtype
+local getchar = nuts.getchar
+local isglyph = nuts.isglyph
+local getdisc = nuts.getdisc
-local setchar = nuts.setchar
-local setfont = nuts.setfont
-local setscales = nuts.setscales
+local setchar = nuts.setchar
+local setfont = nuts.setfont
+local setscales = nuts.setscales
-local copy_node = nuts.copy
-local endofmath = nuts.endofmath
-local insertafter = nuts.insertafter
-local findattribute = nuts.findattribute
-local unsetattributes = nuts.unsetattributes
+local copy_node = nuts.copy
+local endofmath = nuts.endofmath
+local insertafter = nuts.insertafter
+local findattribute = nuts.findattribute
+local unsetattributes = nuts.unsetattributes
-local nextglyph = nuts.traversers.glyph
+local nextglyph = nuts.traversers.glyph
-local nodecodes = nodes.nodecodes
-local kerncodes = nodes.kerncodes
+local nodecodes = nodes.nodecodes
+local kerncodes = nodes.kerncodes
-local glyph_code = nodecodes.glyph
-local kern_code = nodecodes.kern
-local disc_code = nodecodes.disc
-local math_code = nodecodes.math
+local glyph_code = nodecodes.glyph
+local kern_code = nodecodes.kern
+local disc_code = nodecodes.disc
+local math_code = nodecodes.math
-local fontkern_code = kerncodes.fontkern
+local fontkern_code = kerncodes.fontkern
-local enableaction = nodes.tasks.enableaction
+local enableaction = nodes.tasks.enableaction
-local newkern = nuts.pool.kern
+local newkern = nuts.pool.kern
-local fonthashes = fonts.hashes
-local fontdata = fonthashes.identifiers
-local fontchar = fonthashes.characters
+local fonthashes = fonts.hashes
+local fontdata = fonthashes.identifiers
+local fontchar = fonthashes.characters
-local currentfont = font.current
+local currentfont = font.current
-local variables = interfaces.variables
-local v_reset = variables.reset
+local variables = interfaces.variables
+local v_reset = variables.reset
-local texsetattribute = tex.setattribute
-local unsetvalue = attributes.unsetvalue
-local texgetcount = tex.getcount
+local texsetattribute = tex.setattribute
+----- unsetvalue = attributes.unsetvalue
+----- texgetcount = tex.getcount
+local texgetscales = tex.getglyphscales
-typesetters = typesetters or { }
-local typesetters = typesetters
+typesetters = typesetters or { }
+local typesetters = typesetters
-typesetters.cases = typesetters.cases or { }
-local cases = typesetters.cases
+typesetters.cases = typesetters.cases or { }
+local cases = typesetters.cases
-cases.actions = { }
-local actions = cases.actions
-local a_cases = attributes.private("case")
+cases.actions = { }
+local actions = cases.actions
+local a_cases = attributes.private("case")
-local run = 0 -- a trick to make neighbouring ranges work
-local blocked = { }
+local run = 0 -- a trick to make neighbouring ranges work
-local fontstate = { } -- this will become something generic
+local registervalue = attributes.registervalue
+local getvalue = attributes.getvalue
+local texsetattribute = tex.setattribute
local function set(tag,font)
- if run < 0x7F then
- run = run + 1
- else
- run = 1
- end
- local a = (font << 16)
- + (tag << 8)
- + (run << 0)
- blocked[a] = false
- -- it makes sense to fetch them all at once ut it doesn't happen often: tex.getglyphscales() scale xscale yscale data [script] [state]
- fontstate[a] = {
- texgetcount("glyphscale"),
- texgetcount("glyphxscale"),
- texgetcount("glyphyscale"),
- texgetcount("glyphdatafield")
+ run = run + 1
+ local settings = {
+ font = font,
+ tag = tag,
+ run = run, -- still needed ?
+ -- blocked = false
+ scales = { texgetscales() },
}
- return a
-end
-
-local function get(a)
- return
- (a >> 8) & 0x00FF, -- tag
- (a >> 16) & 0xFFFF, -- font
- (a >> 0) & 0x00FF -- run
+ texsetattribute(a_cases,registervalue(a_cases,settings))
end
-- a previous implementation used char(0) as placeholder for the larger font, so we needed
@@ -172,17 +159,17 @@ end
cases.register = register
-local function WORD(start,attr,lastfont,n,count,where,first)
+local function WORD(start,data,lastfont,n,count,where,first)
lastfont[n] = false
return replacer(first or start,uccodes)
end
-local function word(start,attr,lastfont,n,count,where,first)
+local function word(start,data,lastfont,n,count,where,first)
lastfont[n] = false
return replacer(first or start,lccodes)
end
-local function Words(start,attr,lastfont,n,count,where,first) -- looks quite complex
+local function Words(start,data,lastfont,n,count,where,first) -- looks quite complex
if where == "post" then
return
end
@@ -194,18 +181,18 @@ local function Words(start,attr,lastfont,n,count,where,first) -- looks quite com
end
end
-local function Word(start,attr,lastfont,n,count,where,first)
- blocked[attr] = true
- return Words(start,attr,lastfont,n,count,where,first)
+local function Word(start,data,lastfont,n,count,where,first)
+ data.blocked = true
+ return Words(start,data,lastfont,n,count,where,first)
end
-local function camel(start,attr,lastfont,n,count,where,first)
- word(start,attr,lastfont,n,count,where,first)
- Words(start,attr,lastfont,n,count,where,first)
+local function camel(start,data,lastfont,n,count,where,first)
+ word(start,data,lastfont,n,count,where,first)
+ Words(start,data,lastfont,n,count,where,first)
return start, true
end
-local function mixed(start,attr,lastfont,n,count,where,first)
+local function mixed(start,data,lastfont,n,count,where,first)
if where == "post" then
return
end
@@ -217,10 +204,10 @@ local function mixed(start,attr,lastfont,n,count,where,first)
elseif dc == char then
local lfa = lastfont[n]
if lfa then
- local s = fontstate[attr]
+ local s = data.scales
setfont(used,lfa)
if s then
- setscales(used, s[1], s[2], s[3])
+ setscales(used,s[1],s[2],s[3])
end
end
else
@@ -229,17 +216,17 @@ local function mixed(start,attr,lastfont,n,count,where,first)
return start, true
end
-local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3
+local function Capital(start,data,lastfont,n,count,where,first,once) -- 3
local used = first or start
if count == 1 and where ~= "post" then
local lfa = lastfont[n]
if lfa then
local dc = uccodes[getchar(used)]
if dc then
- local s = fontstate[attr]
+ local s = data.scales
setfont(used,lfa)
if s then
- setscales(used, s[1], s[2], s[3])
+ setscales(used,s[1],s[2],s[3])
end
end
end
@@ -251,15 +238,15 @@ local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3
return start, c
end
-local function capital(start,attr,lastfont,n,where,count,first,count) -- 4
- return Capital(start,attr,lastfont,n,where,count,first,true)
+local function capital(start,data,lastfont,n,where,count,first,count) -- 4
+ return Capital(start,data,lastfont,n,where,count,first,true)
end
-local function none(start,attr,lastfont,n,count,where,first)
+local function none(start,data,lastfont,n,count,where,first)
return start, true
end
-local function randomized(start,attr,lastfont,n,count,where,first)
+local function randomized(start,data,lastfont,n,count,where,first)
local used = first or start
local char,
font = getcharfont(used)
@@ -301,89 +288,92 @@ register(variables.cap, variables.capital) -- clone
register(variables.Cap, variables.Capital) -- clone
function cases.handler(head)
- local _, start = findattribute(head, a_cases)
+ local _, start = findattribute(head,a_cases)
if start then
local lastfont = { }
local lastattr = nil
local count = 0
- local done = false
while start do -- while because start can jump ahead
local id = getid(start)
if id == glyph_code then
local attr = getattr(start,a_cases)
- if attr and attr > 0 and not blocked[attr] then
- if attr ~= lastattr then
- lastattr = attr
- count = 1
- else
- count = count + 1
- end
- local n, id, m = get(attr)
--- if lastfont[n] == nil then
- lastfont[n] = id
--- end
- local action = actions[n] -- map back to low number
- if action then
- local quit
- start, quit = action(start,attr,lastfont,n,count)
- if trace_casing then
- report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,quit and "-" or "+")
+ if attr and attr > 0 then
+ local data = getvalue(a_cases,attr)
+ if data and not data.blocked then
+ if attr ~= lastattr then
+ lastattr = attr
+ count = 1
+ else
+ count = count + 1
+ end
+ local tag = data.tag
+ local font = data.font
+ local run = data.run
+ local action = actions[tag] -- map back to low number
+ lastfont[tag] = font
+ if action then
+ local quit
+ start, quit = action(start,data,lastfont,tag,count)
+ if trace_casing then
+ report_casing("case trigger %a, instance %a, fontid %a, result %a",
+ tag,run,font,quit and "-" or "+")
+ end
+ elseif trace_casing then
+ report_casing("unknown case trigger %a",tag)
end
- elseif trace_casing then
- report_casing("unknown case trigger %a",n)
end
- done = true
end
elseif id == disc_code then
local attr = getattr(start,a_cases)
- if attr and attr > 0 and not blocked[attr] then
- if attr ~= lastattr then
- lastattr = attr
- count = 0
- end
- local n, id, m = get(attr)
--- if lastfont[n] == nil then
- lastfont[n] = id
--- end
- local action = actions[n] -- map back to low number
- if action then
- local pre, post, replace = getdisc(start)
- if replace then
- local cnt = count
- for g in nextglyph, replace do
- cnt = cnt + 1
- getattr(g,a_cases)
- local h, quit = action(start,attr,lastfont,n,cnt,"replace",g)
- if quit then
- break
+ if attr and attr > 0 then
+ local data = getvalue(a_cases,attr)
+ if data and not data.blocked then
+ if attr ~= lastattr then
+ lastattr = attr
+ count = 0
+ end
+ local tag = data.tag
+ local font = data.font
+ local action = actions[tag] -- map back to low number
+ lastfont[tag] = font
+ if action then
+ local pre, post, replace = getdisc(start)
+ if replace then
+ local cnt = count
+ for g in nextglyph, replace do
+ cnt = cnt + 1
+ getattr(g,a_cases)
+ local h, quit = action(start,data,lastfont,tag,cnt,"replace",g)
+ if quit then
+ break
+ end
end
end
- end
- if pre then
- local cnt = count
- for g in nextglyph, pre do
- cnt = cnt + 1
- getattr(g,a_cases)
- local h, quit = action(start,attr,lastfont,n,cnt,"pre",g)
- if quit then
- break
+ if pre then
+ local cnt = count
+ for g in nextglyph, pre do
+ cnt = cnt + 1
+ getattr(g,a_cases)
+ local h, quit = action(start,data,lastfont,tag,cnt,"pre",g)
+ if quit then
+ break
+ end
end
end
- end
- if post then
- local cnt = count
- for g in nextglyph, post do
- cnt = cnt + 1
- getattr(g,a_cases)
- local h, quit = action(start,attr,lastfont,n,cnt,"post",g)
- if quit then
- break
+ if post then
+ local cnt = count
+ for g in nextglyph, post do
+ cnt = cnt + 1
+ getattr(g,a_cases)
+ local h, quit = action(start,data,lastfont,tag,cnt,"post",g)
+ if quit then
+ break
+ end
end
end
end
+ count = count + 1
end
- count = count + 1
- done = true
end
else
if id == math_code then
@@ -395,9 +385,6 @@ function cases.handler(head)
start = getnext(start)
end
end
- if done then
- -- unsetattributes(a_cases,head)
- end
end
return head
end
@@ -405,9 +392,7 @@ end
local enabled = false
function cases.set(n,id)
- if n == v_reset then
- n = unsetvalue
- else
+ if n ~= v_reset then
n = registered[n] or tonumber(n)
if n then
if not enabled then
@@ -417,13 +402,11 @@ function cases.set(n,id)
end
enabled = true
end
- n = set(n,id or currentfont())
- else
- n = unsetvalue
+ set(n,id or currentfont())
+ return
end
end
- texsetattribute(a_cases,n)
- -- return n -- bonus
+ texsetattribute(a_cases) -- ,unsetvalue)
end
-- interface
diff --git a/tex/context/base/mkxl/typo-rub.lmt b/tex/context/base/mkxl/typo-rub.lmt
index eff522e02..f5bba7f7f 100644
--- a/tex/context/base/mkxl/typo-rub.lmt
+++ b/tex/context/base/mkxl/typo-rub.lmt
@@ -170,13 +170,14 @@ do
local function setruby(n,m)
nofrubies = nofrubies + 1
local r = takebox(n)
- rubylist[nofrubies] = setmetatableindex({
+ local t = {
text = r,
width = getwidth(r),
basewidth = 0,
start = false,
stop = false,
- }, shared)
+ }
+ rubylist[nofrubies] = setmetatableindex(t, shared)
texsetattribute(a_ruby,nofrubies)
end
diff --git a/tex/context/base/mkxl/typo-rub.mkxl b/tex/context/base/mkxl/typo-rub.mkxl
index b4b0cbc5e..bf48d8fa1 100644
--- a/tex/context/base/mkxl/typo-rub.mkxl
+++ b/tex/context/base/mkxl/typo-rub.mkxl
@@ -60,7 +60,7 @@
comment {#2}
\relax}
-\setvalue{\??rubyanalyze\v!top}#1#2%
+\defcsname\??rubyanalyze\v!top\endcsname#1#2%
{\clf_ruby
align {\rubyparameter\c!align}%
stretch {\rubyparameter\c!stretch}%
@@ -70,7 +70,7 @@
comment {#2}
\relax}
-\setvalue{\??rubyplacement\v!top}#1#2%
+\defcsname\??rubyplacement\v!top\endcsname#1#2%
{\setbox\scratchbox\hbox\bgroup
\userubystyleandcolor\c!style\c!color
#2%
@@ -79,7 +79,7 @@
\relax
#1}
-\setvalue{\??rubyplacement\v!right}#1#2%
+\defcsname\??rubyplacement\v!right\endcsname#1#2%
{#1%
\edef\p_distance{\rubyparameter\c!distance}%
\ifempty\p_distance\orelse\ifx\p_distance\v!none\else\hskip\p_distance\fi
@@ -88,7 +88,7 @@
\rubyparameter\c!left#2\rubyparameter\c!right
\endgroup}
-\setvalue{\??rubyplacement\v!left}#1#2%
+\defcsname\??rubyplacement\v!left\endcsname#1#2%
{\begingroup
\userubystyleandcolor\c!style\c!color
\rubyparameter\c!left#2\rubyparameter\c!right
diff --git a/tex/context/modules/mkiv/m-matrix.mkiv b/tex/context/modules/mkiv/m-matrix.mkiv
index 4a0bd712d..a5747ac81 100644
--- a/tex/context/modules/mkiv/m-matrix.mkiv
+++ b/tex/context/modules/mkiv/m-matrix.mkiv
@@ -729,6 +729,7 @@ $\qquad\qquad$
\stopsubject
\startsubject[title={Transpose a matrix}]
+
\startbuffer
\startluacode
moduledata.matrix.typeset(document.DemoMatrixA)
@@ -752,6 +753,7 @@ $\qquad\qquad$
\getbuffer[demo]
+\startbuffer
\startluacode
context("$<1,2,3> \\cdot <3,1,2, 4> \\ =\\ $ ")
context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 }))
@@ -882,7 +884,6 @@ context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 }))
context("$\\Rightarrow$")
moduledata.matrix.typeset(moduledata.matrix.rowechelon(m,1))
\stopluacode
-
\stopbuffer
\getbuffer[demo]
@@ -989,6 +990,4 @@ context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 }))
\getbuffer[demo]
-\stopsubject
-
\stoptext
diff --git a/tex/context/modules/mkiv/m-punk.mkiv b/tex/context/modules/mkiv/m-punk.mkiv
index 9eb7411ba..8aecfb01f 100644
--- a/tex/context/modules/mkiv/m-punk.mkiv
+++ b/tex/context/modules/mkiv/m-punk.mkiv
@@ -19,7 +19,7 @@
\ifcase\contextlmtxmode\else
\writestatus{punk}{use metapost library punk instead}
- \endinput
+ \expandafter\endinput
\fi
\startluacode
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index f3e33db69..f0cd85039 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 : 2021-12-14 19:16
+-- merge date : 2021-12-24 19:07
do -- begin closure to overcome local limits and interference