summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2014-03-22 15:31:00 +0100
committerHans Hagen <pragma@wxs.nl>2014-03-22 15:31:00 +0100
commitc70b2e466bbb07e976f8684d56ae4e5398169e7d (patch)
treed644f87f32feeddcfb2de6e8ebe6667423eb0be4 /tex
parent244a447d70f406e1341a56016564518013496a32 (diff)
downloadcontext-c70b2e466bbb07e976f8684d56ae4e5398169e7d.tar.gz
beta 2014.03.22 15:31
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/anch-pos.lua66
-rw-r--r--tex/context/base/attr-lay.mkiv3
-rw-r--r--tex/context/base/back-exp.lua4
-rw-r--r--tex/context/base/back-ini.lua8
-rw-r--r--tex/context/base/back-ini.mkiv11
-rw-r--r--tex/context/base/back-pdf.lua2
-rw-r--r--tex/context/base/back-pdf.mkiv2
-rw-r--r--tex/context/base/bibl-tra.lua10
-rw-r--r--tex/context/base/buff-imp-lua.lua2
-rw-r--r--tex/context/base/buff-ini.lua31
-rw-r--r--tex/context/base/buff-ver.lua64
-rw-r--r--tex/context/base/buff-ver.mkiv21
-rw-r--r--tex/context/base/catc-ctx.mkiv34
-rw-r--r--tex/context/base/catc-ini.lua4
-rw-r--r--tex/context/base/catc-ini.mkiv2
-rw-r--r--tex/context/base/catc-xml.mkiv21
-rw-r--r--tex/context/base/char-ini.lua3
-rw-r--r--tex/context/base/char-ini.mkiv44
-rw-r--r--tex/context/base/cldf-ini.lua714
-rw-r--r--tex/context/base/cldf-ini.mkiv9
-rw-r--r--tex/context/base/cldf-ver.lua22
-rw-r--r--tex/context/base/colo-ini.lua47
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/context-version.pdfbin4096 -> 4082 bytes
-rw-r--r--tex/context/base/context.mkiv6
-rw-r--r--tex/context/base/core-con.lua8
-rw-r--r--tex/context/base/core-env.mkiv18
-rw-r--r--tex/context/base/core-uti.lua61
-rw-r--r--tex/context/base/core-uti.mkiv16
-rw-r--r--tex/context/base/data-exp.lua4
-rw-r--r--tex/context/base/data-ini.lua2
-rw-r--r--tex/context/base/data-met.lua2
-rw-r--r--tex/context/base/data-res.lua8
-rw-r--r--tex/context/base/file-ini.lua22
-rw-r--r--tex/context/base/file-job.mkvi18
-rw-r--r--tex/context/base/file-mod.mkvi2
-rw-r--r--tex/context/base/file-res.lua2
-rw-r--r--tex/context/base/font-chk.lua2
-rw-r--r--tex/context/base/font-ctx.lua711
-rw-r--r--tex/context/base/font-fea.mkvi10
-rw-r--r--tex/context/base/font-fil.mkvi4
-rw-r--r--tex/context/base/font-gds.lua2
-rw-r--r--tex/context/base/font-ini.mkvi86
-rw-r--r--tex/context/base/font-lib.mkvi10
-rw-r--r--tex/context/base/font-mis.lua2
-rw-r--r--tex/context/base/font-odv.lua106
-rw-r--r--tex/context/base/font-ota.lua3
-rw-r--r--tex/context/base/font-otb.lua83
-rw-r--r--tex/context/base/font-otc.lua7
-rw-r--r--tex/context/base/font-otd.lua26
-rw-r--r--tex/context/base/font-otf.lua133
-rw-r--r--tex/context/base/font-otn.lua182
-rw-r--r--tex/context/base/font-otp.lua22
-rw-r--r--tex/context/base/font-otx.lua93
-rw-r--r--tex/context/base/font-sel.lua70
-rw-r--r--tex/context/base/font-sel.mkvi25
-rw-r--r--tex/context/base/font-set.mkvi29
-rw-r--r--tex/context/base/font-syn.lua10
-rw-r--r--tex/context/base/font-var.mkvi3
-rw-r--r--tex/context/base/l-dir.lua7
-rw-r--r--tex/context/base/l-io.lua2
-rw-r--r--tex/context/base/l-os.lua20
-rw-r--r--tex/context/base/l-table.lua38
-rw-r--r--tex/context/base/l-unicode.lua9
-rw-r--r--tex/context/base/lang-def.mkiv4
-rw-r--r--tex/context/base/lang-ini.mkiv4
-rw-r--r--tex/context/base/lang-lab.mkiv2
-rw-r--r--tex/context/base/lang-rep.lua2
-rw-r--r--tex/context/base/lpdf-ano.lua655
-rw-r--r--tex/context/base/lpdf-col.lua90
-rw-r--r--tex/context/base/lpdf-fld.lua191
-rw-r--r--tex/context/base/lpdf-fmt.lua4
-rw-r--r--tex/context/base/lpdf-grp.lua2
-rw-r--r--tex/context/base/lpdf-ini.lua349
-rw-r--r--tex/context/base/lpdf-mis.lua80
-rw-r--r--tex/context/base/lpdf-mov.lua5
-rw-r--r--tex/context/base/lpdf-nod.lua118
-rw-r--r--tex/context/base/lpdf-ren.lua76
-rw-r--r--tex/context/base/lpdf-swf.lua4
-rw-r--r--tex/context/base/lpdf-tag.lua147
-rw-r--r--tex/context/base/lpdf-u3d.lua6
-rw-r--r--tex/context/base/lpdf-wid.lua35
-rw-r--r--tex/context/base/luat-cbk.lua2
-rw-r--r--tex/context/base/luat-cnf.lua11
-rw-r--r--tex/context/base/luat-cod.lua5
-rw-r--r--tex/context/base/luat-ini.lua6
-rw-r--r--tex/context/base/luat-ini.mkiv71
-rw-r--r--tex/context/base/luat-run.lua76
-rw-r--r--tex/context/base/luat-sto.lua121
-rw-r--r--tex/context/base/lxml-lpt.lua55
-rw-r--r--tex/context/base/lxml-tex.lua159
-rw-r--r--tex/context/base/m-spreadsheet.lua4
-rw-r--r--tex/context/base/math-dir.lua1
-rw-r--r--tex/context/base/math-fbk.lua6
-rw-r--r--tex/context/base/math-fen.mkiv1
-rw-r--r--tex/context/base/math-frc.mkiv2
-rw-r--r--tex/context/base/math-ini.lua24
-rw-r--r--tex/context/base/math-ini.mkiv33
-rw-r--r--tex/context/base/math-noa.lua5
-rw-r--r--tex/context/base/math-rad.mkvi4
-rw-r--r--tex/context/base/meta-fnt.lua4
-rw-r--r--tex/context/base/meta-pdf.lua4
-rw-r--r--tex/context/base/meta-tex.mkiv4
-rw-r--r--tex/context/base/mlib-pdf.lua56
-rw-r--r--tex/context/base/mlib-pps.lua44
-rw-r--r--tex/context/base/mult-aux.lua2
-rw-r--r--tex/context/base/mult-aux.mkiv292
-rw-r--r--tex/context/base/mult-def.lua6
-rw-r--r--tex/context/base/mult-def.mkiv6
-rw-r--r--tex/context/base/mult-ini.lua6
-rw-r--r--tex/context/base/mult-low.lua9
-rw-r--r--tex/context/base/mult-nl.mkii4
-rw-r--r--tex/context/base/mult-prm.lua9
-rw-r--r--tex/context/base/node-aux.lua45
-rw-r--r--tex/context/base/node-fin.lua3
-rw-r--r--tex/context/base/node-ini.mkiv6
-rw-r--r--tex/context/base/node-inj.lua20
-rw-r--r--tex/context/base/node-met.lua2
-rw-r--r--tex/context/base/node-nut.lua52
-rw-r--r--tex/context/base/node-ref.lua71
-rw-r--r--tex/context/base/node-res.lua91
-rw-r--r--tex/context/base/pack-com.mkiv4
-rw-r--r--tex/context/base/pack-mis.mkvi2
-rw-r--r--tex/context/base/pack-mrl.mkiv4
-rw-r--r--tex/context/base/pack-rul.lua2
-rw-r--r--tex/context/base/page-flt.lua79
-rw-r--r--tex/context/base/page-imp.mkiv2
-rw-r--r--tex/context/base/page-mix.lua121
-rw-r--r--tex/context/base/page-mix.mkiv6
-rw-r--r--tex/context/base/page-mul.mkiv2
-rw-r--r--tex/context/base/page-txt.mkvi12
-rw-r--r--tex/context/base/pdfr-def.mkii2
-rw-r--r--tex/context/base/phys-dim.lua67
-rw-r--r--tex/context/base/publ-dat.lua10
-rw-r--r--tex/context/base/publ-ini.mkiv2
-rw-r--r--tex/context/base/s-abr-01.tex1
-rw-r--r--tex/context/base/s-inf-03.mkiv1
-rw-r--r--tex/context/base/scrn-but.mkvi4
-rw-r--r--tex/context/base/scrn-wid.mkvi2
-rw-r--r--tex/context/base/sort-ini.lua2
-rw-r--r--tex/context/base/spac-chr.lua2
-rw-r--r--tex/context/base/spac-hor.mkiv57
-rw-r--r--tex/context/base/spac-ver.lua58
-rw-r--r--tex/context/base/spac-ver.mkiv18
-rw-r--r--tex/context/base/status-files.pdfbin24795 -> 24618 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin226993 -> 241486 bytes
-rw-r--r--tex/context/base/strc-blk.lua2
-rw-r--r--tex/context/base/strc-con.mkvi5
-rw-r--r--tex/context/base/strc-des.mkvi4
-rw-r--r--tex/context/base/strc-doc.lua54
-rw-r--r--tex/context/base/strc-doc.mkiv3
-rw-r--r--tex/context/base/strc-enu.mkvi2
-rw-r--r--tex/context/base/strc-ini.lua73
-rw-r--r--tex/context/base/strc-itm.mkvi2
-rw-r--r--tex/context/base/strc-lst.lua18
-rw-r--r--tex/context/base/strc-lst.mkvi8
-rw-r--r--tex/context/base/strc-mar.lua3
-rw-r--r--tex/context/base/strc-not.mkvi11
-rw-r--r--tex/context/base/strc-num.lua9
-rw-r--r--tex/context/base/strc-num.mkiv16
-rw-r--r--tex/context/base/strc-pag.lua21
-rw-r--r--tex/context/base/strc-pag.mkiv6
-rw-r--r--tex/context/base/strc-ref.lua116
-rw-r--r--tex/context/base/strc-ref.mkvi3
-rw-r--r--tex/context/base/strc-reg.lua602
-rw-r--r--tex/context/base/strc-reg.mkiv250
-rw-r--r--tex/context/base/strc-rsc.lua4
-rw-r--r--tex/context/base/strc-sec.mkiv74
-rw-r--r--tex/context/base/strc-syn.lua35
-rw-r--r--tex/context/base/strc-syn.mkiv337
-rw-r--r--tex/context/base/syst-aux.lua5
-rw-r--r--tex/context/base/syst-aux.mkiv6
-rw-r--r--tex/context/base/syst-con.lua44
-rw-r--r--tex/context/base/syst-lua.lua44
-rw-r--r--tex/context/base/tabl-tbl.lua20
-rw-r--r--tex/context/base/tabl-tbl.mkiv6
-rw-r--r--tex/context/base/tabl-xtb.lua1
-rw-r--r--tex/context/base/tabl-xtb.mkvi16
-rw-r--r--tex/context/base/task-ini.lua7
-rw-r--r--tex/context/base/trac-deb.lua109
-rw-r--r--tex/context/base/trac-inf.lua29
-rw-r--r--tex/context/base/trac-vis.lua8
-rw-r--r--tex/context/base/type-imp-ebgaramond.mkiv45
-rw-r--r--tex/context/base/type-imp-latinmodern.mkiv5
-rw-r--r--tex/context/base/type-ini.mkvi12
-rw-r--r--tex/context/base/typo-brk.lua3
-rw-r--r--tex/context/base/typo-cln.lua1
-rw-r--r--tex/context/base/typo-dha.lua5
-rw-r--r--tex/context/base/typo-dir.lua120
-rw-r--r--tex/context/base/typo-drp.lua3
-rw-r--r--tex/context/base/typo-dua.lua2
-rw-r--r--tex/context/base/typo-dub.lua7
-rw-r--r--tex/context/base/typo-fln.lua5
-rw-r--r--tex/context/base/typo-fln.mkiv2
-rw-r--r--tex/context/base/typo-itc.lua1
-rw-r--r--tex/context/base/typo-krn.mkiv2
-rw-r--r--tex/context/base/typo-mar.lua52
-rw-r--r--tex/context/base/typo-mar.mkiv8
-rw-r--r--tex/context/base/typo-prc.lua15
-rw-r--r--tex/context/base/typo-rep.lua2
-rw-r--r--tex/context/base/typo-spa.lua1
-rw-r--r--tex/context/base/typo-tal.lua4
-rw-r--r--tex/context/base/typo-txt.mkvi2
-rw-r--r--tex/context/base/util-env.lua2
-rw-r--r--tex/context/base/util-prs.lua4
-rw-r--r--tex/context/base/util-str.lua125
-rw-r--r--tex/context/base/util-tab.lua25
-rw-r--r--tex/context/interface/cont-nl.xml4
-rw-r--r--tex/context/interface/keys-nl.xml4
-rw-r--r--tex/context/sample/cervantes-es.tex6
-rw-r--r--tex/context/sample/quevedo-es.tex19
-rw-r--r--tex/generic/context/luatex/luatex-fonts-inj.lua11
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua275
-rw-r--r--tex/generic/context/luatex/luatex-fonts-otn.lua24
214 files changed, 5983 insertions, 3312 deletions
diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua
index 0bd945c8a..c2b62bae7 100644
--- a/tex/context/base/anch-pos.lua
+++ b/tex/context/base/anch-pos.lua
@@ -14,6 +14,10 @@ more efficient.</p>
-- plus (extra) is obsolete but we will keep it for a while
+-- context(new_latelua_node(f_enhance(tag)))
+-- =>
+-- context.lateluafunction(function() f_enhance(tag) end)
+
-- maybe replace texsp by our own converter (stay at the lua end)
-- eventually mp will have large numbers so we can use sp there too
@@ -174,9 +178,12 @@ local nofpages = nil
-- beware ... we're not sparse here as lua will reserve slots for the nilled
+local getpos = function() getpos = backends.codeinjections.getpos return getpos () end
+local gethpos = function() gethpos = backends.codeinjections.gethpos return gethpos() end
+local getvpos = function() getvpos = backends.codeinjections.getvpos return getvpos() end
+
local function setdim(name,w,h,d,extra) -- will be used when we move to sp allover
- local x = pdf.h
- local y = pdf.v
+ local x, y = getpos()
if x == 0 then x = nil end
if y == 0 then y = nil end
if w == 0 then w = nil end
@@ -226,10 +233,13 @@ local function enhance(data)
data.r = region
end
if data.x == true then
- data.x = pdf.h
- end
- if data.y == true then
- data.y = pdf.v
+ if data.y == true then
+ data.x, data.y = getpos()
+ else
+ data.x = gethpos()
+ end
+ elseif data.y == true then
+ data.y = getvpos()
end
if data.p == true then
data.p = texgetcount("realpageno")
@@ -289,7 +299,7 @@ commands.setpos = setall
function jobpositions.b_col(tag)
tobesaved[tag] = {
r = true,
- x = pdf.h,
+ x = gethpos(),
w = 0,
}
insert(columns,tag)
@@ -301,7 +311,7 @@ function jobpositions.e_col(tag)
if not t then
-- something's wrong
else
- t.w = pdf.h - t.x
+ t.w = gethpos() - t.x
t.r = region
end
remove(columns)
@@ -328,8 +338,7 @@ end
function jobpositions.b_region(tag)
local last = tobesaved[tag]
- last.x = pdf.h
- last.y = pdf.v
+ last.x, last.y = getpos()
last.p = texgetcount("realpageno")
insert(regions,tag)
region = tag
@@ -337,10 +346,11 @@ end
function jobpositions.e_region(correct)
local last = tobesaved[region]
+ local v = getvpos()
if correct then
- last.h = last.y - pdf.v
+ last.h = last.y - v
end
- last.y = pdf.v
+ last.y = v
remove(regions)
region = regions[#regions]
end
@@ -357,7 +367,7 @@ function jobpositions.markregionbox(n,tag,correct)
tobesaved[tag] = {
p = true,
x = true,
- y = pdf.v, -- true,
+ y = getvpos(), -- true,
w = w ~= 0 and w or nil,
h = h ~= 0 and h or nil,
d = d ~= 0 and d or nil,
@@ -748,7 +758,7 @@ function commands.MPx(id)
if jpi then
local x = jpi.x
if x and x ~= true and x ~= 0 then
- context("%.5fpt",x*pt)
+ context("%.5Fpt",x*pt)
return
end
end
@@ -760,7 +770,7 @@ function commands.MPy(id)
if jpi then
local y = jpi.y
if y and y ~= true and y ~= 0 then
- context("%.5fpt",y*pt)
+ context("%.5Fpt",y*pt)
return
end
end
@@ -772,7 +782,7 @@ function commands.MPw(id)
if jpi then
local w = jpi.w
if w and w ~= 0 then
- context("%.5fpt",w*pt)
+ context("%.5Fpt",w*pt)
return
end
end
@@ -784,7 +794,7 @@ function commands.MPh(id)
if jpi then
local h = jpi.h
if h and h ~= 0 then
- context("%.5fpt",h*pt)
+ context("%.5Fpt",h*pt)
return
end
end
@@ -796,7 +806,7 @@ function commands.MPd(id)
if jpi then
local d = jpi.d
if d and d ~= 0 then
- context("%.5fpt",d*pt)
+ context("%.5Fpt",d*pt)
return
end
end
@@ -806,7 +816,7 @@ end
function commands.MPxy(id)
local jpi = collected[id]
if jpi then
- context('(%.5fpt,%.5fpt)',
+ context('(%.5Fpt,%.5Fpt)',
jpi.x*pt,
jpi.y*pt
)
@@ -818,7 +828,7 @@ end
function commands.MPll(id)
local jpi = collected[id]
if jpi then
- context('(%.5fpt,%.5fpt)',
+ context('(%.5Fpt,%.5Fpt)',
jpi.x *pt,
(jpi.y-jpi.d)*pt
)
@@ -830,7 +840,7 @@ end
function commands.MPlr(id)
local jpi = collected[id]
if jpi then
- context('(%.5fpt,%.5fpt)',
+ context('(%.5Fpt,%.5Fpt)',
(jpi.x + jpi.w)*pt,
(jpi.y - jpi.d)*pt
)
@@ -842,7 +852,7 @@ end
function commands.MPur(id)
local jpi = collected[id]
if jpi then
- context('(%.5fpt,%.5fpt)',
+ context('(%.5Fpt,%.5Fpt)',
(jpi.x + jpi.w)*pt,
(jpi.y + jpi.h)*pt
)
@@ -854,7 +864,7 @@ end
function commands.MPul(id)
local jpi = collected[id]
if jpi then
- context('(%.5fpt,%.5fpt)',
+ context('(%.5Fpt,%.5Fpt)',
jpi.x *pt,
(jpi.y + jpi.h)*pt
)
@@ -868,7 +878,7 @@ local function MPpos(id)
if jpi then
local p = jpi.p
if p then
- context("%s,%.5fpt,%.5fpt,%.5fpt,%.5fpt,%.5fpt",
+ context("%s,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt",
p,
jpi.x*pt,
jpi.y*pt,
@@ -926,7 +936,7 @@ local function MPpardata(n)
t = collected[tag]
end
if t then
- context("%.5fpt,%.5fpt,%.5fpt,%.5fpt,%s,%.5fpt",
+ context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%s,%.5Fpt",
t.hs*pt,
t.ls*pt,
t.rs*pt,
@@ -952,7 +962,7 @@ end
function commands.MPls(id)
local t = collected[id]
if t then
- context("%.5fpt",t.ls*pt)
+ context("%.5Fpt",t.ls*pt)
else
context("0pt")
end
@@ -961,7 +971,7 @@ end
function commands.MPrs(id)
local t = collected[id]
if t then
- context("%.5fpt",t.rs*pt)
+ context("%.5Fpt",t.rs*pt)
else
context("0pt")
end
@@ -994,7 +1004,7 @@ end
function commands.MPxywhd(id)
local t = collected[id]
if t then
- context("%.5fpt,%.5fpt,%.5fpt,%.5fpt,%.5fpt",
+ context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt",
t.x*pt,
t.y*pt,
t.w*pt,
diff --git a/tex/context/base/attr-lay.mkiv b/tex/context/base/attr-lay.mkiv
index d4aae3060..6055c2a73 100644
--- a/tex/context/base/attr-lay.mkiv
+++ b/tex/context/base/attr-lay.mkiv
@@ -94,8 +94,7 @@
\let\layoutcomponentboxattribute \empty
\unexpanded\def\showlayoutcomponents
- {%\ctxlua{attributes.viewerlayers.enable()}% automatic
- \let\setlayoutcomponentattribute \attr_layoutcomponent_set
+ {\let\setlayoutcomponentattribute \attr_layoutcomponent_set
\let\resetlayoutcomponentattribute\attr_layoutcomponent_reset}
\unexpanded\def\attr_layoutcomponent_cleanup
diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua
index d4133396b..79538eb72 100644
--- a/tex/context/base/back-exp.lua
+++ b/tex/context/base/back-exp.lua
@@ -609,8 +609,8 @@ function structurestags.setfigure(name,page,width,height)
usedimages.image[detailedtag("image")] = {
name = name,
page = page,
- width = number.todimen(width,"cm","%0.3fcm"),
- height = number.todimen(height,"cm","%0.3fcm"),
+ width = number.todimen(width, "cm","%0.3Fcm"),
+ height = number.todimen(height,"cm","%0.3Fcm"),
}
end
diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua
index 6f58b3262..e2dabd91e 100644
--- a/tex/context/base/back-ini.lua
+++ b/tex/context/base/back-ini.lua
@@ -95,3 +95,11 @@ tables.vfspecials = allocate {
startslant = comment,
stopslant = comment,
}
+
+-- we'd better have this return something (defaults)
+
+function codeinjections.getpos () return 0, 0 end
+function codeinjections.gethpos () return 0 end
+function codeinjections.getvpos () return 0 end
+function codeinjections.hasmatrix() return false end
+function codeinjections.getmatrix() return 1, 0, 0, 1, 0, 0 end
diff --git a/tex/context/base/back-ini.mkiv b/tex/context/base/back-ini.mkiv
index fc8759c14..de4ba6138 100644
--- a/tex/context/base/back-ini.mkiv
+++ b/tex/context/base/back-ini.mkiv
@@ -23,8 +23,9 @@
\unprotect
-\ifdefined\everybackendshipout \else \newtoks\everybackendshipout \fi
-\ifdefined\everylastbackendshipout \else \newtoks\everylastbackendshipout \fi
+\ifdefined\everybackendshipout \else \newtoks\everybackendshipout \fi
+\ifdefined\everylastbackendshipout \else \newtoks\everylastbackendshipout \fi
+\ifdefined\everybackendlastinshipout \else \newtoks\everybackendlastinshipout \fi % e.g. finalize via latelua
%D Right from the start \CONTEXT\ had a backend system based on
%D runtime pluggable code. As most backend issues involved specials
@@ -126,9 +127,9 @@
%D From now on, mapfile loading is also a special; we assume the
%D more or less standard dvips syntax.
-\let \doresetmapfilelist \donothing
-\let \doloadmapfile \gobbletwoarguments % + - = | filename
-\let \doloadmapline \gobbletwoarguments % + - = | fileline
+%let \doresetmapfilelist \donothing
+%let \doloadmapfile \gobbletwoarguments % + - = | filename
+%let \doloadmapline \gobbletwoarguments % + - = | fileline
%D \macros
%D {jobsuffix}
diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua
index f8a5dab6f..34a28e3f7 100644
--- a/tex/context/base/back-pdf.lua
+++ b/tex/context/base/back-pdf.lua
@@ -24,7 +24,7 @@ local context = context
local sind, cosd = math.sind, math.cosd
local insert, remove = table.insert, table.remove
-local f_matrix = string.formatters["%0.8f %0.8f %0.8f %0.8f"]
+local f_matrix = string.formatters["%0.8F %0.8F %0.8F %0.8F"]
function commands.pdfrotation(a)
-- todo: check for 1 and 0 and flush sparse
diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv
index 948a14138..5423a0df6 100644
--- a/tex/context/base/back-pdf.mkiv
+++ b/tex/context/base/back-pdf.mkiv
@@ -238,7 +238,7 @@
%D The following will move to the backend \LUA\ code:
-\appendtoks \ctxlua{backends.codeinjections.finalizepage ()}\to \everybackendshipout % is immediate
+%appendtoks \ctxlua{backends.codeinjections.finalizepage ()}\to \everybackendshipout % is immediate
%appendtoks \ctxlua{backends.codeinjections.finalizedocument()}\to \everylastbackendshipout % is immediate
%D Temporary hack, will be removed or improved or default.
diff --git a/tex/context/base/bibl-tra.lua b/tex/context/base/bibl-tra.lua
index 75dc3e86f..223554b4d 100644
--- a/tex/context/base/bibl-tra.lua
+++ b/tex/context/base/bibl-tra.lua
@@ -55,11 +55,11 @@ local ordered = { }
local shorts = { }
local mode = 0
-local template = utilities.strings.striplong([[
- \citation{*}
- \bibstyle{cont-%s}
- \bibdata{%s}
-]])
+local template = [[
+\citation{*}
+\bibstyle{cont-%s}
+\bibdata{%s}
+]]
local bibtexbin = environment.arguments.mlbibtex and "mlbibcontext" or "bibtex"
diff --git a/tex/context/base/buff-imp-lua.lua b/tex/context/base/buff-imp-lua.lua
index 04e79afba..4396c1ab8 100644
--- a/tex/context/base/buff-imp-lua.lua
+++ b/tex/context/base/buff-imp-lua.lua
@@ -139,7 +139,7 @@ local comment = P("--")
local name = (patterns.letter + patterns.underscore)
* (patterns.letter + patterns.underscore + patterns.digit)^0
local boundary = S('()[]{}')
-local special = S("-+/*^%=#") + P("..")
+local special = S("-+/*^%=#~|<>") + P("..")
-- The following longstring parser is taken from Roberto's documentation
-- that can be found at http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html.
diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua
index 08416c9ad..1196b7890 100644
--- a/tex/context/base/buff-ini.lua
+++ b/tex/context/base/buff-ini.lua
@@ -143,37 +143,12 @@ local function collectcontent(name,separator) -- no print
end
local function loadcontent(name) -- no print
- local names = getnames(name)
- local nnames = #names
- local ok = false
- if nnames == 0 then
- ok = load(getcontent("")) -- default buffer
- elseif nnames == 1 then
- ok = load(getcontent(names[1]))
- else
- -- lua 5.2 chunked load
- local i = 0
- ok = load(function()
- while true do
- i = i + 1
- if i > nnames then
- return nil
- end
- local c = getcontent(names[i])
- if c == "" then
- -- would trigger end of load
- else
- return c
- end
- end
- end)
- end
+ local content = collectcontent(name,"\n")
+ local ok, err = load(content)
if ok then
return ok()
- elseif nnames == 0 then
- report_buffers("invalid lua code in default buffer")
else
- report_buffers("invalid lua code in buffer %a",concat(names,","))
+ report_buffers("invalid lua code in buffer %a: %s",name,err or "unknown error")
end
end
diff --git a/tex/context/base/buff-ver.lua b/tex/context/base/buff-ver.lua
index 3300ac6cb..14914d42d 100644
--- a/tex/context/base/buff-ver.lua
+++ b/tex/context/base/buff-ver.lua
@@ -46,70 +46,70 @@ local v_all = variables.all
-- beware, all macros have an argument:
-local doinlineverbatimnewline = context.doinlineverbatimnewline
-local doinlineverbatimbeginline = context.doinlineverbatimbeginline
-local doinlineverbatimemptyline = context.doinlineverbatimemptyline
-local doinlineverbatimstart = context.doinlineverbatimstart
-local doinlineverbatimstop = context.doinlineverbatimstop
-
-local dodisplayverbatiminitialize = context.dodisplayverbatiminitialize -- the number of arguments might change over time
-local dodisplayverbatimnewline = context.dodisplayverbatimnewline
-local dodisplayverbatimbeginline = context.dodisplayverbatimbeginline
-local dodisplayverbatimemptyline = context.dodisplayverbatimemptyline
-local dodisplayverbatimstart = context.dodisplayverbatimstart
-local dodisplayverbatimstop = context.dodisplayverbatimstop
-
-local verbatim = context.verbatim
-local doverbatimspace = context.doverbatimspace
+local ctx_inlineverbatimnewline = context.doinlineverbatimnewline
+local ctx_inlineverbatimbeginline = context.doinlineverbatimbeginline
+local ctx_inlineverbatimemptyline = context.doinlineverbatimemptyline
+local ctx_inlineverbatimstart = context.doinlineverbatimstart
+local ctx_inlineverbatimstop = context.doinlineverbatimstop
+
+local ctx_displayverbatiminitialize = context.dodisplayverbatiminitialize -- the number of arguments might change over time
+local ctx_displayverbatimnewline = context.dodisplayverbatimnewline
+local ctx_displayverbatimbeginline = context.dodisplayverbatimbeginline
+local ctx_displayverbatimemptyline = context.dodisplayverbatimemptyline
+local ctx_displayverbatimstart = context.dodisplayverbatimstart
+local ctx_displayverbatimstop = context.dodisplayverbatimstop
+
+local ctx_verbatim = context.verbatim
+local ctx_verbatimspace = context.doverbatimspace
local CargOne = Carg(1)
local function f_emptyline(s,settings)
if settings and settings.nature == "inline" then
- doinlineverbatimemptyline()
+ ctx_inlineverbatimemptyline()
else
- dodisplayverbatimemptyline()
+ ctx_displayverbatimemptyline()
end
end
local function f_beginline(s,settings)
if settings and settings.nature == "inline" then
- doinlineverbatimbeginline()
+ ctx_inlineverbatimbeginline()
else
- dodisplayverbatimbeginline()
+ ctx_displayverbatimbeginline()
end
end
local function f_newline(s,settings)
if settings and settings.nature == "inline" then
- doinlineverbatimnewline()
+ ctx_inlineverbatimnewline()
else
- dodisplayverbatimnewline()
+ ctx_displayverbatimnewline()
end
end
local function f_start(s,settings)
if settings and settings.nature == "inline" then
- doinlineverbatimstart()
+ ctx_inlineverbatimstart()
else
- dodisplayverbatimstart()
+ ctx_displayverbatimstart()
end
end
local function f_stop(s,settings)
if settings and settings.nature == "inline" then
- doinlineverbatimstop()
+ ctx_inlineverbatimstop()
else
- dodisplayverbatimstop()
+ ctx_displayverbatimstop()
end
end
local function f_default(s) -- (s,settings)
- verbatim(s)
+ ctx_verbatim(s)
end
local function f_space() -- (s,settings)
- doverbatimspace()
+ ctx_verbatimspace()
end
local function f_signal() -- (s,settings)
@@ -200,7 +200,7 @@ local function getvisualizer(method,nature)
end
end
-local fallback = context.verbatim
+local ctx_fallback = ctx_verbatim
local function makepattern(visualizer,replacement,pattern)
if not pattern then
@@ -208,9 +208,9 @@ local function makepattern(visualizer,replacement,pattern)
return patterns.alwaystrue
else
if type(visualizer) == "table" and type(replacement) == "string" then
- replacement = visualizer[replacement] or fallback
+ replacement = visualizer[replacement] or ctx_fallback
else
- replacement = fallback
+ replacement = ctx_fallback
end
return (C(pattern) * CargOne) / replacement
end
@@ -506,7 +506,7 @@ local function visualize(content,settings) -- maybe also method in settings
if trace_visualize then
report_visualizers("visualize using method %a",method)
end
- fallback(content,1,settings)
+ ctx_fallback(content,1,settings)
end
end
end
@@ -711,7 +711,7 @@ commands.loadvisualizer = visualizers.load
function commands.typebuffer(settings)
local lines = getlines(settings.name)
if lines then
- dodisplayverbatiminitialize(#lines)
+ ctx_displayverbatiminitialize(#lines)
local content, m = filter(lines,settings)
if content and content ~= "" then
-- content = decodecomment(content)
diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv
index 6c4fb6fc1..17dfd9d69 100644
--- a/tex/context/base/buff-ver.mkiv
+++ b/tex/context/base/buff-ver.mkiv
@@ -19,6 +19,8 @@
\unprotect
+\startcontextdefinitioncode
+
\definesystemattribute[verbatimline][public]
\appendtoksonce
@@ -169,7 +171,11 @@
\appendtoks
\setuevalue{\e!start\currenttyping}{\buff_verbatim_typing_start{\currenttyping}}%
\setuevalue{\e!stop \currenttyping}{\buff_verbatim_typing_stop {\currenttyping}}%
- \normalexpanded{\definelinenumbering[\currenttyping]}%
+ \ifx\currenttypingparent\empty
+ \normalexpanded{\definelinenumbering[\currenttyping]}%
+ \else
+ \normalexpanded{\definelinenumbering[\currenttyping][\currenttypingparent]}%
+ \fi
\to \everydefinetyping
\appendtoks
@@ -261,7 +267,7 @@
{\dontleavehmode
\bgroup
\edef\currenttype{#1}%
- \doifnextoptionalelse\buff_verbatim_type_yes\buff_verbatim_type_nop}
+ \doifnextoptionalcselse\buff_verbatim_type_yes\buff_verbatim_type_nop}
\def\buff_verbatim_type_yes[#1]%
{\setupcurrenttype[#1]%
@@ -277,7 +283,7 @@
\edef\currenttype{#1}%
\lettypeparameter\c!lines\v!hyphenated
\let\specialobeyedspace\specialstretchedspace
- \doifnextoptionalelse\buff_verbatim_type_yes\buff_verbatim_type_nop}
+ \doifnextoptionalcselse\buff_verbatim_type_yes\buff_verbatim_type_nop}
\def\buff_verbatim_type_one
{\ifx\next\bgroup
@@ -696,8 +702,11 @@
\definetyping[\v!typing]
-\setuptyping[\v!file] [\s!parent=\??typing\v!typing] % we don't want \start..\stop overload
-\setuptyping[\v!buffer][\s!parent=\??typing\v!file] % we don't want \start..\stop overload
+\setuptyping [\v!file] [\s!parent=\??typing \v!typing] % we don't want \start..\stop overload
+\setuplinenumbering[\v!file] [\s!parent=\??linenumbering\v!typing]
+
+\setuptyping [\v!buffer][\s!parent=\??typing \v!file] % we don't want \start..\stop overload
+\setuplinenumbering[\v!buffer][\s!parent=\??linenumbering\v!file]
%D The setups for inline verbatim default to:
@@ -910,4 +919,6 @@
\def\tex #1{\letterbackslash#1}%
\to \everysimplifycommands
+\stopcontextdefinitioncode
+
\protect \endinput
diff --git a/tex/context/base/catc-ctx.mkiv b/tex/context/base/catc-ctx.mkiv
index ddade7f52..5af8a5035 100644
--- a/tex/context/base/catc-ctx.mkiv
+++ b/tex/context/base/catc-ctx.mkiv
@@ -142,4 +142,38 @@
\normalprotected\def\stopcontextcode
{\popcatcodetable}
+% not visible, only for special cases
+
+\newcatcodetable \ctdcatcodes % context definitions
+
+\startcatcodetable \ctdcatcodes
+ \catcode\tabasciicode \ignorecatcode
+ \catcode\endoflineasciicode \ignorecatcode
+ \catcode\formfeedasciicode \ignorecatcode
+ \catcode\spaceasciicode \ignorecatcode
+ \catcode\endoffileasciicode \ignorecatcode
+ \catcode\circumflexasciicode \superscriptcatcode % candidate
+ \catcode\underscoreasciicode \lettercatcode
+ \catcode\ampersandasciicode \alignmentcatcode
+% \catcode\colonasciicode \lettercatcode % candidate
+ \catcode\backslashasciicode \escapecatcode
+ \catcode\leftbraceasciicode \begingroupcatcode
+ \catcode\rightbraceasciicode \endgroupcatcode
+ \catcode\dollarasciicode \mathshiftcatcode
+ \catcode\hashasciicode \parametercatcode
+ \catcode\commentasciicode \commentcatcode
+ \catcode\atsignasciicode \lettercatcode
+ \catcode\exclamationmarkasciicode\lettercatcode
+ \catcode\questionmarkasciicode \lettercatcode
+ \catcode\tildeasciicode \activecatcode
+ \catcode\barasciicode \activecatcode
+\stopcatcodetable
+
+\normalprotected\def\startcontextdefinitioncode
+ {\pushcatcodetable
+ \catcodetable\ctdcatcodes}
+
+\normalprotected\def\stopcontextdefinitioncode
+ {\popcatcodetable}
+
\endinput
diff --git a/tex/context/base/catc-ini.lua b/tex/context/base/catc-ini.lua
index d4f9b65af..9241f5a1b 100644
--- a/tex/context/base/catc-ini.lua
+++ b/tex/context/base/catc-ini.lua
@@ -39,3 +39,7 @@ end
table.setmetatableindex(numbers,function(t,k) if type(k) == "number" then t[k] = k return k end end)
table.setmetatableindex(names, function(t,k) if type(k) == "string" then t[k] = k return k end end)
+
+commands.registercatcodetable = catcodes.register
+--------.definecatcodetable = characters.define -- not yet defined
+--------.setcharactercodes = characters.setcodes -- not yet defined
diff --git a/tex/context/base/catc-ini.mkiv b/tex/context/base/catc-ini.mkiv
index 791ce31c4..d8247217c 100644
--- a/tex/context/base/catc-ini.mkiv
+++ b/tex/context/base/catc-ini.mkiv
@@ -108,7 +108,7 @@
\expandafter\xdef\csname\??catcodetablen\number\c_syst_catcodes_n\endcsname{\string#1}% logging
\newconstant#1%
#1\c_syst_catcodes_n
- \ctxlua{catcodes.register("\expandafter\gobbleoneargument\string#1",\number#1)}}
+ \ctxcommand{registercatcodetable("\expandafter\gobbleoneargument\string#1",\number#1)}}
\newtoks \everysetdefaultcatcodes
diff --git a/tex/context/base/catc-xml.mkiv b/tex/context/base/catc-xml.mkiv
index 5e7df11f5..a23a2fe0a 100644
--- a/tex/context/base/catc-xml.mkiv
+++ b/tex/context/base/catc-xml.mkiv
@@ -114,20 +114,11 @@
%D We register the catcodetables at the \LUA\ end where some further
%D initializations take place.
-\ctxlua {
- characters.define(
- { % letter catcodes
- \number\xmlcatcodesn,
- \number\xmlcatcodese,
- \number\xmlcatcodesr,
- },
- { % activate catcodes
- \number\xmlcatcodesn,
- \number\xmlcatcodese,
- \number\xmlcatcodesr,
- }
- )
- catcodes.register("xmlcatcodes",\number\xmlcatcodes)
-}
+\ctxcommand{definecatcodetable(
+ {\number\xmlcatcodesn,\number\xmlcatcodese,\number\xmlcatcodesr},% letter catcodes
+ {\number\xmlcatcodesn,\number\xmlcatcodese,\number\xmlcatcodesr} % activate catcodes
+)}
+
+\ctxcommand{registercatcodetable("xmlcatcodes",\number\xmlcatcodes)}
\endinput
diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua
index ac47760f3..d6e8d18a9 100644
--- a/tex/context/base/char-ini.lua
+++ b/tex/context/base/char-ini.lua
@@ -1214,3 +1214,6 @@ end
-- entities.amp = utfchar(characters.activeoffset + utfbyte("&"))
-- entities.gt = utfchar(characters.activeoffset + utfbyte(">"))
-- end
+
+commands.definecatcodetable = characters.define
+commands.setcharactercodes = characters.setcodes
diff --git a/tex/context/base/char-ini.mkiv b/tex/context/base/char-ini.mkiv
index 113d26709..db52ae723 100644
--- a/tex/context/base/char-ini.mkiv
+++ b/tex/context/base/char-ini.mkiv
@@ -65,32 +65,30 @@
% \def\setcclcuc#1#2#3{\global\catcode#1=\lettercatcode\global\lccode#1=#2\global\uccode#1=#3\relax}
% \def\setcclcucself#1{\global\catcode#1=\lettercatcode\global\lccode#1=#1\global\uccode#1=#1\relax }
-\ctxlua{characters.setcodes()}
+\ctxcommand{setcharactercodes()}
% Is setting up vrb tpa and tpb needed?
-\ctxlua {
- characters.define(
- { % letter catcodes
- \number\texcatcodes,
- \number\ctxcatcodes,
- \number\notcatcodes,
- %number\mthcatcodes,
- \number\vrbcatcodes,
- \number\prtcatcodes,
- \number\tpacatcodes,
- \number\tpbcatcodes,
- \number\txtcatcodes,
- },
- { % activate catcodes
- \number\ctxcatcodes,
- \number\notcatcodes,
- \number\prtcatcodes, % new
- }
- )
-% catcodes.register("xmlcatcodes",\number\xmlcatcodes)
-}
+\ctxcommand{definecatcodetable(
+ { % letter catcodes
+ \number\texcatcodes,
+ \number\ctxcatcodes,
+ \number\notcatcodes,
+ %number\mthcatcodes,
+ \number\vrbcatcodes,
+ \number\prtcatcodes,
+ \number\tpacatcodes,
+ \number\tpbcatcodes,
+ \number\txtcatcodes,
+ },
+ { % activate catcodes
+ \number\ctxcatcodes,
+ \number\notcatcodes,
+ \number\prtcatcodes, % new
+ }
+)}
-\def\chardescription#1{\ctxcommand{chardescription(\number#1)}}
+\def\chardescription#1%
+ {\ctxcommand{chardescription(\number#1)}}
\protect \endinput
diff --git a/tex/context/base/cldf-ini.lua b/tex/context/base/cldf-ini.lua
index b29db4090..0a0f71266 100644
--- a/tex/context/base/cldf-ini.lua
+++ b/tex/context/base/cldf-ini.lua
@@ -23,6 +23,11 @@ if not modules then modules = { } end modules ['cldf-ini'] = {
-- todo: context("%bold{total: }%s",total)
-- todo: context.documentvariable("title")
+-- during the crited project we ran into the situation that luajittex was 10-20 times
+-- slower that luatex ... after 3 days of testing and probing we finally figured out that
+-- the the differences between the lua and luajit hashers can lead to quite a slowdown
+-- in some cases.
+
local tex = tex
context = context or { }
@@ -37,7 +42,6 @@ local formatters = string.formatters -- using formatteds is slower in this case
local loaddata = io.loaddata
local texsprint = tex.sprint
-local textprint = tex.tprint
local texprint = tex.print
local texwrite = tex.write
local texgetcount = tex.getcount
@@ -64,72 +68,239 @@ local report_cld = logs.reporter("cld","stack")
local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end)
--- for tracing it's easier to have two stacks
+-- In earlier experiments a function tables was referred to as lua.calls and the
+-- primitive \luafunctions was \luacall.
-local _stack_f_, _n_f_ = { }, 0
-local _stack_n_, _n_n_ = { }, 0
+local luafunctions = lua.get_functions_table and lua.get_functions_table()
+local usedstack = nil
+local showstackusage = false
-local function _store_f_(ti)
- _n_f_ = _n_f_ + 1
- _stack_f_[_n_f_] = ti
- return _n_f_
-end
+-- luafunctions = false
-local function _store_n_(ti)
- _n_n_ = _n_n_ + 1
- _stack_n_[_n_n_] = ti
- return _n_n_
-end
+trackers.register("context.stack",function(v) showstackusage = v end)
-local function _flush_f_(n)
- local sn = _stack_f_[n]
- if not sn then
- report_cld("data with id %a cannot be found on stack",n)
- else
- local tn = type(sn)
- if tn == "function" then
- if not sn() and texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
- _stack_f_[n] = nil
- else
- -- keep, beware, that way the stack can grow
- end
+local storefunction, flushfunction
+local storenode, flushnode
+local registerfunction, unregisterfunction, reservefunction, knownfunctions, callfunctiononce
+
+if luafunctions then
+
+ local freed, nofused, noffreed = { }, 0, 0 -- maybe use the number of @@trialtypesetting
+
+ usedstack = function()
+ return nofused, noffreed
+ end
+
+ flushfunction = function(slot,arg)
+ if arg() then
+ -- keep
+ elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
+ noffreed = noffreed + 1
+ freed[noffreed] = slot
+ luafunctions[slot] = false
else
- if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
- writenode(sn)
- _stack_f_[n] = nil
- else
- writenode(copynodelist(sn))
- -- keep, beware, that way the stack can grow
- end
+ -- keep
end
end
-end
-local function _flush_n_(n)
- local sn = _stack_n_[n]
- if not sn then
- report_cld("data with id %a cannot be found on stack",n)
- elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
- writenode(sn)
- _stack_n_[n] = nil
- else
- writenode(copynodelist(sn))
- -- keep, beware, that way the stack can grow
+ storefunction = function(arg)
+ local f = function(slot) flushfunction(slot,arg) end
+ if noffreed > 0 then
+ local n = freed[noffreed]
+ freed[noffreed] = nil
+ noffreed = noffreed - 1
+ luafunctions[n] = f
+ return n
+ else
+ nofused = nofused + 1
+ luafunctions[nofused] = f
+ return nofused
+ end
+ end
+
+ flushnode = function(slot,arg)
+ if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
+ writenode(arg)
+ noffreed = noffreed + 1
+ freed[noffreed] = slot
+ luafunctions[slot] = false
+ else
+ writenode(copynodelist(arg))
+ end
+ end
+
+ storenode = function(arg)
+ local f = function(slot) flushnode(slot,arg) end
+ if noffreed > 0 then
+ local n = freed[noffreed]
+ freed[noffreed] = nil
+ noffreed = noffreed - 1
+ luafunctions[n] = f
+ return n
+ else
+ nofused = nofused + 1
+ luafunctions[nofused] = f
+ return nofused
+ end
+ end
+
+ registerfunction = function(f)
+ if type(f) == "string" then
+ f = loadstring(f)
+ end
+ if type(f) ~= "function" then
+ f = function() report_cld("invalid function %A",f) end
+ end
+ if noffreed > 0 then
+ local n = freed[noffreed]
+ freed[noffreed] = nil
+ noffreed = noffreed - 1
+ luafunctions[n] = f
+ return n
+ else
+ nofused = nofused + 1
+ luafunctions[nofused] = f
+ return nofused
+ end
+ end
+
+ unregisterfunction = function(slot)
+ if luafunctions[slot] then
+ noffreed = noffreed + 1
+ freed[noffreed] = slot
+ luafunctions[slot] = false
+ else
+ report_cld("invalid function slot %A",slot)
+ end
+ end
+
+ reservefunction = function()
+ if noffreed > 0 then
+ local n = freed[noffreed]
+ freed[noffreed] = nil
+ noffreed = noffreed - 1
+ return n
+ else
+ nofused = nofused + 1
+ return nofused
+ end
end
-end
-function context.restart()
- _stack_f_, _n_f_ = { }, 0
- _stack_n_, _n_n_ = { }, 0
+ callfunctiononce = function(slot)
+ luafunctions[slot](slot)
+ noffreed = noffreed + 1
+ freed[noffreed] = slot
+ luafunctions[slot] = false
+ end
+
+ table.setmetatablecall(luafunctions,function(t,n) return luafunctions[n](n) end)
+
+ knownfunctions = luafunctions
+
+else
+
+ local luafunctions, noffunctions = { }, 0
+ local luanodes, nofnodes = { }, 0
+
+ usedstack = function()
+ return noffunctions + nofnodes, 0
+ end
+
+ flushfunction = function(n)
+ local sn = luafunctions[n]
+ if not sn then
+ report_cld("data with id %a cannot be found on stack",n)
+ elseif not sn() and texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
+ luafunctions[n] = nil
+ end
+ end
+
+ storefunction = function(ti)
+ noffunctions = noffunctions + 1
+ luafunctions[noffunctions] = ti
+ return noffunctions
+ end
+
+ -- freefunction = function(n)
+ -- luafunctions[n] = nil
+ -- end
+
+ flushnode = function(n)
+ local sn = luanodes[n]
+ if not sn then
+ report_cld("data with id %a cannot be found on stack",n)
+ elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private!
+ writenode(sn)
+ luanodes[n] = nil
+ else
+ writenode(copynodelist(sn))
+ end
+ end
+
+ storenode = function(ti)
+ nofnodes = nofnodes + 1
+ luanodes[nofnodes] = ti
+ return nofnodes
+ end
+
+ _cldf_ = flushfunction -- global
+ _cldn_ = flushnode -- global
+ -- _cldl_ = function(n) return luafunctions[n]() end -- luafunctions(n)
+ _cldl_ = luafunctions
+
+ registerfunction = function(f)
+ if type(f) == "string" then
+ f = loadstring(f)
+ end
+ if type(f) ~= "function" then
+ f = function() report_cld("invalid function %A",f) end
+ end
+ noffunctions = noffunctions + 1
+ luafunctions[noffunctions] = f
+ return noffunctions
+ end
+
+ unregisterfunction = function(slot)
+ if luafunctions[slot] then
+ luafunctions[slot] = nil
+ else
+ report_cld("invalid function slot %A",slot)
+ end
+ end
+
+ reservefunction = function()
+ noffunctions = noffunctions + 1
+ return noffunctions
+ end
+
+ callfunctiononce = function(slot)
+ luafunctions[slot](slot)
+ luafunctions[slot] = nil
+ end
+
+ table.setmetatablecall(luafunctions,function(t,n) return luafunctions[n](n) end)
+
+ knownfunctions = luafunctions
+
end
-context._stack_f_ = _stack_f_
-context._store_f_ = _store_f_
-context._flush_f_ = _flush_f_ _cldf_ = _flush_f_
+context.registerfunction = registerfunction
+context.unregisterfunction = unregisterfunction
+context.reservefunction = reservefunction
+context.knownfunctions = knownfunctions
+context.callfunctiononce = callfunctiononce _cldo_ = callfunctiononce
+context.storenode = storenode -- private helper
+
+function commands.ctxfunction(code)
+ context(registerfunction(code))
+end
-context._stack_n_ = _stack_n_
-context._store_n_ = _store_n_
-context._flush_n_ = _flush_n_ _cldn_ = _flush_n_
+-- local f_cldo = formatters["_cldo_(%i)"]
+-- local latelua_node = nodes.pool.latelua
+--
+-- function context.lateluafunctionnnode(f)
+-- return latelua_node(f_cldo(registerfunction(f)))
+-- end
-- Should we keep the catcodes with the function?
@@ -359,98 +530,210 @@ end
local containseol = patterns.containseol
-local function writer(parent,command,first,...) -- already optimized before call
- local t = { first, ... }
- flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
- local direct = false
- for i=1,#t do
- local ti = t[i]
- local typ = type(ti)
- if direct then
- if typ == "string" or typ == "number" then
- flush(currentcatcodes,ti)
- else -- node.write
- report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
- end
- direct = false
- elseif ti == nil then
- -- nothing
- elseif ti == "" then
- flush(currentcatcodes,"{}")
- elseif typ == "string" then
- -- is processelines seen ?
- if processlines and lpegmatch(containseol,ti) then
- flush(currentcatcodes,"{")
- local flushlines = parent.__flushlines or flushlines
- flushlines(ti)
- flush(currentcatcodes,"}")
- elseif currentcatcodes == contentcatcodes then
+local writer
+
+if luafunctions then
+
+ writer = function (parent,command,first,...) -- already optimized before call
+ local t = { first, ... }
+ flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
+ local direct = false
+ for i=1,#t do
+ local ti = t[i]
+ local typ = type(ti)
+ if direct then
+ if typ == "string" or typ == "number" then
+ flush(currentcatcodes,ti)
+ else -- node.write
+ report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
+ end
+ direct = false
+ elseif ti == nil then
+ -- nothing
+ elseif ti == "" then
+ flush(currentcatcodes,"{}")
+ elseif typ == "string" then
+ -- is processelines seen ?
+ if processlines and lpegmatch(containseol,ti) then
+ flush(currentcatcodes,"{")
+ local flushlines = parent.__flushlines or flushlines
+ flushlines(ti)
+ flush(currentcatcodes,"}")
+ elseif currentcatcodes == contentcatcodes then
+ flush(currentcatcodes,"{",ti,"}")
+ else
+ flush(currentcatcodes,"{")
+ flush(contentcatcodes,ti)
+ flush(currentcatcodes,"}")
+ end
+ elseif typ == "number" then
+ -- numbers never have funny catcodes
flush(currentcatcodes,"{",ti,"}")
- else
- flush(currentcatcodes,"{")
- flush(contentcatcodes,ti)
- flush(currentcatcodes,"}")
- end
- elseif typ == "number" then
- -- numbers never have funny catcodes
- flush(currentcatcodes,"{",ti,"}")
- elseif typ == "table" then
- local tn = #ti
- if tn == 0 then
- local done = false
- for k, v in next, ti do
- if done then
- if v == "" then
- flush(currentcatcodes,",",k,'=')
+ elseif typ == "table" then
+ local tn = #ti
+ if tn == 0 then
+ local done = false
+ for k, v in next, ti do
+ if done then
+ if v == "" then
+ flush(currentcatcodes,",",k,'=')
+ else
+ flush(currentcatcodes,",",k,"={",v,"}")
+ end
else
- flush(currentcatcodes,",",k,"={",v,"}")
+ if v == "" then
+ flush(currentcatcodes,"[",k,"=")
+ else
+ flush(currentcatcodes,"[",k,"={",v,"}")
+ end
+ done = true
end
+ end
+ if done then
+ flush(currentcatcodes,"]")
+ else
+ flush(currentcatcodes,"[]")
+ end
+ elseif tn == 1 then -- some 20% faster than the next loop
+ local tj = ti[1]
+ if type(tj) == "function" then
+ flush(currentcatcodes,"[\\cldl",storefunction(tj),"]")
else
- if v == "" then
- flush(currentcatcodes,"[",k,"=")
+ flush(currentcatcodes,"[",tj,"]")
+ end
+ else -- is concat really faster than flushes here? probably needed anyway (print artifacts)
+ flush(currentcatcodes,"[")
+ for j=1,tn do
+ local tj = ti[j]
+ if type(tj) == "function" then
+ if j == tn then
+ flush(currentcatcodes,"\\cldl",storefunction(tj),"]")
+ else
+ flush(currentcatcodes,"\\cldl",storefunction(tj),",")
+ end
else
- flush(currentcatcodes,"[",k,"={",v,"}")
+ if j == tn then
+ flush(currentcatcodes,tj,"]")
+ else
+ flush(currentcatcodes,tj,",")
+ end
end
- done = true
end
end
- if done then
- flush(currentcatcodes,"]")
+ elseif typ == "function" then
+ flush(currentcatcodes,"{\\cldl ",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ if ti then
+ flushdirect(currentcatcodes,"\r")
else
- flush(currentcatcodes,"[]")
+ direct = true
+ end
+ elseif typ == "thread" then
+ report_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(ti) then -- slow
+ flush(currentcatcodes,"{\\cldl",storenode(ti),"}")
+ else
+ report_context("error: %a gets a weird argument %a",command,ti)
+ end
+ end
+ end
+
+else
+
+ writer = function (parent,command,first,...) -- already optimized before call
+ local t = { first, ... }
+ flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes
+ local direct = false
+ for i=1,#t do
+ local ti = t[i]
+ local typ = type(ti)
+ if direct then
+ if typ == "string" or typ == "number" then
+ flush(currentcatcodes,ti)
+ else -- node.write
+ report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
end
- elseif tn == 1 then -- some 20% faster than the next loop
- local tj = ti[1]
- if type(tj) == "function" then
- flush(currentcatcodes,"[\\cldf{",_store_f_(tj),"}]")
+ direct = false
+ elseif ti == nil then
+ -- nothing
+ elseif ti == "" then
+ flush(currentcatcodes,"{}")
+ elseif typ == "string" then
+ -- is processelines seen ?
+ if processlines and lpegmatch(containseol,ti) then
+ flush(currentcatcodes,"{")
+ local flushlines = parent.__flushlines or flushlines
+ flushlines(ti)
+ flush(currentcatcodes,"}")
+ elseif currentcatcodes == contentcatcodes then
+ flush(currentcatcodes,"{",ti,"}")
else
- flush(currentcatcodes,"[",tj,"]")
+ flush(currentcatcodes,"{")
+ flush(contentcatcodes,ti)
+ flush(currentcatcodes,"}")
end
- else -- is concat really faster than flushes here? probably needed anyway (print artifacts)
- for j=1,tn do
- local tj = ti[j]
+ elseif typ == "number" then
+ -- numbers never have funny catcodes
+ flush(currentcatcodes,"{",ti,"}")
+ elseif typ == "table" then
+ local tn = #ti
+ if tn == 0 then
+ local done = false
+ for k, v in next, ti do
+ if done then
+ if v == "" then
+ flush(currentcatcodes,",",k,'=')
+ else
+ flush(currentcatcodes,",",k,"={",v,"}")
+ end
+ else
+ if v == "" then
+ flush(currentcatcodes,"[",k,"=")
+ else
+ flush(currentcatcodes,"[",k,"={",v,"}")
+ end
+ done = true
+ end
+ end
+ if done then
+ flush(currentcatcodes,"]")
+ else
+ flush(currentcatcodes,"[]")
+ end
+ elseif tn == 1 then -- some 20% faster than the next loop
+ local tj = ti[1]
if type(tj) == "function" then
- ti[j] = "\\cldf{" .. _store_f_(tj) .. "}"
+ flush(currentcatcodes,"[\\cldf{",storefunction(tj),"}]")
+ else
+ flush(currentcatcodes,"[",tj,"]")
+ end
+ else -- is concat really faster than flushes here? probably needed anyway (print artifacts)
+ for j=1,tn do
+ local tj = ti[j]
+ if type(tj) == "function" then
+ ti[j] = "\\cldf{" .. storefunction(tj) .. "}"
+ end
end
+ flush(currentcatcodes,"[",concat(ti,","),"]")
end
- flush(currentcatcodes,"[",concat(ti,","),"]")
- end
- elseif typ == "function" then
- flush(currentcatcodes,"{\\cldf{",_store_f_(ti),"}}") -- todo: ctx|prt|texcatcodes
- elseif typ == "boolean" then
- if ti then
- flushdirect(currentcatcodes,"\r")
+ elseif typ == "function" then
+ flush(currentcatcodes,"{\\cldf{",storefunction(ti),"}}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ if ti then
+ flushdirect(currentcatcodes,"\r")
+ else
+ direct = true
+ end
+ elseif typ == "thread" then
+ report_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(ti) then -- slow
+ flush(currentcatcodes,"{\\cldn{",storenode(ti),"}}")
else
- direct = true
+ report_context("error: %a gets a weird argument %a",command,ti)
end
- elseif typ == "thread" then
- report_context("coroutines not supported as we cannot yield across boundaries")
- elseif isnode(ti) then -- slow
- flush(currentcatcodes,"{\\cldn{",_store_n_(ti),"}}")
- else
- report_context("error: %a gets a weird argument %a",command,ti)
end
end
+
end
local generics = { } context.generics = generics
@@ -507,70 +790,154 @@ end
function context.constructcsonly(k) -- not much faster than the next but more mem efficient
local c = "\\" .. tostring(generics[k] or k)
- rawset(context, k, function()
+ local v = function()
flush(prtcatcodes,c)
- end)
+ end
+ rawset(context,k,v)
+ return v
end
function context.constructcs(k)
local c = "\\" .. tostring(generics[k] or k)
- rawset(context, k, function(first,...)
+ local v = function(first,...)
if first == nil then
flush(prtcatcodes,c)
else
return writer(context,c,first,...)
end
- end)
+ end
+ rawset(context,k,v)
+ return v
end
-local function caller(parent,f,a,...)
- if not parent then
- -- so we don't need to test in the calling (slower but often no issue)
- elseif f ~= nil then
- local typ = type(f)
- if typ == "string" then
- if a then
- flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
- elseif processlines and lpegmatch(containseol,f) then
- local flushlines = parent.__flushlines or flushlines
- flushlines(f)
- else
- flush(contentcatcodes,f)
- end
- elseif typ == "number" then
- if a then
- flush(currentcatcodes,f,a,...)
+-- local splitformatters = utilities.strings.formatters.new(true) -- not faster (yet)
+
+local caller
+
+if luafunctions then
+
+ caller = function(parent,f,a,...)
+ if not parent then
+ -- so we don't need to test in the calling (slower but often no issue)
+ elseif f ~= nil then
+ local typ = type(f)
+ if typ == "string" then
+ if f == "" then
+ -- new, can save a bit sometimes
+ -- if trace_context then
+ -- report_context("empty argument to context()")
+ -- end
+ elseif a then
+ flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
+ -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes
+ elseif processlines and lpegmatch(containseol,f) then
+ local flushlines = parent.__flushlines or flushlines
+ flushlines(f)
+ else
+ flush(contentcatcodes,f)
+ end
+ elseif typ == "number" then
+ if a then
+ flush(currentcatcodes,f,a,...)
+ else
+ flush(currentcatcodes,f)
+ end
+ elseif typ == "function" then
+ -- ignored: a ...
+ flush(currentcatcodes,"{\\cldl",storefunction(f),"}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ if f then
+ if a ~= nil then
+ local flushlines = parent.__flushlines or flushlines
+ flushlines(a)
+ else
+ flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
+ end
+ else
+ if a ~= nil then
+ -- no command, same as context(a,...)
+ writer(parent,"",a,...)
+ else
+ -- ignored
+ end
+ end
+ elseif typ == "thread" then
+ report_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(f) then -- slow
+ -- writenode(f)
+ flush(currentcatcodes,"\\cldl",storenode(f)," ")
else
- flush(currentcatcodes,f)
+ report_context("error: %a gets a weird argument %a","context",f)
end
- elseif typ == "function" then
- -- ignored: a ...
- flush(currentcatcodes,"{\\cldf{",_store_f_(f),"}}") -- todo: ctx|prt|texcatcodes
- elseif typ == "boolean" then
- if f then
- if a ~= nil then
+ end
+ end
+
+ function context.flushnode(n)
+ flush(currentcatcodes,"\\cldl",storenode(n)," ")
+ end
+
+else
+
+ caller = function(parent,f,a,...)
+ if not parent then
+ -- so we don't need to test in the calling (slower but often no issue)
+ elseif f ~= nil then
+ local typ = type(f)
+ if typ == "string" then
+ if f == "" then
+ -- new, can save a bit sometimes
+ -- if trace_context then
+ -- report_context("empty argument to context()")
+ -- end
+ elseif a then
+ flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
+ -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes
+ elseif processlines and lpegmatch(containseol,f) then
local flushlines = parent.__flushlines or flushlines
- flushlines(a)
+ flushlines(f)
else
- flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
+ flush(contentcatcodes,f)
end
- else
- if a ~= nil then
- -- no command, same as context(a,...)
- writer(parent,"",a,...)
+ elseif typ == "number" then
+ if a then
+ flush(currentcatcodes,f,a,...)
+ else
+ flush(currentcatcodes,f)
+ end
+ elseif typ == "function" then
+ -- ignored: a ...
+ flush(currentcatcodes,"{\\cldf{",storefunction(f),"}}") -- todo: ctx|prt|texcatcodes
+ elseif typ == "boolean" then
+ if f then
+ if a ~= nil then
+ local flushlines = parent.__flushlines or flushlines
+ flushlines(a)
+ else
+ flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
+ end
else
- -- ignored
+ if a ~= nil then
+ -- no command, same as context(a,...)
+ writer(parent,"",a,...)
+ else
+ -- ignored
+ end
end
+ elseif typ == "thread" then
+ report_context("coroutines not supported as we cannot yield across boundaries")
+ elseif isnode(f) then -- slow
+ -- writenode(f)
+ flush(currentcatcodes,"\\cldn{",storenode(f),"}")
+ else
+ report_context("error: %a gets a weird argument %a","context",f)
end
- elseif typ == "thread" then
- report_context("coroutines not supported as we cannot yield across boundaries")
- elseif isnode(f) then -- slow
- -- writenode(f)
- flush(currentcatcodes,"\\cldn{",_store_n_(f),"}")
- else
- report_context("error: %a gets a weird argument %a","context",f)
end
end
+
+ function context.flushnode(n)
+ flush(currentcatcodes,"\\cldn{",storenode(n),"}")
+ end
+
end
local defaultcaller = caller
@@ -642,8 +1009,12 @@ local visualizer = lpeg.replacer {
}
statistics.register("traced context", function()
+ local used, freed = usedstack()
+ local unreachable = used - freed
if nofwriters > 0 or nofflushes > 0 then
- return format("writers: %s, flushes: %s, maxstack: %s",nofwriters,nofflushes,_n_f_)
+ return format("writers: %s, flushes: %s, maxstack: %s",nofwriters,nofflushes,used,freed,unreachable)
+ elseif showstackusage or unreachable > 0 then
+ return format("maxstack: %s, freed: %s, unreachable: %s",used,freed,unreachable)
end
end)
@@ -1019,7 +1390,8 @@ local function caller(parent,f,a,...)
end
elseif typ == "function" then
-- ignored: a ...
- flush(currentcatcodes,mpdrawing,"{\\cldf{",store_(f),"}}")
+-- flush(currentcatcodes,mpdrawing,"{\\cldf{",store_(f),"}}")
+ flush(currentcatcodes,mpdrawing,"{\\cldl",store_(f),"}")
elseif typ == "boolean" then
-- ignored: a ...
if f then
diff --git a/tex/context/base/cldf-ini.mkiv b/tex/context/base/cldf-ini.mkiv
index 258409d7a..12ada1383 100644
--- a/tex/context/base/cldf-ini.mkiv
+++ b/tex/context/base/cldf-ini.mkiv
@@ -36,6 +36,15 @@
\def\cldf#1{\directlua{_cldf_(#1)}} % global (functions)
\def\cldn#1{\directlua{_cldn_(#1)}} % global (nodes)
+\ifx\luafunction\undefined
+ \def\luafunction#1{\directlua{_cldl_(#1)}}
+\fi
+
+\let\cldl\luafunction
+
+% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode1=\activecatcode \global\let^^A=\cldf
+% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode2=\activecatcode \global\let^^B=\cldn
+
\normalprotected\def\cldprocessfile#1{\directlua{context.runfile("#1")}}
\def\cldloadfile #1{\directlua{context.loadfile("#1")}}
\def\cldcontext #1{\directlua{context(#1)}}
diff --git a/tex/context/base/cldf-ver.lua b/tex/context/base/cldf-ver.lua
index b48fd253a..66432eb1c 100644
--- a/tex/context/base/cldf-ver.lua
+++ b/tex/context/base/cldf-ver.lua
@@ -56,16 +56,18 @@ function context.tocontext(first,...)
end
end
-function context.tobuffer(name,str)
- context.startbuffer { name }
- context.pushcatcodes("verbatim")
- local lines = (type(str) == "string" and find(str,"[\n\r]") and splitlines(str)) or str
- for i=1,#lines do
- context(lines[i] .. " ")
- end
- context.stopbuffer()
- context.popcatcodes()
-end
+-- function context.tobuffer(name,str)
+-- context.startbuffer { name }
+-- context.pushcatcodes("verbatim")
+-- local lines = (type(str) == "string" and find(str,"[\n\r]") and splitlines(str)) or str
+-- for i=1,#lines do
+-- context(lines[i] .. " ")
+-- end
+-- context.stopbuffer()
+-- context.popcatcodes()
+-- end
+
+context.tobuffer = buffers.assign -- (name,str,catcodes)
function context.tolines(str)
local lines = type(str) == "string" and splitlines(str) or str
diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua
index 535ee71b8..94e9e6615 100644
--- a/tex/context/base/colo-ini.lua
+++ b/tex/context/base/colo-ini.lua
@@ -65,24 +65,37 @@ function colors.setlist(name)
return table.sortedkeys(name and name ~= "" and colorsets[name] or colorsets.default or {})
end
+local context_colordefagc = context.colordefagc
+local context_colordefagt = context.colordefagt
+local context_colordefalc = context.colordefalc
+local context_colordefalt = context.colordefalt
+local context_colordeffgc = context.colordeffgc
+local context_colordeffgt = context.colordeffgt
+local context_colordefflc = context.colordefflc
+local context_colordefflt = context.colordefflt
+local context_colordefrgc = context.colordefrgc
+local context_colordefrgt = context.colordefrgt
+local context_colordefrlc = context.colordefrlc
+local context_colordefrlt = context.colordefrlt
+
local function definecolor(name, ca, global)
if ca and ca > 0 then
if global then
if trace_define then
report_colors("define global color %a with attribute %a",name,ca)
end
- context.colordefagc(name,ca)
+ context_colordefagc(name,ca)
else
if trace_define then
report_colors("define local color %a with attribute %a",name,ca)
end
- context.colordefalc(name,ca)
+ context_colordefalc(name,ca)
end
else
if global then
- context.colordefrgc(name)
+ context_colordefrgc(name)
else
- context.colordefrlc(name)
+ context_colordefrlc(name)
end
end
colorset[name] = true-- maybe we can store more
@@ -94,18 +107,18 @@ local function inheritcolor(name, ca, global)
if trace_define then
report_colors("inherit global color %a with attribute %a",name,ca)
end
- context.colordeffgc(name,ca) -- some day we will set the macro directly
+ context_colordeffgc(name,ca) -- some day we will set the macro directly
else
if trace_define then
report_colors("inherit local color %a with attribute %a",name,ca)
end
- context.colordefflc(name,ca)
+ context_colordefflc(name,ca)
end
else
if global then
- context.colordefrgc(name)
+ context_colordefrgc(name)
else
- context.colordefrlc(name)
+ context_colordefrlc(name)
end
end
colorset[name] = true-- maybe we can store more
@@ -117,18 +130,18 @@ local function definetransparent(name, ta, global)
if trace_define then
report_colors("define global transparency %a with attribute %a",name,ta)
end
- context.colordefagt(name,ta)
+ context_colordefagt(name,ta)
else
if trace_define then
report_colors("define local transparency %a with attribute %a",name,ta)
end
- context.colordefalt(name,ta)
+ context_colordefalt(name,ta)
end
else
if global then
- context.colordefrgt(name)
+ context_colordefrgt(name)
else
- context.colordefrlt(name)
+ context_colordefrlt(name)
end
end
end
@@ -139,18 +152,18 @@ local function inherittransparent(name, ta, global)
if trace_define then
report_colors("inherit global transparency %a with attribute %a",name,ta)
end
- context.colordeffgt(name,ta)
+ context_colordeffgt(name,ta)
else
if trace_define then
report_colors("inherit local transparency %a with attribute %a",name,ta)
end
- context.colordefflt(name,ta)
+ context_colordefflt(name,ta)
end
else
if global then
- context.colordefrgt(name)
+ context_colordefrgt(name)
else
- context.colordefrlt(name)
+ context_colordefrlt(name)
end
end
end
@@ -382,7 +395,7 @@ function colors.isblack(ca) -- maybe commands
end
function colors.definespotcolor(name,parent,str,global)
- if parent == "" or find(parent,"=") then
+ if parent == "" or find(parent,"=",1,true) then
colors.registerspotcolor(name, parent)
elseif name ~= parent then
local cp = attributes_list[a_color][parent]
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 733afc6d0..d764ff352 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2014.02.14 17:07}
+\newcontextversion{2014.03.22 15:31}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index 275625528..4263371c0 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 8c67fbd50..d5a722525 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -28,7 +28,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2014.02.14 17:07}
+\edef\contextversion{2014.03.22 15:31}
\edef\contextkind {beta}
%D For those who want to use this:
@@ -234,7 +234,7 @@
\loadmarkfile{strc-xml}
\loadmarkfile{strc-def} % might happen later
\loadmkvifile{strc-ref}
-\loadmarkfile{strc-reg}
+%loadmarkfile{strc-reg}
\loadmkvifile{strc-lev} % experiment
\loadmarkfile{spac-ali}
@@ -296,6 +296,8 @@
\loadmarkfile{pack-pos}
\loadmkvifile{page-mak}
+\loadmarkfile{strc-reg} % uses mixed columns
+
\loadmarkfile{page-lin}
\loadmarkfile{page-par}
\loadmarkfile{typo-pag}
diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua
index dad24a7d4..73ca3e304 100644
--- a/tex/context/base/core-con.lua
+++ b/tex/context/base/core-con.lua
@@ -14,14 +14,13 @@ slower but look nicer this way.</p>
<p>Some code may move to a module in the language namespace.</p>
--ldx]]--
-local command, context = commands, context
-
local floor, date, time, concat = math.floor, os.date, os.time, table.concat
local lower, rep, match = string.lower, string.rep, string.match
local utfchar, utfbyte = utf.char, utf.byte
local tonumber, tostring = tonumber, tostring
local context = context
+local commands = commands
local settings_to_array = utilities.parsers.settings_to_array
local allocate = utilities.storage.allocate
@@ -37,9 +36,8 @@ local languages = languages
converters.number = tonumber
converters.numbers = tonumber
-function commands.number(n) context(n) end
-
-commands.numbers = commands.number
+commands.number = context
+commands.numbers = context
-- to be reconsidered ... languages namespace here, might become local plus a register command
diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv
index 1c92a371c..c7e02444a 100644
--- a/tex/context/base/core-env.mkiv
+++ b/tex/context/base/core-env.mkiv
@@ -273,7 +273,7 @@
\unexpanded\def\startmodeset
{\pushmacro\c_syst_modes_set_done
\setfalse\conditionalfalse
- \doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit}
+ \doifnextoptionalcselse\syst_modes_set_start\syst_modes_set_quit}
\def\syst_modes_set_start[#1]%
{\edef\m_mode_case{#1}%
@@ -293,10 +293,10 @@
\def\syst_modes_set_yes#1%
{\settrue\c_syst_modes_set_done
#1%
- \doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit}
+ \doifnextoptionalcselse\syst_modes_set_start\syst_modes_set_quit}
\def\syst_modes_set_nop#1%
- {\doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit}
+ {\doifnextoptionalcselse\syst_modes_set_start\syst_modes_set_quit}
\def\syst_modes_set_quit#1\stopmodeset
{\popmacro\c_syst_modes_set_done}
@@ -316,7 +316,7 @@
\expanded % will become obsolete
{\def\expandafter\noexpand\csname\e!start\v!setups\endcsname
- {\begingroup\noexpand\doifnextoptionalelse
+ {\begingroup\noexpand\doifnextoptionalcselse
{\noexpand\dostartsetupsA\expandafter\noexpand\csname\e!stop\v!setups\endcsname}
{\noexpand\dostartsetupsB\expandafter\noexpand\csname\e!stop\v!setups\endcsname}}}
@@ -467,11 +467,11 @@
% Is doglobal still relevant? Maybe always global? Or never? Anyway, it will become obsolete.
-\unexpanded\def\startluasetups {\begingroup\doifnextoptionalelse\syst_setups_start_lua_a\syst_setups_start_lua_b}
-\unexpanded\def\startxmlsetups {\begingroup\doifnextoptionalelse\syst_setups_start_xml_a\syst_setups_start_xml_b}
-\unexpanded\def\startrawsetups {\begingroup\doifnextoptionalelse\syst_setups_start_raw_a\syst_setups_start_raw_b}
-\unexpanded\def\startlocalsetups{\begingroup\doifnextoptionalelse\syst_setups_start_loc_a\syst_setups_start_loc_b}
-\unexpanded\def\startsetups {\begingroup\doifnextoptionalelse\syst_setups_start_tex_a\syst_setups_start_tex_b}
+\unexpanded\def\startluasetups {\begingroup\doifnextoptionalcselse\syst_setups_start_lua_a\syst_setups_start_lua_b}
+\unexpanded\def\startxmlsetups {\begingroup\doifnextoptionalcselse\syst_setups_start_xml_a\syst_setups_start_xml_b}
+\unexpanded\def\startrawsetups {\begingroup\doifnextoptionalcselse\syst_setups_start_raw_a\syst_setups_start_raw_b}
+\unexpanded\def\startlocalsetups{\begingroup\doifnextoptionalcselse\syst_setups_start_loc_a\syst_setups_start_loc_b}
+\unexpanded\def\startsetups {\begingroup\doifnextoptionalcselse\syst_setups_start_tex_a\syst_setups_start_tex_b}
\let\stopluasetups \relax
\let\stopxmlsetups \relax
diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua
index 71b80170c..1903ad823 100644
--- a/tex/context/base/core-uti.lua
+++ b/tex/context/base/core-uti.lua
@@ -36,7 +36,7 @@ local report_passes = logs.reporter("job","passes")
job = job or { }
local job = job
-job.version = 1.24
+job.version = 1.25
job.packversion = 1.02
-- some day we will implement loading of other jobs and then we need
@@ -51,7 +51,13 @@ directly access the variable using a <l n='lua'/> call.</p>
local savelist, comment = { }, { }
function job.comment(key,value)
- comment[key] = value
+ if type(key) == "table" then
+ for k, v in next, key do
+ comment[k] = v
+ end
+ else
+ comment[key] = value
+ end
end
job.comment("version",job.version)
@@ -73,8 +79,8 @@ function job.initialize(loadname,savename)
end)
end
-function job.register(collected, tobesaved, initializer, finalizer)
- savelist[#savelist+1] = { collected, tobesaved, initializer, finalizer }
+function job.register(collected, tobesaved, initializer, finalizer, serializer)
+ savelist[#savelist+1] = { collected, tobesaved, initializer, finalizer, serializer }
end
-- as an example we implement variables
@@ -100,7 +106,7 @@ job.register('job.variables.checksums', 'job.variables.checksums', initializer)
local rmethod, rvalue
-local setxvalue = context.setxvalue
+local ctx_setxvalue = context.setxvalue
local function initializer()
tobesaved = jobvariables.tobesaved
@@ -116,7 +122,7 @@ local function initializer()
end
tobesaved.randomseed = rvalue
for cs, value in next, collected do
- setxvalue(cs,value)
+ ctx_setxvalue(cs,value)
end
end
@@ -175,10 +181,12 @@ function job.save(filename) -- we could return a table but it can get pretty lar
f:write("local utilitydata = { }\n\n")
f:write(serialize(comment,"utilitydata.comment",true),"\n\n")
for l=1,#savelist do
- local list = savelist[l]
- local target = format("utilitydata.%s",list[1])
- local data = list[2]
- local finalizer = list[4]
+ -- f:write("do\n\n") -- no solution for the jit limitatione either
+ local list = savelist[l]
+ local target = format("utilitydata.%s",list[1])
+ local data = list[2]
+ local finalizer = list[4]
+ local serializer = list[5]
if type(data) == "string" then
data = utilities.tables.accesstable(data)
end
@@ -189,11 +197,18 @@ function job.save(filename) -- we could return a table but it can get pretty lar
packers.pack(data,jobpacker,true)
end
local definer, name = definetable(target,true,true) -- no first and no last
- f:write(definer,"\n\n",serialize(data,name,true),"\n\n")
+ if serializer then
+ f:write(definer,"\n\n",serializer(data,name,true),"\n\n")
+ else
+ f:write(definer,"\n\n",serialize(data,name,true),"\n\n")
+ end
+ -- f:write("end\n\n")
end
if job.pack then
packers.strip(jobpacker)
+ -- f:write("do\n\n")
f:write(serialize(jobpacker,"utilitydata.job.packed",true),"\n\n")
+ -- f:write("end\n\n")
end
f:write("return utilitydata")
f:close()
@@ -214,8 +229,9 @@ local function load(filename)
return data
end
else
- os.remove(filename) -- probably a bad file
- report_passes("removing stale job data file %a, restart job",filename)
+ os.remove(filename) -- probably a bad file (or luajit overflow as it cannot handle large tables well)
+ report_passes("removing stale job data file %a, restart job, message: %s%s",filename,tostring(data),
+ jit and " (try luatex instead of luajittex)" or "")
os.exit(true) -- trigger second run
end
end
@@ -323,16 +339,19 @@ function statistics.formatruntime(runtime)
if shipped > 0 or pages > 0 then
local persecond = shipped / runtime
if pages == 0 then pages = shipped end
-if jit then
-local saved = watts_per_core * runtime * kg_per_watt_per_second / speedup_by_other_engine
-local saved = used_wood_factor * runtime
--- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f kg tree saved by using luajittex",runtime,pages,shipped,persecond,saved)
- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f mg tree saved by using luajittex",runtime,pages,shipped,persecond,saved*1000*1000)
-else
- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond)
-end
+ -- if jit then
+ -- local saved = watts_per_core * runtime * kg_per_watt_per_second / speedup_by_other_engine
+ -- local saved = used_wood_factor * runtime
+ -- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f mg tree saved by using luajittex",runtime,pages,shipped,persecond,saved*1000*1000)
+ -- else
+ return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond)
+ -- end
else
return format("%s seconds",runtime)
end
end
end
+
+
+commands.savevariable = job.variables.save
+commands.setjobcomment = job.comment
diff --git a/tex/context/base/core-uti.mkiv b/tex/context/base/core-uti.mkiv
index 527b90445..5937240b9 100644
--- a/tex/context/base/core-uti.mkiv
+++ b/tex/context/base/core-uti.mkiv
@@ -18,21 +18,19 @@
\registerctxluafile{core-uti}{1.001}
\def\savecurrentvalue#1#2% immediate, so not \unexpanded
- {\ctxlua{job.variables.save("\strippedcsname#1","#2")}}
+ {\ctxcommand{savevariable("\strippedcsname#1","#2")}}
\appendtoks
- \ctxlua {
- % job.comment("file","\jobname")
- job.comment("file",tex.jobname)
- job.comment("format","\contextformat")
- job.comment("stamp","\contextversion")
- job.comment("escape","\!!bs\space...\space\!!es")
- }%
+ \ctxlua{job.comment{
+ file = tex.jobname,
+ format = "\contextformat",
+ stamp = "\contextversion",
+ escape = "\!!bs\space...\space\!!es"
+ }}%
\to \everystarttext
\appendtoks
\ctxlua {
- % job.initialize("\jobname.tuc","\jobname.tua")
job.initialize(tex.jobname .. ".tuc",tex.jobname .. ".tua")
}%
\to \everyjob
diff --git a/tex/context/base/data-exp.lua b/tex/context/base/data-exp.lua
index c67e97bb1..9534e73a0 100644
--- a/tex/context/base/data-exp.lua
+++ b/tex/context/base/data-exp.lua
@@ -123,7 +123,7 @@ local function splitpathexpr(str, newlist, validate) -- I couldn't resist lpeggi
local old = str
str = lpegmatch(l_rest, str)
until old == str
- until old == str -- or not find(str,"{")
+ until old == str -- or not find(str,"{",1,true)
str = lpegmatch(stripper_1,str)
if validate then
for s in gmatch(str,"[^,]+") do
@@ -191,7 +191,7 @@ function resolvers.cleanpath(str) -- tricky, maybe only simple paths
report_expansions("no home dir set, ignoring dependent paths")
end
function resolvers.cleanpath(str)
- if not str or find(str,"~") then
+ if not str or find(str,"~",1,true) then
return "" -- special case
else
return lpegmatch(cleanup,str)
diff --git a/tex/context/base/data-ini.lua b/tex/context/base/data-ini.lua
index 201c6a2d7..bbd233ae7 100644
--- a/tex/context/base/data-ini.lua
+++ b/tex/context/base/data-ini.lua
@@ -217,7 +217,7 @@ end
environment.texroot = file.collapsepath(texroot)
-if profiler then
+if type(profiler) == "table" and not jit then
directives.register("system.profile",function()
profiler.start("luatex-profile.log")
end)
diff --git a/tex/context/base/data-met.lua b/tex/context/base/data-met.lua
index ee9de3fd9..67b9eb22b 100644
--- a/tex/context/base/data-met.lua
+++ b/tex/context/base/data-met.lua
@@ -38,7 +38,7 @@ local function splitmethod(filename) -- todo: filetype in specification
-- filename = gsub(filename,"^%./",getcurrentdir().."/") -- we will merge dir.expandname and collapse some day
- if not find(filename,"://") then
+ if not find(filename,"://",1,true) then
return { scheme = "file", path = filename, original = filename, filename = filename }
end
local specification = url.hashed(filename)
diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua
index 64c38f82c..8e2a4978a 100644
--- a/tex/context/base/data-res.lua
+++ b/tex/context/base/data-res.lua
@@ -359,7 +359,7 @@ local function identify_configuration_files()
-- todo: environment.skipweirdcnfpaths directive
if trace_locating then
local fullpath = gsub(resolvers.resolve(collapsepath(filepath)),"//","/")
- local weirdpath = find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c")
+ local weirdpath = find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
report_resolving("looking for %a on %s path %a from specification %a",luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
end
if lfs.isfile(realname) then
@@ -1027,7 +1027,7 @@ local function find_direct(filename,allresults)
end
local function find_wildcard(filename,allresults)
- if find(filename,'%*') then
+ if find(filename,'*',1,true) then
if trace_locating then
report_resolving("checking wildcard %a", filename)
end
@@ -1204,7 +1204,7 @@ local function find_intree(filename,filetype,wantedfiles,allresults)
local scheme = url.hasscheme(pathname)
if not scheme or scheme == "file" then
local pname = gsub(pathname,"%.%*$",'')
- if not find(pname,"%*") then
+ if not find(pname,"*",1,true) then
if can_be_dir(pname) then
-- quick root scan first
for k=1,#wantedfiles do
@@ -1510,7 +1510,7 @@ local function findwildcardfiles(filename,allresults,result) -- todo: remap: and
local path = lower(lpegmatch(makewildcard,dirn) or dirn)
local name = lower(lpegmatch(makewildcard,base) or base)
local files, done = instance.files, false
- if find(name,"%*") then
+ if find(name,"*",1,true) then
local hashes = instance.hashes
for k=1,#hashes do
local hash = hashes[k]
diff --git a/tex/context/base/file-ini.lua b/tex/context/base/file-ini.lua
index 2bc742a1f..3314bb33d 100644
--- a/tex/context/base/file-ini.lua
+++ b/tex/context/base/file-ini.lua
@@ -11,27 +11,29 @@ if not modules then modules = { } end modules ['file-ini'] = {
<l n='tex'/>. These methods have counterparts at the <l n='tex'/> end.</p>
--ldx]]--
-resolvers.jobs = resolvers.jobs or { }
+resolvers.jobs = resolvers.jobs or { }
-local texsetcount = tex.setcount
-local setvalue = context.setvalue
+local texsetcount = tex.setcount
+
+local context_setvalue = context.setvalue
+local commands_doifelse = commands.doifelse
function commands.splitfilename(fullname)
local t = file.nametotable(fullname)
local path = t.path
texsetcount("splitoffkind",(path == "" and 0) or (path == '.' and 1) or 2)
- setvalue("splitofffull",fullname)
- setvalue("splitoffpath",path)
- setvalue("splitoffname",t.name)
- setvalue("splitoffbase",t.base)
- setvalue("splitofftype",t.suffix)
+ context_setvalue("splitofffull",fullname)
+ context_setvalue("splitoffpath",path)
+ context_setvalue("splitoffname",t.name)
+ context_setvalue("splitoffbase",t.base)
+ context_setvalue("splitofftype",t.suffix)
end
function commands.doifparentfileelse(n)
- commands.doifelse(n == environment.jobname or n == environment.jobname .. '.tex' or n == environment.outputfilename)
+ commands_doifelse(n == environment.jobname or n == environment.jobname .. '.tex' or n == environment.outputfilename)
end
function commands.doiffileexistelse(name)
local foundname = resolvers.findtexfile(name)
- commands.doifelse(foundname and foundname ~= "")
+ commands_doifelse(foundname and foundname ~= "")
end
diff --git a/tex/context/base/file-job.mkvi b/tex/context/base/file-job.mkvi
index fa395a32e..5f646ed28 100644
--- a/tex/context/base/file-job.mkvi
+++ b/tex/context/base/file-job.mkvi
@@ -129,20 +129,20 @@
\unexpanded\def\processfileonce#name{\ctxcommand{processfileonce("#name")}}
\unexpanded\def\processfilenone#name{\ctxcommand{processfilenone("#name")}}
-\unexpanded\def\project {\doifnextoptionalelse\useproject \syst_structure_arg_project}
-\unexpanded\def\product {\doifnextoptionalelse\useproduct \syst_structure_arg_product}
-\unexpanded\def\component {\doifnextoptionalelse\usecomponent \syst_structure_arg_component}
-\unexpanded\def\environment{\doifnextoptionalelse\useenvironment\syst_structure_arg_environment}
+\unexpanded\def\project {\doifnextoptionalcselse\useproject \syst_structure_arg_project}
+\unexpanded\def\product {\doifnextoptionalcselse\useproduct \syst_structure_arg_product}
+\unexpanded\def\component {\doifnextoptionalcselse\usecomponent \syst_structure_arg_component}
+\unexpanded\def\environment{\doifnextoptionalcselse\useenvironment\syst_structure_arg_environment}
\def\syst_structure_arg_project #name {\ctxcommand{useproject ("#name")}}
\def\syst_structure_arg_product #name {\ctxcommand{useproduct ("#name")}}
\def\syst_structure_arg_component #name {\ctxcommand{usecomponent ("#name")}}
\def\syst_structure_arg_environment#name {\ctxcommand{useenvironment("#name")}}
-\unexpanded\def\startproject {\doifnextoptionalelse\syst_structure_start_opt_project \syst_structure_start_arg_project }
-\unexpanded\def\startproduct {\doifnextoptionalelse\syst_structure_start_opt_product \syst_structure_start_arg_product }
-\unexpanded\def\startcomponent {\doifnextoptionalelse\syst_structure_start_opt_component \syst_structure_start_arg_component }
-\unexpanded\def\startenvironment{\doifnextoptionalelse\syst_structure_start_opt_environment\syst_structure_start_arg_environment}
+\unexpanded\def\startproject {\doifnextoptionalcselse\syst_structure_start_opt_project \syst_structure_start_arg_project }
+\unexpanded\def\startproduct {\doifnextoptionalcselse\syst_structure_start_opt_product \syst_structure_start_arg_product }
+\unexpanded\def\startcomponent {\doifnextoptionalcselse\syst_structure_start_opt_component \syst_structure_start_arg_component }
+\unexpanded\def\startenvironment{\doifnextoptionalcselse\syst_structure_start_opt_environment\syst_structure_start_arg_environment}
\def\syst_structure_start_arg_project #name {\ctxcommand{startproject ("#name")}}
\def\syst_structure_start_arg_product #name {\ctxcommand{startproduct ("#name")}}
@@ -216,7 +216,7 @@
% {\letvalue{\e!stop\v!localenvironment}\relax}
% {\grabuntil{\e!stop\v!localenvironment}\gobbleoneargument}}
%
-% \setvalue{\v!localenvironment}{\doifnextoptionalelse\uselocalenvironment\redolocalenvironment}
+% \setvalue{\v!localenvironment}{\doifnextoptionalcselse\uselocalenvironment\redolocalenvironment}
%
% \def\redolocalenvironment#1 {\uselocalenvironment[#1]}
% \def\uselocalenvironment[#1]{\doexecutefileonce{#1}}
diff --git a/tex/context/base/file-mod.mkvi b/tex/context/base/file-mod.mkvi
index 00966a442..1591a69cc 100644
--- a/tex/context/base/file-mod.mkvi
+++ b/tex/context/base/file-mod.mkvi
@@ -107,7 +107,7 @@
\newtoks\everysetupmodule
\unexpanded\def\startmodule
- {\doifnextoptionalelse\syst_modules_start_yes\syst_modules_start_nop}
+ {\doifnextoptionalcselse\syst_modules_start_yes\syst_modules_start_nop}
\def\syst_modules_start_yes[#name]%
{\pushmacro\currentmodule
diff --git a/tex/context/base/file-res.lua b/tex/context/base/file-res.lua
index 8a50c0d58..9ae7a6b06 100644
--- a/tex/context/base/file-res.lua
+++ b/tex/context/base/file-res.lua
@@ -136,7 +136,7 @@ function getreadfilename(scheme,path,name) -- better do a split and then pass ta
if hasscheme(name) or is_qualified_path(name) then
fullname = name
else
- if not find(name,"%%") then
+ if not find(name,"%",1,true) then
name = urlescape(name) -- if no % in names
end
fullname = ((path == "") and format("%s:///%s",scheme,name)) or format("%s:///%s/%s",scheme,path,name)
diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua
index 5d4f6059b..178ca71be 100644
--- a/tex/context/base/font-chk.lua
+++ b/tex/context/base/font-chk.lua
@@ -159,7 +159,7 @@ local variants = {
{ tag = "yellow", r = .6, g = .6, b = 0 },
}
-local pdf_blob = "pdf: q %0.6f 0 0 %0.6f 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q"
+local pdf_blob = "pdf: q %0.6F 0 0 %0.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q"
local cache = { } -- saves some tables but not that impressive
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
index e251cc9c1..13b1ac6a8 100644
--- a/tex/context/base/font-ctx.lua
+++ b/tex/context/base/font-ctx.lua
@@ -61,11 +61,12 @@ local nuts = nodes.nuts
local tonut = nuts.tonut
local getfield = nuts.getfield
-local getattr = nuts.getattr
-local getfont = nuts.getfont
-
local setfield = nuts.setfield
+local getattr = nuts.getattr
local setattr = nuts.setattr
+local getprop = nuts.getprop
+local setprop = nuts.setprop
+local getfont = nuts.getfont
local texgetattribute = tex.getattribute
local texsetattribute = tex.setattribute
@@ -137,8 +138,17 @@ function fonts.helpers.name(tfmdata)
return file.basename(type(tfmdata) == "number" and properties[tfmdata].name or tfmdata.properties.name)
end
-utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = fonts.helpers.name })
-utilities.strings.formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]], { sequenced = table.sequenced })
+if _LUAVERSION < 5.2 then
+
+ utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], "local fontname = fonts.helpers.name")
+ utilities.strings.formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],"local sequenced = table.sequenced")
+
+else
+
+ utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = fonts.helpers.name })
+ utilities.strings.formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],{ sequenced = table.sequenced })
+
+end
-- ... like font-sfm or so
@@ -155,47 +165,49 @@ local hashes = { }
function constructors.trytosharefont(target,tfmdata)
constructors.noffontsloaded = constructors.noffontsloaded + 1
if constructors.sharefonts then
- local properties = target.properties
- local fullname = target.fullname
local fonthash = target.specification.hash
- local sharedname = hashes[fonthash]
- if sharedname then
- -- this is ok for context as we know that only features can mess with font definitions
- -- so a similar hash means that the fonts are similar too
- if trace_defining then
- report_defining("font %a uses backend resources of font %a (%s)",target.fullname,sharedname,"common hash")
- end
- target.fullname = sharedname
- properties.sharedwith = sharedname
- constructors.nofsharedfonts = constructors.nofsharedfonts + 1
- constructors.nofsharedhashes = constructors.nofsharedhashes + 1
- else
- -- the one takes more time (in the worst case of many cjk fonts) but it also saves
- -- embedding time
- local characters = target.characters
- local n = 1
- local t = { target.psname }
- local u = sortedkeys(characters)
- for i=1,#u do
- n = n + 1 ; t[n] = k
- n = n + 1 ; t[n] = characters[u[i]].index or k
- end
- local checksum = md5.HEX(concat(t," "))
- local sharedname = shares[checksum]
+ if fonthash then
+ local properties = target.properties
local fullname = target.fullname
+ local sharedname = hashes[fonthash]
if sharedname then
+ -- this is ok for context as we know that only features can mess with font definitions
+ -- so a similar hash means that the fonts are similar too
if trace_defining then
- report_defining("font %a uses backend resources of font %a (%s)",fullname,sharedname,"common vector")
+ report_defining("font %a uses backend resources of font %a (%s)",target.fullname,sharedname,"common hash")
end
- fullname = sharedname
- properties.sharedwith= sharedname
+ target.fullname = sharedname
+ properties.sharedwith = sharedname
constructors.nofsharedfonts = constructors.nofsharedfonts + 1
- constructors.nofsharedvectors = constructors.nofsharedvectors + 1
+ constructors.nofsharedhashes = constructors.nofsharedhashes + 1
else
- shares[checksum] = fullname
+ -- the one takes more time (in the worst case of many cjk fonts) but it also saves
+ -- embedding time
+ local characters = target.characters
+ local n = 1
+ local t = { target.psname }
+ local u = sortedkeys(characters)
+ for i=1,#u do
+ n = n + 1 ; t[n] = k
+ n = n + 1 ; t[n] = characters[u[i]].index or k
+ end
+ local checksum = md5.HEX(concat(t," "))
+ local sharedname = shares[checksum]
+ local fullname = target.fullname
+ if sharedname then
+ if trace_defining then
+ report_defining("font %a uses backend resources of font %a (%s)",fullname,sharedname,"common vector")
+ end
+ fullname = sharedname
+ properties.sharedwith= sharedname
+ constructors.nofsharedfonts = constructors.nofsharedfonts + 1
+ constructors.nofsharedvectors = constructors.nofsharedvectors + 1
+ else
+ shares[checksum] = fullname
+ end
+ target.fullname = fullname
+ hashes[fonthash] = fullname
end
- target.fullname = fullname
- hashes[fonthash] = fullname
end
end
end
@@ -493,7 +505,7 @@ local function definecontext(name,t) -- can be shared
end
local function presetcontext(name,parent,features) -- will go to con and shared
- if features == "" and find(parent,"=") then
+ if features == "" and find(parent,"=",1,true) then
features = parent
parent = ""
end
@@ -810,7 +822,7 @@ local function splitcontext(features) -- presetcontext creates dummy here
local sf = setups[features]
if not sf then
local n -- number
- if find(features,",") then
+ if find(features,",",a,true) then
-- let's assume a combination which is not yet defined but just specified (as in math)
n, sf = presetcontext(features,features,"")
else
@@ -827,13 +839,13 @@ end
-- local setup = setups[features]
-- if setup then
-- return setup
--- elseif find(features,",") then
+-- elseif find(features,",",1,true) then
-- -- This is not that efficient but handy anyway for quick and dirty tests
-- -- beware, due to the way of caching setups you can get the wrong results
-- -- when components change. A safeguard is to nil the cache.
-- local merge = nil
-- for feature in gmatch(features,"[^, ]+") do
--- if find(feature,"=") then
+-- if find(feature,"=",1,true) then
-- local k, v = lpegmatch(splitter,feature)
-- if k and v then
-- if not merge then
@@ -941,319 +953,327 @@ local getspecification = definers.getspecification
-- we can make helper macros which saves parsing (but normaly not
-- that many calls, e.g. in mk a couple of 100 and in metafun 3500)
-local setdefaultfontname = context.fntsetdefname
-local setsomefontname = context.fntsetsomename
-local setemptyfontsize = context.fntsetnopsize
-local setsomefontsize = context.fntsetsomesize
-local letvaluerelax = context.letvaluerelax
-
-function commands.definefont_one(str)
- statistics.starttiming(fonts)
- if trace_defining then
- report_defining("memory usage before: %s",statistics.memused())
- report_defining("start stage one: %s",str)
- end
- local fullname, size = lpegmatch(splitpattern,str)
- local lookup, name, sub, method, detail = getspecification(fullname)
- if not name then
- report_defining("strange definition %a",str)
- setdefaultfontname()
- elseif name == "unknown" then
- setdefaultfontname()
- else
- setsomefontname(name)
- end
- -- we can also use a count for the size
- if size and size ~= "" then
- local mode, size = lpegmatch(sizepattern,size)
- if size and mode then
- texsetcount("scaledfontmode",mode)
- setsomefontsize(size)
+do -- else too many locals
+
+ local ctx_setdefaultfontname = context.fntsetdefname
+ local ctx_setsomefontname = context.fntsetsomename
+ local ctx_setemptyfontsize = context.fntsetnopsize
+ local ctx_setsomefontsize = context.fntsetsomesize
+ local ctx_letvaluerelax = context.letvaluerelax
+
+ function commands.definefont_one(str)
+ statistics.starttiming(fonts)
+ if trace_defining then
+ report_defining("memory usage before: %s",statistics.memused())
+ report_defining("start stage one: %s",str)
+ end
+ local fullname, size = lpegmatch(splitpattern,str)
+ local lookup, name, sub, method, detail = getspecification(fullname)
+ if not name then
+ report_defining("strange definition %a",str)
+ ctx_setdefaultfontname()
+ elseif name == "unknown" then
+ ctx_setdefaultfontname()
+ else
+ ctx_setsomefontname(name)
+ end
+ -- we can also use a count for the size
+ if size and size ~= "" then
+ local mode, size = lpegmatch(sizepattern,size)
+ if size and mode then
+ texsetcount("scaledfontmode",mode)
+ ctx_setsomefontsize(size)
+ else
+ texsetcount("scaledfontmode",0)
+ ctx_setemptyfontsize()
+ end
+ elseif true then
+ -- so we don't need to check in tex
+ texsetcount("scaledfontmode",2)
+ ctx_setemptyfontsize()
else
texsetcount("scaledfontmode",0)
- setemptyfontsize()
+ ctx_setemptyfontsize()
+ end
+ specification = definers.makespecification(str,lookup,name,sub,method,detail,size)
+ if trace_defining then
+ report_defining("stop stage one")
end
- elseif true then
- -- so we don't need to check in tex
- texsetcount("scaledfontmode",2)
- setemptyfontsize()
- else
- texsetcount("scaledfontmode",0)
- setemptyfontsize()
- end
- specification = definers.makespecification(str,lookup,name,sub,method,detail,size)
- if trace_defining then
- report_defining("stop stage one")
end
-end
-local n = 0
-
--- we can also move rscale to here (more consistent)
--- the argument list will become a table
+ local n = 0
-local function nice_cs(cs)
- return (gsub(cs,".->", ""))
-end
+ -- we can also move rscale to here (more consistent)
+ -- the argument list will become a table
-function commands.definefont_two(global,cs,str,size,inheritancemode,classfeatures,fontfeatures,classfallbacks,fontfallbacks,
- mathsize,textsize,relativeid,classgoodies,goodies,classdesignsize,fontdesignsize,scaledfontmode)
- if trace_defining then
- report_defining("start stage two: %s (size %s)",str,size)
- end
- -- name is now resolved and size is scaled cf sa/mo
- local lookup, name, sub, method, detail = getspecification(str or "")
- -- new (todo: inheritancemode)
- local designsize = fontdesignsize ~= "" and fontdesignsize or classdesignsize or ""
- local designname = designsizefilename(name,designsize,size)
- if designname and designname ~= "" then
- if trace_defining or trace_designsize then
- report_defining("remapping name %a, specification %a, size %a, designsize %a",name,designsize,size,designname)
- end
- -- we don't catch detail here
- local o_lookup, o_name, o_sub, o_method, o_detail = getspecification(designname)
- if o_lookup and o_lookup ~= "" then lookup = o_lookup end
- if o_method and o_method ~= "" then method = o_method end
- if o_detail and o_detail ~= "" then detail = o_detail end
- name = o_name
- sub = o_sub
- end
- -- so far
- -- some settings can have been overloaded
- if lookup and lookup ~= "" then
- specification.lookup = lookup
- end
- if relativeid and relativeid ~= "" then -- experimental hook
- local id = tonumber(relativeid) or 0
- specification.relativeid = id > 0 and id
+ local function nice_cs(cs)
+ return (gsub(cs,".->", ""))
end
- --
- specification.name = name
- specification.size = size
- specification.sub = (sub and sub ~= "" and sub) or specification.sub
- specification.mathsize = mathsize
- specification.textsize = textsize
- specification.goodies = goodies
- specification.cs = cs
- specification.global = global
- specification.scalemode = scaledfontmode -- context specific
- if detail and detail ~= "" then
- specification.method = method or "*"
- specification.detail = detail
- elseif specification.detail and specification.detail ~= "" then
- -- already set
- elseif inheritancemode == 0 then
- -- nothing
- elseif inheritancemode == 1 then
- -- fontonly
- if fontfeatures and fontfeatures ~= "" then
- specification.method = "*"
- specification.detail = fontfeatures
- end
- if fontfallbacks and fontfallbacks ~= "" then
- specification.fallbacks = fontfallbacks
- end
- elseif inheritancemode == 2 then
- -- classonly
- if classfeatures and classfeatures ~= "" then
- specification.method = "*"
- specification.detail = classfeatures
- end
- if classfallbacks and classfallbacks ~= "" then
- specification.fallbacks = classfallbacks
- end
- elseif inheritancemode == 3 then
- -- fontfirst
- if fontfeatures and fontfeatures ~= "" then
- specification.method = "*"
- specification.detail = fontfeatures
- elseif classfeatures and classfeatures ~= "" then
- specification.method = "*"
- specification.detail = classfeatures
- end
- if fontfallbacks and fontfallbacks ~= "" then
- specification.fallbacks = fontfallbacks
- elseif classfallbacks and classfallbacks ~= "" then
- specification.fallbacks = classfallbacks
- end
- elseif inheritancemode == 4 then
- -- classfirst
- if classfeatures and classfeatures ~= "" then
- specification.method = "*"
- specification.detail = classfeatures
- elseif fontfeatures and fontfeatures ~= "" then
- specification.method = "*"
- specification.detail = fontfeatures
- end
- if classfallbacks and classfallbacks ~= "" then
- specification.fallbacks = classfallbacks
- elseif fontfallbacks and fontfallbacks ~= "" then
- specification.fallbacks = fontfallbacks
- end
- end
- local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?)
- --
- local lastfontid = 0
- if not tfmdata then
- report_defining("unable to define %a as %a",name,nice_cs(cs))
- lastfontid = -1
- letvaluerelax(cs) -- otherwise the current definition takes the previous one
- elseif type(tfmdata) == "number" then
+
+ function commands.definefont_two(global,cs,str,size,inheritancemode,classfeatures,fontfeatures,classfallbacks,fontfallbacks,
+ mathsize,textsize,relativeid,classgoodies,goodies,classdesignsize,fontdesignsize,scaledfontmode)
if trace_defining then
- report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a",
- name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize)
+ report_defining("start stage two: %s (size %s)",str,size)
end
- csnames[tfmdata] = specification.cs
- texdefinefont(global,cs,tfmdata)
- -- resolved (when designsize is used):
- local size = fontdata[tfmdata].parameters.size or 0
- setsomefontsize(size .. "sp")
- texsetcount("scaledfontsize",size)
- lastfontid = tfmdata
- else
- -- setting the extra characters will move elsewhere
- local characters = tfmdata.characters
- local parameters = tfmdata.parameters
- -- we use char0 as signal; cf the spec pdf can handle this (no char in slot)
- characters[0] = nil
- -- characters[0x00A0] = { width = parameters.space }
- -- characters[0x2007] = { width = characters[0x0030] and characters[0x0030].width or parameters.space } -- figure
- -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period
- --
- constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference
- local id = font.define(tfmdata)
- csnames[id] = specification.cs
- tfmdata.properties.id = id
- definers.register(tfmdata,id) -- to be sure, normally already done
- texdefinefont(global,cs,id)
- constructors.cleanuptable(tfmdata)
- constructors.finalize(tfmdata)
- if trace_defining then
- report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a",
- name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks)
+ -- name is now resolved and size is scaled cf sa/mo
+ local lookup, name, sub, method, detail = getspecification(str or "")
+ -- new (todo: inheritancemode)
+ local designsize = fontdesignsize ~= "" and fontdesignsize or classdesignsize or ""
+ local designname = designsizefilename(name,designsize,size)
+ if designname and designname ~= "" then
+ if trace_defining or trace_designsize then
+ report_defining("remapping name %a, specification %a, size %a, designsize %a",name,designsize,size,designname)
+ end
+ -- we don't catch detail here
+ local o_lookup, o_name, o_sub, o_method, o_detail = getspecification(designname)
+ if o_lookup and o_lookup ~= "" then lookup = o_lookup end
+ if o_method and o_method ~= "" then method = o_method end
+ if o_detail and o_detail ~= "" then detail = o_detail end
+ name = o_name
+ sub = o_sub
end
- -- resolved (when designsize is used):
- local size = tfmdata.parameters.size or 655360
- setsomefontsize(size .. "sp")
- texsetcount("scaledfontsize",size)
- lastfontid = id
- end
- if trace_defining then
- report_defining("memory usage after: %s",statistics.memused())
- report_defining("stop stage two")
- end
- --
- texsetcount("global","lastfontid",lastfontid)
- if not mathsize then
- -- forget about it
- elseif mathsize == 0 then
- lastmathids[1] = lastfontid
- else
- lastmathids[mathsize] = lastfontid
- end
- --
- statistics.stoptiming(fonts)
-end
-
-function definers.define(specification)
- --
- local name = specification.name
- if not name or name == "" then
- return -1
- else
- statistics.starttiming(fonts)
- --
- -- following calls expect a few properties to be set:
- --
- local lookup, name, sub, method, detail = getspecification(name or "")
- --
- specification.name = (name ~= "" and name) or specification.name
- --
- specification.lookup = specification.lookup or (lookup ~= "" and lookup) or "file"
- specification.size = specification.size or 655260
- specification.sub = specification.sub or (sub ~= "" and sub) or ""
- specification.method = specification.method or (method ~= "" and method) or "*"
- specification.detail = specification.detail or (detail ~= "" and detail) or ""
- --
- if type(specification.size) == "string" then
- specification.size = texsp(specification.size) or 655260
+ -- so far
+ -- some settings can have been overloaded
+ if lookup and lookup ~= "" then
+ specification.lookup = lookup
+ end
+ if relativeid and relativeid ~= "" then -- experimental hook
+ local id = tonumber(relativeid) or 0
+ specification.relativeid = id > 0 and id
end
--
- specification.specification = "" -- not used
- specification.resolved = ""
- specification.forced = ""
- specification.features = { } -- via detail, maybe some day
- --
- -- we don't care about mathsize textsize goodies fallbacks
- --
- local cs = specification.cs
- if cs == "" then
- cs = nil
- specification.cs = nil
- specification.global = false
- elseif specification.global == nil then
- specification.global = false
+ specification.name = name
+ specification.size = size
+ specification.sub = (sub and sub ~= "" and sub) or specification.sub
+ specification.mathsize = mathsize
+ specification.textsize = textsize
+ specification.goodies = goodies
+ specification.cs = cs
+ specification.global = global
+ specification.scalemode = scaledfontmode -- context specific
+ if detail and detail ~= "" then
+ specification.method = method or "*"
+ specification.detail = detail
+ elseif specification.detail and specification.detail ~= "" then
+ -- already set
+ elseif inheritancemode == 0 then
+ -- nothing
+ elseif inheritancemode == 1 then
+ -- fontonly
+ if fontfeatures and fontfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = fontfeatures
+ end
+ if fontfallbacks and fontfallbacks ~= "" then
+ specification.fallbacks = fontfallbacks
+ end
+ elseif inheritancemode == 2 then
+ -- classonly
+ if classfeatures and classfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = classfeatures
+ end
+ if classfallbacks and classfallbacks ~= "" then
+ specification.fallbacks = classfallbacks
+ end
+ elseif inheritancemode == 3 then
+ -- fontfirst
+ if fontfeatures and fontfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = fontfeatures
+ elseif classfeatures and classfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = classfeatures
+ end
+ if fontfallbacks and fontfallbacks ~= "" then
+ specification.fallbacks = fontfallbacks
+ elseif classfallbacks and classfallbacks ~= "" then
+ specification.fallbacks = classfallbacks
+ end
+ elseif inheritancemode == 4 then
+ -- classfirst
+ if classfeatures and classfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = classfeatures
+ elseif fontfeatures and fontfeatures ~= "" then
+ specification.method = "*"
+ specification.detail = fontfeatures
+ end
+ if classfallbacks and classfallbacks ~= "" then
+ specification.fallbacks = classfallbacks
+ elseif fontfallbacks and fontfallbacks ~= "" then
+ specification.fallbacks = fontfallbacks
+ end
end
+ local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?)
--
- local tfmdata = definers.read(specification,specification.size)
+ local lastfontid = 0
if not tfmdata then
- return -1, nil
+ report_defining("unable to define %a as %a",name,nice_cs(cs))
+ lastfontid = -1
+ ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one
elseif type(tfmdata) == "number" then
- if cs then
- texdefinefont(specification.global,cs,tfmdata)
- csnames[tfmdata] = cs
+ if trace_defining then
+ report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a",
+ name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize)
end
- return tfmdata, fontdata[tfmdata]
+ csnames[tfmdata] = specification.cs
+ texdefinefont(global,cs,tfmdata)
+ -- resolved (when designsize is used):
+ local size = fontdata[tfmdata].parameters.size or 0
+ ctx_setsomefontsize(size .. "sp")
+ texsetcount("scaledfontsize",size)
+ lastfontid = tfmdata
else
+ -- setting the extra characters will move elsewhere
+ local characters = tfmdata.characters
+ local parameters = tfmdata.parameters
+ -- we use char0 as signal; cf the spec pdf can handle this (no char in slot)
+ characters[0] = nil
+ -- characters[0x00A0] = { width = parameters.space }
+ -- characters[0x2007] = { width = characters[0x0030] and characters[0x0030].width or parameters.space } -- figure
+ -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period
+ --
constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference
local id = font.define(tfmdata)
+ csnames[id] = specification.cs
tfmdata.properties.id = id
- definers.register(tfmdata,id)
- if cs then
- texdefinefont(specification.global,cs,id)
- csnames[id] = cs
- end
+ definers.register(tfmdata,id) -- to be sure, normally already done
+ texdefinefont(global,cs,id)
constructors.cleanuptable(tfmdata)
constructors.finalize(tfmdata)
- return id, tfmdata
+ if trace_defining then
+ report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a",
+ name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks)
+ end
+ -- resolved (when designsize is used):
+ local size = tfmdata.parameters.size or 655360
+ ctx_setsomefontsize(size .. "sp")
+ texsetcount("scaledfontsize",size)
+ lastfontid = id
+ end
+ if trace_defining then
+ report_defining("memory usage after: %s",statistics.memused())
+ report_defining("stop stage two")
end
+ --
+ texsetcount("global","lastfontid",lastfontid)
+ if not mathsize then
+ -- forget about it
+ elseif mathsize == 0 then
+ lastmathids[1] = lastfontid
+ else
+ lastmathids[mathsize] = lastfontid
+ end
+ --
statistics.stoptiming(fonts)
end
+
+ function definers.define(specification)
+ --
+ local name = specification.name
+ if not name or name == "" then
+ return -1
+ else
+ statistics.starttiming(fonts)
+ --
+ -- following calls expect a few properties to be set:
+ --
+ local lookup, name, sub, method, detail = getspecification(name or "")
+ --
+ specification.name = (name ~= "" and name) or specification.name
+ --
+ specification.lookup = specification.lookup or (lookup ~= "" and lookup) or "file"
+ specification.size = specification.size or 655260
+ specification.sub = specification.sub or (sub ~= "" and sub) or ""
+ specification.method = specification.method or (method ~= "" and method) or "*"
+ specification.detail = specification.detail or (detail ~= "" and detail) or ""
+ --
+ if type(specification.size) == "string" then
+ specification.size = texsp(specification.size) or 655260
+ end
+ --
+ specification.specification = "" -- not used
+ specification.resolved = ""
+ specification.forced = ""
+ specification.features = { } -- via detail, maybe some day
+ --
+ -- we don't care about mathsize textsize goodies fallbacks
+ --
+ local cs = specification.cs
+ if cs == "" then
+ cs = nil
+ specification.cs = nil
+ specification.global = false
+ elseif specification.global == nil then
+ specification.global = false
+ end
+ --
+ local tfmdata = definers.read(specification,specification.size)
+ if not tfmdata then
+ return -1, nil
+ elseif type(tfmdata) == "number" then
+ if cs then
+ texdefinefont(specification.global,cs,tfmdata)
+ csnames[tfmdata] = cs
+ end
+ return tfmdata, fontdata[tfmdata]
+ else
+ constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference
+ local id = font.define(tfmdata)
+ tfmdata.properties.id = id
+ definers.register(tfmdata,id)
+ if cs then
+ texdefinefont(specification.global,cs,id)
+ csnames[id] = cs
+ end
+ constructors.cleanuptable(tfmdata)
+ constructors.finalize(tfmdata)
+ return id, tfmdata
+ end
+ statistics.stoptiming(fonts)
+ end
+ end
+
end
-- local id, cs = fonts.definers.internal { }
-- local id, cs = fonts.definers.internal { number = 2 }
-- local id, cs = fonts.definers.internal { name = "dejavusans" }
-local n = 0
-
-function definers.internal(specification,cs)
- specification = specification or { }
- local name = specification.name
- local size = specification.size and number.todimen(specification.size) or texgetdimen("bodyfontsize")
- local number = tonumber(specification.number)
- local id = nil
- if number then
- id = number
- elseif name and name ~= "" then
- local cs = cs or specification.cs
- if not cs then
- n = n + 1 -- beware ... there can be many and they are often used once
- -- cs = formatters["internal font %s"](n)
- cs = "internal font " .. n
- else
- specification.cs = cs
+do
+
+ local n = 0
+
+ function definers.internal(specification,cs)
+ specification = specification or { }
+ local name = specification.name
+ local size = specification.size and number.todimen(specification.size) or texgetdimen("bodyfontsize")
+ local number = tonumber(specification.number)
+ local id = nil
+ if number then
+ id = number
+ elseif name and name ~= "" then
+ local cs = cs or specification.cs
+ if not cs then
+ n = n + 1 -- beware ... there can be many and they are often used once
+ -- cs = formatters["internal font %s"](n)
+ cs = "internal font " .. n
+ else
+ specification.cs = cs
+ end
+ id = definers.define {
+ name = name,
+ size = size,
+ cs = cs,
+ }
end
- id = definers.define {
- name = name,
- size = size,
- cs = cs,
- }
- end
- if not id then
- id = currentfont()
+ if not id then
+ id = currentfont()
+ end
+ return id, csnames[id]
end
- return id, csnames[id]
+
end
local enable_auto_r_scale = false
@@ -1519,6 +1539,11 @@ local Shapes = {
mono = "Mono",
}
+local ctx_startfontclass = context.startfontclass
+local ctx_stopfontclass = context.stopfontclass
+local ctx_definefontsynonym = context.definefontsynonym
+local ctx_dofastdefinetypeface = context.dofastdefinetypeface
+
function fonts.definetypeface(name,t)
if type(name) == "table" then
-- {name=abc,k=v,...}
@@ -1546,14 +1571,14 @@ function fonts.definetypeface(name,t)
local normalwidth = t.normalwidth or t.width or p.normalwidth or p.width or "normal"
local boldwidth = t.boldwidth or t.width or p.boldwidth or p.width or "normal"
Shape = Shapes[shape] or "Serif"
- context.startfontclass { name }
- context.definefontsynonym( { format("%s", Shape) }, { format("spec:%s-%s-regular-%s", fontname, normalweight, normalwidth) } )
- context.definefontsynonym( { format("%sBold", Shape) }, { format("spec:%s-%s-regular-%s", fontname, boldweight, boldwidth ) } )
- context.definefontsynonym( { format("%sBoldItalic", Shape) }, { format("spec:%s-%s-italic-%s", fontname, boldweight, boldwidth ) } )
- context.definefontsynonym( { format("%sItalic", Shape) }, { format("spec:%s-%s-italic-%s", fontname, normalweight, normalwidth) } )
- context.stopfontclass()
+ ctx_startfontclass { name }
+ ctx_definefontsynonym( { format("%s", Shape) }, { format("spec:%s-%s-regular-%s", fontname, normalweight, normalwidth) } )
+ ctx_definefontsynonym( { format("%sBold", Shape) }, { format("spec:%s-%s-regular-%s", fontname, boldweight, boldwidth ) } )
+ ctx_definefontsynonym( { format("%sBoldItalic", Shape) }, { format("spec:%s-%s-italic-%s", fontname, boldweight, boldwidth ) } )
+ ctx_definefontsynonym( { format("%sItalic", Shape) }, { format("spec:%s-%s-italic-%s", fontname, normalweight, normalwidth) } )
+ ctx_stopfontclass()
local settings = sequenced({ features= t.features },",")
- context.dofastdefinetypeface(name, shortcut, shape, size, settings)
+ ctx_dofastdefinetypeface(name, shortcut, shape, size, settings)
end
function fonts.current() -- todo: also handle name
@@ -1566,10 +1591,15 @@ end
-- interfaces
+local context_char = context.char
+local context_getvalue = context.getvalue
+
+local commands_doifelse = commands.doifelse
+
function commands.fontchar(n)
n = nametoslot(n)
if n then
- context.char(n)
+ context_char(n)
end
end
@@ -1579,7 +1609,7 @@ function commands.doifelsecurrentfonthasfeature(name) -- can be made faster with
f = f and f.rawdata
f = f and f.resources
f = f and f.features
- commands.doifelse(f and (f.gpos[name] or f.gsub[name]))
+ commands_doifelse(f and (f.gpos[name] or f.gsub[name]))
end
local p, f = 1, formatters["%0.1fpt"] -- normally this value is changed only once
@@ -1751,14 +1781,15 @@ end
-- redefinition
-local quads = hashes.quads
-local xheights = hashes.xheights
+-- local hashes = fonts.hashes
+-- local emwidths = hashes.emwidths
+-- local exheights = hashes.exheights
setmetatableindex(dimenfactors, function(t,k)
if k == "ex" then
- return 1/xheights[currentfont()]
+ return 1/exheights[currentfont()]
elseif k == "em" then
- return 1/quads[currentfont()]
+ return 1/emwidths[currentfont()]
elseif k == "pct" or k == "%" then
return 1/(texget("hsize")/100)
else
@@ -1835,7 +1866,7 @@ end
-- end
function commands.setfontofid(id)
- context.getvalue(csnames[id])
+ context_getvalue(csnames[id])
end
-- more interfacing:
@@ -1911,7 +1942,6 @@ end
-- a fontkern plug:
-
local copy_node = nuts.copy
local kern = nuts.pool.register(nuts.pool.kern())
@@ -1967,7 +1997,7 @@ local function markstates(head)
head = tonut(head)
local model = getattr(head,a_colormodel) or 1
for glyph in traverse_by_id(glyph_code,head) do
- local a = getattr(glyph,a_state)
+ local a = getprop(glyph,a_state)
if a then
local name = names[a]
if name then
@@ -2023,3 +2053,12 @@ function methods.nocolor(head,font,attr)
end
return head, true
end
+
+function commands.purefontname(name)
+ if type(name) == "number" then
+ name = fonts.helpers.name(name)
+ end
+ if type(name) == "string" then
+ context(file.basename(name))
+ end
+end
diff --git a/tex/context/base/font-fea.mkvi b/tex/context/base/font-fea.mkvi
index 8d985b411..35a9a642a 100644
--- a/tex/context/base/font-fea.mkvi
+++ b/tex/context/base/font-fea.mkvi
@@ -143,11 +143,11 @@
% hashing at this end is slower
-\unexpanded\def\addfeature {\doifnextoptionalelse\font_feature_add_yes \font_feature_add_nop }
-\unexpanded\def\subtractfeature {\doifnextoptionalelse\font_feature_subtract_yes \font_feature_subtract_nop }
-\unexpanded\def\replacefeature {\doifnextoptionalelse\font_feature_replace_yes \font_feature_replace_nop }
-\unexpanded\def\resetandaddfeature{\doifnextoptionalelse\font_feature_reset_add_yes\font_feature_reset_add_nop}
-\unexpanded\def\feature {\doifnextoptionalelse\font_feature_yes \font_feature_nop }
+\unexpanded\def\addfeature {\doifnextoptionalcselse\font_feature_add_yes \font_feature_add_nop }
+\unexpanded\def\subtractfeature {\doifnextoptionalcselse\font_feature_subtract_yes \font_feature_subtract_nop }
+\unexpanded\def\replacefeature {\doifnextoptionalcselse\font_feature_replace_yes \font_feature_replace_nop }
+\unexpanded\def\resetandaddfeature{\doifnextoptionalcselse\font_feature_reset_add_yes\font_feature_reset_add_nop}
+\unexpanded\def\feature {\doifnextoptionalcselse\font_feature_yes \font_feature_nop }
\unexpanded\def\font_feature_add_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_add}
\unexpanded\def\font_feature_add_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_add}
diff --git a/tex/context/base/font-fil.mkvi b/tex/context/base/font-fil.mkvi
index dcb298619..158bcda71 100644
--- a/tex/context/base/font-fil.mkvi
+++ b/tex/context/base/font-fil.mkvi
@@ -89,11 +89,11 @@
\def\font_basics_define_font_synonym_nop
{\expandafter\let\csname\??fontfile\m_font_name\endcsname\m_font_file
- \doifnextoptionalelse\font_basics_define_font_synonym_nop_opt\font_basics_define_font_synonym_nop_nil}
+ \doifnextoptionalcselse\font_basics_define_font_synonym_nop_opt\font_basics_define_font_synonym_nop_nil}
\def\font_basics_define_font_synonym_yes
{\expandafter\let\csname\??fontfile\fontclass\m_font_name\endcsname\m_font_file
- \doifnextoptionalelse\font_basics_define_font_synonym_yes_opt\font_basics_define_font_synonym_yes_nil}
+ \doifnextoptionalcselse\font_basics_define_font_synonym_yes_opt\font_basics_define_font_synonym_yes_nil}
\def\font_basics_define_font_synonym_nop_opt[#specification]%
{\let\p_features \undefined
diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua
index e57f784a0..9e7cb841e 100644
--- a/tex/context/base/font-gds.lua
+++ b/tex/context/base/font-gds.lua
@@ -278,7 +278,7 @@ local function setcolorscheme(tfmdata,scheme)
end
elseif type(name) == "number" then
reverse[name] = i
- elseif find(name,":") then
+ elseif find(name,":",1,true) then
local start, stop = splitup(name,":")
start = tonumber(start)
stop = tonumber(stop)
diff --git a/tex/context/base/font-ini.mkvi b/tex/context/base/font-ini.mkvi
index 521901e05..cc850b9af 100644
--- a/tex/context/base/font-ini.mkvi
+++ b/tex/context/base/font-ini.mkvi
@@ -363,7 +363,7 @@
\let\thedefinedfont\relax % not to be confused with \everydefinefont
\unexpanded\def\definedfont
- {\doifnextoptionalelse\font_basics_defined_font_yes\font_basics_defined_font_nop}
+ {\doifnextoptionalcselse\font_basics_defined_font_yes\font_basics_defined_font_nop}
\def\font_basics_defined_font_yes[#specification]%
{\c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly
@@ -2082,7 +2082,7 @@
% \newtoks \everyswitchtobodyfont
\unexpanded\def\setupbodyfont
- {\doifnextoptionalelse\font_basics_setupbodyfont_yes\font_basics_setupbodyfont_nop}
+ {\doifnextoptionalcselse\font_basics_setupbodyfont_yes\font_basics_setupbodyfont_nop}
\def\font_basics_setupbodyfont_nop
{\restoreglobalbodyfont
@@ -2175,7 +2175,8 @@
%D The next auxilliary macro is an alternative to \type
%D {\fontname}.
-\def\purefontname#font{\ctxlua{file.basename("\fontname#font"}} % will be function using id
+\def\purefontname#font{\ctxcommand{purefontname("\fontname#font")}}
+%def\purefontname#font{\ctxcommand{purefontname(\number\fontid#font)}}
%D \macros
%D {switchstyleonly}
@@ -2190,7 +2191,7 @@
%D \stoptyping
\unexpanded\def\switchstyleonly
- {\doifnextoptionalelse\font_basics_switch_style_only_opt\font_basics_switch_style_only_arg}
+ {\doifnextoptionalcselse\font_basics_switch_style_only_opt\font_basics_switch_style_only_arg}
\def\font_basics_switch_style_only_arg#name% stupid version
{\font_helpers_set_current_font_style{\csname\??fontshortstyle\checkedstrippedcsname#name\endcsname}%
@@ -2348,6 +2349,83 @@
\def\saveddefinedfontid {\number\fontid\font}
\def\saveddefinedfontname{\fontname\font}
+% yes or no:
+% \let\font_basics_check_text_bodyfont_slow\font_basics_check_text_bodyfont
+%
+% \unexpanded\def\font_basics_check_text_bodyfont
+% {\ifproductionrun
+% % not per se \s!..'s
+% \glet\font_basics_check_text_bodyfont \font_basics_check_text_bodyfont_slow
+% \glet\font_basics_check_text_bodyfont_fast\relax
+% \expandafter\font_basics_check_text_bodyfont
+% \else
+% \expandafter\font_basics_check_text_bodyfont_fast
+% \fi}
+%
+% \def\font_basics_check_text_bodyfont_fast#style#alternative#size% size can be empty (checking needed as \bf is already defined)
+% {\setugvalue{#style#size}% \rma
+% {\let\fontstyle#style%
+% \let\fontsize #size%
+% \font_helpers_check_big_math_synchronization % double? better in everymath?
+% \font_helpers_synchronize_font}%
+% \setugvalue{#alternative#size}% \sla
+% {\let\fontalternative#alternative%
+% \let\fontsize #size%
+% \font_helpers_check_big_math_synchronization % double? better in everymath?
+% \font_helpers_synchronize_font}%
+% \setugvalue{#style#alternative#size}% \rmsla
+% {\let\fontstyle #style%
+% \let\fontalternative#alternative%
+% \let\fontsize #size%
+% \font_helpers_check_big_math_synchronization % double? better in everymath?
+% \font_helpers_synchronize_font}%
+% \ifcsname\s!normal#style\endcsname % text/math check
+% \expandafter\let\csname#style\expandafter\endcsname\csname\s!normal#style\endcsname
+% \else
+% \setugvalue{#style}% \rm
+% {\let\fontstyle#style%
+% \font_typescripts_inherit_check\fontstyle
+% \ifmmode\mr\fi % otherwise \rm not downward compatible ... not adapted yet
+% \font_helpers_synchronize_font}%
+% \fi
+% \ifcsname\s!normal#alternative\endcsname % text/math check
+% \expandafter\let\csname#alternative\expandafter\endcsname\csname\s!normal#alternative\endcsname
+% \else
+% \setugvalue{#alternative}% \sl
+% {\let\fontalternative#alternative%
+% \font_helpers_synchronize_font}%
+% \fi
+% \setugvalue{#style\s!x}% \rmx
+% {\csname#style\endcsname\tx}%
+% \setugvalue{#style\s!xx}% \rmxx
+% {\csname#style\endcsname\txx}%
+% \setugvalue{#alternative\s!x}% \slx
+% {\font_helpers_check_nested_x_fontsize
+% \ifmmode
+% \scriptstyle
+% \else
+% \let\fontface4%
+% \let\fontalternative#alternative%
+% \font_helpers_synchronize_font
+% \fi
+% \currentxfontsize\plusone
+% \let\tx\txx}%
+% \setugvalue{#alternative\s!xx}% \slxx
+% {\font_helpers_check_nested_x_fontsize
+% \ifmmode
+% \scriptscriptstyle
+% \else
+% \let\fontface5%
+% \let\fontalternative#alternative%
+% \font_helpers_synchronize_font
+% \fi
+% \currentxfontsize\plustwo
+% \let\tx\empty
+% \let\txx\empty}%
+% \setugvalue{#style#alternative}% \rmsl
+% {\let\fontstyle #style%
+% \let\fontalternative#alternative%
+% \font_helpers_synchronize_font}}
\protect \endinput
diff --git a/tex/context/base/font-lib.mkvi b/tex/context/base/font-lib.mkvi
index a664d9b3a..92db44722 100644
--- a/tex/context/base/font-lib.mkvi
+++ b/tex/context/base/font-lib.mkvi
@@ -38,7 +38,15 @@
\registerctxluafile{font-ott}{1.001} % otf tables (first)
\registerctxluafile{font-otf}{1.001} % otf main
\registerctxluafile{font-otb}{1.001} % otf main base
-\registerctxluafile{node-inj}{1.001} % we might split it off
+
+\ctxcommand{doifelse(nodes.properties)} {
+ \doiffileelse{font-inj.lua}
+ {\registerctxluafile{font-inj}{1.001}}
+ {\registerctxluafile{node-inj}{1.001}}
+} {
+ \registerctxluafile{node-inj}{1.001}
+}
+
%registerctxluafile{font-ota}{1.001} % otf analyzers
\registerctxluafile{font-otx}{1.001} % otf analyzers
\registerctxluafile{font-otn}{1.001} % otf main node
diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua
index 63cae37f3..7385d6f31 100644
--- a/tex/context/base/font-mis.lua
+++ b/tex/context/base/font-mis.lua
@@ -22,7 +22,7 @@ local handlers = fonts.handlers
handlers.otf = handlers.otf or { }
local otf = handlers.otf
-otf.version = otf.version or 2.751
+otf.version = otf.version or 2.755
otf.cache = otf.cache or containers.define("fonts", "otf", otf.version, true)
function otf.loadcached(filename,format,sub)
diff --git a/tex/context/base/font-odv.lua b/tex/context/base/font-odv.lua
index d07c38d9a..079027ffe 100644
--- a/tex/context/base/font-odv.lua
+++ b/tex/context/base/font-odv.lua
@@ -118,8 +118,8 @@ local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
local getfield = nuts.getfield
local setfield = nuts.setfield
-local getattr = nuts.getattr
-local setattr = nuts.setattr
+local getprop = nuts.getprop
+local setprop = nuts.setprop
local insert_node_after = nuts.insert_after
local copy_node = nuts.copy
@@ -649,7 +649,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces)
current = start
else
current = getnext(n)
- setattr(start,a_state,s_rphf)
+ setprop(start,a_state,s_rphf)
end
end
@@ -682,9 +682,9 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces)
local nextcurrent = copy_node(current)
setfield(tempcurrent,"next",nextcurrent)
setfield(nextcurrent,"prev",tempcurrent)
- setattr(tempcurrent,a_state,s_blwf)
+ setprop(tempcurrent,a_state,s_blwf)
tempcurrent = processcharacters(tempcurrent,font)
- setattr(tempcurrent,a_state,unsetvalue)
+ setprop(tempcurrent,a_state,unsetvalue)
if getchar(next) == getchar(tempcurrent) then
flush_list(tempcurrent)
local n = copy_node(current)
@@ -713,7 +713,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces)
while not basefound do
-- find base consonant
if consonant[getchar(current)] then
- setattr(current,a_state,s_half)
+ setprop(current,a_state,s_half)
if not firstcons then
firstcons = current
end
@@ -722,7 +722,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces)
base = current
elseif blwfcache[getchar(current)] then
-- consonant has below-base (or post-base) form
- setattr(current,a_state,s_blwf)
+ setprop(current,a_state,s_blwf)
else
base = current
end
@@ -802,15 +802,15 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces)
while current ~= stop do
local next = getnext(current)
if next ~= stop and halant[getchar(next)] and getchar(getnext(next)) == c_zwnj then
- setattr(current,a_state,unsetvalue)
+ setprop(current,a_state,unsetvalue)
end
current = next
end
- if base ~= stop and getattr(base,a_state) then
+ if base ~= stop and getprop(base,a_state) then
local next = getnext(base)
if halant[getchar(next)] and not (next ~= stop and getchar(getnext(next)) == c_zwj) then
- setattr(base,a_state,unsetvalue)
+ setprop(base,a_state,unsetvalue)
end
end
@@ -906,7 +906,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces)
end
bn = next
end
- if getattr(current,a_state) == s_rphf then
+ if getprop(current,a_state) == s_rphf then
-- position Reph (Ra + H) after post-base 'matra' (if any) since these
-- become marks on the 'matra', not on the base glyph
if b ~= current then
@@ -998,12 +998,12 @@ end
function handlers.devanagari_reorder_matras(head,start,kind,lookupname,replacement) -- no leak
local current = start -- we could cache attributes here
local startfont = getfont(start)
- local startattr = getattr(start,a_syllabe)
+ local startattr = getprop(start,a_syllabe)
-- can be fast loop
- while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == font and getattr(current,a_syllabe) == startattr do
+ while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == font and getprop(current,a_syllabe) == startattr do
local next = getnext(current)
- if halant[getchar(current)] and not getattr(current,a_state) then
- if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == font and getattr(next,a_syllabe) == startattr and zw_char[getchar(next)] then
+ if halant[getchar(current)] and not getprop(current,a_state) then
+ if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == font and getprop(next,a_syllabe) == startattr and zw_char[getchar(next)] then
current = next
end
local startnext = getnext(start)
@@ -1054,11 +1054,11 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement
local startnext = nil
local startprev = nil
local startfont = getfont(start)
- local startattr = getattr(start,a_syllabe)
- while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do --step 2
- if halant[getchar(current)] and not getattr(current,a_state) then
+ local startattr = getprop(start,a_syllabe)
+ while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do --step 2
+ if halant[getchar(current)] and not getprop(current,a_state) then
local next = getnext(current)
- if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == startfont and getattr(next,a_syllabe) == startattr and zw_char[getchar(next)] then
+ if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == startfont and getprop(next,a_syllabe) == startattr and zw_char[getchar(next)] then
current = next
end
startnext = getnext(start)
@@ -1071,15 +1071,15 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement
setfield(current,"next",start)
setfield(start,"prev",current)
start = startnext
- startattr = getattr(start,a_syllabe)
+ startattr = getprop(start,a_syllabe)
break
end
current = getnext(current)
end
if not startnext then
current = getnext(start)
- while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do --step 4
- if getattr(current,a_state) == s_pstf then --post-base
+ while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do --step 4
+ if getprop(current,a_state) == s_pstf then --post-base
startnext = getnext(start)
head = remove_node(head,start)
local prev = getprev(current)
@@ -1088,7 +1088,7 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement
setfield(start,"next",current)
setfield(current,"prev",start)
start = startnext
- startattr = getattr(start,a_syllabe)
+ startattr = getprop(start,a_syllabe)
break
end
current = getnext(current)
@@ -1100,7 +1100,7 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement
if not startnext then
current = getnext(start)
local c = nil
- while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do --step 5
+ while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do --step 5
if not c then
local char = getchar(current)
-- todo: combine in one
@@ -1121,14 +1121,14 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement
setfield(c,"prev",start)
-- end
start = startnext
- startattr = getattr(start,a_syllabe)
+ startattr = getprop(start,a_syllabe)
end
end
-- leaks
if not startnext then
current = start
local next = getnext(current)
- while next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == startfont and getattr(next,a_syllabe) == startattr do --step 6
+ while next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == startfont and getprop(next,a_syllabe) == startattr do --step 6
current = next
next = getnext(current)
end
@@ -1165,12 +1165,12 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start,k
local startnext = nil
local startprev = nil
local startfont = getfont(start)
- local startattr = getattr(start,a_syllabe)
+ local startattr = getprop(start,a_syllabe)
-- can be fast for loop + caching state
- while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do
+ while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do
local next = getnext(current)
- if halant[getchar(current)] and not getattr(current,a_state) then
- if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == font and getattr(next,a_syllabe) == startattr then
+ if halant[getchar(current)] and not getprop(current,a_state) then
+ if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == font and getprop(next,a_syllabe) == startattr then
local char = getchar(next)
if char == c_zwnj or char == c_zwj then
current = next
@@ -1192,9 +1192,9 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start,k
end
if not startnext then
current = getnext(start)
- startattr = getattr(start,a_syllabe)
- while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do
- if not consonant[getchar(current)] and getattr(current,a_state) then --main
+ startattr = getprop(start,a_syllabe)
+ while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do
+ if not consonant[getchar(current)] and getprop(current,a_state) then --main
startnext = getnext(start)
removenode(start,start)
local prev = getprev(current)
@@ -1377,7 +1377,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
current = next
current = getnext(current)
elseif current == start then
- setattr(current,a_state,s_rphf)
+ setprop(current,a_state,s_rphf)
current = next
else
current = next
@@ -1418,8 +1418,8 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
local next = getnext(current)
local n = locl[next] or getchar(next)
if found[n] then
- setattr(current,a_state,s_pref)
- setattr(next,a_state,s_pref)
+ setprop(current,a_state,s_pref)
+ setprop(next,a_state,s_pref)
current = next
end
end
@@ -1440,7 +1440,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
if next ~= stop and getchar(getnext(next)) == c_zwnj then -- zwnj prevent creation of half
current = next
else
- setattr(current,a_state,s_half)
+ setprop(current,a_state,s_half)
if not halfpos then
halfpos = current
end
@@ -1462,8 +1462,8 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
local next = getnext(current)
local n = locl[next] or getchar(next)
if found[n] then
- setattr(current,a_state,s_blwf)
- setattr(next,a_state,s_blwf)
+ setprop(current,a_state,s_blwf)
+ setprop(next,a_state,s_blwf)
current = next
subpos = current
end
@@ -1482,8 +1482,8 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
local next = getnext(current)
local n = locl[next] or getchar(next)
if found[n] then
- setattr(current,a_state,s_pstf)
- setattr(next,a_state,s_pstf)
+ setprop(current,a_state,s_pstf)
+ setprop(next,a_state,s_pstf)
current = next
postpos = current
end
@@ -1501,7 +1501,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
local current, base, firstcons = start, nil, nil
- if getattr(start,a_state) == s_rphf then
+ if getprop(start,a_state) == s_rphf then
-- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants
current = getnext(getnext(start))
end
@@ -1532,13 +1532,13 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
local tmp = getnext(next)
local changestop = next == stop
setfield(next,"next",nil)
- setattr(current,a_state,s_pref)
+ setprop(current,a_state,s_pref)
current = processcharacters(current,font)
- setattr(current,a_state,s_blwf)
+ setprop(current,a_state,s_blwf)
current = processcharacters(current,font)
- setattr(current,a_state,s_pstf)
+ setprop(current,a_state,s_pstf)
current = processcharacters(current,font)
- setattr(current,a_state,unsetvalue)
+ setprop(current,a_state,unsetvalue)
if halant[getchar(current)] then
setfield(getnext(current),"next",tmp)
local nc = copy_node(current)
@@ -1572,7 +1572,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
firstcons = current
end
-- check whether consonant has below-base or post-base form or is pre-base reordering Ra
- local a = getattr(current,a_state)
+ local a = getprop(current,a_state)
if not (a == s_pref or a == s_blwf or a == s_pstf) then
base = current
end
@@ -1586,13 +1586,13 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa
end
if not base then
- if getattr(start,a_state) == s_rphf then
- setattr(start,a_state,unsetvalue)
+ if getprop(start,a_state) == s_rphf then
+ setprop(start,a_state,unsetvalue)
end
return head, stop, nbspaces
else
- if getattr(base,a_state) then
- setattr(base,a_state,unsetvalue)
+ if getprop(base,a_state) then
+ setprop(base,a_state,unsetvalue)
end
basepos = base
end
@@ -2319,14 +2319,14 @@ function methods.dev2(head,font,attr)
local c = syllablestart
local n = getnext(syllableend)
while c ~= n do
- setattr(c,a_syllabe,syllabe)
+ setprop(c,a_syllabe,syllabe)
c = getnext(c)
end
end
if syllableend and syllablestart ~= syllableend then
head, current, nbspaces = dev2_reorder(head,syllablestart,syllableend,font,attr,nbspaces)
end
- if not syllableend and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == font and not getattr(current,a_state) then
+ if not syllableend and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == font and not getprop(current,a_state) then
local mark = mark_four[getchar(current)]
if mark then
head, current = inject_syntax_error(head,current,mark)
diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua
index 9af5a3347..8d60ddc0e 100644
--- a/tex/context/base/font-ota.lua
+++ b/tex/context/base/font-ota.lua
@@ -8,6 +8,9 @@ if not modules then modules = { } end modules ['font-ota'] = {
-- this might become scrp-*.lua
+-- [attr] : getprop or getattr
+-- [attr] : setprop or setattr
+
local type = type
if not trackers then trackers = { register = function() end } end
diff --git a/tex/context/base/font-otb.lua b/tex/context/base/font-otb.lua
index 2a7b821ea..946d552e4 100644
--- a/tex/context/base/font-otb.lua
+++ b/tex/context/base/font-otb.lua
@@ -594,8 +594,9 @@ basemethod = "independent"
local function featuresinitializer(tfmdata,value)
if true then -- value then
- local t = trace_preparing and os.clock()
- local features = tfmdata.shared.features
+ local starttime = trace_preparing and os.clock()
+ local features = tfmdata.shared.features
+ local fullname = trace_preparing and tfmdata.properties.fullname
if features then
applybasemethod("initializehashes",tfmdata)
local collectlookups = otf.collectlookups
@@ -605,34 +606,70 @@ local function featuresinitializer(tfmdata,value)
local language = properties.language
local basesubstitutions = rawdata.resources.features.gsub
local basepositionings = rawdata.resources.features.gpos
- if basesubstitutions then
- for feature, data in next, basesubstitutions do
- local value = features[feature]
- if value then
- local validlookups, lookuplist = collectlookups(rawdata,feature,script,language)
- if validlookups then
- applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist)
- registerbasefeature(feature,value)
- end
- end
- end
- end
- if basepositionings then
- for feature, data in next, basepositionings do
- local value = features[feature]
- if value then
- local validlookups, lookuplist = collectlookups(rawdata,feature,script,language)
- if validlookups then
- applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist)
- registerbasefeature(feature,value)
+ --
+ -- if basesubstitutions then
+ -- for feature, data in next, basesubstitutions do
+ -- local value = features[feature]
+ -- if value then
+ -- local validlookups, lookuplist = collectlookups(rawdata,feature,script,language)
+ -- if validlookups then
+ -- applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist)
+ -- registerbasefeature(feature,value)
+ -- end
+ -- end
+ -- end
+ -- end
+ -- if basepositionings then
+ -- for feature, data in next, basepositionings do
+ -- local value = features[feature]
+ -- if value then
+ -- local validlookups, lookuplist = collectlookups(rawdata,feature,script,language)
+ -- if validlookups then
+ -- applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist)
+ -- registerbasefeature(feature,value)
+ -- end
+ -- end
+ -- end
+ -- end
+ --
+ if basesubstitutions or basepositionings then
+ local sequences = tfmdata.resources.sequences
+ for s=1,#sequences do
+ local sequence = sequences[s]
+ local sfeatures = sequence.features
+ if sfeatures then
+ local order = sequence.order
+ if order then
+ for i=1,#order do --
+ local feature = order[i]
+ if features[feature] then
+ local validlookups, lookuplist = collectlookups(rawdata,feature,script,language)
+ if not validlookups then
+ -- skip
+ elseif basesubstitutions and basesubstitutions[feature] then
+ if trace_preparing then
+ report_prepare("filtering base feature %a for %a",feature,fullname)
+ end
+ applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ elseif basepositionings and basepositionings[feature] then
+ if trace_preparing then
+ report_prepare("filtering base feature %a for %a",feature,fullname)
+ end
+ applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ end
+ end
+ end
end
end
end
end
+ --
registerbasehash(tfmdata)
end
if trace_preparing then
- report_prepare("preparation time is %0.3f seconds for %a",os.clock()-t,tfmdata.properties.fullname)
+ report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname)
end
end
end
diff --git a/tex/context/base/font-otc.lua b/tex/context/base/font-otc.lua
index 3006e47ca..92775270d 100644
--- a/tex/context/base/font-otc.lua
+++ b/tex/context/base/font-otc.lua
@@ -70,6 +70,7 @@ local function addfeature(data,feature,specifications)
local subtables = specification.subtables or { specification.data } or { }
local featuretype = types[specification.type or "substitution"]
local featureflags = specification.flags or noflags
+ local featureorder = specification.order or { feature }
local added = false
local featurename = format("ctx_%s_%s",feature,s)
local st = { }
@@ -138,6 +139,7 @@ local function addfeature(data,feature,specifications)
features = { [feature] = askedfeatures },
flags = featureflags,
name = featurename,
+ order = featureorder,
subtables = st,
type = featuretype,
}
@@ -204,6 +206,7 @@ local tlig_specification = {
type = "ligature",
features = everywhere,
data = tlig,
+ order = { "tlig" },
flags = noflags,
}
@@ -226,6 +229,7 @@ local trep_specification = {
type = "substitution",
features = everywhere,
data = trep,
+ order = { "trep" },
flags = noflags,
}
@@ -256,6 +260,7 @@ if characters.combined then
type = "ligature",
features = everywhere,
data = tcom,
+ order = { "tcom" },
flags = noflags,
initialize = initialize,
}
@@ -314,6 +319,7 @@ local anum_specification = {
{
type = "substitution",
features = { arab = { urd = true, dflt = true } },
+ order = { "anum" },
data = anum_arabic,
flags = noflags, -- { },
valid = valid,
@@ -321,6 +327,7 @@ local anum_specification = {
{
type = "substitution",
features = { arab = { urd = true } },
+ order = { "anum" },
data = anum_persian,
flags = noflags, -- { },
valid = valid,
diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua
index 919da2379..e421111dd 100644
--- a/tex/context/base/font-otd.lua
+++ b/tex/context/base/font-otd.lua
@@ -129,10 +129,13 @@ local default = "dflt"
-- what about analyze in local and not in font
-local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr,dynamic)
+local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr,dynamic,ra)
local features = sequence.features
if features then
- for kind, scripts in next, features do
+ local order = sequence.order or { }
+ -- for kind, scripts in next, features do
+ for i=1,#order do --
+ local kind = order[i] --
local e_e
local a_e = a_enabled and a_enabled[kind] -- the value (location)
if a_e ~= nil then
@@ -141,6 +144,7 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr
e_e = s_enabled and s_enabled[kind] -- the value (font)
end
if e_e then
+ local scripts = features[kind] --
local languages = scripts[script] or scripts[wildcard]
if languages then
-- local valid, what = false
@@ -174,14 +178,14 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr
"font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a",
font,attr or 0,dynamic,kind,script,language,sequence.name,valid)
end
- return { valid, attribute, sequence.chain or 0, kind, sequence }
+ ra[#ra+1] = { valid, attribute, sequence.chain or 0, kind, sequence }
end
end
end
end
- return false -- { valid, attribute, chain, "generic", sequence } -- false anyway, could be flag instead of table
+ -- { valid, attribute, chain, "generic", sequence } -- false anyway, could be flag instead of table
else
- return false -- { false, false, chain, false, sequence } -- indirect lookup, part of chain (todo: make this a separate table)
+ -- { false, false, chain, false, sequence } -- indirect lookup, part of chain (todo: make this a separate table)
end
end
@@ -249,12 +253,16 @@ function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in specia
-- return v
-- end
-- end)
+-- for s=1,#sequences do
+-- local v = initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic)
+-- if v then
+-- ra[#ra+1] = v
+-- end
+-- end
for s=1,#sequences do
- local v = initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic)
- if v then
- ra[#ra+1] = v
- end
+ initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic,ra)
end
+-- table.save((jit and "tmc-" or "tma-")..font..".log",ra) -- bug in jit
end
return ra
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index eb28bc368..0a5d1cfea 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -48,7 +48,7 @@ local otf = fonts.handlers.otf
otf.glists = { "gsub", "gpos" }
-otf.version = 2.751 -- beware: also sync font-mis.lua
+otf.version = 2.755 -- beware: also sync font-mis.lua
otf.cache = containers.define("fonts", "otf", otf.version, true)
local fontdata = fonts.hashes.identifiers
@@ -687,15 +687,22 @@ actions["prepare glyphs"] = function(data,filename,raw)
local glyph = cidglyphs[index]
if glyph then
local unicode = glyph.unicode
+if unicode >= 0x00E000 and unicode <= 0x00F8FF then
+ unicode = -1
+elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFD then
+ unicode = -1
+elseif unicode >= 0x100000 and unicode <= 0x10FFFD then
+ unicode = -1
+end
local name = glyph.name or cidnames[index]
- if not unicode or unicode == -1 or unicode >= criterium then
+ if not unicode or unicode == -1 then -- or unicode >= criterium then
unicode = cidunicodes[index]
end
if unicode and descriptions[unicode] then
report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode)
unicode = -1
end
- if not unicode or unicode == -1 or unicode >= criterium then
+ if not unicode or unicode == -1 then -- or unicode >= criterium then
if not name then
name = format("u%06X",private)
end
@@ -747,7 +754,7 @@ actions["prepare glyphs"] = function(data,filename,raw)
if glyph then
local unicode = glyph.unicode
local name = glyph.name
- if not unicode or unicode == -1 or unicode >= criterium then
+ if not unicode or unicode == -1 then -- or unicode >= criterium then
unicode = private
unicodes[name] = private
if trace_private then
@@ -809,6 +816,10 @@ end
-- the next one is still messy but will get better when we have
-- flattened map/enc tables in the font loader
+-- the next one is not using a valid base for unicode privates
+--
+-- PsuedoEncodeUnencoded(EncMap *map,struct ttfinfo *info)
+
actions["check encoding"] = function(data,filename,raw)
local descriptions = data.descriptions
local resources = data.resources
@@ -825,6 +836,7 @@ actions["check encoding"] = function(data,filename,raw)
-- local encname = lower(data.enc_name or raw.enc_name or mapdata.enc_name or "")
local encname = lower(data.enc_name or mapdata.enc_name or "")
local criterium = 0xFFFF -- for instance cambria has a lot of mess up there
+ local privateoffset = constructors.privateoffset
-- end of messy
@@ -832,81 +844,44 @@ actions["check encoding"] = function(data,filename,raw)
if trace_loading then
report_otf("checking embedded unicode map %a",encname)
end
- -- if false then
- -- for unicode, index in next, unicodetoindex do -- altuni already covers this
- -- if unicode <= criterium and not descriptions[unicode] then
- -- local parent = indices[index] -- why nil?
- -- if not parent then
- -- report_otf("weird, unicode %U points to nowhere with index %H",unicode,index)
- -- else
- -- local parentdescription = descriptions[parent]
- -- if parentdescription then
- -- local altuni = parentdescription.altuni
- -- if not altuni then
- -- altuni = { { unicode = unicode } }
- -- parentdescription.altuni = altuni
- -- duplicates[parent] = { unicode }
- -- else
- -- local done = false
- -- for i=1,#altuni do
- -- if altuni[i].unicode == unicode then
- -- done = true
- -- break
- -- end
- -- end
- -- if not done then
- -- -- let's assume simple cjk reuse
- -- insert(altuni,{ unicode = unicode })
- -- insert(duplicates[parent],unicode)
- -- end
- -- end
- -- -- if trace_loading then
- -- -- report_otf("weird, unicode %U points to nowhere with index %H",unicode,index)
- -- -- end
- -- else
- -- report_otf("weird, unicode %U points to %U with index %H",unicode,index)
- -- end
- -- end
- -- end
- -- end
- -- else
- local hash = { }
- for index, unicode in next, indices do -- indextounicode
- hash[index] = descriptions[unicode]
- end
- local reported = { }
- for unicode, index in next, unicodetoindex do
- if not descriptions[unicode] then
- local d = hash[index]
+ local reported = { }
+ -- we loop over the original unicode->index mapping but we
+ -- need to keep in mind that that one can have weird entries
+ -- so we need some extra checking
+ for maybeunicode, index in next, unicodetoindex do
+ if descriptions[maybeunicode] then
+ -- we ignore invalid unicodes (unicode = -1) (ff can map wrong to non private)
+ else
+ local unicode = indices[index]
+ if not unicode then
+ -- weird (cjk or so?)
+ elseif maybeunicode == unicode then
+ -- no need to add
+ elseif unicode > privateoffset then
+ -- we have a non-unicode
+ else
+ local d = descriptions[unicode]
if d then
- if d.unicode ~= unicode then
- local c = d.copies
- if c then
- c[unicode] = true
- else
- d.copies = { [unicode] = true }
- end
+ local c = d.copies
+ if c then
+ c[maybeunicode] = true
+ else
+ d.copies = { [maybeunicode] = true }
end
- elseif not reported[i] then
+ elseif index and not reported[index] then
report_otf("missing index %i",index)
- reported[i] = true
+ reported[index] = true
end
end
end
- for index, data in next, hash do -- indextounicode
- data.copies = sortedkeys(data.copies)
- end
- for index, unicode in next, indices do -- indextounicode
- local description = hash[index]
- local copies = description.copies
- if copies then
- duplicates[unicode] = copies
- description.copies = nil
- else
- report_otf("copies but no unicode parent %U",unicode)
- end
+ end
+ for unicode, data in next, descriptions do
+ local d = data.copies
+ if d then
+ duplicates[unicode] = sortedkeys(d)
+ data.copies = nil
end
- -- end
+ end
elseif properties.cidinfo then
report_otf("warning: no unicode map, used cidmap %a",properties.cidinfo.usedname)
else
@@ -939,6 +914,7 @@ actions["add duplicates"] = function(data,filename,raw)
report_otf("ignoring excessive duplicates of %U (n=%s)",unicode,nofduplicates)
end
else
+ -- local validduplicates = { }
for i=1,nofduplicates do
local u = d[i]
if not descriptions[u] then
@@ -957,16 +933,18 @@ actions["add duplicates"] = function(data,filename,raw)
end
-- todo: lookups etc
end
- if u > 0 then
+ if u > 0 then -- and
local duplicate = table.copy(description) -- else packing problem
duplicate.comment = format("copy of U+%05X", unicode)
descriptions[u] = duplicate
+ -- validduplicates[#validduplicates+1] = u
if trace_loading then
report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n)
end
end
end
end
+ -- duplicates[unicode] = #validduplicates > 0 and validduplicates or nil
end
end
end
@@ -1197,10 +1175,16 @@ actions["reorganize subtables"] = function(data,filename,raw)
elseif features then
-- scripts, tag, ismac
local f = { }
+ local o = { }
for i=1,#features do
local df = features[i]
local tag = strip(lower(df.tag))
- local ft = f[tag] if not ft then ft = {} f[tag] = ft end
+ local ft = f[tag]
+ if not ft then
+ ft = { }
+ f[tag] = ft
+ o[#o+1] = tag
+ end
local dscripts = df.scripts
for i=1,#dscripts do
local d = dscripts[i]
@@ -1220,6 +1204,7 @@ actions["reorganize subtables"] = function(data,filename,raw)
subtables = subtables,
markclass = markclass,
features = f,
+ order = o,
}
else
lookups[name] = {
diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua
index 75e95749c..540716b35 100644
--- a/tex/context/base/font-otn.lua
+++ b/tex/context/base/font-otn.lua
@@ -182,17 +182,18 @@ local tonode = nuts.tonode
local tonut = nuts.tonut
local getfield = nuts.getfield
+local setfield = nuts.setfield
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
local getattr = nuts.getattr
+local setattr = nuts.setattr
+local getprop = nuts.getprop
+local setprop = nuts.setprop
local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
local getchar = nuts.getchar
-local setfield = nuts.setfield
-local setattr = nuts.setattr
-
local insert_node_after = nuts.insert_after
local delete_node = nuts.delete
local copy_node = nuts.copy
@@ -234,13 +235,7 @@ local privateattribute = attributes.private
-- of only some.
local a_state = privateattribute('state')
-local a_markbase = privateattribute('markbase')
-local a_markmark = privateattribute('markmark')
-local a_markdone = privateattribute('markdone') -- assigned at the injection end
-local a_cursbase = privateattribute('cursbase')
-local a_curscurs = privateattribute('curscurs')
-local a_cursdone = privateattribute('cursdone')
-local a_kernpair = privateattribute('kernpair')
+local a_cursbase = privateattribute('cursbase') -- to be checked
local a_ligacomp = privateattribute('ligacomp') -- assigned here (ideally it should be combined)
local injections = nodes.injections
@@ -249,9 +244,7 @@ local setcursive = injections.setcursive
local setkern = injections.setkern
local setpair = injections.setpair
-local markonce = true
local cursonce = true
-local kernonce = true
local fonthashes = fonts.hashes
local fontdata = fonthashes.identifiers
@@ -459,9 +452,9 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
baseindex = baseindex + componentindex
componentindex = getcomponentindex(start)
elseif not deletemarks then -- quite fishy
- setattr(start,a_ligacomp,baseindex + (getattr(start,a_ligacomp) or componentindex))
+ setprop(start,a_ligacomp,baseindex + (getprop(start,a_ligacomp) or componentindex))
if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp))
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getprop(start,a_ligacomp))
end
head, current = insert_node_after(head,current,copy_node(start)) -- unlikely that mark has components
elseif trace_marks then
@@ -475,9 +468,9 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
while start and getid(start) == glyph_code do
local char = getchar(start)
if marks[char] then
- setattr(start,a_ligacomp,baseindex + (getattr(start,a_ligacomp) or componentindex))
+ setprop(start,a_ligacomp,baseindex + (getprop(start,a_ligacomp) or componentindex))
if trace_marks then
- logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp))
+ logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getprop(start,a_ligacomp))
end
else
break
@@ -710,7 +703,7 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence
if al[anchor] then
local ma = markanchors[anchor]
if ma then
- local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma)
+ local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar])
if trace_marks then
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)",
pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
@@ -759,7 +752,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ
end
end
end
- local index = getattr(start,a_ligacomp)
+ local index = getprop(start,a_ligacomp)
local baseanchors = descriptions[basechar]
if baseanchors then
baseanchors = baseanchors.anchors
@@ -773,7 +766,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ
if ma then
ba = ba[index]
if ba then
- local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index
+ local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) -- index
if trace_marks then
logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)",
pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy)
@@ -809,10 +802,10 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence
local markchar = getchar(start)
if marks[markchar] then
local base = getprev(start) -- [glyph] [basemark] [start=mark]
- local slc = getattr(start,a_ligacomp)
+ local slc = getprop(start,a_ligacomp)
if slc then -- a rather messy loop ... needs checking with husayni
while base do
- local blc = getattr(base,a_ligacomp)
+ local blc = getprop(base,a_ligacomp)
if blc and blc ~= slc then
base = getprev(base)
else
@@ -833,7 +826,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence
if al[anchor] then
local ma = markanchors[anchor]
if ma then
- local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true)
+ local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar])
if trace_marks then
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)",
pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
@@ -861,7 +854,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence
end
function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) -- to be checked
- local alreadydone = cursonce and getattr(start,a_cursbase)
+ local alreadydone = cursonce and getprop(start,a_cursbase)
if not alreadydone then
local done = false
local startchar = getchar(start)
@@ -1343,7 +1336,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext
if al[anchor] then
local ma = markanchors[anchor]
if ma then
- local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma)
+ local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar])
if trace_marks then
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)",
cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
@@ -1399,7 +1392,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon
end
end
-- todo: like marks a ligatures hash
- local index = getattr(start,a_ligacomp)
+ local index = getprop(start,a_ligacomp)
local baseanchors = descriptions[basechar].anchors
if baseanchors then
local baseanchors = baseanchors['baselig']
@@ -1411,7 +1404,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon
if ma then
ba = ba[index]
if ba then
- local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index
+ local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar])
if trace_marks then
logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)",
cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy)
@@ -1441,62 +1434,57 @@ end
function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
local markchar = getchar(start)
if marks[markchar] then
- -- local alreadydone = markonce and getattr(start,a_markmark)
- -- if not alreadydone then
- -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark
- local subtables = currentlookup.subtables
- local lookupname = subtables[1]
- local markanchors = lookuphash[lookupname]
- if markanchors then
- markanchors = markanchors[markchar]
- end
- if markanchors then
- local base = getprev(start) -- [glyph] [basemark] [start=mark]
- local slc = getattr(start,a_ligacomp)
- if slc then -- a rather messy loop ... needs checking with husayni
- while base do
- local blc = getattr(base,a_ligacomp)
- if blc and blc ~= slc then
- base = getprev(base)
- else
- break
- end
+ -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark
+ local subtables = currentlookup.subtables
+ local lookupname = subtables[1]
+ local markanchors = lookuphash[lookupname]
+ if markanchors then
+ markanchors = markanchors[markchar]
+ end
+ if markanchors then
+ local base = getprev(start) -- [glyph] [basemark] [start=mark]
+ local slc = getprop(start,a_ligacomp)
+ if slc then -- a rather messy loop ... needs checking with husayni
+ while base do
+ local blc = getprop(base,a_ligacomp)
+ if blc and blc ~= slc then
+ base = getprev(base)
+ else
+ break
end
end
- if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then -- subtype test can go
- local basechar = getchar(base)
- local baseanchors = descriptions[basechar].anchors
+ end
+ if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then -- subtype test can go
+ local basechar = getchar(base)
+ local baseanchors = descriptions[basechar].anchors
+ if baseanchors then
+ baseanchors = baseanchors['basemark']
if baseanchors then
- baseanchors = baseanchors['basemark']
- if baseanchors then
- local al = anchorlookups[lookupname]
- for anchor,ba in next, baseanchors do
- if al[anchor] then
- local ma = markanchors[anchor]
- if ma then
- local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true)
- if trace_marks then
- logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)",
- cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
- end
- return head, start, true
+ local al = anchorlookups[lookupname]
+ for anchor,ba in next, baseanchors do
+ if al[anchor] then
+ local ma = markanchors[anchor]
+ if ma then
+ local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar])
+ if trace_marks then
+ logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)",
+ cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
end
+ return head, start, true
end
end
- if trace_bugs then
- logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar))
- end
+ end
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar))
end
end
- elseif trace_bugs then
- logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname))
end
elseif trace_bugs then
- logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar))
+ logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname))
end
- -- elseif trace_marks and trace_details then
- -- logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone)
- -- end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar))
+ end
elseif trace_bugs then
logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar))
end
@@ -1504,7 +1492,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext
end
function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
- local alreadydone = cursonce and getattr(start,a_cursbase)
+ local alreadydone = cursonce and getprop(start,a_cursbase)
if not alreadydone then
local startchar = getchar(start)
local subtables = currentlookup.subtables
@@ -2065,9 +2053,12 @@ local autofeatures = fonts.analyzers.features -- was: constants
local function initialize(sequence,script,language,enabled)
local features = sequence.features
if features then
- for kind, scripts in next, features do
+ local order = features.order
+ for i=1,#order do --
+ local kind = order[i] --
local valid = enabled[kind]
if valid then
+ local scripts = features[kind] --
local languages = scripts[script] or scripts[wildcard]
if languages and (languages[language] or languages[wildcard]) then
return { valid, autofeatures[kind] or false, sequence.chain or 0, kind, sequence }
@@ -2101,19 +2092,12 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context
}
rs[language] = rl
local sequences = tfmdata.resources.sequences
--- setmetatableindex(rl, function(t,k)
--- if type(k) == "number" then
--- local v = enabled and initialize(sequences[k],script,language,enabled)
--- t[k] = v
--- return v
--- end
--- end)
-for s=1,#sequences do
- local v = enabled and initialize(sequences[s],script,language,enabled)
- if v then
- rl[#rl+1] = v
- end
-end
+ for s=1,#sequences do
+ local v = enabled and initialize(sequences[s],script,language,enabled)
+ if v then
+ rl[#rl+1] = v
+ end
+ end
end
return rl
end
@@ -2141,7 +2125,7 @@ end
-- attr = attr or false
--
-- local a = getattr(start,0)
--- if (a == attr and (not attribute or getattr(start,a_state) == attribute)) or (not attribute or getattr(start,a_state) == attribute) then
+-- if (a == attr and (not attribute or getprop(start,a_state) == attribute)) or (not attribute or getprop(start,a_state) == attribute) then
-- -- the action
-- end
@@ -2263,9 +2247,9 @@ local function featuresprocessor(head,font,attr)
if id == glyph_code and getfont(start) == font and getsubtype(start) < 256 then
local a = getattr(start,0)
if a then
- a = (a == attr) and (not attribute or getattr(start,a_state) == attribute)
+ a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
else
- a = not attribute or getattr(start,a_state) == attribute
+ a = not attribute or getprop(start,a_state) == attribute
end
if a then
local lookupmatch = lookupcache[getchar(start)]
@@ -2299,9 +2283,9 @@ local function featuresprocessor(head,font,attr)
-- setfield(next,"prev",prev)
local a = getattr(prev,0)
if a then
- a = (a == attr) and (not attribute or getattr(prev,a_state) == attribute)
+ a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute)
else
- a = not attribute or getattr(prev,a_state) == attribute
+ a = not attribute or getprop(prev,a_state) == attribute
end
if a then
local lookupmatch = lookupcache[getchar(prev)]
@@ -2326,9 +2310,9 @@ local function featuresprocessor(head,font,attr)
if getfont(start) == font and getsubtype(start) < 256 then
local a = getattr(start,0)
if a then
- a = (a == attr) and (not attribute or getattr(start,a_state) == attribute)
+ a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
else
- a = not attribute or getattr(start,a_state) == attribute
+ a = not attribute or getprop(start,a_state) == attribute
end
if a then
local lookupmatch = lookupcache[getchar(start)]
@@ -2424,9 +2408,9 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then
if id == glyph_code and getfont(start) == font and getsubtype(start) < 256 then
local a = getattr(start,0)
if a then
- a = (a == attr) and (not attribute or getattr(start,a_state) == attribute)
+ a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
else
- a = not attribute or getattr(start,a_state) == attribute
+ a = not attribute or getprop(start,a_state) == attribute
end
if a then
for i=1,ns do
@@ -2472,9 +2456,9 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then
-- setfield(next,"prev",prev)
local a = getattr(prev,0)
if a then
- a = (a == attr) and (not attribute or getattr(prev,a_state) == attribute)
+ a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute)
else
- a = not attribute or getattr(prev,a_state) == attribute
+ a = not attribute or getprop(prev,a_state) == attribute
end
if a then
for i=1,ns do
@@ -2507,9 +2491,9 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then
if getfont(start) == font and getsubtype(start) < 256 then
local a = getattr(start,0)
if a then
- a = (a == attr) and (not attribute or getattr(start,a_state) == attribute)
+ a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
else
- a = not attribute or getattr(start,a_state) == attribute
+ a = not attribute or getprop(start,a_state) == attribute
end
if a then
for i=1,ns do
diff --git a/tex/context/base/font-otp.lua b/tex/context/base/font-otp.lua
index 217bb7535..c80ee86ae 100644
--- a/tex/context/base/font-otp.lua
+++ b/tex/context/base/font-otp.lua
@@ -407,6 +407,14 @@ local function packdata(data)
features[script] = pack_normal(feature)
end
end
+ local order = sequence.order
+ if order then
+ sequence.order = pack_indexed(order)
+ end
+ local markclass = sequence.markclass
+ if markclass then
+ sequence.markclass = pack_boolean(markclass)
+ end
end
end
local lookups = resources.lookups
@@ -825,6 +833,20 @@ local function unpackdata(data)
end
end
end
+ local order = feature.order
+ if order then
+ local tv = tables[order]
+ if tv then
+ feature.order = tv
+ end
+ end
+ local markclass = feature.markclass
+ if markclass then
+ local tv = tables[markclass]
+ if tv then
+ feature.markclass = tv
+ end
+ end
end
end
local lookups = resources.lookups
diff --git a/tex/context/base/font-otx.lua b/tex/context/base/font-otx.lua
index b7d2ae0bc..dc0469e39 100644
--- a/tex/context/base/font-otx.lua
+++ b/tex/context/base/font-otx.lua
@@ -37,13 +37,12 @@ local getfield = nuts.getfield
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
-local getattr = nuts.getattr
+local getprop = nuts.getprop
+local setprop = nuts.setprop
local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
local getchar = nuts.getchar
-local setattr = nuts.setattr
-
local traverse_id = nuts.traverse_id
local traverse_node_list = nuts.traverse
local end_of_math = nuts.end_of_math
@@ -124,34 +123,34 @@ function analyzers.setstate(head,font) -- we can skip math
if d then
if d.class == "mark" then
done = true
- setattr(current,a_state,s_mark)
+ setprop(current,a_state,s_mark)
elseif useunicodemarks and categories[char] == "mn" then
done = true
- setattr(current,a_state,s_mark)
+ setprop(current,a_state,s_mark)
elseif n == 0 then
first, last, n = current, current, 1
- setattr(current,a_state,s_init)
+ setprop(current,a_state,s_init)
else
last, n = current, n+1
- setattr(current,a_state,s_medi)
+ setprop(current,a_state,s_medi)
end
else -- finish
if first and first == last then
- setattr(last,a_state,s_isol)
+ setprop(last,a_state,s_isol)
elseif last then
- setattr(last,a_state,s_fina)
+ setprop(last,a_state,s_fina)
end
first, last, n = nil, nil, 0
end
elseif id == disc_code then
-- always in the middle
- setattr(current,a_state,s_medi)
+ setprop(current,a_state,s_medi)
last = current
else -- finish
if first and first == last then
- setattr(last,a_state,s_isol)
+ setprop(last,a_state,s_isol)
elseif last then
- setattr(last,a_state,s_fina)
+ setprop(last,a_state,s_fina)
end
first, last, n = nil, nil, 0
if id == math_code then
@@ -161,9 +160,9 @@ function analyzers.setstate(head,font) -- we can skip math
current = getnext(current)
end
if first and first == last then
- setattr(last,a_state,s_isol)
+ setprop(last,a_state,s_isol)
elseif last then
- setattr(last,a_state,s_fina)
+ setprop(last,a_state,s_fina)
end
return head, done
end
@@ -279,92 +278,92 @@ function methods.arab(head,font,attr)
current = tonut(current)
while current do
local id = getid(current)
- if id == glyph_code and getfont(current) == font and getsubtype(current)<256 and not getattr(current,a_state) then
+ if id == glyph_code and getfont(current) == font and getsubtype(current)<256 and not getprop(current,a_state) then
done = true
local char = getchar(current)
local classifier = classifiers[char]
if not classifier then
if last then
if c_last == s_medi or c_last == s_fina then
- setattr(last,a_state,s_fina)
+ setprop(last,a_state,s_fina)
else
warning(last,"fina")
- setattr(last,a_state,s_error)
+ setprop(last,a_state,s_error)
end
first, last = nil, nil
elseif first then
if c_first == s_medi or c_first == s_fina then
- setattr(first,a_state,s_isol)
+ setprop(first,a_state,s_isol)
else
warning(first,"isol")
- setattr(first,a_state,s_error)
+ setprop(first,a_state,s_error)
end
first = nil
end
elseif classifier == s_mark then
- setattr(current,a_state,s_mark)
+ setprop(current,a_state,s_mark)
elseif classifier == s_isol then
if last then
if c_last == s_medi or c_last == s_fina then
- setattr(last,a_state,s_fina)
+ setprop(last,a_state,s_fina)
else
warning(last,"fina")
- setattr(last,a_state,s_error)
+ setprop(last,a_state,s_error)
end
first, last = nil, nil
elseif first then
if c_first == s_medi or c_first == s_fina then
- setattr(first,a_state,s_isol)
+ setprop(first,a_state,s_isol)
else
warning(first,"isol")
- setattr(first,a_state,s_error)
+ setprop(first,a_state,s_error)
end
first = nil
end
- setattr(current,a_state,s_isol)
+ setprop(current,a_state,s_isol)
elseif classifier == s_medi then
if first then
last = current
c_last = classifier
- setattr(current,a_state,s_medi)
+ setprop(current,a_state,s_medi)
else
- setattr(current,a_state,s_init)
+ setprop(current,a_state,s_init)
first = current
c_first = classifier
end
elseif classifier == s_fina then
if last then
- if getattr(last,a_state) ~= s_init then
- setattr(last,a_state,s_medi)
+ if getprop(last,a_state) ~= s_init then
+ setprop(last,a_state,s_medi)
end
- setattr(current,a_state,s_fina)
+ setprop(current,a_state,s_fina)
first, last = nil, nil
elseif first then
- -- if getattr(first,a_state) ~= s_init then
+ -- if getprop(first,a_state) ~= s_init then
-- -- needs checking
- -- setattr(first,a_state,s_medi)
+ -- setprop(first,a_state,s_medi)
-- end
- setattr(current,a_state,s_fina)
+ setprop(current,a_state,s_fina)
first = nil
else
- setattr(current,a_state,s_isol)
+ setprop(current,a_state,s_isol)
end
else -- classifier == s_rest
- setattr(current,a_state,s_rest)
+ setprop(current,a_state,s_rest)
if last then
if c_last == s_medi or c_last == s_fina then
- setattr(last,a_state,s_fina)
+ setprop(last,a_state,s_fina)
else
warning(last,"fina")
- setattr(last,a_state,s_error)
+ setprop(last,a_state,s_error)
end
first, last = nil, nil
elseif first then
if c_first == s_medi or c_first == s_fina then
- setattr(first,a_state,s_isol)
+ setprop(first,a_state,s_isol)
else
warning(first,"isol")
- setattr(first,a_state,s_error)
+ setprop(first,a_state,s_error)
end
first = nil
end
@@ -372,18 +371,18 @@ function methods.arab(head,font,attr)
else
if last then
if c_last == s_medi or c_last == s_fina then
- setattr(last,a_state,s_fina)
+ setprop(last,a_state,s_fina)
else
warning(last,"fina")
- setattr(last,a_state,s_error)
+ setprop(last,a_state,s_error)
end
first, last = nil, nil
elseif first then
if c_first == s_medi or c_first == s_fina then
- setattr(first,a_state,s_isol)
+ setprop(first,a_state,s_isol)
else
warning(first,"isol")
- setattr(first,a_state,s_error)
+ setprop(first,a_state,s_error)
end
first = nil
end
@@ -395,17 +394,17 @@ function methods.arab(head,font,attr)
end
if last then
if c_last == s_medi or c_last == s_fina then
- setattr(last,a_state,s_fina)
+ setprop(last,a_state,s_fina)
else
warning(last,"fina")
- setattr(last,a_state,s_error)
+ setprop(last,a_state,s_error)
end
elseif first then
if c_first == s_medi or c_first == s_fina then
- setattr(first,a_state,s_isol)
+ setprop(first,a_state,s_isol)
else
warning(first,"isol")
- setattr(first,a_state,s_error)
+ setprop(first,a_state,s_error)
end
end
return head, done
diff --git a/tex/context/base/font-sel.lua b/tex/context/base/font-sel.lua
index 2881917eb..86300c2db 100644
--- a/tex/context/base/font-sel.lua
+++ b/tex/context/base/font-sel.lua
@@ -174,28 +174,58 @@ local names = {
["heavyitalic"] = { "heavyitalic" },
},
["default"] = { -- weight, width, italic
- ["thin"] = { weight = { 100, 200, 300, 400, 500 }, width = 5, italic = false },
- ["extralight"] = { weight = { 200, 100, 300, 400, 500 }, width = 5, italic = false },
- ["light"] = { weight = { 300, 200, 100, 400, 500 }, width = 5, italic = false },
- ["regular"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = false },
- ["italic"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = true },
- ["medium"] = { weight = { 500, 400, 300, 200, 100 }, width = 5, italic = false },
- ["demibold"] = { weight = { 600, 700, 800, 900 }, width = 5, italic = false },
- ["bold"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = false },
- ["bolditalic"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = true },
- ["smallcaps"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = false },
- ["heavy"] = { weight = { 800, 900, 700, 600 }, width = 5, italic = false },
- ["black"] = { weight = { 900, 800, 700, 600 }, width = 5, italic = false },
+ ["thin"] = { weight = { 100, 200, 300, 400, 500 }, width = 5, italic = false },
+ ["thinitalic"] = { weight = { 100, 200, 300, 400, 500 }, width = 5, italic = true },
+ ["extralight"] = { weight = { 200, 100, 300, 400, 500 }, width = 5, italic = false },
+ ["extralightitalic"] = { weight = { 200, 100, 300, 400, 500 }, width = 5, italic = true },
+ ["light"] = { weight = { 300, 200, 100, 400, 500 }, width = 5, italic = false },
+ ["lightitalic"] = { weight = { 300, 200, 100, 400, 500 }, width = 5, italic = true },
+ ["regular"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = false },
+ ["italic"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = true },
+ ["medium"] = { weight = { 500, 400, 300, 200, 100 }, width = 5, italic = false },
+ ["mediumitalic"] = { weight = { 500, 400, 300, 200, 100 }, width = 5, italic = true },
+ ["demibold"] = { weight = { 600, 700, 800, 900 }, width = 5, italic = false },
+ ["demibolditalic"] = { weight = { 600, 700, 800, 900 }, width = 5, italic = true },
+ ["bold"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = false },
+ ["bolditalic"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = true },
+ ["extrabold"] = { weight = { 800, 900, 700, 600 }, width = 5, italic = false },
+ ["extrabolditalic"] = { weight = { 800, 900, 700, 600 }, width = 5, italic = true },
+ ["heavy"] = { weight = { 900, 800, 700, 600 }, width = 5, italic = false },
+ ["heavyitalic"] = { weight = { 900, 800, 700, 600 }, width = 5, italic = true },
}
}
-names.simplefonts.slanted = names.simplefonts.italic
-names.simplefonts.boldslanted = names.simplefonts.bolditalic
+-- simplefonts synonyms
-names.default.normal = names.default.regular
-names.default.slanted = names.default.italic
-names.default.semibold = names.default.demibold
-names.default.boldslanted = names.default.bolditalic
+names.simplefonts.slanted = names.simplefonts.italic
+names.simplefonts.boldslanted = names.simplefonts.bolditalic
+
+-- default synonyms
+
+names.default.ultralight = names.default.extralight
+names.default.semibold = names.default.demibold
+names.default.ultrabold = names.default.extrabold
+names.default.black = names.default.heavy
+
+names.default.ultralightitalic = names.default.extralightitalic
+names.default.semibolditalic = names.default.demibolditalic
+names.default.ultrabolditalic = names.default.extrabolditalic
+names.default.blackitalic = names.default.heavyitalic
+
+names.default.thinslanted = names.default.thinitalic
+names.default.extralightslanted = names.default.extralightitalic
+names.default.ultralightslanted = names.default.extralightitalic
+names.default.lightslanted = names.default.lightitalic
+names.default.slanted = names.default.italic
+names.default.demiboldslanted = names.default.demibolditalic
+names.default.semiboldslanted = names.default.demibolditalic
+names.default.boldslanted = names.default.bolditalic
+names.default.extraboldslanted = names.default.extrabolditalic
+names.default.ultraboldslanted = names.default.extrabolditalic
+names.default.heavyslanted = names.default.heavyitalic
+names.default.blackslanted = names.default.heavyitalic
+
+names.default.smallcaps = names.default.regular
local mathsettings = {
["asanamath"] = {
@@ -494,7 +524,7 @@ local function definefontsynonym(data,alternative,index,fallback)
end
for _, entry in next, fontdata do
local designsize = entry["designsize"] or 100
- if designsize == 100 or designsize == 120 or designsize == 0 or #fontdata == 1 then
+ if designsize == 100 or designsize == 110 or designsize == 120 or designsize == 0 or #fontdata == 1 then
local filepath, filename = splitbase(entry["filename"])
registerdesignsizes( fontfile, "default", filename )
break
@@ -600,7 +630,7 @@ local function definemathfontfallback(data,alternative,index)
for _, entry in next, fontdata do
local filename = entry["filename"]
local designsize = entry["designsize"] or 100
- if designsize == 100 or designsize == 120 or designsize == 0 or #fontdata == 1 then
+ if designsize == 100 or designsize == 110 or designsize == 120 or designsize == 0 or #fontdata == 1 then
context.definefontfallback( { fallback }, { formatters["file:%s*%s"](filename,features) }, { range }, { rscale = rscale, check = check, force = force, offset = offset } )
break
end
diff --git a/tex/context/base/font-sel.mkvi b/tex/context/base/font-sel.mkvi
index 3d4dc6807..0b1d10c51 100644
--- a/tex/context/base/font-sel.mkvi
+++ b/tex/context/base/font-sel.mkvi
@@ -1,6 +1,6 @@
%D \module
%D [ file=font-sel,
-%D version=2013.10.19,
+%D version=2014.03.10,
%D title=\CONTEXT\ User Module,
%D subtitle=Selectfont,
%D author=Wolfgang Schuster,
@@ -115,11 +115,18 @@
% unknown preset
\fi}
-\definefontfamilypreset [range:chinese] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,bopomofo,bopomofoextended}]
-\definefontfamilypreset [range:japanese] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,hiragana,katakana}]
-\definefontfamilypreset [range:korean] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,hangulcompatibilityjamo,hanguljamo,hanguljamoextendeda,hanguljamoextendedb,hangulsyllables}]
-\definefontfamilypreset [range:cyrillic] [\c!range={cyrillic,cyrillicextendeda,cyrillicextendedb,cyrillicsupplement}]
-\definefontfamilypreset [range:greek] [\c!range={greekandcoptic,greekextended,ancientgreeknumbers}]
+%definefontfamilypreset [range:chinese] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,bopomofo,bopomofoextended}]
+%definefontfamilypreset [range:japanese] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,hiragana,katakana}]
+%definefontfamilypreset [range:korean] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,hangulcompatibilityjamo,hanguljamo,hanguljamoextendeda,hanguljamoextendedb,hangulsyllables}]
+%definefontfamilypreset [range:cyrillic] [\c!range={cyrillic,cyrillicextendeda,cyrillicextendedb,cyrillicsupplement}]
+%definefontfamilypreset [range:greek] [\c!range={greekandcoptic,greekextended,ancientgreeknumbers}]
+
+\definefontfamilypreset [range:chinese] [\c!range={0x02E80-0x02EFF,0x03000-0x031EF,0x03300-0x09FFF,0x0F900-0x0FFEF,0x20000-0x2A6DF,0x2F800-0x2FA1F,0x03100-0x0312F,0x031A0-0x031BF}]
+\definefontfamilypreset [range:japanese] [\c!range={0x02E80-0x02EFF,0x03000-0x031EF,0x03300-0x09FFF,0x0F900-0x0FFEF,0x20000-0x2A6DF,0x2F800-0x2FA1F,0x03040-0x0309F,0x030A0-0x030FF}]
+\definefontfamilypreset [range:korean] [\c!range={0x02E80-0x02EFF,0x03000-0x031EF,0x03300-0x09FFF,0x0F900-0x0FFEF,0x20000-0x2A6DF,0x2F800-0x2FA1F,0x01100-0x011FF,0x03130-0x0318F,0x0A960-0x0D7FF}]
+\definefontfamilypreset [range:cyrillic] [\c!range={0x00400-0x0052F,0x02DE0-0x02DFF,0x0A640-0x0A69F}]
+\definefontfamilypreset [range:greek] [\c!range={0x00370-0x003FF,0x01F00-0x01FFF,0x10140-0x1018F}]
+\definefontfamilypreset [range:hebrew] [\c!range={0x00590-0x005FF,0x0FB00-0x0FB4F}]
\definefontfamilypreset [math:digitsnormal] [\c!range=digitsnormal]
\definefontfamilypreset [math:digitsbold] [\c!range=digitsnormal,\c!offset=digitsbold,\s!tf=style:bold]
@@ -219,13 +226,13 @@
%D \stoptyping
%D
%D When a document contains different languages and the global font lacks some characters
-%D for one language, one could set a different font where these charcters are taken from.
+%D for one language, one could set a different font where these characters are taken from.
%D This fallback font (there can be more than one for a certain style) could be set with
%D the \tex{definefallbackfamily} command which takes the same argument as
%D the \tex{definefontfamily} command.
%D
%D \starttyping
-%D \definefallbackfamily [mainface] [serif] [DejaVu Serif] [range=cyrillic,force=yes]
+%D \definefallbackfamily [mainface] [serif] [DejaVu Serif] [range=cyrillic]
%D \definefontfamily [mainface] [serif] [TeX Gyre Pagella]
%D
%D \setupbodyfont[mainface]
@@ -364,4 +371,4 @@
\c!smallcapsfeatures=\s!smallcaps,
\c!style=\s!rm]
-\protect
+\protect \ No newline at end of file
diff --git a/tex/context/base/font-set.mkvi b/tex/context/base/font-set.mkvi
index 0e2058c18..f94d6c86e 100644
--- a/tex/context/base/font-set.mkvi
+++ b/tex/context/base/font-set.mkvi
@@ -39,27 +39,36 @@
% \enablemode[lmmath]
+\let\m_font_fallback_name\empty
+
\def\font_preloads_reset_nullfont % this is needed because some macro packages (tikz) misuse \nullfont
{\dorecurse\plusseven{\fontdimen\recurselevel\nullfont\zeropoint}% keep en eye on this as:
\ctxcommand{resetnullfont()}% in luatex 0.70 this will also do the previous
\globallet\font_preloads_reset_nullfont\relax}
+\def\font_preload_check_mode
+ {\doifmodeelse{lmmath}
+ {\def\m_font_fallback_name{modern-designsize-virtual}}% this will stay
+ {\def\m_font_fallback_name{modern-designsize}}% % this might become 'modern'
+ \glet\font_preload_check_mode\relax}
+
\def\font_preload_default_fonts
{\font_preloads_reset
- \doifmodeelse{lmmath}
- {\setupbodyfont[modern-designsize-virtual,\fontstyle,\fontbody]}% this will stay
- {\setupbodyfont[modern-designsize,\fontstyle,\fontbody]}% % this might become 'modern'
- \showmessage\m!fonts6{fallback modern \fontstyle\normalspace\normalizedbodyfontsize}}
+ \font_preload_check_mode
+ \setupbodyfont[\m_font_fallback_name,\fontstyle,\fontbody]%
+ \showmessage\m!fonts6{fallback \m_font_fallback_name\space \fontstyle\normalspace\normalizedbodyfontsize}}
\def\font_preload_default_fonts_mm
- {\writestatus\m!fonts{preloading latin modern fonts (math)}%
- \definetypeface[\fontclass][\s!mm][\s!math][modern][\s!default]%
- \showmessage\m!fonts6{fallback modern mm \normalizedbodyfontsize}}
+ {\font_preload_check_mode
+ \writestatus\m!fonts{preloading \m_font_fallback_name\space (math)}%
+ \definetypeface[\fontclass][\s!mm][\s!math][\m_font_fallback_name][\s!default]%
+ \showmessage\m!fonts6{fallback \m_font_fallback_name\space mm \normalizedbodyfontsize}}
\def\font_preload_default_fonts_tt
- {\writestatus\m!fonts{preloading latin modern fonts (mono)}%
- \definetypeface[\fontclass][\s!tt][\s!mono][modern][\s!default]%
- \showmessage\m!fonts6{fallback modern tt \normalizedbodyfontsize}}
+ {\font_preload_check_mode
+ \writestatus\m!fonts{preloading \m_font_fallback_name\space (mono)}%
+ \definetypeface[\fontclass][\s!tt][\s!mono][\m_font_fallback_name][\s!default]%
+ \showmessage\m!fonts6{fallback \m_font_fallback_name\space tt \normalizedbodyfontsize}}
\def\font_preloads_reset
{\glet\font_preload_default_fonts \relax
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua
index 6296f088e..18ed46a2f 100644
--- a/tex/context/base/font-syn.lua
+++ b/tex/context/base/font-syn.lua
@@ -396,7 +396,7 @@ function filters.afm(name)
if key and #key > 0 then
hash[lower(key)] = value
end
- if find(line,"StartCharMetrics") then
+ if find(line,"StartCharMetrics",1,true) then
break
end
end
@@ -1801,7 +1801,7 @@ local lastlookups, lastpattern = { }, ""
-- local lookups = specifications
-- if name then
-- lookups = families[name]
--- elseif not find(pattern,"=") then
+-- elseif not find(pattern,"=",1,true) then
-- lookups = families[pattern]
-- end
-- if trace_names then
@@ -1810,7 +1810,7 @@ local lastlookups, lastpattern = { }, ""
-- if lookups then
-- for key, value in gmatch(pattern,"([^=,]+)=([^=,]+)") do
-- local t, n = { }, 0
--- if find(value,"*") then
+-- if find(value,"*",1,true) then
-- value = topattern(value)
-- for i=1,#lookups do
-- local s = lookups[i]
@@ -1843,7 +1843,7 @@ local lastlookups, lastpattern = { }, ""
local function look_them_up(lookups,specification)
for key, value in next, specification do
local t, n = { }, 0
- if find(value,"*") then
+ if find(value,"*",1,true) then
value = topattern(value)
for i=1,#lookups do
local s = lookups[i]
@@ -1906,7 +1906,7 @@ function names.lookup(pattern,name,reload) -- todo: find
lastpattern = false
lastlookups = lookups or { }
elseif lastpattern ~= pattern then
- local lookups = first_look(name or (not find(pattern,"=") and pattern),reload)
+ local lookups = first_look(name or (not find(pattern,"=",1,true) and pattern),reload)
if lookups then
if trace_names then
report_names("starting with %s lookups for %a",#lookups,pattern)
diff --git a/tex/context/base/font-var.mkvi b/tex/context/base/font-var.mkvi
index e50c2bad4..fb60b711c 100644
--- a/tex/context/base/font-var.mkvi
+++ b/tex/context/base/font-var.mkvi
@@ -50,4 +50,7 @@
\let\fontsize \defaultfontsize
\let\fontface \!!zerocount
+% we can use an indirect mapping for fontclasses (map string onto numbers) and indeed this
+% is somewhat more efficient but also makes the code messy ... maybe some day ...
+
\protect \endinput
diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua
index b658b7c75..257212060 100644
--- a/tex/context/base/l-dir.lua
+++ b/tex/context/base/l-dir.lua
@@ -27,7 +27,7 @@ local currentdir = lfs.currentdir
local chdir = lfs.chdir
local mkdir = lfs.mkdir
-local onwindows = os.type == "windows" or find(os.getenv("PATH"),";")
+local onwindows = os.type == "windows" or find(os.getenv("PATH"),";",1,true)
-- in case we load outside luatex
@@ -189,7 +189,7 @@ local function glob(str,t)
local split = lpegmatch(pattern,str) -- we could use the file splitter
if split then
local root, path, base = split[1], split[2], split[3]
- local recurse = find(base,"%*%*")
+ local recurse = find(base,"**",1,true) -- find(base,"%*%*")
local start = root .. path
local result = lpegmatch(filter,start .. base)
globpattern(start,result,recurse,t)
@@ -215,7 +215,7 @@ local function glob(str,t)
local t = t or { }
local action = action or function(name) t[#t+1] = name end
local root, path, base = split[1], split[2], split[3]
- local recurse = find(base,"%*%*")
+ local recurse = find(base,"**",1,true) -- find(base,"%*%*")
local start = root .. path
local result = lpegmatch(filter,start .. base)
globpattern(start,result,recurse,action)
@@ -296,7 +296,6 @@ if onwindows then
str = ""
for i=1,n do
local s = select(i,...)
- local s = select(i,...)
if s == "" then
-- skip
elseif str == "" then
diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua
index 52f166af9..020e811bf 100644
--- a/tex/context/base/l-io.lua
+++ b/tex/context/base/l-io.lua
@@ -12,7 +12,7 @@ local concat = table.concat
local floor = math.floor
local type = type
-if string.find(os.getenv("PATH"),";") then
+if string.find(os.getenv("PATH"),";",1,true) then
io.fileseparator, io.pathseparator = "\\", ";"
else
io.fileseparator, io.pathseparator = "/" , ":"
diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua
index bfafa4f95..1dff79cd3 100644
--- a/tex/context/base/l-os.lua
+++ b/tex/context/base/l-os.lua
@@ -137,7 +137,7 @@ function os.resultof(command)
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";") then
+ if find(os.getenv("PATH"),";",1,true) then
io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "mswin"
else
io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix"
@@ -236,7 +236,7 @@ elseif os.type == "windows" then
function resolvers.platform(t,k)
local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or ""
- if find(architecture,"AMD64") then
+ if find(architecture,"AMD64",1,true) then
-- platform = "mswin-64"
platform = "win64"
else
@@ -252,9 +252,9 @@ elseif name == "linux" then
function resolvers.platform(t,k)
-- we sometimes have HOSTTYPE set so let's check that first
local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
- if find(architecture,"x86_64") then
+ if find(architecture,"x86_64",1,true) then
platform = "linux-64"
- elseif find(architecture,"ppc") then
+ elseif find(architecture,"ppc",1,true) then
platform = "linux-ppc"
else
platform = "linux"
@@ -285,9 +285,9 @@ elseif name == "macosx" then
if architecture == "" then
-- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n")
platform = "osx-intel"
- elseif find(architecture,"i386") then
+ elseif find(architecture,"i386",1,true) then
platform = "osx-intel"
- elseif find(architecture,"x86_64") then
+ elseif find(architecture,"x86_64",1,true) then
platform = "osx-64"
else
platform = "osx-ppc"
@@ -301,7 +301,7 @@ elseif name == "sunos" then
function resolvers.platform(t,k)
local platform, architecture = "", os.resultof("uname -m") or ""
- if find(architecture,"sparc") then
+ if find(architecture,"sparc",1,true) then
platform = "solaris-sparc"
else -- if architecture == 'i86pc'
platform = "solaris-intel"
@@ -315,7 +315,7 @@ elseif name == "freebsd" then
function resolvers.platform(t,k)
local platform, architecture = "", os.resultof("uname -m") or ""
- if find(architecture,"amd64") then
+ if find(architecture,"amd64",1,true) then
platform = "freebsd-amd64"
else
platform = "freebsd"
@@ -330,7 +330,7 @@ elseif name == "kfreebsd" then
function resolvers.platform(t,k)
-- we sometimes have HOSTTYPE set so let's check that first
local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
- if find(architecture,"x86_64") then
+ if find(architecture,"x86_64",1,true) then
platform = "kfreebsd-amd64"
else
platform = "kfreebsd-i386"
@@ -356,7 +356,7 @@ else
end
function resolvers.bits(t,k)
- local bits = find(os.platform,"64") and 64 or 32
+ local bits = find(os.platform,"64",1,true) and 64 or 32
os.bits = bits
return bits
end
diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua
index c318c57bb..d231830ed 100644
--- a/tex/context/base/l-table.lua
+++ b/tex/context/base/l-table.lua
@@ -88,6 +88,38 @@ local function sortedkeys(tab)
end
end
+local function sortedhashonly(tab)
+ if tab then
+ local srt, s = { }, 0
+ for key,_ in next, tab do
+ if type(key) == "string" then
+ s = s + 1
+ srt[s] = key
+ end
+ end
+ sort(srt)
+ return srt
+ else
+ return { }
+ end
+end
+
+local function sortedindexonly(tab)
+ if tab then
+ local srt, s = { }, 0
+ for key,_ in next, tab do
+ if type(key) == "number" then
+ s = s + 1
+ srt[s] = key
+ end
+ end
+ sort(srt)
+ return srt
+ else
+ return { }
+ end
+end
+
local function sortedhashkeys(tab,cmp) -- fast one
if tab then
local srt, s = { }, 0
@@ -114,8 +146,10 @@ function table.allkeys(t)
return sortedkeys(keys)
end
-table.sortedkeys = sortedkeys
-table.sortedhashkeys = sortedhashkeys
+table.sortedkeys = sortedkeys
+table.sortedhashonly = sortedhashonly
+table.sortedindexonly = sortedindexonly
+table.sortedhashkeys = sortedhashkeys
local function nothing() end
diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua
index 6601a4c62..be61f3d73 100644
--- a/tex/context/base/l-unicode.lua
+++ b/tex/context/base/l-unicode.lua
@@ -6,7 +6,14 @@ if not modules then modules = { } end modules ['l-unicode'] = {
license = "see context related readme files"
}
--- this module will be reorganized
+-- in lua 5.3:
+
+-- utf8.char(···) : concatinated
+-- utf8.charpatt : "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
+-- utf8.codes(s) : for p, c in utf8.codes(s) do body end
+-- utf8.codepoint(s [, i [, j]])
+-- utf8.len(s [, i])
+-- utf8.offset(s, n [, i])
-- todo: utf.sub replacement (used in syst-aux)
-- we put these in the utf namespace:
diff --git a/tex/context/base/lang-def.mkiv b/tex/context/base/lang-def.mkiv
index 18f572039..5c1d6de9c 100644
--- a/tex/context/base/lang-def.mkiv
+++ b/tex/context/base/lang-def.mkiv
@@ -634,6 +634,10 @@
\c!rightquotation=\upperrightdoubleninequote,
\c!date={\v!year,\space,\v!month,\space,\v!day}]
+\installlanguage[\s!pt-br][\c!default=\s!pt] % Brazil
+\installlanguage[\s!es-es][\c!default=\s!es] % Spain
+\installlanguage[\s!es-la][\c!default=\s!es] % Latin America
+
\installlanguage
[\s!ro]
[\c!spacing=\v!packed,
diff --git a/tex/context/base/lang-ini.mkiv b/tex/context/base/lang-ini.mkiv
index 17d00033b..4ed7839bd 100644
--- a/tex/context/base/lang-ini.mkiv
+++ b/tex/context/base/lang-ini.mkiv
@@ -479,7 +479,7 @@
\lang_basics_switch_asked}
\unexpanded\def\language
- {\doifnextoptionalelse\lang_basics_set_current\normallanguage}
+ {\doifnextoptionalcselse\lang_basics_set_current\normallanguage}
\newcount\mainlanguagenumber
@@ -505,7 +505,7 @@
\normallanguage\mainlanguagenumber
\to \everybeforepagebody
-%D New (see nomarking and nolist):
+%D Used at all?
\def\splitsequence#1#2%
{\doifelse{#1}\v!no{#2}{\doifelse{#1}\v!yes{\languageparameter\c!limittext}{#1}}}
diff --git a/tex/context/base/lang-lab.mkiv b/tex/context/base/lang-lab.mkiv
index 14d9d8594..7dcaaecb4 100644
--- a/tex/context/base/lang-lab.mkiv
+++ b/tex/context/base/lang-lab.mkiv
@@ -180,7 +180,7 @@
\grabuntil{stop#1text}\lang_labels_text_prefix_start_indeed}
\def\lang_labels_text_prefix_start_indeed#1% text (not special checking done here yet, only for long texts anyway)
- {\expandafter\edef\csname\??label\currenttextprefixclass:\currenttextprefixtag:\currenttextprefixname\endcsname{{\ctxlua{context(string.strip(\!!bs#1\!!es))}}\empty}}
+ {\expandafter\edef\csname\??label\currenttextprefixclass:\currenttextprefixtag:\currenttextprefixname\endcsname{{\ctxcommand{strip(\!!bs#1\!!es)}}\empty}}
\def\lang_labels_text_prefix_setup[#1][#2]%
{\ifsecondargument
diff --git a/tex/context/base/lang-rep.lua b/tex/context/base/lang-rep.lua
index be74d597a..02eb59f48 100644
--- a/tex/context/base/lang-rep.lua
+++ b/tex/context/base/lang-rep.lua
@@ -90,7 +90,7 @@ local function add(root,word,replacement)
-- for i=1,#newlist do
-- newlist[i] = utfbyte(newlist[i])
-- end
- local special = find(replacement,"{")
+ local special = find(replacement,"{",1,true)
local newlist = lpegmatch(splitter,replacement)
--
root[l].final = {
diff --git a/tex/context/base/lpdf-ano.lua b/tex/context/base/lpdf-ano.lua
index 3f0e718b3..45b0e8e9c 100644
--- a/tex/context/base/lpdf-ano.lua
+++ b/tex/context/base/lpdf-ano.lua
@@ -10,46 +10,62 @@ if not modules then modules = { } end modules ['lpdf-ano'] = {
-- todo: /AA << WC << ... >> >> : WillClose actions etc
-local next, tostring = next, tostring
-local rep, format = string.rep, string.format
+-- internal references are indicated by a number (and turned into aut:<number>)
+-- we only flush internal destinations that are referred
+
+local next, tostring, tonumber, rawget = next, tostring, tonumber, rawget
+local rep, format, find = string.rep, string.format, string.find
+local min = math.min
local lpegmatch = lpeg.match
local formatters = string.formatters
local backends, lpdf = backends, lpdf
-local trace_references = false trackers.register("references.references", function(v) trace_references = v end)
-local trace_destinations = false trackers.register("references.destinations", function(v) trace_destinations = v end)
-local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end)
+local trace_references = false trackers.register("references.references", function(v) trace_references = v end)
+local trace_destinations = false trackers.register("references.destinations", function(v) trace_destinations = v end)
+local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end)
-local report_reference = logs.reporter("backend","references")
-local report_destination = logs.reporter("backend","destinations")
-local report_bookmark = logs.reporter("backend","bookmarks")
+local report_reference = logs.reporter("backend","references")
+local report_destination = logs.reporter("backend","destinations")
+local report_bookmark = logs.reporter("backend","bookmarks")
local variables = interfaces.variables
local constants = interfaces.constants
+local factor = number.dimenfactors.bp
+
local settings_to_array = utilities.parsers.settings_to_array
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
local nodeinjections = backends.pdf.nodeinjections
local codeinjections = backends.pdf.codeinjections
local registrations = backends.pdf.registrations
+local getpos = codeinjections.getpos
+local gethpos = codeinjections.gethpos
+local getvpos = codeinjections.getvpos
+
local javascriptcode = interactions.javascripts.code
local references = structures.references
local bookmarks = structures.bookmarks
+local flaginternals = references.flaginternals
+local usedinternals = references.usedinternals
+
local runners = references.runners
local specials = references.specials
local handlers = references.handlers
local executers = references.executers
-local getinnermethod = references.getinnermethod
local nodepool = nodes.pool
-local pdfannotation_node = nodepool.pdfannotation
-local pdfdestination_node = nodepool.pdfdestination
-local latelua_node = nodepool.latelua
+----- pdfannotation_node = nodepool.pdfannotation
+----- pdfdestination_node = nodepool.pdfdestination
+----- latelua_node = nodepool.latelua
+local latelua_function_node = nodepool.lateluafunction -- still node ... todo
local texgetcount = tex.getcount
@@ -63,7 +79,12 @@ local pdfshareobjectreference = lpdf.shareobjectreference
local pdfreserveobject = lpdf.reserveobject
local pdfpagereference = lpdf.pagereference
local pdfdelayedobject = lpdf.delayedobject
-local pdfregisterannotation = lpdf.registerannotation
+local pdfregisterannotation = lpdf.registerannotation -- forward definition (for the moment)
+local pdfnull = lpdf.null
+local pdfaddtocatalog = lpdf.addtocatalog
+local pdfaddtonames = lpdf.addtonames
+local pdfaddtopageattributes = lpdf.addtopageattributes
+local pdfrectangle = lpdf.rectangle
-- todo: 3dview
@@ -81,28 +102,308 @@ local pdf_named = pdfconstant("Named")
local pdf_border = pdfarray { 0, 0, 0 }
-local cache = { }
+-- the used and flag code here is somewhat messy in the sense
+-- that it belongs in strc-ref but at the same time depends on
+-- the backend so we keep it here
-local function pagedestination(n) -- only cache fit
- if n > 0 then
- local pd = cache[n]
- if not pd then
- local a = pdfarray {
- pdfreference(pdfpagereference(n)),
- pdf_fit,
- }
- pd = pdfshareobjectreference(a)
- cache[n] = pd
+-- the caching is somewhat memory intense on the one hand but
+-- it saves many small temporary tables so it might pay off
+
+local destinationviews = { } -- prevent messages
+
+local pagedestinations = allocate()
+local pagereferences = allocate() -- annots are cached themselves
+
+setmetatableindex(pagedestinations, function(t,k)
+ k = tonumber(k)
+ local v = rawget(t,k)
+ if v then
+ -- report_reference("page number expected, got %s: %a",type(k),k)
+ return v
+ end
+ local v = k > 0 and pdfarray {
+ pdfreference(pdfpagereference(k)),
+ pdf_fit,
+ } or pdfnull()
+ t[k] = v
+ return v
+end)
+
+setmetatableindex(pagereferences,function(t,k)
+ k = tonumber(k)
+ local v = rawget(t,k)
+ if v then
+ return v
+ end
+ local v = pdfdictionary { -- can be cached
+ S = pdf_goto,
+ D = pagedestinations[k],
+ }
+ t[k] = v
+ return v
+end)
+
+lpdf.pagereferences = pagereferences -- table
+lpdf.pagedestinations = pagedestinations -- table
+
+local defaultdestination = pdfarray { 0, pdf_fit }
+
+-- fit is default (see lpdf-nod)
+
+local destinations = { } -- to be used soon
+
+local function pdfregisterdestination(name,reference)
+ local d = destinations[name]
+ if d then
+ report_destination("ignoring duplicate destination %a with reference %a",name,reference)
+ else
+ destinations[name] = reference
+ end
+end
+
+lpdf.registerdestination = pdfregisterdestination
+
+local maxslice = 32 -- could be made configureable ... 64 is also ok
+
+local function pdfnametree(destinations)
+ local slices = { }
+ local sorted = table.sortedkeys(destinations)
+ local size = #sorted
+
+ if size <= 1.5*maxslice then
+ maxslice = size
+ end
+
+ for i=1,size,maxslice do
+ local amount = min(i+maxslice-1,size)
+ local names = pdfarray { }
+ for j=i,amount do
+ local destination = sorted[j]
+ names[#names+1] = destination
+ names[#names+1] = pdfreference(destinations[destination])
+ end
+ local first = sorted[i]
+ local last = sorted[amount]
+ local limits = pdfarray {
+ first,
+ last,
+ }
+ local d = pdfdictionary {
+ Names = names,
+ Limits = limits,
+ }
+ slices[#slices+1] = {
+ reference = pdfreference(pdfflushobject(d)),
+ limits = limits,
+ }
+ end
+ local function collectkids(slices,first,last)
+ local k = pdfarray()
+ local d = pdfdictionary {
+ Kids = k,
+ Limits = pdfarray {
+ slices[first].limits[1],
+ slices[last ].limits[2],
+ },
+ }
+ for i=first,last do
+ k[#k+1] = slices[i].reference
+ end
+ return d
+ end
+ if #slices == 1 then
+ return slices[1].reference
+ else
+ while true do
+ if #slices > maxslice then
+ local temp = { }
+ local size = #slices
+ for i=1,size,maxslice do
+ local kids = collectkids(slices,i,min(i+maxslice-1,size))
+ temp[#temp+1] = {
+ reference = pdfreference(pdfflushobject(kids)),
+ limits = kids.Limits,
+ }
+ end
+ slices = temp
+ else
+ return pdfreference(pdfflushobject(collectkids(slices,1,#slices)))
+ end
end
- return pd
end
end
-lpdf.pagedestination = pagedestination
+local function pdfdestinationspecification()
+ if next(destinations) then -- safeguard
+ local r = pdfnametree(destinations)
+-- pdfaddtocatalog("Dests",r)
+ pdfaddtonames("Dests",r)
+ destinations = nil
+ end
+end
-local defaultdestination = pdfarray { 0, pdf_fit }
+lpdf.nametree = pdfnametree
+lpdf.destinationspecification = pdfdestinationspecification
+
+lpdf.registerdocumentfinalizer(pdfdestinationspecification,"collect destinations")
+
+-- todo
+
+local destinations = { }
+
+local f_xyz = formatters["<< /D [ %i 0 R /XYZ %0.3F %0.3F null ] >>"]
+local f_fit = formatters["<< /D [ %i 0 R /Fit ] >>"]
+local f_fitb = formatters["<< /D [ %i 0 R /FitB ] >>"]
+local f_fith = formatters["<< /D [ %i 0 R /FitH %0.3F ] >>"]
+local f_fitv = formatters["<< /D [ %i 0 R /FitV %0.3F ] >>"]
+local f_fitbh = formatters["<< /D [ %i 0 R /FitBH %0.3F ] >>"]
+local f_fitbv = formatters["<< /D [ %i 0 R /FitBV %0.3F ] >>"]
+local f_fitr = formatters["<< /D [ %i 0 R /FitR [%0.3F %0.3F %0.3F %0.3F ] ] >>"]
+
+-- nicer is to create dictionaries and set properties but overkill
+--
+-- local d_xyz = pdfdictionary {
+-- D = pdfarray {
+-- pdfreference(0),
+-- pdfconstant("XYZ"),
+-- 0,
+-- 0,
+-- pdfnull(),
+-- }
+-- }
+--
+-- local function xyz(r,width,height,depth) -- same
+-- local llx, lly = pdfrectangle(width,height,depth)
+-- d_xyz.D[1][1] = r
+-- d_xyz.D[3] = llx
+-- d_xyz.D[4] = lly
+-- return d_xyz()
+-- end
+
+local destinationactions = {
+ xyz = function(r,width,height,depth)
+ local llx, lly = pdfrectangle(width,height,depth)
+ return f_xyz(r,llx,lly)
+ end,
+ fitr = function(r,width,height,depth)
+ return f_fitr(r,pdfrectangle(width,height,depth))
+ end,
+ fith = function(r) return f_fith (r,getvpos*factor) end,
+ fitbh = function(r) return f_fitbh(r,getvpos*factor) end,
+ fitv = function(r) return f_fitv (r,gethpos*factor) end,
+ fitbv = function(r) return f_fitbv(r,gethpos*factor) end,
+ fit = f_fit,
+ fitb = f_fitb,
+}
+
+local mapping = {
+ xyz = "xyz", [variables.standard] = "xyz",
+ fitr = "fitr", [variables.frame] = "fitr",
+ fith = "fith", [variables.width] = "fith",
+ fitbh = "fitbh", [variables.minwidth] = "fitbh",
+ fitv = "fitv", [variables.height] = "fitv",
+ fitbv = "fitbv", [variables.minheight] = "fitbv",
+ fit = "fit", [variables.fit] = "fit",
+ fitb = "fitb",
+}
+
+local defaultaction = destinationactions.fit
+
+-- A complication is that we need to use named destinations when we have views so we
+-- end up with a mix. A previous versions just output multiple destinations but not
+-- that we noved all to here we can be more sparse.
+
+local pagedestinations = { }
+
+table.setmetatableindex(pagedestinations,function(t,k)
+ local v = pdfdelayedobject(f_fit(k))
+ t[k] = v
+ return v
+end)
+
+local function flushdestination(width,height,depth,names,view)
+ local r = pdfpagereference(texgetcount("realpageno"))
+ if view == "fit" then
+ r = pagedestinations[r]
+ else
+ local action = view and destinationactions[view] or defaultaction
+ r = pdfdelayedobject(action(r,width,height,depth))
+ end
+ for n=1,#names do
+ local name = names[n]
+ if name then
+ pdfregisterdestination(name,r)
+ end
+ end
+end
+
+function nodeinjections.destination(width,height,depth,names,view)
+ -- todo check if begin end node / was comment
+ if view then
+ view = mapping[view] or "fit"
+ else
+ view = "fit"
+ end
+ if trace_destinations then
+ report_destination("width %p, height %p, depth %p, names %|t, view %a",width,height,depth,names,view)
+ end
+ local noview = view ~= "fit"
+ local doview = false
+ for n=1,#names do
+ local name = names[n]
+ if not destinationviews[name] then
+ destinationviews[name] = not noview
+ if type(name) == "number" then
+ local u = usedinternals[name]
+ if u then
+ if not noview then
+ flaginternals[name] = view
+ end
+ if references.innermethod ~= "auto" or u ~= true then
+ names[n] = "aut:" .. name
+ doview = true
+ else
+ names[n] = false
+ end
+ else
+ names[n] = false
+ end
+ else
+ doview = true
+ end
+ end
+ end
+ if doview then
+ return latelua_function_node(function() flushdestination(width,height,depth,names,view) end)
+ end
+end
+
+local function somedestination(destination,page)
+ if type(destination) == "number" then
+ flaginternals[destination] = true
+ if references.innermethod == "auto" and usedinternals[destination] == true then
+ return pagereferences[page]
+ else
+ return pdfdictionary { -- can be cached
+ S = pdf_goto,
+ D = "aut:" .. destination,
+ }
+ end
+ else
+ if references.innermethod == "auto" and destinationviews[destination] == true then
+ return pagereferences[page] -- we use a simple one but the destination is there
+ else
+ return pdfdictionary { -- can be cached
+ S = pdf_goto,
+ D = destination,
+ }
+ end
+ end
+end
+
+-- annotations
-local function link(url,filename,destination,page,actions)
+local function pdflink(url,filename,destination,page,actions)
if filename and filename ~= "" then
if file.basename(filename) == tex.jobname then
return false
@@ -137,30 +438,12 @@ local function link(url,filename,destination,page,actions)
NewWindow = (actions.newwindow and true) or nil,
}
elseif destination and destination ~= "" then
- return pdfdictionary { -- can be cached
- S = pdf_goto,
- D = destination,
- }
- else
- local p = tonumber(page)
- if p and p > 0 then
- return pdfdictionary { -- can be cached
- S = pdf_goto,
- D = pdfarray {
- pdfreference(pdfpagereference(p)),
- pdf_fit,
- }
- }
- elseif trace_references then
- report_reference("invalid page reference %a",page)
- end
+ return somedestination(destination,page)
end
- return false
+ return pagereferences[page] -- we use a simple one but the destination is there
end
-lpdf.link = link
-
-function lpdf.launch(program,parameters)
+local function pdflaunch(program,parameters)
if program and program ~= "" then
local d = pdfdictionary {
S = pdf_launch,
@@ -174,7 +457,7 @@ function lpdf.launch(program,parameters)
end
end
-function lpdf.javascript(name,arguments)
+local function pdfjavascript(name,arguments)
local script = javascriptcode(name,arguments) -- make into object (hash)
if script then
return pdfdictionary {
@@ -184,6 +467,10 @@ function lpdf.javascript(name,arguments)
end
end
+lpdf.link = pdflink
+lpdf.launch = pdflaunch
+lpdf.javascript = pdfjavascript
+
local function pdfaction(actions)
local nofactions = #actions
if nofactions > 0 then
@@ -231,144 +518,134 @@ function codeinjections.prerollreference(actions) -- share can become option
end
end
-local function use_normal_annotations()
-
- local function reference(width,height,depth,prerolled) -- keep this one
- if prerolled then
- if trace_references then
- report_reference("width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled)
- end
- return pdfannotation_node(width,height,depth,prerolled)
- end
- end
-
- local function finishreference()
- end
-
- return reference, finishreference
-
-end
+-- local function use_normal_annotations()
+--
+-- local function reference(width,height,depth,prerolled) -- keep this one
+-- if prerolled then
+-- if trace_references then
+-- report_reference("width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled)
+-- end
+-- return pdfannotation_node(width,height,depth,prerolled)
+-- end
+-- end
+--
+-- local function finishreference()
+-- end
+--
+-- return reference, finishreference
+--
+-- end
-- eventually we can do this for special refs only
-local hashed, nofunique, nofused = { }, 0, 0
-
-local f_annot = formatters["<< /Type /Annot %s /Rect [%0.3f %0.3f %0.3f %0.3f] >>"]
-local f_bpnf = formatters["_bpnf_(%s,%s,%s,'%s')"]
+local hashed = { }
+local nofunique = 0
+local nofused = 0
+local nofspecial = 0
+local share = true
-local function use_shared_annotations()
+local f_annot = formatters["<< /Type /Annot %s /Rect [%0.3F %0.3F %0.3F %0.3F] >>"]
- local factor = number.dimenfactors.bp
+directives.register("refences.sharelinks", function(v) share = v end)
- local function finishreference(width,height,depth,prerolled) -- %0.2f looks okay enough (no scaling anyway)
- local h, v = pdf.h, pdf.v
- local llx, lly = h*factor, (v - depth)*factor
- local urx, ury = (h + width)*factor, (v + height)*factor
- local annot = f_annot(prerolled,llx,lly,urx,ury)
- local n = hashed[annot]
- if not n then
- n = pdfdelayedobject(annot)
- hashed[annot] = n
- nofunique = nofunique + 1
- end
- nofused = nofused + 1
- pdfregisterannotation(n)
+table.setmetatableindex(hashed,function(t,k)
+ local v = pdfdelayedobject(k)
+ if share then
+ t[k] = v
end
+ nofunique = nofunique + 1
+ return v
+end)
+
+local function finishreference(width,height,depth,prerolled) -- %0.2f looks okay enough (no scaling anyway)
+ local annot = hashed[f_annot(prerolled,pdfrectangle(width,height,depth))]
+ nofused = nofused + 1
+ return pdfregisterannotation(annot)
+end
- _bpnf_ = finishreference
-
- local function reference(width,height,depth,prerolled)
- if prerolled then
- if trace_references then
- report_reference("width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled)
- end
- local luacode = f_bpnf(width,height,depth,prerolled)
- return latelua_node(luacode)
- end
+local function finishannotation(width,height,depth,prerolled,r)
+ local annot = f_annot(prerolled,pdfrectangle(width,height,depth))
+ if r then
+ pdfdelayedobject(annot,r)
+ else
+ r = pdfdelayedobject(annot)
end
+ nofspecial = nofspecial + 1
+ return pdfregisterannotation(r)
+end
- statistics.register("pdf annotations", function()
- if nofused > 0 then
- return format("%s embedded, %s unique",nofused,nofunique)
- else
- return nil
+function nodeinjections.reference(width,height,depth,prerolled)
+ if prerolled then
+ if trace_references then
+ report_reference("link: width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled)
end
- end)
-
-
- return reference, finishreference
-
+ return latelua_function_node(function() finishreference(width,height,depth,prerolled) end)
+ end
end
-local lln = latelua_node() if node.has_field(lln,'string') then
-
- directives.register("refences.sharelinks", function(v)
- if v then
- nodeinjections.reference, codeinjections.finishreference = use_shared_annotations()
- else
- nodeinjections.reference, codeinjections.finishreference = use_normal_annotations()
+function nodeinjections.annotation(width,height,depth,prerolled,r)
+ if prerolled then
+ if trace_references then
+ report_reference("special: width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled)
end
- end)
+ return latelua_function_node(function() finishannotation(width,height,depth,prerolled,r or false) end)
+ end
+end
- nodeinjections.reference, codeinjections.finishreference = use_shared_annotations()
+-- beware, we register during a latelua sweep so we have to make sure that
+-- we finalize after that (also in a latelua for the moment as we have no
+-- callback yet)
-else
+local annotations = nil
- nodeinjections.reference, codeinjections.finishreference = use_normal_annotations()
+function lpdf.registerannotation(n)
+ if annotations then
+ annotations[#annotations+1] = pdfreference(n)
+ else
+ annotations = pdfarray { pdfreference(n) } -- no need to use lpdf.array cum suis
+ end
+end
-end node.free(lln)
+pdfregisterannotation = lpdf.registerannotation
--- -- -- --
--- -- -- --
+function lpdf.annotationspecification()
+ if annotations then
+ local r = pdfdelayedobject(tostring(annotations)) -- delayed so okay in latelua
+ pdfaddtopageattributes("Annots",pdfreference(r))
+ annotations = nil
+ end
+end
-local done = { } -- prevent messages
+lpdf.registerpagefinalizer(lpdf.annotationspecification,"finalize annotations")
-function nodeinjections.destination(width,height,depth,name,view)
- if not done[name] then
- done[name] = true
- if trace_destinations then
- report_destination("width %p, height %p, depth %p, name %a, view %a",width,height,depth,name,view)
- end
- return pdfdestination_node(width,height,depth,name,view) -- can be begin/end node
+statistics.register("pdf annotations", function()
+ if nofused > 0 or nofspecial > 0 then
+ return format("%s links (%s unique), %s special",nofused,nofunique,nofspecial)
+ else
+ return nil
end
-end
+end)
-- runners and specials
--- runners["inner"] = function(var,actions)
--- if getinnermethod() == "names" then
--- local vi = var.i
--- if vi then
--- local vir = vi.references
--- if vir then
--- local internal = vir.internal
--- if internal then
--- var.inner = "aut:" .. internal
--- end
--- end
--- end
--- else
--- var.inner = nil
--- end
--- local prefix = var.p
--- local inner = var.inner
--- if inner and prefix and prefix ~= "" then
--- inner = prefix .. ":" .. inner -- might not always be ok
--- end
--- return link(nil,nil,inner,var.r,actions)
--- end
-
runners["inner"] = function(var,actions)
local internal = false
- if getinnermethod() == "names" then
+ local method = references.innermethod
+ if method == "names" or method == "auto" then
local vi = var.i
if vi then
local vir = vi.references
if vir then
-- todo: no need for it when we have a real reference
- internal = vir.internal
- if internal then
- var.inner = "aut:" .. internal
+ local reference = vir.reference
+ if reference and reference ~= "" then
+ var.inner = reference
+ else
+ internal = vir.internal
+ if internal then
+ var.inner = internal
+ flaginternals[internal] = true
+ end
end
end
end
@@ -381,7 +658,7 @@ runners["inner"] = function(var,actions)
-- no prefix with e.g. components
inner = prefix .. ":" .. inner
end
- return link(nil,nil,inner,var.r,actions)
+ return pdflink(nil,nil,inner,var.r,actions)
end
runners["inner with arguments"] = function(var,actions)
@@ -391,12 +668,12 @@ end
runners["outer"] = function(var,actions)
local file, url = references.checkedfileorurl(var.outer,var.outer)
- return link(url,file,var.arguments,nil,actions)
+ return pdflink(url,file,var.arguments,nil,actions)
end
runners["outer with inner"] = function(var,actions)
local file = references.checkedfile(var.outer) -- was var.f but fails ... why
- return link(nil,file,var.inner,var.r,actions)
+ return pdflink(nil,file,var.inner,var.r,actions)
end
runners["special outer with operation"] = function(var,actions)
@@ -443,12 +720,23 @@ function specials.internal(var,actions) -- better resolve in strc-ref
if not v then
-- error
report_reference("no internal reference %a",i)
- elseif getinnermethod() == "names" then
- -- named
- return link(nil,nil,"aut:"..i,v.references.realpage,actions)
else
- -- page
- return link(nil,nil,nil,v.references.realpage,actions)
+ flaginternals[i] = true
+ local method = references.innermethod
+ if method == "names" then
+ -- named
+ return pdflink(nil,nil,i,v.references.realpage,actions)
+ elseif method == "auto" then
+ -- named
+ if usedinternals[i] == true then
+ return pdflink(nil,nil,nil,v.references.realpage,actions)
+ else
+ return pdflink(nil,nil,i,v.references.realpage,actions)
+ end
+ else
+ -- page
+ return pdflink(nil,nil,nil,v.references.realpage,actions)
+ end
end
end
@@ -462,7 +750,7 @@ function specials.page(var,actions)
local file = var.f
if file then
file = references.checkedfile(file)
- return link(nil,file,nil,var.operation,actions)
+ return pdflink(nil,file,nil,var.operation,actions)
else
local p = var.r
if not p then -- todo: call special from reference code
@@ -476,7 +764,7 @@ function specials.page(var,actions)
-- var.r = p
-- end
end
- return link(nil,nil,nil,p or var.operation,actions)
+ return pdflink(nil,nil,nil,p or var.operation,actions)
end
end
@@ -484,9 +772,9 @@ function specials.realpage(var,actions)
local file = var.f
if file then
file = references.checkedfile(file)
- return link(nil,file,nil,var.operation,actions)
+ return pdflink(nil,file,nil,var.operation,actions)
else
- return link(nil,nil,nil,var.operation,actions)
+ return pdflink(nil,nil,nil,var.operation,actions)
end
end
@@ -494,7 +782,7 @@ function specials.userpage(var,actions)
local file = var.f
if file then
file = references.checkedfile(file)
- return link(nil,file,nil,var.operation,actions)
+ return pdflink(nil,file,nil,var.operation,actions)
else
local p = var.r
if not p then -- todo: call special from reference code
@@ -506,7 +794,7 @@ function specials.userpage(var,actions)
-- var.r = p
-- end
end
- return link(nil,nil,nil,p or var.operation,actions)
+ return pdflink(nil,nil,nil,p or var.operation,actions)
end
end
@@ -514,7 +802,7 @@ function specials.deltapage(var,actions)
local p = tonumber(var.operation)
if p then
p = references.checkedrealpage(p + texgetcount("realpageno"))
- return link(nil,nil,nil,p,actions)
+ return pdflink(nil,nil,nil,p,actions)
end
end
@@ -555,26 +843,26 @@ end
function specials.url(var,actions)
local url = references.checkedurl(var.operation)
- return link(url,nil,var.arguments,nil,actions)
+ return pdflink(url,nil,var.arguments,nil,actions)
end
function specials.file(var,actions)
local file = references.checkedfile(var.operation)
- return link(nil,file,var.arguments,nil,actions)
+ return pdflink(nil,file,var.arguments,nil,actions)
end
function specials.fileorurl(var,actions)
local file, url = references.checkedfileorurl(var.operation,var.operation)
- return link(url,file,var.arguments,nil,actions)
+ return pdflink(url,file,var.arguments,nil,actions)
end
function specials.program(var,content)
local program = references.checkedprogram(var.operation)
- return lpdf.launch(program,var.arguments)
+ return pdflaunch(program,var.arguments)
end
function specials.javascript(var)
- return lpdf.javascript(var.operation,var.arguments)
+ return pdfjavascript(var.operation,var.arguments)
end
specials.JS = specials.javascript
@@ -698,11 +986,6 @@ function specials.action(var)
end
end
---~ entry.A = pdfdictionary {
---~ S = pdf_goto,
---~ D = ....
---~ }
-
local function build(levels,start,parent,method)
local startlevel = levels[start][1]
local i, n = start, 0
@@ -728,11 +1011,7 @@ local function build(levels,start,parent,method)
Parent = parent,
Prev = prev and pdfreference(prev),
}
- if method == "internal" then
- entry.Dest = "aut:" .. reference.internal
- else -- if method == "page" then
- entry.Dest = pagedestination(reference.realpage)
- end
+ entry.Dest = somedestination(reference.internal,reference.realpage)
if not first then first, last = child, child end
prev = child
last = prev
@@ -771,10 +1050,10 @@ function codeinjections.addbookmarks(levels,method)
Count = m,
}
pdfflushobject(parent,dict)
- lpdf.addtocatalog("Outlines",lpdf.reference(parent))
+ pdfaddtocatalog("Outlines",lpdf.reference(parent))
end
end
-- this could also be hooked into the frontend finalizer
-lpdf.registerdocumentfinalizer(function() bookmarks.place() end,1,"bookmarks")
+lpdf.registerdocumentfinalizer(function() bookmarks.place() end,1,"bookmarks") -- hm, why indirect call
diff --git a/tex/context/base/lpdf-col.lua b/tex/context/base/lpdf-col.lua
index b358d0820..b2d508611 100644
--- a/tex/context/base/lpdf-col.lua
+++ b/tex/context/base/lpdf-col.lua
@@ -14,42 +14,48 @@ local formatters = string.formatters
local backends, lpdf, nodes = backends, lpdf, nodes
-local allocate = utilities.storage.allocate
-local formatters = string.formatters
-
-local nodeinjections = backends.pdf.nodeinjections
-local codeinjections = backends.pdf.codeinjections
-local registrations = backends.pdf.registrations
-
-local nodepool = nodes.pool
-local register = nodepool.register
-local pdfliteral = nodepool.pdfliteral
-
-local pdfconstant = lpdf.constant
-local pdfstring = lpdf.string
-local pdfdictionary = lpdf.dictionary
-local pdfarray = lpdf.array
-local pdfreference = lpdf.reference
-local pdfverbose = lpdf.verbose
-local pdfflushobject = lpdf.flushobject
-local pdfflushstreamobject = lpdf.flushstreamobject
-
-local colors = attributes.colors
-local transparencies = attributes.transparencies
-local registertransparancy = transparencies.register
-local registercolor = colors.register
-local colorsvalue = colors.value
-local transparenciesvalue = transparencies.value
-local forcedmodel = colors.forcedmodel
-
-local c_transparency = pdfconstant("Transparency")
-
-local f_gray = formatters["%.3f g %.3f G"]
-local f_rgb = formatters["%.3f %.3f %.3f rg %.3f %.3f %.3f RG"]
-local f_cmyk = formatters["%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K"]
+local allocate = utilities.storage.allocate
+local formatters = string.formatters
+
+local nodeinjections = backends.pdf.nodeinjections
+local codeinjections = backends.pdf.codeinjections
+local registrations = backends.pdf.registrations
+
+local nodepool = nodes.pool
+local register = nodepool.register
+local pdfliteral = nodepool.pdfliteral
+
+local pdfconstant = lpdf.constant
+local pdfstring = lpdf.string
+local pdfdictionary = lpdf.dictionary
+local pdfarray = lpdf.array
+local pdfreference = lpdf.reference
+local pdfverbose = lpdf.verbose
+local pdfflushobject = lpdf.flushobject
+local pdfflushstreamobject = lpdf.flushstreamobject
+
+local pdfshareobjectreference = lpdf.shareobjectreference
+
+local addtopageattributes = lpdf.addtopageattributes
+local adddocumentcolorspace = lpdf.adddocumentcolorspace
+local adddocumentextgstate = lpdf.adddocumentextgstate
+
+local colors = attributes.colors
+local transparencies = attributes.transparencies
+local registertransparancy = transparencies.register
+local registercolor = colors.register
+local colorsvalue = colors.value
+local transparenciesvalue = transparencies.value
+local forcedmodel = colors.forcedmodel
+
+local c_transparency = pdfconstant("Transparency")
+
+local f_gray = formatters["%.3F g %.3F G"]
+local f_rgb = formatters["%.3F %.3F %.3F rg %.3F %.3F %.3F RG"]
+local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"]
local f_spot = formatters["/%s cs /%s CS %s SCN %s scn"]
local f_tr = formatters["Tr%s"]
-local f_cm = formatters["q %f %f %f %f %f %f cm"]
+local f_cm = formatters["q %F %F %F %F %F %F cm"]
local f_effect = formatters["%s Tc %s w %s Tr"]
local f_tr_gs = formatters["/Tr%s gs"]
local f_num_1 = tostring
@@ -95,7 +101,7 @@ local function addpagegroup()
if currentgroupcolormodel then
local g = transparencygroups[currentgroupcolormodel]
if g then
- lpdf.addtopageattributes("Group",g)
+ addtopageattributes("Group",g)
end
end
end
@@ -224,7 +230,7 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range,
local mr = pdfreference(m)
spotcolorhash[name] = m
documentcolorspaces[name] = mr
- lpdf.adddocumentcolorspace(name,mr)
+ adddocumentcolorspace(name,mr)
else
local cnames = pdfarray()
local domain = pdfarray()
@@ -280,13 +286,13 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range,
cnames,
colorspace,
pdfreference(calculation),
- lpdf.shareobjectreference(tostring(channels)), -- optional but needed for shades
+ pdfshareobjectreference(tostring(channels)), -- optional but needed for shades
}
local m = pdfflushobject(array)
local mr = pdfreference(m)
spotcolorhash[name] = m
documentcolorspaces[name] = mr
- lpdf.adddocumentcolorspace(name,mr)
+ adddocumentcolorspace(name,mr)
end
end
@@ -336,7 +342,7 @@ local function registersomeindexcolor(name,noffractions,names,p,colorspace,range
end
vector = pdfverbose { "<", concat(vector, " "), ">" }
local n = pdfflushobject(pdfarray{ pdf_indexed, a, 255, vector })
- lpdf.adddocumentcolorspace(format("%s_indexed",name),pdfreference(n))
+ adddocumentcolorspace(format("%s_indexed",name),pdfreference(n))
return n
end
@@ -455,7 +461,7 @@ function registrations.transparency(n,a,t)
local mr = pdfreference(m)
transparencyhash[0] = m
documenttransparencies[0] = mr
- lpdf.adddocumentextgstate("Tr0",mr)
+ adddocumentextgstate("Tr0",mr)
done = true
end
if n > 0 and not transparencyhash[n] then
@@ -470,7 +476,7 @@ function registrations.transparency(n,a,t)
local mr = pdfreference(m)
transparencyhash[n] = m
documenttransparencies[n] = mr
- lpdf.adddocumentextgstate(f_tr(n),mr)
+ adddocumentextgstate(f_tr(n),mr)
end
end
@@ -689,7 +695,7 @@ end
-- this will move to lpdf-spe.lua
-local f_slant = formatters["pdf: q 1 0 %f 1 0 0 cm"]
+local f_slant = formatters["pdf: q 1 0 %F 1 0 0 cm"]
backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph and rule color
diff --git a/tex/context/base/lpdf-fld.lua b/tex/context/base/lpdf-fld.lua
index a9b9fd72d..fc5a11c43 100644
--- a/tex/context/base/lpdf-fld.lua
+++ b/tex/context/base/lpdf-fld.lua
@@ -55,7 +55,8 @@ if not modules then modules = { } end modules ['lpdf-fld'] = {
-- for printing especially when highlighting (those colorfull foregrounds) is
-- on.
-local gmatch, lower, format = string.gmatch, string.lower, string.format
+local tostring, next = tostring, next
+local gmatch, lower, format, formatters = string.gmatch, string.lower, string.format, string.formatters
local lpegmatch = lpeg.match
local utfchar = utf.char
local bpfactor, todimen = number.dimenfactors.bp, string.todimen
@@ -92,14 +93,13 @@ local pdfflushobject = lpdf.flushobject
local pdfshareobjectreference = lpdf.shareobjectreference
local pdfshareobject = lpdf.shareobject
local pdfreserveobject = lpdf.reserveobject
-local pdfreserveannotation = lpdf.reserveannotation
local pdfaction = lpdf.action
-local hpack_node = node.hpack
-
-local nodepool = nodes.pool
+local pdfcolor = lpdf.color
+local pdfcolorvalues = lpdf.colorvalues
+local pdflayerreference = lpdf.layerreference
-local pdfannotation_node = nodepool.pdfannotation
+local hpack_node = node.hpack
local submitoutputformat = 0 -- 0=unknown 1=HTML 2=FDF 3=XML => not yet used, needs to be checked
@@ -125,39 +125,39 @@ function codeinjections.setformsmethod(name)
end
local flag = { -- /Ff
- ReadOnly = 1, -- 1
- Required = 2, -- 2
- NoExport = 4, -- 3
- MultiLine = 4096, -- 13
- Password = 8192, -- 14
- NoToggleToOff = 16384, -- 15
- Radio = 32768, -- 16
- PushButton = 65536, -- 17
- PopUp = 131072, -- 18
- Edit = 262144, -- 19
- Sort = 524288, -- 20
- FileSelect = 1048576, -- 21
- DoNotSpellCheck = 4194304, -- 23
- DoNotScroll = 8388608, -- 24
- Comb = 16777216, -- 25
- RichText = 33554432, -- 26
- RadiosInUnison = 33554432, -- 26
- CommitOnSelChange = 67108864, -- 27
+ ReadOnly = 2^ 0, -- 1
+ Required = 2^ 1, -- 2
+ NoExport = 2^ 2, -- 3
+ MultiLine = 2^12, -- 13
+ Password = 2^13, -- 14
+ NoToggleToOff = 2^14, -- 15
+ Radio = 2^15, -- 16
+ PushButton = 2^16, -- 17
+ PopUp = 2^17, -- 18
+ Edit = 2^18, -- 19
+ Sort = 2^19, -- 20
+ FileSelect = 2^20, -- 21
+ DoNotSpellCheck = 2^22, -- 23
+ DoNotScroll = 2^23, -- 24
+ Comb = 2^24, -- 25
+ RichText = 2^25, -- 26
+ RadiosInUnison = 2^25, -- 26
+ CommitOnSelChange = 2^26, -- 27
}
local plus = { -- /F
- Invisible = 1, -- 1
- Hidden = 2, -- 2
- Printable = 4, -- 3
- Print = 4, -- 3
- NoZoom = 8, -- 4
- NoRotate = 16, -- 5
- NoView = 32, -- 6
- ReadOnly = 64, -- 7
- Locked = 128, -- 8
- ToggleNoView = 256, -- 9
- LockedContents = 512, -- 10,
- AutoView = 256, -- 288 (6+9)
+ Invisible = 2^0, -- 1
+ Hidden = 2^1, -- 2
+ Printable = 2^2, -- 3
+ Print = 2^2, -- 3
+ NoZoom = 2^3, -- 4
+ NoRotate = 2^4, -- 5
+ NoView = 2^5, -- 6
+ ReadOnly = 2^6, -- 7
+ Locked = 2^7, -- 8
+ ToggleNoView = 2^8, -- 9
+ LockedContents = 2^9, -- 10,
+ AutoView = 2^8, -- 6 + 9 ?
}
-- todo: check what is interfaced
@@ -198,33 +198,82 @@ local function fieldplus(specification) -- /F
return n
end
-local function checked(what)
- local set, bug = references.identify("",what)
- if not bug and #set > 0 then
- local r, n = pdfaction(set)
- return pdfshareobjectreference(r)
- end
-end
+-- keep:
+--
+-- local function checked(what)
+-- local set, bug = references.identify("",what)
+-- if not bug and #set > 0 then
+-- local r, n = pdfaction(set)
+-- return pdfshareobjectreference(r)
+-- end
+-- end
+--
+-- local function fieldactions(specification) -- share actions
+-- local d, a = { }, nil
+-- a = specification.mousedown
+-- or specification.clickin if a and a ~= "" then d.D = checked(a) end
+-- a = specification.mouseup
+-- or specification.clickout if a and a ~= "" then d.U = checked(a) end
+-- a = specification.regionin if a and a ~= "" then d.E = checked(a) end -- Enter
+-- a = specification.regionout if a and a ~= "" then d.X = checked(a) end -- eXit
+-- a = specification.afterkey if a and a ~= "" then d.K = checked(a) end
+-- a = specification.format if a and a ~= "" then d.F = checked(a) end
+-- a = specification.validate if a and a ~= "" then d.V = checked(a) end
+-- a = specification.calculate if a and a ~= "" then d.C = checked(a) end
+-- a = specification.focusin if a and a ~= "" then d.Fo = checked(a) end
+-- a = specification.focusout if a and a ~= "" then d.Bl = checked(a) end
+-- a = specification.openpage if a and a ~= "" then d.PO = checked(a) end
+-- a = specification.closepage if a and a ~= "" then d.PC = checked(a) end
+-- -- a = specification.visiblepage if a and a ~= "" then d.PV = checked(a) end
+-- -- a = specification.invisiblepage if a and a ~= "" then d.PI = checked(a) end
+-- return next(d) and pdfdictionary(d)
+-- end
+
+local mapping = {
+ mousedown = "D", clickin = "D",
+ mouseup = "U", clickout = "U",
+ regionin = "E",
+ regionout = "X",
+ afterkey = "K",
+ format = "F",
+ validate = "V",
+ calculate = "C",
+ focusin = "Fo",
+ focusout = "Bl",
+ openpage = "PO",
+ closepage = "PC",
+ -- visiblepage = "PV",
+ -- invisiblepage = "PI",
+}
local function fieldactions(specification) -- share actions
- local d, a = { }, nil
- a = specification.mousedown
- or specification.clickin if a and a ~= "" then d.D = checked(a) end
- a = specification.mouseup
- or specification.clickout if a and a ~= "" then d.U = checked(a) end
- a = specification.regionin if a and a ~= "" then d.E = checked(a) end -- Enter
- a = specification.regionout if a and a ~= "" then d.X = checked(a) end -- eXit
- a = specification.afterkey if a and a ~= "" then d.K = checked(a) end
- a = specification.format if a and a ~= "" then d.F = checked(a) end
- a = specification.validate if a and a ~= "" then d.V = checked(a) end
- a = specification.calculate if a and a ~= "" then d.C = checked(a) end
- a = specification.focusin if a and a ~= "" then d.Fo = checked(a) end
- a = specification.focusout if a and a ~= "" then d.Bl = checked(a) end
- a = specification.openpage if a and a ~= "" then d.PO = checked(a) end
- a = specification.closepage if a and a ~= "" then d.PC = checked(a) end
- -- a = specification.visiblepage if a and a ~= "" then d.PV = checked(a) end
- -- a = specification.invisiblepage if a and a ~= "" then d.PI = checked(a) end
- return next(d) and pdfdictionary(d)
+ local d = nil
+ for key, target in next, mapping do
+ local code = specification[key]
+ if code and code ~= "" then
+ -- local a = checked(code)
+ local set, bug = references.identify("",code)
+ if not bug and #set > 0 then
+ local a = pdfaction(set) -- r, n
+ if a then
+ local r = pdfshareobjectreference(a)
+ if d then
+ d[target] = r
+ else
+ d = pdfdictionary { [target] = r }
+ end
+ else
+ report_fields("invalid field action %a, case %s",code,2)
+ end
+ else
+ report_fields("invalid field action %a, case %s",code,1)
+ end
+ end
+ end
+ -- if d then
+ -- d = pdfshareobjectreference(d) -- not much overlap or maybe only some patterns
+ -- end
+ return d
end
-- fonts and color
@@ -298,16 +347,16 @@ local function fieldsurrounding(specification)
fontsize = todimen(fontsize)
fontsize = fontsize and (bpfactor * fontsize) or 12
fontraise = 0.1 * fontsize -- todo: figure out what the natural one is and compensate for strutdp
- local fontcode = format("%0.4f Tf %0.4f Ts",fontsize,fontraise)
+ local fontcode = formatters["%0.4f Tf %0.4f Ts"](fontsize,fontraise)
-- we could test for colorvalue being 1 (black) and omit it then
- local colorcode = lpdf.color(3,colorvalue) -- we force an rgb color space
+ local colorcode = pdfcolor(3,colorvalue) -- we force an rgb color space
if trace_fields then
report_fields("using font, style %a, alternative %a, size %p, tag %a, code %a",fontstyle,fontalternative,fontsize,tag,fontcode)
report_fields("using color, value %a, code %a",colorvalue,colorcode)
end
local stream = pdfstream {
pdfconstant(tag),
- format("%s %s",fontcode,colorcode)
+ formatters["%s %s"](fontcode,colorcode)
}
usedfonts[tag] = a -- the name
-- move up with "x.y Ts"
@@ -579,8 +628,8 @@ local function fieldrendering(specification)
local svalue = specification.fontsymbol
if bvalue or fvalue or (svalue and svalue ~= "") then
return pdfdictionary {
- BG = bvalue and pdfarray { lpdf.colorvalues(3,bvalue) } or nil, -- or zero_bg,
- BC = fvalue and pdfarray { lpdf.colorvalues(3,fvalue) } or nil, -- or zero_bc,
+ BG = bvalue and pdfarray { pdfcolorvalues(3,bvalue) } or nil, -- or zero_bg,
+ BC = fvalue and pdfarray { pdfcolorvalues(3,fvalue) } or nil, -- or zero_bc,
CA = svalue and pdfstring (svalue) or nil,
}
end
@@ -590,7 +639,7 @@ end
local function fieldlayer(specification) -- we can move this in line
local layer = specification.layer
- return (layer and lpdf.layerreference(layer)) or nil
+ return (layer and pdflayerreference(layer)) or nil
end
-- defining
@@ -611,7 +660,7 @@ local xfdftemplate = [[
function codeinjections.exportformdata(name)
local result = { }
for k, v in table.sortedhash(fields) do
- result[#result+1] = format(" <field name='%s'><value>%s</value></field>",v.name or k,v.default or "")
+ result[#result+1] = formatters[" <field name='%s'><value>%s</value></field>"](v.name or k,v.default or "")
end
local base = file.basename(tex.jobname)
local xfdf = format(xfdftemplate,base,table.concat(result,"\n"))
@@ -912,7 +961,7 @@ local function save_parent(field,specification,d,hasopt)
end
local function save_kid(field,specification,d,optname)
- local kn = pdfreserveannotation()
+ local kn = pdfreserveobject()
field.kids[#field.kids+1] = pdfreference(kn)
if optname then
local opt = field.opt
@@ -921,7 +970,7 @@ local function save_kid(field,specification,d,optname)
end
end
local width, height, depth = specification.width or 0, specification.height or 0, specification.depth
- local box = hpack_node(pdfannotation_node(width,height,depth,d(),kn))
+ local box = hpack_node(nodeinjections.annotation(width,height,depth,d(),kn))
box.width, box.height, box.depth = width, height, depth -- redundant
return box
end
@@ -969,6 +1018,8 @@ local function makelinechild(name,specification)
if trace_fields then
report_fields("using child text %a",name)
end
+ -- we could save a little by not setting some key/value when it's the
+ -- same as parent but it would cost more memory to keep track of it
local d = pdfdictionary {
Subtype = pdf_widget,
Parent = pdfreference(parent.pobj),
diff --git a/tex/context/base/lpdf-fmt.lua b/tex/context/base/lpdf-fmt.lua
index b444f03c3..568b801b4 100644
--- a/tex/context/base/lpdf-fmt.lua
+++ b/tex/context/base/lpdf-fmt.lua
@@ -349,7 +349,7 @@ local filenames = {
}
local function locatefile(filename)
- local fullname = resolvers.findfile(filename,"icc")
+ local fullname = resolvers.findfile(filename,"icc",1,true)
if not fullname or fullname == "" then
fullname = resolvers.finders.byscheme("loc",filename) -- could be specific to the project
end
@@ -743,7 +743,7 @@ end
function codeinjections.supportedformats()
local t = { }
for k, v in table.sortedhash(formats) do
- if find(k,"pdf") then
+ if find(k,"pdf",1,true) then
t[#t+1] = k
end
end
diff --git a/tex/context/base/lpdf-grp.lua b/tex/context/base/lpdf-grp.lua
index fed5e6a46..befe52c76 100644
--- a/tex/context/base/lpdf-grp.lua
+++ b/tex/context/base/lpdf-grp.lua
@@ -236,7 +236,7 @@ function img.package(image) -- see lpdf-u3d **
local height = boundingbox[4]
local xform = img.scan {
attr = resources(),
- stream = format("%f 0 0 %f 0 0 cm /%s Do",width,height,imagetag),
+ stream = format("%F 0 0 %F 0 0 cm /%s Do",width,height,imagetag),
bbox = { 0, 0, width/factor, height/factor },
}
img.immediatewrite(xform)
diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua
index 23fe6c177..34825698c 100644
--- a/tex/context/base/lpdf-ini.lua
+++ b/tex/context/base/lpdf-ini.lua
@@ -9,15 +9,28 @@ if not modules then modules = { } end modules ['lpdf-ini'] = {
local setmetatable, getmetatable, type, next, tostring, tonumber, rawset = setmetatable, getmetatable, type, next, tostring, tonumber, rawset
local char, byte, format, gsub, concat, match, sub, gmatch = string.char, string.byte, string.format, string.gsub, table.concat, string.match, string.sub, string.gmatch
local utfchar, utfvalues = utf.char, utf.values
-local sind, cosd, floor = math.sind, math.cosd, math.floor
+local sind, cosd, floor, max, min = math.sind, math.cosd, math.floor, math.max, math.min
local lpegmatch, P, C, R, S, Cc, Cs = lpeg.match, lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Cs
local formatters = string.formatters
+-- pdf.mapfile pdf.mapline (todo: used in font-ctx.lua)
+-- pdf.getpos pdf.gethpos pdf.getvpos
+-- pdf.reserveobj pdf.immediateobj pdf.obj pdf.refobj
+-- pdf.pageref
+-- pdf.catalog pdf.info pdf.names pdf.trailer
+
+local backends = backends
+local pdf = pdf
+lpdf = lpdf or { }
+local lpdf = lpdf
+
local pdfreserveobject = pdf.reserveobj
local pdfimmediateobject = pdf.immediateobj
local pdfdeferredobject = pdf.obj
local pdfreferenceobject = pdf.refobj
+local factor = number.dimenfactors.bp
+
local trace_finalizers = false trackers.register("backend.finalizers", function(v) trace_finalizers = v end)
local trace_resources = false trackers.register("backend.resources", function(v) trace_resources = v end)
local trace_objects = false trackers.register("backend.objects", function(v) trace_objects = v end)
@@ -26,8 +39,6 @@ local trace_detail = false trackers.register("backend.detail", function
local report_objects = logs.reporter("backend","objects")
local report_finalizing = logs.reporter("backend","finalizing")
-local backends = backends
-
backends.pdf = backends.pdf or {
comment = "backend for directly generating pdf output",
nodeinjections = { },
@@ -36,8 +47,76 @@ backends.pdf = backends.pdf or {
tables = { },
}
-lpdf = lpdf or { }
-local lpdf = lpdf
+-- first some helpers
+
+local codeinjections = backends.pdf.codeinjections
+
+local pdfgetpos, pdfgethpos, pdfgetvpos, pdfhasmatrix, pdfgetmatrix
+
+if pdf.getpos then
+ pdfgetpos = pdf.getpos
+ pdfgethpos = pdf.gethpos
+ pdfgetvpos = pdf.getvpos
+ pdfgetmatrix = pdf.getmatrix
+ pdfhasmatrix = pdf.hasmatrix
+else
+ if pdf.h then
+ function pdfgetpos () return pdf.h, pdf.v end
+ function pdfgethpos() return pdf.h end
+ function pdfgetvpos() return pdf.v end
+ end
+ function pdfhasmatrix() return false end
+ function pdfgetmatrix() return 1, 0, 0, 1, 0, 0 end
+end
+
+codeinjections.getpos = pdfgetpos lpdf.getpos = pdfgetpos
+codeinjections.gethpos = pdfgethpos lpdf.gethpos = pdfgethpos
+codeinjections.getvpos = pdfgetvpos lpdf.getvpos = pdfgetvpos
+codeinjections.hasmatrix = pdfhasmatrix lpdf.hasmatrix = pdfhasmatrix
+codeinjections.getmatrix = pdfgetmatrix lpdf.getmatrix = pdfgetmatrix
+
+function lpdf.transform(llx,lly,urx,ury)
+ if pdfhasmatrix() then
+ local sx, rx, ry, sy = pdfgetmatrix()
+ local w, h = urx - llx, ury - lly
+ return llx, lly, llx + sy*w - ry*h, lly + sx*h - rx*w
+ else
+ return llx, lly, urx, ury
+ end
+end
+
+-- function lpdf.rectangle(width,height,depth)
+-- local h, v = pdfgetpos()
+-- local llx, lly, urx, ury
+-- if pdfhasmatrix() then
+-- local sx, rx, ry, sy = pdfgetmatrix()
+-- llx = 0
+-- lly = -depth
+-- -- llx = ry * depth
+-- -- lly = -sx * depth
+-- urx = sy * width - ry * height
+-- ury = sx * height - rx * width
+-- else
+-- llx = 0
+-- lly = -depth
+-- urx = width
+-- ury = height
+-- return (h+llx)*factor, (v+lly)*factor, (h+urx)*factor, (v+ury)*factor
+-- end
+-- end
+
+function lpdf.rectangle(width,height,depth)
+ local h, v = pdfgetpos()
+ if pdfhasmatrix() then
+ local sx, rx, ry, sy = pdfgetmatrix()
+ -- return (h+ry*depth)*factor, (v-sx*depth)*factor, (h+sy*width-ry*height)*factor, (v+sx*height-rx*width)*factor
+ return h *factor, (v- depth)*factor, (h+sy*width-ry*height)*factor, (v+sx*height-rx*width)*factor
+ else
+ return h *factor, (v- depth)*factor, (h+ width )*factor, (v+ height )*factor
+ end
+end
+
+--
local function tosixteen(str) -- an lpeg might be faster (no table)
if not str or str == "" then
@@ -91,13 +170,13 @@ end
lpdf.toeight = toeight
---~ local escaped = lpeg.Cs((lpeg.S("\0\t\n\r\f ()[]{}/%")/function(s) return format("#%02X",byte(s)) end + lpeg.P(1))^0)
-
---~ local function cleaned(str)
---~ return (str and str ~= "" and lpegmatch(escaped,str)) or ""
---~ end
-
---~ lpdf.cleaned = cleaned -- not public yet
+-- local escaped = lpeg.Cs((lpeg.S("\0\t\n\r\f ()[]{}/%")/function(s) return format("#%02X",byte(s)) end + lpeg.P(1))^0)
+--
+-- local function cleaned(str)
+-- return (str and str ~= "" and lpegmatch(escaped,str)) or ""
+-- end
+--
+-- lpdf.cleaned = cleaned -- not public yet
local function merge_t(a,b)
local t = { }
@@ -112,16 +191,16 @@ local f_dictionary = formatters["<< % t >>"]
local f_key_array = formatters["/%s [ % t ]"]
local f_array = formatters["[ % t ]"]
+-- local f_key_value = formatters["/%s %s"]
+-- local f_key_dictionary = formatters["/%s <<% t>>"]
+-- local f_dictionary = formatters["<<% t>>"]
+-- local f_key_array = formatters["/%s [% t]"]
+-- local f_array = formatters["[% t]"]
+
local tostring_a, tostring_d
tostring_d = function(t,contentonly,key)
- if not next(t) then
- if contentonly then
- return ""
- else
- return "<< >>"
- end
- else
+ if next(t) then
local r, rn = { }, 0
for k, v in next, t do
rn = rn + 1
@@ -150,18 +229,16 @@ tostring_d = function(t,contentonly,key)
else
return f_dictionary(r)
end
+ elseif contentonly then
+ return ""
+ else
+ return "<< >>"
end
end
tostring_a = function(t,contentonly,key)
local tn = #t
- if tn == 0 then
- if contentonly then
- return ""
- else
- return "[ ]"
- end
- else
+ if tn ~= 0 then
local r = { }
for k=1,tn do
local v = t[k]
@@ -191,10 +268,14 @@ tostring_a = function(t,contentonly,key)
else
return f_array(r)
end
+ elseif contentonly then
+ return ""
+ else
+ return "[ ]"
end
end
-local tostring_x = function(t) return concat(t, " ") end
+local tostring_x = function(t) return concat(t," ") end
local tostring_s = function(t) return toeight(t[1]) end
local tostring_u = function(t) return tosixteen(t[1]) end
local tostring_n = function(t) return tostring(t[1]) end -- tostring not needed
@@ -207,7 +288,7 @@ local tostring_r = function(t) local n = t[1] return n and n > 0 and (n .. " 0 R
local tostring_v = function(t)
local s = t[1]
if type(s) == "table" then
- return concat(s,"")
+ return concat(s)
else
return s
end
@@ -325,12 +406,27 @@ local function pdfboolean(b,default)
end
end
-local function pdfreference(r)
- return setmetatable({ r or 0 },mt_r)
+local r_zero = setmetatable({ 0 },mt_r)
+
+local function pdfreference(r) -- maybe make a weak table
+ if r and r ~= 0 then
+ return setmetatable({ r },mt_r)
+ else
+ return r_zero
+ end
end
+local v_zero = setmetatable({ 0 },mt_v)
+local v_empty = setmetatable({ "" },mt_v)
+
local function pdfverbose(t) -- maybe check for type
- return setmetatable({ t or "" },mt_v)
+ if t == 0 then
+ return v_zero
+ elseif t == "" then
+ return v_empty
+ else
+ return setmetatable({ t },mt_v)
+ end
end
lpdf.stream = pdfstream -- THIS WILL PROBABLY CHANGE
@@ -345,37 +441,19 @@ lpdf.boolean = pdfboolean
lpdf.reference = pdfreference
lpdf.verbose = pdfverbose
--- n = pdf.obj(n, str)
--- n = pdf.obj(n, "file", filename)
--- n = pdf.obj(n, "stream", streamtext, attrtext)
--- n = pdf.obj(n, "streamfile", filename, attrtext)
-
--- we only use immediate objects
-
--- todo: tracing
-
local names, cache = { }, { }
function lpdf.reserveobject(name)
- if name == "annot" then
- -- catch misuse
- return pdfreserveobject("annot")
- else
- local r = pdfreserveobject()
- if name then
- names[name] = r
- if trace_objects then
- report_objects("reserving number %a under name %a",r,name)
- end
- elseif trace_objects then
- report_objects("reserving number %a",r)
+ local r = pdfreserveobject() -- we don't support "annot"
+ if name then
+ names[name] = r
+ if trace_objects then
+ report_objects("reserving number %a under name %a",r,name)
end
- return r
+ elseif trace_objects then
+ report_objects("reserving number %a",r)
end
-end
-
-function lpdf.reserveannotation()
- return pdfreserveobject("annot")
+ return r
end
-- lpdf.immediateobject = pdfimmediateobject
@@ -383,11 +461,29 @@ end
-- lpdf.object = pdfdeferredobject
-- lpdf.referenceobject = pdfreferenceobject
-lpdf.pagereference = pdf.pageref or tex.pdfpageref
-lpdf.registerannotation = pdf.registerannot
+local pagereference = pdf.pageref or tex.pdfpageref
+local nofpages = 0
+
+function lpdf.pagereference(n)
+ if nofpages == 0 then
+ nofpages = structures.pages.nofpages
+ if nofpages == 0 then
+ nofpages = 1
+ end
+ end
+ if n > nofpages then
+ return pagereference(nofpages) -- or 1, could be configureable
+ else
+ return pagereference(n)
+ end
+end
-function lpdf.delayedobject(data) -- we will get rid of this one
- local n = pdfdeferredobject(data)
+function lpdf.delayedobject(data,n)
+ if n then
+ pdfdeferredobject(n,data)
+ else
+ n = pdfdeferredobject(data)
+ end
pdfreferenceobject(n)
return n
end
@@ -484,57 +580,6 @@ function lpdf.shareobjectreference(content)
end
end
---~ local d = lpdf.dictionary()
---~ local e = lpdf.dictionary { ["e"] = "abc", x = lpdf.dictionary { ["f"] = "ABC" } }
---~ local f = lpdf.dictionary { ["f"] = "ABC" }
---~ local a = lpdf.array { lpdf.array { lpdf.string("xxx") } }
-
---~ print(a)
---~ os.exit()
-
---~ d["test"] = lpdf.string ("test")
---~ d["more"] = "more"
---~ d["bool"] = true
---~ d["numb"] = 1234
---~ d["oeps"] = lpdf.dictionary { ["hans"] = "ton" }
---~ d["whow"] = lpdf.array { lpdf.string("ton") }
-
---~ a[#a+1] = lpdf.string("xxx")
---~ a[#a+1] = lpdf.string("yyy")
-
---~ d.what = a
-
---~ print(e)
-
---~ local d = lpdf.dictionary()
---~ d["abcd"] = { 1, 2, 3, "test" }
---~ print(d)
---~ print(d())
-
---~ local d = lpdf.array()
---~ d[#d+1] = 1
---~ d[#d+1] = 2
---~ d[#d+1] = 3
---~ d[#d+1] = "test"
---~ print(d)
-
---~ local d = lpdf.array()
---~ d[#d+1] = { 1, 2, 3, "test" }
---~ print(d)
-
---~ local d = lpdf.array()
---~ d[#d+1] = { a=1, b=2, c=3, d="test" }
---~ print(d)
-
---~ local s = lpdf.constant("xx")
---~ print(s) -- fails somehow
---~ print(s()) -- fails somehow
-
---~ local s = lpdf.boolean(false)
---~ s.value = true
---~ print(s)
---~ print(s())
-
-- three priority levels, default=2
local pagefinalizers, documentfinalizers = { { }, { }, { } }, { { }, { }, { } }
@@ -606,8 +651,8 @@ end
lpdf.registerpagefinalizer = registerpagefinalizer
lpdf.registerdocumentfinalizer = registerdocumentfinalizer
-function lpdf.finalizepage()
- if not environment.initex then
+function lpdf.finalizepage(shipout)
+ if shipout and not environment.initex then
-- resetpageproperties() -- maybe better before
run(pagefinalizers,"page")
setpageproperties()
@@ -625,9 +670,27 @@ function lpdf.finalizedocument()
end
end
-backends.pdf.codeinjections.finalizepage = lpdf.finalizepage -- will go when we have hook
+-- backends.pdf.codeinjections.finalizepage = lpdf.finalizepage -- no longer triggered at the tex end
+
+if not callbacks.register("finish_pdfpage", lpdf.finalizepage) then
+
+ local find_tail = nodes.tail
+ local latelua_node = nodes.pool.latelua
+
+ function backends.pdf.nodeinjections.finalizepage(head)
+ local t = find_tail(head.list)
+ if t then
+ local n = latelua_node("lpdf.finalizepage(true)") -- last in the shipout
+ t.next = n
+ n.prev = t
+ end
+ return head, true
+ end
+
+ nodes.tasks.appendaction("shipouts","normalizers","backends.pdf.nodeinjections.finalizepage")
+
+end
---~ callbacks.register("finish_pdfpage", lpdf.finalizepage)
callbacks.register("finish_pdffile", lpdf.finalizedocument)
-- some minimal tracing, handy for checking the order
@@ -718,7 +781,7 @@ registerpagefinalizer(checkshades,3,"shades")
function lpdf.rotationcm(a)
local s, c = sind(a), cosd(a)
- return format("%0.6f %0.6f %0.6f %0.6f 0 0 cm",c,s,-s,c)
+ return format("%0.6F %0.6F %0.6F %0.6F 0 0 cm",c,s,-s,c)
end
-- ! -> universaltime
@@ -795,29 +858,29 @@ end
-- lpdf.addtoinfo("ConTeXt.Jobname", environment.jobname)
-- lpdf.addtoinfo("ConTeXt.Url", "www.pragma-ade.com")
-if not pdfreferenceobject then
-
- local delayed = { }
-
- local function flush()
- local n = 0
- for k,v in next, delayed do
- pdfimmediateobject(k,v)
- n = n + 1
- end
- if trace_objects then
- report_objects("%s objects flushed",n)
- end
- delayed = { }
- end
-
- lpdf.registerdocumentfinalizer(flush,3,"objects") -- so we need a final flush too
- lpdf.registerpagefinalizer (flush,3,"objects") -- somehow this lags behind .. I need to look into that some day
-
- function lpdf.delayedobject(data)
- local n = pdfreserveobject()
- delayed[n] = data
- return n
- end
-
-end
+-- if not pdfreferenceobject then
+--
+-- local delayed = { }
+--
+-- local function flush()
+-- local n = 0
+-- for k,v in next, delayed do
+-- pdfimmediateobject(k,v)
+-- n = n + 1
+-- end
+-- if trace_objects then
+-- report_objects("%s objects flushed",n)
+-- end
+-- delayed = { }
+-- end
+--
+-- lpdf.registerdocumentfinalizer(flush,3,"objects") -- so we need a final flush too
+-- lpdf.registerpagefinalizer (flush,3,"objects") -- somehow this lags behind .. I need to look into that some day
+--
+-- function lpdf.delayedobject(data)
+-- local n = pdfreserveobject()
+-- delayed[n] = data
+-- return n
+-- end
+--
+-- end
diff --git a/tex/context/base/lpdf-mis.lua b/tex/context/base/lpdf-mis.lua
index 43f6cb7e1..6efbd3882 100644
--- a/tex/context/base/lpdf-mis.lua
+++ b/tex/context/base/lpdf-mis.lua
@@ -16,7 +16,7 @@ if not modules then modules = { } end modules ['lpdf-mis'] = {
-- course there are a couple of more changes.
local next, tostring = next, tostring
-local format, gsub = string.format, string.gsub
+local format, gsub, formatters = string.format, string.gsub, string.formatters
local texset = tex.set
local backends, lpdf, nodes = backends, lpdf, nodes
@@ -41,6 +41,14 @@ local pdfverbose = lpdf.verbose
local pdfstring = lpdf.string
local pdfflushobject = lpdf.flushobject
local pdfflushstreamobject = lpdf.flushstreamobject
+local pdfaction = lpdf.action
+
+local formattedtimestamp = lpdf.pdftimestamp
+local adddocumentextgstate = lpdf.adddocumentextgstate
+local addtocatalog = lpdf.addtocatalog
+local addtoinfo = lpdf.addtoinfo
+local addtopageattributes = lpdf.addtopageattributes
+local addtonames = lpdf.addtonames
local variables = interfaces.variables
local v_stop = variables.stop
@@ -60,8 +68,8 @@ local function initializenegative()
}
local negative = pdfdictionary { Type = g, TR = pdfreference(pdfflushstreamobject("{ 1 exch sub }",d)) }
local positive = pdfdictionary { Type = g, TR = pdfconstant("Identity") }
- lpdf.adddocumentextgstate("GSnegative", pdfreference(pdfflushobject(negative)))
- lpdf.adddocumentextgstate("GSpositive", pdfreference(pdfflushobject(positive)))
+ adddocumentextgstate("GSnegative", pdfreference(pdfflushobject(negative)))
+ adddocumentextgstate("GSpositive", pdfreference(pdfflushobject(positive)))
initializenegative = nil
end
@@ -69,8 +77,8 @@ local function initializeoverprint()
local g = pdfconstant("ExtGState")
local knockout = pdfdictionary { Type = g, OP = false, OPM = 0 }
local overprint = pdfdictionary { Type = g, OP = true, OPM = 1 }
- lpdf.adddocumentextgstate("GSknockout", pdfreference(pdfflushobject(knockout)))
- lpdf.adddocumentextgstate("GSoverprint", pdfreference(pdfflushobject(overprint)))
+ adddocumentextgstate("GSknockout", pdfreference(pdfflushobject(knockout)))
+ adddocumentextgstate("GSoverprint", pdfreference(pdfflushobject(overprint)))
initializeoverprint = nil
end
@@ -92,8 +100,6 @@ function nodeinjections.negative()
return copy_node(negative)
end
---
-
-- function codeinjections.addtransparencygroup()
-- -- png: /CS /DeviceRGB /I true
-- local d = pdfdictionary {
@@ -101,7 +107,7 @@ end
-- I = true,
-- K = true,
-- }
--- lpdf.registerpagefinalizer(function() lpdf.addtopageattributes("Group",d) end) -- hm
+-- lpdf.registerpagefinalizer(function() addtopageattributes("Group",d) end) -- hm
-- end
-- actions (todo: store and update when changed)
@@ -126,10 +132,10 @@ end
local function flushdocumentactions()
if opendocument then
- lpdf.addtocatalog("OpenAction",lpdf.action(opendocument))
+ addtocatalog("OpenAction",pdfaction(opendocument))
end
if closedocument then
- lpdf.addtocatalog("CloseAction",lpdf.action(closedocument))
+ addtocatalog("CloseAction",pdfaction(closedocument))
end
end
@@ -137,12 +143,12 @@ local function flushpageactions()
if openpage or closepage then
local d = pdfdictionary()
if openpage then
- d.O = lpdf.action(openpage)
+ d.O = pdfaction(openpage)
end
if closepage then
- d.C = lpdf.action(closepage)
+ d.C = pdfaction(closepage)
end
- lpdf.addtopageattributes("AA",d)
+ addtopageattributes("AA",d)
end
end
@@ -169,37 +175,37 @@ local function setupidentity()
if not title or title == "" then
title = tex.jobname
end
- lpdf.addtoinfo("Title", pdfunicode(title), title)
+ addtoinfo("Title", pdfunicode(title), title)
local subtitle = identity.subtitle or ""
if subtitle ~= "" then
- lpdf.addtoinfo("Subject", pdfunicode(subtitle), subtitle)
+ addtoinfo("Subject", pdfunicode(subtitle), subtitle)
end
local author = identity.author or ""
if author ~= "" then
- lpdf.addtoinfo("Author", pdfunicode(author), author) -- '/Author' in /Info, 'Creator' in XMP
+ addtoinfo("Author", pdfunicode(author), author) -- '/Author' in /Info, 'Creator' in XMP
end
local creator = identity.creator or ""
if creator ~= "" then
- lpdf.addtoinfo("Creator", pdfunicode(creator), creator) -- '/Creator' in /Info, 'CreatorTool' in XMP
+ addtoinfo("Creator", pdfunicode(creator), creator) -- '/Creator' in /Info, 'CreatorTool' in XMP
end
- lpdf.addtoinfo("CreationDate", pdfstring(lpdf.pdftimestamp(lpdf.timestamp())))
+ local currenttimestamp = lpdf.timestamp()
+ addtoinfo("CreationDate", pdfstring(formattedtimestamp(currenttimestamp)))
local date = identity.date or ""
- local pdfdate = lpdf.pdftimestamp(date)
+ local pdfdate = formattedtimestamp(date)
if pdfdate then
- lpdf.addtoinfo("ModDate", pdfstring(pdfdate), date)
+ addtoinfo("ModDate", pdfstring(pdfdate), date)
else
-- users should enter the date in 2010-01-19T23:27:50+01:00 format
-- and if not provided that way we use the creation time instead
- date = lpdf.timestamp()
- lpdf.addtoinfo("ModDate", pdfstring(lpdf.pdftimestamp(date)), date)
+ addtoinfo("ModDate", pdfstring(formattedtimestamp(currenttimestamp)), currenttimestamp)
end
local keywords = identity.keywords or ""
if keywords ~= "" then
keywords = gsub(keywords, "[%s,]+", " ")
- lpdf.addtoinfo("Keywords",pdfunicode(keywords), keywords)
+ addtoinfo("Keywords",pdfunicode(keywords), keywords)
end
local id = lpdf.id()
- lpdf.addtoinfo("ID", pdfstring(id), id) -- needed for pdf/x
+ addtoinfo("ID", pdfstring(id), id) -- needed for pdf/x
done = true
else
-- no need for a message
@@ -226,7 +232,7 @@ local function flushjavascripts()
a[#a+1] = pdfstring(name)
a[#a+1] = pdfreference(pdfflushobject(j))
end
- lpdf.addtonames("JavaScript",pdfreference(pdfflushobject(pdfdictionary{ Names = a })))
+ addtonames("JavaScript",pdfreference(pdfflushobject(pdfdictionary{ Names = a })))
end
end
@@ -285,16 +291,16 @@ local function documentspecification()
layout = layout and pdfconstant(layout)
fit = fit and pdfdictionary { FitWindow = true }
if layout then
- lpdf.addtocatalog("PageLayout",layout)
+ addtocatalog("PageLayout",layout)
end
if mode then
- lpdf.addtocatalog("PageMode",mode)
+ addtocatalog("PageMode",mode)
end
if fit then
- lpdf.addtocatalog("ViewerPreferences",fit)
+ addtocatalog("ViewerPreferences",fit)
end
- lpdf.addtoinfo ("Trapped", pdfconstant("False")) -- '/Trapped' in /Info, 'Trapped' in XMP
- lpdf.addtocatalog("Version", pdfconstant(format("1.%s",tex.pdfminorversion)))
+ addtoinfo ("Trapped", pdfconstant("False")) -- '/Trapped' in /Info, 'Trapped' in XMP
+ addtocatalog("Version", pdfconstant(format("1.%s",tex.pdfminorversion)))
end
end
@@ -303,7 +309,7 @@ end
local factor = number.dimenfactors.bp
local function boxvalue(n) -- we could share them
- return pdfverbose(format("%0.4f",factor * n))
+ return pdfverbose(formatters["%0.4F"](factor * n))
end
local function pagespecification()
@@ -314,10 +320,10 @@ local function pagespecification()
boxvalue(width-leftoffset),
boxvalue(pageheight-topoffset),
}
- lpdf.addtopageattributes("CropBox",box) -- mandate for rendering
- lpdf.addtopageattributes("TrimBox",box) -- mandate for pdf/x
- -- lpdf.addtopageattributes("BleedBox",box)
- -- lpdf.addtopageattributes("ArtBox",box)
+ addtopageattributes("CropBox",box) -- mandate for rendering
+ addtopageattributes("TrimBox",box) -- mandate for pdf/x
+ -- addtopageattributes("BleedBox",box)
+ -- addtopageattributes("ArtBox",box)
end
lpdf.registerpagefinalizer(pagespecification,"page specification")
@@ -365,7 +371,7 @@ local map = {
-- end
-- end
-- end
--- lpdf.addtocatalog("PageLabels", pdfdictionary { Nums = list })
+-- addtocatalog("PageLabels", pdfdictionary { Nums = list })
-- end
local function featurecreep()
@@ -416,7 +422,7 @@ local function featurecreep()
stopped = false
end
end
- lpdf.addtocatalog("PageLabels", pdfdictionary { Nums = list })
+ addtocatalog("PageLabels", pdfdictionary { Nums = list })
end
lpdf.registerdocumentfinalizer(featurecreep,"featurecreep")
diff --git a/tex/context/base/lpdf-mov.lua b/tex/context/base/lpdf-mov.lua
index 41db97e0c..fd3e89722 100644
--- a/tex/context/base/lpdf-mov.lua
+++ b/tex/context/base/lpdf-mov.lua
@@ -11,7 +11,6 @@ local format = string.format
local lpdf = lpdf
local nodeinjections = backends.pdf.nodeinjections
-local pdfannotation_node = nodes.pool.pdfannotation
local pdfconstant = lpdf.constant
local pdfdictionary = lpdf.dictionary
local pdfarray = lpdf.array
@@ -38,7 +37,7 @@ function nodeinjections.insertmovie(specification)
Movie = moviedict,
A = controldict,
}
- write_node(pdfannotation_node(width,height,0,action())) -- test: context(...)
+ write_node(nodeinjections.annotation(width,height,0,action())) -- test: context(...)
end
function nodeinjections.insertsound(specification)
@@ -58,6 +57,6 @@ function nodeinjections.insertsound(specification)
Movie = sounddict,
A = controldict,
}
- write_node(pdfannotation_node(0,0,0,action())) -- test: context(...)
+ write_node(nodeinjections.annotation(0,0,0,action())) -- test: context(...)
end
end
diff --git a/tex/context/base/lpdf-nod.lua b/tex/context/base/lpdf-nod.lua
index 68d7fca90..6295947d0 100644
--- a/tex/context/base/lpdf-nod.lua
+++ b/tex/context/base/lpdf-nod.lua
@@ -90,10 +90,10 @@ function nodepool.pdfsetmatrix(rx,sx,sy,ry,tx,ty) -- todo: tx ty
if rx == 1 and ry == 1 then
setfield(t,"data","1 0 0 1")
else
- setfield(t,"data",formatters["%0.6f 0 0 %0.6f"](rx,ry))
+ setfield(t,"data",formatters["%0.6F 0 0 %0.6F"](rx,ry))
end
else
- setfield(t,"data",formatters["%0.6f %0.6f %0.6f %0.6f"](rx,sx,sy,ry))
+ setfield(t,"data",formatters["%0.6F %0.6F %0.6F %0.6F"](rx,sx,sy,ry))
end
end
return t
@@ -103,24 +103,28 @@ nodeinjections.save = nodepool.pdfsave
nodeinjections.restore = nodepool.pdfrestore
nodeinjections.transform = nodepool.pdfsetmatrix
+-- the next one is implemented differently, using latelua
+
function nodepool.pdfannotation(w,h,d,data,n)
- local t = copy_node(pdfannot)
- if w and w ~= 0 then
- setfield(t,"width",w)
- end
- if h and h ~= 0 then
- setfield(t,"height",h)
- end
- if d and d ~= 0 then
- setfield(t,"depth",d)
- end
- if n then
- setfield(t,"objnum",n)
- end
- if data and data ~= "" then
- setfield(t,"data",data)
- end
- return t
+ report("don't use node based annotations!")
+ os.exit()
+-- local t = copy_node(pdfannot)
+-- if w and w ~= 0 then
+-- setfield(t,"width",w)
+-- end
+-- if h and h ~= 0 then
+-- setfield(t,"height",h)
+-- end
+-- if d and d ~= 0 then
+-- setfield(t,"depth",d)
+-- end
+-- if n then
+-- setfield(t,"objnum",n)
+-- end
+-- if data and data ~= "" then
+-- setfield(t,"data",data)
+-- end
+-- return t
end
-- (!) The next code in pdfdest.w is wrong:
@@ -137,41 +141,43 @@ end
-- so we need to force a matrix.
function nodepool.pdfdestination(w,h,d,name,view,n)
- local t = copy_node(pdfdest)
- local hasdimensions = false
- if w and w ~= 0 then
- setfield(t,"width",w)
- hasdimensions = true
- end
- if h and h ~= 0 then
- setfield(t,"height",h)
- hasdimensions = true
- end
- if d and d ~= 0 then
- setfield(t,"depth",d)
- hasdimensions = true
- end
- if n then
- setfield(t,"objnum",n)
- end
- view = views[view] or view or 1 -- fit is default
- setfield(t,"dest_id",name)
- setfield(t,"dest_type",view)
- if hasdimensions and view == 0 then -- xyz
- -- see (!) s -> m -> t -> r
- -- linked
- local s = copy_node(pdfsave)
- local m = copy_node(pdfsetmatrix)
- local r = copy_node(pdfrestore)
- setfield(m,"data","1 0 0 1")
- setfield(s,"next",m)
- setfield(m,"next",t)
- setfield(t,"next",r)
- setfield(m,"prev",s)
- setfield(t,"prev",m)
- setfield(r,"prev",t)
- return s -- a list
- else
- return t
- end
+ report("don't use node based destinations!")
+ os.exit()
+-- local t = copy_node(pdfdest)
+-- local hasdimensions = false
+-- if w and w ~= 0 then
+-- setfield(t,"width",w)
+-- hasdimensions = true
+-- end
+-- if h and h ~= 0 then
+-- setfield(t,"height",h)
+-- hasdimensions = true
+-- end
+-- if d and d ~= 0 then
+-- setfield(t,"depth",d)
+-- hasdimensions = true
+-- end
+-- if n then
+-- setfield(t,"objnum",n)
+-- end
+-- view = views[view] or view or 1 -- fit is default
+-- setfield(t,"dest_id",name)
+-- setfield(t,"dest_type",view)
+-- if hasdimensions and view == 0 then -- xyz
+-- -- see (!) s -> m -> t -> r
+-- -- linked
+-- local s = copy_node(pdfsave)
+-- local m = copy_node(pdfsetmatrix)
+-- local r = copy_node(pdfrestore)
+-- setfield(m,"data","1 0 0 1")
+-- setfield(s,"next",m)
+-- setfield(m,"next",t)
+-- setfield(t,"next",r)
+-- setfield(m,"prev",s)
+-- setfield(t,"prev",m)
+-- setfield(r,"prev",t)
+-- return s -- a list
+-- else
+-- return t
+-- end
end
diff --git a/tex/context/base/lpdf-ren.lua b/tex/context/base/lpdf-ren.lua
index 6af65f9de..37b706420 100644
--- a/tex/context/base/lpdf-ren.lua
+++ b/tex/context/base/lpdf-ren.lua
@@ -15,47 +15,51 @@ local settings_to_array = utilities.parsers.settings_to_array
local backends, lpdf, nodes, node = backends, lpdf, nodes, node
-local nodeinjections = backends.pdf.nodeinjections
-local codeinjections = backends.pdf.codeinjections
-local registrations = backends.pdf.registrations
-local viewerlayers = attributes.viewerlayers
+local nodeinjections = backends.pdf.nodeinjections
+local codeinjections = backends.pdf.codeinjections
+local registrations = backends.pdf.registrations
+local viewerlayers = attributes.viewerlayers
-local references = structures.references
+local references = structures.references
-references.executers = references.executers or { }
-local executers = references.executers
+references.executers = references.executers or { }
+local executers = references.executers
-local variables = interfaces.variables
+local variables = interfaces.variables
-local v_no = variables.no
-local v_yes = variables.yes
-local v_start = variables.start
-local v_stop = variables.stop
-local v_reset = variables.reset
-local v_auto = variables.auto
-local v_random = variables.random
+local v_no = variables.no
+local v_yes = variables.yes
+local v_start = variables.start
+local v_stop = variables.stop
+local v_reset = variables.reset
+local v_auto = variables.auto
+local v_random = variables.random
-local pdfconstant = lpdf.constant
-local pdfdictionary = lpdf.dictionary
-local pdfarray = lpdf.array
-local pdfreference = lpdf.reference
-local pdfflushobject = lpdf.flushobject
-local pdfreserveobject = lpdf.reserveobject
+local pdfconstant = lpdf.constant
+local pdfdictionary = lpdf.dictionary
+local pdfarray = lpdf.array
+local pdfreference = lpdf.reference
+local pdfflushobject = lpdf.flushobject
+local pdfreserveobject = lpdf.reserveobject
-local nodepool = nodes.pool
-local register = nodepool.register
-local pdfliteral = nodepool.pdfliteral
+local addtopageattributes = lpdf.addtopageattributes
+local addtopageresources = lpdf.addtopageresources
+local addtocatalog = lpdf.addtocatalog
-local pdf_ocg = pdfconstant("OCG")
-local pdf_ocmd = pdfconstant("OCMD")
-local pdf_off = pdfconstant("OFF")
-local pdf_on = pdfconstant("ON")
-local pdf_toggle = pdfconstant("Toggle")
-local pdf_setocgstate = pdfconstant("SetOCGState")
+local nodepool = nodes.pool
+local register = nodepool.register
+local pdfliteral = nodepool.pdfliteral
-local copy_node = node.copy
+local pdf_ocg = pdfconstant("OCG")
+local pdf_ocmd = pdfconstant("OCMD")
+local pdf_off = pdfconstant("OFF")
+local pdf_on = pdfconstant("ON")
+local pdf_toggle = pdfconstant("Toggle")
+local pdf_setocgstate = pdfconstant("SetOCGState")
-local lpdf_usage = pdfdictionary { Print = pdfdictionary { PrintState = pdf_off } }
+local copy_node = node.copy
+
+local lpdf_usage = pdfdictionary { Print = pdfdictionary { PrintState = pdf_off } }
-- We can have references to layers before they are places, for instance from
-- hide and vide actions. This is why we need to be able to force usage of layers
@@ -163,7 +167,7 @@ local function flushtextlayers()
BaseState = pdf_on,
},
}
- lpdf.addtocatalog("OCProperties",d)
+ addtocatalog("OCProperties",d)
textlayers = nil
end
end
@@ -171,7 +175,7 @@ end
local function flushpagelayers() -- we can share these
if pagelayers then
- lpdf.addtopageresources("Properties",pdfreference(pagelayersreference)) -- we could cache this
+ addtopageresources("Properties",pdfreference(pagelayersreference)) -- we could cache this
end
end
@@ -342,8 +346,8 @@ function codeinjections.setpagetransition(specification)
end
delay = tonumber(delay)
if delay and delay > 0 then
- lpdf.addtopageattributes("Dur",delay)
+ addtopageattributes("Dur",delay)
end
- lpdf.addtopageattributes("Trans",d)
+ addtopageattributes("Trans",d)
end
end
diff --git a/tex/context/base/lpdf-swf.lua b/tex/context/base/lpdf-swf.lua
index 12c80036f..88cdcc4ec 100644
--- a/tex/context/base/lpdf-swf.lua
+++ b/tex/context/base/lpdf-swf.lua
@@ -28,8 +28,6 @@ local checkedkey = lpdf.checkedkey
local codeinjections = backends.pdf.codeinjections
local nodeinjections = backends.pdf.nodeinjections
-local pdfannotation_node = nodes.pool.pdfannotation
-
local trace_swf = false trackers.register("backend.swf", function(v) trace_swf = v end)
local report_swf = logs.reporter("backend","swf")
@@ -302,5 +300,5 @@ function backends.pdf.nodeinjections.insertswf(spec)
-- factor = spec.factor,
-- label = spec.label,
}
- context(pdfannotation_node(spec.width,spec.height,0,annotation())) -- the context wrap is probably also needed elsewhere
+ context(nodeinjections.annotation(spec.width,spec.height,0,annotation())) -- the context wrap is probably also needed elsewhere
end
diff --git a/tex/context/base/lpdf-tag.lua b/tex/context/base/lpdf-tag.lua
index afddec345..276816e80 100644
--- a/tex/context/base/lpdf-tag.lua
+++ b/tex/context/base/lpdf-tag.lua
@@ -15,75 +15,78 @@ local trace_tags = false trackers.register("structures.tags", function(v) trace
local report_tags = logs.reporter("backend","tags")
-local backends = backends
-local lpdf = lpdf
-local nodes = nodes
-
-local nodeinjections = backends.pdf.nodeinjections
-local codeinjections = backends.pdf.codeinjections
-
-local tasks = nodes.tasks
-
-local pdfdictionary = lpdf.dictionary
-local pdfarray = lpdf.array
-local pdfboolean = lpdf.boolean
-local pdfconstant = lpdf.constant
-local pdfreference = lpdf.reference
-local pdfunicode = lpdf.unicode
-local pdfstring = lpdf.string
-local pdfflushobject = lpdf.flushobject
-local pdfreserveobject = lpdf.reserveobject
-local pdfpagereference = lpdf.pagereference
-
-local texgetcount = tex.getcount
-
-local nodecodes = nodes.nodecodes
-
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local glyph_code = nodecodes.glyph
-
-local a_tagged = attributes.private('tagged')
-local a_image = attributes.private('image')
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
-
-local nodepool = nuts.pool
-local pdfliteral = nodepool.pdfliteral
-
-local getid = nuts.getid
-local getattr = nuts.getattr
-local getprev = nuts.getprev
-local getnext = nuts.getnext
-local getlist = nuts.getlist
-local setfield = nuts.setfield
-
-local traverse_nodes = nuts.traverse
-local tosequence = nuts.tosequence
-local copy_node = nuts.copy
-local slide_nodelist = nuts.slide
-local insert_before = nuts.insert_before
-local insert_after = nuts.insert_after
-
-local structure_stack = { }
-local structure_kids = pdfarray()
-local structure_ref = pdfreserveobject()
-local parent_ref = pdfreserveobject()
-local root = { pref = pdfreference(structure_ref), kids = structure_kids }
-local tree = { }
-local elements = { }
-local names = pdfarray()
-local taglist = structures.tags.taglist
-local usedlabels = structures.tags.labels
-local properties = structures.tags.properties
-local usedmapping = { }
-
-local colonsplitter = lpeg.splitat(":")
-local dashsplitter = lpeg.splitat("-")
-
-local add_ids = false -- true
+local backends = backends
+local lpdf = lpdf
+local nodes = nodes
+
+local nodeinjections = backends.pdf.nodeinjections
+local codeinjections = backends.pdf.codeinjections
+
+local tasks = nodes.tasks
+
+local pdfdictionary = lpdf.dictionary
+local pdfarray = lpdf.array
+local pdfboolean = lpdf.boolean
+local pdfconstant = lpdf.constant
+local pdfreference = lpdf.reference
+local pdfunicode = lpdf.unicode
+local pdfstring = lpdf.string
+local pdfflushobject = lpdf.flushobject
+local pdfreserveobject = lpdf.reserveobject
+local pdfpagereference = lpdf.pagereference
+
+local addtocatalog = lpdf.addtocatalog
+local addtopageattributes = lpdf.addtopageattributes
+
+local texgetcount = tex.getcount
+
+local nodecodes = nodes.nodecodes
+
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local glyph_code = nodecodes.glyph
+
+local a_tagged = attributes.private('tagged')
+local a_image = attributes.private('image')
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+
+local nodepool = nuts.pool
+local pdfliteral = nodepool.pdfliteral
+
+local getid = nuts.getid
+local getattr = nuts.getattr
+local getprev = nuts.getprev
+local getnext = nuts.getnext
+local getlist = nuts.getlist
+local setfield = nuts.setfield
+
+local traverse_nodes = nuts.traverse
+local tosequence = nuts.tosequence
+local copy_node = nuts.copy
+local slide_nodelist = nuts.slide
+local insert_before = nuts.insert_before
+local insert_after = nuts.insert_after
+
+local structure_stack = { }
+local structure_kids = pdfarray()
+local structure_ref = pdfreserveobject()
+local parent_ref = pdfreserveobject()
+local root = { pref = pdfreference(structure_ref), kids = structure_kids }
+local tree = { }
+local elements = { }
+local names = pdfarray()
+local taglist = structures.tags.taglist
+local usedlabels = structures.tags.labels
+local properties = structures.tags.properties
+local usedmapping = { }
+
+local colonsplitter = lpeg.splitat(":")
+local dashsplitter = lpeg.splitat("-")
+
+local add_ids = false -- true
-- function codeinjections.maptag(original,target,kind)
-- mapping[original] = { target, kind or "inline" }
@@ -124,14 +127,14 @@ local function finishstructure()
RoleMap = rolemap,
}
pdfflushobject(structure_ref,structuretree)
- lpdf.addtocatalog("StructTreeRoot",pdfreference(structure_ref))
+ addtocatalog("StructTreeRoot",pdfreference(structure_ref))
--
local markinfo = pdfdictionary {
Marked = pdfboolean(true),
-- UserProperties = pdfboolean(true),
-- Suspects = pdfboolean(true),
}
- lpdf.addtocatalog("MarkInfo",pdfreference(pdfflushobject(markinfo)))
+ addtocatalog("MarkInfo",pdfreference(pdfflushobject(markinfo)))
--
for fulltag, element in next, elements do
pdfflushobject(element.knum,element.kids)
@@ -156,7 +159,7 @@ end
local function finishpage()
-- flush what can be flushed
- lpdf.addtopageattributes("StructParents",pagenum-1)
+ addtopageattributes("StructParents",pagenum-1)
end
-- here we can flush and free elements that are finished
diff --git a/tex/context/base/lpdf-u3d.lua b/tex/context/base/lpdf-u3d.lua
index 33269486c..f1df1d18e 100644
--- a/tex/context/base/lpdf-u3d.lua
+++ b/tex/context/base/lpdf-u3d.lua
@@ -38,8 +38,6 @@ local pdfflushstreamfileobject = lpdf.flushstreamfileobject
local checkedkey = lpdf.checkedkey
local limited = lpdf.limited
-local pdfannotation_node = nodes.pool.pdfannotation
-
local schemes = table.tohash {
"Artwork", "None", "White", "Day", "Night", "Hard",
"Primary", "Blue", "Red", "Cube", "CAD", "Headlamp",
@@ -462,7 +460,7 @@ local function insert3d(spec) -- width, height, factor, display, controls, label
},
ProcSet = pdfarray { pdfconstant("PDF"), pdfconstant("ImageC") },
}
- local pwd = pdfflushstreamobject(format("q /GS gs %f 0 0 %f 0 0 cm /IM Do Q",factor*width,factor*height),pw)
+ local pwd = pdfflushstreamobject(format("q /GS gs %F 0 0 %F 0 0 cm /IM Do Q",factor*width,factor*height),pw)
annot.AP = pdfdictionary {
N = pdfreference(pwd)
}
@@ -484,5 +482,5 @@ function nodeinjections.insertu3d(spec)
controls = spec.controls,
label = spec.label,
}
- node.write(pdfannotation_node(spec.width,spec.height,0,annotation()))
+ node.write(nodeinjections.annotation(spec.width,spec.height,0,annotation()))
end
diff --git a/tex/context/base/lpdf-wid.lua b/tex/context/base/lpdf-wid.lua
index 11ac82a08..39f2f690c 100644
--- a/tex/context/base/lpdf-wid.lua
+++ b/tex/context/base/lpdf-wid.lua
@@ -46,14 +46,13 @@ local pdfcolorspec = lpdf.colorspec
local pdfflushobject = lpdf.flushobject
local pdfflushstreamobject = lpdf.flushstreamobject
local pdfflushstreamfileobject = lpdf.flushstreamfileobject
-local pdfreserveannotation = lpdf.reserveannotation
local pdfreserveobject = lpdf.reserveobject
local pdfpagereference = lpdf.pagereference
local pdfshareobjectreference = lpdf.shareobjectreference
+local pdfaction = lpdf.action
-local nodepool = nodes.pool
-
-local pdfannotation_node = nodepool.pdfannotation
+local pdftransparencyvalue = lpdf.transparencyvalue
+local pdfcolorvalues = lpdf.colorvalues
local hpack_node = node.hpack
local write_node = node.write -- test context(...) instead
@@ -170,12 +169,12 @@ end
local function analyzecolor(colorvalue,colormodel)
local cvalue = colorvalue and tonumber(colorvalue)
local cmodel = colormodel and tonumber(colormodel) or 3
- return cvalue and pdfarray { lpdf.colorvalues(cmodel,cvalue) } or nil
+ return cvalue and pdfarray { pdfcolorvalues(cmodel,cvalue) } or nil
end
local function analyzetransparency(transparencyvalue)
local tvalue = transparencyvalue and tonumber(transparencyvalue)
- return tvalue and lpdf.transparencyvalue(tvalue) or nil
+ return tvalue and pdftransparencyvalue(tvalue) or nil
end
-- Attachments
@@ -342,7 +341,7 @@ function nodeinjections.attachfile(specification)
OC = analyzelayer(specification.layer),
}
local width, height, depth = specification.width or 0, specification.height or 0, specification.depth
- local box = hpack_node(pdfannotation_node(width,height,depth,d()))
+ local box = hpack_node(nodeinjections.annotation(width,height,depth,d()))
box.width, box.height, box.depth = width, height, depth
return box
end
@@ -427,19 +426,19 @@ function nodeinjections.comment(specification) -- brrr: seems to be done twice
local box
if usepopupcomments then
-- rather useless as we can hide/vide
- local nd = pdfreserveannotation()
- local nc = pdfreserveannotation()
+ local nd = pdfreserveobject()
+ local nc = pdfreserveobject()
local c = pdfdictionary {
Subtype = pdfconstant("Popup"),
Parent = pdfreference(nd),
}
d.Popup = pdfreference(nc)
box = hpack_node(
- pdfannotation_node(0,0,0,d(),nd),
- pdfannotation_node(width,height,depth,c(),nc)
+ nodeinjections.annotation(0,0,0,d(),nd),
+ nodeinjections.annotation(width,height,depth,c(),nc)
)
else
- box = hpack_node(pdfannotation_node(width,height,depth,d()))
+ box = hpack_node(nodeinjections.annotation(width,height,depth,d()))
end
box.width, box.height, box.depth = width, height, depth -- redundant
return box
@@ -484,7 +483,7 @@ end
local ms, mu, mf = { }, { }, { }
local function delayed(label)
- local a = pdfreserveannotation()
+ local a = pdfreserveobject()
mu[label] = a
return pdfreference(a)
end
@@ -504,12 +503,12 @@ local function insertrenderingwindow(specification)
local actions = nil
if openpage or closepage then
actions = pdfdictionary {
- PO = (openpage and lpdf.action(openpage )) or nil,
- PC = (closepage and lpdf.action(closepage)) or nil,
+ PO = (openpage and lpdfaction(openpage )) or nil,
+ PC = (closepage and lpdfaction(closepage)) or nil,
}
end
local page = tonumber(specification.page) or texgetcount("realpageno") -- todo
- local r = mu[label] or pdfreserveannotation() -- why the reserve here?
+ local r = mu[label] or pdfreserveobject() -- why the reserve here?
local a = pdfdictionary {
S = pdfconstant("Rendition"),
R = mf[label],
@@ -528,7 +527,7 @@ local function insertrenderingwindow(specification)
if height == 0 or width == 0 then
-- todo: sound needs no window
end
- write_node(pdfannotation_node(width,height,0,d(),r)) -- save ref
+ write_node(nodeinjections.annotation(width,height,0,d(),r)) -- save ref
return pdfreference(r)
end
@@ -539,7 +538,7 @@ local function insertrendering(specification)
local option = settings_to_hash(specification.option)
if not mf[label] then
local filename = specification.filename
- local isurl = find(filename,"://")
+ local isurl = find(filename,"://",1,true)
-- local start = pdfdictionary {
-- Type = pdfconstant("MediaOffset"),
-- S = pdfconstant("T"), -- time
diff --git a/tex/context/base/luat-cbk.lua b/tex/context/base/luat-cbk.lua
index 4f044f9ac..8c224ad2c 100644
--- a/tex/context/base/luat-cbk.lua
+++ b/tex/context/base/luat-cbk.lua
@@ -118,7 +118,7 @@ end
function callbacks.freeze(name,freeze)
freeze = type(freeze) == "string" and freeze
- if find(name,"%*") then
+ if find(name,"*",1,true) then
local pattern = name
for name, _ in next, list do
if find(name,pattern) then
diff --git a/tex/context/base/luat-cnf.lua b/tex/context/base/luat-cnf.lua
index 4ad6cd69d..fba2b71d1 100644
--- a/tex/context/base/luat-cnf.lua
+++ b/tex/context/base/luat-cnf.lua
@@ -134,13 +134,14 @@ function texconfig.init()
-- shortcut and helper
+ local bytecode = lua.bytecode
+
local function init(start)
- local b = lua.bytecode
local i = start
local t = os.clock()
- while b[i] do
- b[i]() ;
- b[i] = nil ;
+ while bytecode[i] do
+ bytecode[i]() ;
+ bytecode[i] = nil ;
i = i + 1
-- collectgarbage('step')
end
@@ -159,6 +160,8 @@ function texconfig.init()
end
end
+ texconfig.init = function() end
+
end
-- we provide a qualified path
diff --git a/tex/context/base/luat-cod.lua b/tex/context/base/luat-cod.lua
index 8b015477f..c16a3b110 100644
--- a/tex/context/base/luat-cod.lua
+++ b/tex/context/base/luat-cod.lua
@@ -51,6 +51,9 @@ function lua.registercode(filename,version)
bytecode[n] = code
lua.lastbytecode = n
end
+ elseif environment.initex then
+ texio.write_nl("\nerror loading file: " .. filename .. " (aborting)")
+ os.exit()
end
end
end
@@ -85,7 +88,7 @@ local environment = environment
-- no string.unquoted yet
local sourcefile = gsub(arg and arg[1] or "","^\"(.*)\"$","%1")
-local sourcepath = find(sourcefile,"/") and gsub(sourcefile,"/[^/]+$","") or ""
+local sourcepath = find(sourcefile,"/",1,true) and gsub(sourcefile,"/[^/]+$","") or ""
local targetpath = "."
-- delayed (via metatable):
diff --git a/tex/context/base/luat-ini.lua b/tex/context/base/luat-ini.lua
index 587214b93..9303b614a 100644
--- a/tex/context/base/luat-ini.lua
+++ b/tex/context/base/luat-ini.lua
@@ -72,6 +72,8 @@ lua.messages = lua.messages or { } local messages = lua.messages
storage.register("lua/numbers", numbers, "lua.numbers" )
storage.register("lua/messages", messages, "lua.messages")
+local f_message = string.formatters["=[instance: %s]"] -- the = controls the lua error / see: lobject.c
+
local setfenv = setfenv or debug.setfenv -- < 5.2
if setfenv then
@@ -183,7 +185,7 @@ elseif libraries then -- assume >= 5.2
messages[lnn] = message
numbers[name] = lnn
end
- luanames[lnn] = message
+ luanames[lnn] = f_message(message)
context(lnn)
end
@@ -198,7 +200,7 @@ else
messages[lnn] = message
numbers[name] = lnn
end
- luanames[lnn] = message
+ luanames[lnn] = f_message(message)
context(lnn)
end
diff --git a/tex/context/base/luat-ini.mkiv b/tex/context/base/luat-ini.mkiv
index a3a590311..7823ebd5a 100644
--- a/tex/context/base/luat-ini.mkiv
+++ b/tex/context/base/luat-ini.mkiv
@@ -120,23 +120,31 @@
\obeyluatokens
\csname\??luacode#1\endcsname}
+% \unexpanded\def\definenamedlua[#1]#2[#3]% no optional arg handling here yet / we could use numbers instead (more efficient)
+% {\ifcsname\??luacode#1\endcsname \else
+% \scratchcounter\ctxlua{lua.registername("#1","#3")}%
+% \normalexpanded{\xdef\csname\??luacode#1\endcsname##1\csname\e!stop#1\v!code\endcsname}%
+% {\noexpand\normalexpanded{\endgroup\noexpand\directlua\the\scratchcounter{_G=protect("#1\s!data")##1}}}%
+% \expandafter\edef\csname\e!start#1\v!code\endcsname {\luat_start_named_lua_code{#1}}%
+% \expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\the\scratchcounter{_G=protect("#1\s!data")##1}}%
+% \fi}
+
\unexpanded\def\definenamedlua[#1]#2[#3]% no optional arg handling here yet / we could use numbers instead (more efficient)
{\ifcsname\??luacode#1\endcsname \else
- \scratchcounter\ctxlua{lua.registername("#1","#3")}%
+ \expandafter\chardef\csname\??luacode:#1\endcsname\ctxlua{lua.registername("#1","#3")}%
\normalexpanded{\xdef\csname\??luacode#1\endcsname##1\csname\e!stop#1\v!code\endcsname}%
- %{\endgroup\noexpand\directlua\the\scratchcounter{local _ENV=protect("#1\s!data")##1}}%
- {\noexpand\normalexpanded{\endgroup\noexpand\directlua\the\scratchcounter{local _ENV=protect("#1\s!data")##1}}}%
+ {\noexpand\normalexpanded{\endgroup\noexpand\directlua\csname\??luacode:#1\endcsname{_G=protect("#1\s!data")##1}}}%
\expandafter\edef\csname\e!start#1\v!code\endcsname {\luat_start_named_lua_code{#1}}%
- \expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\the\scratchcounter{local _ENV=protect("#1\s!data")##1}}%
+ \expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\csname\??luacode:#1\endcsname{_G=protect("#1\s!data")##1}}%
\fi}
%D We predefine a few.
% \definenamedlua[module][module instance] % not needed
-\definenamedlua[user] [private user instance]
-\definenamedlua[third] [third party module instance]
-\definenamedlua[isolated][isolated instance]
+\definenamedlua[user] [private user]
+\definenamedlua[third] [third party module]
+\definenamedlua[isolated][isolated]
%D In practice this works out as follows:
%D
@@ -266,4 +274,53 @@
\def\luat_lua_code
{\normalexpanded{\endgroup\noexpand\directlua\expandafter{\the\scratchtoks}}} % \zerocount is default
+% \startctxfunction MyFunctionA
+% context(" A1 ")
+% \stopctxfunction
+%
+% \startctxfunctiondefinition MyFunctionB
+% context(" B2 ")
+% \stopctxfunctiondefinition
+%
+% \starttext
+% \dorecurse{10000}{\ctxfunction{MyFunctionA}} \page
+% \dorecurse{10000}{\MyFunctionB} \page
+% \dorecurse{10000}{\ctxlua{context(" C3 ")}} \page
+% \stoptext
+
+\installcorenamespace{ctxfunction}
+
+\normalprotected\def\startctxfunctiondefinition #1 %
+ {\begingroup \obeylualines \obeyluatokens \luat_start_lua_function_definition_indeed{#1}}
+
+% \def\luat_start_lua_function_definition_indeed#1#2\stopctxfunctiondefinition
+% {\endgroup\expandafter\edef\csname#1\endcsname{\noexpand\luafunction\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax}}
+
+\installcorenamespace{luafunction}
+
+\def\luat_start_lua_function_definition_indeed#1#2\stopctxfunctiondefinition
+ {\endgroup
+ \expandafter\chardef\csname\??luafunction#1\endcsname\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax
+ \expandafter\edef\csname#1\endcsname{\noexpand\luafunction\csname\??luafunction#1\endcsname}}
+
+% \unexpanded\def\setctxluafunction#1#2% experiment
+% {\expandafter\chardef\csname#1\endcsname#2\relax}
+
+\unexpanded\def\setctxluafunction#1#2% experiment
+ {\expandafter\chardef\csname\??luafunction#1\endcsname#2\relax
+ \expandafter\edef\csname#1\endcsname{\noexpand\luafunction\csname\??luafunction#1\endcsname}}
+
+\let\stopctxfunctiondefinition\relax
+
+\normalprotected\def\startctxfunction #1 %
+ {\begingroup \obeylualines \obeyluatokens \luat_start_lua_function_indeed{#1}}
+
+\def\luat_start_lua_function_indeed#1#2\stopctxfunction
+ {\endgroup\expandafter\edef\csname\??ctxfunction#1\endcsname{\noexpand\luafunction\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax}}
+
+\let\stopctxfunction\relax
+
+\def\ctxfunction#1%
+ {\csname\??ctxfunction#1\endcsname}
+
\protect \endinput
diff --git a/tex/context/base/luat-run.lua b/tex/context/base/luat-run.lua
index 719a6f7c9..ab4b3463c 100644
--- a/tex/context/base/luat-run.lua
+++ b/tex/context/base/luat-run.lua
@@ -6,8 +6,8 @@ if not modules then modules = { } end modules ['luat-run'] = {
license = "see context related readme files"
}
-local format = string.format
-local insert = table.insert
+local format, find = string.format, string.find
+local insert, remove = table.insert, table.remove
-- trace_job_status is also controlled by statistics.enable that is set via the directive system.nostatistics
@@ -158,3 +158,75 @@ statistics.register("synctex tracing",function()
return "synctex has been enabled (extra log file generated)"
end
end)
+
+-- filenames
+
+local types = {
+ "data",
+ "font map",
+ "image",
+ "font subset",
+ "full font",
+}
+
+local report_open = logs.reporter("open source")
+local report_close = logs.reporter("close source")
+local report_load = logs.reporter("load resource")
+
+local register = callbacks.register
+
+local level = 0
+local total = 0
+local stack = { }
+local all = true
+
+local function report_start(left,name)
+ if not left then
+ -- skip
+ elseif left ~= 1 then
+ if all then
+ report_load("%s > %s",types[left],name or "?")
+ end
+ elseif find(name,"virtual://") then
+ insert(stack,false)
+ else
+ insert(stack,name)
+ total = total + 1
+ level = level + 1
+ report_open("%i > %i > %s",level,total,name or "?")
+ end
+end
+
+local function report_stop(right)
+ if level == 1 or not right or right == 1 then
+ local name = remove(stack)
+ if name then
+ report_close("%i > %i > %s",level,total,name or "?")
+ level = level - 1
+ end
+ end
+end
+
+local function report_none()
+end
+
+register("start_file",report_start)
+register("stop_file", report_stop)
+
+directives.register("system.reportfiles", function(v)
+ if v == "noresources" then
+ all = false
+ register("start_file",report_start)
+ register("stop_file", report_stop)
+ elseif toboolean(v) or v == "all" then
+ all = true
+ register("start_file",report_start)
+ register("stop_file", report_stop)
+ elseif v == "traditional" then
+ register("start_file",nil)
+ register("stop_file", nil)
+ else
+ register("start_file",report_none)
+ register("stop_file", report_none)
+ end
+end)
diff --git a/tex/context/base/luat-sto.lua b/tex/context/base/luat-sto.lua
index 041050fb8..b04d655c2 100644
--- a/tex/context/base/luat-sto.lua
+++ b/tex/context/base/luat-sto.lua
@@ -13,6 +13,7 @@ local gmatch, format = string.gmatch, string.format
local serialize, concat, sortedhash = table.serialize, table.concat, table.sortedhash
local bytecode = lua.bytecode
local strippedloadstring = utilities.lua.strippedloadstring
+local formatters = string.formatters
local trace_storage = false
local report_storage = logs.reporter("system","storage")
@@ -48,38 +49,71 @@ function storage.register(...)
return t
end
-local n = 0
-local function dump()
- local max = storage.max
- for i=1,#data do
- local d = data[i]
- local message, original, target = d[1], d[2] ,d[3]
- local c, code, name = 0, { }, nil
- -- we have a nice definer for this
- for str in gmatch(target,"([^%.]+)") do
- if name then
- name = name .. "." .. str
+local n = 0 -- is that one used ?
+
+if environment.initex then
+
+ -- local function dump()
+ -- local max = storage.max
+ -- for i=1,#data do
+ -- local d = data[i]
+ -- local message, original, target = d[1], d[2] ,d[3]
+ -- local c, code, name = 0, { }, nil
+ -- -- we have a nice definer for this
+ -- for str in gmatch(target,"([^%.]+)") do
+ -- if name then
+ -- name = name .. "." .. str
+ -- else
+ -- name = str
+ -- end
+ -- c = c + 1 ; code[c] = formatters["%s = %s or { }"](name,name)
+ -- end
+ -- max = max + 1
+ -- if trace_storage then
+ -- c = c + 1 ; code[c] = formatters["print('restoring %s from slot %s')"](message,max)
+ -- end
+ -- c = c + 1 ; code[c] = serialize(original,name)
+ -- if trace_storage then
+ -- report_storage('saving %a in slot %a, size %s',message,max,#code[c])
+ -- end
+ -- -- we don't need tracing in such tables
+ -- bytecode[max] = strippedloadstring(concat(code,"\n"),storage.strip,format("slot %s (%s)",max,name))
+ -- collectgarbage("step")
+ -- end
+ -- storage.max = max
+ -- end
+
+ local function dump()
+ local max = storage.max
+ local strip = storage.strip
+ for i=1,#data do
+ max = max + 1
+ local tabledata = data[i]
+ local message = tabledata[1]
+ local original = tabledata[2]
+ local target = tabledata[3]
+ local definition = utilities.tables.definetable(target,false,true)
+ local comment = formatters["restoring %s from slot %s"](message,max)
+ if trace_storage then
+ comment = formatters["print('%s')"](comment)
else
- name = str
+ comment = formatters["-- %s"](comment)
end
- c = c + 1 ; code[c] = format("%s = %s or { }",name,name)
- end
- max = max + 1
- if trace_storage then
- c = c + 1 ; code[c] = format("print('restoring %s from slot %s')",message,max)
- end
- c = c + 1 ; code[c] = serialize(original,name)
- if trace_storage then
- report_storage('saving %a in slot %a, size %s',message,max,#code[c])
+ local dumped = serialize(original,target)
+ if trace_storage then
+ report_storage('saving %a in slot %a, size %s',message,max,#dumped)
+ end
+ -- we don't need tracing in such tables
+ dumped = concat({ definition, comment, dumped },"\n")
+ bytecode[max] = strippedloadstring(dumped,strip,formatters["slot %s (%s)"](max,name))
+ collectgarbage("step")
end
- -- we don't need tracing in such tables
- bytecode[max] = strippedloadstring(concat(code,"\n"),storage.strip,format("slot %s (%s)",max,name))
- collectgarbage("step")
+ storage.max = max
end
- storage.max = max
-end
-lua.registerfinalizer(dump,"dump storage")
+ lua.registerfinalizer(dump,"dump storage")
+
+end
-- to be tested with otf caching:
@@ -115,31 +149,14 @@ statistics.register("stored bytecode data", function()
local tofmodules = storage.tofmodules or 0
local tofdumps = storage.toftables or 0
if environment.initex then
- local luautilities = utilities.lua
- local nofstrippedbytes = luautilities.nofstrippedbytes
- local nofstrippedchunks = luautilities.nofstrippedchunks
- if nofstrippedbytes > 0 then
- return format("%s modules, %s tables, %s chunks, %s chunks stripped (%s bytes)",
- nofmodules,
- nofdumps,
- nofmodules + nofdumps,
- nofstrippedchunks,
- nofstrippedbytes
- )
- elseif nofstrippedchunks > 0 then
- return format("%s modules, %s tables, %s chunks, %s chunks stripped",
- nofmodules,
- nofdumps,
- nofmodules + nofdumps,
- nofstrippedchunks
- )
- else
- return format("%s modules, %s tables, %s chunks",
- nofmodules,
- nofdumps,
- nofmodules + nofdumps
- )
- end
+ local luautilities = utilities.lua
+ return format("%s modules, %s tables, %s chunks, %s chunks stripped (%s bytes)",
+ nofmodules,
+ nofdumps,
+ nofmodules + nofdumps,
+ luautilities.nofstrippedchunks or 0,
+ luautilities.nofstrippedbytes or 0
+ )
else
return format("%s modules (%0.3f sec), %s tables (%0.3f sec), %s chunks (%0.3f sec)",
nofmodules, tofmodules,
diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua
index 51ab321b9..8567f2623 100644
--- a/tex/context/base/lxml-lpt.lua
+++ b/tex/context/base/lxml-lpt.lua
@@ -1039,37 +1039,6 @@ local function normal_apply(list,parsed,nofparsed,order)
return collected
end
---~ local function applylpath(list,pattern)
---~ -- we avoid an extra call
---~ local parsed = cache[pattern]
---~ if parsed then
---~ lpathcalls = lpathcalls + 1
---~ lpathcached = lpathcached + 1
---~ elseif type(pattern) == "table" then
---~ lpathcalls = lpathcalls + 1
---~ parsed = pattern
---~ else
---~ parsed = lpath(pattern) or pattern
---~ end
---~ if not parsed then
---~ return
---~ end
---~ local nofparsed = #parsed
---~ if nofparsed == 0 then
---~ return -- something is wrong
---~ end
---~ local one = list[1] -- we could have a third argument: isroot and list or list[1] or whatever we like ... todo
---~ if not one then
---~ return -- something is wrong
---~ elseif not trace_lpath then
---~ return normal_apply(list,parsed,nofparsed,one.mi)
---~ elseif trace_lprofile then
---~ return profiled_apply(list,parsed,nofparsed,one.mi)
---~ else
---~ return traced_apply(list,parsed,nofparsed,one.mi)
---~ end
---~ end
-
local function applylpath(list,pattern)
if not list then
return
@@ -1384,8 +1353,13 @@ function xml.elements(root,pattern,reverse) -- r, d, k
local collected = applylpath(root,pattern)
if not collected then
return dummy
- elseif reverse then
- local c = #collected + 1
+ end
+ local n = #collected
+ if n == 0 then
+ return dummy
+ end
+ if reverse then
+ local c = n + 1
return function()
if c > 1 then
c = c - 1
@@ -1395,7 +1369,7 @@ function xml.elements(root,pattern,reverse) -- r, d, k
end
end
else
- local n, c = #collected, 0
+ local c = 0
return function()
if c < n then
c = c + 1
@@ -1411,8 +1385,13 @@ function xml.collected(root,pattern,reverse) -- e
local collected = applylpath(root,pattern)
if not collected then
return dummy
- elseif reverse then
- local c = #collected + 1
+ end
+ local n = #collected
+ if n == 0 then
+ return dummy
+ end
+ if reverse then
+ local c = n + 1
return function()
if c > 1 then
c = c - 1
@@ -1420,7 +1399,7 @@ function xml.collected(root,pattern,reverse) -- e
end
end
else
- local n, c = #collected, 0
+ local c = 0
return function()
if c < n then
c = c + 1
@@ -1441,7 +1420,7 @@ end
-- texy (see xfdf):
-local function split(e)
+local function split(e) -- todo: use helpers / lpeg
local dt = e.dt
if dt then
for i=1,#dt do
diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua
index 2cbdfc886..111b1445a 100644
--- a/tex/context/base/lxml-tex.lua
+++ b/tex/context/base/lxml-tex.lua
@@ -36,6 +36,7 @@ local xmlwithelements = xml.withelements
local xmlserialize, xmlcollect, xmltext, xmltostring = xml.serialize, xml.collect, xml.text, xml.tostring
local xmlapplylpath = xml.applylpath
local xmlunprivatized, xmlprivatetoken, xmlprivatecodes = xml.unprivatized, xml.privatetoken, xml.privatecodes
+local xmlstripelement = xml.stripelement
local variables = (interfaces and interfaces.variables) or { }
@@ -915,16 +916,18 @@ function lxml.setsetup(id,pattern,setup)
end
end
end
+ elseif setup == "-" then
+ for c=1,nc do
+ collected[c].command = false
+ end
+ elseif setup == "+" then
+ for c=1,nc do
+ collected[c].command = true
+ end
else
for c=1,nc do
local e = collected[c]
- if setup == "-" then
- e.command = false
- elseif setup == "+" then
- e.command = true
- else
- e.command = e.tg
- end
+ e.command = e.tg
end
end
elseif trace_setups then
@@ -967,16 +970,18 @@ function lxml.setsetup(id,pattern,setup)
end
end
end
+ elseif b == "-" then
+ for c=1,nc do
+ collected[c].command = false
+ end
+ elseif b == "+" then
+ for c=1,nc do
+ collected[c].command = true
+ end
else
for c=1,nc do
local e = collected[c]
- if b == "-" then
- e.command = false
- elseif b == "+" then
- e.command = true
- else
- e.command = a .. e.tg
- end
+ e.command = a .. e.tg
end
end
elseif trace_setups then
@@ -1186,7 +1191,7 @@ local function stripped(collected) -- tricky as we strip in place
local nc = #collected
if nc > 0 then
for c=1,nc do
- cprint(xml.stripelement(collected[c]))
+ cprint(xmlstripelement(collected[c]))
end
end
end
@@ -1311,10 +1316,11 @@ function texfinalizers.name(collected,n)
c = collected[nc-n+1]
end
if c then
- if c.ns == "" then
+ local ns = c.ns
+ if not ns or ns == "" then
contextsprint(ctxcatcodes,c.tg)
else
- contextsprint(ctxcatcodes,c.ns,":",c.tg)
+ contextsprint(ctxcatcodes,ns,":",c.tg)
end
end
end
@@ -1327,11 +1333,11 @@ function texfinalizers.tags(collected,nonamespace)
if nc > 0 then
for c=1,nc do
local e = collected[c]
- local ns, tg = e.ns, e.tg
- if nonamespace or ns == "" then
- contextsprint(ctxcatcodes,tg)
+ local ns = e.ns
+ if nonamespace or (not ns or ns == "") then
+ contextsprint(ctxcatcodes,e.tg)
else
- contextsprint(ctxcatcodes,ns,":",tg)
+ contextsprint(ctxcatcodes,ns,":",e.tg)
end
end
end
@@ -1341,11 +1347,10 @@ end
--
local function verbatim(id,before,after)
- local root = getid(id)
- if root then
- if before then contextsprint(ctxcatcodes,before,"[",root.tg or "?","]") end
- lxml.toverbatim(xmltostring(root.dt))
---~ lxml.toverbatim(xml.totext(root.dt))
+ local e = getid(id)
+ if e then
+ if before then contextsprint(ctxcatcodes,before,"[",e.tg or "?","]") end
+ lxml.toverbatim(xmltostring(e.dt)) -- lxml.toverbatim(xml.totext(e.dt))
if after then contextsprint(ctxcatcodes,after) end
end
end
@@ -1451,66 +1456,112 @@ end
lxml.index = lxml.position
function lxml.pos(id)
- local root = getid(id)
- contextsprint(ctxcatcodes,(root and root.ni) or 0)
-end
+ local e = getid(id)
+ contextsprint(ctxcatcodes,e and e.ni or 0)
+end
+
+-- function lxml.att(id,a,default)
+-- local root = getid(id)
+-- if root then
+-- local at = root.at
+-- local str = (at and at[a]) or default
+-- if str and str ~= "" then
+-- contextsprint(notcatcodes,str)
+-- end
+-- elseif default then
+-- contextsprint(notcatcodes,default)
+-- end
+-- end
+--
+-- no need for an assignment so:
function lxml.att(id,a,default)
- local root = getid(id)
- if root then
- local at = root.at
- local str = (at and at[a]) or default
- if str and str ~= "" then
- contextsprint(notcatcodes,str)
+ local e = getid(id)
+ if e then
+ local at = e.at
+ if at then
+ -- normally always true
+ local str = at[a]
+ if not str then
+ if default and default ~= "" then
+ contextsprint(notcatcodes,default)
+ end
+ elseif str ~= "" then
+ contextsprint(notcatcodes,str)
+ end
+ elseif default and default ~= "" then
+ contextsprint(notcatcodes,default)
end
- elseif default then
+ elseif default and default ~= "" then
contextsprint(notcatcodes,default)
end
end
function lxml.name(id) -- or remapped name? -> lxml.info, combine
- local r = getid(id)
- local ns = r.rn or r.ns or ""
- if ns ~= "" then
- contextsprint(ctxcatcodes,ns,":",r.tg)
- else
- contextsprint(ctxcatcodes,r.tg)
+ local e = getid(id)
+ if e then
+ local ns = e.rn or e.ns
+ if ns and ns ~= "" then
+ contextsprint(ctxcatcodes,ns,":",e.tg)
+ else
+ contextsprint(ctxcatcodes,e.tg)
+ end
end
end
function lxml.match(id) -- or remapped name? -> lxml.info, combine
- contextsprint(ctxcatcodes,getid(id).mi or 0)
+ local e = getid(id)
+ contextsprint(ctxcatcodes,e and e.mi or 0)
end
function lxml.tag(id) -- tag vs name -> also in l-xml tag->name
- contextsprint(ctxcatcodes,getid(id).tg or "")
+ local e = getid(id)
+ if e then
+ local tg = e.tg
+ if tg and tg ~= "" then
+ contextsprint(ctxcatcodes,tg)
+ end
+ end
end
function lxml.namespace(id) -- or remapped name?
- local root = getid(id)
- contextsprint(ctxcatcodes,root.rn or root.ns or "")
+ local e = getid(id)
+ if e then
+ local ns = e.rn or e.ns
+ if ns and ns ~= "" then
+ contextsprint(ctxcatcodes,ns)
+ end
+ end
end
function lxml.flush(id)
- id = getid(id)
- local dt = id and id.dt
- if dt then
- xmlsprint(dt)
+ local e = getid(id)
+ if e then
+ local dt = e.dt
+ if dt then
+ xmlsprint(dt)
+ end
end
end
function lxml.snippet(id,i)
local e = getid(id)
if e then
- local edt = e.dt
- if edt then
- xmlsprint(edt[i])
+ local dt = e.dt
+ if dt then
+ local dti = dt[i]
+ if dti then
+ xmlsprint(dti)
+ end
end
end
end
function lxml.direct(id)
- xmlsprint(getid(id))
+ local e = getid(id)
+ if e then
+ xmlsprint(e)
+ end
end
function lxml.command(id,pattern,cmd)
diff --git a/tex/context/base/m-spreadsheet.lua b/tex/context/base/m-spreadsheet.lua
index f329acf9a..1b3c5cb34 100644
--- a/tex/context/base/m-spreadsheet.lua
+++ b/tex/context/base/m-spreadsheet.lua
@@ -129,10 +129,10 @@ function datacell(a,b,...)
end
local function checktemplate(s)
- if find(s,"%%") then
+ if find(s,"%",1,true) then
-- normal template
return s
- elseif find(s,"@") then
+ elseif find(s,"@",1,true) then
-- tex specific template
return gsub(s,"@","%%")
else
diff --git a/tex/context/base/math-dir.lua b/tex/context/base/math-dir.lua
index 525d07831..bcc5461e9 100644
--- a/tex/context/base/math-dir.lua
+++ b/tex/context/base/math-dir.lua
@@ -33,6 +33,7 @@ local getid = nuts.getid
local getlist = nuts.getlist
local setfield = nuts.setfield
local getattr = nuts.getattr
+local setattr = nuts.setattr
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
diff --git a/tex/context/base/math-fbk.lua b/tex/context/base/math-fbk.lua
index f4bd1348a..70a8ae8d6 100644
--- a/tex/context/base/math-fbk.lua
+++ b/tex/context/base/math-fbk.lua
@@ -180,12 +180,12 @@ end
-- virtualcharacters[0x208B] = 0x002B
virtualcharacters[0x207A] = function(data)
- data.replacement = 0x2212
+ data.replacement = 0x002B
return raised(data)
end
virtualcharacters[0x207B] = function(data)
- data.replacement = 0x002B
+ data.replacement = 0x2212
return raised(data)
end
@@ -512,7 +512,7 @@ addextra(0xFE940, { category = "mn", description="SMALL ANNUITY SYMBOL", unicode
local function actuarian(data)
local characters = data.target.characters
local parameters = data.target.parameters
- local basechar = characters[0x0078] -- x (0x0058 X)
+ local basechar = characters[0x0078] -- x (0x0058 X) or 0x1D431
local linewidth = parameters.xheight / 10
local basewidth = basechar.width
local baseheight = basechar.height
diff --git a/tex/context/base/math-fen.mkiv b/tex/context/base/math-fen.mkiv
index fe959cc1e..33afbf675 100644
--- a/tex/context/base/math-fen.mkiv
+++ b/tex/context/base/math-fen.mkiv
@@ -235,6 +235,7 @@
\expandafter\let\csname\??mathright\meaning ⟫\endcsname\Rdoubleangle
\expandafter\let\csname\??mathright\meaning }\endcsname\Rbrace
\expandafter\let\csname\??mathright\meaning |\endcsname\Rbar
+\expandafter\let\csname\??mathright\meaning ‖\endcsname\Rdoublebar
\expandafter\let\csname\??mathright\meaning ⦀\endcsname\Rtriplebar
\expandafter\let\csname\??mathright\meaning /\endcsname\Rsolidus
\expandafter\let\csname\??mathright\meaning .\endcsname\Rnothing
diff --git a/tex/context/base/math-frc.mkiv b/tex/context/base/math-frc.mkiv
index 65fa30942..f4f3f2b84 100644
--- a/tex/context/base/math-frc.mkiv
+++ b/tex/context/base/math-frc.mkiv
@@ -274,7 +274,7 @@
%D \getbuffer
\unexpanded\def\cfrac
- {\doifnextoptionalelse\math_cfrac_yes\math_cfrac_nop}
+ {\doifnextoptionalcselse\math_cfrac_yes\math_cfrac_nop}
\def\math_cfrac_nop {\math_cfrac_indeed[cc]}
\def\math_cfrac_yes[#1]{\math_cfrac_indeed[#1cc]}
diff --git a/tex/context/base/math-ini.lua b/tex/context/base/math-ini.lua
index 1351559a0..9772ce538 100644
--- a/tex/context/base/math-ini.lua
+++ b/tex/context/base/math-ini.lua
@@ -22,8 +22,8 @@ local floor = math.floor
local context = context
local commands = commands
-local contextsprint = context.sprint
-local contextfprint = context.fprint -- a bit inefficient
+local context_sprint = context.sprint
+----- context_fprint = context.fprint -- a bit inefficient
local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
@@ -213,28 +213,28 @@ local f_char = formatters[ [[\Umathchardef\%s "%X "%X "%X ]] ]
local setmathsymbol = function(name,class,family,slot) -- hex is nicer for tracing
if class == classes.accent then
- contextsprint(f_accent(name,family,slot))
+ context_sprint(f_accent(name,family,slot))
elseif class == classes.topaccent then
- contextsprint(f_topaccent(name,family,slot))
+ context_sprint(f_topaccent(name,family,slot))
elseif class == classes.botaccent then
- contextsprint(f_botaccent(name,family,slot))
+ context_sprint(f_botaccent(name,family,slot))
elseif class == classes.over then
- contextsprint(f_over(name,family,slot))
+ context_sprint(f_over(name,family,slot))
elseif class == classes.under then
- contextsprint(f_under(name,family,slot))
+ context_sprint(f_under(name,family,slot))
elseif class == open_class or class == close_class or class == middle_class then
setdelcode("global",slot,{family,slot,0,0})
- contextsprint(f_fence(name,class,family,slot))
+ context_sprint(f_fence(name,class,family,slot))
elseif class == classes.delimiter then
setdelcode("global",slot,{family,slot,0,0})
- contextsprint(f_delimiter(name,family,slot))
+ context_sprint(f_delimiter(name,family,slot))
elseif class == classes.radical then
- contextsprint(f_radical(name,family,slot))
+ context_sprint(f_radical(name,family,slot))
elseif class == classes.root then
- contextsprint(f_root(name,family,slot))
+ context_sprint(f_root(name,family,slot))
else
-- beware, open/close and other specials should not end up here
- contextsprint(f_char(name,class,family,slot))
+ context_sprint(f_char(name,class,family,slot))
end
end
diff --git a/tex/context/base/math-ini.mkiv b/tex/context/base/math-ini.mkiv
index bf9f5278c..38069eba7 100644
--- a/tex/context/base/math-ini.mkiv
+++ b/tex/context/base/math-ini.mkiv
@@ -117,7 +117,7 @@
\installswitchcommandhandler \??mathematics {mathematics} \??mathematics
\unexpanded\def\startmathematics % no grouping, if ever then also an optional second
- {\doifnextoptionalelse\math_mathematics_start_yes\math_mathematics_start_nop}
+ {\doifnextoptionalcselse\math_mathematics_start_yes\math_mathematics_start_nop}
\unexpanded\def\math_mathematics_start_yes[#1]%
{\pushmacro\currentmathematics
@@ -366,10 +366,39 @@
%D Let's define a few comands here:
-\definemathcommand [mathstrut] {\vphantom{(}}
+%definemathcommand [mathstrut] {\vphantom{(}}
%definemathcommand [joinrel] {\mathrel{\mkern-3mu}}
\definemathcommand [joinrel] [rel] {\mkern-3mu}
+\chardef\c_math_strut"28
+
+\unexpanded\def\math_strut_htdp#1%
+ {\s!height\fontcharht#1\c_math_strut
+ \s!depth \fontchardp#1\c_math_strut}
+
+\unexpanded\def\math_strut_normal
+ {\vrule
+ \normalexpanded{\math_strut_htdp{\mathstylefont\normalmathstyle}}%
+ \s!width \zeropoint
+ \relax}
+
+\unexpanded\def\math_strut_visual
+ {\hskip-.01\emwidth
+ \vrule
+ \normalexpanded{\math_strut_htdp{\mathstylefont\normalmathstyle}}%
+ \s!width .02\emwidth
+ \relax
+ \hskip-.01\emwidth}
+
+\unexpanded\def\showmathstruts % let's not overload \nath_strut_normal
+ {\let\math_strut\math_strut_visual}
+
+\let\math_strut\math_strut_normal
+
+% \unexpanded\def\mathstrut{\mathcodecommand{nothing}{\math_strut}}
+
+\definemathcommand [mathstrut] {\math_strut}
+
%D We could have a arg variant \unknown\ but not now.
\unexpanded\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits}
diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua
index 4e25fe206..a7f0fcf55 100644
--- a/tex/context/base/math-noa.lua
+++ b/tex/context/base/math-noa.lua
@@ -60,15 +60,14 @@ local tonut = nuts.tonut
local nutstring = nuts.tostring
local getfield = nuts.getfield
+local setfield = nuts.setfield
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
-local getattr = nuts.getattr
local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
local getchar = nuts.getchar
-
-local setfield = nuts.setfield
+local getattr = nuts.getattr
local setattr = nuts.setattr
local insert_node_after = nuts.insert_after
diff --git a/tex/context/base/math-rad.mkvi b/tex/context/base/math-rad.mkvi
index c6053071e..f27114b88 100644
--- a/tex/context/base/math-rad.mkvi
+++ b/tex/context/base/math-rad.mkvi
@@ -28,7 +28,7 @@
\def\root#1\of{\rootradical{#1}} % #2
-\unexpanded\def\sqrt{\doifnextoptionalelse\rootwithdegree\rootwithoutdegree}
+\unexpanded\def\sqrt{\doifnextoptionalcselse\rootwithdegree\rootwithoutdegree}
\def\styledrootradical#1#2% so that \text works ok ... \rootradical behaves somewhat weird
{\normalexpanded{\rootradical{\normalunexpanded{#1}}{\noexpand\triggermathstyle{\normalmathstyle}\normalunexpanded{#2}}}}
@@ -62,7 +62,7 @@
\unexpanded\def\math_radical_handle#tag%
{\begingroup
\edef\currentmathradical{#tag}%
- \doifnextoptionalelse\math_radical_degree_yes\math_radical_degree_nop}
+ \doifnextoptionalcselse\math_radical_degree_yes\math_radical_degree_nop}
\def\math_radical_alternative{\csname\??mathradicalalternative\mathradicalparameter\c!alternative\endcsname}
diff --git a/tex/context/base/meta-fnt.lua b/tex/context/base/meta-fnt.lua
index cf47f0c92..596d0f456 100644
--- a/tex/context/base/meta-fnt.lua
+++ b/tex/context/base/meta-fnt.lua
@@ -29,7 +29,7 @@ local characters, descriptions = { }, { }
local factor, code, slot, width, height, depth, total, variants, bbox, llx, lly, urx, ury = 100, { }, 0, 0, 0, 0, 0, 0, true, 0, 0, 0, 0
-- The next variant of ActualText is what Taco and I could come up with
--- eventually. As of September 2013 Acrobat copies okay, Summatra copies a
+-- eventually. As of September 2013 Acrobat copies okay, Sumatra copies a
-- question mark, pdftotext injects an extra space and Okular adds a
-- newline plus space.
@@ -79,7 +79,7 @@ local flusher = {
if inline then
characters[slot] = {
commands = {
- { "special", "pdf: " .. topdf(slot,code) },
+ { "special", "pdf:" .. topdf(slot,code) },
}
}
else
diff --git a/tex/context/base/meta-pdf.lua b/tex/context/base/meta-pdf.lua
index 46e20ad31..512384450 100644
--- a/tex/context/base/meta-pdf.lua
+++ b/tex/context/base/meta-pdf.lua
@@ -38,8 +38,8 @@ local mptopdf = metapost.mptopdf
mptopdf.nofconverted = 0
-local f_translate = formatters["1 0 0 0 1 %f %f cm"] -- no %s due to 1e-035 issues
-local f_concat = formatters["%f %f %f %f %f %f cm"] -- no %s due to 1e-035 issues
+local f_translate = formatters["1 0 0 0 1 %F %F cm"] -- no %s due to 1e-035 issues
+local f_concat = formatters["%F %F %F %F %F %F cm"] -- no %s due to 1e-035 issues
local m_path, m_stack, m_texts, m_version, m_date, m_shortcuts = { }, { }, { }, 0, 0, false
diff --git a/tex/context/base/meta-tex.mkiv b/tex/context/base/meta-tex.mkiv
index deac883c8..c690765fd 100644
--- a/tex/context/base/meta-tex.mkiv
+++ b/tex/context/base/meta-tex.mkiv
@@ -68,7 +68,7 @@
\unexpanded\def\definetextext[#1]%
{\def\currenttextext{#1}%
- \doifnextoptionalelse\meta_textext_define_one\meta_textext_define_zero}
+ \doifnextoptionalcselse\meta_textext_define_one\meta_textext_define_zero}
\def\meta_textext_define_one {\setvalue{\??graphictexarguments1:\currenttextext}}
\def\meta_textext_define_zero{\setvalue{\??graphictexarguments0:\currenttextext}}
@@ -79,7 +79,7 @@
{textext.drt("\mpsometxt#1{\ctxlua{metapost.escaped(\!!bs#2\!!es)}}")}
\unexpanded\def\mpsometxt % no _ catcode
- {\doifnextoptionalelse\meta_some_txt_indeed_yes\meta_some_txt_indeed_nop}
+ {\doifnextoptionalcselse\meta_some_txt_indeed_yes\meta_some_txt_indeed_nop}
\def\meta_some_txt_indeed_yes[#1]%
{\def\currenttextext{#1}%
diff --git a/tex/context/base/mlib-pdf.lua b/tex/context/base/mlib-pdf.lua
index 6bb08bd1d..d25dde884 100644
--- a/tex/context/base/mlib-pdf.lua
+++ b/tex/context/base/mlib-pdf.lua
@@ -41,6 +41,18 @@ local experiment = true -- uses context(node) that already does delayed nod
local savedliterals = nil -- needs checking
local mpsliteral = nodes.pool.register(node.new("whatsit",nodes.whatsitcodes.pdfliteral)) -- pdfliteral.mode = 1
+local f_f = formatters["%F"]
+
+local f_m = formatters["%F %F m"]
+local f_c = formatters["%F %F %F %F %F %F c"]
+local f_l = formatters["%F %F l"]
+local f_cm = formatters["%F %F %F %F %F %F cm"]
+local f_M = formatters["%F M"]
+local f_j = formatters["%i j"]
+local f_J = formatters["%i J"]
+local f_d = formatters["[%s] %F d"]
+local f_w = formatters["%F w"]
+
local pdfliteral = function(s)
local literal = copy_node(mpsliteral)
literal.data = s
@@ -119,7 +131,7 @@ end
function pdfflusher.startfigure(n,llx,lly,urx,ury,message)
savedliterals = nil
metapost.n = metapost.n + 1
- context.startMPLIBtoPDF(llx,lly,urx,ury)
+ context.startMPLIBtoPDF(f_f(llx),f_f(lly),f_f(urx),f_f(ury))
if message then pdfflusher.comment(message) end
end
@@ -192,11 +204,11 @@ local function flushnormalpath(path, t, open)
nt = nt + 1
pth = path[i]
if not ith then
- t[nt] = formatters["%f %f m"](pth.x_coord,pth.y_coord)
+ t[nt] = f_m(pth.x_coord,pth.y_coord)
elseif curved(ith,pth) then
- t[nt] = formatters["%f %f %f %f %f %f c"](ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord)
+ t[nt] = f_c(ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord)
else
- t[nt] = formatters["%f %f l"](pth.x_coord,pth.y_coord)
+ t[nt] = f_l(pth.x_coord,pth.y_coord)
end
ith = pth
end
@@ -204,15 +216,15 @@ local function flushnormalpath(path, t, open)
nt = nt + 1
local one = path[1]
if curved(pth,one) then
- t[nt] = formatters["%f %f %f %f %f %f c"](pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord )
+ t[nt] = f_c(pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord )
else
- t[nt] = formatters["%f %f l"](one.x_coord,one.y_coord)
+ t[nt] = f_l(one.x_coord,one.y_coord)
end
elseif #path == 1 then
-- special case .. draw point
local one = path[1]
nt = nt + 1
- t[nt] = formatters["%f %f l"](one.x_coord,one.y_coord)
+ t[nt] = f_l(one.x_coord,one.y_coord)
end
return t
end
@@ -226,18 +238,18 @@ local function flushconcatpath(path, t, open)
nt = 0
end
nt = nt + 1
- t[nt] = formatters["%f %f %f %f %f %f cm"](sx,rx,ry,sy,tx,ty)
+ t[nt] = f_cm(sx,rx,ry,sy,tx,ty)
for i=1,#path do
nt = nt + 1
pth = path[i]
if not ith then
- t[nt] = formatters["%f %f m"](mpconcat(pth.x_coord,pth.y_coord))
+ t[nt] = f_m(mpconcat(pth.x_coord,pth.y_coord))
elseif curved(ith,pth) then
local a, b = mpconcat(ith.right_x,ith.right_y)
local c, d = mpconcat(pth.left_x,pth.left_y)
- t[nt] = formatters["%f %f %f %f %f %f c"](a,b,c,d,mpconcat(pth.x_coord,pth.y_coord))
+ t[nt] = f_c(a,b,c,d,mpconcat(pth.x_coord,pth.y_coord))
else
- t[nt] = formatters["%f %f l"](mpconcat(pth.x_coord, pth.y_coord))
+ t[nt] = f_l(mpconcat(pth.x_coord, pth.y_coord))
end
ith = pth
end
@@ -247,15 +259,15 @@ local function flushconcatpath(path, t, open)
if curved(pth,one) then
local a, b = mpconcat(pth.right_x,pth.right_y)
local c, d = mpconcat(one.left_x,one.left_y)
- t[nt] = formatters["%f %f %f %f %f %f c"](a,b,c,d,mpconcat(one.x_coord, one.y_coord))
+ t[nt] = f_c(a,b,c,d,mpconcat(one.x_coord, one.y_coord))
else
- t[nt] = formatters["%f %f l"](mpconcat(one.x_coord,one.y_coord))
+ t[nt] = f_l(mpconcat(one.x_coord,one.y_coord))
end
elseif #path == 1 then
-- special case .. draw point
nt = nt + 1
local one = path[1]
- t[nt] = formatters["%f %f l"](mpconcat(one.x_coord,one.y_coord))
+ t[nt] = f_l(mpconcat(one.x_coord,one.y_coord))
end
return t
end
@@ -431,7 +443,7 @@ function metapost.flush(result,flusher,askedfig)
elseif objecttype == "text" then
t[#t+1] = "q"
local ot = object.transform -- 3,4,5,6,1,2
- t[#t+1] = formatters["%f %f %f %f %f %f cm"](ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%f %f m %f %f %f %f 0 0 cm"](unpack(ot))
+ t[#t+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%F %F m %F %F %F %F 0 0 cm"](unpack(ot))
flushfigure(t) -- flush accumulated literals
t = { }
textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth)
@@ -456,21 +468,21 @@ function metapost.flush(result,flusher,askedfig)
local ml = object.miterlimit
if ml and ml ~= miterlimit then
miterlimit = ml
- t[#t+1] = formatters["%f M"](ml)
+ t[#t+1] = f_M(ml)
end
local lj = object.linejoin
if lj and lj ~= linejoin then
linejoin = lj
- t[#t+1] = formatters["%i j"](lj)
+ t[#t+1] = f_j(lj)
end
local lc = object.linecap
if lc and lc ~= linecap then
linecap = lc
- t[#t+1] = formatters["%i J"](lc)
+ t[#t+1] = f_J(lc)
end
local dl = object.dash
if dl then
- local d = formatters["[%s] %f d"](concat(dl.dashes or {}," "),dl.offset)
+ local d = f_d(concat(dl.dashes or {}," "),dl.offset)
if d ~= dashed then
dashed = d
t[#t+1] = dashed
@@ -486,7 +498,7 @@ function metapost.flush(result,flusher,askedfig)
if pen then
if pen.type == 'elliptical' then
transformed, penwidth = pen_characteristics(original) -- boolean, value
- t[#t+1] = formatters["%f w"](penwidth) -- todo: only if changed
+ t[#t+1] = f_w(penwidth) -- todo: only if changed
if objecttype == 'fill' then
objecttype = 'both'
end
@@ -506,7 +518,7 @@ function metapost.flush(result,flusher,askedfig)
if objecttype == "fill" then
t[#t+1] = "h f"
elseif objecttype == "outline" then
- t[#t+1] = (open and "S") or "h S"
+ t[#t+1] = open and "S" or "h S"
elseif objecttype == "both" then
t[#t+1] = "h B"
end
@@ -527,7 +539,7 @@ function metapost.flush(result,flusher,askedfig)
if objecttype == "fill" then
t[#t+1] = "h f"
elseif objecttype == "outline" then
- t[#t+1] = (open and "S") or "h S"
+ t[#t+1] = open and "S" or "h S"
elseif objecttype == "both" then
t[#t+1] = "h B"
end
diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua
index 385fb3ece..c76dca245 100644
--- a/tex/context/base/mlib-pps.lua
+++ b/tex/context/base/mlib-pps.lua
@@ -18,6 +18,9 @@ local formatters = string.formatters
local mplib, metapost, lpdf, context = mplib, metapost, lpdf, context
+local context = context
+local context_setvalue = context.setvalue
+
local texgetbox = tex.getbox
local texsetbox = tex.setbox
local copy_list = node.copy_list
@@ -82,10 +85,13 @@ function metapost.setoutercolor(mode,colormodel,colorattribute,transparencyattri
innertransparency = outertransparency -- not yet used
end
-local f_gray = formatters["%.3f g %.3f G"]
-local f_rgb = formatters["%.3f %.3f %.3f rg %.3f %.3f %.3f RG"]
-local f_cmyk = formatters["%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K"]
-local f_cm = formatters["q %f %f %f %f %f %f cm"]
+local f_f = formatters["%F"]
+local f_f3 = formatters["%.3F"]
+
+local f_gray = formatters["%.3F g %.3F G"]
+local f_rgb = formatters["%.3F %.3F %.3F rg %.3F %.3F %.3F RG"]
+local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"]
+local f_cm = formatters["q %F %F %F %F %F %F cm"]
local f_shade = formatters["MpSh%s"]
local function checked_color_pair(color,...)
@@ -482,8 +488,8 @@ local factor = 65536*(7227/7200)
function metapost.edefsxsy(wd,ht,dp) -- helper for figure
local hd = ht + dp
- context.setvalue("sx",wd ~= 0 and factor/wd or 0)
- context.setvalue("sy",hd ~= 0 and factor/hd or 0)
+ context_setvalue("sx",wd ~= 0 and factor/wd or 0)
+ context_setvalue("sy",hd ~= 0 and factor/hd or 0)
end
local function sxsy(wd,ht,dp) -- helper for text
@@ -887,21 +893,21 @@ local function tx_analyze(object,prescript) -- todo: hash content and reuse them
-- no color
elseif #c == 1 then
if a and t then
- s = formatters["\\directcolored[s=%f,a=%f,t=%f]%s"](c[1],a,t,s)
+ s = formatters["\\directcolored[s=%F,a=%F,t=%F]%s"](c[1],a,t,s)
else
- s = formatters["\\directcolored[s=%f]%s"](c[1],s)
+ s = formatters["\\directcolored[s=%F]%s"](c[1],s)
end
elseif #c == 3 then
if a and t then
- s = formatters["\\directcolored[r=%f,g=%f,b=%f,a=%f,t=%f]%s"](c[1],c[2],c[3],a,t,s)
+ s = formatters["\\directcolored[r=%F,g=%F,b=%F,a=%F,t=%F]%s"](c[1],c[2],c[3],a,t,s)
else
- s = formatters["\\directcolored[r=%f,g=%f,b=%f]%s"](c[1],c[2],c[3],s)
+ s = formatters["\\directcolored[r=%F,g=%F,b=%F]%s"](c[1],c[2],c[3],s)
end
elseif #c == 4 then
if a and t then
- s = formatters["\\directcolored[c=%f,m=%f,y=%f,k=%f,a=%f,t=%f]%s"](c[1],c[2],c[3],c[4],a,t,s)
+ s = formatters["\\directcolored[c=%F,m=%F,y=%F,k=%F,a=%F,t=%F]%s"](c[1],c[2],c[3],c[4],a,t,s)
else
- s = formatters["\\directcolored[c=%f,m=%f,y=%f,k=%f]%s"](c[1],c[2],c[3],c[4],s)
+ s = formatters["\\directcolored[c=%F,m=%F,y=%F,k=%F]%s"](c[1],c[2],c[3],c[4],s)
end
end
context.MPLIBsettext(tx_last,s)
@@ -956,12 +962,12 @@ local function tx_process(object,prescript,before,after)
before[#before+1] = function()
-- flush always happens, we can have a special flush function injected before
context.MPLIBgettextscaledcm(n,
- format("%f",sx), -- bah ... %s no longer checks
- format("%f",rx), -- bah ... %s no longer checks
- format("%f",ry), -- bah ... %s no longer checks
- format("%f",sy), -- bah ... %s no longer checks
- format("%f",tx), -- bah ... %s no longer checks
- format("%f",ty), -- bah ... %s no longer checks
+ f_f(sx), -- bah ... %s no longer checks
+ f_f(rx), -- bah ... %s no longer checks
+ f_f(ry), -- bah ... %s no longer checks
+ f_f(sy), -- bah ... %s no longer checks
+ f_f(tx), -- bah ... %s no longer checks
+ f_f(ty), -- bah ... %s no longer checks
sxsy(box.width,box.height,box.depth))
end
else
@@ -1136,7 +1142,7 @@ end
-- color and transparency
local value = Cs ( (
- (Carg(1) * C((1-P(","))^1)) / function(a,b) return format("%0.3f",a * tonumber(b)) end
+ (Carg(1) * C((1-P(","))^1)) / function(a,b) return f_f3(a * tonumber(b)) end
+ P(","))^1
)
diff --git a/tex/context/base/mult-aux.lua b/tex/context/base/mult-aux.lua
index bdc626d4c..5a103213c 100644
--- a/tex/context/base/mult-aux.lua
+++ b/tex/context/base/mult-aux.lua
@@ -54,7 +54,7 @@ function namespaces.define(namespace,settings)
if trace_namespaces then
report_namespaces("namespace %a for %a uses parent %a",namespace,name,parent)
end
- if not find(parent,"\\") then
+ if not find(parent,"\\",1,true) then
parent = "\\" .. prefix .. parent
-- todo: check if defined
end
diff --git a/tex/context/base/mult-aux.mkiv b/tex/context/base/mult-aux.mkiv
index 6c44a0ec9..1811f9592 100644
--- a/tex/context/base/mult-aux.mkiv
+++ b/tex/context/base/mult-aux.mkiv
@@ -106,10 +106,14 @@
\doubleexpandafter\gobbleoneargument
\else
\mult_interfaces_get_parameters_assign#1==\empty\_e_o_p_
- \doubleexpandafter\mult_interfaces_get_parameters_item
+ % \doubleexpandafter\mult_interfaces_get_parameters_item % saves skipping when at end
\fi\fi#2}
-\def\mult_interfaces_get_parameters_error#1#2#3%
+\def\mult_interfaces_get_parameters_error#1#2% #3%
+ {\mult_interfaces_get_parameters_error_indeed{#1}{#2}%
+ \gobbleoneargument}
+
+\def\mult_interfaces_get_parameters_error_indeed#1#2%
{\showassignerror{#2}{\the\inputlineno\space(#1)}}
\def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_
@@ -118,9 +122,54 @@
\else\ifx#3\empty
\doubleexpandafter\mult_interfaces_get_parameters_error
\else
- \doubleexpandafter\dosetvalue
+ \doubleexpandafter\mult_interfaces_def
\fi\fi
- \m_mult_interfaces_namespace{#1}{#2}}
+ \m_mult_interfaces_namespace{#1}{#2}%
+ \doubleexpandafter\mult_interfaces_get_parameters_item}
+
+\startinterface english
+
+ % some 10% faster
+
+ \let\mult_interfaces_get_parameters_error\undefined
+
+ \def\mult_interfaces_get_parameters_error_one#1\csname#2#3\endcsname#4%
+ {\mult_interfaces_get_parameters_error_indeed{#2}{#3}\iftrue}
+
+ \def\mult_interfaces_get_parameters_error_two#1\csname#2#3\endcsname#4%
+ {\mult_interfaces_get_parameters_error_indeed{#2}{#3}}
+
+ \def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_
+ {\ifx\empty#1\empty
+ \mult_interfaces_get_parameters_error_one
+ \else\ifx#3\empty
+ \mult_interfaces_get_parameters_error_two
+ \else
+ \expandafter\def\csname\m_mult_interfaces_namespace#1\endcsname{#2}%
+ \fi\fi
+ \doubleexpandafter\mult_interfaces_get_parameters_item}
+
+ % interesting but not faster
+ %
+ % \def\mult_interfaces_get_parameters_error_one#1\m_mult_interfaces_namespace#2\fi\fi%
+ % {\mult_interfaces_get_parameters_error_indeed\m_mult_interfaces_namespace{#2}\m_mult_interfaces_namespace\s!dummy\fi}
+ %
+ % \def\mult_interfaces_get_parameters_error_two#1\m_mult_interfaces_namespace#2\fi\fi%
+ % {\mult_interfaces_get_parameters_error_indeed\m_mult_interfaces_namespace{#2}\m_mult_interfaces_namespace\s!dummy\fi\fi}
+ %
+ % \def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_
+ % {\expandafter\def\csname
+ % \ifx\empty#1\empty
+ % \mult_interfaces_get_parameters_error_one
+ % \else\ifx#3\empty
+ % \mult_interfaces_get_parameters_error_two
+ % \else
+ % \m_mult_interfaces_namespace#1%
+ % \fi\fi
+ % \endcsname{#2}
+ % \doubleexpandafter\mult_interfaces_get_parameters_item}
+
+\stopinterface
\newif\ifassignment
@@ -132,6 +181,24 @@
% End of experimental code.
+\unexpanded\def\mult_interfaces_let #1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname}
+\unexpanded\def\mult_interfaces_lete#1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname\empty}
+\unexpanded\def\mult_interfaces_def #1#2{\expandafter\def \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname}
+\unexpanded\def\mult_interfaces_edef#1#2{\expandafter\edef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname}
+\unexpanded\def\mult_interfaces_gdef#1#2{\expandafter\gdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname}
+\unexpanded\def\mult_interfaces_xdef#1#2{\expandafter\xdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname}
+
+\startinterface english
+
+ \unexpanded\def\mult_interfaces_let #1#2{\expandafter \let\csname#1#2\endcsname}
+ \unexpanded\def\mult_interfaces_lete#1#2{\expandafter \let\csname#1#2\endcsname\empty}
+ \unexpanded\def\mult_interfaces_def #1#2{\expandafter \def\csname#1#2\endcsname}
+ \unexpanded\def\mult_interfaces_edef#1#2{\expandafter\edef\csname#1#2\endcsname}
+ \unexpanded\def\mult_interfaces_gdef#1#2{\expandafter\gdef\csname#1#2\endcsname}
+ \unexpanded\def\mult_interfaces_xdef#1#2{\expandafter\xdef\csname#1#2\endcsname}
+
+\stopinterface
+
% the commented detokenized variant that backtracks ... needs testing usage first
%
% \let\whatever\relax
@@ -207,14 +274,14 @@
% In \MKIV\ we can probably use the english variant for all other
% languages too.
-% todo: inline the \do*value
+% todo: inline the def/let
\unexpanded\def\mult_interfaces_install_parameter_set_handler#1#2#3#4#5#6%
{\ifx#2\relax\let#2\empty\fi
- \unexpanded\def#3{\dosetvalue {#1#2:}}% ##1 {##2} (braces are mandate)
- \unexpanded\def#4{\dosetevalue{#1#2:}}% ##1 {##2} (braces are mandate)
- \unexpanded\def#5{\doletvalue {#1#2:}}% ##1 ##2
- \unexpanded\def#6{\doletvalue {#1#2:}\empty}}% ##1
+ \unexpanded\def#3{\mult_interfaces_def {#1#2:}}% ##1 {##2} (braces are mandate)
+ \unexpanded\def#4{\mult_interfaces_edef{#1#2:}}% ##1 {##2} (braces are mandate)
+ \unexpanded\def#5{\mult_interfaces_let {#1#2:}}% ##1 ##2
+ \unexpanded\def#6{\mult_interfaces_lete{#1#2:}}}% ##1
\startinterface english
@@ -548,10 +615,10 @@
\expandafter\noexpand\csname everysetup#2\endcsname}}
\unexpanded\def\mult_interfaces_install_direct_parameter_set_handler#1#2#3#4#5%
- {\unexpanded\def#2{\dosetvalue #1}%
- \unexpanded\def#3{\dosetevalue#1}%
- \unexpanded\def#4{\doletvalue #1}%
- \unexpanded\def#5{\doletvalue #1\empty}}%
+ {\unexpanded\def#2{\mult_interfaces_def #1}%
+ \unexpanded\def#3{\mult_interfaces_edef#1}%
+ \unexpanded\def#4{\mult_interfaces_let #1}%
+ \unexpanded\def#5{\mult_interfaces_let #1\empty}}%
\startinterface english
@@ -694,9 +761,8 @@
\ctxcommand{registernamespace(\number\c_mult_interfaces_n_of_namespaces,"#1")}%
\fi}
-\def\mult_interfaces_get_parameters_error#1#2#3% redefined
- {\ctxcommand{showassignerror("#1","#2","#3",\the\inputlineno)}%
- \waitonfatalerror}
+\def\mult_interfaces_get_parameters_error_indeed#1#2%
+ {\ctxcommand{showassignerror("#1","#2",\the\inputlineno)}} % no longer \waitonfatalerror
% We install two core namespaces here, as we want nice error messages. Maybe
% we will reserve the first 9.
@@ -856,4 +922,198 @@
%D \edef\m_class_whatever{whatever}
%D \stoptyping
+% experiment: in principle this is faster but not that noticeable as we don't do that
+% many assignments and mechanism that do are also slow; the advantage is mostly nicer
+% in tracing
+
+\def\s!simple{simple}
+\def\s!single{single}
+\def\s!double{double}
+\def\s!triple{triple}
+
+\unexpanded\def\syst_helpers_double_empty#1#2#3%
+ {\syst_helpers_argument_reset
+ \doifnextoptionalelse
+ {\syst_helpers_double_empty_one_yes_mult#2#3}%
+ {\syst_helpers_double_empty_one_nop_mult#1}}
+
+\def\syst_helpers_double_empty_one_yes_mult#1#2[#3]%
+ {\firstargumenttrue
+ \doifnextoptionalelse
+ {\secondargumenttrue#2[{#3}]}%
+ {\syst_helpers_double_empty_two_nop_mult#1{#3}}}
+
+\def\syst_helpers_double_empty_one_nop_mult% #1%
+ {\firstargumentfalse
+ \secondargumentfalse
+ }% #1}
+
+\def\syst_helpers_double_empty_two_nop_mult
+ {\secondargumentfalse
+ \if_next_blank_space_token
+ \expandafter\syst_helpers_double_empty_one_spaced_mult
+ \else
+ \expandafter\syst_helpers_double_empty_one_normal_mult
+ \fi}
+
+\def\syst_helpers_double_empty_one_spaced_mult#1#2{#1[{#2}] }
+\def\syst_helpers_double_empty_one_normal_mult#1#2{#1[{#2}]}
+
+\unexpanded\def\mult_interfaces_install_setup_handler#1#2#3#4#5#6#7#8%
+ {\ifx#3\relax\let#3\empty\fi
+ \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% no every ! don't change it
+ \newtoks#4%
+ \newtoks#7%
+ \edef\m_mult_interface_setup{\strippedcsname#2_}%
+ \unexpanded\edef#2{\syst_helpers_double_empty
+ \csname\m_mult_interface_setup\s!simple\endcsname
+ \csname\m_mult_interface_setup\s!single\endcsname
+ \csname\m_mult_interface_setup\s!double\endcsname}%
+ \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]%
+ {\let#6#3%
+ \def#8####1% we will have a simple one as well
+ {\edef#3{####1}%
+ \mult_interfaces_get_parameters{#1#3:}[##2]%
+ \the#4}%
+ \processcommalist[##1]#8%
+ \let#3#6%
+ \the#7}%
+ \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]%
+ {\let#6#3%
+ \let#3\empty
+ \mult_interfaces_get_parameters{#1:}[##1]%
+ \the#4%
+ \let#3#6%
+ \the#7}%
+ \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname%
+ {\let#6#3%
+ \let#3\empty
+ \the#4%
+ \let#3#6%
+ \the#7}}
+
+\unexpanded\def\installsetuphandler#1#2%
+ {\normalexpanded
+ {\mult_interfaces_install_setup_handler
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname setup#2\endcsname
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname everysetup#2\endcsname
+ \expandafter\noexpand\csname setupcurrent#2\endcsname
+ \expandafter\noexpand\csname saved_setup_current#2\endcsname
+ \expandafter\noexpand\csname everysetup#2root\endcsname
+ \expandafter\noexpand\csname nested_setup_current#2\endcsname}}
+
+\unexpanded\def\syst_helpers_triple_empty#1#2#3#4%
+ {\syst_helpers_argument_reset
+ \doifnextoptionalelse
+ {\syst_helpers_triple_empty_one_yes_mult#2#3#4}%
+ {\syst_helpers_triple_empty_one_nop_mult#1}}
+
+\def\syst_helpers_triple_empty_one_yes_mult#1#2#3[#4]%
+ {\firstargumenttrue
+ \doifnextoptionalelse
+ {\syst_helpers_triple_empty_two_yes_mult#2#3{#4}}%
+ {\syst_helpers_triple_empty_two_nop_mult#1{#4}}}
+
+\def\syst_helpers_triple_empty_two_yes_mult#1#2#3[#4]%
+ {\secondargumenttrue
+ \doifnextoptionalelse
+ {\thirdargumenttrue#2[{#3}][{#4}]}%
+ {\syst_helpers_triple_empty_three_nop_mult#1{#3}{#4}}}
+
+\def\syst_helpers_triple_empty_one_nop_mult % #1%
+ {\firstargumentfalse
+ \secondargumentfalse
+ \thirdargumentfalse
+ } % #1
+
+\def\syst_helpers_triple_empty_two_nop_mult
+ {\secondargumentfalse
+ \thirdargumentfalse
+ \if_next_blank_space_token
+ \expandafter\syst_helpers_triple_empty_two_spaced_mult
+ \else
+ \expandafter\syst_helpers_triple_empty_two_normal_mult
+ \fi}
+
+\def\syst_helpers_triple_empty_three_nop_mult
+ {\thirdargumentfalse
+ \if_next_blank_space_token
+ \expandafter\syst_helpers_triple_empty_three_spaced_mult
+ \else
+ \expandafter\syst_helpers_triple_empty_three_normal_mult
+ \fi}
+
+\def\syst_helpers_triple_empty_two_spaced_mult #1#2{#1[{#2}] }
+\def\syst_helpers_triple_empty_two_normal_mult #1#2{#1[{#2}]}
+\def\syst_helpers_triple_empty_three_spaced_mult#1#2#3{#1[{#2}][{#3}] }
+\def\syst_helpers_triple_empty_three_normal_mult#1#2#3{#1[{#2}][{#3}]}
+
+\unexpanded\def\mult_interfaces_install_auto_setup_handler#1#2#3#4#5#6#7#8%
+ {\ifx#3\relax\let#3\empty\fi
+ \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}%
+ \newtoks#4%
+ \edef\m_mult_interface_setup{\strippedcsname#2_}%
+ \unexpanded\edef#2{\syst_helpers_triple_empty
+ \csname\m_mult_interface_setup\s!simple\endcsname
+ \csname\m_mult_interface_setup\s!single\endcsname
+ \csname\m_mult_interface_setup\s!double\endcsname
+ \csname\m_mult_interface_setup\s!triple\endcsname}%
+ \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!triple\endcsname[##1][##2][##3]%
+ {\let#7#3%
+ \def#8####1%
+ {\edef#3{####1}%
+ \expandafter\def\csname#1#3:\s!parent\endcsname{#1##2}%
+ \mult_interfaces_get_parameters{#1#3:}[##3]% always sets parent
+ \the#4}%
+ \processcommalist[##1]#8%
+ \let#3#7}%
+ \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]%
+ {\let#7#3%
+ \def#8####1%
+ {\edef#3{####1}%
+ #6% checks parent and sets if needed
+ \mult_interfaces_get_parameters{#1#3:}[##2]%
+ \the#4}%
+ \processcommalist[##1]#8%
+ \let#3#7}%
+ \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]%
+ {\let#7#3%
+ \let#3\empty
+ \mult_interfaces_get_parameters{#1:}[##1]%
+ \the#4%
+ \let#3#7}%
+ \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname%
+ {\let#7#3%
+ \let#3\empty
+ \the#4%
+ \let#3#7}}
+
+\unexpanded\def\installautosetuphandler#1#2%
+ {\normalexpanded
+ {\mult_interfaces_install_auto_setup_handler
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname setup#2\endcsname
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname everysetup#2\endcsname
+ \expandafter\noexpand\csname setupcurrent#2\endcsname
+ \expandafter\noexpand\csname check#2parent\endcsname
+ \expandafter\noexpand\csname saved_setup_current#2\endcsname
+ \expandafter\noexpand\csname nested_setup_current#2\endcsname}}
+
+% okay, we can also get rid of the #9, but thsi code looks pretty bad, while the previous is
+% still okay given that we can also use #6 as setup1 (so in fact we can save some cs again and
+% only use one extra)
+%
+% \global\advance\commalevel \plusone
+% \expandafter\def\csname\??nextcommalevel\the\commalevel\endcsname####1,%
+% {\edef#3{####1}%
+% \mult_interfaces_get_parameters{#1#3:}[##2]%
+% \the#5%
+% \syst_helpers_do_process_comma_item}%
+% \expandafter\syst_helpers_do_do_process_comma_item\gobbleoneargument\relax##1,]\relax
+% % \syst_helpers_do_do_process_comma_item##1,]\relax
+% \global\advance\commalevel \minusone
+
\protect
diff --git a/tex/context/base/mult-def.lua b/tex/context/base/mult-def.lua
index 65db8fd5e..fc2b932c2 100644
--- a/tex/context/base/mult-def.lua
+++ b/tex/context/base/mult-def.lua
@@ -3055,7 +3055,7 @@ return {
["pe"]="درج‌شماره‌صفحه",
["ro"]="punenumarpagina",
},
- ["placereferencelist"]={
+ ["placereferencelist"]={ -- not in mkiv
["cs"]="placereferencelist",
["de"]="placereferencelist",
["en"]="placereferencelist",
@@ -9708,7 +9708,7 @@ return {
["en"]="reference",
["fr"]="reference",
["it"]="riferimento",
- ["nl"]="verwijzing",
+ ["nl"]="referentie",
["pe"]="مرجع",
["ro"]="referinta",
},
@@ -10917,7 +10917,7 @@ return {
["en"]="unknownreference",
["fr"]="referenceinconnue",
["it"]="riferimentoingoto",
- ["nl"]="onbekendeverwijzing",
+ ["nl"]="onbekendereferentie",
["pe"]="مرجع‌ناشناس",
["ro"]="referintanecunoscuta",
},
diff --git a/tex/context/base/mult-def.mkiv b/tex/context/base/mult-def.mkiv
index 9206743f4..35b212710 100644
--- a/tex/context/base/mult-def.mkiv
+++ b/tex/context/base/mult-def.mkiv
@@ -64,6 +64,8 @@
\def\c!group {group}
\def\c!groupsuffix {groupsuffix}
+\def\c!referencemethod {referencemethod} % forward both
+
\def\v!dataset {dataset}
\def\v!compressseparator{compressseparator}
\def\v!notation {notation}
@@ -117,6 +119,10 @@
\def\c!etaldisplay{etaldisplay}
\def\c!etaltext {etaltext}
+\ifdefined\v!simplelist\else \def\v!simplelist{simplelist} \fi
+\ifdefined\v!sorting \else \def\v!sorting {sorting} \fi
+\ifdefined\v!synonym \else \def\v!synonym {synonym} \fi
+
% stop todo
\protect \endinput
diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua
index e3ff904a6..08f1639d0 100644
--- a/tex/context/base/mult-ini.lua
+++ b/tex/context/base/mult-ini.lua
@@ -299,12 +299,12 @@ function commands.getmessage(category,tag,default)
context(interfaces.getmessage(category,tag,default))
end
-function commands.showassignerror(namespace,key,value,line)
- local ns, instance = match(namespace,"^(%d+)[^%a]+(%a+)")
+function commands.showassignerror(namespace,key,line)
+ local ns, instance = match(namespace,"^(%d+)[^%a]+(%a*)")
if ns then
namespace = corenamespaces[tonumber(ns)] or ns
end
- if instance then
+ if instance and instance ~= "" then
context.writestatus("setup",formatters["error in line %a, namespace %a, instance %a, key %a"](line,namespace,instance,key))
else
context.writestatus("setup",formatters["error in line %a, namespace %a, key %a"](line,namespace,key))
diff --git a/tex/context/base/mult-low.lua b/tex/context/base/mult-low.lua
index 250b20c22..a5b8874d6 100644
--- a/tex/context/base/mult-low.lua
+++ b/tex/context/base/mult-low.lua
@@ -47,7 +47,7 @@ return {
"inicatcodes",
"ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes",
"prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes",
- "xmlcatcodes",
+ "xmlcatcodes", "ctdcatcodes",
--
"escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode",
"endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode",
@@ -136,6 +136,7 @@ return {
"starttexdefinition", "stoptexdefinition",
"starttexcode", "stoptexcode",
"startcontextcode", "stopcontextcode",
+ "startcontextdefinitioncode", "stopcontextdefinitioncode",
--
"doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup",
"doifelsecommandhandler","doifnotcommandhandler","doifcommandhandler",
@@ -219,7 +220,9 @@ return {
--
"doif", "doifnot", "doifelse",
"doifinset", "doifnotinset", "doifinsetelse",
- "doifnextcharelse", "doifnextoptionalelse", "doifnextbgroupelse", "doifnextparenthesiselse", "doiffastoptionalcheckelse",
+ "doifnextcharelse", "doifnextoptionalelse", "doifnextoptionalcselse", "doiffastoptionalcheckelse",
+ "doifnextbgroupelse", "doifnextbgroupcselse",
+ "doifnextparenthesiselse",
"doifundefinedelse", "doifdefinedelse", "doifundefined", "doifdefined",
"doifelsevalue", "doifvalue", "doifnotvalue",
"doifnothing", "doifsomething", "doifelsenothing", "doifsomethingelse",
@@ -353,6 +356,8 @@ return {
"definenamedlua",
"obeylualines", "obeyluatokens",
"startluacode", "stopluacode", "startlua", "stoplua",
+ "startctxfunction","stopctxfunction","ctxfunction",
+ "startctxfunctiondefinition","stopctxfunctiondefinition",
--
"carryoverpar",
--
diff --git a/tex/context/base/mult-nl.mkii b/tex/context/base/mult-nl.mkii
index a1f9742f1..015f58ff1 100644
--- a/tex/context/base/mult-nl.mkii
+++ b/tex/context/base/mult-nl.mkii
@@ -944,7 +944,7 @@
\setinterfaceconstant{reduction}{reductie}
\setinterfaceconstant{ref}{ref}
\setinterfaceconstant{refcommand}{refcommand}
-\setinterfaceconstant{reference}{verwijzing}
+\setinterfaceconstant{reference}{referentie}
\setinterfaceconstant{referenceprefix}{referenceprefix}
\setinterfaceconstant{referencing}{refereren}
\setinterfaceconstant{region}{gebied}
@@ -1094,7 +1094,7 @@
\setinterfaceconstant{totalnumber}{totalnumber}
\setinterfaceconstant{type}{type}
\setinterfaceconstant{unit}{eenheid}
-\setinterfaceconstant{unknownreference}{onbekendeverwijzing}
+\setinterfaceconstant{unknownreference}{onbekendereferentie}
\setinterfaceconstant{urlalternative}{urlvariant}
\setinterfaceconstant{urlspace}{urlspatie}
\setinterfaceconstant{validate}{valideer}
diff --git a/tex/context/base/mult-prm.lua b/tex/context/base/mult-prm.lua
index e6fa4abcc..f0b850a5c 100644
--- a/tex/context/base/mult-prm.lua
+++ b/tex/context/base/mult-prm.lua
@@ -235,6 +235,7 @@ return {
"luatexdatestamp",
"luatexrevision",
"luatexversion",
+ "luafunction",
"mathstyle",
"nokerns",
"noligs",
@@ -573,10 +574,10 @@ return {
"catcodetable",
"char",
"chardef",
- "chardp",
- "charht",
- "charit",
- "charwd",
+--"chardp",
+--"charht",
+--"charit",
+--"charwd",
"cleaders",
"clearmarks",
"closein",
diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua
index 7f4b0342a..499116258 100644
--- a/tex/context/base/node-aux.lua
+++ b/tex/context/base/node-aux.lua
@@ -49,6 +49,7 @@ local copy_node_list = nuts.copy_list
local find_tail = nuts.tail
local insert_node_after = nuts.insert_after
local isnode = nuts.is_node
+local getbox = nuts.getbox
local nodes_traverse_id = nodes.traverse_id
local nodes_first_glyph = nodes.first_glyph
@@ -61,8 +62,52 @@ local unsetvalue = attributes.unsetvalue
local current_font = font.current
+local texsetbox = tex.setbox
+
local report_error = logs.reporter("node-aux:error")
+-- At some point we figured that copying before using was the safest bet
+-- when dealing with boxes at the tex end. This is because tex also needs
+-- to manage the grouping (i.e. savestack). However, there is an easy
+-- solution that keeps the tex end happy as tex.setbox deals with this. The
+-- overhead of one temporary list node is neglectable.
+--
+-- function tex.takebox(id)
+-- local box = tex.getbox(id)
+-- if box then
+-- local copy = node.copy(box)
+-- local list = box.list
+-- copy.list = list
+-- box.list = nil
+-- tex.setbox(id,nil)
+-- return copy
+-- end
+-- end
+
+local function takebox(id)
+ local box = getbox(id)
+ if box then
+ local copy = copy_node(box)
+ local list = getlist(box)
+ setfield(copy,"list",list)
+ setfield(box,"list",nil)
+ texsetbox(id,nil)
+ return copy
+ end
+end
+
+function nodes.takebox(id)
+ local b = takebox(id)
+ if b then
+ return tonode(b)
+ end
+end
+
+nuts.takebox = takebox
+tex.takebox = nodes.takebox -- sometimes more clear
+
+-- so far
+
local function repackhlist(list,...)
local temp, b = hpack_nodes(list,...)
list = getlist(temp)
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua
index 8476b47a6..250035f39 100644
--- a/tex/context/base/node-fin.lua
+++ b/tex/context/base/node-fin.lua
@@ -20,14 +20,13 @@ local tonode = nuts.tonode
local tonut = nuts.tonut
local getfield = nuts.getfield
+local setfield = nuts.setfield
local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
local getlist = nuts.getlist
local getleader = nuts.getleader
local getattr = nuts.getattr
-
-local setfield = nuts.setfield
local setattr = nuts.setattr
local copy_node = nuts.copy
diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv
index e99653327..142f0d7ba 100644
--- a/tex/context/base/node-ini.mkiv
+++ b/tex/context/base/node-ini.mkiv
@@ -19,9 +19,7 @@
\registerctxluafile{node-ini}{1.001}
\registerctxluafile{node-met}{1.001}
-
-\ctxlua{if nodes.gonuts then context.registerctxluafile("node-nut","1.001") end}
-
+\registerctxluafile{node-nut}{1.001}
\registerctxluafile{node-res}{1.001}
\registerctxluafile{node-dir}{1.001}
\registerctxluafile{node-aux}{1.001}
@@ -36,6 +34,8 @@
\registerctxluafile{node-acc}{1.001} % experimental
%registerctxluafile{node-prp}{1.001} % makes no sense (yet)
+\doiffileelse{node-ppt.lua}{\registerctxluafile{node-ppt}{1.001}}{}
+
\newcount\c_node_tracers_show_box % box number
\unexpanded\def\shownextnodes{\afterassignment\node_tracers_show_next\c_node_tracers_show_box}
diff --git a/tex/context/base/node-inj.lua b/tex/context/base/node-inj.lua
index f30070e9e..b91646ffc 100644
--- a/tex/context/base/node-inj.lua
+++ b/tex/context/base/node-inj.lua
@@ -8,8 +8,7 @@ if not modules then modules = { } end modules ['node-inj'] = {
-- This is very experimental (this will change when we have luatex > .50 and
-- a few pending thingies are available. Also, Idris needs to make a few more
--- test fonts. Btw, future versions of luatex will have extended glyph properties
--- that can be of help. Some optimizations can go away when we have faster machines.
+-- test fonts. Some optimizations can go away when we have faster machines.
-- todo: ignore kerns between disc and glyph
@@ -30,7 +29,6 @@ local injections = nodes.injections
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
-local disc_code = nodecodes.disc
local kern_code = nodecodes.kern
local nuts = nodes.nuts
@@ -58,7 +56,7 @@ local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local a_kernpair = attributes.private('kernpair')
-local a_ligacomp = attributes.private('ligacomp')
+----- a_ligacomp = attributes.private('ligacomp')
local a_markbase = attributes.private('markbase')
local a_markmark = attributes.private('markmark')
local a_markdone = attributes.private('markdone')
@@ -127,9 +125,9 @@ function injections.setkern(current,factor,rlmode,x,tfmchr)
end
end
-function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) -- ba=baseanchor, ma=markanchor
- local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) -- the index argument is no longer used but when this
- local bound = getattr(base,a_markbase) -- fails again we should pass it
+function injections.setmark(start,base,factor,rlmode,ba,ma) -- ba=baseanchor, ma=markanchor
+ local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2])
+ local bound = getattr(base,a_markbase)
local index = 1
if bound then
local mb = marks[bound]
@@ -144,13 +142,12 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) --
report_injections("possible problem, %U is base mark without data (id %a)",getchar(base),bound)
end
end
--- index = index or 1
index = index or 1
bound = #marks + 1
setattr(base,a_markbase,bound)
setattr(start,a_markmark,bound)
setattr(start,a_markdone,index)
- marks[bound] = { [index] = { dx, dy, rlmode, baseismark } }
+ marks[bound] = { [index] = { dx, dy, rlmode } }
return dx, dy, bound
end
@@ -354,7 +351,7 @@ function injections.handler(head,where,keep)
end
end
if maxt > 0 then
- local ny = getfield(n,"yoffset")
+ local ny = getfield(n,"yoffset") -- hm, n unset ?
for i=maxt,1,-1 do
ny = ny + d[i]
local ti = t[i]
@@ -516,8 +513,7 @@ function injections.handler(head,where,keep)
-- if trace_injections then
-- show_result(head)
-- end
-head = tonode(head)
- return head, true
+ return tonode(head), true
elseif not keep then
kerns, cursives, marks = { }, { }, { }
end
diff --git a/tex/context/base/node-met.lua b/tex/context/base/node-met.lua
index d52349b4a..335ce2a98 100644
--- a/tex/context/base/node-met.lua
+++ b/tex/context/base/node-met.lua
@@ -68,7 +68,7 @@ local nodes = nodes
nodes.gonuts = gonuts
-local nodecodes = nodes.codes
+local nodecodes = nodes.nodecodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
diff --git a/tex/context/base/node-nut.lua b/tex/context/base/node-nut.lua
index 4732b09eb..a2f4c93ff 100644
--- a/tex/context/base/node-nut.lua
+++ b/tex/context/base/node-nut.lua
@@ -648,3 +648,55 @@ nuts.untracedslide = untracedslide
nuts.nestedtracedslide = nestedtracedslide
-- nuts.slide = tracedslide
+
+-- this might move
+
+local propertydata = direct.get_properties_table and direct.get_properties_table()
+
+local getattr = nuts.getattr
+local setattr = nuts.setattr
+
+if propertydata then
+
+ nodes.properties = {
+ data = propertydata,
+ }
+
+ direct.set_properties_mode(true,false)
+ -- direct.set_properties_mode(true,true)
+
+ -- experimental code with respect to copying attributes has been removed
+ -- as it doesn't pay of (most attributes are only accessed once anyway)
+
+ nuts.getprop = function(n,k)
+ local p = propertydata[n]
+ if p then
+ return p[k]
+ end
+ end
+
+ nuts.setprop = function(n,k,v)
+ if v then
+ local p = propertydata[n]
+ if p then
+ p[k] = v
+ else
+ propertydata[n] = { [k] = v }
+ end
+ end
+ end
+
+ nodes.setprop = nodes.setproperty
+ nodes.getprop = nodes.getproperty
+
+else
+
+ -- for testing and simple cases
+
+ nuts.getprop = getattr
+ nuts.setprop = setattr
+
+ nodes.setprop = getattr
+ nodes.getprop = setattr
+
+end
diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua
index 7cfbde849..5623dbb05 100644
--- a/tex/context/base/node-ref.lua
+++ b/tex/context/base/node-ref.lua
@@ -123,28 +123,27 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t
if result and resolved then
if head == first then
if trace_backend then
- report_area("head: %04i %s %s %s => w=%p, h=%p, d=%p, c=%s",reference,pardir or "---",txtdir or "----",tosequence(first,last,true),width,height,depth,resolved)
+ report_area("%s: %04i %s %s %s => w=%p, h=%p, d=%p, c=%S","head",
+ reference,pardir or "---",txtdir or "---",tosequence(first,last,true),width,height,depth,resolved)
end
setfield(result,"next",first)
setfield(first,"prev",result)
return result, last
else
if trace_backend then
- report_area("middle: %04i %s %s => w=%p, h=%p, d=%p, c=%s",reference,pardir or "---",txtdir or "----",tosequence(first,last,true),width,height,depth,resolved)
+ report_area("%s: %04i %s %s %s => w=%p, h=%p, d=%p, c=%S","middle",
+ reference,pardir or "---",txtdir or "---",tosequence(first,last,true),width,height,depth,resolved)
end
local prev = getprev(first)
if prev then
- setfield(result,"next",first)
- setfield(result,"prev",prev)
setfield(prev,"next",result)
- setfield(first,"prev",result)
- else
- setfield(result,"next",first)
- setfield(first,"prev",result)
- end
- if first == getnext(head) then
- setfield(head,"next",result) -- hm, weird
+ setfield(result,"prev",prev)
end
+ setfield(result,"next",first)
+ setfield(first,"prev",result)
+-- if first == getnext(head) then
+-- setfield(head,"next",result) -- hm, weird
+-- end
return head, last
end
else
@@ -195,7 +194,8 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir)
-- todo: only when width is ok
if result and resolved then
if trace_backend then
- report_area("box: %04i %s %s: w=%p, h=%p, d=%p, c=%s",reference,pardir or "---",txtdir or "----",width,height,depth,resolved)
+ report_area("%s: %04i %s %s %s: w=%p, h=%p, d=%p, c=%S","box",
+ reference,pardir or "---",txtdir or "----","[]",width,height,depth,resolved)
end
if not first then
setfield(current,"list",result)
@@ -226,6 +226,10 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
txtdir = txtdir or "==="
while current do
local id = getid(current)
+-- do
+-- local r = getattr(current,attribute)
+-- if r then print(attribute,r) end
+-- end
if id == hlist_code or id == vlist_code then
local r = getattr(current,attribute)
-- somehow reference is true so the following fails (second one not done) in
@@ -297,7 +301,7 @@ local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir)
end
local list = getlist(current)
if list then
- setfield(current,"list",inject_area(list,attribute,make,stack,done,current,pardir,txtdir))
+ setfield(current,"list",(inject_area(list,attribute,make,stack,done,current,pardir,txtdir)))
end
elseif id == whatsit_code then
local subtype = getsubtype(current)
@@ -429,6 +433,7 @@ annot = tonut(annot)
end
if current then
setfield(current,"next",annot)
+ setfield(annot,"prev",current)
else
result = annot
end
@@ -503,32 +508,28 @@ local function makedestination(width,height,depth,reference)
step = 4*65536
width, height, depth = 5*step, 5*step, 0
end
- for n=1,#name do
- local rule = hpack_list(colorize(width,height,depth,3,reference,"destination"))
- setfield(rule,"width",0)
- if not result then
- result, current = rule, rule
- else
- setfield(current,"next",rule)
- setfield(rule,"prev",current)
- current = rule
- end
- width, height = width - step, height - step
+ local rule = hpack_list(colorize(width,height,depth,3,reference,"destination"))
+ setfield(rule,"width",0)
+ if not result then
+ result, current = rule, rule
+ else
+ setfield(current,"next",rule)
+ setfield(rule,"prev",current)
+ current = rule
end
+ width, height = width - step, height - step
end
nofdestinations = nofdestinations + 1
- for n=1,#name do
- local annot = nodeinjections.destination(width,height,depth,name[n],view)
- if annot then
-annot = tonut(annot) -- obsolete soon
- if not result then
- result = annot
- else
- setfield(current,"next",annot)
- setfield(annot,"prev",current)
- end
- current = find_node_tail(annot)
+ local annot = nodeinjections.destination(width,height,depth,name,view)
+ if annot then
+ annot = tonut(annot) -- obsolete soon
+ if result then
+ setfield(current,"next",annot)
+ setfield(annot,"prev",current)
+ else
+ result = annot
end
+ current = find_node_tail(annot)
end
if result then
-- some internal error
diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua
index 968283745..0d45d1bd6 100644
--- a/tex/context/base/node-res.lua
+++ b/tex/context/base/node-res.lua
@@ -74,6 +74,9 @@ local copy_nut = nuts.copy
local new_nut = nuts.new
local free_nut = nuts.free
+local copy_node = nodes.copy
+local new_node = nodes.new
+
-- at some point we could have a dual set (the overhead of tonut is not much larger than
-- metatable associations at the lua/c end esp if we also take assignments into account
@@ -288,19 +291,85 @@ function nutpool.rule(width,height,depth,dir) -- w/h/d == nil will let them adap
return n
end
--- if node.has_field(latelua,'string') then
- function nutpool.latelua(code)
- local n = copy_nut(latelua)
- setfield(n,"string",code)
+function nutpool.latelua(code)
+ local n = copy_nut(latelua)
+ setfield(n,"string",code)
+ return n
+end
+
+if context and _cldo_ then
+
+ -- a typical case where we have more nodes than nuts
+
+ local context = context
+
+ local f_cldo = string.formatters["_cldo_(%i)"]
+ local register = context.registerfunction
+
+ local latelua_node = register_node(new_node("whatsit",whatsitcodes.latelua))
+ local latelua_nut = register_nut (new_nut ("whatsit",whatsitcodes.latelua))
+
+ local setfield_node = nodes.setfield
+ local setfield_nut = nuts .setfield
+
+ function nodepool.lateluafunction(f)
+ local n = copy_node(latelua_node)
+ setfield_node(n,"string",f_cldo(register(f)))
return n
end
--- else
--- function nutpool.latelua(code)
--- local n = copy_nut(latelua)
--- setfield(n,"data",code)
--- return n
--- end
--- end
+ function nutpool.lateluafunction(f)
+ local n = copy_nut(latelua_nut)
+ setfield_nut(n,"string",f_cldo(register(f)))
+ return n
+ end
+
+ -- when function in latelua:
+
+ -- function nodepool.lateluafunction(f)
+ -- local n = copy_node(latelua_node)
+ -- setfield_node(n,"string",f)
+ -- return n
+ -- end
+ -- function nutpool.lateluafunction(f)
+ -- local n = copy_nut(latelua_nut)
+ -- setfield_nut(n,"string",f)
+ -- return n
+ -- end
+
+ local latefunction = nodepool.lateluafunction
+ local flushnode = context.flushnode
+
+ function context.lateluafunction(f)
+ flushnode(latefunction(f)) -- hm, quite some indirect calls
+ end
+
+ -- when function in latelua:
+
+ -- function context.lateluafunction(f)
+ -- local n = copy_node(latelua_node)
+ -- setfield_node(n,"string",f)
+ -- flushnode(n)
+ -- end
+
+ -- local contextsprint = context.sprint
+ -- local ctxcatcodes = tex.ctxcatcodes
+ -- local storenode = context.storenode
+
+ -- when 0.79 is out:
+
+ -- function context.lateluafunction(f)
+ -- contextsprint(ctxcatcodes,"\\cldl",storenode(latefunction(f))," ")
+ -- end
+
+ -- when function in latelua:
+
+ -- function context.lateluafunction(f)
+ -- local n = copy_node(latelua_node)
+ -- setfield_node(n,"string",f)
+ -- contextsprint(ctxcatcodes,"\\cldl",storenode(n)," ")
+ -- end
+
+end
function nutpool.leftmarginkern(glyph,width)
local n = copy_nut(left_margin_kern)
diff --git a/tex/context/base/pack-com.mkiv b/tex/context/base/pack-com.mkiv
index 2c28d6b20..4ca77af1c 100644
--- a/tex/context/base/pack-com.mkiv
+++ b/tex/context/base/pack-com.mkiv
@@ -626,12 +626,12 @@
\unexpanded\def\placepairedbox[#1]%
{\bgroup
\edef\currentpairedbox{#1}%
- \doifnextoptionalelse\pack_pairedboxes_place\pack_pairedboxes_place_indeed}
+ \doifnextoptionalcselse\pack_pairedboxes_place\pack_pairedboxes_place_indeed}
\unexpanded\def\startplacepairedbox[#1]%
{\bgroup
\edef\currentpairedbox{#1}%
- \doifnextoptionalelse\pack_pairedboxes_place\pack_pairedboxes_place_indeed}
+ \doifnextoptionalcselse\pack_pairedboxes_place\pack_pairedboxes_place_indeed}
\unexpanded\def\stopplacepairedbox
{}
diff --git a/tex/context/base/pack-mis.mkvi b/tex/context/base/pack-mis.mkvi
index 978cc120c..38fcc18e4 100644
--- a/tex/context/base/pack-mis.mkvi
+++ b/tex/context/base/pack-mis.mkvi
@@ -46,7 +46,7 @@
\unexpanded\def\pack_placement#tag%
{\bgroup
\edef\currentplacement{#tag}%
- \doifnextoptionalelse\pack_placement_yes\pack_placement_nop}
+ \doifnextoptionalcselse\pack_placement_yes\pack_placement_nop}
\def\pack_placement_yes[#settings]%
{\setupcurrentplacement[#settings]%
diff --git a/tex/context/base/pack-mrl.mkiv b/tex/context/base/pack-mrl.mkiv
index 7c3f08825..3e81a4d69 100644
--- a/tex/context/base/pack-mrl.mkiv
+++ b/tex/context/base/pack-mrl.mkiv
@@ -40,7 +40,7 @@
\unexpanded\def\blackrule
{\hbox\bgroup
- \doifnextoptionalelse\pack_black_rule_pickup\pack_black_rule_indeed}
+ \doifnextoptionalcselse\pack_black_rule_pickup\pack_black_rule_indeed}
\def\pack_black_rule_pickup[#1]%
{\setupcurrentblackrules[#1]%
@@ -96,7 +96,7 @@
\unexpanded\def\blackrules % probably never used
{\hbox\bgroup
- \doifnextoptionalelse\pack_black_rules_pickup\pack_black_rules_indeed}
+ \doifnextoptionalcselse\pack_black_rules_pickup\pack_black_rules_indeed}
\def\pack_black_rules_pickup[#1]%
{\setupcurrentblackrules[#1]%
diff --git a/tex/context/base/pack-rul.lua b/tex/context/base/pack-rul.lua
index c8ed0722b..5796da800 100644
--- a/tex/context/base/pack-rul.lua
+++ b/tex/context/base/pack-rul.lua
@@ -33,8 +33,6 @@ local getsubtype = nuts.getsubtype
local getbox = nuts.getbox
local hpack = nuts.hpack
-local free = nuts.free
-local copy = nuts.copy_list
local traverse_id = nuts.traverse_id
local node_dimensions = nuts.dimensions
diff --git a/tex/context/base/page-flt.lua b/tex/context/base/page-flt.lua
index 11aa2be21..7b1afc55c 100644
--- a/tex/context/base/page-flt.lua
+++ b/tex/context/base/page-flt.lua
@@ -21,20 +21,23 @@ local C, S, P, lpegmatch = lpeg.C, lpeg.S, lpeg.P, lpeg.match
-- we use floatbox, floatwidth, floatheight
-- text page leftpage rightpage (todo: top, bottom, margin, order)
-local copy_node_list = node.copy_list
+local copy_node_list = node.copy_list
+local flush_node_list = node.flush_list
+local copy_node = node.copy
-local setdimen = tex.setdimen
-local setcount = tex.setcount
-local texgetbox = tex.getbox
-local texsetbox = tex.setbox
+local setdimen = tex.setdimen
+local setcount = tex.setcount
+local texgetbox = tex.getbox
+local texsetbox = tex.setbox
+local textakebox = nodes.takebox
-floats = floats or { }
-local floats = floats
+floats = floats or { }
+local floats = floats
-local noffloats = 0
-local last = nil
-local default = "text"
-local pushed = { }
+local noffloats = 0
+local last = nil
+local default = "text"
+local pushed = { }
local function initialize()
return {
@@ -105,21 +108,20 @@ end
function floats.save(which,data)
which = which or default
- local b = texgetbox("floatbox")
+ local b = textakebox("floatbox")
if b then
local stack = stacks[which]
noffloats = noffloats + 1
- local w, h, d = b.width, b.height, b.depth
local t = {
n = noffloats,
data = data or { },
- box = copy_node_list(b),
+ box = b,
}
- texsetbox("floatbox",nil)
insert(stack,t)
setcount("global","savednoffloats",#stacks[default])
if trace_floats then
- report_floats("%s, category %a, number %a, slot %a, width %p, height %p, depth %p","saving",which,noffloats,#stack,w,h,d)
+ report_floats("%s, category %a, number %a, slot %a, width %p, height %p, depth %p","saving",
+ which,noffloats,#stack,b.width,b.height,b.depth)
else
interfaces.showmessage("floatblocks",2,noffloats)
end
@@ -132,14 +134,13 @@ function floats.resave(which)
if last then
which = which or default
local stack = stacks[which]
- local b = texgetbox("floatbox")
- local w, h, d = b.width, b.height, b.depth
- last.box = copy_node_list(b)
- texsetbox("floatbox",nil)
+ local b = textakebox("floatbox")
+ last.box = b
insert(stack,1,last)
setcount("global","savednoffloats",#stacks[default])
if trace_floats then
- report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","resaving",which,noffloats,#stack,w,h,d)
+ report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","resaving",
+ which,noffloats,#stack,b.width,b.height,b.depth)
else
interfaces.showmessage("floatblocks",2,noffloats)
end
@@ -153,9 +154,10 @@ function floats.flush(which,n,bylabel)
local stack = stacks[which]
local t, b, n = get(stack,n or 1,bylabel)
if t then
- local w, h, d = setdimensions(b)
if trace_floats then
- report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","flushing",which,t.n,n,w,h,d)
+ local w, h, d = setdimensions(b) -- ?
+ report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","flushing",
+ which,t.n,n,w,h,d)
else
interfaces.showmessage("floatblocks",3,t.n)
end
@@ -173,9 +175,10 @@ function floats.consult(which,n)
local stack = stacks[which]
local t, b, n = get(stack,n)
if t then
- local w, h, d = setdimensions(b)
if trace_floats then
- report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","consulting",which,t.n,n,w,h,d)
+ local w, h, d = setdimensions(b)
+ report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","consulting",
+ which,t.n,n,w,h,d)
end
return t, b, n
else
@@ -270,16 +273,16 @@ end
-- interface
-local context = context
-local setvalue = context.setvalue
+local context = context
+local context_setvalue = context.setvalue
-commands.flushfloat = floats.flush
-commands.savefloat = floats.save
-commands.resavefloat = floats.resave
-commands.pushfloat = floats.push
-commands.popfloat = floats.pop
-commands.consultfloat = floats.consult
-commands.collectfloat = floats.collect
+commands.flushfloat = floats.flush
+commands.savefloat = floats.save
+commands.resavefloat = floats.resave
+commands.pushfloat = floats.push
+commands.popfloat = floats.pop
+commands.consultfloat = floats.consult
+commands.collectfloat = floats.collect
function commands.getfloatvariable (...) local v = floats.getvariable(...) if v then context(v) end end
function commands.checkedpagefloat (...) local v = floats.checkedpagefloat(...) if v then context(v) end end
@@ -289,8 +292,8 @@ function commands.doifelsesavedfloat(...) commands.doifelse(floats.nofstacked(..
function commands.analysefloatmethod(str) -- currently only one method
local method, label, row, column = floats.analysemethod(str)
- setvalue("floatmethod",method or "")
- setvalue("floatlabel", label or "")
- setvalue("floatrow", row or "")
- setvalue("floatcolumn",column or "")
+ context_setvalue("floatmethod",method or "")
+ context_setvalue("floatlabel", label or "")
+ context_setvalue("floatrow", row or "")
+ context_setvalue("floatcolumn",column or "")
end
diff --git a/tex/context/base/page-imp.mkiv b/tex/context/base/page-imp.mkiv
index cfa535ab2..230ede570 100644
--- a/tex/context/base/page-imp.mkiv
+++ b/tex/context/base/page-imp.mkiv
@@ -41,7 +41,7 @@
\prependtoks
\page_shipouts_flush_text_data
\to \everylastshipout
-
+
% Problem: we need to apply the finalizers to a to be shipped out page (as
% we can have positioning involved). However, we can also add stuff in the
% imposition, like cropmarks. Fortunately we do that with metapost so
diff --git a/tex/context/base/page-mix.lua b/tex/context/base/page-mix.lua
index 30a1fdccd..0fbaa4e30 100644
--- a/tex/context/base/page-mix.lua
+++ b/tex/context/base/page-mix.lua
@@ -295,18 +295,47 @@ local function setsplit(specification) -- a rather large function
local rest = nil
local lastlocked = nil
local lastcurrent = nil
+ local lastcontent = nil
local backtracked = false
if trace_state then
report_state("setting collector to column %s",column)
end
+ local function unlock(penalty)
+ if lastlocked then
+ if trace_state then
+ report_state("penalty %s, unlocking in column %s",penalty or "-",column)
+ end
+ lastlocked = nil
+ end
+ lastcurrent = nil
+ lastcontent = nil
+ end
+
+ local function lock(penalty,current)
+ if trace_state then
+ report_state("penalty %s, locking in column %s",penalty,column)
+ end
+ lastlocked = penalty
+ lastcurrent = current or lastcurrent
+ lastcontent = nil
+ end
+
local function backtrack(start)
local current = start
-- first skip over glue and penalty
while current do
local id = getid(current)
- if id == glue_code or id == penalty_code then
+ if id == glue_code then
+ if trace_state then
+ report_state("backtracking over %s in column %s","glue",column)
+ end
+ current = getprev(current)
+ elseif id == penalty_code then
+ if trace_state then
+ report_state("backtracking over %s in column %s","penalty",column)
+ end
current = getprev(current)
else
break
@@ -315,13 +344,24 @@ local function setsplit(specification) -- a rather large function
-- then skip over content
while current do
local id = getid(current)
- if id == glue_code or id == penalty_code then
+ if id == glue_code then
+ if trace_state then
+ report_state("quitting at %s in column %s","glue",column)
+ end
+ break
+ elseif id == penalty_code then
+ if trace_state then
+ report_state("quitting at %s in column %s","penalty",column)
+ end
break
else
current = getprev(current)
end
end
if not current then
+ if trace_state then
+ report_state("no effective backtracking in column %s",column)
+ end
current = start
end
return current
@@ -338,7 +378,12 @@ local function setsplit(specification) -- a rather large function
backtracked = true
end
lastcurrent = nil
- lastlocked = nil
+ if lastlocked then
+ if trace_state then
+ report_state("unlocking in column %s",column)
+ end
+ lastlocked = nil
+ end
end
if head == lasthead then
if trace_state then
@@ -439,6 +484,9 @@ local function setsplit(specification) -- a rather large function
else
-- what else? ignore? treat as valid as usual?
end
+ if lastcontent then
+ unlock()
+ end
end
local function process_kern(current,nxt)
@@ -466,24 +514,27 @@ local function setsplit(specification) -- a rather large function
local function process_rule(current,nxt)
-- simple variant of h|vlist
local advance = getfield(current,"height") -- + getfield(current,"depth")
- local state, skipped = checked(advance+currentskips,"rule")
- if trace_state then
- report_state("%-7s > column %s, state %a, rule, advance %p, height %p","rule",column,state,advance,inserttotal,height)
- if skipped ~= 0 then
- report_state("%-7s > column %s, discarded %p","rule",column,skipped)
+ if advance ~= 0 then
+ local state, skipped = checked(advance,"rule")
+ if trace_state then
+ report_state("%-7s > column %s, state %a, rule, advance %p, height %p","rule",column,state,advance,inserttotal,height)
+ if skipped ~= 0 then
+ report_state("%-7s > column %s, discarded %p","rule",column,skipped)
+ end
end
+ if state == "quit" then
+ return true
+ end
+ height = height + depth + skip + advance
+ -- if state == "next" then
+ -- height = height + nextskips
+ -- else
+ -- height = height + currentskips
+ -- end
+ depth = getfield(current,"depth")
+ skip = 0
end
- if state == "quit" then
- return true
- end
- height = height + depth + skip + advance
- if state == "next" then
- height = height + nextskips
- else
- height = height + currentskips
- end
- depth = getfield(current,"depth")
- skip = 0
+ lastcontent = current
end
-- okay, here we could do some badness like magic but we want something
@@ -495,8 +546,7 @@ local function setsplit(specification) -- a rather large function
local function process_penalty(current,nxt)
local penalty = getfield(current,"penalty")
if penalty == 0 then
- lastlocked = nil
- lastcurrent = nil
+ unlock(penalty)
elseif penalty == forcedbreak then
local needed = getattribute(current,a_checkedbreak)
local proceed = not needed or needed == 0
@@ -508,8 +558,7 @@ local function setsplit(specification) -- a rather large function
end
end
if proceed then
- lastlocked = nil
- lastcurrent = nil
+ unlock(penalty)
local okay, skipped = gotonext()
if okay then
if trace_state then
@@ -530,18 +579,15 @@ local function setsplit(specification) -- a rather large function
end
elseif penalty < 0 then
-- we don't care too much
- lastlocked = nil
- lastcurrent = nil
+ unlock(penalty)
elseif penalty >= 10000 then
if not lastcurrent then
- lastcurrent = current
- lastlocked = penalty
+ lock(penalty,current)
elseif penalty > lastlocked then
- lastlocked = penalty
+ lock(penalty)
end
else
- lastlocked = nil
- lastcurrent = nil
+ unlock(penalty)
end
end
@@ -582,8 +628,11 @@ local function setsplit(specification) -- a rather large function
if trace_state then
report_state("%-7s > column %s, height %p, depth %p, skip %p","line",column,height,depth,skip)
end
+ lastcontent = current
end
+local kept = head
+
while current do
local id = getid(current)
@@ -633,14 +682,16 @@ local function setsplit(specification) -- a rather large function
if not current then
if trace_state then
- report_state("nilling rest")
+ report_state("nothing left")
end
- rest = nil
- elseif rest == lasthead then
+ -- needs well defined case
+ -- rest = nil
+ elseif rest == lasthead then
if trace_state then
- report_state("nilling rest as rest is lasthead")
+ report_state("rest equals lasthead")
end
- rest = nil
+ -- test case: x\index{AB} \index{AA}x \blank \placeindex
+ -- makes line disappear: rest = nil
end
if stripbottom then
diff --git a/tex/context/base/page-mix.mkiv b/tex/context/base/page-mix.mkiv
index d2bb38ca0..38b5d672f 100644
--- a/tex/context/base/page-mix.mkiv
+++ b/tex/context/base/page-mix.mkiv
@@ -75,7 +75,7 @@
\let\startmixedcolumns\relax % defined later
\let\stopmixedcolumns \relax % defined later
-\appendtoks
+\appendtoks % could become an option
\setuevalue{\e!start\currentmixedcolumns}{\startmixedcolumns[\currentmixedcolumns]}%
\setuevalue{\e!stop \currentmixedcolumns}{\stopmixedcolumns}%
\to \everydefinemixedcolumns
@@ -500,7 +500,9 @@
\setvalue{\??mixedcolumnsstop\s!otr}%
{\par
\ifcase\c_page_mix_otr_nesting\or
- \doif{\mixedcolumnsparameter\c!balance}\v!yes{\c_page_mix_routine\c_page_mix_routine_balance}%
+ \doifelse{\mixedcolumnsparameter\c!balance}\v!yes
+ {\c_page_mix_routine\c_page_mix_routine_balance}%
+ {\penalty-\plustenthousand}% weird hack, we need to trigger the otr sometimes (new per 20140306, see balancing-001.tex)
\page_otr_trigger_output_routine
\fi}
diff --git a/tex/context/base/page-mul.mkiv b/tex/context/base/page-mul.mkiv
index 73d84fe14..0063b3311 100644
--- a/tex/context/base/page-mul.mkiv
+++ b/tex/context/base/page-mul.mkiv
@@ -960,7 +960,7 @@
\ifnum\c_page_mul_balance_tries>\c_page_mul_balance_tries_max\relax
\showmessage\m!columns7\empty
\else
- \showmessage\m!columns8{\the\c_page_mul_balance_tries\space}%
+ \showmessage\m!columns8{\the\c_page_mul_balance_tries}%
\fi
\egroup}
diff --git a/tex/context/base/page-txt.mkvi b/tex/context/base/page-txt.mkvi
index 240f0e00b..6d8d50028 100644
--- a/tex/context/base/page-txt.mkvi
+++ b/tex/context/base/page-txt.mkvi
@@ -440,12 +440,12 @@
\def\page_layouts_set_text_content[#vertical][#horizontal][#one][#two][#three]% header text middle text/text
{\iffifthargument
- \setvalue{\namedlayoutelementhash{#vertical:#horizontal}\executeifdefined{\??layouttextcontent\c!text:#one}\c!middletext}%
+ \setvalue{\namedlayoutelementhash{#vertical:#horizontal}\executeifdefined{\??layouttextcontent\v!text:#one}\c!middletext}%
{\page_layouts_process_element_double
\c!leftstyle \c!leftcolor \c!leftwidth {#two}%
\c!rightstyle\c!rightcolor\c!rightwidth{#three}}%
\else\iffourthargument
- \setvalue{\namedlayoutelementhash{#vertical:#horizontal}\executeifdefined{\??layouttextcontent\c!text:#one}\c!middletext}%
+ \setvalue{\namedlayoutelementhash{#vertical:#horizontal}\executeifdefined{\??layouttextcontent\v!text:#one}\c!middletext}%
{\page_layouts_process_element_double
\c!leftstyle \c!leftcolor \c!leftwidth {#two}%
\c!rightstyle\c!rightcolor\c!rightwidth{#two}}%
@@ -462,16 +462,16 @@
\def\page_layouts_reset_text_content[#vertical][#horizontal][#tag]% header text middle
{\edef\currentlayoutelement{#vertical:#horizontal}%
\ifthirdargument
- \letvalueempty{\layoutelementhash\executeifdefined{\??layouttextcontent\c!text:#tag}\c!middletext}%
+ \letvalueempty{\layoutelementhash\executeifdefined{\??layouttextcontent\v!text:#tag}\c!middletext}%
\else\ifsecondargument
\resetlayoutelementparameter\c!lefttext
\resetlayoutelementparameter\c!middletext
\resetlayoutelementparameter\c!righttext
\fi\fi}
-\letvalue{\??layouttextcontent\c!middle:\c!text}\c!middletext
-\letvalue{\??layouttextcontent\c!left :\c!text}\c!lefttext
-\letvalue{\??layouttextcontent\c!right :\c!text}\c!righttext
+\letvalue{\??layouttextcontent\c!middle:\v!text}\c!middletext
+\letvalue{\??layouttextcontent\c!left :\v!text}\c!lefttext
+\letvalue{\??layouttextcontent\c!right :\v!text}\c!righttext
%D The placement of a whole line is handled by the next two
%D macros. These are hooked into the general purpose token
diff --git a/tex/context/base/pdfr-def.mkii b/tex/context/base/pdfr-def.mkii
index 7554bda9e..b3f67b93f 100644
--- a/tex/context/base/pdfr-def.mkii
+++ b/tex/context/base/pdfr-def.mkii
@@ -1,4 +1,4 @@
-% filename : pdfr-def.tex
+% filename : pdfr-def.mkii
% comment : generated by mtxrun --script chars --pdf
% author : Hans Hagen, PRAGMA-ADE, Hasselt NL
% copyright: PRAGMA ADE / ConTeXt Development Team
diff --git a/tex/context/base/phys-dim.lua b/tex/context/base/phys-dim.lua
index e40d1eabb..870cbd29b 100644
--- a/tex/context/base/phys-dim.lua
+++ b/tex/context/base/phys-dim.lua
@@ -39,6 +39,7 @@ if not modules then modules = { } end modules ['phys-dim'] = {
-- RevPerSec = [[RPS]],
-- RevPerMin = [[RPM]],
+local rawset, next = rawset, next
local V, P, S, R, C, Cc, Cs, matchlpeg = lpeg.V, lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.match
local format, lower = string.format, string.lower
local appendlpeg = lpeg.append
@@ -506,20 +507,20 @@ local packaged_units = {
-- rendering:
-local unitsPUS = context.unitsPUS
-local unitsPU = context.unitsPU
-local unitsPS = context.unitsPS
-local unitsP = context.unitsP
-local unitsUS = context.unitsUS
-local unitsU = context.unitsU
-local unitsS = context.unitsS
-local unitsO = context.unitsO
-local unitsN = context.unitsN
-local unitsC = context.unitsC
-local unitsQ = context.unitsQ
-local unitsNstart = context.unitsNstart
-local unitsNstop = context.unitsNstop
-local unitsNspace = context.unitsNspace
+local ctx_unitsPUS = context.unitsPUS
+local ctx_unitsPU = context.unitsPU
+local ctx_unitsPS = context.unitsPS
+local ctx_unitsP = context.unitsP
+local ctx_unitsUS = context.unitsUS
+local ctx_unitsU = context.unitsU
+local ctx_unitsS = context.unitsS
+local ctx_unitsO = context.unitsO
+local ctx_unitsN = context.unitsN
+local ctx_unitsC = context.unitsC
+local ctx_unitsQ = context.unitsQ
+local ctx_unitsNstart = context.unitsNstart
+local ctx_unitsNstop = context.unitsNstop
+local ctx_unitsNspace = context.unitsNspace
local labels = languages.data.labels
@@ -664,28 +665,28 @@ local function dimpus(p,u,s)
if p ~= "" then
if u ~= "" then
if s ~= "" then
- unitsPUS(p,u,s)
+ ctx_unitsPUS(p,u,s)
else
- unitsPU(p,u)
+ ctx_unitsPU(p,u)
end
elseif s ~= "" then
- unitsPS(p,s)
+ ctx_unitsPS(p,s)
else
- unitsP(p)
+ ctx_unitsP(p)
end
else
if u ~= "" then
if s ~= "" then
- unitsUS(u,s)
+ ctx_unitsUS(u,s)
-- elseif c then
- -- unitsC(u)
+ -- ctx_unitsC(u)
else
- unitsU(u)
+ ctx_unitsU(u)
end
elseif s ~= "" then
- unitsS(s)
+ ctx_unitsS(s)
else
- unitsP(p)
+ ctx_unitsP(p)
end
end
end
@@ -699,7 +700,7 @@ local function dimop(o)
report_units("operator %a",o)
end
if o then
- unitsO(o)
+ ctx_unitsO(o)
end
end
@@ -709,7 +710,7 @@ local function dimsym(s)
end
s = symbol_units[s] or s
if s then
- unitsC(s)
+ ctx_unitsC(s)
end
end
@@ -719,7 +720,7 @@ local function dimpre(p)
end
p = packaged_units[p] or p
if p then
- unitsU(p)
+ ctx_unitsU(p)
end
end
@@ -789,7 +790,7 @@ local function update_parsers() -- todo: don't remap utf sequences
* (V("packaged") / dimpre)
* V("somespace"),
-- someunknown = V("somespace")
- -- * (V("nospace")/unitsU)
+ -- * (V("nospace")/ctx_unitsU)
-- * V("somespace"),
--
combination = V("longprefix") * V("longunit") -- centi meter
@@ -804,7 +805,7 @@ local function update_parsers() -- todo: don't remap utf sequences
+ (V("longsuffix") * V("combination")) / dimspu
+ (V("combination") * (V("shortsuffix") + V("nothing"))) / dimpus
)
- * (V("qualifier") / unitsQ)^-1
+ * (V("qualifier") / ctx_unitsQ)^-1
* V("somespace"),
operator = V("somespace")
* ((V("longoperator") + V("shortoperator")) / dimop)
@@ -824,13 +825,13 @@ local function update_parsers() -- todo: don't remap utf sequences
local number = Cs( P("$") * (1-P("$"))^1 * P("$")
+ P([[\m{]]) * (1-P("}"))^1 * P("}")
+ (1-R("az","AZ")-P(" "))^1 -- todo: catch { } -- not ok
- ) / unitsN
+ ) / ctx_unitsN
- local start = Cc(nil) / unitsNstart
- local stop = Cc(nil) / unitsNstop
- local space = Cc(nil) / unitsNspace
+ local start = Cc(nil) / ctx_unitsNstart
+ local stop = Cc(nil) / ctx_unitsNstop
+ local space = Cc(nil) / ctx_unitsNspace
- -- todo: avoid \unitsNstart\unitsNstop (weird that it can happen .. now catched at tex end)
+ -- todo: avoid \ctx_unitsNstart\ctx_unitsNstop (weird that it can happen .. now catched at tex end)
local p_c_combinedparser = P { "start",
number = start * dleader * (p_c_dparser + number) * stop,
diff --git a/tex/context/base/publ-dat.lua b/tex/context/base/publ-dat.lua
index 8fce94822..b463064ca 100644
--- a/tex/context/base/publ-dat.lua
+++ b/tex/context/base/publ-dat.lua
@@ -382,9 +382,7 @@ end
function loaders.lua(dataset,filename) -- if filename is a table we load that one
dataset = datasets[dataset]
- if type(dataset) == "table" then
- dataset = datasets[dataset]
- end
+ inspect(filename)
local data = type(filename) == "table" and filename or table.load(filename)
if data then
local luadata = dataset.luadata
@@ -401,13 +399,13 @@ function loaders.xml(dataset,filename)
dataset = datasets[dataset]
local luadata = dataset.luadata
local root = xml.load(filename)
- for entry in xmlcollected(root,"/bibtex/entry") do
- local attributes = entry.at
+ for bibentry in xmlcollected(root,"/bibtex/entry") do
+ local attributes = bibentry.at
local tag = attributes.tag
local entry = {
category = attributes.category
}
- for field in xmlcollected(entry,"/field") do
+ for field in xmlcollected(bibentry,"/field") do
-- entry[field.at.name] = xmltext(field)
entry[field.at.name] = field.dt[1] -- no cleaning yet
end
diff --git a/tex/context/base/publ-ini.mkiv b/tex/context/base/publ-ini.mkiv
index 42226695c..adbf8f7fc 100644
--- a/tex/context/base/publ-ini.mkiv
+++ b/tex/context/base/publ-ini.mkiv
@@ -530,7 +530,7 @@
% \to \everysetupbtxlistplacement
\unexpanded\def\btxflushauthor
- {\doifnextoptionalelse\btx_flush_author_yes\btx_flush_author_nop}
+ {\doifnextoptionalcselse\btx_flush_author_yes\btx_flush_author_nop}
\def\btx_flush_author_yes[#1]{\btx_flush_author{#1}}
\def\btx_flush_author_nop {\btx_flush_author{\btxlistvariantparameter\c!author}}
diff --git a/tex/context/base/s-abr-01.tex b/tex/context/base/s-abr-01.tex
index e9ea6393b..733eebf7b 100644
--- a/tex/context/base/s-abr-01.tex
+++ b/tex/context/base/s-abr-01.tex
@@ -240,6 +240,7 @@
\logo [TABLE] {\TaBlE}
\logo [TCPIP] {tcp/ip}
\logo [TDS] {tds} % no sc te
+\logo [TEI] {tei} % no sc te
\logo [TETEX] {te\TeX} % no sc te
\logo [TEX] {\TeX}
\logo [TEXADRES] {\TeX adress}
diff --git a/tex/context/base/s-inf-03.mkiv b/tex/context/base/s-inf-03.mkiv
index fc654fef5..b6dada55a 100644
--- a/tex/context/base/s-inf-03.mkiv
+++ b/tex/context/base/s-inf-03.mkiv
@@ -352,7 +352,6 @@ for k, v in table.sortedpairs(_G) do
end
end
-
\stopluacode
\stoptext
diff --git a/tex/context/base/scrn-but.mkvi b/tex/context/base/scrn-but.mkvi
index fd2da9e08..f8b236c52 100644
--- a/tex/context/base/scrn-but.mkvi
+++ b/tex/context/base/scrn-but.mkvi
@@ -217,12 +217,12 @@
{\global\settrue\c_scrn_button_skipped}
\def\scrn_button_make_normal#currentparameter#inheritedframed#letparameter#setparameter#text%
- {\ctxlua{structures.references.injectcurrentset(nil,nil)}%
+ {\ctxcommand{injectcurrentreference()}%
\hbox attr \referenceattribute \lastreferenceattribute
{#inheritedframed{\ignorespaces#text\removeunwantedspaces}}}
\def\scrn_button_make_contrast#currentparameter#inheritedframed#letparameter#setparameter#text%
- {\ctxlua{structures.references.injectcurrentset(nil,nil)}%
+ {\ctxcommand{injectcurrentreference()}%
\hbox attr \referenceattribute \lastreferenceattribute
{#setparameter\c!foregroundcolor{#currentparameter\c!contrastcolor}%
#inheritedframed{\ignorespaces#text\removeunwantedspaces}}}
diff --git a/tex/context/base/scrn-wid.mkvi b/tex/context/base/scrn-wid.mkvi
index fad451651..8dcc7a86a 100644
--- a/tex/context/base/scrn-wid.mkvi
+++ b/tex/context/base/scrn-wid.mkvi
@@ -401,7 +401,7 @@
{\doifassignmentelse{#title}
{\setupcurrentcomment[#title]}
{\setupcurrentcomment[\c!title=#title,#settings]}%
- \ctxlua{buffers.assign("\v!comment",\!!bs#text\!!es)}% todo: expansion control, but expanded by default (xml)
+ \ctxcommand{assignbuffer("\v!comment",\!!bs#text\!!es)}% todo: expansion control, but expanded by default (xml)
\scrn_comment_inject
\ignorespaces}
diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua
index d279f1253..9ac020166 100644
--- a/tex/context/base/sort-ini.lua
+++ b/tex/context/base/sort-ini.lua
@@ -457,7 +457,7 @@ function sorters.strip(str) -- todo: only letters and such
str = gsub(str,"\\[\"\'~^`]*","") -- \"e -- hm, too greedy
str = gsub(str,"\\%S*","") -- the rest
str = gsub(str,"%s","\001") -- can be option
- str = gsub(str,"[%s%[%](){}%$\"\']*","")
+ str = gsub(str,"[%s%[%](){}%$\"\']*","") -- %s already done
if digits == v_numbers then
str = gsub(str,"(%d+)",numify) -- sort numbers properly
end
diff --git a/tex/context/base/spac-chr.lua b/tex/context/base/spac-chr.lua
index 4122a64b6..1abba350a 100644
--- a/tex/context/base/spac-chr.lua
+++ b/tex/context/base/spac-chr.lua
@@ -14,6 +14,8 @@ local byte, lower = string.byte, string.lower
-- to be redone: characters will become tagged spaces instead as then we keep track of
-- spaceskip etc
+-- todo: only setattr when export
+
local next = next
trace_characters = false trackers.register("typesetters.characters", function(v) trace_characters = v end)
diff --git a/tex/context/base/spac-hor.mkiv b/tex/context/base/spac-hor.mkiv
index 4cd913290..92491ce32 100644
--- a/tex/context/base/spac-hor.mkiv
+++ b/tex/context/base/spac-hor.mkiv
@@ -32,7 +32,7 @@
{\doifoutervmode{\ifconditional\c_spac_indentation_indent_first\else\spac_indentation_variant_no\fi}}
\unexpanded\def\setupindenting
- {\doifnextoptionalelse\spac_indentation_setup_options\spac_indentation_setup_size}
+ {\doifnextoptionalcselse\spac_indentation_setup_options\spac_indentation_setup_size}
\unexpanded\def\spac_indentation_setup_size
{\assigndimension\v_spac_indentation_current\d_spac_indentation_par{1\emwidth}{1.5\emwidth}{2\emwidth}}
@@ -64,24 +64,65 @@
\def\spac_indentation_set_everypar
{\everypar{\checkindentation}}
+% \def\spac_indentation_apply_step_one#1%
+% {\ifcsname\??indentingmethod#1\endcsname
+% % case two
+% \else
+% \edef\v_spac_indentation_current{#1}% single entry in list
+% \let\normalindentation\v_spac_indentation_current
+% \spac_indentation_setup_size
+% \fi}
+%
+% \def\spac_indentation_apply_step_two#1%
+% {\ifcsname\??indentingmethod#1\endcsname
+% \csname\??indentingmethod#1\endcsname
+% \else
+% % case one
+% \fi}
+
+% \defineindenting[whatever][yes,2cm]
+% %defineindenting[whatever][yes,-2cm]
+%
+% \setupindenting[yes,-2em] \input ward \par
+% \setupindenting[yes,2em] \input ward \par
+% \setupindenting[whatever] \input ward \par
+
+\installcorenamespace {indentingpreset}
+
+\unexpanded\def\defineindenting
+ {\dodoubleargument\spac_indenting_define}
+
+\def\spac_indenting_define[#1][#2]% todo: mixes
+ {\setevalue{\??indentingpreset#1}{#2}}
+
+\def\spac_indentation_apply_step_one_nested#1%
+ {\expandafter\processcommacommand\expandafter[\csname\??indentingpreset#1\endcsname]\spac_indentation_apply_step_one}
+
+\def\spac_indentation_apply_step_two_nested#1%
+ {\expandafter\processcommacommand\expandafter[\csname\??indentingpreset#1\endcsname]\spac_indentation_apply_step_two}
+
\def\spac_indentation_apply_step_one#1%
- {\ifcsname\??indentingmethod#1\endcsname
+ {\ifcsname\??indentingpreset#1\endcsname
+ \spac_indentation_apply_step_one_nested{#1}%
+ \else\ifcsname\??indentingmethod#1\endcsname
% case two
\else
\edef\v_spac_indentation_current{#1}% single entry in list
\let\normalindentation\v_spac_indentation_current
\spac_indentation_setup_size
- \fi}
+ \fi\fi}
\def\spac_indentation_apply_step_two#1%
- {\ifcsname\??indentingmethod#1\endcsname
+ {\ifcsname\??indentingpreset#1\endcsname
+ \spac_indentation_apply_step_two_nested{#1}%
+ \else\ifcsname\??indentingmethod#1\endcsname
\csname\??indentingmethod#1\endcsname
\else
% case one
- \fi}
+ \fi\fi}
\unexpanded\def\indenting % kind of obsolete
- {\doifnextoptionalelse\spac_indentation_setup_options\relax}
+ {\doifnextoptionalcselse\spac_indentation_setup_options\relax}
% use \noindentation to suppress next indentation
@@ -339,7 +380,7 @@
\installspacingmethod \v!broad {\nonfrenchspacing} % more depending on what punctuation
\unexpanded\def\setupspacing
- {\doifnextoptionalelse\spac_spacecodes_setup_yes\spac_spacecodes_setup_nop}
+ {\doifnextoptionalcselse\spac_spacecodes_setup_yes\spac_spacecodes_setup_nop}
\def\spac_spacecodes_setup_yes[#1]%
{\csname\??spacecodemethod#1\endcsname
@@ -1059,7 +1100,7 @@
%D A rather unknown one:
\unexpanded\def\widened % moved from cont-new
- {\doifnextoptionalelse\spac_widened_yes\spac_widened_nop}
+ {\doifnextoptionalcselse\spac_widened_yes\spac_widened_nop}
\def\spac_widened_yes[#1]#2{\hbox \s!spread #1{\hss#2\hss}}
\def\spac_widened_nop #1{\hbox \s!spread \emwidth{\hss#1\hss}}
diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua
index 7d78d6c12..21695a396 100644
--- a/tex/context/base/spac-ver.lua
+++ b/tex/context/base/spac-ver.lua
@@ -584,15 +584,15 @@ do -- todo: interface.variables
-- This will change: just node.write and we can store the values in skips which
-- then obeys grouping
- local fixedblankskip = context.fixedblankskip
- local flexibleblankskip = context.flexibleblankskip
- local setblankcategory = context.setblankcategory
- local setblankorder = context.setblankorder
- local setblankpenalty = context.setblankpenalty
- local setblankhandling = context.setblankhandling
- local flushblankhandling = context.flushblankhandling
- local addpredefinedblankskip = context.addpredefinedblankskip
- local addaskedblankskip = context.addaskedblankskip
+ local ctx_fixedblankskip = context.fixedblankskip
+ local ctx_flexibleblankskip = context.flexibleblankskip
+ local ctx_setblankcategory = context.setblankcategory
+ local ctx_setblankorder = context.setblankorder
+ local ctx_setblankpenalty = context.setblankpenalty
+ ----- ctx_setblankhandling = context.setblankhandling
+ local ctx_flushblankhandling = context.flushblankhandling
+ local ctx_addpredefinedblankskip = context.addpredefinedblankskip
+ local ctx_addaskedblankskip = context.addaskedblankskip
local function analyze(str,oldcategory) -- we could use shorter names
for s in gmatch(str,"([^ ,]+)") do
@@ -604,35 +604,35 @@ do -- todo: interface.variables
if mk then
category = analyze(mk,category)
elseif keyword == k_fixed then
- fixedblankskip()
+ ctx_fixedblankskip()
elseif keyword == k_flexible then
- flexibleblankskip()
+ ctx_flexibleblankskip()
elseif keyword == k_category then
local category = tonumber(detail)
if category then
- setblankcategory(category)
+ ctx_setblankcategory(category)
if category ~= oldcategory then
- flushblankhandling()
+ ctx_flushblankhandling()
oldcategory = category
end
end
elseif keyword == k_order and detail then
local order = tonumber(detail)
if order then
- setblankorder(order)
+ ctx_setblankorder(order)
end
elseif keyword == k_penalty and detail then
local penalty = tonumber(detail)
if penalty then
- setblankpenalty(penalty)
+ ctx_setblankpenalty(penalty)
end
else
amount = tonumber(amount) or 1
local sk = skip[keyword]
if sk then
- addpredefinedblankskip(amount,keyword)
+ ctx_addpredefinedblankskip(amount,keyword)
else -- no check
- addaskedblankskip(amount,keyword)
+ ctx_addaskedblankskip(amount,keyword)
end
end
end
@@ -640,22 +640,22 @@ do -- todo: interface.variables
return category
end
- local pushlogger = context.pushlogger
- local startblankhandling = context.startblankhandling
- local stopblankhandling = context.stopblankhandling
- local poplogger = context.poplogger
+ local ctx_pushlogger = context.pushlogger
+ local ctx_startblankhandling = context.startblankhandling
+ local ctx_stopblankhandling = context.stopblankhandling
+ local ctx_poplogger = context.poplogger
function vspacing.analyze(str)
if trace_vspacing then
- pushlogger(report_vspacing)
- startblankhandling()
+ ctx_pushlogger(report_vspacing)
+ ctx_startblankhandling()
analyze(str,1)
- stopblankhandling()
- poplogger()
+ ctx_stopblankhandling()
+ ctx_poplogger()
else
- startblankhandling()
+ ctx_startblankhandling()
analyze(str,1)
- stopblankhandling()
+ ctx_stopblankhandling()
end
end
@@ -774,7 +774,8 @@ local splittopskip_code = skipcodes.splittopskip
-- end
local free_glue_node = free_node
-local free_glue_spec = function() end -- free_node
+local free_glue_spec = function() end
+----- free_glue_spec = free_node -- can be enabled in in 0.73 (so for the moment we leak due to old luatex engine issues)
function vspacing.snapbox(n,how)
local sv = snapmethods[how]
@@ -1403,3 +1404,4 @@ commands.vspacingdefine = vspacing.setmap
commands.vspacingcollapse = vspacing.collapsevbox
commands.vspacingsnap = vspacing.snapbox
commands.resetprevdepth = vspacing.resetprevdepth
+commands.definesnapmethod = vspacing.definesnapmethod
diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv
index afa722cfe..1f8bf2c79 100644
--- a/tex/context/base/spac-ver.mkiv
+++ b/tex/context/base/spac-ver.mkiv
@@ -152,10 +152,14 @@
\unexpanded\def\setupinterlinespace
{\dodoubleempty\spac_linespacing_setup}
+\ifdefined\setupinterlinespace_double \else
+ \let\setupinterlinespace_double\setup_interlinespace % for a while
+\fi
+
\def\spac_linespacing_setup[#1][#2]%
{\settrue\interlinespaceisset % reset has to be done when needed
\ifsecondargument
- \setup_interlinespace[#1][#2]%
+ \setupinterlinespace_double[#1][#2]%
\else\iffirstargument
\ifcsname\namedinterlinespacehash{#1}\s!parent\endcsname
\edef\currentinterlinespace{#1}%
@@ -330,7 +334,7 @@
\let\v_spac_whitespace_current\v!none
\unexpanded\def\setupwhitespace
- {\doifnextoptionalelse\spac_whitespace_setup_yes\spac_whitespace_setup_nop}
+ {\doifnextoptionalcselse\spac_whitespace_setup_yes\spac_whitespace_setup_nop}
\def\spac_whitespace_setup_nop
{\ifx\v_spac_whitespace_current\v!none\else
@@ -1154,6 +1158,10 @@
\let\normaloffinterlineskip\offinterlineskip % knuth's original
+\appendtoks
+ \ifvmode\ctxcommand{resetprevdepth()}\fi % a nasty hack (tested for a while now)
+\to \everyafteroutput
+
%D My own one:
\unexpanded\def\spac_helpers_push_interlineskip_yes
@@ -1325,7 +1333,7 @@
\unexpanded\def\installsnapvalues#1#2% todo: a proper define
{\edef\currentsnapper{#1:#2}%
\ifcsname\??gridsnapperattributes\currentsnapper\endcsname \else
- \setevalue{\??gridsnapperattributes\currentsnapper}{\ctxlua{builders.vspacing.definesnapmethod("#1","#2")}}%
+ \setevalue{\??gridsnapperattributes\currentsnapper}{\ctxcommand{definesnapmethod("#1","#2")}}%
\fi
\setevalue{\??gridsnappers#1}{\attribute\snapmethodattribute\csname\??gridsnapperattributes\currentsnapper\endcsname\space}}
@@ -1751,7 +1759,7 @@
% The main spacer:
\unexpanded\def\vspacing
- {\doifnextoptionalelse\spac_vspacing_yes\spac_vspacing_nop}
+ {\doifnextoptionalcselse\spac_vspacing_yes\spac_vspacing_nop}
\def\spac_vspacing_yes
{\ifinpagebody % somewhat weird
@@ -1807,7 +1815,7 @@
% these depend on bigskipamount cum suis so we'd better sync them
\unexpanded\def\setupvspacing
- {\doifnextoptionalelse\setupvspacing_yes\setupvspacing_nop}
+ {\doifnextoptionalcselse\setupvspacing_yes\setupvspacing_nop}
\let\currentvspacing\s!default % hm, default, standard ...
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index ae09bb5ae..ae1fb5fec 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 8f1f3e5c8..ba896a1f9 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/strc-blk.lua b/tex/context/base/strc-blk.lua
index 935b6c061..ce3304d59 100644
--- a/tex/context/base/strc-blk.lua
+++ b/tex/context/base/strc-blk.lua
@@ -78,7 +78,7 @@ end
function blocks.select(state,name,tag,criterium)
criterium = criterium or "text"
- if find(tag,"=") then tag = "" end
+ if find(tag,"=",1,true) then tag = "" end
local names = settings_to_set(name)
local all = tag == ""
local tags = not all and settings_to_set(tag)
diff --git a/tex/context/base/strc-con.mkvi b/tex/context/base/strc-con.mkvi
index 75519b8ce..1862b00a6 100644
--- a/tex/context/base/strc-con.mkvi
+++ b/tex/context/base/strc-con.mkvi
@@ -980,10 +980,11 @@
}
}\relax
% \writestatus{constructions}{registering \currentconstruction: \number\scratchcounter}%
+ \ctxcommand{setinternalreference("\referenceprefix","\currentconstructionreference",\nextinternalreference,"\interactionparameter\c!focus")}%
\normalexpanded{%
\endgroup
\edef\noexpand\currentconstructionlistentry {\the\scratchcounter}%
- \edef\noexpand\currentconstructionattribute {\ctxcommand {setinternalreference("\referenceprefix","\currentconstructionreference",\nextinternalreference,"\interactionparameter\c!focus")}}%
+ \edef\noexpand\currentconstructionattribute {\the\lastdestinationattribute}%
\edef\noexpand\currentconstructionsynchronize{\ctxlatecommand{enhancelist(\the\scratchcounter)}}%
}%
\fi}
@@ -993,7 +994,7 @@
% macros.
\def\reinstateconstructionnumberentry#1% was xdef
- {\edef\currentconstructionattribute {\ctxcommand {getinternalreference(#1)}}%
+ {\edef\currentconstructionattribute {\ctxcommand {getinternallistreference(#1)}}%
\edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}}
\installstructurelistprocessor{construction}{\usestructurelistprocessor{number+title}}
diff --git a/tex/context/base/strc-des.mkvi b/tex/context/base/strc-des.mkvi
index 9c4d3fc6d..fa20d3cae 100644
--- a/tex/context/base/strc-des.mkvi
+++ b/tex/context/base/strc-des.mkvi
@@ -102,7 +102,7 @@
\unexpanded\def\strc_descriptions_start#1%
{\begingroup
\strc_constructions_initialize{#1}%
- \doifnextoptionalelse\strc_descriptions_start_yes\strc_descriptions_start_nop}
+ \doifnextoptionalcselse\strc_descriptions_start_yes\strc_descriptions_start_nop}
\unexpanded\def\strc_descriptions_start_yes[#1]%
{\doifassignmentelse{#1}\strc_descriptions_start_yes_assignment\strc_descriptions_start_yes_reference[#1]}
@@ -162,7 +162,7 @@
\unexpanded\def\strc_descriptions_command#1%
{\begingroup
\strc_constructions_initialize{#1}%
- \doifnextoptionalelse\strc_descriptions_yes\strc_descriptions_nop}
+ \doifnextoptionalcselse\strc_descriptions_yes\strc_descriptions_nop}
\unexpanded\def\strc_descriptions_yes
{\ifconditional\c_strc_constructions_title_state
diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua
index e3cbb02ed..38830a4e7 100644
--- a/tex/context/base/strc-doc.lua
+++ b/tex/context/base/strc-doc.lua
@@ -61,6 +61,10 @@ local strippedprocessor = processors.stripped
local a_internal = attributes.private('internal')
+local ctx_convertnumber = context.convertnumber
+local ctx_sprint = context.sprint
+local ctx_finalizeauto = context.finalizeautostructurelevel
+
-- -- -- document -- -- --
local data -- the current state
@@ -239,7 +243,7 @@ end
local saveset = { } -- experiment, see sections/tricky-001.tex
-function sections.somelevel(given)
+function sections.setentry(given)
-- old number
local numbers = data.numbers
@@ -456,7 +460,7 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp
local data = data.status[depth]
local d
if data then
- if find(key,"%.") then
+ if find(key,".",1,true) then
d = accesstable(key,data)
else
d = data.titledata
@@ -468,7 +472,7 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp
local metadata = data.metadata
local catcodes = metadata and metadata.catcodes
if catcodes then
- context.sprint(catcodes,d)
+ ctx_sprint(catcodes,d)
else
context(d)
end
@@ -477,7 +481,7 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp
else
local catcodes = catcodenumbers[honorcatcodetable]
if catcodes then
- context.sprint(catcodes,d)
+ ctx_sprint(catcodes,d)
else
context(d)
end
@@ -512,14 +516,20 @@ function sections.current()
return data.status[data.depth]
end
-function sections.depthnumber(n)
+local function depthnumber(n)
local depth = data.depth
if not n or n == 0 then
n = depth
elseif n < 0 then
n = depth + n
end
- return context(data.numbers[n] or 0)
+ return data.numbers[n] or 0
+end
+
+sections.depthnumber = depthnumber
+
+function commands.depthnumber(n)
+ return context(depthnumber(n))
end
function sections.autodepth(numbers)
@@ -580,11 +590,11 @@ local function process(index,numbers,ownnumbers,criterium,separatorset,conversio
if ownnumber ~= "" then
applyprocessor(ownnumber)
elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups)
- context.convertnumber(conversion,number)
+ ctx_convertnumber(conversion,number)
else
local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
local data = startapplyprocessor(theconversion)
- context.convertnumber(data or "numbers",number)
+ ctx_convertnumber(data or "numbers",number)
stopapplyprocessor()
end
end
@@ -926,7 +936,7 @@ function commands.autonextstructurelevel(level)
else
for i=level,#levels do
if levels[i] then
- context.finalizeautostructurelevel()
+ ctx_finalizeauto()
levels[i] = false
end
end
@@ -937,7 +947,7 @@ end
function commands.autofinishstructurelevels()
for i=1,#levels do
if levels[i] then
- context.finalizeautostructurelevel()
+ ctx_finalizeauto()
end
end
levels = { }
@@ -945,8 +955,8 @@ end
-- interface (some are actually already commands, like sections.fullnumber)
-commands.structurenumber = function() sections.fullnumber() end
-commands.structuretitle = function() sections.title () end
+commands.structurenumber = sections.fullnumber
+commands.structuretitle = sections.title
commands.structurevariable = function(name) sections.structuredata(nil,name) end
commands.structureuservariable = function(name) sections.userdata (nil,name) end
@@ -954,15 +964,23 @@ commands.structurecatcodedget = function(name) sections.structured
commands.structuregivencatcodedget = function(name,catcode) sections.structuredata(nil,name,nil,catcode) end
commands.structureautocatcodedget = function(name,catcode) sections.structuredata(nil,name,nil,catcode) end
-commands.namedstructurevariable = function(depth,name) sections.structuredata(depth,name) end
-commands.namedstructureuservariable = function(depth,name) sections.userdata (depth,name) end
+commands.namedstructurevariable = sections.structuredata
+commands.namedstructureuservariable = sections.userdata
---
+commands.setsectionlevel = sections.setlevel
+commands.setsectionnumber = sections.setnumber
+commands.getsectionnumber = sections.getnumber
+commands.getfullsectionnumber = sections.fullnumber
+commands.getstructuredata = sections.structuredata
+commands.getcurrentsectionlevel = sections.getcurrentlevel
-commands.setsectionblock = sections.setblock
-commands.pushsectionblock = sections.pushblock
-commands.popsectionblock = sections.popblock
+commands.setsectionblock = sections.setblock
+commands.pushsectionblock = sections.pushblock
+commands.popsectionblock = sections.popblock
+commands.registersection = sections.register
+commands.setsectionentry = sections.setentry
+commands.reportstructure = sections.reportstructure
--
local byway = "^" .. v_by -- ugly but downward compatible
diff --git a/tex/context/base/strc-doc.mkiv b/tex/context/base/strc-doc.mkiv
index c8dfae1e4..98abfd611 100644
--- a/tex/context/base/strc-doc.mkiv
+++ b/tex/context/base/strc-doc.mkiv
@@ -20,7 +20,8 @@
%D This will move:
\unexpanded\def\setstructuresynchronization#1% todo: use ctxcontext
- {\xdef\currentstructureattribute {\ctxlua {tex.write(structures.references.setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference,"\interactionparameter\c!focus"))}}%
+ {\ctxcommand{setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference,"\interactionparameter\c!focus")}%
+ \xdef\currentstructureattribute {\the\lastdestinationattribute}%
\xdef\currentstructuresynchronize{\ctxlatecommand{enhancelist(#1)}}}
\protect \endinput
diff --git a/tex/context/base/strc-enu.mkvi b/tex/context/base/strc-enu.mkvi
index e369bc2e1..0a01d2637 100644
--- a/tex/context/base/strc-enu.mkvi
+++ b/tex/context/base/strc-enu.mkvi
@@ -370,6 +370,6 @@
\fi}
\unexpanded\def\strc_enumerations_skip_number_coupling[#tag]% e.g. for questions with no answer
- {\ctxlua{structures.references.setnextorder("construction","#tag")}}
+ {\ctxcommand{setnextreferenceorder("construction","#tag")}}
\protect \endinput
diff --git a/tex/context/base/strc-ini.lua b/tex/context/base/strc-ini.lua
index 09ed79288..a48679e6f 100644
--- a/tex/context/base/strc-ini.lua
+++ b/tex/context/base/strc-ini.lua
@@ -38,14 +38,19 @@ local txtcatcodes = catcodenumbers.txtcatcodes
local context = context
local commands = commands
-local pushcatcodes = context.pushcatcodes
-local popcatcodes = context.popcatcodes
-
local trace_processors = false
local report_processors = logs.reporter("processors","structure")
trackers.register("typesetters.processors", function(v) trace_processors = v end)
+local xmlconvert = lxml.convert
+local xmlstore = lxml.store
+
+local ctx_pushcatcodes = context.pushcatcodes
+local ctx_popcatcodes = context.popcatcodes
+local ctx_xmlsetup = context.xmlsetup
+local ctx_xmlprocessbuffer = context.xmlprocessbuffer
+
-- -- -- namespace -- -- --
-- This is tricky: we have stored and initialized already some of
@@ -151,11 +156,17 @@ local function simplify(d,nodefault)
for k, v in next, d do
local tv = type(v)
if tv == "table" then
- if next(v) then t[k] = simplify(v) end
+ if next(v) then
+ t[k] = simplify(v)
+ end
elseif tv == "string" then
- if v ~= "" and v ~= "default" then t[k] = v end
+ if v ~= "" and v ~= "default" then
+ t[k] = v
+ end
elseif tv == "boolean" then
- if v then t[k] = v end
+ if v then
+ t[k] = v
+ end
else
t[k] = v
end
@@ -168,6 +179,34 @@ local function simplify(d,nodefault)
end
end
+-- we only care about the tuc file so this would do too:
+--
+-- local function simplify(d,nodefault)
+-- if d then
+-- for k, v in next, d do
+-- local tv = type(v)
+-- if tv == "string" then
+-- if v == "" or v == "default" then
+-- d[k] = nil
+-- end
+-- elseif tv == "table" then
+-- if next(v) then
+-- simplify(v)
+-- end
+-- elseif tv == "boolean" then
+-- if not v then
+-- d[k] = nil
+-- end
+-- end
+-- end
+-- return d
+-- elseif nodefault then
+-- return nil
+-- else
+-- return { }
+-- end
+-- end
+
helpers.simplify = simplify
function helpers.merged(...)
@@ -211,19 +250,19 @@ function helpers.title(title,metadata) -- coding is xml is rather old and not th
report_processors("putting xml data in buffer: %s",xmldata)
report_processors("processing buffer with setup %a and tag %a",xmlsetup,tag)
end
- if experiment then
- -- the question is: will this be forgotten ... better store in a via file
- local xmltable = lxml.convert("temp",xmldata or "")
- lxml.store("temp",xmltable)
- context.xmlsetup("temp",xmlsetup or "")
- else
- context.xmlprocessbuffer("dummy",tag,xmlsetup or "")
- end
+ if experiment then
+ -- the question is: will this be forgotten ... better store in a via file
+ local xmltable = xmlconvert("temp",xmldata or "")
+ xmlstore("temp",xmltable)
+ ctx_xmlsetup("temp",xmlsetup or "")
+ else
+ ctx_xmlprocessbuffer("dummy",tag,xmlsetup or "")
+ end
elseif xmlsetup then -- title is reference to node (so \xmlraw should have been used)
if trace_processors then
report_processors("feeding xmlsetup %a using node %a",xmlsetup,title)
end
- context.xmlsetup(title,metadata.xmlsetup)
+ ctx_xmlsetup(title,metadata.xmlsetup)
else
local catcodes = metadata.catcodes
if catcodes == notcatcodes or catcodes == xmlcatcodes then
@@ -241,9 +280,9 @@ function helpers.title(title,metadata) -- coding is xml is rather old and not th
-- doesn't work when a newline is in there \section{Test\ A} so we do
-- it this way:
--
- pushcatcodes(catcodes)
+ ctx_pushcatcodes(catcodes)
context(title)
- popcatcodes()
+ ctx_popcatcodes()
end
end
else
diff --git a/tex/context/base/strc-itm.mkvi b/tex/context/base/strc-itm.mkvi
index 8259fa38d..9e11f2047 100644
--- a/tex/context/base/strc-itm.mkvi
+++ b/tex/context/base/strc-itm.mkvi
@@ -331,7 +331,7 @@
\def\strc_itemgroups_store_continue_state#options#settings%
{\setxvalue{\??itemgroupoption \currentitemgroup}{\strc_itemgroups_process_options{#options}}%
- \setgvalue{\??itemgroupsetting\currentitemgroup}{\setupcurrentitemgroup [#settings]}}
+ \setgvalue{\??itemgroupsetting\currentitemgroup}{\setupcurrentitemgroup[#settings]}}
\def\strc_itemgroups_fetch_continue_state
{\getvalue{\??itemgroupoption \currentitemgroup}%
diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua
index d86368b6a..6ad491be2 100644
--- a/tex/context/base/strc-lst.lua
+++ b/tex/context/base/strc-lst.lua
@@ -16,7 +16,7 @@ if not modules then modules = { } end modules ['strc-lst'] = {
-- move more to commands
local format, gmatch, gsub = string.format, string.gmatch, string.gsub
-local tonumber = tonumber
+local tonumber, type = tonumber, type
local concat, insert, remove = table.concat, table.insert, table.remove
local lpegmatch = lpeg.match
local simple_hash_to_string, settings_to_hash = utilities.parsers.simple_hash_to_string, utilities.parsers.settings_to_hash
@@ -49,7 +49,7 @@ lists.collected = collected
lists.tobesaved = tobesaved
lists.enhancers = lists.enhancers or { }
-lists.internals = allocate(lists.internals or { }) -- to be checked
+-----.internals = allocate(lists.internals or { }) -- to be checked
lists.ordered = allocate(lists.ordered or { }) -- to be checked
lists.cached = cached
lists.pushed = pushed
@@ -88,6 +88,7 @@ local function initializer()
local collected = lists.collected
local internals = checked(references.internals)
local ordered = lists.ordered
+ local usedinternals = references.usedinternals
local blockdone = { }
for i=1,#collected do
local c = collected[i]
@@ -99,6 +100,7 @@ local function initializer()
local internal = r.internal
if internal then
internals[internal] = c
+ usedinternals[internal] = r.used
end
local block = r.block
if block and not blockdone[block] then
@@ -128,7 +130,17 @@ local function initializer()
end
end
-job.register('structures.lists.collected', tobesaved, initializer)
+local function finalizer()
+ local flaginternals = references.flaginternals
+ for i=1,#tobesaved do
+ local r = tobesaved[i].references
+ if r and flaginternals[r.internal] then
+ r.used = true
+ end
+ end
+end
+
+job.register('structures.lists.collected', tobesaved, initializer, finalizer)
local groupindices = table.setmetatableindex("table")
diff --git a/tex/context/base/strc-lst.mkvi b/tex/context/base/strc-lst.mkvi
index f78881221..0008f0602 100644
--- a/tex/context/base/strc-lst.mkvi
+++ b/tex/context/base/strc-lst.mkvi
@@ -147,8 +147,8 @@
\ifx\p_location\v!here
% this branch injects nodes !
\expanded{\ctxlatecommand{enhancelist(\currentlistnumber)}}%
- \ctxlua{structures.references.setinternalreference(nil,nil,\nextinternalreference)}% will change
- \xdef\currentstructurelistattribute{\number\lastdestinationattribute}%
+ \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% will change
+ \xdef\currentstructurelistattribute{\the\lastdestinationattribute}%
\dontleavehmode\hbox attr \destinationattribute \lastdestinationattribute{}% todo
\else
% and this one doesn't
@@ -1050,7 +1050,7 @@
\listparameter\c!numbercommand\currentlistsymbol
\listparameter\c!right
\endgroup
- \kern.5em
+ \kern.5\emwidth\relax
\nobreak
\fi
\fi
@@ -1069,7 +1069,7 @@
\ifconditional\c_lists_has_page
\ifconditional\c_lists_show_page
\nobreak
- \hskip.75em\relax
+ \hskip.75\emwidth\relax
\nobreak
\strc_lists_set_reference_attribute\v!pagenumber
\strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
diff --git a/tex/context/base/strc-mar.lua b/tex/context/base/strc-mar.lua
index 258787d0a..9c6259de4 100644
--- a/tex/context/base/strc-mar.lua
+++ b/tex/context/base/strc-mar.lua
@@ -712,6 +712,9 @@ end
-- interface
+commands.markingtitle = marks.title
+commands.markingnumber = marks.number
+
commands.definemarking = marks.define
commands.relatemarking = marks.relate
commands.setmarking = marks.set
diff --git a/tex/context/base/strc-not.mkvi b/tex/context/base/strc-not.mkvi
index a1aecf83a..b15285f8c 100644
--- a/tex/context/base/strc-not.mkvi
+++ b/tex/context/base/strc-not.mkvi
@@ -231,7 +231,7 @@
\ifnotesenabled
\strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
\fi
- \doifnextoptionalelse\strc_notations_command_yes\strc_notations_command_nop}
+ \doifnextoptionalcselse\strc_notations_command_yes\strc_notations_command_nop}
\unexpanded\def\strc_notations_command_nop#title%
{\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=][]%
@@ -265,7 +265,7 @@
% \normalexpanded % not that efficient but also not that frequently used (\normaldef for parser)
% {\normaldef\noexpand\strc_pickup_yes[##1]##2\csname\e!stop#stoptag\endcsname{\strc_notations_command_yes[##1]{##2}}%
% \normaldef\noexpand\strc_pickup_nop ##1\csname\e!stop#stoptag\endcsname{\strc_notations_command_nop {##1}}}%
-% \doifnextoptionalelse\strc_pickup_yes\strc_pickup_nop}
+% \doifnextoptionalcselse\strc_pickup_yes\strc_pickup_nop}
\unexpanded\def\strc_notations_start#tag#stoptag%
{\begingroup
@@ -278,7 +278,7 @@
\normalexpanded % not that efficient but also not that frequently used (\normaldef for parser)
{\def\noexpand\strc_pickup_yes[#one]#two\csname\e!stop#stoptag\endcsname{\strc_notations_command_yes[#one]{#two}}%
\def\noexpand\strc_pickup_nop #one\csname\e!stop#stoptag\endcsname{\strc_notations_command_nop {#one}}}%
- \doifnextoptionalelse\strc_pickup_yes\strc_pickup_nop}
+ \doifnextoptionalcselse\strc_pickup_yes\strc_pickup_nop}
\unexpanded\def\strc_notations_start_yes[#reference]#title%
{\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=][]%
@@ -460,7 +460,11 @@
\else\ifconditional\inlocalnotes % todo: per note class
\global\settrue\postponednote
\else
+\ifconditional\c_strc_notes_delayed
+ % probably end notes
+\else
\handlenoteinsert\currentnote\currentnotenumber % either an insert or just delayed
+\fi
\fi\fi
\endgroup
\fi
@@ -1242,6 +1246,7 @@
\appendtoks
\doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment
\penalty\currentnotepenalty
+ %\interlinepenalty\maxdimen % todo
\forgetall
\strc_notes_set_bodyfont
\redoconvertfont % to undo \undo calls in in headings etc
diff --git a/tex/context/base/strc-num.lua b/tex/context/base/strc-num.lua
index 67e9b1734..e1fc60030 100644
--- a/tex/context/base/strc-num.lua
+++ b/tex/context/base/strc-num.lua
@@ -404,7 +404,7 @@ function counters.restart(name,n,newstart,noreset)
if newstart then
local d = allocate(name,n)
d.start = newstart
- if not noreset then
+ if not noreset then -- why / when needed ?
reset(name,n) -- hm
end
end
@@ -589,8 +589,13 @@ function commands.doifnotcounter (name) commands.doifnot (counterdata[name]) end
function commands.incrementedcounter(...) context(counters.add(...)) end
+-- the noreset is somewhat messy ... always false messes up e.g. itemize but true the pagenumbers
+--
+-- if this fails i'll clean up this still somewhat experimental mechanism (but i need use cases)
+
function commands.checkcountersetup(name,level,start,state)
- counters.restart(name,1,start,true) -- no reset
+ local noreset = true -- level > 0 -- was true
+ counters.restart(name,1,start,noreset) -- was true
counters.setstate(name,state)
counters.setlevel(name,level)
sections.setchecker(name,level,counters.reset)
diff --git a/tex/context/base/strc-num.mkiv b/tex/context/base/strc-num.mkiv
index 2fa8b0e9a..b0e36ffba 100644
--- a/tex/context/base/strc-num.mkiv
+++ b/tex/context/base/strc-num.mkiv
@@ -17,6 +17,8 @@
\unprotect
+\startcontextdefinitioncode
+
% work in progress
% to be checked: can we use the command handler code here?
% all settings will move to lua
@@ -63,6 +65,11 @@
\appendtoks
\ifx\currentcounter\empty \else
+ \edef\p_number{\counterparameter\c!number}%
+ \ifx\p_number\empty \else
+ \ctxcommand{setcounter("\counterparameter\s!name",1,\number\p_number)}%
+ \letcounterparameter\c!number\empty
+ \fi
\edef\p_start{\counterparameter\c!start}%
\setexpandedcounterparameter\c!start{\ifx\p_start\empty0\else\number\p_start\fi}%
\strc_counters_check_setup
@@ -351,7 +358,7 @@
{\begingroup
\edef\currentcounter{#1}%
\ifsecondargument\setupcurrentcounter[#2]\fi
- \ctxlua{structures.sections.prefixedconverted(
+ \ctxcommand{prefixedconverted(
"\counterparameter\s!name",
{
prefix = "\counterparameter\c!prefix",
@@ -379,7 +386,7 @@
\endgroup}
\def\directconvertedcounter#1#2% name, type
- {\ctxlua{structures.sections.prefixedconverted(
+ {\ctxcommand{prefixedconverted(
"\namedcounterparameter{#1}\s!name",
{
prefix = "\namedcounterparameter{#1}\c!prefix",
@@ -609,7 +616,8 @@
userdata = \!!bs\detokenize{#9}\!!es % will be converted to table at the lua end
}
}}%
- \xdef\m_strc_counters_last_registered_attribute {\ctxcommand {setinternalreference(nil,nil,\nextinternalreference)}}%
+ \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}%
+ \xdef\m_strc_counters_last_registered_attribute {\the\lastdestinationattribute}%
\xdef\m_strc_counters_last_registered_synchronize{\ctxlatecommand{enhancelist(\m_strc_counters_last_registered_index)}}%
\else
\glet\m_strc_counters_last_registered_index \relax
@@ -764,4 +772,6 @@
% \fi
% \to \everysetupcounter
+\stopcontextdefinitioncode
+
\protect \endinput
diff --git a/tex/context/base/strc-pag.lua b/tex/context/base/strc-pag.lua
index fd0a367aa..c294a4645 100644
--- a/tex/context/base/strc-pag.lua
+++ b/tex/context/base/strc-pag.lua
@@ -34,6 +34,8 @@ local stopapplyprocessor = processors.stopapply
local texsetcount = tex.setcount
local texgetcount = tex.getcount
+local ctx_convertnumber = context.convertnumber
+
-- storage
local collected, tobesaved = allocate(), allocate()
@@ -101,11 +103,11 @@ function counters.specials.userpage()
end
end
-local f_convert = string.formatters["\\convertnumber{%s}{%s}"]
-
-local function convertnumber(str,n)
- return f_convert(str or "numbers",n)
-end
+-- local f_convert = string.formatters["\\convertnumber{%s}{%s}"]
+--
+-- local function convertnumber(str,n)
+-- return f_convert(str or "numbers",n)
+-- end
function pages.number(realdata,pagespec)
local userpage, block = realdata.number, realdata.block or "" -- sections.currentblock()
@@ -118,12 +120,12 @@ function pages.number(realdata,pagespec)
applyprocessor(starter)
end
if conversion ~= "" then
- context.convertnumber(conversion,userpage)
+ ctx_convertnumber(conversion,userpage)
else
if conversionset == "" then conversionset = "default" end
local theconversion = sets.get("structure:conversions",block,conversionset,1,"numbers") -- to be checked: 1
local data = startapplyprocessor(theconversion)
- context.convertnumber(data or "number",userpage)
+ ctx_convertnumber(data or "number",userpage)
stopapplyprocessor()
end
if stopper ~= "" then
@@ -318,3 +320,8 @@ function sections.prefixedconverted(name,prefixspec,numberspec)
counters.converted(name,numberspec)
end
end
+
+--
+
+commands.savepagedata = pages.save
+commands.prefixedconverted = sections.prefixedconverted -- weird place
diff --git a/tex/context/base/strc-pag.mkiv b/tex/context/base/strc-pag.mkiv
index c4e9819ba..6eddc0fba 100644
--- a/tex/context/base/strc-pag.mkiv
+++ b/tex/context/base/strc-pag.mkiv
@@ -17,6 +17,8 @@
\unprotect
+\startcontextdefinitioncode
+
% Allocation:
\countdef\realpageno \zerocount \realpageno \plusone
@@ -109,7 +111,7 @@
% invisible =
\def\strc_pagenumbers_page_state_save % \normalexpanded?
- {\ctxlua{structures.pages.save({
+ {\ctxcommand{savepagedata({
prefix = "\namedcounterparameter\s!userpage\c!prefix",
separatorset = "\namedcounterparameter\s!userpage\c!prefixseparatorset",
conversion = "\namedcounterparameter\s!userpage\c!prefixconversion",
@@ -462,4 +464,6 @@
\initializepagecounters
+\stopcontextdefinitioncode
+
\protect \endinput
diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua
index 938af1ad7..9cf8382be 100644
--- a/tex/context/base/strc-ref.lua
+++ b/tex/context/base/strc-ref.lua
@@ -91,6 +91,8 @@ local tobesaved = allocate()
local collected = allocate()
local tobereferred = allocate()
local referred = allocate()
+local usedinternals = allocate()
+local flaginternals = allocate()
references.derived = derived
references.specials = specials
@@ -103,6 +105,8 @@ references.tobesaved = tobesaved
references.collected = collected
references.tobereferred = tobereferred
references.referred = referred
+references.usedinternals = usedinternals
+references.flaginternals = flaginternals
local splitreference = references.splitreference
local splitprefix = references.splitcomponent -- replaces: references.splitprefix
@@ -119,6 +123,7 @@ local finalizers = { }
function references.registerinitializer(func) -- we could use a token register instead
initializers[#initializers+1] = func
end
+
function references.registerfinalizer(func) -- we could use a token register instead
finalizers[#finalizers+1] = func
end
@@ -246,15 +251,20 @@ local function setnextorder(kind,name)
texsetcount("global","locationorder",lastorder)
end
-references.setnextorder = setnextorder
-function references.setnextinternal(kind,name)
+local function setnextinternal(kind,name)
setnextorder(kind,name) -- always incremented with internal
local n = texgetcount("locationcount") + 1
texsetcount("global","locationcount",n)
return n
end
+references.setnextorder = setnextorder
+references.setnextinternal = setnextinternal
+
+commands.setnextreferenceorder = setnextorder
+commands.setnextinternalreference = setnextinternal
+
function references.currentorder(kind,name)
return orders[kind] and orders[kind][name] or lastorder
end
@@ -272,8 +282,6 @@ local function setcomponent(data)
-- but for the moment we do it here (experiment)
end
-commands.setnextinternalreference = references.setnextinternal
-
function commands.currentreferenceorder(kind,name)
context(references.currentorder(kind,name))
end
@@ -448,9 +456,9 @@ function references.urls.define(name,url,file,description)
end
end
-local pushcatcodes = context.pushcatcodes
-local popcatcodes = context.popcatcodes
-local txtcatcodes = catcodes.numbers.txtcatcodes -- or just use "txtcatcodes"
+local ctx_pushcatcodes = context.pushcatcodes
+local ctx_popcatcodes = context.popcatcodes
+local txtcatcodes = catcodes.numbers.txtcatcodes -- or just use "txtcatcodes"
function references.urls.get(name)
local u = urls[name]
@@ -467,9 +475,9 @@ end
function commands.geturl(name)
local url = references.urls.get(name)
if url and url ~= "" then
- pushcatcodes(txtcatcodes)
+ ctx_pushcatcodes(txtcatcodes)
context(url)
- popcatcodes()
+ ctx_popcatcodes()
end
end
@@ -685,8 +693,8 @@ local function resolve(prefix,reference,args,set) -- we start with prefix,refere
if not set then
set = { prefix = prefix, reference = reference }
else
- set.reference = set.reference or reference
- set.prefix = set.prefix or prefix
+ if not set.reference then set.reference = reference end
+ if not set.prefix then set.prefix = prefix end
end
local r = settings_to_array(reference)
for i=1,#r do
@@ -760,8 +768,8 @@ function commands.setreferencearguments(k,v)
references.currentset[k].arguments = v
end
-local expandreferenceoperation = context.expandreferenceoperation
-local expandreferencearguments = context.expandreferencearguments
+local ctx_expandreferenceoperation = context.expandreferenceoperation
+local ctx_expandreferencearguments = context.expandreferencearguments
function references.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex
local currentset = references.currentset
@@ -769,12 +777,12 @@ function references.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex
for i=1,#currentset do
local ci = currentset[i]
local operation = ci.operation
- if operation and find(operation,"\\") then -- if o_has_tex then
- expandreferenceoperation(i,operation)
+ if operation and find(operation,"\\",1,true) then -- if o_has_tex then
+ ctx_expandreferenceoperation(i,operation)
end
local arguments = ci.arguments
- if arguments and find(arguments,"\\") then -- if a_has_tex then
- expandreferencearguments(i,arguments)
+ if arguments and find(arguments,"\\",1,true) then -- if a_has_tex then
+ ctx_expandreferencearguments(i,arguments)
end
end
end
@@ -1194,7 +1202,7 @@ local function identify_arguments(set,var,i)
local s = specials[var.inner]
if s then
-- inner{argument}
- var.kind = "special with arguments"
+ var.kind = "special operation with arguments"
else
var.error = "unknown inner or special"
end
@@ -1685,23 +1693,30 @@ end
luatex.registerstopactions(references.reportproblems)
-local innermethod = "names"
+-- The auto method will try to avoid named internals in a clever way which
+-- can make files smaller without sacrificing external references. Some of
+-- the housekeeping happens the backend side.
+
+local innermethod = "auto" -- was "names"
+local defaultinnermethod = defaultinnermethod
+references.innermethod = innermethod -- don't mess with this one directly
function references.setinnermethod(m)
if m then
- if m == "page" or m == "mixed" or m == "names" then
+ if m == "page" or m == "mixed" or m == "names" or m == "auto" then
innermethod = m
elseif m == true or m == v_yes then
innermethod = "page"
end
end
+ references.innermethod = innermethod
function references.setinnermethod()
report_references("inner method is already set and frozen to %a",innermethod)
end
end
function references.getinnermethod()
- return innermethod or "names"
+ return innermethod or defaultinnermethod
end
directives.register("references.linkmethod", function(v) -- page mixed names
@@ -1710,28 +1725,21 @@ end)
-- this is inconsistent
-function references.setinternalreference(prefix,tag,internal,view) -- needs checking
- if innermethod == "page" then
- return unsetvalue
- else
+local destinationattributes = { }
+
+local function setinternalreference(prefix,tag,internal,view) -- needs checking
+ local destination = unsetvalue
+ if innermethod ~= "page" then
local t, tn = { }, 0 -- maybe add to current
if tag then
if prefix and prefix ~= "" then
prefix = prefix .. ":" -- watch out, : here
- -- for ref in gmatch(tag,"[^,]+") do
- -- tn = tn + 1
- -- t[tn] = prefix .. ref
- -- end
local function action(ref)
tn = tn + 1
t[tn] = prefix .. ref
end
process_settings(tag,action)
else
- -- for ref in gmatch(tag,"[^,]+") do
- -- tn = tn + 1
- -- t[tn] = ref
- -- end
local function action(ref)
tn = tn + 1
t[tn] = ref
@@ -1739,36 +1747,48 @@ function references.setinternalreference(prefix,tag,internal,view) -- needs chec
process_settings(tag,action)
end
end
- if internal and innermethod == "names" then -- mixed or page
+ -- ugly .. later we decide to ignore it when we have a real one
+ -- but for testing we might want to see them all
+ if internal and (innermethod == "names" or innermethod == "auto") then -- mixed or page
tn = tn + 1
- t[tn] = "aut:" .. internal
+ t[tn] = internal -- when number it's internal
end
- local destination = references.mark(t,nil,nil,view) -- returns an attribute
- texsetcount("lastdestinationattribute",destination)
- return destination
+ destination = references.mark(t,nil,nil,view) -- returns an attribute
end
+ if internal then -- new
+ destinationattributes[internal] = destination
+ end
+ texsetcount("lastdestinationattribute",destination)
+ return destination
+end
+
+local function getinternalreference(internal)
+ return destinationattributes[internal] or 0
end
+references.setinternalreference = setinternalreference
+references.getinternalreference = getinternalreference
+commands.setinternalreference = setinternalreference
+commands.getinternalreference = getinternalreference
+
function references.setandgetattribute(kind,prefix,tag,data,view) -- maybe do internal automatically here
- local attr = references.set(kind,prefix,tag,data) and references.setinternalreference(prefix,tag,nil,view) or unsetvalue
+ local attr = references.set(kind,prefix,tag,data) and setinternalreference(prefix,tag,nil,view) or unsetvalue
texsetcount("lastdestinationattribute",attr)
return attr
end
commands.setreferenceattribute = references.setandgetattribute
-function references.getinternalreference(n) -- n points into list (todo: registers)
+function references.getinternallistreference(n) -- n points into list (todo: registers)
local l = lists.collected[n]
- return l and l.references.internal or n
-end
-
-function commands.setinternalreference(prefix,tag,internal,view) -- needs checking
- context(references.setinternalreference(prefix,tag,internal,view))
+ local i = l and l.references.internal
+ return i and destinationattributes[i] or 0
end
-function commands.getinternalreference(n) -- this will also be a texcount
+function commands.getinternallistreference(n) -- this will also be a texcount
local l = lists.collected[n]
- context(l and l.references.internal or n)
+ local i = l and l.references.internal
+ context(i and destinationattributes[i] or 0)
end
--
@@ -2164,7 +2184,7 @@ runners["special operation with arguments"] = runners["special"]
-- check the validity.
function specials.internal(var,actions)
- local v = references.internals[tonumber(var.operation)]
+ local v = internals[tonumber(var.operation)]
local r = v and v.references.realpage
if r then
actions.realpage = r
diff --git a/tex/context/base/strc-ref.mkvi b/tex/context/base/strc-ref.mkvi
index 85c6a0729..4696c61da 100644
--- a/tex/context/base/strc-ref.mkvi
+++ b/tex/context/base/strc-ref.mkvi
@@ -947,11 +947,12 @@
\begingroup
\let\crlf\space
\let\\\space
- \postponenotes
+ \postponenotes % might go
\referencingparameter\c!left
\doifreferencefoundelse{#label}
{\goto{\limitatetext\currentreferencetitle{\referencingparameter\c!width}\unknown}[#label]}% not so efficient (dup lookup)
{}% todo
+ \flushnotes % might go
\referencingparameter\c!right
\endgroup}
diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua
index b0d8a8a25..bdb2e0d67 100644
--- a/tex/context/base/strc-reg.lua
+++ b/tex/context/base/strc-reg.lua
@@ -13,50 +13,95 @@ local utfchar = utf.char
local lpegmatch = lpeg.match
local allocate = utilities.storage.allocate
-local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end)
+local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end)
-local report_registers = logs.reporter("structure","registers")
+local report_registers = logs.reporter("structure","registers")
-local structures = structures
-local registers = structures.registers
-local helpers = structures.helpers
-local sections = structures.sections
-local documents = structures.documents
-local pages = structures.pages
-local references = structures.references
+local structures = structures
+local registers = structures.registers
+local helpers = structures.helpers
+local sections = structures.sections
+local documents = structures.documents
+local pages = structures.pages
+local references = structures.references
-local mappings = sorters.mappings
-local entries = sorters.entries
-local replacements = sorters.replacements
+local usedinternals = references.usedinternals
-local processors = typesetters.processors
-local splitprocessor = processors.split
+local mappings = sorters.mappings
+local entries = sorters.entries
+local replacements = sorters.replacements
-local texgetcount = tex.getcount
+local processors = typesetters.processors
+local splitprocessor = processors.split
-local variables = interfaces.variables
-local context = context
-local commands = commands
+local texgetcount = tex.getcount
-local matchingtilldepth = sections.matchingtilldepth
-local numberatdepth = sections.numberatdepth
+local variables = interfaces.variables
+local v_forward = variables.forward
+local v_all = variables.all
+local v_yes = variables.yes
+local v_current = variables.current
+local v_previous = variables.previous
+local v_text = variables.text
-local absmaxlevel = 5 -- \c_strc_registers_maxlevel
+local context = context
+local commands = commands
+
+local matchingtilldepth = sections.matchingtilldepth
+local numberatdepth = sections.numberatdepth
+local currentlevel = sections.currentlevel
+local currentid = sections.currentid
+
+local touserdata = helpers.touserdata
+
+local internalreferences = references.internals
+local setinternalreference = references.setinternalreference
+
+local setmetatableindex = table.setmetatableindex
+local texsetattribute = tex.setattribute
+
+local a_destination = attributes.private('destination')
+
+local absmaxlevel = 5 -- \c_strc_registers_maxlevel
+
+local ctx_startregisteroutput = context.startregisteroutput
+local ctx_stopregisteroutput = context.stopregisteroutput
+local ctx_startregistersection = context.startregistersection
+local ctx_stopregistersection = context.stopregistersection
+local ctx_startregisterentries = context.startregisterentries
+local ctx_stopregisterentries = context.stopregisterentries
+local ctx_startregisterentry = context.startregisterentry
+local ctx_stopregisterentry = context.stopregisterentry
+local ctx_startregisterpages = context.startregisterpages
+local ctx_stopregisterpages = context.stopregisterpages
+local ctx_stopregisterseewords = context.stopregisterseewords
+local ctx_startregisterseewords = context.startregisterseewords
+local ctx_registerentry = context.registerentry
+local ctx_registerseeword = context.registerseeword
+local ctx_registerpagerange = context.registerpagerange
+local ctx_registeronepage = context.registeronepage
-- some day we will share registers and lists (although there are some conceptual
-- differences in the application of keywords)
local function filtercollected(names,criterium,number,collected,prevmode)
- if not criterium or criterium == "" then criterium = variables.all end
- local data = documents.data
- local numbers, depth = data.numbers, data.depth
- local hash, result, nofresult, all, detail = { }, { }, 0, not names or names == "" or names == variables.all, nil
+ if not criterium or criterium == "" then
+ criterium = v_all
+ end
+ local data = documents.data
+ local numbers = data.numbers
+ local depth = data.depth
+ local hash = { }
+ local result = { }
+ local nofresult = 0
+ local all = not names or names == "" or names == v_all
+ local detail = nil
if not all then
for s in gmatch(names,"[^, ]+") do
hash[s] = true
end
end
- if criterium == variables.all or criterium == variables.text then
+ if criterium == v_all or criterium == v_text then
for i=1,#collected do
local v = collected[i]
if all then
@@ -70,10 +115,11 @@ local function filtercollected(names,criterium,number,collected,prevmode)
end
end
end
- elseif criterium == variables.current then
+ elseif criterium == v_current then
+ local collectedsections = sections.collected
for i=1,#collected do
local v = collected[i]
- local sectionnumber = sections.collected[v.references.section]
+ local sectionnumber = collectedsections[v.references.section]
if sectionnumber then
local cnumbers = sectionnumber.numbers
if prevmode then
@@ -108,10 +154,11 @@ local function filtercollected(names,criterium,number,collected,prevmode)
end
end
end
- elseif criterium == variables.previous then
+ elseif criterium == v_previous then
+ local collectedsections = sections.collected
for i=1,#collected do
local v = collected[i]
- local sectionnumber = sections.collected[v.references.section]
+ local sectionnumber = collectedsections[v.references.section]
if sectionnumber then
local cnumbers = sectionnumber.numbers
if (all or hash[v.metadata.name]) and #cnumbers >= depth then
@@ -141,9 +188,9 @@ local function filtercollected(names,criterium,number,collected,prevmode)
end
elseif criterium == variables["local"] then
if sections.autodepth(data.numbers) == 0 then
- return filtercollected(names,variables.all,number,collected,prevmode)
+ return filtercollected(names,v_all,number,collected,prevmode)
else
- return filtercollected(names,variables.current,number,collected,prevmode)
+ return filtercollected(names,v_current,number,collected,prevmode)
end
else -- sectionname, number
-- beware, this works ok for registers
@@ -193,44 +240,77 @@ registers.filtercollected = filtercollected
-- result table; we might do that here as well but since sorting code is
-- older we delay that decision
+-- maybe store the specification in the format (although we predefine only
+-- saved registers)
+
+local function checker(t,k)
+ local v = {
+ metadata = {
+ language = 'en',
+ sorted = false,
+ class = class,
+ },
+ entries = { },
+ }
+ t[k] = v
+ return v
+end
+
local function initializer()
tobesaved = registers.tobesaved
collected = registers.collected
- local internals = references.internals
+ setmetatableindex(tobesaved,checker)
+ setmetatableindex(collected,checker)
+ local usedinternals = references.usedinternals
for name, list in next, collected do
local entries = list.entries
- for e=1,#entries do
- local entry = entries[e]
- local r = entry.references
- if r then
- local internal = r and r.internal
- if internal then
- internals[internal] = entry
+ if not list.metadata.notsaved then
+ for e=1,#entries do
+ local entry = entries[e]
+ local r = entry.references
+ if r then
+ local internal = r and r.internal
+ if internal then
+ internalreferences[internal] = entry
+ usedinternals[internal] = r.used
+ end
+ end
+ end
+ end
+ end
+end
+
+local function finalizer()
+ local flaginternals = references.flaginternals
+ for k, v in next, tobesaved do
+ local entries = v.entries
+ if entries then
+ for i=1,#entries do
+ local r = entries[i].references
+ if r and flaginternals[r.internal] then
+ r.used = true
end
end
end
end
end
-job.register('structures.registers.collected', tobesaved, initializer)
+job.register('structures.registers.collected', tobesaved, initializer, finalizer)
+
+setmetatableindex(tobesaved,checker)
+setmetatableindex(collected,checker)
-local function allocate(class)
+local function defineregister(class,method)
local d = tobesaved[class]
- if not d then
- d = {
- metadata = {
- language = 'en',
- sorted = false,
- class = class
- },
- entries = { },
- }
- tobesaved[class] = d
- end
- return d
+ if method == v_forward then
+ d.metadata.notsaved = true
+ end
end
-registers.define = allocate
+registers.define = defineregister -- 4 times is somewhat over the top but we want consistency
+registers.setmethod = defineregister -- and we might have a difference some day
+commands.defineregister = defineregister
+commands.setregistermethod = defineregister
local entrysplitter = lpeg.tsplitat('+') -- & obsolete in mkiv
@@ -239,7 +319,6 @@ local tagged = { }
local function preprocessentries(rawdata)
local entries = rawdata.entries
if entries then
---~ table.print(rawdata)
local e, k = entries[1] or "", entries[2] or ""
local et, kt, entryproc, pageproc
if type(e) == "table" then
@@ -255,14 +334,15 @@ local function preprocessentries(rawdata)
kt = lpegmatch(entrysplitter,k)
end
entries = { }
- for k=1,#et do
- entries[k] = { et[k] or "", kt[k] or "" }
- end
+ local ok = false
for k=#et,1,-1 do
- if entries[k][1] ~= "" then
- break
- else
+ local etk = et[k]
+ local ktk = kt[k]
+ if not ok and etk == "" then
entries[k] = nil
+ else
+ entries[k] = { etk or "", ktk ~= "" and ktk or nil }
+ ok = true
end
end
rawdata.list = entries
@@ -277,44 +357,94 @@ local function preprocessentries(rawdata)
end
end
-function registers.store(rawdata) -- metadata, references, entries
- local data = allocate(rawdata.metadata.name).entries
+local function storeregister(rawdata) -- metadata, references, entries
local references = rawdata.references
- references.realpage = references.realpage or 0 -- just to be sure as it can be refered to
+ local metadata = rawdata.metadata
+ -- checking
+ if not metadata.kind then
+ metadata.kind = "entry"
+ end
+ --
+ if not metadata.catcodes then
+ metadata.catcodes = tex.catcodetable -- get
+ end
+ --
+ local name = metadata.name
+ local notsaved = tobesaved[name].metadata.notsaved
+ --
+ local internal = references.internal
+ if not internal then
+ internal = texgetcount("locationcount") -- we assume that it has been set
+ references.internal = internal
+ end
+ --
+ if notsaved then
+ usedinternals[internal] = true -- todo view (we assume that forward references index entries are used)
+ end
+ --
+ if not references.realpage then
+ references.realpage = 0 -- just to be sure as it can be refered to
+ end
+ --
+ local userdata = rawdata.userdata
+ if userdata then
+ rawdata.userdata = touserdata(userdata)
+ end
+ --
+ references.section = currentid()
+ metadata.level = currentlevel()
+ --
+ local data = notsaved and collected[name] or tobesaved[name]
+ local entries = data.entries
+ internalreferences[internal] = rawdata
preprocessentries(rawdata)
- data[#data+1] = rawdata
+ entries[#entries+1] = rawdata
local label = references.label
- if label and label ~= "" then tagged[label] = #data end
- context(#data)
+ if label and label ~= "" then
+ tagged[label] = #entries
+ else
+ references.label = nil
+ end
+ return #entries
end
-function registers.enhance(name,n)
- local r = tobesaved[name].entries[n]
- if r then
- r.references.realpage = texgetcount("realpageno")
+local function enhanceregister(name,n)
+ local data = tobesaved[name].metadata.notsaved and collected[name] or tobesaved[name]
+ local entry = data.entries[n]
+ if entry then
+ entry.references.realpage = texgetcount("realpageno")
end
end
-function registers.extend(name,tag,rawdata) -- maybe do lastsection internally
+local function extendregister(name,tag,rawdata) -- maybe do lastsection internally
if type(tag) == "string" then
tag = tagged[tag]
end
if tag then
- local r = tobesaved[name].entries[tag]
- if r then
- local rr = r.references
- rr.lastrealpage = texgetcount("realpageno")
- rr.lastsection = sections.currentid()
+ local data = tobesaved[name].metadata.notsaved and collected[name] or tobesaved[name]
+ local entry = data.entries[tag]
+ if entry then
+ local references = entry.references
+ references.lastrealpage = texgetcount("realpageno")
+ references.lastsection = currentid()
if rawdata then
+ local userdata = rawdata.userdata
+ if userdata then
+ rawdata.userdata = touserdata(userdata)
+ end
if rawdata.entries then
preprocessentries(rawdata)
end
- for k,v in next, rawdata do
- if not r[k] then
- r[k] = v
+ local metadata = rawdata.metadata
+ if metadata and not metadata.catcodes then
+ metadata.catcodes = tex.catcodetable -- get
+ end
+ for k, v in next, rawdata do
+ local rk = references[k]
+ if not rk then
+ references[k] = v
else
- local rk = r[k]
- for kk,vv in next, v do
+ for kk, vv in next, v do
if type(vv) == "table" then
if next(vv) then
rk[kk] = vv
@@ -330,6 +460,19 @@ function registers.extend(name,tag,rawdata) -- maybe do lastsection internally
end
end
+registers.store = storeregister
+registers.enhance = enhanceregister
+registers.extend = extendregister
+
+function commands.storeregister(rawdata)
+ local nofentries = storeregister(rawdata)
+ setinternalreference(nil,nil,rawdata.references.internal)
+ context(nofentries)
+end
+
+commands.enhanceregister = enhanceregister
+commands.extendregister = extendregister
+
-- sorting and rendering
local compare = sorters.comparers.basic
@@ -339,7 +482,8 @@ function registers.compare(a,b)
if result ~= 0 then
return result
else
- local ka, kb = a.metadata.kind, b.metadata.kind
+ local ka = a.metadata.kind
+ local kb = b.metadata.kind
if ka == kb then
local page_a, page_b = a.references.realpage, b.references.realpage
if not page_a or not page_b then
@@ -453,17 +597,19 @@ end
function registers.prepare(data)
-- data has 'list' table
- local strip = sorters.strip
+ local strip = sorters.strip
local splitter = sorters.splitters.utf
- local result = data.result
+ local result = data.result
if result then
for i=1, #result do
- local entry, split = result[i], { }
- local list = entry.list
+ local entry = result[i]
+ local split = { }
+ local list = entry.list
if list then
for l=1,#list do
- local ll = list[l]
- local word, key = ll[1], ll[2]
+ local ll = list[l]
+ local word = ll[1]
+ local key = ll[2]
if not key or key == "" then
key = word
end
@@ -478,7 +624,11 @@ function registers.prepare(data)
end
function registers.sort(data,options)
- sorters.sort(data.result,registers.compare)
+ -- if options.pagenumber == false then
+ -- sorters.sort(data.result,compare)
+ -- else
+ sorters.sort(data.result,registers.compare)
+ -- end
end
function registers.unique(data,options)
@@ -487,7 +637,8 @@ function registers.unique(data,options)
for k=1,#dataresult do
local v = dataresult[k]
if prev then
- local pr, vr = prev.references, v.references
+ local vr = v.references
+ local pr = prev.references
if not equal(prev.list,v.list) then
-- ok
elseif pr.realpage ~= vr.realpage then
@@ -530,10 +681,11 @@ function registers.finalize(data,options) -- maps character to index (order)
if trace_registers then
report_registers("splitting at %a",tag)
end
- done, nofdone = { }, 0
+ done = { }
+ nofdone = 0
nofsplit = nofsplit + 1
+ lasttag = tag
split[nofsplit] = { tag = tag, data = done }
- lasttag = tag
end
nofdone = nofdone + 1
done[nofdone] = v
@@ -541,7 +693,7 @@ function registers.finalize(data,options) -- maps character to index (order)
data.result = split
end
-function registers.analyzed(class,options)
+local function analyzeregister(class,options)
local data = collected[class]
if data and data.entries then
options = options or { }
@@ -558,10 +710,22 @@ function registers.analyzed(class,options)
end
end
+registers.analyze = analyzeregister
+
+function registers.analyze(class,options)
+ context(analyzeregister(class,options))
+end
+
+
-- todo take conversion from index
function registers.userdata(index,name)
local data = references.internals[tonumber(index)]
+ return data and data.userdata and data.userdata[name] or nil
+end
+
+function commands.registeruserdata(index,name)
+ local data = references.internals[tonumber(index)]
data = data and data.userdata and data.userdata[name]
if data then
context(data)
@@ -570,22 +734,26 @@ end
-- todo: ownnumber
+local h_prefixpage = helpers.prefixpage
+local h_prefixlastpage = helpers.prefixlastpage
+local h_title = helpers.title
+
local function pagerange(f_entry,t_entry,is_last,prefixspec,pagespec)
local fer, ter = f_entry.references, t_entry.references
- context.registerpagerange(
+ ctx_registerpagerange(
f_entry.processors and f_entry.processors[2] or "",
fer.internal or 0,
fer.realpage or 0,
function()
- helpers.prefixpage(f_entry,prefixspec,pagespec)
+ h_prefixpage(f_entry,prefixspec,pagespec)
end,
ter.internal or 0,
ter.lastrealpage or ter.realpage or 0,
function()
if is_last then
- helpers.prefixlastpage(t_entry,prefixspec,pagespec) -- swaps page and realpage keys
+ h_prefixlastpage(t_entry,prefixspec,pagespec) -- swaps page and realpage keys
else
- helpers.prefixpage (t_entry,prefixspec,pagespec)
+ h_prefixpage (t_entry,prefixspec,pagespec)
end
end
)
@@ -593,11 +761,11 @@ end
local function pagenumber(entry,prefixspec,pagespec)
local er = entry.references
- context.registeronepage(
+ ctx_registeronepage(
entry.processors and entry.processors[2] or "",
er.internal or 0,
er.realpage or 0,
- function() helpers.prefixpage(entry,prefixspec,pagespec) end
+ function() h_prefixpage(entry,prefixspec,pagespec) end
)
end
@@ -665,8 +833,9 @@ local function collapsepages(pages)
end
function registers.flush(data,options,prefixspec,pagespec)
- local collapse_singles = options.compress == variables.yes
- local collapse_ranges = options.compress == variables.all
+ local collapse_singles = options.compress == v_yes
+ local collapse_ranges = options.compress == v_all
+ local show_page_number = options.pagenumber ~= false -- true or false
local result = data.result
local maxlevel = 0
--
@@ -684,18 +853,19 @@ function registers.flush(data,options,prefixspec,pagespec)
report_registers("limiting level to %a",maxlevel)
end
--
- context.startregisteroutput()
-local done = { }
+ ctx_startregisteroutput()
+ local done = { }
+ local started = false
for i=1,#result do
-- ranges need checking !
local sublist = result[i]
-- local done = { false, false, false, false }
-for i=1,maxlevel do
- done[i] = false
-end
+ for i=1,maxlevel do
+ done[i] = false
+ end
local data = sublist.data
local d, n = 0, 0
- context.startregistersection(sublist.tag)
+ ctx_startregistersection(sublist.tag)
for d=1,#data do
local entry = data[d]
if entry.metadata.kind == "see" then
@@ -714,9 +884,9 @@ end
d = d + 1
local entry = data[d]
local e = { false, false, false }
-for i=3,maxlevel do
- e[i] = false
-end
+ for i=3,maxlevel do
+ e[i] = false
+ end
local metadata = entry.metadata
local kind = metadata.kind
local list = entry.list
@@ -727,125 +897,135 @@ end
if e[i] ~= done[i] then
if e[i] and e[i] ~= "" then
done[i] = e[i]
-for j=i+1,maxlevel do
- done[j] = false
-end
+ for j=i+1,maxlevel do
+ done[j] = false
+ end
+ if started then
+ ctx_stopregisterentry()
+ started = false
+ end
if n == i then
- context.stopregisterentries()
- context.startregisterentries(n)
+-- ctx_stopregisterentries()
+-- ctx_startregisterentries(n)
else
while n > i do
n = n - 1
- context.stopregisterentries()
+ ctx_stopregisterentries()
end
while n < i do
n = n + 1
- context.startregisterentries(n)
+ ctx_startregisterentries(n)
end
end
- local internal = entry.references.internal or 0
- local seeparent = entry.references.seeparent or ""
- local processor = entry.processors and entry.processors[1] or ""
+ local references = entry.references
+ local processors = entry.processors
+ local internal = references.internal or 0
+ local seeparent = references.seeparent or ""
+ local processor = processors and processors[1] or ""
-- so, we need to keep e as is (local), or we need local title = e[i] ... which might be
-- more of a problem
+ ctx_startregisterentry(0) -- will become a counter
+ started = true
if metadata then
- context.registerentry(processor,internal,seeparent,function() helpers.title(e[i],metadata) end)
+ ctx_registerentry(processor,internal,seeparent,function() h_title(e[i],metadata) end)
else -- ?
- context.registerentry(processor,internal,seeindex,e[i])
+ ctx_registerentry(processor,internal,seeindex,e[i])
end
else
done[i] = false
-for j=i+1,maxlevel do
- done[j] = false
-end
+ for j=i+1,maxlevel do
+ done[j] = false
+ end
end
end
end
if kind == 'entry' then
- context.startregisterpages()
- if collapse_singles or collapse_ranges then
- -- we collapse ranges and keep existing ranges as they are
- -- so we get prebuilt as well as built ranges
- local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0
- while dd < #data do
- dd = dd + 1
- local next = data[dd]
- if next and next.metadata.kind == "see" then
- dd = dd - 1
- break
- else
- local el, nl = entry.list, next.list
- if not equal(el,nl) then
+ if show_page_number then
+ ctx_startregisterpages()
+ if collapse_singles or collapse_ranges then
+ -- we collapse ranges and keep existing ranges as they are
+ -- so we get prebuilt as well as built ranges
+ local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0
+ while dd < #data do
+ dd = dd + 1
+ local next = data[dd]
+ if next and next.metadata.kind == "see" then
dd = dd - 1
- --~ first = nil
break
- elseif next.references.lastrealpage then
- nofpages = nofpages + 1
- pages[nofpages] = first and { first, last or first } or { entry, entry }
- nofpages = nofpages + 1
- pages[nofpages] = { next, next }
- first, last, prev = nil, nil, nil
- elseif not first then
- first, prev = next, next
- elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ?
- last, prev = next, next
else
- nofpages = nofpages + 1
- pages[nofpages] = { first, last or first }
- first, last, prev = next, nil, next
+ local el, nl = entry.list, next.list
+ if not equal(el,nl) then
+ dd = dd - 1
+ --~ first = nil
+ break
+ elseif next.references.lastrealpage then
+ nofpages = nofpages + 1
+ pages[nofpages] = first and { first, last or first } or { entry, entry }
+ nofpages = nofpages + 1
+ pages[nofpages] = { next, next }
+ first, last, prev = nil, nil, nil
+ elseif not first then
+ first, prev = next, next
+ elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ?
+ last, prev = next, next
+ else
+ nofpages = nofpages + 1
+ pages[nofpages] = { first, last or first }
+ first, last, prev = next, nil, next
+ end
end
end
- end
- if first then
- nofpages = nofpages + 1
- pages[nofpages] = { first, last or first }
- end
- if collapse_ranges and nofpages > 1 then
- nofpages = collapsepages(pages)
- end
- if nofpages > 0 then -- or 0
- d = dd
- for p=1,nofpages do
- local first, last = pages[p][1], pages[p][2]
- if first == last then
- if first.references.lastrealpage then
- pagerange(first,first,true,prefixspec,pagespec)
+ if first then
+ nofpages = nofpages + 1
+ pages[nofpages] = { first, last or first }
+ end
+ if collapse_ranges and nofpages > 1 then
+ nofpages = collapsepages(pages)
+ end
+ if nofpages > 0 then -- or 0
+ d = dd
+ for p=1,nofpages do
+ local first, last = pages[p][1], pages[p][2]
+ if first == last then
+ if first.references.lastrealpage then
+ pagerange(first,first,true,prefixspec,pagespec)
+ else
+ pagenumber(first,prefixspec,pagespec)
+ end
+ elseif last.references.lastrealpage then
+ pagerange(first,last,true,prefixspec,pagespec)
else
- pagenumber(first,prefixspec,pagespec)
+ pagerange(first,last,false,prefixspec,pagespec)
end
- elseif last.references.lastrealpage then
- pagerange(first,last,true,prefixspec,pagespec)
- else
- pagerange(first,last,false,prefixspec,pagespec)
end
- end
- elseif entry.references.lastrealpage then
- pagerange(entry,entry,true,prefixspec,pagespec)
- else
- pagenumber(entry,prefixspec,pagespec)
- end
- else
- while true do
- if entry.references.lastrealpage then
+ elseif entry.references.lastrealpage then
pagerange(entry,entry,true,prefixspec,pagespec)
else
pagenumber(entry,prefixspec,pagespec)
end
- if d == #data then
- break
- else
- d = d + 1
- local next = data[d]
- if next.metadata.kind == "see" or not equal(entry.list,next.list) then
- d = d - 1
+ else
+ while true do
+ if entry.references.lastrealpage then
+ pagerange(entry,entry,true,prefixspec,pagespec)
+ else
+ pagenumber(entry,prefixspec,pagespec)
+ end
+ if d == #data then
break
else
- entry = next
+ d = d + 1
+ local next = data[d]
+ if next.metadata.kind == "see" or not equal(entry.list,next.list) then
+ d = d - 1
+ break
+ else
+ entry = next
+ end
end
end
end
+ ctx_stopregisterpages()
end
- context.stopregisterpages()
elseif kind == 'see' then
local t, nt = { }, 0
while true do
@@ -864,38 +1044,46 @@ end
end
end
end
- context.startregisterseewords()
+ ctx_startregisterseewords()
for i=1,nt do
local entry = t[i]
local seeword = entry.seeword
local seetext = seeword.text or ""
local processor = seeword.processor or (entry.processors and entry.processors[1]) or ""
local seeindex = entry.references.seeindex or ""
- context.registerseeword(i,n,processor,0,seeindex,seetext)
+ ctx_registerseeword(i,n,processor,0,seeindex,seetext)
end
- context.stopregisterseewords()
+ ctx_stopregisterseewords()
end
end
+ if started then
+ ctx_stopregisterentry()
+ started = false
+ end
while n > 0 do
- context.stopregisterentries()
+ ctx_stopregisterentries()
n = n - 1
end
- context.stopregistersection()
+ ctx_stopregistersection()
end
- context.stopregisteroutput()
+ ctx_stopregisteroutput()
-- for now, maybe at some point we will do a multipass or so
data.result = nil
data.metadata.sorted = false
+ -- temp hack for luajittex :
+ local entries = data.entries
+ for i=1,#entries do
+ entries[i].split = nil
+ end
+ -- collectgarbage("collect")
end
-
-function registers.analyze(class,options)
- context(registers.analyzed(class,options))
-end
-
-function registers.process(class,...)
- if registers.analyzed(class,...) > 0 then
- registers.flush(collected[class],...)
+local function processregister(class,...)
+ if analyzeregister(class,...) > 0 then
+ local data = collected[class]
+ registers.flush(data,...)
end
end
+registers.process = processregister
+commands.processregister = processregister
diff --git a/tex/context/base/strc-reg.mkiv b/tex/context/base/strc-reg.mkiv
index 2d28114c3..d072aca69 100644
--- a/tex/context/base/strc-reg.mkiv
+++ b/tex/context/base/strc-reg.mkiv
@@ -17,6 +17,8 @@
\unprotect
+\startcontextdefinitioncode
+
% todo: tag:: becomes rendering
% todo: language, character, linked, location
% todo: fonts etc at sublevels (already defined)
@@ -106,6 +108,14 @@
\c!entries=,
\c!alternative=]
+
+\definemixedcolumns
+ [\v!register]
+ [\c!n=\registerparameter\c!n,
+ \c!balance=\registerparameter\c!balance,
+ \c!align=\registerparameter\c!align,
+ \c!tolerance=\registerparameter\c!tolerance]
+
%D \starttyping
%D \setupregister[index][1][textcolor=darkred]
%D \setupregister[index][2][textcolor=darkgreen,textstyle=bold]
@@ -123,7 +133,8 @@
\appendtoks
\ifconditional\c_strc_registers_defining \else % todo: dosingle ...
\settrue\c_strc_registers_defining
- \ctxlua{structures.registers.define('\currentregister')}%
+ \definemixedcolumns[\currentregister][\v!register]% first as otherwise it overloads start/stop
+ \ctxcommand{defineregister("\currentregister","\registerparameter\c!referencemethod")}%
\normalexpanded{\presetheadtext[\currentregister=\Word{\currentregister}]}%
\setuevalue{\currentregister}{\dodoubleempty\strc_registers_insert_entry[\currentregister]}%
\setuevalue{\e!see\currentregister}{\dodoubleempty\strc_registers_insert_see[\currentregister]}%
@@ -143,6 +154,10 @@
\fi
\to \everydefineregister
+\appendtoks
+ \ctxcommand{setregistermethod("\currentregister","\registerparameter\c!referencemethod")}%
+\to \everysetupregister
+
%D Registering:
\def\strc_registers_register_page_entry
@@ -152,6 +167,52 @@
\expandafter\strc_registers_register_page_entry_indeed
\fi}
+\def\strc_registers_register_page_expand_xml_entries
+ {\xmlstartraw
+ \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
+ \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
+ \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
+ \xmlstopraw
+ \globallet\currentregistercoding\s!xml}
+
+\def\strc_registers_register_page_expand_yes_entries
+ {\xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
+ \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
+ \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
+ \globallet\currentregistercoding\s!tex}
+
+\def\strc_registers_register_page_expand_nop_entries
+ {\xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}%
+ \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}%
+ \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}%
+ \globallet\currentregistercoding\s!tex}
+
+\def\strc_registers_register_page_expand_xml
+ {\xmlstartraw
+ \xdef\currentregisterentries{\registerparameter\c!entries}%
+ \xmlstopraw
+ \globallet\currentregistercoding\s!xml}
+
+\def\strc_registers_register_page_expand_yes
+ {\xdef\currentregisterentries{\registerparameter\c!entries}%
+ \globallet\currentregistercoding\s!tex}
+
+\def\strc_registers_register_page_expand_nop
+ {\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
+ \globallet\currentregistercoding\s!tex}
+
+\def\strc_registers_register_page_expand_xml_keys
+ {\xmlstartraw
+ \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}%
+ \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}%
+ \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}%
+ \xmlstopraw}
+
+\def\strc_registers_register_page_expand_yes_keys
+ {\xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}%
+ \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}%
+ \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}}
+
\def\strc_registers_register_page_entry_indeed#1#2#3% register data userdata
{\begingroup
\edef\currentregister{#1}%
@@ -165,75 +226,54 @@
\xdef\currentregisterxmlsetup {\registerparameter\c!xmlsetup}%
\ifx\currentregisterentries\empty
\ifx\currentregisterexpansion\s!xml
- \xmlstartraw
- \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
- \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
- \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
- \xmlstopraw
- \globallet\currentregistercoding\s!xml
+ \strc_registers_register_page_expand_xml_entries
+ \else\ifx\currentregisterexpansion\v!yes
+ \strc_registers_register_page_expand_yes_entries
\else
- \ifx\currentregisterexpansion\v!yes
- \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}%
- \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}%
- \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}%
- \else
- \xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}%
- \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}%
- \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}%
- \fi
- \globallet\currentregistercoding\s!tex
- \fi
+ \strc_registers_register_page_expand_nop_entries
+ \fi\fi
\else
\ifx\currentregisterexpansion\s!xml
- \xmlstartraw
- \xdef\currentregisterentries{\registerparameter\c!entries}%
- \xmlstopraw
- \globallet\currentregistercoding\s!xml
+ \strc_registers_register_page_expand_xml
+ \else\ifx\currentregisterexpansion\v!yes
+ \strc_registers_register_page_expand_yes
\else
- \ifx\currentregisterexpansion\v!yes
- \xdef\currentregisterentries{\registerparameter\c!entries}%
- \else
- \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}%
- \fi
- \globallet\currentregistercoding\s!tex
- \fi
+ \strc_registers_register_page_expand_nop
+ \fi\fi
\fi
\ifx\currentregisterkeys\empty
\ifx\currentregistercoding\s!xml
- \xmlstartraw
- \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}%
- \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}%
- \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}%
- \xmlstopraw
+ \strc_registers_register_page_expand_xml_keys
\else
- \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}%
- \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}%
- \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}%
+ \strc_registers_register_page_expand_yes_keys
\fi
\fi
\setnextinternalreference
% we could consider storing register entries in a list which we
% could then sort
- \xdef\currentregisternumber{\ctxlua{
- structures.registers.store { % 'own' should not be in metadata
+ \xdef\currentregisternumber{\ctxcommand{storeregister{ % 'own' should not be in metadata
metadata = {
- kind = "entry",
+ % kind = "entry",
name = "\currentregister",
- level = structures.sections.currentlevel(),
+ % level = structures.sections.currentlevel(),
coding = "\currentregistercoding",
- catcodes = \the\catcodetable,
+ % catcodes = \the\catcodetable,
\ifx\currentregisterownnumber\v!yes
own = "\registerparameter\c!alternative", % can be used instead of pagenumber
\fi
- xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text
+ \ifx\currentreferencecoding\s!xml
+ xmlroot = "\xmldocument", % only useful when text
+ \fi
\ifx\currentregisterxmlsetup\empty \else
xmlsetup = "\currentregisterxmlsetup",
\fi
},
references = {
- internal = \nextinternalreference,
- section = structures.sections.currentid(), % hm, why then not also lastsection the same way
+ % internal = \nextinternalreference,
+ % section = structures.sections.currentid(), % hm, why then not also lastsection the same way
+ \ifx\currentregisterlabel\empty \else
label = "\currentregisterlabel",
+ \fi
},
% \ifx\currentregisterentries\empty \else
entries = {
@@ -253,11 +293,11 @@
userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es)
}
}}%
- \ctxlua{structures.references.setinternalreference(nil,nil,\nextinternalreference)}%
+ % \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% in previous
\ifx\currentregisterownnumber\v!yes
\glet\currentregistersynchronize\relax
\else
- \xdef\currentregistersynchronize{\ctxlatelua{structures.registers.enhance("\currentregister",\currentregisternumber)}}%
+ \xdef\currentregistersynchronize{\ctxlatecommand{enhanceregister("\currentregister",\currentregisternumber)}}%
\fi
\currentregistersynchronize % here?
% needs thinking ... bla\index{bla}. will break before the . but adding a
@@ -296,7 +336,7 @@
\fi}
\def\strc_registers_stop_entry[#1][#2]%
- {\normalexpanded{\ctxlatelua{structures.registers.extend("#1","#2")}}}
+ {\normalexpanded{\ctxlatecommand{extendregister("#1","#2")}}}
\def\setregisterentry {\dotripleempty\strc_registers_set_entry}
\def\finishregisterentry{\dotripleempty\strc_registers_finish_entry}
@@ -329,19 +369,19 @@
\fi
% I hate this kind of mess ... but it's a user request.
\ifx\currentregisterentries\empty
- \normalexpanded{\ctxlua{structures.registers.extend("\currentregister","\currentregisterlabel", {
+ \normalexpanded{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", {
metadata = {
\ifx\currentregisterownnumber\v!yes
own = "\registerparameter\c!alternative", % can be used instead of pagenumber
\fi
},
- userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es)
+ userdata = \!!bs\detokenize{#3}\!!es
})%
}}%
\else
- \normalexpanded{\ctxlua{structures.registers.extend("\currentregister","\currentregisterlabel", {
+ \normalexpanded{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", {
metadata = {
- catcodes = \the\catcodetable,
+ % catcodes = \the\catcodetable,
coding = "\currentregistercoding",
\ifx\currentregisterownnumber\v!yes
own = "\registerparameter\c!alternative", % can be used instead of pagenumber
@@ -352,7 +392,7 @@
\!!bs\currentregisterentries\!!es,
\!!bs\currentregisterkeys\!!es
},
- userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es)
+ userdata = \!!bs\detokenize{#3}\!!es
})
}}%
\fi
@@ -374,7 +414,7 @@
% \placeregister[index][n=1]
% \stoptext
-% some overlap wit previous
+% some overlap with previous
\unexpanded\def\setstructurepageregister
{\dotripleempty\strc_registers_set}
@@ -421,16 +461,16 @@
\fi
\setnextinternalreference
% we could consider storing register entries in list
- \edef\temp{\ctxlua{ structures.registers.store {
+ \edef\temp{\ctxcommand{storeregister{
metadata = {
kind = "see",
name = "\currentregister",
- level = structures.sections.currentlevel(),
- catcodes = \the\catcodetable,
+ % level = structures.sections.currentlevel(),
+ % catcodes = \the\catcodetable,
},
references = {
- internal = \nextinternalreference,
- section = structures.sections.currentid(),
+ % internal = \nextinternalreference,
+ % section = structures.sections.currentid(),
},
entries = {
% we need a special one for xml, this is just a single one
@@ -457,12 +497,13 @@
{\begingroup
\edef\currentregister{#1}%
\setupregister[\currentregister][#2]%
- \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxlua{structures.registers.analyze('\currentregister',{
+ \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxcommand{analyzeregister('\currentregister',{
language = "\registerparameter\s!language",
method = "\registerparameter\c!method",
numberorder = "\registerparameter\c!numberorder",
compress = "\registerparameter\c!compress",
criterium = "\registerparameter\c!criterium",
+ pagenumber = \ifx\registerpageseparatorsymbol\empty false\else true\fi,
})}}}% brrr
\ifcase\utilityregisterlength\relax
\resetsystemmode\v!register
@@ -479,6 +520,27 @@
\unexpanded\def\placeregister
{\dodoubleempty\strc_registers_place}
+% \def\strc_registers_place[#1][#2]%
+% {\iffirstargument
+% \begingroup
+% %\forgetall
+% \edef\currentregister{#1}%
+% \setupregister[\currentregister][#2]%
+% \the\everyplaceregister
+% \ifnum\registerparameter\c!n>\plusone
+% \startcolumns
+% [\c!n=\registerparameter\c!n,
+% \c!balance=\registerparameter\c!balance,
+% \c!align=\registerparameter\c!align,
+% \c!tolerance=\registerparameter\c!tolerance]%
+% \strc_registers_place_indeed
+% \stopcolumns
+% \else
+% \strc_registers_place_indeed
+% \fi
+% \endgroup
+% \fi}
+
\def\strc_registers_place[#1][#2]%
{\iffirstargument
\begingroup
@@ -486,43 +548,36 @@
\edef\currentregister{#1}%
\setupregister[\currentregister][#2]%
\the\everyplaceregister
- \ifnum\registerparameter\c!n>\plusone
- \startcolumns
- [\c!n=\registerparameter\c!n,
- \c!balance=\registerparameter\c!balance,
- \c!align=\registerparameter\c!align,
- \c!tolerance=\registerparameter\c!tolerance]%
- \strc_registers_place_indeed
- \stopcolumns
+ \ifnum\namedmixedcolumnsparameter\currentregister\c!n>\plusone
+ \startmixedcolumns[\currentregister]
+ \strc_registers_place_indeed
+ \stopmixedcolumns
\else
\strc_registers_place_indeed
\fi
\endgroup
\fi}
-\def\strc_registers_place_columns
- {\startcolumns
- [\c!n=\registerparameter\c!n,
- \c!balance=\registerparameter\c!balance,
- \c!align=\registerparameter\c!align,
- \c!tolerance=\registerparameter\c!tolerance]%
- \startpacked[\v!blank]%
- \strc_registers_place_indeed
- \stoppacked
- \stopcolumns}
-
-\def\strc_registers_place_normal
- {\startpacked[\v!blank]%
- \strc_registers_place_indeed
- \stoppacked}
+% \def\strc_registers_place_columns
+% {\startmixedcolumns[\currentregister]
+% \startpacked[\v!blank]%
+% \strc_registers_place_indeed
+% \stoppacked
+% \stopmixedcolumns}
+%
+% \def\strc_registers_place_normal
+% {\startpacked[\v!blank]%
+% \strc_registers_place_indeed
+% \stoppacked}
\def\strc_registers_place_indeed
- {\ctxlua{structures.registers.process('\currentregister',{
+ {\ctxcommand{processregister('\currentregister',{
language = "\registerparameter\s!language",
method = "\registerparameter\c!method",
numberorder = "\registerparameter\c!numberorder",
compress = "\registerparameter\c!compress",
criterium = "\registerparameter\c!criterium",
+ pagenumber = \ifx\registerpageseparatorsymbol\empty false\else true\fi,
},{
separatorset = "\registerparameter\c!pageprefixseparatorset",
conversionset = "\registerparameter\c!pageprefixconversionset",
@@ -685,6 +740,9 @@
% \hangafter\plusone
% \let\currentregister\savedcurrentregister}
+\newdimen\d_strc_registers_hangindent
+\newcount\c_strc_registers_hangafter
+
\unexpanded\def\startregisterentries#1% depth
{\endgraf
\begingroup
@@ -696,8 +754,9 @@
\ifnum\scratchcounter>\plusone
\advance\leftskip\d_strc_registers_distance\relax
\fi
- \hangindent\registerparameter\c!distance\relax
- \hangafter\plusone
+ \d_strc_registers_hangindent\registerparameter\c!distance\relax
+ \c_strc_registers_hangafter \plusone
+\blank[\v!samepage]%
\let\currentregister\savedcurrentregister}
\unexpanded\def\stopregisterentries
@@ -705,6 +764,15 @@
\dostoptagged
\endgroup}
+\unexpanded\def\startregisterentry#1% todo: level
+ {\begingroup
+ \hangindent\d_strc_registers_hangindent
+ \hangafter \c_strc_registers_hangafter}
+
+\unexpanded\def\stopregisterentry
+ {\endgraf
+ \endgroup}
+
\unexpanded\def\startregistersection#1% title
{\dostarttagged\t!registersection\empty
\dostarttagged\t!registertag\empty
@@ -745,7 +813,7 @@
\fi}
\unexpanded\def\registeronepagerangeseparator
- {|\endash|}
+ {|\endash|} % todo use \prewordbreak
\def\withregisterpagecommand#1#2#3#4%
{\def\currentregisterpageindex{#2}%
@@ -846,7 +914,7 @@
% \placeregister[index][n=1,pagecommand=\MyRegisterPageCommand]
% \stoptext
-\def\registerpageuserdata #1#2{\ctxlua{structures.registers.userdata(#1,"#2")}}
+\def\registerpageuserdata #1#2{\ctxcommand{registeruserdata(#1,"#2")}}
\def\currentregisterpageuserdata {\registerpageuserdata\currentregisterpageindex} % {#1}
% not yet ok : new internal handler names
@@ -857,10 +925,10 @@
\installcorenamespace{registersymbol}
\setvalue{\??registersymbol n}%
- {\def\registerpageseparatorsymbol{, }}
+ {\def\registerpageseparatorsymbol{,\space}}
\setvalue{\??registersymbol a}%
- {\def\registerpageseparatorsymbol{, }} % now done via conversion
+ {\def\registerpageseparatorsymbol{,\space}} % now done via conversion
\setvalue{\??registersymbol\v!none}%
{\let\registerpageseparatorsymbol\empty
@@ -904,4 +972,6 @@
[\v!index]
% [\v!indices]
+\stopcontextdefinitioncode
+
\protect \endinput
diff --git a/tex/context/base/strc-rsc.lua b/tex/context/base/strc-rsc.lua
index a90f577e3..e2105a4ef 100644
--- a/tex/context/base/strc-rsc.lua
+++ b/tex/context/base/strc-rsc.lua
@@ -67,11 +67,11 @@ local function splitreference(str)
local t = lpegmatch(referencesplitter,str)
if t then
local a = t.arguments
- if a and find(a,"\\") then
+ if a and find(a,"\\",1,true) then
t.has_tex = true
else
local o = t.arguments
- if o and find(o,"\\") then
+ if o and find(o,"\\",1,true) then
t.has_tex = true
end
end
diff --git a/tex/context/base/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv
index 2962e2c49..d55b80574 100644
--- a/tex/context/base/strc-sec.mkiv
+++ b/tex/context/base/strc-sec.mkiv
@@ -15,6 +15,8 @@
\unprotect
+\startcontextdefinitioncode
+
\installcorenamespace{structure}
\installdirectcommandhandler \??structure {structure} % unchecked, so we need to initialize used parameters
@@ -130,9 +132,9 @@
\xdef\currentstructuremarking {\structureparameter\c!marking}%
\xdef\currentstructurelist {\structureparameter\c!list}%
\xmlstopraw
-\iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll
- \strc_sectioning_autobookmark\currentstructuretitle
-\fi \fi \fi
+ \iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll
+ \strc_sectioning_autobookmark\currentstructuretitle
+ \fi \fi \fi
\ifx\currentstructurelist\empty
\globallet\currentstructurelist\currentstructuretitle
\fi
@@ -143,23 +145,23 @@
\xdef\currentstructurebookmark{\structureparameter\c!bookmark}%
\xdef\currentstructuremarking {\structureparameter\c!marking}%
\xdef\currentstructurelist {\structureparameter\c!list}%
-\iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll
- \strc_sectioning_autobookmark\currentstructuretitle
-\fi \fi \fi
+ \iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll
+ \strc_sectioning_autobookmark\currentstructuretitle
+ \fi \fi \fi
\else
\xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}%
\xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}%
\xdef\currentstructuremarking {\detokenizedstructureparameter\c!marking}%
\xdef\currentstructurelist {\detokenizedstructureparameter\c!list}%
\iflocation \ifx\currentstructurebookmark\empty
-\ifconditional\c_strc_bookmarks_preroll
- \strc_sectioning_autobookmark{\structureparameter\c!title}%
-\else
- \begingroup
- \simplifycommands
- \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}%
- \endgroup
-\fi
+ \ifconditional\c_strc_bookmarks_preroll
+ \strc_sectioning_autobookmark{\structureparameter\c!title}%
+ \else
+ \begingroup
+ \simplifycommands
+ \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}%
+ \endgroup
+ \fi
\fi \fi
\fi
\ifx\currentstructurelist\empty
@@ -170,8 +172,8 @@
\setnextinternalreference
\storeinternalreference\currentstructurename\nextinternalreference %
\strc_sectioning_set_reference_prefix
- \xdef\currentstructurenumber{\ctxlua{ % todo: combine with next call, adapt marks accordingly
- structures.sections.somelevel {
+ \ctxcommand{% todo: combine with next call, adapt marks accordingly
+ setsectionentry{
references = {
internal = \nextinternalreference,
block = "\currentsectionblock",
@@ -218,7 +220,9 @@
numberdata = {
% needed ?
block = "\currentsectionblock",
- hidenumber = \ifx\currentstructureshownumber\v!no true\else nil\fi, % titles
+ \ifx\currentstructureshownumber\v!no
+ hidenumber = true, % titles
+ \fi
% so far
separatorset = "\structureparameter\c!sectionseparatorset",
conversion = "\structureparameter\c!sectionconversion", % for good old times sake
@@ -231,14 +235,12 @@
},
userdata = \!!bs\detokenize{#3}\!!es % will be converted to table at the lua end
}
- }}%
- % \xdef\currentstructurelistnumber{\ctxcommand{addtolist(structures.sections.current())}}%
+ }%
\xdef\currentstructurelistnumber{\ctxcommand{currentsectiontolist()}}%
% \currentstructuresynchronize has to be called someplace, since it introduces a node
\setstructuresynchronization\currentstructurelistnumber
\endgroup}
-\let\currentstructurenumber \!!zerocount
\let\currentsectioncountervalue \!!zerocount % redefined later
\let\previoussectioncountervalue\!!zerocount % redefined later
@@ -300,14 +302,14 @@
\newconditional\c_strc_rendering_continuous % not used (mkii ?)
-\def\setstructurelevel #1#2{\ctxlua{structures.sections.setlevel("#1","#2")}} % name, level|parent
-\def\getstructurelevel #1{\ctxlua{structures.sections.getcurrentlevel("#1")}}% name
-\def\setstructurenumber #1#2{\ctxlua{structures.sections.setnumber(#1,"#2")}} % level, number (+/-)
-\def\getstructurenumber #1{\ctxlua{structures.sections.getnumber(#1)}} % level
-\def\getsomestructurenumber #1#2{\ctxlua{structures.sections.getnumber(#1,"#2")}} % level, what
-\def\getfullstructurenumber #1{\ctxlua{structures.sections.fullnumber(#1)}} % level
-\def\getsomefullstructurenumber#1#2{\ctxlua{structures.sections.fullnumber(#1,"#2")}}
-\def\getspecificstructuretitle #1{\ctxlua{structures.sections.structuredata("#1","titledata.title",nil,"\headparameter\s!catcodes")}}%
+\def\setstructurelevel #1#2{\ctxcommand{setsectionlevel("#1","#2")}} % name, level|parent
+\def\getstructurelevel #1{\ctxcommand{getcurrentsectionlevel("#1")}}% name
+\def\setstructurenumber #1#2{\ctxcommand{setsectionnumber(#1,"#2")}} % level, number (+/-)
+\def\getstructurenumber #1{\ctxcommand{getsectionnumber(#1)}} % level
+\def\getsomestructurenumber #1#2{\ctxcommand{getsectionnumber(#1,"#2")}} % level, what
+\def\getfullstructurenumber #1{\ctxcommand{getfullsectionnumber(#1)}} % level
+\def\getsomefullstructurenumber#1#2{\ctxcommand{getfullsectionnumber(#1,"#2")}}
+\def\getspecificstructuretitle #1{\ctxcommand{getstructuredata("#1","titledata.title",nil,"\headparameter\s!catcodes")}}%
% will be:
%
@@ -435,7 +437,7 @@
\edef\currentsectionheadcoupling{\sectionheadcoupling\currenthead}%
\edef\currentsectionheadsection {\sectionheadsection \currentsectionheadcoupling}%
\edef\currentsectionlevel {\sectionlevel \currentsectionheadsection}%
- \ctxlua{structures.sections.register("\currenthead",{
+ \ctxcommand{registersection("\currenthead",{
coupling = "\currentsectionheadcoupling",
section = "\currentsectionheadsection",
level = \currentsectionlevel,
@@ -578,8 +580,8 @@
% head -> head
-\def\sectionheadmarkingtitle #1#2{\ctxlua{structures.marks.title("#1","#2")}}
-\def\sectionheadmarkingnumber#1#2{\ctxlua{structures.marks.number("#1","#2")}}
+\def\sectionheadmarkingtitle #1#2{\ctxcommand{markingtitle("#1","#2")}}
+\def\sectionheadmarkingnumber#1#2{\ctxcommand{markingnumber("#1","#2")}}
\def\sectionheadcoupling#1{\namedheadparameter{#1}\c!coupling}
\def\sectionheadsection #1{\namedheadparameter{#1}\c!section}
@@ -763,7 +765,7 @@
\unexpanded\def\placeheadtext {\dosingleempty\strc_sectioning_place_head_text } % use with care
\unexpanded\def\placeheadnumber{\dosingleempty\strc_sectioning_place_head_number} % use with care
-\unexpanded\def\strc_sectioning_report{\ctxlua{structures.sections.reportstructure()}}
+\unexpanded\def\strc_sectioning_report{\ctxcommand{reportstructure()}}
\ifdefined\strc_rendering_initialize_style_and_color \else
@@ -1039,8 +1041,8 @@
#1%
\fi}
-\def\currentsectioncountervalue {\ctxlua{structures.sections.depthnumber(\thenamedheadlevel\currenthead)}}
-\def\previoussectioncountervalue{\ctxlua{structures.sections.depthnumber(\thenamedheadlevel\currenthead-1)}}
+\def\currentsectioncountervalue {\ctxcommand{depthnumber(\thenamedheadlevel\currenthead)}}
+\def\previoussectioncountervalue{\ctxcommand{depthnumber(\thenamedheadlevel\currenthead-1)}}
\def\strc_sectioning_handle_page_nop
{\edef\p_continue{\headparameter\c!continue}%
@@ -1119,7 +1121,7 @@
\let\sectioncountervalue\structurevalue
-\def\currentheadtext{obsolete, use marks}
+\def\currentheadtext{obsolete,\space use marks}
% list references, will be redone in lua when we need it
@@ -1154,4 +1156,6 @@
\finalizeautostructurelevels
\to \everystoptext
+\stopcontextdefinitioncode
+
\protect \endinput
diff --git a/tex/context/base/strc-syn.lua b/tex/context/base/strc-syn.lua
index ca4b3ac18..604365b2d 100644
--- a/tex/context/base/strc-syn.lua
+++ b/tex/context/base/strc-syn.lua
@@ -12,6 +12,9 @@ local allocate = utilities.storage.allocate
-- interface to tex end
+local context = context
+local sorters = sorters
+
local structures = structures
local synonyms = structures.synonyms
local tags = structures.tags
@@ -19,6 +22,10 @@ local tags = structures.tags
local collected = allocate()
local tobesaved = allocate()
+local firstofsplit = sorters.firstofsplit
+local strip = sorters.strip
+local splitter = sorters.splitters.utf
+
synonyms.collected = collected
synonyms.tobesaved = tobesaved
@@ -114,8 +121,6 @@ function synonyms.filter(data,options)
end
function synonyms.prepare(data)
- local strip = sorters.strip
- local splitter = sorters.splitters.utf
local result = data.result
if result then
for i=1, #result do
@@ -123,7 +128,7 @@ function synonyms.prepare(data)
local rd = r.definition
if rd then
local rt = rd.tag
- local sortkey = (rt and rt ~= "" and rt) or rd.synonym
+ local sortkey = rt and rt ~= "" and rt or rd.synonym
r.split = splitter(strip(sortkey))
end
end
@@ -140,13 +145,17 @@ function synonyms.finalize(data,options)
local split = { }
for k=1,#result do
local v = result[k]
- local entry, tag = sorters.firstofsplit(v)
+ local entry, tag = firstofsplit(v)
local s = split[entry] -- keeps track of change
+ local d
if not s then
- s = { tag = tag, data = { } }
+ d = { }
+ s = { tag = tag, data = d }
split[entry] = s
+ else
+ d = s.data
end
- s.data[#s.data+1] = v
+ d[#d+1] = v
end
data.result = split
end
@@ -154,24 +163,21 @@ end
-- for now, maybe at some point we will do a multipass or so
-- maybe pass the settings differently
+local ctx_synonymentry = context.synonymentry
+
function synonyms.flush(data,options)
local kind = data.metadata.kind -- hack, will be done better
- -- context[format("\\start%soutput",kind)]()
local result = data.result
local sorted = table.sortedkeys(result)
for k=1,#sorted do
local letter = sorted[k]
local sublist = result[letter]
local data = sublist.data
- -- context[format("\\start%ssection",kind)](sublist.tag)
for d=1,#data do
local entry = data[d].definition
- -- context[format("\\%sentry",kind)](d,entry.tag,entry.synonym,entry.meaning or "")
- context("\\%sentry{%s}{%s}{%s}{%s}",kind,d,entry.tag,entry.synonym,entry.meaning or "")
+ ctx_synonymentry(d,entry.tag,entry.synonym,entry.meaning or "")
end
- -- context[format("\\stop%ssection",kind)]()
end
- -- context[format("\\stop%soutput",kind)]()
data.result = nil
data.metadata.sorted = false
end
@@ -196,3 +202,8 @@ function synonyms.process(class,options)
end
end
+commands.registersynonym = synonyms.register
+commands.registerusedsynonym = synonyms.registerused
+commands.synonymmeaning = synonyms.meaning
+commands.synonymname = synonyms.synonym
+commands.processsynonyms = synonyms.process
diff --git a/tex/context/base/strc-syn.mkiv b/tex/context/base/strc-syn.mkiv
index e0087d450..73aca18e6 100644
--- a/tex/context/base/strc-syn.mkiv
+++ b/tex/context/base/strc-syn.mkiv
@@ -20,20 +20,6 @@
\unprotect
-\ifdefined\dotagsynonym \else \let\dotagsynonym\relax \fi
-\ifdefined\dotagsorting \else \let\dotagsorting\relax \fi
-
-% general help, can be shared
-
-% simplifiedcommands -> flag in lua
-%
-% expansion
-% criterium -> when start, then flag in list
-% command-> wanneer?
-% state -> flagging enabled
-% conversion ?
-% todo: register xml mode etc
-
% split but common in lua
\def\preprocessexpansion#1#2#3#4%
@@ -51,13 +37,93 @@
\globallet#3\s!tex
\fi}
-\installcorenamespace{synonym}
+%D We now use a simple list variant:
+
+\installcorenamespace {simplelist}
+
+\installcommandhandler \??simplelist {simplelist} \??simplelist
+
+\let\setupsimplelists\setupsimplelist
+
+\setupsimplelists[%
+ %c!title=,
+ %c!text=,
+ %
+ %c!style=,
+ %c!color=,
+ %c!command=,
+ %c!align=,
+ %
+ %c!headstyle=,
+ %c!headcolor=,
+ %c!headalign=,
+ %
+ %c!titlestyle=,
+ %c!titlecolor=,
+ %c!titlecommand=,
+ %c!titleleft=,
+ %c!titleright=,
+ %
+ %c!closesymbol=,
+ %c!closecommand=,
+ %
+ \c!alternative=\v!left,
+ \c!display=\v!yes,
+ \c!width=7\emwidth,
+ \c!distance=\emwidth,
+ \c!titledistance=.5\emwidth,
+ %c!hang=,
+ %c!sample=,
+ \c!margin=\v!no,
+ \c!before=\blank,
+ \c!inbetween=\blank,
+ \c!after=\blank,
+ %c!indentnext=,
+ %c!indenting=,
+ %
+ \c!expansion=\v!no,
+ %c!xmlsetup=,
+ %s!catcodes=,
+ \s!language=\currentmainlanguage,
+]
+
+\appendtoks
+ \setfalse\c_strc_constructions_define_commands
+ \ifx\currentsimplelistparent\empty
+ \defineconstruction[\currentsimplelist][\s!handler=\v!simplelist,\c!level=1]%
+ \else
+ \defineconstruction[\currentsimplelist][\currentsimplelistparent][\s!handler=\v!simplelist,\c!level=1]%
+ \fi
+ \settrue\c_strc_constructions_define_commands
+\to \everydefinesimplelist
+
+\setuvalue{\??constructioninitializer\v!simplelist}%
+ {\let\currentsimplelist \currentconstruction
+ \let\constructionparameter \simplelistparameter
+ \let\detokenizedconstructionparameter\detokenizedsimplelistparameter
+ \let\letconstructionparameter \letsimplelistparameter
+ \let\useconstructionstyleandcolor \usesimpleliststyleandcolor
+ \let\setupcurrentconstruction \setupcurrentsimplelist}
+
+\setuvalue{\??constructionfinalizer\v!simplelist}%
+ {}
+
+\setuvalue{\??constructiontexthandler\v!simplelist}%
+ {\begingroup
+ \useconstructionstyleandcolor\c!headstyle\c!headcolor
+ \the\everyconstruction
+ \constructionparameter\c!headcommand
+ {\strut
+ \currentsimplelistentry}%
+ \endgroup}
-\installsimplecommandhandler \??synonym {synonym} \??synonym
+% And we build on top of this.
-\let\setupsynonyms\setupsynonym
+\ifdefined\dotagsynonym \else \let\dotagsynonym\relax \fi
+\ifdefined\dotagsorting \else \let\dotagsorting\relax \fi
-\setupsynonyms
+\definesimplelist
+ [\v!synonym]
[\c!state=\v!start,
%\c!synonymstyle=,
%\c!textstyle=,
@@ -75,50 +141,62 @@
%\c!after=,
\c!indentnext=\v!no,
%\c!expansion=,
- \c!method=,
- \s!language=\currentmainlanguage]
+ \c!method=]
+
+\let\setupsynonyms\setupsimplelist
\unexpanded\def\definesynonyms
- {\doquadrupleempty\dodefinesynonyms}
+ {\doquadrupleempty\strc_synonyms_define}
-\def\dodefinesynonyms[#1][#2][#3][#4]% name plural \meaning \use
+\def\strc_synonyms_define[#1][#2][#3][#4]% name plural \meaning \use
{\edef\currentsynonym{#1}%
\iffourthargument
- \unexpanded\def#4##1{\doinsertsynonym{#1}{##1}}% name tag
+ \unexpanded\def#4##1{\strc_synonyms_insert{#1}{##1}}% name tag
\ifthirdargument
- \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning
+ \unexpanded\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning
\fi
\setuvalue{#1}{\definesynonym[\v!no][#1]}% \name
\else
\ifthirdargument
- \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning
+ \unexpanded\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning
\fi
\setuvalue{#1}{\definesynonym[\v!yes][#1]}% \name
\fi
- \checksynonymparent
- \setupcurrentsynonym[\s!single={#1},\s!multi={#2}]%
+ %
+% \checksynonymparent
+% \setupcurrentsynonym[\s!single={#1},\s!multi={#2}]%
+ \setfalse\c_strc_constructions_define_commands
+ \definesimplelist
+ [\currentsynonym]%
+ [\v!sorting]
+ [\s!single={#1},%
+ \s!multi={#2}]%
+ \settrue\c_strc_constructions_define_commands
+ %
\presetheadtext[#2=\Word{#2}]% changes the \if...argument
+ %
\setvalue{\e!setup #2\e!endsetup}{\setupsynonym[#1]}% obsolete definition
\setvalue{\e!place \e!listof#2}{\placelistofsynonyms[#1]}% accepts extra argument
\setvalue{\e!complete\e!listof#2}{\completelistofsynonyms[#1]}}
\unexpanded\def\definesynonym
- {\dotripleempty\dodefinesynonym}
+ {\dotripleempty\strc_synonyms_define_entry}
-\def\dodefinesynonym[#1][#2][#3]#4#5%
+\def\strc_synonyms_define_entry[#1][#2][#3]#4#5%
{\begingroup
\edef\currentsynonym{#2}%
\edef\currentsynonymtag{#3}%
+ \let\currentsimplelist\currentsimplelist
\ifx\currentsynonymtag\empty
\edef\currentsynonymtag{#4}%
\fi
\ifx\currentsynonymtag\empty
% todo: error message
\else
- \edef\currentsynonymexpansion{\synonymparameter\c!expansion}%
+ \edef\currentsynonymexpansion{\simplelistparameter\c!expansion}%
\preprocessexpansion\currentsynonymexpansion\currentsynonymtext \currentsynonymcoding{#4}%
\preprocessexpansion\currentsynonymexpansion\currentsynonymmeaning\currentsynonymcoding{#5}%
- \ctxlua{structures.synonyms.register("\currentsynonym", "synonym", {
+ \ctxcommand{registersynonym("\currentsynonym", "synonym", {
metadata = {
catcodes = \the\catcodetable,
coding = "\currentsynonymcoding",
@@ -131,91 +209,77 @@
used = false,
}
})}%
- \doif{#1}\v!yes{\setuxvalue\currentsynonymtag{\noexpand\doinsertsynonym{\currentsynonym}{\currentsynonymtag}}}%
+ \doif{#1}\v!yes{\setuxvalue\currentsynonymtag{\strc_synonyms_insert{\currentsynonym}{\currentsynonymtag}}}%
\fi
\endgroup}
\unexpanded\def\registersynonym
- {\dodoubleargument\doregistersynonym}
+ {\dodoubleargument\strc_synonyms_register}
-\def\doregistersynonym[#1][#2]%
- {\ctxlua{structures.synonyms.registerused("#1","#2")}}
+\def\strc_synonyms_register[#1][#2]%
+ {\ctxcommand{registerusedsynonym("#1","#2")}}
-\unexpanded\def\doinsertsynonymmeaning#1#2% name tag
+\unexpanded\def\strc_synonyms_insert_meaning#1#2% name tag
{\begingroup
- \def\currentsynonym{#1}%
- \usesynonymstyleandcolor\c!textstyle\c!textcolor
- \synonymparameter\c!textcommand{\ctxlua{structures.synonyms.meaning("#1","#2")}}%
+ \def\currentsimplelist{#1}%
+ \usesimpleliststyleandcolor\c!textstyle\c!textcolor
+ \simplelistparameter\c!textcommand{\ctxcommand{synonymmeaning("#1","#2")}}%
\endgroup}
-\unexpanded\def\doinsertsynonym#1#2% name tag
+\unexpanded\def\strc_synonyms_insert#1#2% name tag
{\begingroup
- \def\currentsynonym{#1}%
+ \edef\currentsimplelist{#1}%
+ \let\currentsynonym\currentsimplelist % for a while
\def\currentsynonymtag{#2}%
\dostarttagged\t!synonym\currentsynonym
\dotagsynonym
- \usesynonymstyleandcolor\c!synonymstyle\c!synonymcolor
- \synonymparameter\c!synonymcommand{\ctxlua{structures.synonyms.synonym("#1","#2")}}%
+ \usesimpleliststyleandcolor\c!synonymstyle\c!synonymcolor
+ \simplelistparameter\c!synonymcommand{\ctxcommand{synonymname("#1","#2")}}%
\dostoptagged
- \normalexpanded{\endgroup\synonymparameter\c!next}}
+ \normalexpanded{\endgroup\simplelistparameter\c!next}}
\unexpanded\def\placelistofsynonyms
- {\dodoubleempty\doplacelistofsynonyms}
+ {\dodoubleempty\strc_synonyms_place_list}
-\def\doplacelistofsynonyms[#1][#2]%
+\def\strc_synonyms_place_list[#1][#2]%
{\begingroup
- \def\currentsynonym{#1}%
- \definedescription % todo, per class
- [syndef]
- [\c!location=\synonymparameter\c!location,
- \c!width=\synonymparameter\c!width,
- \c!distance=\synonymparameter\c!distance,
- \c!sample=\synonymparameter\c!sample,
- \c!hang=\synonymparameter\c!hang,
- \c!align=\synonymparameter\c!align,
- \c!before=\synonymparameter\c!before,
- \c!inbetween=\synonymparameter\c!inbetween,
- \c!after=\synonymparameter\c!after,
- \c!indentnext=\synonymparameter\c!indentnext,
- \c!headstyle=\synonymparameter\c!textstyle,
- \c!headcolor=\synonymparameter\c!textcolor,
- \c!style=,
- \c!color=.
- #2]%
+ \edef\currentsimplelist{#1}%
+ \strc_constructions_initialize{#1}%
+ \setupcurrentsimplelist[#2]%
+ \let\synonymentry\strc_synonym_normal
\startpacked
- \ctxlua{structures.synonyms.process('#1',{
- criterium = "\synonymparameter\c!criterium",
- language = "\synonymparameter\s!language",
- method = "\synonymparameter\c!method",
+ \ctxcommand{processsynonyms('#1',{
+ criterium = "\simplelistparameter\c!criterium",
+ language = "\simplelistparameter\s!language",
+ method = "\simplelistparameter\c!method",
})}%
\stoppacked
\endgroup}
\def\completelistofsynonyms
- {\dodoubleempty\docompletelistofsynonyms}
+ {\dodoubleempty\strc_synonyms_complete_list}
-\def\docompletelistofsynonyms[#1][#2]%
- {\edef\currentsynonym{#1}%
- \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\synonymparameter\s!multi}},\c!reference=#1]}%
- \doplacelistofsynonyms[#1][#2]%
+\def\strc_synonyms_complete_list[#1][#2]%
+ {\begingroup
+ \edef\currentsimplelist{#1}%
+ \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\simplelistparameter\s!multi}},\c!reference=#1]}%
+ \strc_synonyms_place_list[#1][#2]%
\page
- \stopnamedsection}
-
-\let\startsynonymoutput \relax
-\let\stopsynonymoutput \relax
-\let\startsynonymsection\gobbleoneargument
-\let\stopsynonymsection \relax
+ \stopnamedsection
+ \endgroup}
-\unexpanded\def\synonymentry#1#2#3#4%
- {\syndef{#3}#4\par}
+\unexpanded\def\strc_synonym_normal#1#2#3#4%
+ {\begingroup
+ \def\currentsimplelistentry{#3}%
+ \csname\??constructionstarthandler\v!construction\endcsname
+ #4%
+ \csname\??constructionstophandler\v!construction\endcsname
+ \endgroup}
%D Sorting (a simplified version of synonym).
-\installcorenamespace{sorting}
-
-\installsimplecommandhandler \??sorting {sorting} \??sorting
-
-\setupsorting
+\definesimplelist
+ [\v!sorting]
[\c!state=\v!start,
%\c!command=, % we test for defined !
%\c!criterium=,
@@ -223,48 +287,57 @@
%\c!before=,
\c!after=\endgraf,
%\c!expansion=,
- \c!method=,
- \s!language=\currentmainlanguage]
+ \c!method=]
+
+\let\setupsorting\setupsimplelist
\unexpanded\def\definesorting
- {\dotripleempty\dodefinesorting}
+ {\dotripleempty\strc_sorting_define}
% if #3=\relax or \v!none, then no command but still protected
-\def\dodefinesorting[#1][#2][#3]%
+\def\strc_sorting_define[#1][#2][#3]%
{\edef\currentsorting{#1}%
\ifthirdargument
\doifnot{#3}\v!none
{\ifx#3\relax \else
- \unexpanded\def#3##1{\doinsertsort{#1}{##1}}%
+ \unexpanded\def#3##1{\strc_sorting_insert{#1}{##1}}%
\fi}%
\setuvalue{#1}{\definesort[\v!no][#1]}%
\else
\setuvalue{#1}{\definesort[\v!yes][#1]}%
\fi
- \checksortingparent
- \setupcurrentsorting[\s!multi={#2}]%
+ \setfalse\c_strc_constructions_define_commands
+ \definesimplelist
+ [\currentsorting]%
+ [\v!sorting]
+ [\s!single={#1},%
+ \s!multi={#2}]%
+ \settrue\c_strc_constructions_define_commands
+ %
\presetheadtext[#2=\Word{#2}]% after \ifthirdargument -)
+ %
\setvalue{\e!setup #2\e!endsetup}{\setupsorting[#1]}% obsolete definition
\setvalue{\e!place \e!listof#2}{\placelistofsorts[#1]}%
\setvalue{\e!complete\e!listof#2}{\completelistofsorts[#1]}}
\unexpanded\def\definesort
- {\dotripleempty\dodefinesort}
+ {\dotripleempty\strc_sorting_define_entry}
-\def\dodefinesort[#1][#2][#3]#4%
+\def\strc_sorting_define_entry[#1][#2][#3]#4%
{\begingroup
\edef\currentsorting{#2}%
\edef\currentsortingtag{#3}%
+ \let\currentsimplelist\currentsimplelist
\ifx\currentsortingtag\empty
\edef\currentsortingtag{#4}%
\fi
\ifx\currentsortingtag\empty
% todo: error message
\else
- \edef\currentsortingexpansion{\sortingparameter\c!expansion}%
+ \edef\currentsortingexpansion{\simplelistparameter\c!expansion}%
\preprocessexpansion\currentsortingexpansion\currentsortingtext\currentsortingcoding{#4}%
- \ctxlua{structures.synonyms.register("\currentsorting", "sorting", {
+ \ctxcommand{registersynonym("\currentsorting", "sorting", {
metadata = {
catcodes = \the\catcodetable,
coding = "\currentsortingcoding",
@@ -276,67 +349,77 @@
% used = false,
}
})}%
- \doif{#1}\v!yes{\setuxvalue\currentsortingtag{\noexpand\doinsertsort{\currentsorting}{\currentsortingtag}}}%
+ \doif{#1}\v!yes{\setuxvalue\currentsortingtag{\strc_sorting_insert{\currentsorting}{\currentsortingtag}}}%
\fi
\endgroup}
-\unexpanded\def\doinsertsort#1#2% name tag
+\unexpanded\def\strc_sorting_insert#1#2% name tag
{\begingroup
% no kap currently, of .. we need to map cap onto WORD
\edef\currentsorting{#1}%
\def\currentsortingtag{#2}%
+ \let\currentsimplelist\currentsorting
\dostarttagged\t!sorting\currentsorting
\dotagsorting
- \usesortingstyleandcolor\c!style\c!color
- \ctxlua{structures.synonyms.synonym("#1","#2")}%
+ \usesimpleliststyleandcolor\c!style\c!color
+ \ctxcommand{synonymname("#1","#2")}%
\dostoptagged
- \normalexpanded{\endgroup\sortingparameter\c!next}}
+ \normalexpanded{\endgroup\simplelistparameter\c!next}}
\unexpanded\def\registersort
- {\dodoubleargument\doregistersort}
+ {\dodoubleargument\strc_sorting_register}
-\def\doregistersort[#1][#2]%
- {\ctxlua{structures.synonyms.registerused("#1","#2")}}
+\def\strc_sorting_register[#1][#2]%
+ {\ctxcommand{registerusedsynonym("#1","#2")}}
% before after
%
% maybe just 'commandset' and then combine
\unexpanded\def\placelistofsorts
- {\dodoubleempty\doplacelistofsorts}
+ {\dodoubleempty\strc_sorting_place_list}
-\def\doplacelistofsorts[#1][#2]% NOG EEN RUWE VERSIE MAKEN ZONDER WITRUIMTE ETC ETC
+\def\strc_sorting_place_list[#1][#2]%
{\begingroup
- \def\currentsorting{#1}%
- \setupcurrentsorting[#2]%
+ \edef\currentsimplelist{#1}%
+ \strc_constructions_initialize{#1}%
+ \setupcurrentsimplelist[#2]%
+ \edef\p_simplelist_command{\simplelistparameter\c!command}%
+ \ifx\p_simplelist_command\empty
+ \let\synonymentry\strc_sorting_normal
+ \else
+ \let\synonymentry\strc_sorting_command
+ \fi
\startpacked
- \ctxlua{structures.synonyms.process('#1',{
- criterium = "\sortingparameter\c!criterium",
- language = "\sortingparameter\s!language",
- method = "\sortingparameter\c!method",
+ \ctxcommand{processsynonyms('#1',{
+ criterium = "\simplelistparameter\c!criterium",
+ language = "\simplelistparameter\s!language",
+ method = "\simplelistparameter\c!method",
})}%
\stoppacked
\endgroup}
\unexpanded\def\completelistofsorts
- {\dodoubleempty\docompletelistofsorts}
+ {\dodoubleempty\strc_sorting_complete_list}
-\def\docompletelistofsorts[#1][#2]%
- {\edef\currentsorting{#1}%
- \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\sortingparameter\s!multi}},\c!reference=#1]}%
- \doplacelistofsorts[#1][#2]%
+\def\strc_sorting_complete_list[#1][#2]%
+ {\begingroup
+ \edef\currentsimplelist{#1}%
+ \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\simplelistparameter\s!multi}},\c!reference=#1]}%
+ \strc_sorting_place_list[#1][#2]%
\page
- \stopnamedsection}
+ \stopnamedsection
+ \endgroup}
-\let\startsortingoutput \relax
-\let\stopsortingoutput \relax
-\let\startsortingsection\gobbleoneargument
-\let\stopsortingsection \relax
+\def\strc_sorting_command#1#2#3#4% #4 is meaning but empty here
+ {\p_simplelist_command{#1}{#2}{#3}}
-\def\sortingentry#1#2#3#4% #4 is meaning but empty here
- {\doifelsenothing{\sortingparameter\c!command}
- {\begingroup\usesortingstyleandcolor\c!style\c!color#3\endgroup\par} % todo
- {\sortingparameter\c!command{#1}{#2}{#3}}}
+\def\strc_sorting_normal#1#2#3#4% #4 is meaning but empty here
+ {\begingroup
+ \usesimpleliststyleandcolor\c!style\c!color
+ #3%
+ \endgroup
+ \par}
%D Presets.
diff --git a/tex/context/base/syst-aux.lua b/tex/context/base/syst-aux.lua
index 6b5e18d16..de15428f9 100644
--- a/tex/context/base/syst-aux.lua
+++ b/tex/context/base/syst-aux.lua
@@ -78,7 +78,7 @@ end
-- end
-- end
-local pattern = (C((1-P("%"))^1) * Carg(1)) /function(n,d) return format("%.0fsp",d * tonumber(n)/100) end * P("%") * P(-1)
+local pattern = (C((1-P("%"))^1) * Carg(1)) /function(n,d) return format("%.0fsp",d * tonumber(n)/100) end * P("%") * P(-1) -- .0 ?
-- commands.percentageof("10%",65536*10)
@@ -109,7 +109,8 @@ function commands.thetexdefinition(str)
context(lpegmatch(pattern,str))
end
-local upper, lower = utf.upper, utf.lower
+local upper, lower, strip = utf.upper, utf.lower, string.strip
function commands.upper(s) context(upper(s)) end
function commands.lower(s) context(lower(s)) end
+function commands.strip(s) context(strip(s)) end
diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv
index c7be461a3..876044240 100644
--- a/tex/context/base/syst-aux.mkiv
+++ b/tex/context/base/syst-aux.mkiv
@@ -346,6 +346,12 @@
\let\if_next_blank_space_token\iffalse
\futurelet\nexttoken\syst_helpers_inspect_next_bgroup_character}
+\unexpanded\def\doifnextbgroupcselse#1#2%
+ {\let\m_syst_action_yes#1%
+ \let\m_syst_action_nop#2%
+ \let\if_next_blank_space_token\iffalse
+ \futurelet\nexttoken\syst_helpers_inspect_next_bgroup_character}
+
\def\syst_helpers_inspect_next_bgroup_character
{\ifx\nexttoken\blankspace
\expandafter\syst_helpers_reinspect_next_bgroup_character
diff --git a/tex/context/base/syst-con.lua b/tex/context/base/syst-con.lua
index 48f02da3a..dfbd49051 100644
--- a/tex/context/base/syst-con.lua
+++ b/tex/context/base/syst-con.lua
@@ -6,29 +6,39 @@ if not modules then modules = { } end modules ['syst-con'] = {
license = "see context related readme files"
}
-converters = converters or { }
+local tonumber = tonumber
+local utfchar = utf.char
+local gsub, format = string.gsub, string.format
+
+converters = converters or { }
+local converters = converters
+
+local context = context
+local comands = commands
+
+local formatters = string,formatters
--[[ldx--
<p>For raw 8 bit characters, the offset is 0x110000 (bottom of plane 18) at
the top of <l n='luatex'/>'s char range but outside the unicode range.</p>
--ldx]]--
-local tonumber = tonumber
-local utfchar = utf.char
-local gsub, format = string.gsub, string.format
+function converters.hexstringtonumber(n) tonumber(n,16) end
+function converters.octstringtonumber(n) tonumber(n, 8) end
-function converters.hexstringtonumber(n) tonumber(n,16) end
-function converters.octstringtonumber(n) tonumber(n, 8) end
function converters.rawcharacter (n) utfchar(0x110000+n) end
-function converters.lchexnumber (n) format("%x" ,n) end
-function converters.uchexnumber (n) format("%X" ,n) end
-function converters.lchexnumbers (n) format("%02x",n) end
-function converters.uchexnumbers (n) format("%02X",n) end
-function converters.octnumber (n) format("%03o",n) end
+
+converters.lchexnumber = formatters["%x" ]
+converters.uchexnumber = formatters["%X" ]
+converters.lchexnumbers = formatters["%02x"]
+converters.uchexnumbers = formatters["%02X"]
+converters.octnumber = formatters["%03o"]
function commands.hexstringtonumber(n) context(tonumber(n,16)) end
function commands.octstringtonumber(n) context(tonumber(n, 8)) end
+
function commands.rawcharacter (n) context(utfchar(0x110000+n)) end
+
function commands.lchexnumber (n) context("%x" ,n) end
function commands.uchexnumber (n) context("%X" ,n) end
function commands.lchexnumbers (n) context("%02x",n) end
@@ -53,10 +63,10 @@ local cos, sin, tan = math.cos, math.sin, math.tan
-- function commands.cos (n) context(cos (n)) end
-- function commands.tan (n) context(tan (n)) end
-function commands.sind(n) context("%0.6f",sind(n)) end
-function commands.cosd(n) context("%0.6f",cosd(n)) end
-function commands.tand(n) context("%0.6f",tand(n)) end
+function commands.sind(n) context("%0.6F",sind(n)) end
+function commands.cosd(n) context("%0.6F",cosd(n)) end
+function commands.tand(n) context("%0.6F",tand(n)) end
-function commands.sin (n) context("%0.6f",sin (n)) end
-function commands.cos (n) context("%0.6f",cos (n)) end
-function commands.tan (n) context("%0.6f",tan (n)) end
+function commands.sin (n) context("%0.6F",sin (n)) end
+function commands.cos (n) context("%0.6F",cos (n)) end
+function commands.tan (n) context("%0.6F",tan (n)) end
diff --git a/tex/context/base/syst-lua.lua b/tex/context/base/syst-lua.lua
index e47041444..cd7dcc062 100644
--- a/tex/context/base/syst-lua.lua
+++ b/tex/context/base/syst-lua.lua
@@ -17,37 +17,37 @@ local context = context
function commands.writestatus(...) logs.status(...) end -- overloaded later
-local firstoftwoarguments = context.firstoftwoarguments -- context.constructcsonly("firstoftwoarguments" )
-local secondoftwoarguments = context.secondoftwoarguments -- context.constructcsonly("secondoftwoarguments")
-local firstofoneargument = context.firstofoneargument -- context.constructcsonly("firstofoneargument" )
-local gobbleoneargument = context.gobbleoneargument -- context.constructcsonly("gobbleoneargument" )
+local ctx_firstoftwoarguments = context.firstoftwoarguments -- context.constructcsonly("firstoftwoarguments" )
+local ctx_secondoftwoarguments = context.secondoftwoarguments -- context.constructcsonly("secondoftwoarguments")
+local ctx_firstofoneargument = context.firstofoneargument -- context.constructcsonly("firstofoneargument" )
+local ctx_gobbleoneargument = context.gobbleoneargument -- context.constructcsonly("gobbleoneargument" )
--- contextsprint(prtcatcodes,[[\ui_fo]]) -- firstofonearguments
--- contextsprint(prtcatcodes,[[\ui_go]]) -- gobbleonearguments
--- contextsprint(prtcatcodes,[[\ui_ft]]) -- firstoftwoarguments
--- contextsprint(prtcatcodes,[[\ui_st]]) -- secondoftwoarguments
+-- contextsprint(prtcatcodes,[[\ui_fo]]) -- ctx_firstofonearguments
+-- contextsprint(prtcatcodes,[[\ui_go]]) -- ctx_gobbleonearguments
+-- contextsprint(prtcatcodes,[[\ui_ft]]) -- ctx_firstoftwoarguments
+-- contextsprint(prtcatcodes,[[\ui_st]]) -- ctx_secondoftwoarguments
function commands.doifelse(b)
if b then
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
else
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
end
end
function commands.doif(b)
if b then
- firstofoneargument()
+ ctx_firstofoneargument()
else
- gobbleoneargument()
+ ctx_gobbleoneargument()
end
end
function commands.doifnot(b)
if b then
- gobbleoneargument()
+ ctx_gobbleoneargument()
else
- firstofoneargument()
+ ctx_firstofoneargument()
end
end
@@ -59,9 +59,9 @@ end
function commands.doifelsespaces(str)
if find(str,"^ +$") then
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
else
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
end
end
@@ -84,12 +84,12 @@ function commands.doifcommonelse(a,b) -- often the same test
for i=1,na do
for j=1,nb do
if ha[i] == hb[j] then
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
return
end
end
end
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
end
function commands.doifinsetelse(a,b)
@@ -97,20 +97,20 @@ function commands.doifinsetelse(a,b)
if not hb then hb = lpegmatch(s,b) h[b] = hb end
for i=1,#hb do
if a == hb[i] then
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
return
end
end
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
end
local pattern = lpeg.patterns.validdimen
function commands.doifdimenstringelse(str)
if lpegmatch(pattern,str) then
- firstoftwoarguments()
+ ctx_firstoftwoarguments()
else
- secondoftwoarguments()
+ ctx_secondoftwoarguments()
end
end
diff --git a/tex/context/base/tabl-tbl.lua b/tex/context/base/tabl-tbl.lua
index 21564a472..b088a1008 100644
--- a/tex/context/base/tabl-tbl.lua
+++ b/tex/context/base/tabl-tbl.lua
@@ -9,21 +9,25 @@ if not modules then modules = { } end modules ['tabl-tbl'] = {
-- A couple of hacks ... easier to do in Lua than in regular TeX. More will
-- follow.
-local context, commands = context, commands
-
local tonumber = tonumber
local gsub, rep, sub, find = string.gsub, string.rep, string.sub, string.find
local P, C, Cc, Ct, lpegmatch = lpeg.P, lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.match
+local context = context
+local commands = commands
+
local texsetcount = tex.setcount
-local separator = P("|")
-local nested = lpeg.patterns.nested
-local pattern = Ct((separator * (C(nested) + Cc("")) * C((1-separator)^0))^0)
+local separator = P("|")
+local nested = lpeg.patterns.nested
+local pattern = Ct((separator * (C(nested) + Cc("")) * C((1-separator)^0))^0)
+
+local ctx_settabulatelastentry = context.settabulatelastentry
+local ctx_settabulateentry = context.settabulateentry
function commands.presettabulate(preamble)
preamble = gsub(preamble,"~","d") -- let's get rid of ~ mess here
- if find(preamble,"%*") then
+ if find(preamble,"*",1,true) then
-- todo: lpeg but not now
preamble = gsub(preamble, "%*(%b{})(%b{})", function(n,p)
return rep(sub(p,2,-2),tonumber(sub(n,2,-2)) or 1)
@@ -35,7 +39,7 @@ function commands.presettabulate(preamble)
texsetcount("global","c_tabl_tabulate_has_rule_spec_first", t[1] == "" and 0 or 1)
texsetcount("global","c_tabl_tabulate_has_rule_spec_last", t[m+1] == "" and 0 or 1)
for i=1,m,2 do
- context.settabulateentry(t[i],t[i+1])
+ ctx_settabulateentry(t[i],t[i+1])
end
- context.settabulatelastentry(t[m+1])
+ ctx_settabulatelastentry(t[m+1])
end
diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv
index 82d1be893..1aeaa2e56 100644
--- a/tex/context/base/tabl-tbl.mkiv
+++ b/tex/context/base/tabl-tbl.mkiv
@@ -1076,8 +1076,8 @@
\tabulatenoalign{\kern-\lineheight}%
\fi}
-\setuvalue{\e!start\v!tabulatehead}{\doifnextoptionalelse\tabl_tabulate_start_head_yes\tabl_tabulate_start_head_nop}
-\setuvalue{\e!start\v!tabulatetail}{\doifnextoptionalelse\tabl_tabulate_start_foot_yes\tabl_tabulate_start_foot_nop}
+\setuvalue{\e!start\v!tabulatehead}{\doifnextoptionalcselse\tabl_tabulate_start_head_yes\tabl_tabulate_start_head_nop}
+\setuvalue{\e!start\v!tabulatetail}{\doifnextoptionalcselse\tabl_tabulate_start_foot_yes\tabl_tabulate_start_foot_nop}
\let\m_tabl_tabulate_data\empty
@@ -1097,7 +1097,7 @@
% {\bgroup
% \edef\currenttabulationparent{#1}%
% \let\currenttabulation\currenttabulationparent
-% \doifnextoptionalelse\tabl_start_defined_yes\tabl_start_defined_nop}
+% \doifnextoptionalcselse\tabl_start_defined_yes\tabl_start_defined_nop}
%
% \def\tabl_start_defined_yes[#1]%
% {\edef\currenttabulation{\currenttabulation:#1}%
diff --git a/tex/context/base/tabl-xtb.lua b/tex/context/base/tabl-xtb.lua
index 653eb6e08..d18719a89 100644
--- a/tex/context/base/tabl-xtb.lua
+++ b/tex/context/base/tabl-xtb.lua
@@ -41,7 +41,6 @@ local format = string.format
local concat = table.concat
local points = number.points
-local context = context
local context_beginvbox = context.beginvbox
local context_endvbox = context.endvbox
local context_blank = context.blank
diff --git a/tex/context/base/tabl-xtb.mkvi b/tex/context/base/tabl-xtb.mkvi
index 556bec5ce..cca56dbee 100644
--- a/tex/context/base/tabl-xtb.mkvi
+++ b/tex/context/base/tabl-xtb.mkvi
@@ -402,7 +402,7 @@
\unexpanded\def\startxrow
{\begingroup
- \doifnextoptionalelse\tabl_x_start_row_yes\tabl_x_start_row_nop}
+ \doifnextoptionalcselse\tabl_x_start_row_yes\tabl_x_start_row_nop}
\unexpanded\def\tabl_x_start_row_reflow_width_yes[#settings]%
{\setupcurrentxtable[#settings]%
@@ -435,7 +435,7 @@
\endgroup}
\unexpanded\def\startxcell
- {\doifnextoptionalelse\tabl_x_start_cell_yes\tabl_x_start_cell_nop}
+ {\doifnextoptionalcselse\tabl_x_start_cell_yes\tabl_x_start_cell_nop}
\unexpanded\def\stopxcell
{\tabl_x_stop_cell}
@@ -677,7 +677,7 @@
\unexpanded\def\startxgroup
{\begingroup
- \doifnextoptionalelse\tabl_x_start_group_delayed_one\relax}
+ \doifnextoptionalcselse\tabl_x_start_group_delayed_one\relax}
\unexpanded\def\stopxgroup
{\endgroup}
@@ -695,7 +695,7 @@
\chaintocurrentxtable{#tag}%
\fi
\edef\currentxtable{#tag}%
- \doifnextoptionalelse\setupcurrentxtable\relax}
+ \doifnextoptionalcselse\setupcurrentxtable\relax}
\let\startxrowgroup \startxgroup
\let\stopxrowgroup \stopxgroup
@@ -706,7 +706,7 @@
\unexpanded\def\startxcell
{\begingroup
- \doifnextoptionalelse\tabl_x_start_cell_delayed_one\tabl_x_start_cell_nop}
+ \doifnextoptionalcselse\tabl_x_start_cell_delayed_one\tabl_x_start_cell_nop}
\unexpanded\def\tabl_x_start_cell_delayed_one[#tag]%
% {\ifcsname\namedxtablehash{#tag}\s!parent\endcsname
@@ -721,7 +721,7 @@
\chaintocurrentxtable{#tag}%
\fi
\edef\currentxtable{#tag}%
- \doifnextoptionalelse\tabl_x_start_cell_yes\tabl_x_start_cell_nop}
+ \doifnextoptionalcselse\tabl_x_start_cell_yes\tabl_x_start_cell_nop}
\unexpanded\def\stopxcell
{\tabl_x_stop_cell
@@ -731,7 +731,7 @@
\unexpanded\def\startxrow
{\begingroup
- \doifnextoptionalelse\tabl_x_start_row_delayed_one\tabl_x_start_row_nop}
+ \doifnextoptionalcselse\tabl_x_start_row_delayed_one\tabl_x_start_row_nop}
\unexpanded\def\tabl_x_start_row_delayed_one[#tag]%
% {\ifcsname\namedxtablehash{#tag}\s!parent\endcsname
@@ -746,7 +746,7 @@
\chaintocurrentxtable{#tag}%
\fi
\edef\currentxtable{#tag}%
- \doifnextoptionalelse\tabl_x_start_row_yes\tabl_x_start_row_nop}
+ \doifnextoptionalcselse\tabl_x_start_row_yes\tabl_x_start_row_nop}
\unexpanded\def\stopxrow
{\tabl_x_stop_row
diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua
index fa9b0cf10..ff1d36486 100644
--- a/tex/context/base/task-ini.lua
+++ b/tex/context/base/task-ini.lua
@@ -18,11 +18,13 @@ if not modules then modules = { } end modules ['task-ini'] = {
-- not apply the font handler, we can remove all checks for subtypes 255
local tasks = nodes.tasks
+local prependaction = tasks.prependaction
local appendaction = tasks.appendaction
local disableaction = tasks.disableaction
local freezegroup = tasks.freezegroup
local freezecallbacks = callbacks.freeze
+
appendaction("processors", "normalizers", "typesetters.characters.handler") -- always on
appendaction("processors", "normalizers", "fonts.collections.process") -- disabled
appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled
@@ -120,6 +122,11 @@ appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler")
appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler")
appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler")
+-- rather special (this might get hardcoded):
+
+-- prependaction("processors", "before", "nodes.properties.attach")
+-- appendaction ("shipouts", "normalizers", "nodes.properties.delayed")
+
-- speedup: only kick in when used
disableaction("processors", "languages.replacements.handler")
diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua
index 4cc48c4a5..cd8f803d4 100644
--- a/tex/context/base/trac-deb.lua
+++ b/tex/context/base/trac-deb.lua
@@ -9,27 +9,30 @@ if not modules then modules = { } end modules ['trac-deb'] = {
local lpeg, status = lpeg, status
local lpegmatch = lpeg.match
-local format, concat, match = string.format, table.concat, string.match
+local format, concat, match, find = string.format, table.concat, string.match, string.find
local tonumber, tostring = tonumber, tostring
-- maybe tracers -> tracers.tex (and tracers.lua for current debugger)
-local report_system = logs.reporter("system","tex")
+local report_tex = logs.reporter("tex error")
+local report_lua = logs.reporter("lua error")
+local report_nl = logs.newline
+local report_str = logs.writer
-tracers = tracers or { }
-local tracers = tracers
+tracers = tracers or { }
+local tracers = tracers
-tracers.lists = { }
-local lists = tracers.lists
+tracers.lists = { }
+local lists = tracers.lists
-tracers.strings = { }
-local strings = tracers.strings
+tracers.strings = { }
+local strings = tracers.strings
-local texgetdimen = tex.getdimen
-local texgettoks = tex.gettoks
-local texgetcount = tex.getcount
+local texgetdimen = tex.getdimen
+local texgettoks = tex.gettoks
+local texgetcount = tex.getcount
-strings.undefined = "undefined"
+strings.undefined = "undefined"
lists.scratch = {
0, 2, 4, 6, 8
@@ -96,7 +99,9 @@ function tracers.knownlist(name)
return l and #l > 0
end
-function tracers.showlines(filename,linenumber,offset,errorstr)
+local savedluaerror = nil
+
+function tracers.showlines(filename,linenumber,offset,luaerrorline)
local data = io.loaddata(filename)
if not data or data == "" then
local hash = url.hashed(filename)
@@ -109,35 +114,18 @@ function tracers.showlines(filename,linenumber,offset,errorstr)
end
local lines = data and string.splitlines(data)
if lines and #lines > 0 then
- -- This does not work completely as we cannot access the last Lua error using
- -- table.print(status.list()). This is on the agenda. Eventually we will
- -- have a sequence of checks here (tex, lua, mp) at this end.
- --
- -- Actually, in 0.75+ the lua error message is even weirder as you can
- -- get:
- --
- -- LuaTeX error [string "\directlua "]:3: unexpected symbol near '1' ...
- --
- -- <inserted text> \endgroup \directlua {
- --
- -- So there is some work to be done in the LuaTeX engine.
- --
- local what, where = match(errorstr,[[LuaTeX error <main (%a+) instance>:(%d+)]])
- or match(errorstr,[[LuaTeX error %[string "\\(.-lua) "%]:(%d+)]]) -- buglet
- if where then
+ if luaerrorline and luaerrorline > 0 then
-- lua error: linenumber points to last line
local start = "\\startluacode"
local stop = "\\stopluacode"
- local where = tonumber(where)
- if lines[linenumber] == start then
- local n = linenumber
- for i=n,1,-1 do
- if lines[i] == start then
- local n = i + where
- if n <= linenumber then
- linenumber = n
- end
+ local n = linenumber
+ for i=n,1,-1 do
+ if find(lines[i],start) then
+ n = i + luaerrorline - 1
+ if n <= linenumber then
+ linenumber = n
end
+ break
end
end
end
@@ -160,29 +148,46 @@ function tracers.showlines(filename,linenumber,offset,errorstr)
end
function tracers.printerror(offset)
- local inputstack = resolvers.inputstack
- local filename = inputstack[#inputstack] or status.filename
- local linenumber = tonumber(status.linenumber) or 0
+ local inputstack = resolvers.inputstack
+ local filename = inputstack[#inputstack] or status.filename
+ local linenumber = tonumber(status.linenumber) or 0
+ local lasttexerror = status.lasterrorstring or "?"
+ local lastluaerror = status.lastluaerrorstring or lasttexerror
+ local luaerrorline = match(lastluaerror,[[%[.-lua%].-:.-(%d+)]]) -- this will work ok in >=0.79
+ local report = luaerrorline and report_lua or report_tex
if not filename then
- report_system("error not related to input file: %s ...",status.lasterrorstring)
+ report("error not related to input file: %s ...",lasttexerror)
elseif type(filename) == "number" then
- report_system("error on line %s of filehandle %s: %s ...",linenumber,filename,status.lasterrorstring)
+ report("error on line %s of filehandle %s: %s ...",linenumber,lasttexerror)
else
- -- currently we still get the error message printed to the log/console so we
- -- add a bit of spacing around our variant
- texio.write_nl("\n")
- local errorstr = status.lasterrorstring or "?"
- -- inspect(status.list())
- report_system("error on line %s in file %s: %s ...\n",linenumber,filename,errorstr) -- lua error?
- texio.write_nl(tracers.showlines(filename,linenumber,offset,errorstr),"\n")
+ report_nl()
+ if luaerrorline then
+ report("error on line %s in file %s:\n\n%s",linenumber,filename,lastluaerror)
+ else
+ report("error on line %s in file %s: %s",linenumber,filename,lasttexerror)
+ if tex.show_context then
+ report_nl()
+ tex.show_context()
+ end
+ end
+ report_nl()
+ report_str(tracers.showlines(filename,linenumber,offset,tonumber(luaerrorline)))
+ report_nl()
end
end
+local nop = function() end
+
directives.register("system.errorcontext", function(v)
+ local register = callback.register
if v then
- callback.register('show_error_hook', function() tracers.printerror(v) end)
+ register('show_error_message', nop)
+ register('show_error_hook', function() tracers.printerror(v) end)
+ register('show_lua_error_hook', nop)
else
- callback.register('show_error_hook', nil)
+ register('show_error_message', nil)
+ register('show_error_hook', nil)
+ register('show_lua_error_hook', nil)
end
end)
diff --git a/tex/context/base/trac-inf.lua b/tex/context/base/trac-inf.lua
index 067cff27c..034726ffc 100644
--- a/tex/context/base/trac-inf.lua
+++ b/tex/context/base/trac-inf.lua
@@ -12,7 +12,7 @@ if not modules then modules = { } end modules ['trac-inf'] = {
-- and rawget.
local type, tonumber, select = type, tonumber, select
-local format, lower = string.format, string.lower
+local format, lower, find = string.format, string.lower, string.find
local concat = table.concat
local clock = os.gettimeofday or os.clock -- should go in environment
@@ -123,10 +123,8 @@ function statistics.show()
-- this code will move
local register = statistics.register
register("used platform", function()
- local mask = lua.mask or "ascii"
- return format("%s, type: %s, binary subtree: %s, symbol mask: %s (%s)",
- os.platform or "unknown",os.type or "unknown", environment.texos or "unknown",
- mask,mask == "utf" and "τεχ" or "tex")
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown", environment.texos or "unknown")
end)
register("luatex banner", function()
return lower(status.banner)
@@ -139,16 +137,25 @@ function statistics.show()
return format("%s direct, %s indirect, %s total", total-indirect, indirect, total)
end)
if jit then
- local status = { jit.status() }
- if status[1] then
- register("luajit status", function()
- return concat(status," ",2)
- end)
+ local jitstatus = { jit.status() }
+ if jitstatus[1] then
+ register("luajit options", concat(jitstatus," ",2))
end
end
-- so far
-- collectgarbage("collect")
- register("current memory usage",statistics.memused)
+ register("lua properties",function()
+ local list = status.list()
+ local hashchar = tonumber(list.luatex_hashchars)
+ local mask = lua.mask or "ascii"
+ return format("engine: %s, used memory: %s, hash type: %s, hash chars: min(%s,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ statistics.memused(),
+ list.luatex_hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask == "utf" and "τεχ" or "tex")
+ end)
register("runtime",statistics.runtime)
logs.newline() -- initial newline
for i=1,#statusinfo do
diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua
index 420e9a00d..7460955eb 100644
--- a/tex/context/base/trac-vis.lua
+++ b/tex/context/base/trac-vis.lua
@@ -439,7 +439,7 @@ local function ruledbox(head,current,vertical,layer,what,simple,previous)
local ht = getfield(current,"height")
local dp = getfield(current,"depth")
local next = getnext(current)
- local prev = previous -- getprev(current) ... prev can be wrong in math mode
+ local prev = previous -- getprev(current) ... prev can be wrong in math mode < 0.78.3
setfield(current,"next",nil)
setfield(current,"prev",nil)
local linewidth = emwidth/10
@@ -860,7 +860,7 @@ local function cleanup()
nk, k_cache = freed(k_cache)
nw, w_cache = freed(w_cache)
nb, b_cache = freed(b_cache)
- -- report_visualize("cache: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes",nf,ng,np,nk,nw,nb)
+ -- report_visualize("cache cleanup: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes",nf,ng,np,nk,nw,nb)
end
local function handler(head)
@@ -931,9 +931,11 @@ function commands.markfonts(n)
visualizers.markfonts(n)
end
+luatex.registerstopactions(cleanup)
+
statistics.register("visualization time",function()
if enabled then
- cleanup() -- in case we don't don't do it each time
+ -- cleanup() -- in case we don't don't do it each time
return format("%s seconds",statistics.elapsedtime(visualizers))
end
end)
diff --git a/tex/context/base/type-imp-ebgaramond.mkiv b/tex/context/base/type-imp-ebgaramond.mkiv
new file mode 100644
index 000000000..838654d49
--- /dev/null
+++ b/tex/context/base/type-imp-ebgaramond.mkiv
@@ -0,0 +1,45 @@
+%D \module
+%D [ file=type-imp-ebgaramond,
+%D version=2013.06.22,
+%D title=\CONTEXT\ Typescript Macros,
+%D subtitle=EB Garamond,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\definefontfeature
+ [eb-garamond-normal]
+ [default]
+ [mode=node,ccmp=yes,calt=yes,
+ liga=yes,dlig=yes,hlig=yes,
+ kern=yes,mark=yes,mkmk=yes,
+ onum=yes,pnum=yes,salt=yes,
+ script=latn]
+
+\definefontfeature
+ [eb-garamond-smallcaps]
+ [eb-garamond-normal]
+ [smcp=yes,c2sc=yes]
+
+\starttypescriptcollection[ebgaramond]
+
+ \starttypescript [serif] [ebgaramond]
+ \loadfontgoodies[ebgaramond]
+ \setups[font:fallback:serif]
+ \definefontsynonym [Serif] [file:ebgaramond-regular] [features=eb-garamond-normal]
+ \definefontsynonym [SerifItalic] [file:ebgaramond-italic] [features=eb-garamond-normal]
+ \definefontsynonym [SerifBold] [file:ebgaramond-bold] [features=eb-garamond-normal]
+ \definefontsynonym [SerifCaps] [Serif] [features=eb-garamond-smallcaps]
+ \stoptypescript
+
+ \starttypescript[ebgaramond]
+ \definetypeface [ebgaramond] [rm] [serif] [ebgaramond] [default] [designsize=auto]
+ \definetypeface [ebgaramond] [tt] [mono] [dejavu] [default]
+ \definetypeface [ebgaramond] [mm] [math] [bonum] [default]
+ \stoptypescript
+
+\stoptypescriptcollection
diff --git a/tex/context/base/type-imp-latinmodern.mkiv b/tex/context/base/type-imp-latinmodern.mkiv
index afe2c6417..fe4b669bd 100644
--- a/tex/context/base/type-imp-latinmodern.mkiv
+++ b/tex/context/base/type-imp-latinmodern.mkiv
@@ -71,11 +71,14 @@
\starttypescript [\s!math] [modern,latin-modern-designsize,latin-modern] [\s!name]
\loadfontgoodies[lm]
- \loadfontgoodies[lm-math]
\definefontsynonym [\s!MathRoman] [LMMathRoman-Regular]
\definefontsynonym [\s!MathRomanBold] [LMMathRoman-Bold]
\stoptypescript
+ \starttypescript [\s!math] [latin-modern-designsize] [\s!name]
+ \loadfontgoodies[lm-math]
+ \stoptypescript
+
\starttypescript [\s!serif] [modern-variable,latin-modern-variable-designsize,latin-modern-variable] [\s!name]
\loadfontgoodies[lm]
\definefontsynonym [\s!Serif] [LMTypewriterVarWd-Regular] [\s!features=\s!default]
diff --git a/tex/context/base/type-ini.mkvi b/tex/context/base/type-ini.mkvi
index a4d576d80..faa9c667c 100644
--- a/tex/context/base/type-ini.mkvi
+++ b/tex/context/base/type-ini.mkvi
@@ -299,7 +299,7 @@
\let\typescripttwo \m_font_typescripts_two
\let\typescriptthree\m_font_typescripts_three
\let\m_font_typescripts_match\empty
- \doifnextoptionalelse\font_typescripts_start_process_one\font_typescripts_start_process_all}
+ \doifnextoptionalcselse\font_typescripts_start_process_one\font_typescripts_start_process_all}
\def\font_typescripts_start_process_all % could be a \let
{\ifconditional\c_font_typescripts_first_pass
@@ -333,10 +333,10 @@
{\font_typescripts_check\m_font_typescripts_three\typescriptthree\font_typescripts_start_process_again_three}
\def\font_typescripts_start_process_again_one
- {\doifnextoptionalelse\font_typescripts_start_process_two\font_typescripts_start_process_yes}
+ {\doifnextoptionalcselse\font_typescripts_start_process_two\font_typescripts_start_process_yes}
\def\font_typescripts_start_process_again_two
- {\doifnextoptionalelse\font_typescripts_start_process_three\font_typescripts_start_process_yes}
+ {\doifnextoptionalcselse\font_typescripts_start_process_three\font_typescripts_start_process_yes}
\let\font_typescripts_start_process_again_three\font_typescripts_start_process_yes
@@ -389,9 +389,9 @@
\unexpanded\def\forgetmapfiles
{\ctxlua{fonts.mappings.reset()}}
-\prependtoks
- \loadmapfile[mkiv-base.map]% can't we preload this one?
-\to \everystarttext
+% \prependtoks
+% \loadmapfile[mkiv-base.map]% can't we preload this one?
+% \to \everystarttext
%D A handy shortcut:
diff --git a/tex/context/base/typo-brk.lua b/tex/context/base/typo-brk.lua
index be11da9c3..14151af43 100644
--- a/tex/context/base/typo-brk.lua
+++ b/tex/context/base/typo-brk.lua
@@ -32,9 +32,8 @@ local getchar = nuts.getchar
local getfont = nuts.getfont
local getid = nuts.getid
local getfield = nuts.getfield
-local getattr = nuts.getattr
-
local setfield = nuts.setfield
+local getattr = nuts.getattr
local setattr = nuts.setattr
local copy_node = nuts.copy
diff --git a/tex/context/base/typo-cln.lua b/tex/context/base/typo-cln.lua
index b7e337662..8b1ac7876 100644
--- a/tex/context/base/typo-cln.lua
+++ b/tex/context/base/typo-cln.lua
@@ -34,6 +34,7 @@ local tonut = nuts.tonut
local setfield = nuts.setfield
local getchar = nuts.getchar
local getattr = nuts.getattr
+local setattr = nuts.setattr
local traverse_id = nuts.traverse_id
diff --git a/tex/context/base/typo-dha.lua b/tex/context/base/typo-dha.lua
index 15e345ff8..3410c2dfc 100644
--- a/tex/context/base/typo-dha.lua
+++ b/tex/context/base/typo-dha.lua
@@ -65,13 +65,14 @@ local getfield = nuts.getfield
local setfield = nuts.setfield
local getattr = nuts.getattr
local setattr = nuts.setattr
+local getprop = nuts.getprop
+local setprop = nuts.setprop
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
local remove_node = nuts.remove
local end_of_math = nuts.end_of_math
-
local nodepool = nuts.pool
local nodecodes = nodes.nodecodes
@@ -240,7 +241,7 @@ local function process(start)
end
elseif lro or override < 0 then
if direction == "r" or direction == "al" then
- setattr(current,a_state,s_isol)
+ setprop(current,a_state,s_isol)
direction = "l"
reversed = true
end
diff --git a/tex/context/base/typo-dir.lua b/tex/context/base/typo-dir.lua
index fbca0f024..e7d3c686c 100644
--- a/tex/context/base/typo-dir.lua
+++ b/tex/context/base/typo-dir.lua
@@ -33,99 +33,41 @@ local formatters = string.formatters
local nodes, node = nodes, node
-local trace_textdirections = false trackers.register("typesetters.directions.text", function(v) trace_textdirections = v end)
-local trace_mathdirections = false trackers.register("typesetters.directions.math", function(v) trace_mathdirections = v end)
-local trace_directions = false trackers.register("typesetters.directions", function(v) trace_textdirections = v trace_mathdirections = v end)
+local trace_textdirections = false trackers.register("typesetters.directions.text", function(v) trace_textdirections = v end)
+local trace_mathdirections = false trackers.register("typesetters.directions.math", function(v) trace_mathdirections = v end)
+local trace_directions = false trackers.register("typesetters.directions", function(v) trace_textdirections = v trace_mathdirections = v end)
local report_textdirections = logs.reporter("typesetting","text directions")
local report_mathdirections = logs.reporter("typesetting","math directions")
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local tonode = nuts.tonode
-local nutstring = nuts.tostring
-
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getfont = nuts.getfont
-local getchar = nuts.getchar
-local getid = nuts.getid
-local getsubtype = nuts.getsubtype
-local getlist = nuts.getlist
-local getfield = nuts.getfield
-local setfield = nuts.setfield
-local getattr = nuts.getattr
-local setattr = nuts.setattr
-
-local hasbit = number.hasbit
-
-local traverse_id = nuts.traverse_id
-local insert_node_before = nuts.insert_before
-local insert_node_after = nuts.insert_after
-local remove_node = nuts.remove
-local end_of_math = nuts.end_of_math
-
-local texsetattribute = tex.setattribute
-local texsetcount = tex.setcount
-local unsetvalue = attributes.unsetvalue
-
-local nodecodes = nodes.nodecodes
-local whatcodes = nodes.whatcodes
-local mathcodes = nodes.mathcodes
-
-local tasks = nodes.tasks
-local tracers = nodes.tracers
-local setcolor = tracers.colors.set
-local resetcolor = tracers.colors.reset
-
-local glyph_code = nodecodes.glyph
-local whatsit_code = nodecodes.whatsit
-local math_code = nodecodes.math
-local penalty_code = nodecodes.penalty
-local kern_code = nodecodes.kern
-local glue_code = nodecodes.glue
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-
-local localpar_code = whatcodes.localpar
-local dir_code = whatcodes.dir
-
-local nodepool = nuts.pool
-
-local new_textdir = nodepool.textdir
-
-local fonthashes = fonts.hashes
-local fontdata = fonthashes.identifiers
-local fontchar = fonthashes.characters
-
-local chardirections = characters.directions
-local charmirrors = characters.mirrors
-local charclasses = characters.textclasses
-
-local directions = typesetters.directions or { }
-typesetters.directions = directions
-
-local a_state = attributes.private('state')
-local a_directions = attributes.private('directions')
-local a_mathbidi = attributes.private('mathbidi')
-
-local strip = false
-
-local s_isol = fonts.analyzers.states.isol
-
-local variables = interfaces.variables
-local v_global = variables["global"]
-local v_local = variables["local"]
-local v_on = variables.on
-local v_yes = variables.yes
-
-local m_enabled = 2^6 -- 64
-local m_global = 2^7
-local m_fences = 2^8
-
-local handlers = { }
-local methods = { }
-local lastmethod = 0
+local hasbit = number.hasbit
+
+local texsetattribute = tex.setattribute
+local unsetvalue = attributes.unsetvalue
+
+local tasks = nodes.tasks
+local tracers = nodes.tracers
+local setcolor = tracers.colors.set
+local resetcolor = tracers.colors.reset
+
+local directions = typesetters.directions or { }
+typesetters.directions = directions
+
+local a_directions = attributes.private('directions')
+
+local variables = interfaces.variables
+local v_global = variables["global"]
+local v_local = variables["local"]
+local v_on = variables.on
+local v_yes = variables.yes
+
+local m_enabled = 2^6 -- 64
+local m_global = 2^7
+local m_fences = 2^8
+
+local handlers = { }
+local methods = { }
+local lastmethod = 0
local function installhandler(name,handler)
local method = methods[name]
diff --git a/tex/context/base/typo-drp.lua b/tex/context/base/typo-drp.lua
index 3a87d94b3..9151100b6 100644
--- a/tex/context/base/typo-drp.lua
+++ b/tex/context/base/typo-drp.lua
@@ -32,9 +32,8 @@ local getchar = nuts.getchar
local getid = nuts.getid
local getsubtype = nuts.getsubtype
local getfield = nuts.getfield
-local getattr = nuts.getattr
-
local setfield = nuts.setfield
+local getattr = nuts.getattr
local setattr = nuts.setattr
local hpack_nodes = nuts.hpack
diff --git a/tex/context/base/typo-dua.lua b/tex/context/base/typo-dua.lua
index 91a27a30e..7dfd7e81c 100644
--- a/tex/context/base/typo-dua.lua
+++ b/tex/context/base/typo-dua.lua
@@ -106,7 +106,7 @@ local maximum_stack = 60 -- probably spec but not needed
local directions = typesetters.directions
local setcolor = directions.setcolor
-local a_directions = attributes.private('directions')
+----- a_directions = attributes.private('directions')
local remove_controls = true directives.register("typesetters.directions.one.removecontrols",function(v) remove_controls = v end)
diff --git a/tex/context/base/typo-dub.lua b/tex/context/base/typo-dub.lua
index 4dc0f21fb..3d48f657e 100644
--- a/tex/context/base/typo-dub.lua
+++ b/tex/context/base/typo-dub.lua
@@ -65,6 +65,7 @@ local getid = nuts.getid
local getsubtype = nuts.getsubtype
local getlist = nuts.getlist
local getattr = nuts.getattr
+local setattr = nuts.setattr
local getfield = nuts.getfield
local setfield = nuts.setfield
@@ -97,11 +98,11 @@ local getfences = directions.getfences
local a_directions = attributes.private('directions')
local a_textbidi = attributes.private('textbidi')
-local a_state = attributes.private('state')
+----- a_state = attributes.private('state')
-local s_isol = fonts.analyzers.states.isol
+----- s_isol = fonts.analyzers.states.isol
--- current[a_state] = s_isol -- maybe better have a special bidi attr value -> override (9) -> todo
+----- current[a_state] = s_isol -- maybe better have a special bidi attr value -> override (9) -> todo
local remove_controls = true directives.register("typesetters.directions.removecontrols",function(v) remove_controls = v end)
----- analyze_fences = true directives.register("typesetters.directions.analyzefences", function(v) analyze_fences = v end)
diff --git a/tex/context/base/typo-fln.lua b/tex/context/base/typo-fln.lua
index 7ce41cd81..884a4c829 100644
--- a/tex/context/base/typo-fln.lua
+++ b/tex/context/base/typo-fln.lua
@@ -30,12 +30,11 @@ local tonode = nuts.tonode
local getnext = nuts.getnext
local getid = nuts.getid
local getfield = nuts.getfield
+local setfield = nuts.setfield
local getlist = nuts.getlist
local getattr = nuts.getattr
-local getbox = nuts.getbox
-
-local setfield = nuts.setfield
local setattr = nuts.setattr
+local getbox = nuts.getbox
local nodecodes = nodes.nodecodes
local glyph_code = nodecodes.glyph
diff --git a/tex/context/base/typo-fln.mkiv b/tex/context/base/typo-fln.mkiv
index d8651b459..c092fc922 100644
--- a/tex/context/base/typo-fln.mkiv
+++ b/tex/context/base/typo-fln.mkiv
@@ -79,7 +79,7 @@
\begingroup
\edef\currentfirstline{#1}%
\usefirstlinestyleandcolor\c!style\c!color
- \ctxlua{commands.setfirstline {
+ \ctxcommand{setfirstline {
alternative = "\firstlineparameter\c!alternative",
ma = \the\attribute\colormodelattribute,
ca = \the\attribute\colorattribute,
diff --git a/tex/context/base/typo-itc.lua b/tex/context/base/typo-itc.lua
index db94c5c54..7373c0321 100644
--- a/tex/context/base/typo-itc.lua
+++ b/tex/context/base/typo-itc.lua
@@ -37,6 +37,7 @@ local getid = nuts.getid
local getfont = nuts.getfont
local getchar = nuts.getchar
local getattr = nuts.getattr
+local setattr = nuts.setattr
local insert_node_after = nuts.insert_after
local delete_node = nuts.delete
diff --git a/tex/context/base/typo-krn.mkiv b/tex/context/base/typo-krn.mkiv
index 3522c02fc..92689f07b 100644
--- a/tex/context/base/typo-krn.mkiv
+++ b/tex/context/base/typo-krn.mkiv
@@ -70,7 +70,7 @@
% \definecharacterkerning [\v!letterspacing ] [\v!kerncharacters] [\c!features=letterspacing]
%
% \unexpanded\def\kerncharacters
-% {\doifnextoptionalelse\typo_kerning_apply_yes\typo_kerning_apply_nop}
+% {\doifnextoptionalcselse\typo_kerning_apply_yes\typo_kerning_apply_nop}
%
% \def\typo_kerning_apply_yes[#1]%
% {\groupedcommand{\typo_kerning_apply_yes_indeed{#1}}\donothing}
diff --git a/tex/context/base/typo-mar.lua b/tex/context/base/typo-mar.lua
index 4bfc107ad..4ea6b1e1d 100644
--- a/tex/context/base/typo-mar.lua
+++ b/tex/context/base/typo-mar.lua
@@ -76,6 +76,7 @@ if not modules then modules = { } end modules ['typo-mar'] = {
local format, validstring = string.format, string.valid
local insert, remove = table.insert, table.remove
local setmetatable, next = setmetatable, next
+local formatters = string.formatters
local attributes, nodes, node, variables = attributes, nodes, node, variables
@@ -170,6 +171,8 @@ local new_stretch = nodepool.stretch
local new_usernumber = nodepool.usernumber
local new_latelua = nodepool.latelua
+local lateluafunction = nodepool.lateluafunction
+
local texgetcount = tex.getcount
local texgetdimen = tex.getdimen
local texget = tex.get
@@ -179,13 +182,15 @@ local points = number.points
local isleftpage = layouts.status.isleftpage
local registertogether = builders.paragraphs.registertogether -- tonode
-local jobpositions = job.positions
-local getposition = jobpositions.position
-
local a_margindata = attributes.private("margindata")
local inline_mark = nodepool.userids["margins.inline"]
+local jobpositions = job.positions
+local getposition = jobpositions.get
+local setposition = jobpositions.set
+local getreserved = jobpositions.getreserved
+
local margins = { }
typesetters.margins = margins
@@ -368,6 +373,16 @@ end
local status, nofstatus = { }, 0
+local f_anchor = formatters["_plib_.set('md:h',%i,{x=true,c=true})"]
+local function setanchor(h_anchor)
+ return new_latelua(f_anchor(h_anchor))
+end
+
+-- local t_anchor = { x = true, c = true }
+-- local function setanchor(h_anchor)
+-- return lateluafunction(function() setposition("md:h",h_anchor,t_anchor) end)
+-- end
+
local function realign(current,candidate)
local location = candidate.location
local margin = candidate.margin
@@ -436,10 +451,10 @@ local function realign(current,candidate)
if inline or anchor ~= v_text or candidate.psubtype == alignment_code then
-- the alignment_code check catches margintexts ste before a tabulate
h_anchors = h_anchors + 1
- anchornode = new_latelua(format("_plib_.set('md:h',%i,{x=true,c=true})",h_anchors))
- local blob = jobpositions.get('md:h', h_anchors)
+ anchornode = setanchor(h_anchors)
+ local blob = getposition('md:h',h_anchors)
if blob then
- local reference = jobpositions.getreserved(anchor,blob.c)
+ local reference = getreserved(anchor,blob.c)
if reference then
if location == v_left then
move_x = (reference.x or 0) - (blob.x or 0)
@@ -494,25 +509,36 @@ end
-- resetstacked()
-function margins.ha(tag) -- maybe l/r keys ipv left/right keys
+local function ha(tag) -- maybe l/r keys ipv left/right keys
local p = cache[tag]
p.p = true
p.y = true
- jobpositions.set('md:v',tag,p)
+ setposition('md:v',tag,p)
cache[tag] = nil
end
-local function markovershoot(current)
+margins.ha = ha
+
+local f_anchor = formatters["typesetters.margins.ha(%s)"]
+local function setanchor(v_anchor)
+ return new_latelua(f_anchor(v_anchor))
+end
+
+-- local function setanchor(v_anchor) -- freezes the global here
+-- return lateluafunction(function() ha(v_anchor) end)
+-- end
+
+local function markovershoot(current) -- todo: alleen als offset > line
v_anchors = v_anchors + 1
cache[v_anchors] = stacked
- local anchor = new_latelua(format("typesetters.margins.ha(%s)",v_anchors)) -- todo: alleen als offset > line
+ local anchor = setanchor(v_anchors)
local list = hpack_nodes(linked_nodes(anchor,getlist(current)))
setfield(current,"list",list)
end
local function getovershoot(location)
- local p = jobpositions.get("md:v",v_anchors)
- local c = jobpositions.get("md:v",v_anchors+1)
+ local p = getposition("md:v",v_anchors)
+ local c = getposition("md:v",v_anchors+1)
if p and c and p.p and p.p == c.p then
local distance = p.y - c.y
local offset = p[location] or 0
@@ -901,3 +927,5 @@ statistics.register("margin data", function()
return nil
end
end)
+
+commands.savemargindata = margins.save
diff --git a/tex/context/base/typo-mar.mkiv b/tex/context/base/typo-mar.mkiv
index 595cf3756..2b89f5777 100644
--- a/tex/context/base/typo-mar.mkiv
+++ b/tex/context/base/typo-mar.mkiv
@@ -258,11 +258,13 @@
\fi
\ifdone
\anch_positions_initialize % we use positions at the lua end
- \ctxlua{typesetters.margins.save{
+ \ctxcommand{savemargindata{
location = "\margindataparameter\c!location",
method = "\margindataparameter\c!method",
category = "\margindataparameter\c!category",
name = "\margindataparameter\c!name",
+ scope = "\margindataparameter\c!scope",
+ number = \number\nextbox,
margin = "\margindataparameter\c!margin", % local normal margin edge
distance = \number\dimexpr\margindataparameter\c!distance,
hoffset = \number\dimexpr\margindataparameter\c!hoffset,
@@ -286,14 +288,12 @@
% \ifzeropt\leftskip \else
% rightskip = \number\rightskip,
% \fi
- scope = "\margindataparameter\c!scope",
align = "\margindataparameter\c!align",
line = \number\margindataparameter\c!line,
stack = "\margindataparameter\c!stack",
- number = \number\nextbox,
}}%
\else
- \ctxlua{typesetters.margins.save{
+ \ctxcommand{savemargindata{
location = "\margindataparameter\c!location",
method = "\margindataparameter\c!method",
category = "\margindataparameter\c!category",
diff --git a/tex/context/base/typo-prc.lua b/tex/context/base/typo-prc.lua
index a6c27ede6..959cabbb8 100644
--- a/tex/context/base/typo-prc.lua
+++ b/tex/context/base/typo-prc.lua
@@ -14,13 +14,16 @@ local lpegmatch, patterns, P, C, Cs = lpeg.match, lpeg.patterns, lpeg.P, lpeg.C,
-- processors: syntax: processor->data ... not ok yet
-typesetters.processors = typesetters.processors or { }
-local processors = typesetters.processors
+typesetters.processors = typesetters.processors or { }
+local processors = typesetters.processors
local trace_processors = false
local report_processors = logs.reporter("processors")
local registered = { }
+context_applyprocessor = context.applyprocessor
+context_firstofoneargument = context.firstofoneargument
+
trackers.register("typesetters.processors", function(v) trace_processors = v end)
function processors.register(p)
@@ -55,7 +58,7 @@ function processors.apply(p,s)
if trace_processors then
report_processors("applying %s processor %a, argument: %s","known",p,s)
end
- context.applyprocessor(p,s)
+ context_applyprocessor(p,s)
elseif s then
if trace_processors then
report_processors("applying %s processor %a, argument: %s","unknown",p,s)
@@ -78,21 +81,21 @@ function processors.startapply(p,s)
if trace_processors then
report_processors("start applying %s processor %a","known",p)
end
- context.applyprocessor(p)
+ context_applyprocessor(p)
context("{")
return s
elseif p then
if trace_processors then
report_processors("start applying %s processor %a","unknown",p)
end
- context.firstofoneargument()
+ context_firstofoneargument()
context("{")
return s
else
if trace_processors then
report_processors("start applying %s processor","ignored")
end
- context.firstofoneargument()
+ context_firstofoneargument()
context("{")
return str
end
diff --git a/tex/context/base/typo-rep.lua b/tex/context/base/typo-rep.lua
index 95b801e2e..15e3f9746 100644
--- a/tex/context/base/typo-rep.lua
+++ b/tex/context/base/typo-rep.lua
@@ -27,8 +27,8 @@ local tonode = nuts.tonode
local getnext = nuts.getnext
local getchar = nuts.getchar
local getid = nuts.getid
-local getattr = nuts.getid
+local getattr = nuts.getattr
local setattr = nuts.setattr
local delete_node = nuts.delete
diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua
index 5cf9ab837..eb84eb7d7 100644
--- a/tex/context/base/typo-spa.lua
+++ b/tex/context/base/typo-spa.lua
@@ -36,7 +36,6 @@ local getchar = nuts.getchar
local getid = nuts.getid
local getfont = nuts.getfont
local getattr = nuts.getattr
-
local setattr = nuts.setattr
local insert_node_before = nuts.insert_before
diff --git a/tex/context/base/typo-tal.lua b/tex/context/base/typo-tal.lua
index debcedfd3..3a2d80e51 100644
--- a/tex/context/base/typo-tal.lua
+++ b/tex/context/base/typo-tal.lua
@@ -29,11 +29,11 @@ local getprev = nuts.getprev
local getid = nuts.getid
local getfont = nuts.getfont
local getchar = nuts.getchar
-local getattr = nuts.getattr
local getfield = nuts.getfield
+local setfield = nuts.setfield
+local getattr = nuts.getattr
local setattr = nuts.setattr
-local setfield = nuts.setfield
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
diff --git a/tex/context/base/typo-txt.mkvi b/tex/context/base/typo-txt.mkvi
index 57f4e5f42..fa79a4f6b 100644
--- a/tex/context/base/typo-txt.mkvi
+++ b/tex/context/base/typo-txt.mkvi
@@ -17,7 +17,7 @@
\unprotect
-\registerctxluafile{typo-txt}{1.001}
+% registerctxluafile{typo-txt}{1.001}
%D \macros
%D {normalizefontheight,normalizefontwidth,normalizedfontsize}
diff --git a/tex/context/base/util-env.lua b/tex/context/base/util-env.lua
index 0a708ea43..e96a464b0 100644
--- a/tex/context/base/util-env.lua
+++ b/tex/context/base/util-env.lua
@@ -197,7 +197,7 @@ function environment.reconstructcommandline(arg,noquote)
a = resolvers.resolve(a)
a = unquoted(a)
a = gsub(a,'"','\\"') -- tricky
- if find(a," ") then
+ if find(a," ",1,true) then
result[#result+1] = quoted(a)
else
result[#result+1] = a
diff --git a/tex/context/base/util-prs.lua b/tex/context/base/util-prs.lua
index e5b35a727..2cede919b 100644
--- a/tex/context/base/util-prs.lua
+++ b/tex/context/base/util-prs.lua
@@ -179,12 +179,12 @@ function parsers.settings_to_array(str,strict)
elseif not str or str == "" then
return { }
elseif strict then
- if find(str,"{") then
+ if find(str,"{",1,true) then
return lpegmatch(pattern,str)
else
return { str }
end
- elseif find(str,",") then
+ elseif find(str,",",1,true) then
return lpegmatch(pattern,str)
else
return { str }
diff --git a/tex/context/base/util-str.lua b/tex/context/base/util-str.lua
index 4ecaed7d3..52c48badd 100644
--- a/tex/context/base/util-str.lua
+++ b/tex/context/base/util-str.lua
@@ -47,10 +47,12 @@ if not number then number = { } end -- temp hack for luatex-fonts
local stripper = patterns.stripzeros
local function points(n)
+ n = tonumber(n)
return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
end
local function basepoints(n)
+ n = tonumber(n)
return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536))
end
@@ -152,17 +154,105 @@ end
-- print(strings.tabtospace(t[k]))
-- end
-function strings.striplong(str) -- strips all leading spaces
- str = gsub(str,"^%s*","")
- str = gsub(str,"[\n\r]+ *","\n")
- return str
+-- todo: lpeg
+
+-- function strings.striplong(str) -- strips all leading spaces
+-- str = gsub(str,"^%s*","")
+-- str = gsub(str,"[\n\r]+ *","\n")
+-- return str
+-- end
+
+local newline = patterns.newline
+local endofstring = patterns.endofstring
+local whitespace = patterns.whitespace
+local spacer = patterns.spacer
+
+local space = spacer^0
+local nospace = space/""
+local endofline = nospace * newline
+
+local stripend = (whitespace^1 * endofstring)/""
+
+local normalline = (nospace * ((1-space*(newline+endofstring))^1) * nospace)
+
+local stripempty = endofline^1/""
+local normalempty = endofline^1
+local singleempty = endofline * (endofline^0/"")
+local doubleempty = endofline * endofline^-1 * (endofline^0/"")
+
+local stripstart = stripempty^0
+
+local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 )
+local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 )
+local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 )
+local p_retain_normal = Cs ( ( normalline + normalempty )^0 )
+local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 )
+local p_retain_noempty = Cs ( ( normalline + singleempty )^0 )
+
+-- function striplines(str,prune,collapse,noempty)
+-- if prune then
+-- if noempty then
+-- return lpegmatch(p_prune_noempty,str) or str
+-- elseif collapse then
+-- return lpegmatch(p_prune_collapse,str) or str
+-- else
+-- return lpegmatch(p_prune_normal,str) or str
+-- end
+-- else
+-- if noempty then
+-- return lpegmatch(p_retain_noempty,str) or str
+-- elseif collapse then
+-- return lpegmatch(p_retain_collapse,str) or str
+-- else
+-- return lpegmatch(p_retain_normal,str) or str
+-- end
+-- end
+-- end
+
+local striplinepatterns = {
+ ["prune"] = p_prune_normal,
+ ["prune and collapse"] = p_prune_collapse, -- default
+ ["prune and no empty"] = p_prune_noempty,
+ ["retain"] = p_retain_normal,
+ ["retain and collapse"] = p_retain_collapse,
+ ["retain and no empty"] = p_retain_noempty,
+}
+
+strings.striplinepatterns = striplinepatterns
+
+function strings.striplines(str,how)
+ return str and lpegmatch(how and striplinepatterns[how] or p_prune_collapse,str) or str
end
--- local template = string.striplong([[
+strings.striplong = strings.striplines -- for old times sake
+
+-- local str = table.concat( {
+-- " ",
+-- " aap",
+-- " noot mies",
+-- " ",
+-- " ",
+-- " zus wim jet",
+-- "zus wim jet",
+-- " zus wim jet",
+-- " ",
+-- }, "\n")
+
+-- local str = table.concat( {
+-- " aaaa",
+-- " bb",
+-- " cccccc",
+-- }, "\n")
+
+-- for k, v in table.sortedhash(utilities.strings.striplinepatterns) do
+-- logs.report("stripper","method: %s, result: [[%s]]",k,utilities.strings.striplines(str,k))
+-- end
+
+-- inspect(strings.striplong([[
-- aaaa
-- bb
-- cccccc
--- ]])
+-- ]]))
function strings.nice(str)
str = gsub(str,"[:%-+_]+"," ") -- maybe more
@@ -418,7 +508,7 @@ local format_i = function(f)
if f and f ~= "" then
return format("format('%%%si',a%s)",f,n)
else
- return format("format('%%i',a%s)",n)
+ return format("format('%%i',a%s)",n) -- why not just tostring()
end
end
@@ -434,6 +524,11 @@ local format_f = function(f)
return format("format('%%%sf',a%s)",f,n)
end
+local format_F = function(f)
+ n = n + 1
+ return format("((a%s == 0 and '0') or (a%s == 1 and '1') or format('%%%sf',a%s))",n,n,f,n)
+end
+
local format_g = function(f)
n = n + 1
return format("format('%%%sg',a%s)",f,n)
@@ -707,7 +802,7 @@ local builder = Cs { "start",
V("!") -- new
+ V("s") + V("q")
+ V("i") + V("d")
- + V("f") + V("g") + V("G") + V("e") + V("E")
+ + V("f") + V("F") + V("g") + V("G") + V("e") + V("E")
+ V("x") + V("X") + V("o")
--
+ V("c")
@@ -742,6 +837,7 @@ local builder = Cs { "start",
["i"] = (prefix_any * P("i")) / format_i, -- %i => regular %i (integer)
["d"] = (prefix_any * P("d")) / format_d, -- %d => regular %d (integer)
["f"] = (prefix_any * P("f")) / format_f, -- %f => regular %f (float)
+ ["F"] = (prefix_any * P("F")) / format_F, -- %F => regular %f (float) but 0/1 check
["g"] = (prefix_any * P("g")) / format_g, -- %g => regular %g (float)
["G"] = (prefix_any * P("G")) / format_G, -- %G => regular %G (float)
["e"] = (prefix_any * P("e")) / format_e, -- %e => regular %e (float)
@@ -816,7 +912,8 @@ local function make(t,str)
f = loadstripped(p)()
else
n = 0
- p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n
+ -- p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n
+ p = lpegmatch(builder,str,1,t._connector_,t._extensions_) -- after this we know n
if n > 0 then
p = format(template,preamble,t._preamble_,arguments[n],p)
-- print("builder 2 >",p)
@@ -875,22 +972,24 @@ strings.formatters = { }
-- table (metatable) in which case we could better keep a count and
-- clear that table when a threshold is reached
+-- _connector_ is an experiment
+
if _LUAVERSION < 5.2 then
- function strings.formatters.new()
- local t = { _extensions_ = { }, _preamble_ = preamble, _environment_ = { }, _type_ = "formatter" }
+ function strings.formatters.new(noconcat)
+ local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = preamble, _environment_ = { } }
setmetatable(t, { __index = make, __call = use })
return t
end
else
- function strings.formatters.new()
+ function strings.formatters.new(noconcat)
local e = { } -- better make a copy as we can overload
for k, v in next, environment do
e[k] = v
end
- local t = { _extensions_ = { }, _preamble_ = "", _environment_ = e, _type_ = "formatter" }
+ local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = "", _environment_ = e }
setmetatable(t, { __index = make, __call = use })
return t
end
diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua
index d235520c4..f9e9b318d 100644
--- a/tex/context/base/util-tab.lua
+++ b/tex/context/base/util-tab.lua
@@ -21,27 +21,29 @@ local utftoeight = utf.toeight
local splitter = lpeg.tsplitat(".")
-function tables.definetable(target,nofirst,nolast) -- defines undefined tables
- local composed, shortcut, t = nil, nil, { }
+function utilities.tables.definetable(target,nofirst,nolast) -- defines undefined tables
+ local composed, t = nil, { }
local snippets = lpegmatch(splitter,target)
for i=1,#snippets - (nolast and 1 or 0) do
local name = snippets[i]
if composed then
- composed = shortcut .. "." .. name
- shortcut = shortcut .. "_" .. name
- t[#t+1] = formatters["local %s = %s if not %s then %s = { } %s = %s end"](shortcut,composed,shortcut,shortcut,composed,shortcut)
+ composed = composed .. "." .. name
+ t[#t+1] = formatters["if not %s then %s = { } end"](composed,composed)
else
composed = name
- shortcut = name
if not nofirst then
t[#t+1] = formatters["%s = %s or { }"](composed,composed)
end
end
end
- if nolast then
- composed = shortcut .. "." .. snippets[#snippets]
+ if composed then
+ if nolast then
+ composed = composed .. "." .. snippets[#snippets]
+ end
+ return concat(t,"\n"), composed -- could be shortcut
+ else
+ return "", target
end
- return concat(t,"\n"), composed
end
-- local t = tables.definedtable("a","b","c","d")
@@ -73,7 +75,7 @@ end
function tables.migratetable(target,v,root)
local t = root or _G
- local names = string.split(target,".")
+ local names = lpegmatch(splitter,target)
for i=1,#names-1 do
local name = names[i]
t[name] = t[name] or { }
@@ -493,7 +495,8 @@ end
-- The next version is somewhat faster, although in practice one will seldom
-- serialize a lot using this one. Often the above variants are more efficient.
--- If we would really need this a lot, we could hash q keys.
+-- If we would really need this a lot, we could hash q keys, or just not used
+-- indented code.
-- char-def.lua : 0.53 -> 0.38
-- husayni.tma : 0.28 -> 0.19
diff --git a/tex/context/interface/cont-nl.xml b/tex/context/interface/cont-nl.xml
index 685033f81..4bfad3798 100644
--- a/tex/context/interface/cont-nl.xml
+++ b/tex/context/interface/cont-nl.xml
@@ -6525,7 +6525,7 @@
<cd:parameter name="maxbreedte">
<cd:constant type="cd:dimension"/>
</cd:parameter>
- <cd:parameter name="onbekendeverwijzing">
+ <cd:parameter name="onbekendereferentie">
<cd:constant type="leeg"/>
<cd:constant type="geen"/>
</cd:parameter>
@@ -8996,7 +8996,7 @@
<cd:constant type="nee"/>
<cd:constant type="geen"/>
</cd:parameter>
- <cd:parameter name="onbekendeverwijzing">
+ <cd:parameter name="onbekendereferentie">
<cd:constant type="ja"/>
<cd:constant type="leeg"/>
<cd:constant type="nee"/>
diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml
index 21536214a..c87088a09 100644
--- a/tex/context/interface/keys-nl.xml
+++ b/tex/context/interface/keys-nl.xml
@@ -950,7 +950,7 @@
<cd:constant name='reduction' value='reductie'/>
<cd:constant name='ref' value='ref'/>
<cd:constant name='refcommand' value='refcommand'/>
- <cd:constant name='reference' value='verwijzing'/>
+ <cd:constant name='reference' value='referentie'/>
<cd:constant name='referenceprefix' value='referenceprefix'/>
<cd:constant name='referencing' value='refereren'/>
<cd:constant name='region' value='gebied'/>
@@ -1100,7 +1100,7 @@
<cd:constant name='totalnumber' value='totalnumber'/>
<cd:constant name='type' value='type'/>
<cd:constant name='unit' value='eenheid'/>
- <cd:constant name='unknownreference' value='onbekendeverwijzing'/>
+ <cd:constant name='unknownreference' value='onbekendereferentie'/>
<cd:constant name='urlalternative' value='urlvariant'/>
<cd:constant name='urlspace' value='urlspatie'/>
<cd:constant name='validate' value='valideer'/>
diff --git a/tex/context/sample/cervantes-es.tex b/tex/context/sample/cervantes-es.tex
new file mode 100644
index 000000000..153797023
--- /dev/null
+++ b/tex/context/sample/cervantes-es.tex
@@ -0,0 +1,6 @@
+En un lugar de la Mancha, de cuyo nombre no quiero acordar-me, no ha
+mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga
+antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que
+carnero, salpicón las más noches, duelos y quebrantos los sábados,
+lantejas los viernes, algún palomino de añadidura los domingos,
+consumían las tres partes de su hacienda.
diff --git a/tex/context/sample/quevedo-es.tex b/tex/context/sample/quevedo-es.tex
new file mode 100644
index 000000000..166b0328f
--- /dev/null
+++ b/tex/context/sample/quevedo-es.tex
@@ -0,0 +1,19 @@
+\startlines
+Un soneto me manda hacer Violante
+que en mi vida me he visto en tanto aprieto;
+catorce versos dicen que es soneto;
+burla burlando van los tres delante.
+
+Yo pensé que no hallara consonante,
+y estoy a la mitad de otro cuarteto;
+mas si me veo en el primer terceto,
+no hay cosa en los cuartetos que me espante.
+
+Por el primer terceto voy entrando,
+y parece que entré con pie derecho,
+pues fin con este verso le voy dando.
+
+Ya estoy en el segundo, y aun sospecho
+que voy los trece versos acabando;
+contad si son catorce, y está hecho.
+\stoplines
diff --git a/tex/generic/context/luatex/luatex-fonts-inj.lua b/tex/generic/context/luatex/luatex-fonts-inj.lua
index ae48150a6..5e6c07070 100644
--- a/tex/generic/context/luatex/luatex-fonts-inj.lua
+++ b/tex/generic/context/luatex/luatex-fonts-inj.lua
@@ -11,8 +11,6 @@ if not modules then modules = { } end modules ['node-inj'] = {
-- test fonts. Btw, future versions of luatex will have extended glyph properties
-- that can be of help. Some optimizations can go away when we have faster machines.
--- todo: make a special one for context
-
local next = next
local utfchar = utf.char
@@ -108,9 +106,9 @@ function injections.setkern(current,factor,rlmode,x,tfmchr)
end
end
-function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) -- ba=baseanchor, ma=markanchor
- local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) -- the index argument is no longer used but when this
- local bound = base[a_markbase] -- fails again we should pass it
+function injections.setmark(start,base,factor,rlmode,ba,ma) -- ba=baseanchor, ma=markanchor
+ local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2])
+ local bound = base[a_markbase]
local index = 1
if bound then
local mb = marks[bound]
@@ -125,13 +123,12 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) --
report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound)
end
end
--- index = index or 1
index = index or 1
bound = #marks + 1
base[a_markbase] = bound
start[a_markmark] = bound
start[a_markdone] = index
- marks[bound] = { [index] = { dx, dy, rlmode, baseismark } }
+ marks[bound] = { [index] = { dx, dy, rlmode } }
return dx, dy, bound
end
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 3f408b96f..655aedf5e 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 : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 02/14/14 17:07:59
+-- merge date : 03/22/14 15:31:38
do -- begin closure to overcome local limits and interference
@@ -901,6 +901,36 @@ local function sortedkeys(tab)
return {}
end
end
+local function sortedhashonly(tab)
+ if tab then
+ local srt,s={},0
+ for key,_ in next,tab do
+ if type(key)=="string" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ sort(srt)
+ return srt
+ else
+ return {}
+ end
+end
+local function sortedindexonly(tab)
+ if tab then
+ local srt,s={},0
+ for key,_ in next,tab do
+ if type(key)=="number" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ sort(srt)
+ return srt
+ else
+ return {}
+ end
+end
local function sortedhashkeys(tab,cmp)
if tab then
local srt,s={},0
@@ -926,6 +956,8 @@ function table.allkeys(t)
return sortedkeys(keys)
end
table.sortedkeys=sortedkeys
+table.sortedhashonly=sortedhashonly
+table.sortedindexonly=sortedindexonly
table.sortedhashkeys=sortedhashkeys
local function nothing() end
local function sortedhash(t,cmp)
@@ -1723,7 +1755,7 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local floor=math.floor
local type=type
-if string.find(os.getenv("PATH"),";") then
+if string.find(os.getenv("PATH"),";",1,true) then
io.fileseparator,io.pathseparator="\\",";"
else
io.fileseparator,io.pathseparator="/",":"
@@ -2542,9 +2574,11 @@ end
if not number then number={} end
local stripper=patterns.stripzeros
local function points(n)
+ n=tonumber(n)
return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
end
local function basepoints(n)
+ n=tonumber(n)
return (not n or n==0) and "0bp" or lpegmatch(stripper,format("%.5fbp",n*(7200/7227)/65536))
end
number.points=points
@@ -2607,11 +2641,39 @@ local pattern=Carg(1)/function(t)
function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
-function strings.striplong(str)
- str=gsub(str,"^%s*","")
- str=gsub(str,"[\n\r]+ *","\n")
- return str
+local newline=patterns.newline
+local endofstring=patterns.endofstring
+local whitespace=patterns.whitespace
+local spacer=patterns.spacer
+local space=spacer^0
+local nospace=space/""
+local endofline=nospace*newline
+local stripend=(whitespace^1*endofstring)/""
+local normalline=(nospace*((1-space*(newline+endofstring))^1)*nospace)
+local stripempty=endofline^1/""
+local normalempty=endofline^1
+local singleempty=endofline*(endofline^0/"")
+local doubleempty=endofline*endofline^-1*(endofline^0/"")
+local stripstart=stripempty^0
+local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
+local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
+local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
+local p_retain_normal=Cs ((normalline+normalempty )^0 )
+local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
+local p_retain_noempty=Cs ((normalline+singleempty )^0 )
+local striplinepatterns={
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+}
+strings.striplinepatterns=striplinepatterns
+function strings.striplines(str,how)
+ return str and lpegmatch(how and striplinepatterns[how] or p_prune_collapse,str) or str
end
+strings.striplong=strings.striplines
function strings.nice(str)
str=gsub(str,"[:%-+_]+"," ")
return str
@@ -2777,7 +2839,7 @@ local format_i=function(f)
if f and f~="" then
return format("format('%%%si',a%s)",f,n)
else
- return format("format('%%i',a%s)",n)
+ return format("format('%%i',a%s)",n)
end
end
local format_d=format_i
@@ -2789,6 +2851,10 @@ local format_f=function(f)
n=n+1
return format("format('%%%sf',a%s)",f,n)
end
+local format_F=function(f)
+ n=n+1
+ return format("((a%s == 0 and '0') or (a%s == 1 and '1') or format('%%%sf',a%s))",n,n,f,n)
+end
local format_g=function(f)
n=n+1
return format("format('%%%sg',a%s)",f,n)
@@ -3003,7 +3069,7 @@ local builder=Cs { "start",
(
P("%")/""*(
V("!")
-+V("s")+V("q")+V("i")+V("d")+V("f")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
++V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
+V("N")
@@ -3023,6 +3089,7 @@ local builder=Cs { "start",
["i"]=(prefix_any*P("i"))/format_i,
["d"]=(prefix_any*P("d"))/format_d,
["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
["g"]=(prefix_any*P("g"))/format_g,
["G"]=(prefix_any*P("G"))/format_G,
["e"]=(prefix_any*P("e"))/format_e,
@@ -3070,7 +3137,7 @@ local function make(t,str)
f=loadstripped(p)()
else
n=0
- p=lpegmatch(builder,str,1,"..",t._extensions_)
+ p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
if n>0 then
p=format(template,preamble,t._preamble_,arguments[n],p)
f=loadstripped(p,t._environment_)()
@@ -3086,18 +3153,18 @@ local function use(t,fmt,...)
end
strings.formatters={}
if _LUAVERSION<5.2 then
- function strings.formatters.new()
- local t={ _extensions_={},_preamble_=preamble,_environment_={},_type_="formatter" }
+ function strings.formatters.new(noconcat)
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
setmetatable(t,{ __index=make,__call=use })
return t
end
else
- function strings.formatters.new()
+ function strings.formatters.new(noconcat)
local e={}
for k,v in next,environment do
e[k]=v
end
- local t={ _extensions_={},_preamble_="",_environment_=e,_type_="formatter" }
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
setmetatable(t,{ __index=make,__call=use })
return t
end
@@ -6504,7 +6571,7 @@ local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
otf.glists={ "gsub","gpos" }
-otf.version=2.751
+otf.version=2.755
otf.cache=containers.define("fonts","otf",otf.version,true)
local fontdata=fonts.hashes.identifiers
local chardata=characters and characters.data
@@ -7047,15 +7114,22 @@ actions["prepare glyphs"]=function(data,filename,raw)
local glyph=cidglyphs[index]
if glyph then
local unicode=glyph.unicode
+if unicode>=0x00E000 and unicode<=0x00F8FF then
+ unicode=-1
+elseif unicode>=0x0F0000 and unicode<=0x0FFFFD then
+ unicode=-1
+elseif unicode>=0x100000 and unicode<=0x10FFFD then
+ unicode=-1
+end
local name=glyph.name or cidnames[index]
- if not unicode or unicode==-1 or unicode>=criterium then
+ if not unicode or unicode==-1 then
unicode=cidunicodes[index]
end
if unicode and descriptions[unicode] then
report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode)
unicode=-1
end
- if not unicode or unicode==-1 or unicode>=criterium then
+ if not unicode or unicode==-1 then
if not name then
name=format("u%06X",private)
end
@@ -7101,7 +7175,7 @@ actions["prepare glyphs"]=function(data,filename,raw)
if glyph then
local unicode=glyph.unicode
local name=glyph.name
- if not unicode or unicode==-1 or unicode>=criterium then
+ if not unicode or unicode==-1 then
unicode=private
unicodes[name]=private
if trace_private then
@@ -7156,47 +7230,43 @@ actions["check encoding"]=function(data,filename,raw)
local unicodetoindex=mapdata and mapdata.map or {}
local indextounicode=mapdata and mapdata.backmap or {}
local encname=lower(data.enc_name or mapdata.enc_name or "")
- local criterium=0xFFFF
+ local criterium=0xFFFF
+ local privateoffset=constructors.privateoffset
if find(encname,"unicode") then
if trace_loading then
report_otf("checking embedded unicode map %a",encname)
end
- local hash={}
- for index,unicode in next,indices do
- hash[index]=descriptions[unicode]
- end
- local reported={}
- for unicode,index in next,unicodetoindex do
- if not descriptions[unicode] then
- local d=hash[index]
+ local reported={}
+ for maybeunicode,index in next,unicodetoindex do
+ if descriptions[maybeunicode] then
+ else
+ local unicode=indices[index]
+ if not unicode then
+ elseif maybeunicode==unicode then
+ elseif unicode>privateoffset then
+ else
+ local d=descriptions[unicode]
if d then
- if d.unicode~=unicode then
- local c=d.copies
- if c then
- c[unicode]=true
- else
- d.copies={ [unicode]=true }
- end
+ local c=d.copies
+ if c then
+ c[maybeunicode]=true
+ else
+ d.copies={ [maybeunicode]=true }
end
- elseif not reported[i] then
+ elseif index and not reported[index] then
report_otf("missing index %i",index)
- reported[i]=true
+ reported[index]=true
end
end
end
- for index,data in next,hash do
- data.copies=sortedkeys(data.copies)
- end
- for index,unicode in next,indices do
- local description=hash[index]
- local copies=description.copies
- if copies then
- duplicates[unicode]=copies
- description.copies=nil
- else
- report_otf("copies but no unicode parent %U",unicode)
- end
+ end
+ for unicode,data in next,descriptions do
+ local d=data.copies
+ if d then
+ duplicates[unicode]=sortedkeys(d)
+ data.copies=nil
end
+ end
elseif properties.cidinfo then
report_otf("warning: no unicode map, used cidmap %a",properties.cidinfo.usedname)
else
@@ -7238,7 +7308,7 @@ actions["add duplicates"]=function(data,filename,raw)
end
end
end
- if u>0 then
+ if u>0 then
local duplicate=table.copy(description)
duplicate.comment=format("copy of U+%05X",unicode)
descriptions[u]=duplicate
@@ -7440,10 +7510,16 @@ actions["reorganize subtables"]=function(data,filename,raw)
report_otf("skipping weird lookup number %s",k)
elseif features then
local f={}
+ local o={}
for i=1,#features do
local df=features[i]
local tag=strip(lower(df.tag))
- local ft=f[tag] if not ft then ft={} f[tag]=ft end
+ local ft=f[tag]
+ if not ft then
+ ft={}
+ f[tag]=ft
+ o[#o+1]=tag
+ end
local dscripts=df.scripts
for i=1,#dscripts do
local d=dscripts[i]
@@ -7463,6 +7539,7 @@ actions["reorganize subtables"]=function(data,filename,raw)
subtables=subtables,
markclass=markclass,
features=f,
+ order=o,
}
else
lookups[name]={
@@ -8908,8 +8985,9 @@ basemethods.shared={
basemethod="independent"
local function featuresinitializer(tfmdata,value)
if true then
- local t=trace_preparing and os.clock()
+ local starttime=trace_preparing and os.clock()
local features=tfmdata.shared.features
+ local fullname=trace_preparing and tfmdata.properties.fullname
if features then
applybasemethod("initializehashes",tfmdata)
local collectlookups=otf.collectlookups
@@ -8919,26 +8997,34 @@ local function featuresinitializer(tfmdata,value)
local language=properties.language
local basesubstitutions=rawdata.resources.features.gsub
local basepositionings=rawdata.resources.features.gpos
- if basesubstitutions then
- for feature,data in next,basesubstitutions do
- local value=features[feature]
- if value then
- local validlookups,lookuplist=collectlookups(rawdata,feature,script,language)
- if validlookups then
- applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist)
- registerbasefeature(feature,value)
- end
- end
- end
- end
- if basepositionings then
- for feature,data in next,basepositionings do
- local value=features[feature]
- if value then
- local validlookups,lookuplist=collectlookups(rawdata,feature,script,language)
- if validlookups then
- applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist)
- registerbasefeature(feature,value)
+ if basesubstitutions or basepositionings then
+ local sequences=tfmdata.resources.sequences
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local sfeatures=sequence.features
+ if sfeatures then
+ local order=sequence.order
+ if order then
+ for i=1,#order do
+ local feature=order[i]
+ if features[feature] then
+ local validlookups,lookuplist=collectlookups(rawdata,feature,script,language)
+ if not validlookups then
+ elseif basesubstitutions and basesubstitutions[feature] then
+ if trace_preparing then
+ report_prepare("filtering base feature %a for %a",feature,fullname)
+ end
+ applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ elseif basepositionings and basepositionings[feature] then
+ if trace_preparing then
+ report_prepare("filtering base feature %a for %a",feature,fullname)
+ end
+ applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ end
+ end
+ end
end
end
end
@@ -8946,7 +9032,7 @@ local function featuresinitializer(tfmdata,value)
registerbasehash(tfmdata)
end
if trace_preparing then
- report_prepare("preparation time is %0.3f seconds for %a",os.clock()-t,tfmdata.properties.fullname)
+ report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname)
end
end
end
@@ -9042,9 +9128,9 @@ function injections.setkern(current,factor,rlmode,x,tfmchr)
return 0,0
end
end
-function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark)
- local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2])
- local bound=base[a_markbase]
+function injections.setmark(start,base,factor,rlmode,ba,ma)
+ local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2])
+ local bound=base[a_markbase]
local index=1
if bound then
local mb=marks[bound]
@@ -9063,7 +9149,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark)
base[a_markbase]=bound
start[a_markmark]=bound
start[a_markdone]=index
- marks[bound]={ [index]={ dx,dy,rlmode,baseismark } }
+ marks[bound]={ [index]={ dx,dy,rlmode } }
return dx,dy,bound
end
local function dir(n)
@@ -11413,9 +11499,12 @@ local autofeatures=fonts.analyzers.features
local function initialize(sequence,script,language,enabled)
local features=sequence.features
if features then
- for kind,scripts in next,features do
+ local order=features.order
+ for i=1,#order do
+ local kind=order[i]
local valid=enabled[kind]
if valid then
+ local scripts=features[kind]
local languages=scripts[script] or scripts[wildcard]
if languages and (languages[language] or languages[wildcard]) then
return { valid,autofeatures[kind] or false,sequence.chain or 0,kind,sequence }
@@ -11447,12 +11536,12 @@ function otf.dataset(tfmdata,font)
}
rs[language]=rl
local sequences=tfmdata.resources.sequences
-for s=1,#sequences do
- local v=enabled and initialize(sequences[s],script,language,enabled)
- if v then
- rl[#rl+1]=v
- end
-end
+ for s=1,#sequences do
+ local v=enabled and initialize(sequences[s],script,language,enabled)
+ if v then
+ rl[#rl+1]=v
+ end
+ end
end
return rl
end
@@ -12479,6 +12568,14 @@ local function packdata(data)
features[script]=pack_normal(feature)
end
end
+ local order=sequence.order
+ if order then
+ sequence.order=pack_indexed(order)
+ end
+ local markclass=sequence.markclass
+ if markclass then
+ sequence.markclass=pack_boolean(markclass)
+ end
end
end
local lookups=resources.lookups
@@ -12891,6 +12988,20 @@ local function unpackdata(data)
end
end
end
+ local order=feature.order
+ if order then
+ local tv=tables[order]
+ if tv then
+ feature.order=tv
+ end
+ end
+ local markclass=feature.markclass
+ if markclass then
+ local tv=tables[markclass]
+ if tv then
+ feature.markclass=tv
+ end
+ end
end
end
local lookups=resources.lookups
diff --git a/tex/generic/context/luatex/luatex-fonts-otn.lua b/tex/generic/context/luatex/luatex-fonts-otn.lua
index c57be5f02..9d3253f2c 100644
--- a/tex/generic/context/luatex/luatex-fonts-otn.lua
+++ b/tex/generic/context/luatex/luatex-fonts-otn.lua
@@ -2038,9 +2038,12 @@ local autofeatures = fonts.analyzers.features -- was: constants
local function initialize(sequence,script,language,enabled)
local features = sequence.features
if features then
- for kind, scripts in next, features do
+ local order = features.order
+ for i=1,#order do
+ local kind = order[i] --
local valid = enabled[kind]
if valid then
+ local scripts = features[kind] --
local languages = scripts[script] or scripts[wildcard]
if languages and (languages[language] or languages[wildcard]) then
return { valid, autofeatures[kind] or false, sequence.chain or 0, kind, sequence }
@@ -2074,19 +2077,12 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context
}
rs[language] = rl
local sequences = tfmdata.resources.sequences
--- setmetatableindex(rl, function(t,k)
--- if type(k) == "number" then
--- local v = enabled and initialize(sequences[k],script,language,enabled)
--- t[k] = v
--- return v
--- end
--- end)
-for s=1,#sequences do
- local v = enabled and initialize(sequences[s],script,language,enabled)
- if v then
- rl[#rl+1] = v
- end
-end
+ for s=1,#sequences do
+ local v = enabled and initialize(sequences[s],script,language,enabled)
+ if v then
+ rl[#rl+1] = v
+ end
+ end
end
return rl
end