summaryrefslogtreecommitdiff
path: root/tex/context
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2014-05-03 13:55:33 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2014-05-03 13:55:33 +0200
commit4fac60d85ade0f051d411be40d5502f360a28402 (patch)
tree3b6b52514c9c2cb779ed659f2daec23d6c6e2b79 /tex/context
parent088de88944c1f2254250bb448c7371a87ff7ee39 (diff)
downloadcontext-4fac60d85ade0f051d411be40d5502f360a28402.tar.gz
2014-04-28 23:25:00
Diffstat (limited to 'tex/context')
-rw-r--r--tex/context/base/anch-pos.lua66
-rw-r--r--tex/context/base/attr-ini.lua69
-rw-r--r--tex/context/base/attr-ini.mkiv70
-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.mkiv4
-rw-r--r--tex/context/base/bibl-bib.lua2
-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.lua37
-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 -> 4061 bytes
-rw-r--r--tex/context/base/context.mkiv8
-rw-r--r--tex/context/base/core-con.lua8
-rw-r--r--tex/context/base/core-env.mkiv30
-rw-r--r--tex/context/base/core-ini.mkiv7
-rw-r--r--tex/context/base/core-sys.lua2
-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/data-sch.lua2
-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-afm.lua12
-rw-r--r--tex/context/base/font-chk.lua49
-rw-r--r--tex/context/base/font-chk.mkiv9
-rw-r--r--tex/context/base/font-con.lua9
-rw-r--r--tex/context/base/font-ctx.lua712
-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.mkvi6
-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.lua109
-rw-r--r--tex/context/base/font-otf.lua133
-rw-r--r--tex/context/base/font-otn.lua196
-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-lua.lua11
-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.lua793
-rw-r--r--tex/context/base/lpdf-col.lua97
-rw-r--r--tex/context/base/lpdf-fld.lua194
-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.lua494
-rw-r--r--tex/context/base/lpdf-mis.lua80
-rw-r--r--tex/context/base/lpdf-mov.lua14
-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.lua7
-rw-r--r--tex/context/base/lpdf-wid.lua46
-rw-r--r--tex/context/base/lpdf-xmp.lua37
-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-env.lua14
-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-ini.mkiv1
-rw-r--r--tex/context/base/lxml-lpt.lua55
-rw-r--r--tex/context/base/lxml-tex.lua163
-rw-r--r--tex/context/base/m-scite.mkiv269
-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.mkiv37
-rw-r--r--tex/context/base/math-noa.lua5
-rw-r--r--tex/context/base/math-rad.mkvi8
-rw-r--r--tex/context/base/meta-fnt.lua4
-rw-r--r--tex/context/base/meta-ini.mkiv5
-rw-r--r--tex/context/base/meta-pdf.lua4
-rw-r--r--tex/context/base/meta-tex.mkiv6
-rw-r--r--tex/context/base/mlib-ctx.lua6
-rw-r--r--tex/context/base/mlib-ctx.mkiv1
-rw-r--r--tex/context/base/mlib-lua.lua185
-rw-r--r--tex/context/base/mlib-pdf.lua56
-rw-r--r--tex/context/base/mlib-pps.lua55
-rw-r--r--tex/context/base/mlib-pps.mkiv29
-rw-r--r--tex/context/base/mlib-run.lua43
-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.lua10
-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.lua2
-rw-r--r--tex/context/base/node-ini.mkiv7
-rw-r--r--tex/context/base/node-inj.lua20
-rw-r--r--tex/context/base/node-ltp.lua4
-rw-r--r--tex/context/base/node-met.lua2
-rw-r--r--tex/context/base/node-nut.lua56
-rw-r--r--tex/context/base/node-ppt.lua476
-rw-r--r--tex/context/base/node-ref.lua92
-rw-r--r--tex/context/base/node-res.lua106
-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-lin.lua172
-rw-r--r--tex/context/base/page-lin.mkvi (renamed from tex/context/base/page-lin.mkiv)461
-rw-r--r--tex/context/base/page-mix.lua121
-rw-r--r--tex/context/base/page-mix.mkiv7
-rw-r--r--tex/context/base/page-mul.mkiv2
-rw-r--r--tex/context/base/page-run.mkiv26
-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.lua22
-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.mkiv5
-rw-r--r--tex/context/base/s-math-repertoire.mkiv5
-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-ali.mkiv34
-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.lua199
-rw-r--r--tex/context/base/spac-ver.mkiv36
-rw-r--r--tex/context/base/status-files.pdfbin24795 -> 24625 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin226993 -> 242466 bytes
-rw-r--r--tex/context/base/status-mkiv.lua11
-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.mkvi29
-rw-r--r--tex/context/base/strc-lab.mkiv28
-rw-r--r--tex/context/base/strc-lst.lua35
-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.mkvi30
-rw-r--r--tex/context/base/strc-num.lua9
-rw-r--r--tex/context/base/strc-num.mkiv266
-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.lua968
-rw-r--r--tex/context/base/strc-ref.mkvi15
-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.mkiv81
-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.mkiv20
-rw-r--r--tex/context/base/syst-con.lua44
-rw-r--r--tex/context/base/syst-ini.mkiv2
-rw-r--r--tex/context/base/syst-lua.lua44
-rw-r--r--tex/context/base/tabl-ntb.mkiv1
-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.lua5
-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.lua158
-rw-r--r--tex/context/base/trac-inf.lua29
-rw-r--r--tex/context/base/trac-log.lua8
-rw-r--r--tex/context/base/trac-vis.lua68
-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-imp-texgyre.mkiv15
-rw-r--r--tex/context/base/type-ini.mkvi12
-rw-r--r--tex/context/base/typo-brk.lua11
-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.lua19
-rw-r--r--tex/context/base/typo-dub.lua24
-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-sci.lua262
-rw-r--r--tex/context/base/util-str.lua125
-rw-r--r--tex/context/base/util-tab.lua25
-rw-r--r--tex/context/fonts/texgyre.lfg6
-rw-r--r--tex/context/interface/cont-nl.xml4
-rw-r--r--tex/context/interface/keys-nl.xml4
-rw-r--r--tex/context/patterns/lang-it.lua9
-rw-r--r--tex/context/patterns/lang-it.pat7
-rw-r--r--tex/context/patterns/lang-it.rme3
-rw-r--r--tex/context/sample/cervantes-es.tex6
-rw-r--r--tex/context/sample/quevedo-es.tex19
251 files changed, 9022 insertions, 4361 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-ini.lua b/tex/context/base/attr-ini.lua
index ad4081681..1e518467c 100644
--- a/tex/context/base/attr-ini.lua
+++ b/tex/context/base/attr-ini.lua
@@ -38,13 +38,13 @@ storage.register("attributes/names", names, "attributes.names")
storage.register("attributes/numbers", numbers, "attributes.numbers")
storage.register("attributes/list", list, "attributes.list")
-function attributes.define(name,number) -- at the tex end
- if not numbers[name] then
- numbers[name] = number
- names[number] = name
- list[number] = { }
- end
-end
+-- function attributes.define(name,number) -- at the tex end
+-- if not numbers[name] then
+-- numbers[name] = number
+-- names[number] = name
+-- list[number] = { }
+-- end
+-- end
--[[ldx--
<p>We reserve this one as we really want it to be always set (faster).</p>
@@ -58,33 +58,14 @@ are only used when no attribute is set at the \TEX\ end which normally
happens in <l n='context'/>.</p>
--ldx]]--
-sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or 127
-
--- to be considered (so that we can use an array access):
---
--- local private = { } attributes.private = private
---
--- setmetatable(private, {
--- __index = function(t,name)
--- local number = sharedstorage.attributes_last_private
--- if number < 1023 then -- texgetcount("minallocatedattribute") - 1
--- number = number + 1
--- sharedstorage.attributes_last_private = number
--- end
--- numbers[name], names[number], list[number] = number, name, { }
--- private[name] = number
--- return number
--- end,
--- __call = function(t,name)
--- return t[name]
--- end
--- } )
+sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or 127
+sharedstorage.attributes_last_public = sharedstorage.attributes_last_public or 1024
function attributes.private(name) -- at the lua end (hidden from user)
local number = numbers[name]
if not number then
local last = sharedstorage.attributes_last_private
- if last < 1023 then -- texgetcount("minallocatedattribute") - 1
+ if last < 1023 then
last = last + 1
sharedstorage.attributes_last_private = last
else
@@ -97,6 +78,29 @@ function attributes.private(name) -- at the lua end (hidden from user)
return number
end
+function attributes.public(name) -- at the lua end (hidden from user)
+ local number = numbers[name]
+ if not number then
+ local last = sharedstorage.attributes_last_public
+ if last < 65535 then
+ last = last + 1
+ sharedstorage.attributes_last_public = last
+ else
+ report_attribute("no more room for public attributes")
+ os.exit()
+ end
+ number = last
+ numbers[name], names[number], list[number] = number, name, { }
+ end
+ return number
+end
+
+attributes.system = attributes.private
+
+function attributes.define(name,number,category)
+ return (attributes[category or "public"] or attributes["public"])(name,number)
+end
+
-- tracers
local report_attribute = logs.reporter("attributes")
@@ -124,11 +128,10 @@ end
-- interface
-commands.defineattribute = attributes.define
-commands.showattributes = attributes.showcurrent
+commands.showattributes = attributes.showcurrent
-function commands.getprivateattribute(name)
- context(attributes.private(name))
+function commands.defineattribute(name,category)
+ context(attributes.define(name,category))
end
-- rather special
diff --git a/tex/context/base/attr-ini.mkiv b/tex/context/base/attr-ini.mkiv
index 3f49e67a9..0c5762534 100644
--- a/tex/context/base/attr-ini.mkiv
+++ b/tex/context/base/attr-ini.mkiv
@@ -40,31 +40,51 @@
\newtoks \attributesresetlist
-\ifdefined \s!global \else \def\s!global{global} \fi % for metatex % or hard check later
-\ifdefined \s!public \else \def\s!public{public} \fi % for metatex % or hard check later
-
-\unexpanded\def\defineattribute
- {\dodoubleempty\attr_basics_define}
-
-\def\attr_basics_define[#1][#2]% alternatively we can let lua do the housekeeping
- {\expandafter\newattribute\csname\??attributecount#1\endcsname
- \expandafter\newconstant \csname\??attributeid#1\endcsname
- \csname\??attributeid#1\endcsname\c_syst_last_allocated_attribute
- \ctxcommand{defineattribute("#1",\number\c_syst_last_allocated_attribute)}%
- \doifnotinset\s!global{#2}{\appendetoks\csname\??attributecount#1\endcsname\attributeunsetvalue\to\attributesresetlist}%
- \doifinset \s!public{#2}{\expandafter\let\csname#1attribute\expandafter\endcsname\csname\??attributeid#1\endcsname}}
-
-\unexpanded\def\definesystemattribute
- {\dodoubleempty\attr_basics_define_system}
-
-\def\attr_basics_define_system[#1][#2]% alternatively we can let lua do the housekeeping
- {\scratchcounter\ctxcommand{getprivateattribute("#1")}\relax
- \expandafter\attributedef\csname\??attributecount#1\endcsname\scratchcounter
- \expandafter\newconstant \csname\??attributeid#1\endcsname
- \csname\??attributeid#1\endcsname\scratchcounter
- %\writestatus\m!system{defining system attribute #1 with number \number\scratchcounter}%
- \doifnotinset\s!global{#2}{\appendetoks\csname\??attributecount#1\endcsname\attributeunsetvalue\to\attributesresetlist}%
- \doifinset \s!public{#2}{\expandafter\let\csname#1attribute\expandafter\endcsname\csname\??attributeid#1\endcsname}}
+\ifdefined \s!global \else \def\s!global {global} \fi % for metatex % or hard check later
+\ifdefined \s!public \else \def\s!public {public} \fi % for metatex % or hard check later
+\ifdefined \s!attribute \else \def\s!attribute{attribute} \fi % for metatex % or hard check later
+
+% \unexpanded\def\defineattribute
+% {\dodoubleempty\attr_basics_define}
+%
+% \unexpanded\def\definesystemattribute
+% {\dodoubleempty\attr_basics_define_system}
+%
+% \def\attr_basics_define[#1]%
+% {\expandafter\newattribute\csname\??attributecount#1\endcsname
+% \expandafter\newconstant \csname\??attributeid#1\endcsname
+% \csname\??attributeid#1\endcsname\c_syst_last_allocated_attribute
+% \ctxcommand{defineattribute("#1",\number\csname\??attributeid#1\endcsname)}%
+% \attr_basics_define_properties[#1]}
+%
+% \def\attr_basics_define_system[#1]%
+% {\scratchcounter\ctxcommand{getprivateattribute("#1")}\relax
+% \expandafter\attributedef\csname\??attributecount#1\endcsname\scratchcounter
+% \expandafter\newconstant \csname\??attributeid#1\endcsname
+% \csname\??attributeid#1\endcsname\scratchcounter
+% %\writestatus\m!system{defining system attribute #1 with number \number\scratchcounter}%
+% \attr_basics_define_properties[#1]}
+%
+% \def\attr_basics_define_properties[#1][#2]%
+% {\doifnotinset\s!global{#2}{\appendetoks\csname\??attributecount#1\endcsname\attributeunsetvalue\to\attributesresetlist}%
+% \doifinset \s!public{#2}{\expandafter\let\csname#1\s!attribute\expandafter\endcsname\csname\??attributeid#1\endcsname}}
+
+\unexpanded\def\defineattribute {\dodoubleempty\attr_basics_define}
+\unexpanded\def\definesystemattribute{\dodoubleempty\attr_basics_define_system}
+
+\def\attr_basics_define {\attr_basics_define_indeed{public}}
+\def\attr_basics_define_system{\attr_basics_define_indeed{private}}
+
+\def\attr_basics_define_indeed#1[#2][#3]%
+ {\scratchcounter\ctxcommand{defineattribute("#2","#1")}\relax
+ %\writestatus\m!system{defining #1 attribute #2 with number \number\scratchcounter}%
+ \expandafter\attributedef\csname\??attributecount#2\endcsname\scratchcounter
+ \expandafter\newconstant \csname\??attributeid#2\endcsname
+ \csname\??attributeid#2\endcsname\scratchcounter
+ \doifnotinset\s!global{#3}{\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\attributesresetlist}%
+ \doifinset \s!public{#3}{\expandafter\let\csname#2\s!attribute\expandafter\endcsname\csname\??attributeid#2\endcsname}}
+
+\unexpanded\def\newattribute#1{\attr_basics_define_indeed{public}[\strippedcsname#1][]}
% expandable so we can \edef them for speed
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..df9594507 100644
--- a/tex/context/base/back-pdf.mkiv
+++ b/tex/context/base/back-pdf.mkiv
@@ -18,8 +18,8 @@
\registerctxluafile{lpdf-nod}{1.001}
\registerctxluafile{lpdf-col}{1.000}
\registerctxluafile{lpdf-xmp}{1.001}
-\registerctxluafile{lpdf-mis}{1.001}
\registerctxluafile{lpdf-ano}{1.001}
+\registerctxluafile{lpdf-mis}{1.001}
\registerctxluafile{lpdf-ren}{1.001}
\registerctxluafile{lpdf-grp}{1.001}
\registerctxluafile{lpdf-wid}{1.001}
@@ -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-bib.lua b/tex/context/base/bibl-bib.lua
index 65ca1f9e1..baeb3d2f9 100644
--- a/tex/context/base/bibl-bib.lua
+++ b/tex/context/base/bibl-bib.lua
@@ -105,7 +105,7 @@ local spacing = space^0
local equal = P("=")
local collapsed = (space^1)/ " "
-local function add(a,b) if b then return a..b else return a end end
+----- function add(a,b) if b then return a..b else return a end end
local keyword = C((R("az","AZ","09") + S("@_:-"))^1) -- C((1-space)^1)
local s_quoted = ((escape*single) + collapsed + (1-single))^0
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..84532f072 100644
--- a/tex/context/base/buff-ini.lua
+++ b/tex/context/base/buff-ini.lua
@@ -12,9 +12,9 @@ local sub, format = string.sub, string.format
local splitlines, validstring = string.splitlines, string.valid
local P, Cs, patterns, lpegmatch = lpeg.P, lpeg.Cs, lpeg.patterns, lpeg.match
-local trace_run = false trackers .register("buffers.run", function(v) trace_run = v end)
-local trace_grab = false trackers .register("buffers.grab", function(v) trace_grab = v end)
-local trace_visualize = false trackers .register("buffers.visualize", function(v) trace_visualize = v end)
+local trace_run = false trackers.register("buffers.run", function(v) trace_run = v end)
+local trace_grab = false trackers.register("buffers.grab", function(v) trace_grab = v end)
+local trace_visualize = false trackers.register("buffers.visualize", function(v) trace_visualize = v end)
local report_buffers = logs.reporter("buffers","usage")
local report_typeset = logs.reporter("buffers","typeset")
@@ -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..e3df6f7bf 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.04.28 23:24}
%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..6450c43f1 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..e1ade2ba1 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.04.28 23:24}
\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,7 +296,9 @@
\loadmarkfile{pack-pos}
\loadmkvifile{page-mak}
-\loadmarkfile{page-lin}
+\loadmarkfile{strc-reg} % uses mixed columns
+
+\loadmkvifile{page-lin}
\loadmarkfile{page-par}
\loadmarkfile{typo-pag}
\loadmarkfile{typo-mar}
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..ca134e230 100644
--- a/tex/context/base/core-env.mkiv
+++ b/tex/context/base/core-env.mkiv
@@ -232,21 +232,21 @@
%D \starttyping
%D \enablemode[two]
%D
-%D \startmodes
+%D \startmodeset
%D [one] {1}
%D [two] {2}
%D [two] {2}
%D [three] {3}
%D [default] {?}
-%D \stopmodes
+%D \stopmodeset
%D
-%D \startmodes
+%D \startmodeset
%D [one] {1}
%D [three] {3}
%D [default] {?}
-%D \stopmodes
+%D \stopmodeset
%D
-%D \startmodes
+%D \startmodeset
%D [one] {
%D \input tufte
%D }
@@ -265,7 +265,7 @@
%D [default] {
%D \input ward
%D }
-%D \stopmodes
+%D \stopmodeset
%D \stoptyping
\newconditional\c_syst_modes_set_done % conditionals can be pushed/popped
@@ -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-ini.mkiv b/tex/context/base/core-ini.mkiv
index 1682bed1b..711c43f94 100644
--- a/tex/context/base/core-ini.mkiv
+++ b/tex/context/base/core-ini.mkiv
@@ -58,14 +58,21 @@
\newtoks \everyforgetall
\newtoks \everycleanupfeatures
\newtoks \everysimplifycommands
+\newtoks \everypreroll
\let\simplifiedcommands\everysimplifycommands % backward compatible, will stay as it's used in styles
+\newconditional\simplifyingcommands % public
+
\unexpanded\def\forgetall {\the\everyforgetall}
\unexpanded\def\cleanupfeatures {\the\everycleanupfeatures}
\unexpanded\def\simplifycommands{\the\everysimplifycommands}
\appendtoks
+ \settrue\simplifyingcommands
+\to \everysimplifycommands
+
+\appendtoks
\everypar\emptytoks % pretty important
\to \everyforgetall
diff --git a/tex/context/base/core-sys.lua b/tex/context/base/core-sys.lua
index 009ec16ea..22b0e457c 100644
--- a/tex/context/base/core-sys.lua
+++ b/tex/context/base/core-sys.lua
@@ -94,7 +94,7 @@ statistics.register("result saved in file", function()
-- suffix will be fetched from backend
local outputfilename = environment.outputfilename or environment.jobname or tex.jobname or "<unset>"
if tex.pdfoutput > 0 then
- return format("%s.%s, compresslevel %s, objectcompreslevel %s",outputfilename,"pdf",tex.pdfcompresslevel, tex.pdfobjcompresslevel)
+ return format("%s.%s, compresslevel %s, objectcompresslevel %s",outputfilename,"pdf",tex.pdfcompresslevel, tex.pdfobjcompresslevel)
else
return format("%s.%s",outputfilename,"dvi") -- hard to imagine
end
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/data-sch.lua b/tex/context/base/data-sch.lua
index 41b941c5a..adc774489 100644
--- a/tex/context/base/data-sch.lua
+++ b/tex/context/base/data-sch.lua
@@ -54,7 +54,7 @@ end
local cached, loaded, reused, thresholds, handlers = { }, { }, { }, { }, { }
local function runcurl(name,cachename) -- we use sockets instead or the curl library when possible
- local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name
+ local command = "curl --silent --insecure --create-dirs --output " .. cachename .. " " .. name
os.spawn(command)
end
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-afm.lua b/tex/context/base/font-afm.lua
index adb4281b2..46ea8a423 100644
--- a/tex/context/base/font-afm.lua
+++ b/tex/context/base/font-afm.lua
@@ -15,6 +15,14 @@ n='otf'/>.</p>
<p>The following code still has traces of intermediate font support
where we handles font encodings. Eventually font encoding goes
away.</p>
+
+<p>The embedding of a font involves creating temporary files and
+depending on your system setup that can fail. It took more than a
+day to figure out why sometimes embedding failed in mingw luatex
+where running on a real path like c:\... failed while running on
+say e:\... being a link worked well. The native windows binaries
+don't have this issue.</p>
+
--ldx]]--
local fonts, logs, trackers, containers, resolvers = fonts, logs, trackers, containers, resolvers
@@ -221,6 +229,7 @@ local function get_indexes(data,pfbname)
report_afm("getting index data from %a",pfbname)
end
for index, glyph in next, glyphs do
+ -- for index, glyph in table.sortedhash(glyphs) do
local name = glyph.name
if name then
local char = characters[name]
@@ -336,6 +345,7 @@ function afm.load(filename)
get_indexes(data,pfbname)
elseif trace_loading then
report_afm("no pfb file for %a",filename)
+ -- data.resources.filename = "unset" -- better than loading the afm file
end
report_afm("unifying %a",filename)
unify(data,filename)
@@ -410,7 +420,7 @@ unify = function(data, filename)
if unicode then
krn[unicode] = kern
else
- print(unicode,name)
+ -- print(unicode,name)
end
end
description.kerns = krn
diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua
index 5d4f6059b..591d59d65 100644
--- a/tex/context/base/font-chk.lua
+++ b/tex/context/base/font-chk.lua
@@ -9,6 +9,8 @@ if not modules then modules = { } end modules ['font-chk'] = {
-- possible optimization: delayed initialization of vectors
-- move to the nodes namespace
+local next = next
+
local formatters = string.formatters
local bpfactor = number.dimenfactors.bp
local fastcopy = table.fastcopy
@@ -32,6 +34,8 @@ local getprivatenode = helpers.getprivatenode
local otffeatures = fonts.constructors.newfeatures("otf")
local registerotffeature = otffeatures.register
+local afmfeatures = fonts.constructors.newfeatures("afm")
+local registerafmfeature = afmfeatures.register
local is_character = characters.is_character
local chardata = characters.data
@@ -159,7 +163,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
@@ -403,3 +407,46 @@ local function expandglyph(characters,index,done)
end
helpers.expandglyph = expandglyph
+
+-- should not be needed as we add .notdef in the engine
+
+local dummyzero = {
+ -- width = 0,
+ -- height = 0,
+ -- depth = 0,
+ commands = { { "special", "" } },
+}
+
+local function adddummysymbols(tfmdata,...)
+ local characters = tfmdata.characters
+ if not characters[0] then
+ characters[0] = dummyzero
+ end
+ -- if not characters[1] then
+ -- characters[1] = dummyzero -- test only
+ -- end
+end
+
+registerotffeature {
+ name = "dummies",
+ description = "dummy symbols",
+ default = true,
+ manipulators = {
+ base = adddummysymbols,
+ node = adddummysymbols,
+ }
+}
+
+registerafmfeature {
+ name = "dummies",
+ description = "dummy symbols",
+ default = true,
+ manipulators = {
+ base = adddummysymbols,
+ node = adddummysymbols,
+ }
+}
+
+-- callback.register("char_exists",function(f,c) -- to slow anyway as called often so we should flag in tfmdata
+-- return true
+-- end)
diff --git a/tex/context/base/font-chk.mkiv b/tex/context/base/font-chk.mkiv
index d436388de..4572041c2 100644
--- a/tex/context/base/font-chk.mkiv
+++ b/tex/context/base/font-chk.mkiv
@@ -15,6 +15,15 @@
\registerctxluafile{font-chk}{1.001}
+\tracinglostchars\zerocount
+
+% Use this instead:
+%
+% \definefontfeature[default][default][missing=yes]
+% \enabletrackers[fonts.missing=replace]
+%
+% or better:
+
\unexpanded\def\checkcharactersinfont {\ctxcommand{checkcharactersinfont()}}
\unexpanded\def\removemissingcharacters {\ctxcommand{removemissingcharacters()}}
\unexpanded\def\replacemissingcharacters{\ctxcommand{replacemissingcharacters()}}
diff --git a/tex/context/base/font-con.lua b/tex/context/base/font-con.lua
index 09293895e..b43961ec6 100644
--- a/tex/context/base/font-con.lua
+++ b/tex/context/base/font-con.lua
@@ -290,14 +290,15 @@ constructors.nofsharedfonts = 0
local sharednames = { }
function constructors.trytosharefont(target,tfmdata)
- if constructors.sharefonts then
+ if constructors.sharefonts then -- not robust !
local characters = target.characters
local n = 1
local t = { target.psname }
local u = sortedkeys(characters)
for i=1,#u do
+ local k = u[i]
n = n + 1 ; t[n] = k
- n = n + 1 ; t[n] = characters[u[i]].index or k
+ n = n + 1 ; t[n] = characters[k].index or k
end
local h = md5.HEX(concat(t," "))
local s = sharednames[h]
@@ -452,8 +453,6 @@ function constructors.scale(tfmdata,specification)
target.psname = psname
target.name = name
--
- -- inspect(properties)
- --
properties.fontname = fontname
properties.fullname = fullname
properties.filename = filename
@@ -826,7 +825,6 @@ function constructors.scale(tfmdata,specification)
end
targetcharacters[unicode] = chr
end
-
--
constructors.aftercopyingcharacters(target,tfmdata)
--
@@ -965,6 +963,7 @@ function constructors.finalize(tfmdata)
--
properties.finalized = true
--
+ --
return tfmdata
end
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
index e251cc9c1..2bfcf3859 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,50 @@ 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
+ local k = u[i]
+ n = n + 1 ; t[n] = k
+ n = n + 1 ; t[n] = characters[k].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 +506,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 +823,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 +840,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 +954,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 +1540,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 +1572,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 +1592,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 +1610,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 +1782,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 +1867,7 @@ end
-- end
function commands.setfontofid(id)
- context.getvalue(csnames[id])
+ context_getvalue(csnames[id])
end
-- more interfacing:
@@ -1911,7 +1943,6 @@ end
-- a fontkern plug:
-
local copy_node = nuts.copy
local kern = nuts.pool.register(nuts.pool.kern())
@@ -1967,7 +1998,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 +2054,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..c1e6d9390 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\fontface\!!plusfour
+% \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\fontface\!!plusfive
+% \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..bfd85245c 100644
--- a/tex/context/base/font-lib.mkvi
+++ b/tex/context/base/font-lib.mkvi
@@ -38,7 +38,11 @@
\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
+
+\doiffileelse{font-inj.lua}
+ {\registerctxluafile{font-inj}{1.001}} % new method (for the moment only local)
+ {\registerctxluafile{node-inj}{1.001}} % old method
+
%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..2dd23b741 100644
--- a/tex/context/base/font-otd.lua
+++ b/tex/context/base/font-otd.lua
@@ -129,59 +129,66 @@ 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 e_e
- local a_e = a_enabled and a_enabled[kind] -- the value (location)
- if a_e ~= nil then
- e_e = a_e
- else
- e_e = s_enabled and s_enabled[kind] -- the value (font)
- end
- if e_e then
- local languages = scripts[script] or scripts[wildcard]
- if languages then
- -- local valid, what = false
- local valid = false
- -- not languages[language] or languages[default] or languages[wildcard] because we want tracing
- -- only first attribute match check, so we assume simple fina's
- -- default can become a font feature itself
- if languages[language] then
- valid = e_e -- was true
- -- what = language
- -- elseif languages[default] then
- -- valid = true
- -- what = default
- elseif languages[wildcard] then
- valid = e_e -- was true
- -- what = wildcard
- end
- if valid then
- local attribute = autofeatures[kind] or false
- -- if a_e and dynamic < 0 then
- -- valid = false
- -- end
- -- if trace_applied then
- -- local typ, action = match(sequence.type,"(.*)_(.*)") -- brrr
- -- report_process(
- -- "%s font: %03i, dynamic: %03i, kind: %s, script: %-4s, language: %-4s (%-4s), type: %s, action: %s, name: %s",
- -- (valid and "+") or "-",font,attr or 0,kind,script,language,what,typ,action,sequence.name)
- -- end
- if trace_applied then
- report_process(
- "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)
+ local order = sequence.order
+ if order then
+ 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
+ e_e = a_e
+ else
+ 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
+ local valid = false
+ -- not languages[language] or languages[default] or languages[wildcard] because we want tracing
+ -- only first attribute match check, so we assume simple fina's
+ -- default can become a font feature itself
+ if languages[language] then
+ valid = e_e -- was true
+ -- what = language
+ -- elseif languages[default] then
+ -- valid = true
+ -- what = default
+ elseif languages[wildcard] then
+ valid = e_e -- was true
+ -- what = wildcard
+ end
+ if valid then
+ local attribute = autofeatures[kind] or false
+ -- if a_e and dynamic < 0 then
+ -- valid = false
+ -- end
+ -- if trace_applied then
+ -- local typ, action = match(sequence.type,"(.*)_(.*)") -- brrr
+ -- report_process(
+ -- "%s font: %03i, dynamic: %03i, kind: %s, script: %-4s, language: %-4s (%-4s), type: %s, action: %s, name: %s",
+ -- (valid and "+") or "-",font,attr or 0,kind,script,language,what,typ,action,sequence.name)
+ -- end
+ if trace_applied then
+ report_process(
+ "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
+ ra[#ra+1] = { valid, attribute, sequence.chain or 0, kind, sequence }
end
- return { valid, attribute, sequence.chain or 0, kind, sequence }
end
end
end
+ -- { valid, attribute, chain, "generic", sequence } -- false anyway, could be flag instead of table
+ else
+ -- can't happen
end
- return false -- { 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 +256,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..25c750ae8 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,14 +2053,21 @@ 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 valid = enabled[kind]
- if valid then
- 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 }
+ local order = sequence.order
+ if order then
+ 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 }
+ end
end
end
+ else
+ -- can't happen
end
end
return false
@@ -2101,19 +2096,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 +2129,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 +2251,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 +2287,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 +2314,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 +2412,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 +2460,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 +2495,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-lua.lua b/tex/context/base/l-lua.lua
index 4a96b0b1d..9565f484a 100644
--- a/tex/context/base/l-lua.lua
+++ b/tex/context/base/l-lua.lua
@@ -6,6 +6,17 @@ if not modules then modules = { } end modules ['l-lua'] = {
license = "see context related readme files"
}
+-- potential issues with 5.3:
+
+-- i'm not sure yet if the int/float change is good for luatex
+
+-- math.min
+-- math.max
+-- tostring
+-- tonumber
+-- utf.*
+-- bit32
+
-- compatibility hacksand helpers
local major, minor = string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
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..827c43ec6 100644
--- a/tex/context/base/lpdf-ano.lua
+++ b/tex/context/base/lpdf-ano.lua
@@ -10,46 +10,66 @@ 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 <autoprefix><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 log_destinations = false directives.register("destinations.log", function(v) log_destinations = 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 v_auto = variables.auto
+local v_page = variables.page
+
+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 usedviews = references.usedviews
+
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 +83,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
@@ -79,102 +104,417 @@ local pdf_t = pdfconstant("T")
local pdf_fit = pdfconstant("Fit")
local pdf_named = pdfconstant("Named")
-local pdf_border = pdfarray { 0, 0, 0 }
+local autoprefix = "#"
-local cache = { }
+-- Bah, I hate this kind of features .. anyway, as we have delayed resolving we
+-- only support a document-wide setup and it has to be set before the first one
+-- is used. Also, we default to a non-intrusive gray and the outline is kept
+-- thin without dashing lines. This is as far as I'm prepared to go. This way
+-- it can also be used as a debug feature.
-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
+local pdf_border_style = pdfarray { 0, 0, 0 } -- radius radius linewidth
+local pdf_border_color = nil
+local set_border = false
+
+function pdfborder()
+ border_set = true
+ return pdf_border_style, pdf_border_color
+end
+
+lpdf.border = pdfborder
+
+directives.register("references.border",function(v)
+ if v and not set_border then
+ if type(v) == "string" then
+ local m = attributes.list[attributes.private('color')] or { }
+ local c = m and m[v]
+ local v = c and attributes.colors.value(c)
+ if v then
+ local r, g, b = v[3], v[4], v[5]
+ -- if r == g and g == b then
+ -- pdf_border_color = pdfarray { r } -- reduced, not not ... bugged viewers
+ -- else
+ pdf_border_color = pdfarray { r, g, b } -- always rgb
+ -- end
+ end
end
- return pd
+ if not pdf_border_color then
+ pdf_border_color = pdfarray { .6, .6, .6 } -- no reduce to { 0.6 } as there are buggy viewers out there
+ end
+ pdf_border_style = pdfarray { 0, 0, .5 } -- < 0.5 is not show by acrobat (at least not in my version)
end
-end
+end)
+
+-- 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
+
+-- the caching is somewhat memory intense on the one hand but
+-- it saves many small temporary tables so it might pay off
+
+local pagedestinations = allocate()
+local pagereferences = allocate() -- annots are cached themselves
-lpdf.pagedestination = pagedestination
+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 }
-local function link(url,filename,destination,page,actions)
- if filename and filename ~= "" then
- if file.basename(filename) == tex.jobname then
- return false
- else
- filename = file.addsuffix(filename,"pdf")
+-- 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
+
+luatex.registerstopactions(function()
+ if log_destinations and next(destinations) then
+ local logsnewline = logs.newline
+ local log_destinations = logs.reporter("system","references")
+ local log_destination = logs.reporter("destination")
+ logs.pushtarget("logfile")
+ logsnewline()
+ log_destinations("start used destinations")
+ logsnewline()
+ local n = 0
+ for destination, pagenumber in table.sortedhash(destinations) do
+ log_destination("% 4i : %-5s : %s",pagenumber,usedviews[destination] or defaultview,destination)
+ n = n + 1
+ end
+ logsnewline()
+ log_destinations("stop used destinations")
+ logsnewline()
+ logs.poptarget()
+ report_destination("%s destinations saved in log file",n)
+ end
+end)
+
+
+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]
+ local pagenumber = destinations[destination]
+ names[#names+1] = destination
+ names[#names+1] = pdfreference(pagenumber)
+ 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 url and url ~= "" then
- if filename and filename ~= "" then
- if destination and destination ~= "" then
- url = file.join(url,filename).."#"..destination
+ 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
- url = file.join(url,filename)
+ return pdfreference(pdfflushobject(collectkids(slices,1,#slices)))
end
end
- return pdfdictionary {
- S = pdf_uri,
- URI = url,
- }
- elseif filename and filename ~= "" then
- -- no page ?
- if destination == "" then
+ end
+end
+
+local function pdfdestinationspecification()
+ if next(destinations) then -- safeguard
+ local r = pdfnametree(destinations)
+ -- pdfaddtocatalog("Dests",r)
+ pdfaddtonames("Dests",r)
+ if not log_destinations then
+ destinations = nil
+ end
+ end
+end
+
+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 ] ] >>"]
+
+local v_standard = variables.standard
+local v_frame = variables.frame
+local v_width = variables.width
+local v_minwidth = variables.minwidth
+local v_height = variables.height
+local v_minheight = variables.minheight
+local v_fit = variables.fit
+local v_tight = variables.tight
+
+-- nicer is to create dictionaries and set properties but it's a bit overkill
+
+local destinationactions = {
+ [v_standard] = function(r,w,h,d) return f_xyz (r,pdfrectangle(w,h,d)) end, -- local left,top with zoom (0 in our case)
+ [v_frame] = function(r,w,h,d) return f_fitr (r,pdfrectangle(w,h,d)) end, -- fit rectangle in window
+ [v_width] = function(r,w,h,d) return f_fith (r, gethpos() *factor) end, -- top coordinate, fit width of page in window
+ [v_minwidth] = function(r,w,h,d) return f_fitbh(r, gethpos() *factor) end, -- top coordinate, fit width of content in window
+ [v_height] = function(r,w,h,d) return f_fitv (r,(getvpos()+h)*factor) end, -- left coordinate, fit height of page in window
+ [v_minheight] = function(r,w,h,d) return f_fitbv(r,(getvpos()+h)*factor) end, -- left coordinate, fit height of content in window
+ [v_fit] = f_fit, -- fit page in window
+ [v_tight] = f_fitb, -- fit content in window
+}
+
+local mapping = {
+ [v_standard] = v_standard, xyz = v_standard,
+ [v_frame] = v_frame, fitr = v_frame,
+ [v_width] = v_width, fith = v_width,
+ [v_minwidth] = v_minwidth, fitbh = v_minwidth,
+ [v_height] = v_height, fitv = v_height,
+ [v_minheight] = v_minheight, fitbv = v_minheight,
+ [v_fit] = v_fit, fit = v_fit,
+ [v_tight] = v_tight, fitb = v_tight,
+}
+
+local defaultview = v_fit
+local defaultaction = destinationactions[defaultview]
+
+-- 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 == defaultview 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
+ view = view and mapping[view] or defaultview
+ if trace_destinations then
+ report_destination("width %p, height %p, depth %p, names %|t, view %a",width,height,depth,names,view)
+ end
+ local method = references.innermethod
+ local noview = view == defaultview
+ local doview = false
+ -- we could save some aut's by using a name when given but it doesn't pay off apart
+ -- from making the code messy and tracing hard .. we only save some destinations
+ -- which we already share anyway
+ for n=1,#names do
+ local name = names[n]
+ if usedviews[name] then
+ -- already done, maybe a warning
+ elseif type(name) == "number" then
+ if noview then
+ usedviews[name] = view
+ names[n] = false
+ elseif method == v_page then
+ usedviews[name] = view
+ names[n] = false
+ else
+ local used = usedinternals[name]
+ if used and used ~= defaultview then
+ usedviews[name] = view
+ names[n] = autoprefix .. name
+ doview = true
+ end
+ end
+ elseif method == v_page then
+ usedviews[name] = view
+ else
+ usedviews[name] = view
+ doview = true
+ end
+ end
+ if doview then
+ return latelua_function_node(function() flushdestination(width,height,depth,names,view) end)
+ end
+end
+
+-- we could share dictionaries ... todo
+
+local function somedestination(destination,internal,page) -- no view anyway
+ if references.innermethod ~= v_page then
+ if type(destination) == "number" then
+ if not internal then
+ internal = destination
+ end
destination = nil
end
- if not destination and page then
- destination = pdfarray { page - 1, pdf_fit }
+ if internal then
+ flaginternals[internal] = true -- for bookmarks and so
+ local used = usedinternals[internal]
+ if used == defaultview or used == true then
+ return pagereferences[page]
+ end
+ if type(destination) ~= "string" then
+ destination = autoprefix .. internal
+ end
+ return pdfdictionary {
+ S = pdf_goto,
+ D = destination,
+ }
end
- return pdfdictionary {
- S = pdf_gotor, -- can also be pdf_launch
- F = filename,
- D = destination or defaultdestination, -- D is mandate
- 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
+ if destination then
+ -- hopefully this one is flushed
+ return pdfdictionary {
S = pdf_goto,
- D = pdfarray {
- pdfreference(pdfpagereference(p)),
- pdf_fit,
- }
+ D = destination,
}
- elseif trace_references then
- report_reference("invalid page reference %a",page)
end
end
- return false
+ return pagereferences[page]
end
-lpdf.link = link
+-- annotations
-function lpdf.launch(program,parameters)
- if program and program ~= "" then
- local d = pdfdictionary {
- S = pdf_launch,
- F = program,
- D = ".",
- }
- if parameters and parameters ~= "" then
- d.P = parameters
- end
- return d
+local pdflink = somedestination
+
+local function pdffilelink(filename,destination,page,actions)
+ if not filename or filename == "" or file.basename(filename) == tex.jobname then
+ return false
+ end
+ filename = file.addsuffix(filename,"pdf")
+ if not destination or destination == "" then
+ destination = pdfarray { (page or 0) - 1, pdf_fit }
end
+ return pdfdictionary {
+ S = pdf_gotor, -- can also be pdf_launch
+ F = filename,
+ D = destination or defaultdestination, -- D is mandate
+ NewWindow = actions.newwindow and true or nil,
+ }
end
-function lpdf.javascript(name,arguments)
+local function pdfurllink(url,destination,page)
+ if not url or url == "" then
+ return false
+ end
+ if destination and destination ~= "" then
+ url = url .. "#" .. destination
+ end
+ return pdfdictionary {
+ S = pdf_uri,
+ URI = url,
+ }
+end
+
+local function pdflaunch(program,parameters)
+ if not program or program == "" then
+ return false
+ end
+ return pdfdictionary {
+ S = pdf_launch,
+ F = program,
+ D = ".",
+ P = parameters ~= "" and parameters or nil
+ }
+end
+
+local function pdfjavascript(name,arguments)
local script = javascriptcode(name,arguments) -- make into object (hash)
if script then
return pdfdictionary {
@@ -219,9 +559,11 @@ function codeinjections.prerollreference(actions) -- share can become option
if actions then
local main, n = pdfaction(actions)
if main then
- main = pdfdictionary {
+ local bs, bc = pdfborder()
+ main = pdfdictionary {
Subtype = pdf_link,
- Border = pdf_border,
+ Border = bs,
+ C = bc,
H = (not actions.highlight and pdf_n) or nil,
A = pdfshareobjectreference(main),
F = 4, -- print (mandate in pdf/a)
@@ -231,157 +573,146 @@ 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 hashed = { }
+local nofunique = 0
+local nofused = 0
+local nofspecial = 0
+local share = true
-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 f_annot = formatters["<< /Type /Annot %s /Rect [ %0.3F %0.3F %0.3F %0.3F ] >>"]
-local function use_shared_annotations()
+directives.register("refences.sharelinks", function(v) share = v end)
- local factor = number.dimenfactors.bp
-
- 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 inner = nil
+ if references.innermethod == v_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
+ local reference = vir.reference
+ if reference and reference ~= "" then
+ var.inner = reference
+ local prefix = var.p
+ if prefix and prefix ~= "" then
+ var.prefix = prefix
+ inner = prefix .. ":" .. reference
+ else
+ inner = reference
+ end
+ end
internal = vir.internal
if internal then
- var.inner = "aut:" .. internal
+ flaginternals[internal] = true
end
end
end
else
var.inner = nil
end
- local prefix = var.p
- local inner = var.inner
- if not internal and inner and prefix and prefix ~= "" then
- -- no prefix with e.g. components
- inner = prefix .. ":" .. inner
- end
- return link(nil,nil,inner,var.r,actions)
+ return pdflink(inner,internal,var.r)
end
runners["inner with arguments"] = function(var,actions)
@@ -391,12 +722,15 @@ end
runners["outer"] = function(var,actions)
local file, url = references.checkedfileorurl(var.outer,var.outer)
- return link(url,file,var.arguments,nil,actions)
+ if file then
+ return pdffilelink(file,var.arguments,nil,actions)
+ elseif url then
+ return pdfurllink(url,var.arguments,nil,actions)
+ end
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 pdffilelink(references.checkedfile(var.outer),var.inner,var.r,actions)
end
runners["special outer with operation"] = function(var,actions)
@@ -443,12 +777,9 @@ 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
+ return pdflink(nil,i,v.references.realpage)
end
end
@@ -461,8 +792,7 @@ local pages = references.pages
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 pdffilelink(references.checkedfile(file),nil,var.operation,actions)
else
local p = var.r
if not p then -- todo: call special from reference code
@@ -472,29 +802,24 @@ function specials.page(var,actions)
else
p = references.realpageofpage(tonumber(p))
end
- -- if p then
- -- var.r = p
- -- end
end
- return link(nil,nil,nil,p or var.operation,actions)
+ return pdflink(nil,nil,p or var.operation)
end
end
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 pdffilelink(references.checkedfile(file),nil,var.operation,actions)
else
- return link(nil,nil,nil,var.operation,actions)
+ return pdflink(nil,nil,var.operation)
end
end
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 pdffilelink(references.checkedfile(file),nil,var.operation,actions)
else
local p = var.r
if not p then -- todo: call special from reference code
@@ -506,7 +831,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,p or var.operation)
end
end
@@ -514,7 +839,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,p)
end
end
@@ -554,27 +879,29 @@ function specials.order(var,actions) -- references.specials !
end
function specials.url(var,actions)
- local url = references.checkedurl(var.operation)
- return link(url,nil,var.arguments,nil,actions)
+ return pdfurllink(references.checkedurl(var.operation),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 pdffilelink(references.checkedfile(var.operation),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)
+ if file then
+ return pdffilelink(file,var.arguments,nil,actions)
+ elseif url then
+ return pdfurllink(url,var.arguments,nil,actions)
+ end
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 +1025,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
@@ -727,12 +1049,9 @@ local function build(levels,start,parent,method)
Title = pdfunicode(title),
Parent = parent,
Prev = prev and pdfreference(prev),
+ A = somedestination(reference.internal,reference.internal,reference.realpage),
}
- 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.internal,reference.realpage)
if not first then first, last = child, child end
prev = child
last = prev
@@ -771,10 +1090,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..9e483f9b5 100644
--- a/tex/context/base/lpdf-col.lua
+++ b/tex/context/base/lpdf-col.lua
@@ -14,42 +14,49 @@ 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 pdfdelayedobject = lpdf.delayedobject
+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
@@ -76,11 +83,13 @@ lpdf.transparencygroups = transparencygroups
table.setmetatableindex(transparencygroups, function(transparencygroups,colormodel)
local cs = colorspaceconstants[colormodel]
if cs then
- local g = pdfreference(pdfflushobject(pdfdictionary {
+ local d = pdfdictionary {
S = c_transparency,
CS = cs,
I = true,
- }))
+ }
+ -- local g = pdfreference(pdfflushobject(tostring(d)))
+ local g = pdfreference(pdfdelayedobject(tostring(d)))
transparencygroups[colormodel] = g
return g
else
@@ -95,7 +104,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 +233,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 +289,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 +345,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 +464,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 +479,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 +698,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..414562ad5 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"
@@ -570,17 +619,14 @@ local function todingbat(n)
end
end
--- local zero_bc = pdfarray { 0, 0, 0 }
--- local zero_bg = pdfarray { 1, 1, 1 }
-
local function fieldrendering(specification)
local bvalue = tonumber(specification.backgroundcolorvalue)
local fvalue = tonumber(specification.framecolorvalue)
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 +636,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 +657,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 +958,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 +967,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 +1015,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..a89b8b8c5 100644
--- a/tex/context/base/lpdf-ini.lua
+++ b/tex/context/base/lpdf-ini.lua
@@ -9,35 +9,178 @@ 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
-local pdfreserveobject = pdf.reserveobj
-local pdfimmediateobject = pdf.immediateobj
-local pdfdeferredobject = pdf.obj
-local pdfreferenceobject = pdf.refobj
+local report_objects = logs.reporter("backend","objects")
+local report_finalizing = logs.reporter("backend","finalizing")
+local report_blocked = logs.reporter("backend","blocked")
+
+-- gethpos : used
+-- getpos : used
+-- getvpos : used
+--
+-- getmatrix : used
+-- hasmatrix : used
+--
+-- mapfile : used in font-ctx.lua
+-- mapline : used in font-ctx.lua
+--
+-- maxobjnum : not used
+-- obj : used
+-- immediateobj : used
+-- objtype : not used
+-- pageref : used
+-- print : can be used
+-- refobj : used
+-- registerannot : not to be used
+-- reserveobj : used
+
+-- pdf.catalog : used
+-- pdf.info : used
+-- pdf.trailer : used
+-- pdf.names : not to be used
+
+-- pdf.setinfo : used
+-- pdf.setcatalog : used
+-- pdf.setnames : not to be used
+-- pdf.settrailer : used
+
+-- pdf.getinfo : used
+-- pdf.getcatalog : used
+-- pdf.getnames : not to be used
+-- pdf.gettrailer : used
+
+local pdf = pdf
+local factor = number.dimenfactors.bp
+
+if pdf.setinfo then
+-- table.setmetatablenewindex(pdf,function(t,k,v)
+-- report_blocked("'pdf.%s' is not supported",k)
+-- end)
+ -- the getters are harmless
+end
+
+if not pdf.setinfo then
+ function pdf.setinfo (s) pdf.info = s end
+ function pdf.setcatalog(s) pdf.catalog = s end
+ function pdf.setnames (s) pdf.names = s end
+ function pdf.settrailer(s) pdf.trailer = s end
+end
+
+if not pdf.getpos then
+ function pdf.getpos () return pdf.h, pdf.v end
+ function pdf.gethpos () return pdf.h end
+ function pdf.getvpos () return pdf.v end
+ function pdf.hasmatrix() return false end
+ function pdf.getmatrix() return 1, 0, 0, 1, 0, 0 end
+end
+
+if not pdf.setpageresources then
+ function pdf.setpageresources (s) pdf.pageresources = s end
+ function pdf.setpageattributes (s) pdf.pageattributes = s end
+ function pdf.setpagesattributes(s) pdf.pagesattributes = s end
+end
+
+local pdfsetinfo = pdf.setinfo
+local pdfsetcatalog = pdf.setcatalog
+local pdfsetnames = pdf.setnames
+local pdfsettrailer = pdf.settrailer
+
+local pdfsetpageresources = pdf.setpageresources
+local pdfsetpageattributes = pdf.setpageattributes
+local pdfsetpagesattributes = pdf.setpagesattributes
+
+local pdfgetpos = pdf.getpos
+local pdfgethpos = pdf.gethpos
+local pdfgetvpos = pdf.getvpos
+local pdfgetmatrix = pdf.getmatrix
+local pdfhasmatrix = pdf.hasmatrix
+
+local pdfreserveobject = pdf.reserveobj
+local pdfimmediateobject = pdf.immediateobj
+local pdfdeferredobject = pdf.obj
+local pdfreferenceobject = pdf.refobj
+
+function pdf.setinfo () report_blocked("'pdf.%s' is not supported","setinfo") end -- use lpdf.addtoinfo etc
+function pdf.setcatalog () report_blocked("'pdf.%s' is not supported","setcatalog") end
+function pdf.setnames () report_blocked("'pdf.%s' is not supported","setnames") end
+function pdf.settrailer () report_blocked("'pdf.%s' is not supported","settrailer") end
+function pdf.setpageresources () report_blocked("'pdf.%s' is not supported","setpageresources") end
+function pdf.setpageattributes () report_blocked("'pdf.%s' is not supported","setpageattributes") end
+function pdf.setpagesattributes() report_blocked("'pdf.%s' is not supported","setpagesattributes") end
+
+function pdf.registerannot() report_blocked("'pdf.%s' is not supported","registerannot") end
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)
local trace_detail = false trackers.register("backend.detail", function(v) trace_detail = v end)
-local report_objects = logs.reporter("backend","objects")
-local report_finalizing = logs.reporter("backend","finalizing")
-
-local backends = backends
-
-backends.pdf = backends.pdf or {
+local backends = backends
+local pdfbackend = {
comment = "backend for directly generating pdf output",
nodeinjections = { },
codeinjections = { },
registrations = { },
tables = { },
}
+backends.pdf = pdfbackend
+lpdf = lpdf or { }
+local lpdf = lpdf
+
+local codeinjections = pdfbackend.codeinjections
+local nodeinjections = pdfbackend.nodeinjections
+
+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
-lpdf = lpdf or { }
-local lpdf = lpdf
+-- 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 +234,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 +255,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 +293,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 +332,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 +352,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 +470,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 +505,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 +525,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.delayedobject(data) -- we will get rid of this one
- local n = pdfdeferredobject(data)
+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,n)
+ if n then
+ pdfdeferredobject(n,data)
+ else
+ n = pdfdeferredobject(data)
+ end
pdfreferenceobject(n)
return n
end
@@ -484,60 +644,10 @@ 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 = { { }, { }, { } }, { { }, { }, { } }
+local pagefinalizers = { { }, { }, { } }
+local documentfinalizers = { { }, { }, { } }
local pageresources, pageattributes, pagesattributes
@@ -550,9 +660,9 @@ end
resetpageproperties()
local function setpageproperties()
- pdf.pageresources = pageresources ()
- pdf.pageattributes = pageattributes ()
- pdf.pagesattributes = pagesattributes()
+ pdfsetpageresources (pageresources ())
+ pdfsetpageattributes (pageattributes ())
+ pdfsetpagesattributes(pagesattributes())
end
local function addtopageresources (k,v) pageresources [k] = v end
@@ -606,8 +716,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 +735,27 @@ function lpdf.finalizedocument()
end
end
-backends.pdf.codeinjections.finalizepage = lpdf.finalizepage -- will go when we have hook
+-- 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 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
@@ -647,15 +775,34 @@ lpdf.protectresources = true
local catalog = pdfdictionary { Type = pdfconstant("Catalog") } -- nicer, but when we assign we nil the Type
local info = pdfdictionary { Type = pdfconstant("Info") } -- nicer, but when we assign we nil the Type
-local names = pdfdictionary { Type = pdfconstant("Names") } -- nicer, but when we assign we nil the Type
+----- names = pdfdictionary { Type = pdfconstant("Names") } -- nicer, but when we assign we nil the Type
-local function flushcatalog() if not environment.initex then trace_flush("catalog") catalog.Type = nil pdf.catalog = catalog() end end
-local function flushinfo () if not environment.initex then trace_flush("info") info .Type = nil pdf.info = info () end end
-local function flushnames () if not environment.initex then trace_flush("names") names .Type = nil pdf.names = names () end end
+local function flushcatalog() if not environment.initex then trace_flush("catalog") catalog.Type = nil pdfsetcatalog(catalog()) end end
+local function flushinfo () if not environment.initex then trace_flush("info") info .Type = nil pdfsetinfo (info ()) end end
+-------------- flushnames () if not environment.initex then trace_flush("names") names .Type = nil pdfsetnames (names ()) end end
function lpdf.addtocatalog(k,v) if not (lpdf.protectresources and catalog[k]) then trace_set("catalog",k) catalog[k] = v end end
function lpdf.addtoinfo (k,v) if not (lpdf.protectresources and info [k]) then trace_set("info", k) info [k] = v end end
-function lpdf.addtonames (k,v) if not (lpdf.protectresources and names [k]) then trace_set("names", k) names [k] = v end end
+-------- lpdf.addtonames (k,v) if not (lpdf.protectresources and names [k]) then trace_set("names", k) names [k] = v end end
+
+local names = pdfdictionary {
+ -- Type = pdfconstant("Names")
+}
+
+local function flushnames()
+ if next(names) and not environment.initex then
+ names.Type = pdfconstant("Names")
+ trace_flush("names")
+ lpdf.addtocatalog("Names",pdfreference(pdfimmediateobject(tostring(names))))
+ end
+end
+
+function lpdf.addtonames(k,v)
+ if not (lpdf.protectresources and names [k]) then
+ trace_set("names", k)
+ names [k] = v
+ end
+end
local dummy = pdfreserveobject() -- else bug in hvmd due so some internal luatex conflict
@@ -705,9 +852,9 @@ registerdocumentfinalizer(flushcolorspaces,3,"color spaces")
registerdocumentfinalizer(flushpatterns,3,"patterns")
registerdocumentfinalizer(flushshades,3,"shades")
+registerdocumentfinalizer(flushnames,3,"names") -- before catalog
registerdocumentfinalizer(flushcatalog,3,"catalog")
registerdocumentfinalizer(flushinfo,3,"info")
-registerdocumentfinalizer(flushnames,3,"names") -- before catalog
registerpagefinalizer(checkextgstates,3,"extended graphic states")
registerpagefinalizer(checkcolorspaces,3,"color spaces")
@@ -718,7 +865,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 +942,56 @@ 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
+-- 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
-end
+-- setmetatable(pdf, {
+-- __index = function(t,k)
+-- if k == "info" then return pdf.getinfo()
+-- elseif k == "catalog" then return pdf.getcatalog()
+-- elseif k == "names" then return pdf.getnames()
+-- elseif k == "trailer" then return pdf.gettrailer()
+-- elseif k == "pageattribute" then return pdf.getpageattribute()
+-- elseif k == "pageattributes" then return pdf.getpageattributes()
+-- elseif k == "pageresources" then return pdf.getpageresources()
+-- elseif
+-- return nil
+-- end
+-- end,
+-- __newindex = function(t,k,v)
+-- if k == "info" then return pdf.setinfo(v)
+-- elseif k == "catalog" then return pdf.setcatalog(v)
+-- elseif k == "names" then return pdf.setnames(v)
+-- elseif k == "trailer" then return pdf.settrailer(v)
+-- elseif k == "pageattribute" then return pdf.setpageattribute(v)
+-- elseif k == "pageattributes" then return pdf.setpageattributes(v)
+-- elseif k == "pageresources" then return pdf.setpageresources(v)
+-- else
+-- rawset(t,k,v)
+-- 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..87375e4ce 100644
--- a/tex/context/base/lpdf-mov.lua
+++ b/tex/context/base/lpdf-mov.lua
@@ -11,10 +11,10 @@ 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
+local pdfborder = lpdf.border
local write_node = node.write
function nodeinjections.insertmovie(specification)
@@ -31,14 +31,16 @@ function nodeinjections.insertmovie(specification)
ShowControls = (specification.controls and true) or false,
Mode = (specification["repeat"] and pdfconstant("Repeat")) or nil,
}
+ local bs, bc = pdfborder()
local action = pdfdictionary {
Subtype = pdfconstant("Movie"),
- Border = pdfarray { 0, 0, 0 },
+ Border = bs,
+ C = bc,
T = format("movie %s",specification.label),
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)
@@ -51,13 +53,15 @@ function nodeinjections.insertsound(specification)
local sounddict = pdfdictionary {
F = soundclip.filename
}
+ local bs, bc = pdfborder()
local action = pdfdictionary {
Subtype = pdfconstant("Movie"),
- Border = pdfarray { 0, 0, 0 },
+ Border = bs,
+ C = bc,
T = format("sound %s",specification.label),
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..f0fca0762 100644
--- a/tex/context/base/lpdf-u3d.lua
+++ b/tex/context/base/lpdf-u3d.lua
@@ -17,6 +17,7 @@ if not modules then modules = { } end modules ['lpdf-u3d'] = {
-- point we will end up with a reimplementation. For instance
-- it makes sense to add the same activation code as with swf.
+local tonumber = tonumber
local format, find = string.format, string.find
local cos, sin, sqrt, pi, atan2, abs = math.cos, math.sin, math.sqrt, math.pi, math.atan2, math.abs
@@ -38,8 +39,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 +461,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 +483,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..895bbd3ff 100644
--- a/tex/context/base/lpdf-wid.lua
+++ b/tex/context/base/lpdf-wid.lua
@@ -46,20 +46,18 @@ 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 pdfborder = lpdf.border
-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
-local pdf_border = pdfarray { 0, 0, 0 } -- can be shared
-
-- symbols
local presets = { } -- xforms
@@ -117,8 +115,8 @@ codeinjections.presetsymbollist = presetsymbollist
-- }
local attachment_symbols = {
- Graph = pdfconstant("GraphPushPin"),
- Paperclip = pdfconstant("PaperclipTag"),
+ Graph = pdfconstant("Graph"),
+ Paperclip = pdfconstant("Paperclip"),
Pushpin = pdfconstant("PushPin"),
}
@@ -170,12 +168,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 +340,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 +425,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 +482,7 @@ end
local ms, mu, mf = { }, { }, { }
local function delayed(label)
- local a = pdfreserveannotation()
+ local a = pdfreserveobject()
mu[label] = a
return pdfreference(a)
end
@@ -504,23 +502,25 @@ 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],
OP = 0,
AN = pdfreference(r),
}
+ local bs, bc = pdfborder()
local d = pdfdictionary {
Subtype = pdfconstant("Screen"),
P = pdfreference(pdfpagereference(page)),
A = a, -- needed in order to make the annotation clickable (i.e. don't bark)
- Border = pdf_border,
+ Border = bs,
+ C = bc,
AA = actions,
}
local width = specification.width or 0
@@ -528,7 +528,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 +539,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/lpdf-xmp.lua b/tex/context/base/lpdf-xmp.lua
index 061ed0757..c8b2d236c 100644
--- a/tex/context/base/lpdf-xmp.lua
+++ b/tex/context/base/lpdf-xmp.lua
@@ -7,6 +7,7 @@ if not modules then modules = { } end modules ['lpdf-xmp'] = {
comment = "with help from Peter Rolf",
}
+local tostring = tostring
local format, random, char, gsub, concat = string.format, math.random, string.char, string.gsub, table.concat
local xmlfillin = xml.fillin
@@ -119,16 +120,16 @@ end
-- redefined
-local addtoinfo = lpdf.addtoinfo
-local addxmpinfo = lpdf.addxmpinfo
+local pdfaddtoinfo = lpdf.addtoinfo
+local pdfaddxmpinfo = lpdf.addxmpinfo
function lpdf.addtoinfo(tag,pdfvalue,strvalue)
- addtoinfo(tag,pdfvalue)
+ pdfaddtoinfo(tag,pdfvalue)
local value = strvalue or gsub(tostring(pdfvalue),"^%((.*)%)$","%1") -- hack
if trace_info then
report_info("set %a to %a",tag,value)
end
- addxmpinfo(tag,value)
+ pdfaddxmpinfo(tag,value)
end
-- for the do-it-yourselvers
@@ -159,20 +160,20 @@ local function flushxmpinfo()
local fullbanner = tex.pdftexbanner
-- local fullbanner = gsub(tex.pdftexbanner,"kpse.*","")
- addxmpinfo("DocumentID", documentid)
- addxmpinfo("InstanceID", instanceid)
- addxmpinfo("Producer", producer)
- addxmpinfo("CreatorTool", creator)
- addxmpinfo("CreateDate", time)
- addxmpinfo("ModifyDate", time)
- addxmpinfo("MetadataDate", time)
- addxmpinfo("PTEX.Fullbanner", fullbanner)
-
- addtoinfo("Producer", producer)
- addtoinfo("Creator", creator)
- addtoinfo("CreationDate", time)
- addtoinfo("ModDate", time)
--- addtoinfo("PTEX.Fullbanner", fullbanner) -- no checking done on existence
+ pdfaddxmpinfo("DocumentID", documentid)
+ pdfaddxmpinfo("InstanceID", instanceid)
+ pdfaddxmpinfo("Producer", producer)
+ pdfaddxmpinfo("CreatorTool", creator)
+ pdfaddxmpinfo("CreateDate", time)
+ pdfaddxmpinfo("ModifyDate", time)
+ pdfaddxmpinfo("MetadataDate", time)
+ pdfaddxmpinfo("PTEX.Fullbanner", fullbanner)
+
+ pdfaddtoinfo("Producer", producer)
+ pdfaddtoinfo("Creator", creator)
+ pdfaddtoinfo("CreationDate", time)
+ pdfaddtoinfo("ModDate", time)
+-- pdfaddtoinfo("PTEX.Fullbanner", fullbanner) -- no checking done on existence
local blob = xml.tostring(xml.first(xmp or valid_xmp(),"/x:xmpmeta"))
local md = pdfdictionary {
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-env.lua b/tex/context/base/luat-env.lua
index 5558e0303..5f2a0d281 100644
--- a/tex/context/base/luat-env.lua
+++ b/tex/context/base/luat-env.lua
@@ -102,14 +102,20 @@ function environment.luafilechunk(filename,silent) -- used for loading lua bytec
local fullname = environment.luafile(filename)
if fullname and fullname ~= "" then
local data = luautilities.loadedluacode(fullname,strippable,filename) -- can be overloaded
- if trace_locating then
+-- if trace_locating then
+-- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+-- elseif not silent then
+-- texio.write("<",data and "+ " or "- ",fullname,">")
+-- end
+ if not silent then
report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- elseif not silent then
- texio.write("<",data and "+ " or "- ",fullname,">")
end
return data
else
- if trace_locating then
+-- if trace_locating then
+-- report_lua("unknown file %a",filename)
+-- end
+ if not silent then
report_lua("unknown file %a",filename)
end
return nil
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..607c3528a 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 = false
+
+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-ini.mkiv b/tex/context/base/lxml-ini.mkiv
index cfa0114d0..239fe4ac0 100644
--- a/tex/context/base/lxml-ini.mkiv
+++ b/tex/context/base/lxml-ini.mkiv
@@ -58,6 +58,7 @@
\def\xmldirect #1{\ctxlxml{direct("#1")}} % in loops, not dt but root
\def\xmlidx #1#2#3{\ctxlxml{idx("#1","#2",\number#3)}}
\def\xmlinclude #1#2#3{\ctxlxml{include("#1","#2","#3",true)}}
+\def\xmlsave #1#2{\ctxlxml{save("#1","#2")}}
\def\xmlindex #1#2#3{\ctxlxml{index("#1","#2",\number#3)}}
\def\xmlinfo #1{\hbox{\ttxx[\ctxlxml{info("#1")}]}}
\def\xmlshow #1{\startpacked\ttx\xmlverbatim{#1}\stoppacked}
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..0503c511c 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 { }
@@ -457,6 +458,10 @@ function lxml.include(id,pattern,attribute,recurse)
stoptiming(xml)
end
+function lxml.save(id,name)
+ xml.save(getid(id),name)
+end
+
function xml.getbuffer(name,compress,entities) -- we need to make sure that commands are processed
if not name or name == "" then
name = tex.jobname
@@ -915,16 +920,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 +974,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 +1195,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 +1320,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 +1337,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 +1351,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 +1460,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-scite.mkiv b/tex/context/base/m-scite.mkiv
new file mode 100644
index 000000000..aed2c2631
--- /dev/null
+++ b/tex/context/base/m-scite.mkiv
@@ -0,0 +1,269 @@
+%D \module
+%D [ file=m-scite,
+%D version=2014.04.28,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\SCITE\ lexers,
+%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.
+
+% We can simplify the scite lexers, as long as we're able to return the
+% lexed result table and provide alexer module with the functions that
+% the lexer expects (so I need to decipher the cxx file).
+%
+% lexer._TOKENSTYLES : table
+% lexer._CHILDREN : flag
+% lexer._EXTRASTYLES : table
+% lexer._GRAMMAR : flag
+%
+% lexers.load : function
+% lexers.lex : function
+%
+% And some properties that map styles onto scintilla styling. I get the
+% impression that we end up with something simpler, a hybrid between the
+% scite lexing and the current context way, so we get an intermediate
+% step, with some penalty for context, but at least I don't have to
+% maintain two sets (three sets as we also have a line based series).
+
+% TODO: as these files are in tds we can locate them and set the lexer root
+% to that one. Currently we're on: we're on context/documents.
+
+% This is an experiment: eventually we need to hook it into the verbatim code
+% and deal with widow lines and so.
+
+\startluacode
+
+-- todo: merge with collapse
+-- todo: prehash whitespaces
+
+-- todo: hook into the pretty print code
+-- todo: a simple catcode regime with only \ { }
+
+local gsub, sub, find = string.gsub, string.sub, string.find
+local concat = table.concat
+local formatters = string.formatters
+local lpegmatch = lpeg.match
+local setmetatableindex = table.setmetatableindex
+
+local scite = require("util-sci")
+buffers.scite = scite
+
+-- context output:
+
+local f_def_color = formatters["\\definecolor[slxc%s][h=%s%s%s]%%"]
+local f_fore_none = formatters["\\def\\slx%s#1{{\\slxc%s#1}}%%"]
+local f_fore_bold = formatters["\\def\\slx%s#1{{\\slxc%s\\bf#1}}%%"]
+local f_none_bold = formatters["\\def\\slx%s#1{{\\bf#1}}%%"]
+local f_none_none = formatters["\\def\\slx%s#1{{#1}}%%"]
+local f_texstyled = formatters["\\slx%s{%s}"]
+
+local f_mapping = [[
+\let\string\slxL\string\letterleftbrace
+\let\string\slxR\string\letterrightbrace
+\let\string\slxM\string\letterdollar
+\let\string\slxV\string\letterbar
+\let\string\slxH\string\letterhash
+\let\string\slxB\string\letterbackslash
+\let\string\slxP\string\letterpercent
+\let\string\slxS\string\fixedspace
+%]]
+
+local replacer = lpeg.replacer {
+ ["{"] = "\\slxL ",
+ ["}"] = "\\slxR ",
+ ["$"] = "\\slxM ",
+ ["|"] = "\\slxV ",
+ ["#"] = "\\slxH ",
+ ["\\"] = "\\slxB ",
+ ["%"] = "\\slxP ",
+ [" "] = "\\slxS ",
+}
+
+local colors = nil
+
+local function exportcolors()
+ if not colors then
+ scite.loadscitelexer()
+ local function black(f)
+ return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == '00')
+ end
+ local result, r = { f_mapping }, 1
+ for k, v in table.sortedhash(lexer.context.styles) do
+ local fore = v.fore
+ if fore and not black(fore) then
+ r = r + 1
+ result[r] = f_def_color(k,fore[1],fore[2],fore[3])
+ end
+ end
+ r = r + 1
+ result[r] = "%"
+ for k, v in table.sortedhash(lexer.context.styles) do
+ local bold = v.bold
+ local fore = v.fore
+ r = r + 1
+ if fore and not black(fore) then
+ if bold then
+ result[r] = f_fore_bold(k,k)
+ else
+ result[r] = f_fore_none(k,k)
+ end
+ else
+ if bold then
+ result[r] = f_none_bold(k)
+ else
+ result[r] = f_none_none(k)
+ end
+ end
+ end
+ colors = concat(result,"\n")
+ end
+ return colors
+end
+
+local function exportwhites()
+ return setmetatableindex(function(t,k)
+ local v = find(k,"white") and true or false
+ t[k] = v
+ return v
+ end)
+end
+
+local function exportstyled(lexer,text)
+ local result = lexer.lex(lexer,text,0)
+ local start = 1
+ local whites = exportwhites()
+ local buffer = { }
+ for i=1,#result,2 do
+ local style = result[i]
+ local position = result[i+1]
+ local txt = sub(text,start,position-1)
+ txt = lpegmatch(replacer,txt)
+ if whites[style] then
+ buffer[#buffer+1] = txt
+ else
+ buffer[#buffer+1] = f_texstyled(style,txt)
+ end
+ start = position
+ end
+ buffer = concat(buffer)
+ return buffer
+end
+
+function scite.installcommands()
+ context(exportcolors())
+end
+
+local function lexdata(data,lexname)
+ buffers.assign("lex",exportstyled(scite.loadedlexers[lexname],data or ""))
+end
+
+scite.lexdata = lexdata
+
+function scite.lexbuffer(name,lexname)
+ lexdata(buffers.getcontent(name) or "",lexname or "tex")
+end
+
+function scite.lexfile(filename,lexname)
+ lexdata(io.loaddata(filename) or "",lexname or file.suffix(filename))
+end
+
+-- html output
+
+\stopluacode
+
+% This is a preliminary interface.
+
+\unprotect
+
+\unexpanded\def\installscitecommands
+ {\ctxlua{buffers.scite.installcommands()}%
+ \let\installscitecommands\relax}
+
+\unexpanded\def\startscite{\startlines}
+\unexpanded\def\stopscite {\stoplines}
+
+\unexpanded\def\scitefile
+ {\dosingleargument\module_scite_file}
+
+\unexpanded\def\module_scite_file[#1]%
+ {\start
+ \ctxlua{buffers.scite.lexfile("#1")}%
+ \installscitecommands
+ \tt
+ \dontcomplain
+ \startscite
+ \getbuffer[lex]%
+ \stopscite
+ \stop}
+
+\unexpanded\def\scitebuffer
+ {\dodoubleargument\module_scite_buffer}
+
+\unexpanded\def\module_scite_buffer[#1][#2]%
+ {\start
+ \ifsecondargument
+ \ctxlua{buffers.scite.lexbuffer("#2","#1")}%
+ \else
+ \ctxlua{buffers.scite.lexbuffer("#1","tex")}%
+ \fi
+ \installscitecommands
+ \tt
+ \dontcomplain
+ \startscite
+ \getbuffer[lex]%
+ \stopscite
+ \stop}
+
+\protect
+
+\continueifinputfile{m-scite.mkiv}
+
+\setupbodyfont[dejavu,8pt]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ header=1cm,
+ footer=1cm,
+ topspace=1cm,
+ bottomspace=1cm,
+ backspace=1cm]
+
+\startbuffer[demo]
+\startsubsubject[title={oeps}]
+
+\startMPcode
+ draw fullcircle
+ scaled 2cm
+ withpen pencircle scaled 1mm
+ withcolor .5green;
+ draw textext (
+ lua (
+ "local function f(s) return string.upper(s) end mp.quoted(f('foo'))"
+ )
+ ) withcolor .5red ;
+\stopMPcode
+
+\startluacode
+ context("foo")
+\stopluacode
+
+\stopsubsubject
+\stopbuffer
+
+\starttext
+
+% \scitefile[../lexers/scite-context-lexer.lua] \page
+% \scitefile[t:/manuals/about/about-metafun.tex] \page
+% \scitefile[t:/sources/strc-sec.mkiv] \page
+% \scitefile[e:/tmp/mp.w] \page
+% \scitefile[t:/manuals/hybrid/tugboat.bib] \page
+\scitefile[e:/tmp/test.bib] \page
+
+% \getbuffer[demo] \scitebuffer[demo]
+
+\stoptext
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..dcd2a5c33 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}
@@ -1267,7 +1296,9 @@
%D
%D \typebuffer \getbuffer
-\unexpanded\def\mathstylehbox#1%
+% to be tested: {#1} but it could have side effects
+
+\unexpanded\def\mathstylehbox#1% sensitive for: a \over b => {a\over b} or \frac{a}{b}
{\normalexpanded{\hbox\bgroup
\startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup}
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..027b5c27d 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}
@@ -74,8 +74,8 @@
\def\math_radical_indeed#body%
{\math_radical_alternative{#body}\endgroup}
-\setvalue{\??mathradicalalternative\v!default}% #1%
- {\rootradical{\currentmathradicaldegree}}
+\setvalue{\??mathradicalalternative\v!default}% #body%
+ {\rootradical{\currentmathradicaldegree}} % {#body}}
\setvalue{\??mathradicalalternative\v!normal}#body%
{\edef\p_color{\mathradicalparameter\c!color}%
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-ini.mkiv b/tex/context/base/meta-ini.mkiv
index 28ba9e901..281143e40 100644
--- a/tex/context/base/meta-ini.mkiv
+++ b/tex/context/base/meta-ini.mkiv
@@ -264,7 +264,10 @@
\ifx\p_setups\empty \else
\setups[\p_setups]%
\fi
- \useMPinstancestyleandcolor\c!textstyle\c!textcolor}
+ \useMPinstancestyleparameter\c!textstyle}
+
+\def\meta_set_current_color
+ {\useMPinstancecolorparameter\c!textcolor}
\def\meta_stop_current_graphic
{\global\t_meta_definitions\emptytoks
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..e7ed59727 100644
--- a/tex/context/base/meta-tex.mkiv
+++ b/tex/context/base/meta-tex.mkiv
@@ -28,7 +28,7 @@
\let\stopTeXtexts\relax
-\def\TeXtext
+\unexpanded\def\TeXtext
{\dosingleempty\meta_textext}
\def\meta_textext[#1]#2#3% contrary to mkii we don't process yet but we do expand
@@ -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-ctx.lua b/tex/context/base/mlib-ctx.lua
index a1a4e645a..fe5218771 100644
--- a/tex/context/base/mlib-ctx.lua
+++ b/tex/context/base/mlib-ctx.lua
@@ -146,9 +146,11 @@ statistics.register("metapost processing time", function()
local nofconverted = metapost.makempy.nofconverted
local elapsedtime = statistics.elapsedtime
local elapsed = statistics.elapsed
- local str = format("%s seconds, loading: %s, execution: %s, n: %s, average: %s",
+ local instances, memory = metapost.getstatistics(true)
+ local str = format("%s seconds, loading: %s, execution: %s, n: %s, average: %s, instances: %i, memory: %0.3f M",
elapsedtime(metapost), elapsedtime(mplib), elapsedtime(metapost.exectime), n,
- elapsedtime((elapsed(metapost) + elapsed(mplib) + elapsed(metapost.exectime)) / n))
+ elapsedtime((elapsed(metapost) + elapsed(mplib) + elapsed(metapost.exectime)) / n),
+ instances, memory/(1024*1024))
if nofconverted > 0 then
return format("%s, external: %s (%s calls)",
str, elapsedtime(metapost.makempy), nofconverted)
diff --git a/tex/context/base/mlib-ctx.mkiv b/tex/context/base/mlib-ctx.mkiv
index 75ff45488..e4c1cb6fe 100644
--- a/tex/context/base/mlib-ctx.mkiv
+++ b/tex/context/base/mlib-ctx.mkiv
@@ -18,6 +18,7 @@
\registerctxluafile{mlib-run}{1.001}
\registerctxluafile{mlib-ctx}{1.001}
+\registerctxluafile{mlib-lua}{1.001}
\unprotect
diff --git a/tex/context/base/mlib-lua.lua b/tex/context/base/mlib-lua.lua
new file mode 100644
index 000000000..9c7a2e43a
--- /dev/null
+++ b/tex/context/base/mlib-lua.lua
@@ -0,0 +1,185 @@
+if not modules then modules = { } end modules ['mlib-pdf'] = {
+ version = 1.001,
+ comment = "companion to mlib-ctx.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+-- This is very preliminary code!
+
+local type, tostring, select, loadstring = type, tostring, select, loadstring
+local formatters = string.formatters
+local find, gsub = string.find, string.gsub
+local concat = table.concat
+local lpegmatch = lpeg.match
+
+local report_luarun = logs.reporter("metapost","lua")
+
+local trace_luarun = false trackers.register("metapost.lua",function(v) trace_luarun = v end)
+local trace_enabled = true
+
+mp = mp or { } -- system namespace
+MP = MP or { } -- user namespace
+
+local buffer, n, max = { }, 0, 10 -- we reuse upto max
+
+function mp._f_()
+ if trace_enabled and trace_luarun then
+ local result = concat(buffer," ",1,n)
+ if n > max then
+ buffer = { }
+ end
+ n = 0
+ report_luarun("data: %s",result)
+ return result
+ else
+ if n == 0 then
+ return ""
+ end
+ local result
+ if n == 1 then
+ result = buffer[1]
+ else
+ result = concat(buffer," ",1,n)
+ end
+ if n > max then
+ buffer = { }
+ end
+ n = 0
+ return result
+ end
+end
+
+local f_pair = formatters["(%s,%s)"]
+local f_triplet = formatters["(%s,%s,%s)"]
+local f_quadruple = formatters["(%s,%s,%s,%s)"]
+
+function mp.print(...)
+ for i=1,select("#",...) do
+ n = n + 1
+ buffer[n] = tostring((select(i,...)))
+ end
+end
+
+function mp.pair(x,y)
+ n = n + 1
+ if type(x) == "table" then
+ buffer[n] = f_pair(x[1],x[2])
+ else
+ buffer[n] = f_pair(x,y)
+ end
+end
+
+function mp.triplet(x,y,z)
+ n = n + 1
+ if type(x) == "table" then
+ buffer[n] = f_triplet(x[1],x[2],x[3])
+ else
+ buffer[n] = f_triplet(x,y,z)
+ end
+end
+
+function mp.quadruple(w,x,y,z)
+ n = n + 1
+ if type(w) == "table" then
+ buffer[n] = f_quadruple(w[1],w[2],w[3],w[4])
+ else
+ buffer[n] = f_quadruple(w,x,y,z)
+ end
+end
+
+local replacer = lpeg.replacer("@","%%")
+
+function mp.format(fmt,...)
+ n = n + 1
+ if not find(fmt,"%%") then
+ fmt = lpegmatch(replacer,fmt)
+ end
+ buffer[n] = formatters[fmt](...)
+end
+
+function mp.quoted(fmt,s,...)
+ n = n + 1
+ if s then
+ if not find(fmt,"%%") then
+ fmt = lpegmatch(replacer,fmt)
+ end
+ buffer[n] = '"' .. formatters[fmt](s,...) .. '"'
+ else
+ buffer[n] = '"' .. fmt .. '"'
+ end
+end
+
+local f_code = formatters["%s return mp._f_()"]
+
+function metapost.runscript(code)
+ local f = loadstring(f_code(code))
+ if f then
+ return tostring(f())
+ else
+ return ""
+ end
+end
+
+local cache, n = { }, 0 -- todo: when > n then reset cache or make weak
+
+function metapost.runscript(code)
+ if trace_enabled and trace_luarun then
+ report_luarun("code: %s",code)
+ end
+ if n > 100 then
+ cache = nil -- forget about caching
+ local f = loadstring(f_code(code))
+ if f then
+ return tostring(f())
+ else
+ return ""
+ end
+ else
+ local f = cache[code]
+ if f then
+ return tostring(f())
+ else
+ f = loadstring(f_code(code))
+ if f then
+ n = n + 1
+ cache[code] = f
+ return tostring(f())
+ else
+ return ""
+ end
+ end
+ end
+end
+
+-- function metapost.initializescriptrunner(mpx)
+-- mp.numeric = function(s) return mpx:get_numeric(s) end
+-- mp.string = function(s) return mpx:get_string (s) end
+-- mp.boolean = function(s) return mpx:get_boolean(s) end
+-- mp.number = mp.numeric
+-- end
+
+local get_numeric = mplib.get_numeric
+local get_string = mplib.get_string
+local get_boolean = mplib.get_boolean
+local get_number = get_numeric
+
+-- function metapost.initializescriptrunner(mpx)
+-- mp.numeric = function(s) return get_numeric(mpx,s) end
+-- mp.string = function(s) return get_string (mpx,s) end
+-- mp.boolean = function(s) return get_boolean(mpx,s) end
+-- mp.number = mp.numeric
+-- end
+
+local currentmpx = nil
+
+mp.numeric = function(s) return get_numeric(currentmpx,s) end
+mp.string = function(s) return get_string (currentmpx,s) end
+mp.boolean = function(s) return get_boolean(currentmpx,s) end
+mp.number = mp.numeric
+
+function metapost.initializescriptrunner(mpx,trialrun)
+ currentmpx = mpx
+ trace_enabled = not trialrun
+end
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..ce95d5ca7 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
@@ -860,7 +866,11 @@ local function tx_reset()
end
local fmt = formatters["%s %s %s % t"]
-local pat = tsplitat(":")
+----- pat = tsplitat(":")
+local pat = lpeg.tsplitter(":",tonumber) -- so that %F can do its work
+
+local ctx_MPLIBsetNtext = context.MPLIBsetNtext
+local ctx_MPLIBsetCtext = context.MPLIBsetCtext
local function tx_analyze(object,prescript) -- todo: hash content and reuse them
local tx_stage = prescript.tx_stage
@@ -884,27 +894,28 @@ local function tx_analyze(object,prescript) -- todo: hash content and reuse them
local tx_last = top.texlast + 1
top.texlast = tx_last
if not c then
- -- no color
+ ctx_MPLIBsetNtext(tx_last,s)
elseif #c == 1 then
if a and t then
- s = formatters["\\directcolored[s=%f,a=%f,t=%f]%s"](c[1],a,t,s)
+ ctx_MPLIBsetCtext(tx_last,formatters["s=%F,a=%F,t=%F"](c[1],a,t),s)
else
- s = formatters["\\directcolored[s=%f]%s"](c[1],s)
+ ctx_MPLIBsetCtext(tx_last,formatters["s=%F"](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)
+ ctx_MPLIBsetCtext(tx_last,formatters["r=%F,g=%F,b=%F,a=%F,t=%F"](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)
+ ctx_MPLIBsetCtext(tx_last,formatters["r=%F,g=%F,b=%F"](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)
+ ctx_MPLIBsetCtext(tx_last,formatters["c=%F,m=%F,y=%F,k=%F,a=%F,t=%F"](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)
+ ctx_MPLIBsetCtext(tx_last,formatters["c=%F,m=%F,y=%F,k=%F"](c[1],c[2],c[3],c[4]),s)
end
+ else
+ ctx_MPLIBsetNtext(tx_last,s)
end
- context.MPLIBsettext(tx_last,s)
top.multipass = true
metapost.multipass = true -- ugly
top.texhash[h] = tx_last
@@ -956,12 +967,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 +1147,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/mlib-pps.mkiv b/tex/context/base/mlib-pps.mkiv
index e16827585..207d9730c 100644
--- a/tex/context/base/mlib-pps.mkiv
+++ b/tex/context/base/mlib-pps.mkiv
@@ -60,27 +60,38 @@
\let\MPLIBflushenvironment\doMPLIBflushenvironment
-\def\MPLIBsettext#1% #2%
+\unexpanded\def\MPLIBsetNtext#1% #2% box text
{\MPLIBflushenvironment
\dowithnextbox{\ctxlua{metapost.settext(\number\nextbox,#1)}}\hbox\bgroup
+ \meta_set_current_color
\let\MPLIBflushenvironment\doMPLIBflushenvironment
\let\next} % gobble open brace
-\def\MPLIBresettexts
+\unexpanded\def\MPLIBsetCtext#1#2% #3% box colorspec text
+ {\MPLIBflushenvironment
+ \dowithnextbox{\ctxlua{metapost.settext(\number\nextbox,#1)}}\hbox\bgroup
+ \directcolored[#2]%
+ \meta_set_current_color % so, textcolor wins !
+ \let\MPLIBflushenvironment\doMPLIBflushenvironment
+ \let\next} % gobble open brace
+
+\let\MPLIBsettext\MPLIBsetNtext
+
+\unexpanded\def\MPLIBresettexts
{\ctxlua{metapost.resettextexts()}}
-\def\MPLIBgettextscaled#1#2#3% why a copy .. can be used more often
+\unexpanded\def\MPLIBgettextscaled#1#2#3% why a copy .. can be used more often
{\ctxlua{metapost.gettext(\number\MPtextbox,#1)}%
\vbox to \zeropoint{\vss\hbox to \zeropoint{\scale[\c!sx=#2,\c!sy=#3]{\raise\dp\MPtextbox\box\MPtextbox}\forcecolorhack\hss}}}
-\def\MPLIBfigure#1#2%
+\unexpanded\def\MPLIBfigure#1#2%
{\setbox\scratchbox\hbox{\externalfigure[#1][\c!mask=#2]}%
\ctxlua{metapost.edefsxsy(\number\wd\scratchbox,\number\ht\scratchbox,0)}%
\vbox to \zeropoint{\vss\hbox to \zeropoint{\scale[\c!sx=\sx,\c!sy=\sy]{\box\scratchbox}\hss}}}
% horrible (we could inline scale and matrix code):
-\def\MPLIBgettextscaledcm#1#2#3#4#5#6#7#8#9% 2-7: sx,rx,ry,sy,tx,ty
+\unexpanded\def\MPLIBgettextscaledcm#1#2#3#4#5#6#7#8#9% 2-7: sx,rx,ry,sy,tx,ty
{\ctxlua{metapost.gettext(\number\MPtextbox,#1)}%
\setbox\MPbox\hbox\bgroup
\dotransformnextbox{#2}{#3}{#4}{#5}{#6}{#7}% does push pop ... will be changed to proper lua call (avoid small numbers)
@@ -103,7 +114,7 @@
\smashbox\MPbox
\box\MPbox}
-\def\MPLIBgraphictext#1% use at mp end
+\unexpanded\def\MPLIBgraphictext#1% use at mp end
{\startTEXpage[\c!scale=10000]#1\stopTEXpage}
%D \startbuffer
@@ -132,7 +143,7 @@
%D
%D \typebuffer \startlinecorrection \getbuffer \stoplinecorrection
-\def\MPLIBpositionwhd#1#2#3#4#5% bp !
+\unexpanded\def\MPLIBpositionwhd#1#2#3#4#5% bp !
{\dosavepositionwhd{#1}\zerocount{#2\onebasepoint}{#3\onebasepoint}{#4\onebasepoint}{#5\onebasepoint}\zeropoint}
% \def\MPLIBextrapass#1%
@@ -158,9 +169,9 @@
\box\scratchbox
\endgroup}
-\def\MPLIBstartgroup#1#2#3#4#5#6% isolated 0/1, knockout 0/1 llx lly urx ury
+\unexpanded\def\MPLIBstartgroup#1#2#3#4#5#6% isolated 0/1, knockout 0/1 llx lly urx ury
{\begingroup
\setbox\scratchbox\hbox\bgroup
- \def\MPLIBstopgroup{\doMPLIBstopgroup{#1}{#2}{#3}{#4}{#5}{#6}}}
+ \unexpanded\def\MPLIBstopgroup{\doMPLIBstopgroup{#1}{#2}{#3}{#4}{#5}{#6}}}
\protect \endinput
diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua
index f30ed0c9f..2a34f44d5 100644
--- a/tex/context/base/mlib-run.lua
+++ b/tex/context/base/mlib-run.lua
@@ -121,7 +121,7 @@ local function o_finder(name,mode,ftype)
return name
end
-local function finder(name, mode, ftype)
+local function finder(name,mode,ftype)
if mode == "w" then
return o_finder(name,mode,ftype)
else
@@ -295,17 +295,28 @@ else
local methods = {
double = "double",
scaled = "scaled",
+ binary = "binary",
+ decimal = "decimal",
default = "scaled",
- decimal = false, -- for the moment
}
+ function metapost.runscript(code)
+ return code
+ end
+
+ function metapost.scripterror(str)
+ report_metapost("script error: %s",str)
+ end
+
function metapost.load(name,method)
starttiming(mplib)
method = method and methods[method] or "scaled"
local mpx = mplib.new {
- ini_version = true,
- find_file = finder,
- math_mode = method,
+ ini_version = true,
+ find_file = finder,
+ math_mode = method,
+ run_script = metapost.runscript,
+ script_error = metapost.scripterror,
}
report_metapost("initializing number mode %a",method)
local result
@@ -402,6 +413,10 @@ local mp_inp, mp_log, mp_tag = { }, { }, 0
-- key/values
+if not metapost.initializescriptrunner then
+ function metapost.initializescriptrunner() end
+end
+
function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig)
local converted, result = false, { }
if type(mpx) == "string" then
@@ -409,6 +424,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass,
end
if mpx and data then
starttiming(metapost)
+ metapost.initializescriptrunner(mpx,trialrun)
if trace_graphics then
if not mp_inp[mpx] then
mp_tag = mp_tag + 1
@@ -625,3 +641,20 @@ function metapost.quickanddirty(mpxformat,data)
report_metapost("invalid quick and dirty run")
end
end
+
+function metapost.getstatistics(memonly)
+ if memonly then
+ local n, m = 0, 0
+ for name, mpx in next, mpxformats do
+ n = n + 1
+ m = m + mpx:statistics().memory
+ end
+ return n, m
+ else
+ local t = { }
+ for name, mpx in next, mpxformats do
+ t[name] = mpx:statistics()
+ end
+ return t
+ end
+end
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..86095edab 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",
@@ -90,6 +90,7 @@ return {
--
"startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset",
"doifmode", "doifmodeelse", "doifnotmode",
+ "startmodeset","stopmodeset",
"startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifallmodeselse", "doifnotallmodes",
"startenvironment", "stopenvironment", "environment",
"startcomponent", "stopcomponent", "component",
@@ -136,6 +137,7 @@ return {
"starttexdefinition", "stoptexdefinition",
"starttexcode", "stoptexcode",
"startcontextcode", "stopcontextcode",
+ "startcontextdefinitioncode", "stopcontextdefinitioncode",
--
"doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup",
"doifelsecommandhandler","doifnotcommandhandler","doifcommandhandler",
@@ -219,7 +221,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 +357,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.lua b/tex/context/base/node-ini.lua
index 652b46caf..a9ef305c0 100644
--- a/tex/context/base/node-ini.lua
+++ b/tex/context/base/node-ini.lua
@@ -220,6 +220,8 @@ listcodes.column = listcodes.alignment
kerncodes.italiccorrection = kerncodes.userkern
kerncodes.kerning = kerncodes.fontkern
+whatcodes.textdir = whatcodes.dir
+
nodes.codes = allocate { -- mostly for listing
glue = skipcodes,
noad = noadcodes,
diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv
index e99653327..5fc519069 100644
--- a/tex/context/base/node-ini.mkiv
+++ b/tex/context/base/node-ini.mkiv
@@ -19,10 +19,9 @@
\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-ppt}{1.001} % experimental
\registerctxluafile{node-dir}{1.001}
\registerctxluafile{node-aux}{1.001}
\registerctxluafile{node-tst}{1.001}
@@ -36,6 +35,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-ltp.lua b/tex/context/base/node-ltp.lua
index 9f2491cfa..6ad5de140 100644
--- a/tex/context/base/node-ltp.lua
+++ b/tex/context/base/node-ltp.lua
@@ -1439,6 +1439,10 @@ local function post_line_break(par)
elseif id < math_code then
-- messy criterium
break
+elseif id == math_code then
+ -- keep the math node
+ setfield(next,"surround",0)
+ break
elseif id == kern_code and (subtype ~= userkern_code and not getattr(next,a_fontkern)) then
-- fontkerns and accent kerns as well as otf injections
break
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..2b4e9968c 100644
--- a/tex/context/base/node-nut.lua
+++ b/tex/context/base/node-nut.lua
@@ -129,7 +129,7 @@ nuts.getfield = direct.getfield
nuts.getnext = direct.getnext
nuts.getprev = direct.getprev
nuts.getid = direct.getid
-nuts.getattr = direct.getfield
+nuts.getattr = direct.has_attribute or direct.getfield
nuts.getchar = direct.getchar
nuts.getfont = direct.getfont
nuts.getsubtype = direct.getsubtype
@@ -141,7 +141,7 @@ nuts.getleader = direct.getleader
-- setters
nuts.setfield = direct.setfield
-nuts.setattr = direct.setfield
+nuts.setattr = direct.set_attribute or setfield
nuts.getbox = direct.getbox
nuts.setbox = direct.setbox
@@ -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-ppt.lua b/tex/context/base/node-ppt.lua
new file mode 100644
index 000000000..c8cba8566
--- /dev/null
+++ b/tex/context/base/node-ppt.lua
@@ -0,0 +1,476 @@
+if not modules then modules = { } end modules ['node-ppt'] = {
+ version = 1.001,
+ comment = "companion to node-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is all very exeperimental and likely to change.
+
+local next, type, unpack, load = next, type, table.unpack, load
+
+local serialize = table.serialize
+local formatters = string.formatters
+
+local report = logs.reporter("properties")
+local report_setting = logs.reporter("properties","setting")
+local trace_setting = false trackers.register("properties.setting", function(v) trace_setting = v end)
+
+-- report("using experimental properties")
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+local getid = nuts.getid
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getsubtype = nuts.getsubtype
+local getfield = nuts.getfield
+local setfield = nuts.setfield
+local getlist = nuts.getlist
+local flushnode = nuts.flush
+local removenode = nuts.remove
+local traverse = nuts.traverse
+local traverse_id = nuts.traverse_id
+
+local nodecodes = nodes.nodecodes
+local whatsitcodes = nodes.whatsitcodes
+
+local whatsit_code = nodecodes.whatsit
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local userdefined_code = whatsitcodes.userdefined
+local localpar_code = whatsitcodes.localpar
+
+local nodepool = nodes.pool
+local new_usernumber = nodepool.usernumber
+
+local nutpool = nuts.pool
+local nut_usernumber = nutpool.usernumber
+
+local variables = interfaces.variables
+local v_before = variables.before
+local v_after = variables.after
+local v_here = variables.here
+
+local cache = { }
+local nofslots = 0
+local property_id = nodepool.userids["property"]
+
+local properties = nodes.properties if not properties then return end -- temp
+local propertydata = properties.data
+
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
+
+if not propertydata then
+ return
+end
+
+-- management
+
+local function register(where,data,...)
+ if not data then
+ data = where
+ where = v_after
+ end
+ if data then
+ local data = { where, data, ... }
+ nofslots = nofslots + 1
+ if nofslots > 1 then
+ cache[nofslots] = data
+ else
+ -- report("restarting attacher")
+ cache = { data } -- also forces collection
+ end
+ return new_usernumber(property_id,nofslots)
+ end
+end
+
+local writenode = node.write
+local flushnode = context.flushnode
+
+function commands.deferredproperty(...)
+-- context(register(...))
+ flushnode(register(...))
+end
+
+
+function commands.immediateproperty(...)
+ writenode(register(...))
+end
+
+commands.attachproperty = commands.deferredproperty
+
+local actions = { } properties.actions = actions
+
+table.setmetatableindex(actions,function(t,k)
+ report("unknown property action %a",k)
+ local v = function() end
+ return v
+end)
+
+local f_delayed = formatters["return function(target,head,where,propdata,parent) %s end"]
+local f_immediate = formatters["return function(target,head,where,propdata) %s end"]
+
+local nofdelayed = 0 -- better is to keep track of it per page ... we can have deleted nodes with properties
+
+function actions.delayed(target,head,where,propdata,code,...) -- this one is used at the tex end
+-- local kind = type(code)
+-- if kind == "string" then
+-- code, err = load(f_delayed(code))
+-- if code then
+-- code = code()
+-- end
+-- elseif kind ~= "function" then
+-- code = nil
+-- end
+ if code then
+ local delayed = propdata.delayed
+ if delayed then
+ delayed[#delayed+1] = { where, code, ... }
+ else
+ propdata.delayed = { { where, code, ... } }
+ nofdelayed = nofdelayed + 1
+ end
+ end
+end
+
+function actions.fdelayed(target,head,where,propdata,code,...) -- this one is used at the tex end
+-- local kind = type(code)
+-- if kind == "string" then
+-- code, err = load(f_delayed(code))
+-- if code then
+-- code = code()
+-- end
+-- elseif kind ~= "function" then
+-- code = nil
+-- end
+ if code then
+ local delayed = propdata.delayed
+ if delayed then
+ delayed[#delayed+1] = { false, code, ... }
+ else
+ propdata.delayed = { { false, code, ... } }
+ nofdelayed = nofdelayed + 1
+ end
+ end
+end
+
+function actions.immediate(target,head,where,propdata,code,...) -- this one is used at the tex end
+ local kind = type(code)
+ if kind == "string" then
+ local f = f_immediate(code)
+ local okay, err = load(f)
+ if okay then
+ local h = okay()(target,head,where,propdata,...)
+ if h and h ~= head then
+ return h
+ end
+ end
+ elseif kind == "function" then
+ local h = code()(target,head,where,propdata,...)
+ if h and h ~= head then
+ return h
+ end
+ end
+end
+
+-- another experiment (a table or function closure are equally efficient); a function
+-- is easier when we want to experiment with different (compatible) implementations
+
+-- function nodes.nuts.pool.deferredfunction(...)
+-- nofdelayed = nofdelayed + 1
+-- local n = nut_usernumber(property_id,0)
+-- propertydata[n] = { deferred = { ... } }
+-- return n
+-- end
+
+-- function nodes.nuts.pool.deferredfunction(f)
+-- nofdelayed = nofdelayed + 1
+-- local n = nut_usernumber(property_id,0)
+-- propertydata[n] = { deferred = f }
+-- return n
+-- end
+
+-- maybe actions will get parent too
+
+local function delayed(head,parent) -- direct based
+ for target in traverse(head) do
+ local p = propertydata[target]
+ if p then
+ -- local deferred = p.deferred -- kind of late lua (but too soon as we have no access to pdf.h/v)
+ -- if deferred then
+ -- -- if #deferred > 0 then
+ -- -- deferred[1](unpack(deferred,2))
+ -- -- else
+ -- -- deferred[1]()
+ -- -- end
+ -- deferred()
+ -- p.deferred = false
+ -- if nofdelayed == 1 then
+ -- nofdelayed = 0
+ -- return head
+ -- else
+ -- nofdelayed = nofdelayed - 1
+ -- end
+ -- else
+ local delayed = p.delayed
+ if delayed then
+ for i=1,#delayed do
+ local d = delayed[i]
+ local code = d[2]
+ local kind = type(code)
+ if kind == "string" then
+ code, err = load(f_delayed(code))
+ if code then
+ code = code()
+ end
+ end
+ local where = d[1]
+ if where then
+ local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent
+ if h and h ~= head then
+ head = h
+ end
+ else
+ code(unpack(d,3))
+ end
+ end
+ p.delayed = nil
+ if nofdelayed == 1 then
+ nofdelayed = 0
+ return head
+ else
+ nofdelayed = nofdelayed - 1
+ end
+ end
+ -- end
+ end
+ local id = getid(target)
+ if id == hlist_code or id == vlist_code then
+ local list = getlist(target)
+ if list then
+ local done = delayed(list,parent)
+ if done then
+ setfield(target,"list",done)
+ end
+ if nofdelayed == 0 then
+ return head
+ end
+ end
+ else
+ -- maybe also some more lists? but we will only use this for some
+ -- special cases .. who knows
+ end
+ end
+ return head
+end
+
+function properties.delayed(head) --
+ if nofdelayed > 0 then
+ -- if next(propertydata) then
+ starttiming(properties)
+ head = delayed(tonut(head))
+ stoptiming(properties)
+ return tonode(head), true -- done in shipout anyway
+ -- else
+ -- delayed = 0
+ -- end
+ end
+ return head, false
+end
+
+-- more explicit ones too
+
+local anchored = {
+ [v_before] = function(n)
+ while n do
+ n = getprev(n)
+ if getid(n) == whatsit_code and getsubtype(n) == user_code and getfield(n,"user_id") == property_id then
+ -- continue
+ else
+ return n
+ end
+ end
+ end,
+ [v_after] = function(n)
+ while n do
+ n = getnext(n)
+ if getid(n) == whatsit_code then
+ local subtype = getsubtype(n)
+ if (subtype == userdefined_code and getfield(n,"user_id") == property_id) then
+ -- continue
+ elseif subtype == localpar_code then
+ -- continue .. can't happen anyway as we cannot write
+ else
+ return n
+ end
+ else
+ return n
+ end
+ end
+ end,
+ [v_here] = function(n)
+ -- todo
+ end,
+}
+
+table.setmetatableindex(anchored,function(t,k)
+ v = anchored[v_after]
+ t[k] = v
+ return v
+end)
+
+function properties.attach(head)
+
+ if nofslots <= 0 then
+ return head, false
+ end
+
+ local done = false
+ local last = nil
+ local head = tonut(head)
+
+ starttiming(properties)
+
+ for source in traverse_id(whatsit_code,head) do
+ if getsubtype(source) == userdefined_code then
+ if last then
+ removenode(head,last,true)
+ last = nil
+ end
+ if getfield(source,"user_id") == property_id then
+ local slot = getfield(source,"value")
+ local data = cache[slot]
+ if data then
+ cache[slot] = nil
+ local where = data[1]
+ local target = anchored[where](source)
+ if target then
+ local first = data[2]
+ local method = type(first)
+ local p_target = propertydata[target]
+ local p_source = propertydata[source]
+ if p_target then
+ if p_source then
+ for k, v in next, p_source do
+ p_target[k] = v
+ end
+ end
+ if method == "table" then
+ for k, v in next, first do
+ p_target[k] = v
+ end
+ elseif method == "function" then
+ first(target,head,where,p_target,unpack(data,3))
+ elseif method == "string" then
+ actions[first](target,head,where,p_target,unpack(data,3))
+ end
+ elseif p_source then
+ if method == "table" then
+ propertydata[target] = p_source
+ for k, v in next, first do
+ p_source[k] = v
+ end
+ elseif method == "function" then
+ propertydata[target] = p_source
+ first(target,head,where,p_source,unpack(data,3))
+ elseif method == "string" then
+ propertydata[target] = p_source
+ actions[first](target,head,where,p_source,unpack(data,3))
+ end
+ else
+ if method == "table" then
+ propertydata[target] = first
+ elseif method == "function" then
+ local t = { }
+ propertydata[target] = t
+ first(target,head,where,t,unpack(data,3))
+ elseif method == "string" then
+ local t = { }
+ propertydata[target] = t
+ actions[first](target,head,where,t,unpack(data,3))
+ end
+ end
+ if trace_setting then
+ report_setting("node %i, id %s, data %s",
+ target,nodecodes[getid(target)],serialize(propertydata[target],false))
+ end
+ end
+ if nofslots == 1 then
+ nofslots = 0
+ last = source
+ break
+ else
+ nofslots = nofslots - 1
+ end
+ end
+ last = source
+ end
+ end
+ end
+
+ if last then
+ removenode(head,last,true)
+ end
+
+ stoptiming(properties)
+
+ return head, done
+
+end
+
+local tasks = nodes.tasks
+
+-- maybe better hard coded in-place
+
+-- tasks.prependaction("processors","before","nodes.properties.attach")
+-- tasks.appendaction("shipouts","normalizers","nodes.properties.delayed")
+
+statistics.register("properties processing time", function()
+ return statistics.elapsedseconds(properties)
+end)
+
+-- only for development
+
+-- local function show(head,level,report)
+-- for target in traverse(head) do
+-- local p = propertydata[target]
+-- if p then
+-- report("level %i, node %i, id %s, data %s",
+-- level,target,nodecodes[getid(target)],serialize(propertydata[target],false))
+-- end
+-- local id = getid(target)
+-- if id == hlist_code or id == vlist_code then
+-- local list = getlist(target)
+-- if list then
+-- show(list,level+1,report)
+-- end
+-- else
+-- -- maybe more lists
+-- end
+-- end
+-- return head, false
+-- end
+--
+-- local report_shipout = logs.reporter("properties","shipout")
+-- local report_processors = logs.reporter("properties","processors")
+--
+-- function properties.showshipout (head) return tonode(show(tonut(head),1,report_shipout )), true end
+-- function properties.showprocessors(head) return tonode(show(tonut(head),1,report_processors)), true end
+--
+-- tasks.prependaction("shipouts","before","nodes.properties.showshipout")
+-- tasks.disableaction("shipouts","nodes.properties.showshipout")
+--
+-- trackers.register("properties.shipout",function(v)
+-- tasks.setaction("shipouts","nodes.properties.showshipout",v)
+-- end)
+--
+-- tasks.appendaction ("processors","after","nodes.properties.showprocessors")
+-- tasks.disableaction("processors","nodes.properties.showprocessors")
+--
+-- trackers.register("properties.processors",function(v)
+-- tasks.setaction("processors","nodes.properties.showprocessors",v)
+-- end)
diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua
index 7cfbde849..c55db4ea3 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)
@@ -228,14 +228,25 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx
local id = getid(current)
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
- -- test \goto{test}[page(2)] test \gotobox{test}[page(2)]
- -- so let's wait till this fails again
- -- if not reference and r and (not skip or r > skip) then -- > or ~=
- if r and (not skip or r > skip) then -- > or ~=
- inject_list(id,current,r,make,stack,pardir,txtdir)
- end
+ -- test \goto{test}[page(2)] test \gotobox{test}[page(2)]
+ -- test \goto{\TeX}[page(2)] test \gotobox{\hbox {x} \hbox {x}}[page(2)]
+ -- if r and (not skip or r >) skip then -- maybe no > test
+ -- inject_list(id,current,r,make,stack,pardir,txtdir)
+ -- end
if r then
+ if not reference then
+ reference, first, last, firstdir = r, current, current, txtdir
+ elseif r == reference then
+ -- same link
+ last = current
+ elseif (done[reference] or 0) == 0 then
+ if not skip or r > skip then -- maybe no > test
+ head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir)
+ reference, first, last, firstdir = nil, nil, nil, nil
+ end
+ else
+ reference, first, last, firstdir = r, current, current, txtdir
+ end
done[r] = (done[r] or 0) + 1
end
local list = getlist(current)
@@ -297,7 +308,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 +440,7 @@ annot = tonut(annot)
end
if current then
setfield(current,"next",annot)
+ setfield(annot,"prev",current)
else
result = annot
end
@@ -503,32 +515,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..1a9d6f02e 100644
--- a/tex/context/base/node-res.lua
+++ b/tex/context/base/node-res.lua
@@ -69,11 +69,15 @@ local getbox = nuts.getbox
local getfield = nuts.getfield
local setfield = nuts.setfield
local getid = nuts.getid
+local getlist = nuts.getlist
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
@@ -253,6 +257,19 @@ function nutpool.glue(width,stretch,shrink,stretch_order,shrink_order)
return someskip(glue,width,stretch,shrink,stretch_order,shrink_order)
end
+function nutpool.negatedglue(glue)
+ local n = copy_nut(glue)
+ local s = copy_nut(getfield(n,"spec"))
+ local width = getfield(s,"width")
+ local stretch = getfield(s,"stretch")
+ local shrink = getfield(s,"shrink")
+ if width then setfield(s,"width", -width) end
+ if stretch then setfield(s,"stretch",-stretch) end
+ if shrink then setfield(s,"shrink", -shrink) end
+ setfield(n,"spec",s)
+ return n
+end
+
function nutpool.leftskip(width,stretch,shrink,stretch_order,shrink_order)
return someskip(leftskip,width,stretch,shrink,stretch_order,shrink_order)
end
@@ -288,19 +305,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)
@@ -444,6 +527,7 @@ local function cleanup(nofboxes) -- todo
for i=0,nofboxes do
local l = getbox(i)
if l then
+-- print(nodes.listtoutf(getlist(l)))
free_nut(l) -- also list ?
nl = nl + 1
end
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-lin.lua b/tex/context/base/page-lin.lua
index 66b7e4684..0b241240c 100644
--- a/tex/context/base/page-lin.lua
+++ b/tex/context/base/page-lin.lua
@@ -39,10 +39,16 @@ local v_page = variables.page
local v_no = variables.no
local nodecodes = nodes.nodecodes
+local skipcodes = nodes.skipcodes
+local whatcodes = nodes.whatcodes
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local whatsit_code = nodecodes.whatsit
+local glue_code = nodecodes.glue
+local glyph_code = nodecodes.glyph
+local leftskip_code = skipcodes.leftskip
+local textdir_code = whatcodes.dir
local a_displaymath = attributes.private('displaymath')
local a_linenumber = attributes.private('linenumber')
@@ -56,6 +62,7 @@ local chunksize = 250 -- not used in boxed
local nuts = nodes.nuts
local getid = nuts.getid
+local getsubtype = nuts.getsubtype
local getnext = nuts.getnext
local getattr = nuts.getattr
local getlist = nuts.getlist
@@ -73,6 +80,12 @@ local insert_node_before = nuts.insert_before
local is_display_math = nuts.is_display_math
local leftmarginwidth = nuts.leftmarginwidth
+local negated_glue = nuts.pool.negatedglue
+local new_hlist = nuts.pool.hlist
+
+local ctx_convertnumber = context.convertnumber
+local ctx_makelinenumber = context.makelinenumber
+
-- cross referencing
function lines.number(n)
@@ -122,7 +135,7 @@ filters.line = filters.line or { }
function filters.line.default(data)
-- helpers.title(data.entries.linenumber or "?",data.metadata)
- context.convertnumber(data.entries.conversion or "numbers",data.entries.linenumber or "0")
+ ctx_convertnumber(data.entries.conversion or "numbers",data.entries.linenumber or "0")
end
function filters.line.page(data,prefixspec,pagespec) -- redundant
@@ -195,7 +208,7 @@ local function check_number(n,a,skip,sameline)
report_lines("skipping line number %s for setup %a: %s (%s)",#current_list,a,s,d.continue or v_no)
end
end
- context.makelinenumber(tag,skipflag,s,getfield(n,"shift"),getfield(n,"width"),leftmarginwidth(getlist(n)),getfield(n,"dir"))
+ ctx_makelinenumber(tag,skipflag,s,getfield(n,"shift"),getfield(n,"width"),leftmarginwidth(getlist(n)),getfield(n,"dir"))
end
end
@@ -206,17 +219,18 @@ end
local function identify(list)
if list then
for n in traverse_id(hlist_code,list) do
- if getattr(n,a_linenumber) then
- return list
+ local a = getattr(n,a_linenumber)
+ if a then
+ return list, a
end
end
local n = list
while n do
local id = getid(n)
if id == hlist_code or id == vlist_code then
- local ok = identify(getlist(n))
+ local ok, a = identify(getlist(n))
if ok then
- return ok
+ return ok, a
end
end
n = getnext(n)
@@ -236,65 +250,141 @@ function boxed.stage_one(n,nested)
current_list = { }
local box = getbox(n)
if box then
- local list = getlist(box)
- if nested then
- list = identify(list)
+ local found = nil
+ local list = getlist(box)
+ if list and nested then
+ list, found = identify(list)
end
- local last_a, last_v, skip = nil, -1, false
- for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found
- if getfield(n,"height") == 0 and getfield(n,"depth") == 0 then
- -- skip funny hlists -- todo: check line subtype
- else
- local list = getlist(n)
- local a = getattr(list,a_linenumber)
- if a and a > 0 then
- if last_a ~= a then
- local da = data[a]
- local ma = da.method
- if ma == v_next then
- skip = true
- elseif ma == v_page then
- da.start = 1 -- eventually we will have a normal counter
- end
- last_a = a
- if trace_numbers then
- report_lines("starting line number range %s: start %s, continue %s",a,da.start,da.continue or v_no)
+ if list then
+ local last_a, last_v, skip = nil, -1, false
+ for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found
+ if getfield(n,"height") == 0 and getfield(n,"depth") == 0 then
+ -- skip funny hlists -- todo: check line subtype
+ else
+ local list = getlist(n)
+ local a = getattr(list,a_linenumber)
+ if not a or a == 0 then
+ local n = getnext(list)
+ while n do
+ local id = getid(n)
+ if id == whatsit_code and getsubtype(n) == textdir_code then
+ n = getnext(n)
+ elseif id == glue_code and getsubtype(n) == leftskip_code then
+ n = getnext(n)
+ else
+if id == glyph_code then
+ break
+else
+ -- can be hlist or skip (e.g. footnote line)
+ n = getnext(n)
+end
+ end
end
+ a = n and getattr(n,a_linenumber)
end
- if getattr(n,a_displaymath) then
- if is_display_math(n) then
- check_number(n,a,skip)
+ if a and a > 0 then
+ if last_a ~= a then
+ local da = data[a]
+ local ma = da.method
+ if ma == v_next then
+ skip = true
+ elseif ma == v_page then
+ da.start = 1 -- eventually we will have a normal counter
+ end
+ last_a = a
+ if trace_numbers then
+ report_lines("starting line number range %s: start %s, continue %s",a,da.start,da.continue or v_no)
+ end
end
- else
- local v = getattr(list,a_verbatimline)
- if not v or v ~= last_v then
- last_v = v
- check_number(n,a,skip)
+ if getattr(n,a_displaymath) then
+ if is_display_math(n) then
+ check_number(n,a,skip)
+ end
else
- check_number(n,a,skip,true)
+ local v = getattr(list,a_verbatimline)
+ if not v or v ~= last_v then
+ last_v = v
+ check_number(n,a,skip)
+ else
+ check_number(n,a,skip,true)
+ end
end
+ skip = false
end
- skip = false
end
end
end
end
end
+-- [dir][leftskip][content]
+
+function boxed.stage_two(n,m)
+ if #current_list > 0 then
+ m = m or lines.scratchbox
+ local t, tn = { }, 0
+ for l in traverse_id(hlist_code,getlist(getbox(m))) do
+ tn = tn + 1
+ t[tn] = copy_node(l) -- use take_box instead
+ end
+ for i=1,#current_list do
+ local li = current_list[i]
+ local n, m, ti = li[1], li[2], t[i]
+ if ti then
+ local l = getlist(n)
+ -- we want to keep leftskip at the start
+-- local id = getid(l)
+-- if id == whatsit_code and getsubtype(l) == textdir_code then
+-- l = getnext(l)
+-- id = getid(l)
+-- end
+-- if getid(l) == glue_code and getsubtype(l) == leftskip_code then
+-- -- [leftskip] [number] [rest]
+-- local forward = copy_node(l)
+-- local backward = negated_glue(l)
+-- local next = getnext(l)
+-- setfield(l,"next",backward)
+-- setfield(backward,"prev",l)
+-- setfield(backward,"next",ti)
+-- setfield(ti,"prev",backward)
+-- setfield(ti,"next",forward)
+-- setfield(forward,"prev",ti)
+-- setfield(forward,"next",next)
+-- setfield(next,"prev",forward)
+-- else
+ -- [number] [rest]
+ setfield(ti,"next",l)
+ setfield(l,"prev",ti)
+ setfield(n,"list",ti)
+-- end
+ resolve(n,m)
+ else
+ report_lines("error in linenumbering (1)")
+ return
+ end
+ end
+ end
+end
+
function boxed.stage_two(n,m)
if #current_list > 0 then
m = m or lines.scratchbox
local t, tn = { }, 0
for l in traverse_id(hlist_code,getlist(getbox(m))) do
tn = tn + 1
- t[tn] = copy_node(l)
+ t[tn] = copy_node(l) -- use take_box instead
end
for i=1,#current_list do
local li = current_list[i]
local n, m, ti = li[1], li[2], t[i]
if ti then
- setfield(ti,"next",getlist(n))
- setfield(n,"list",ti)
+ local l = getlist(n)
+ setfield(ti,"next",l)
+ setfield(l,"prev",ti)
+ local h = copy_node(n)
+ setfield(h,"dir","TLT")
+ setfield(h,"list",ti)
+ setfield(n,"list",h)
resolve(n,m)
else
report_lines("error in linenumbering (1)")
diff --git a/tex/context/base/page-lin.mkiv b/tex/context/base/page-lin.mkvi
index ae293091c..e3b628487 100644
--- a/tex/context/base/page-lin.mkiv
+++ b/tex/context/base/page-lin.mkvi
@@ -15,6 +15,7 @@
% get rid of \mk* (left over from experimental times)
%
% to be redone (was experiment) .. can be hooked into margin code
+% reshuffle arguments
\writestatus{loading}{ConTeXt Core Macros / Line Numbering}
@@ -61,14 +62,16 @@
\installcorenamespace{linenumberinginstance}
+% tag skipflag s getfield(n,"shift") getfield(n,"width") leftmarginwidth(getlist(n)) getfield(n,"dir"))
+
\let\makelinenumber\gobblesevenarguments % used at lua end
\newconditional\page_postprocessors_needed_box
-\unexpanded\def\page_postprocessors_linenumbers_page #1{\page_lines_add_numbers_to_box{#1}\plusone \plusone \zerocount}
-\unexpanded\def\page_postprocessors_linenumbers_box #1{\page_lines_add_numbers_to_box{#1}\plusone \plusone \zerocount}
-\unexpanded\def\page_postprocessors_linenumbers_deepbox#1{\page_lines_add_numbers_to_box{#1}\plusone \plusone \plusone }
-\unexpanded\def\page_postprocessors_linenumbers_column #1{\page_lines_add_numbers_to_box{#1}\currentcolumn\nofcolumns\zerocount}
+\unexpanded\def\page_postprocessors_linenumbers_page #tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \zerocount}
+\unexpanded\def\page_postprocessors_linenumbers_box #tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \zerocount}
+\unexpanded\def\page_postprocessors_linenumbers_deepbox#tag{\page_lines_add_numbers_to_box{#tag}\plusone \plusone \plusone }
+\unexpanded\def\page_postprocessors_linenumbers_column #tag{\page_lines_add_numbers_to_box{#tag}\currentcolumn\nofcolumns\zerocount}
\def\page_lines_parameters_regular
{continue = "\ifnum\c_page_lines_mode=\zerocount\v!yes\else\v!no\fi",
@@ -143,47 +146,20 @@
\c!step=1,
\c!method=\v!first,
\c!continue=\v!no,
- \c!location=\v!left,
\c!style=,
\c!color=,
\c!width=2\emwidth,
\c!left=,
\c!right=,
\c!command=,
+ \c!margin=2.5\emwidth,
\c!distance=\zeropoint,
+ \c!location=\v!default, % depends on direction, columns etc
\c!align=\v!auto]
\definelinenumbering
[]
-% no intermediate changes in values, define a class, otherwise each range
-% would need a number
-
-% todo: text
-
-\installcorenamespace{linenumberinglocation}
-\installcorenamespace{linenumberingalternative}
-
-\expandafter\let\csname\??linenumberinglocation\v!middle \endcsname \zerocount
-\expandafter\let\csname\??linenumberinglocation\v!left \endcsname \plusone
-\expandafter\let\csname\??linenumberinglocation\v!margin \endcsname \plusone
-\expandafter\let\csname\??linenumberinglocation\v!inmargin \endcsname \plusone
-\expandafter\let\csname\??linenumberinglocation\v!inleft \endcsname \plusone
-\expandafter\let\csname\??linenumberinglocation\v!right \endcsname \plustwo
-\expandafter\let\csname\??linenumberinglocation\v!inright \endcsname \plustwo
-\expandafter\let\csname\??linenumberinglocation\v!inner \endcsname \plusthree
-\expandafter\let\csname\??linenumberinglocation\v!outer \endcsname \plusfour
-\expandafter\let\csname\??linenumberinglocation\v!text \endcsname \plusfive
-\expandafter\let\csname\??linenumberinglocation\v!begin \endcsname \plussix
-\expandafter\let\csname\??linenumberinglocation\v!end \endcsname \plusseven
-
-\expandafter\let\csname\??linenumberingalternative\v!middle \endcsname \zerocount
-\expandafter\let\csname\??linenumberingalternative\v!right \endcsname \plusone
-\expandafter\let\csname\??linenumberingalternative\v!flushleft \endcsname \plusone
-\expandafter\let\csname\??linenumberingalternative\v!left \endcsname \plustwo
-\expandafter\let\csname\??linenumberingalternative\v!flushright\endcsname \plustwo
-\expandafter\let\csname\??linenumberingalternative\v!auto \endcsname \plusfive
-
% \startlinenumbering[<startvalue>|continue|settings|name]
% \startlinenumbering[name][<startvalue>|continue|settings]
@@ -254,8 +230,30 @@
\fi
\page_lines_start_followup}
+\newconditional\c_page_lines_auto_narrow
+
\def\page_lines_start_followup
{\numberinglinestrue
+ \edef\p_location{\linenumberingparameter\c!location}%
+ \setfalse\c_page_lines_auto_narrow
+ \ifhmode \else
+ \ifx\p_location\v!text
+ \ifdim\leftskip>\zeropoint \else
+ \advance\leftskip\linenumberingparameter\c!margin
+ \settrue\c_page_lines_auto_narrow
+ \fi
+ \else\ifx\p_location\v!begin
+ \ifdim\leftskip>\zeropoint \else
+ \advance\leftskip\linenumberingparameter\c!margin
+ \settrue\c_page_lines_auto_narrow
+ \fi
+ \else\ifx\p_location\v!end
+ \ifdim\leftskip>\zeropoint \else
+ \advance\rightskip\linenumberingparameter\c!margin
+ \settrue\c_page_lines_auto_narrow
+ \fi
+ \fi\fi\fi
+ \fi
\the\beforeeverylinenumbering
\globallet\page_postprocessors_page \page_postprocessors_linenumbers_page
\globallet\page_postprocessors_column\page_postprocessors_linenumbers_column
@@ -265,67 +263,39 @@
\or
\page_lines_start_define % only when assignment
\fi
- \attribute\linenumberattribute\getvalue{\??linenumberinginstance\currentlinenumbering}\relax}
+ \attribute\linenumberattribute\csname\??linenumberinginstance\currentlinenumbering\endcsname\relax}
\unexpanded\def\stoplinenumbering
{\attribute\linenumberattribute\attributeunsetvalue
\the\aftereverylinenumbering
+ \ifconditional\c_page_lines_auto_narrow\par\fi
\endgroup}
% number placement .. will change into (the new) margin code
-\def\page_lines_number_inner_indeed{\doifoddpageelse\page_lines_number_left_indeed\page_lines_number_right_indeed}
-\def\page_lines_number_outer_indeed{\doifoddpageelse\page_lines_number_right_indeed\page_lines_number_left_indeed}
-
-\def\page_lines_number_left
- {\ifcase\c_page_lines_location
- \expandafter\page_lines_number_left_indeed
- \or
- \expandafter\page_lines_number_left_indeed
- \or
- \expandafter\page_lines_number_left_indeed
- \or
- \expandafter\page_lines_number_inner_indeed
- \or
- \expandafter\page_lines_number_outer_indeed
- \or
- \expandafter\page_lines_number_text_indeed
- \or
- \expandafter\page_lines_number_begin_indeed
- \or
- \expandafter\page_lines_number_end_indeed
- \fi}
-
-\def\page_lines_number_right
- {\ifcase\c_page_lines_location
- \expandafter\page_lines_number_right_indeed
- \or
- \expandafter\page_lines_number_right_indeed
- \or
- \expandafter\page_lines_number_right_indeed
- \or
- \expandafter\page_lines_number_outer_indeed
- \or
- \expandafter\page_lines_number_inner_indeed
- \or
- \expandafter\page_lines_number_text_indeed
- \or
- \expandafter\page_lines_number_end_indeed
- \or
- \expandafter\page_lines_number_begin_indeed
- \fi}
-
\newconditional\c_page_lines_fake_number
\newconstant \b_page_lines_number
\newconstant \c_page_lines_column
\newconstant \c_page_lines_last_column
+\newdimen \d_page_lines_line_width
+\settrue \c_page_lines_dir_left_to_right
+
+\installcorenamespace{linenumberinghandler}
+
+\def\page_line_swap_align % can become a helper
+ {\ifx\p_align\v!inner \let\p_align\v!outer \else
+ \ifx\p_align\v!outer \let\p_align\v!inner \else
+ \ifx\p_align\v!flushleft \let\p_align\v!flushright\else
+ \ifx\p_align\v!flushright\let\p_align\v!flushleft \else
+ \ifx\p_align\v!left \let\p_align\v!right \else
+ \ifx\p_align\v!right \let\p_align\v!left \fi\fi\fi\fi\fi\fi}
-\def\page_lines_add_numbers_to_box#1#2#3#4% box col max nesting
+\def\page_lines_add_numbers_to_box#box#column#max#nesting%
{\bgroup
- \b_page_lines_number #1\relax
- \c_page_lines_column #2\relax
- \c_page_lines_last_column#3\relax
- \c_page_lines_nesting #4\relax
+ \b_page_lines_number #box\relax
+ \c_page_lines_column #column\relax
+ \c_page_lines_last_column#max\relax
+ \c_page_lines_nesting #nesting\relax
\fullrestoreglobalbodyfont
\let\makelinenumber\page_lines_make_number % used at lua end
\setbox\b_page_lines_scratch\vbox
@@ -337,171 +307,195 @@
\let\page_lines_make_number_indeed\relax
-\def\page_lines_make_number#1#2%
- {\edef\currentlinenumbering{#1}%
- \ifcase#2\relax
- \settrue \c_page_lines_fake_number
+% \def\page_lines_rlap{\ifconditional\c_page_lines_dir_left_to_right\expandafter\rlap\else\expandafter\llap\fi}
+% \def\page_lines_llap{\ifconditional\c_page_lines_dir_left_to_right\expandafter\llap\else\expandafter\rlap\fi}
+
+\def\page_lines_add_numbers_to_box#box#column#max#nesting%
+ {\bgroup
+ \b_page_lines_number #box\relax
+ \c_page_lines_column #column\relax
+ \c_page_lines_last_column#max\relax
+ \c_page_lines_nesting #nesting\relax
+ \fullrestoreglobalbodyfont
+ \let\makelinenumber\page_lines_make_number % used at lua end
+ \setbox\b_page_lines_scratch\vbox
+ {\forgetall
+ \offinterlineskip
+ \ctxcommand{linenumbersstageone(\number\b_page_lines_number,\ifcase\c_page_lines_nesting false\else true\fi)}}%
+ \ctxcommand{linenumbersstagetwo(\number\b_page_lines_number,\number\b_page_lines_scratch)}% can move to lua code
+ \egroup}
+
+\def\page_lines_make_number#tag#mode#linenumber#shift#width#leftskip#dir% beware, one needs so compensate for this in the \hsize
+ {\naturalhbox to \zeropoint \bgroup
+ \ifcase#mode\relax
+ % \settrue \c_page_lines_fake_number
\else
- \setfalse\c_page_lines_fake_number
- \fi
- \c_page_lines_location \executeifdefined{\??linenumberinglocation \linenumberingparameter\c!location}\plusone \relax % left
- \c_page_lines_alignment\executeifdefined{\??linenumberingalternative\linenumberingparameter\c!align }\plusfive\relax % auto
- \ifcase\c_page_lines_last_column\relax
- \settrue \c_page_lines_fake_number
- \or
- % one column
- \ifcase\c_page_lines_location
- \settrue \c_page_lines_fake_number
- \let\page_lines_make_number_indeed\page_lines_number_fake_indeed
- \or
- \let\page_lines_make_number_indeed\page_lines_number_left
- \or
- \let\page_lines_make_number_indeed\page_lines_number_right
- \or % inner
- \let\page_lines_make_number_indeed\page_lines_number_inner_indeed
- \or % outer
- \let\page_lines_make_number_indeed\page_lines_number_outer_indeed
- \or % text
- \let\page_lines_make_number_indeed\page_lines_number_text_indeed
+ % \setfalse\c_page_lines_fake_number
+ \edef\currentlinenumbering{#tag}%
+ \def\linenumber{#linenumber}% unsafe
+ \d_page_lines_line_width#width\scaledpoint\relax
+ \d_page_lines_distance\linenumberingparameter\c!distance\relax
+ \edef\p_align{\linenumberingparameter\c!align}%
+ \edef\p_location{\linenumberingparameter\c!location}%
+ \ifcase\istltdir#dir\relax
+ \settrue \c_page_lines_dir_left_to_right
+ \else
+ \setfalse\c_page_lines_dir_left_to_right
+ \fi
+ %
+ % maybe we also need an option to ignore columns, so that we renumber
+ % once but on the other hand this assumes aligned lines
+ %
+ \ifcase\c_page_lines_last_column\relax
+ \settrue \c_page_lines_fake_number % why
\or
- \let\page_lines_make_number_indeed\page_lines_number_begin_indeed
+ % one column
\or
- \let\page_lines_make_number_indeed\page_lines_number_end_indeed
+ % two columns
+ \ifx\p_location\v!default % or just margin
+ \ifcase\c_page_lines_column\relax
+ \settrue \c_page_lines_fake_number % why
+ \or
+ % one
+ \let\p_location\v!left
+ \else
+ % two
+ \let\p_location\v!right
+ % can become a helper
+ \page_line_swap_align
+ \fi
+ \fi
+ \else
+ % too fuzzy
\fi
- \else\ifcase\c_page_lines_column\relax
- \settrue \c_page_lines_fake_number
- \or
- \let\page_lines_make_number_indeed\page_lines_number_left
- \ifcase\c_page_lines_location\or
- \c_page_lines_location\plusone
- \or
- \c_page_lines_location\plustwo
+ \ifx\p_location\v!default
+ \ifconditional\c_page_lines_dir_left_to_right
+ \let\p_location\v!left
+ \else
+ \let\p_location\v!right
+ \page_line_swap_align % yes or no
+ \fi
+ \fi
+ %
+ \executeifdefined{\??linenumberinghandler\p_location}\relax
+ \fi
+ \egroup}
+
+\def\page_lines_number_inject#align#width%
+ {\edef\p_width{\linenumberingparameter\c!width}%
+ \ifx\p_width\v!margin
+ \d_page_lines_width#width%
+ \else
+ \d_page_lines_width\p_width
+ \fi
+ \relax
+ \ifdim\d_page_lines_width>\zeropoint
+% \ifconditional\c_page_lines_dir_left_to_right\else
+% \let\simplealignedbox\simplereversealignedbox
+% \fi
+ \ifconditional\tracelinenumbering
+ \ruledhbox{\simplealignedbox\d_page_lines_width#align{\page_lines_number_inject_indeed}}%
\else
- \c_page_lines_location\plusone
- \or
- \c_page_lines_location\plusone
- \or
- \c_page_lines_location\plusone
- \or
- \c_page_lines_location\plusone % todo
- \or
- \c_page_lines_location\plusone % todo
+ \simplealignedbox\d_page_lines_width#align{\page_lines_number_inject_indeed}%
\fi
\else
- \let\page_lines_make_number_indeed\page_lines_number_right
- \ifcase\c_page_lines_location\or
- \c_page_lines_location\plustwo
- \or
- \c_page_lines_location\plusone
- \or
- \c_page_lines_location\plustwo
- \or
- \c_page_lines_location\plustwo
- \or
- \c_page_lines_location\plustwo % todo
- \or
- \c_page_lines_location\plustwo % todo
+ \ifconditional\tracelinenumbering
+ \ruledhbox
+ \else
+ % \hbox
\fi
- \fi\fi
- \page_lines_make_number_indeed{#1}}
-
-\let\page_lines_number_fake_indeed\gobblesixarguments % needs checking
-
-\def\page_lines_number_text_indeed#1#2#3#4#5#6% beware, one needs so compensate for this in the \hsize
- {\hbox{\page_lines_number_construct{#1}{2}{#2}{#5}\hskip#3\scaledpoint}}
-
-\def\page_lines_number_left_indeed#1#2#3#4#5#6%
- {\naturalhbox to \zeropoint
- {\ifcase\istltdir#6\else \hskip-#4\scaledpoint \fi
- \llap{\page_lines_number_construct{#1}{2}{#2}{#5}\kern#3\scaledpoint}}}
-
-\def\page_lines_number_right_indeed#1#2#3#4#5#6%
- {\naturalhbox to \zeropoint
- {\ifcase\istltdir#6\else \hskip-#4\scaledpoint \fi
- \rlap{\hskip\dimexpr#4\scaledpoint+#3\scaledpoint\relax\page_lines_number_construct{#1}{1}{#2}{#5}}}}
+ {\page_lines_number_inject_indeed}%
+ \fi}
-\def\page_lines_number_begin_indeed#1#2#3#4#5#6%
- {\ifcase\istltdir#6\relax
- \c_page_lines_location\plusone
- \expandafter\page_lines_number_left_indeed
- \else
- \c_page_lines_location\plustwo
- \expandafter\page_lines_number_left_indeed
- \fi{#1}{#2}{#3}{#4}{#5}{#6}}
-
-\def\page_lines_number_end_indeed#1#2#3#4#5#6%
- {\ifcase\istltdir#6\relax
- \c_page_lines_location\plustwo
- \expandafter\page_lines_number_left_indeed
+\def\page_lines_number_inject_indeed
+ {\uselinenumberingstyleandcolor\c!style\c!color
+ \linenumberingparameter\c!command
+ {\linenumberingparameter\c!left
+ \convertnumber{\linenumberingparameter\c!conversion}\linenumber
+ \linenumberingparameter\c!right}}
+
+% \def\dodorlap{\hbox to \zeropoint{\box\nextbox\normalhss}\endgroup}
+% \def\dodollap{\hbox to \zeropoint{\normalhss\box\nextbox}\endgroup}
+
+\def\page_line_handle_left#align#width#distance%
+ {\llap
+ {\page_lines_number_inject#align#width%
+ \kern\dimexpr#distance+\d_page_lines_distance\relax
+ \the\everylinenumber
+ \hss}}
+
+\def\page_line_handle_right#align#width#distance%
+ {\rlap
+ {\kern\dimexpr#distance+\d_page_lines_distance+\d_page_lines_line_width\relax
+ \page_lines_number_inject#align#width%
+ \the\everylinenumber}}
+
+\setuvalue{\??linenumberinghandler\v!left}%
+ {\page_line_handle_left\p_align\leftmarginwidth\leftmargindistance}
+
+\setuvalue{\??linenumberinghandler\v!right}%
+ {\page_line_handle_right\p_align\rightmarginwidth\rightmargindistance}
+
+\setuvalue{\??linenumberinghandler\v!inner}%
+ {\ifodd\realpageno
+ \ifx\p_align\v!inner
+ \page_line_handle_left\v!flushleft\leftmarginwidth\leftmargindistance
+ \else\ifx\p_align\v!outer
+ \page_line_handle_left\v!flushright\leftmarginwidth\leftmargindistance
+ \else
+ \page_line_handle_left\p_align\leftmarginwidth\leftmargindistance
+ \fi\fi
\else
- \c_page_lines_location\plusone
- \expandafter\page_lines_number_left_indeed
- \fi{#1}{#2}{#3}{#4}{#5}{#6}}
+ \ifx\p_align\v!inner
+ \page_line_handle_right\v!flushright\rightmarginwidth\rightmargindistance
+ \else\ifx\p_align\v!outer
+ \page_line_handle_right\v!flushleft\rightmarginwidth\rightmargindistance
+ \else
+ \page_line_handle_right\p_align\rightmarginwidth\rightmargindistance
+ \fi\fi
+ \fi}
-\def\page_lines_number_construct#1#2#3#4% tag 1=left|2=right linenumber leftskip
- {\begingroup
- \def\currentlinenumbering{#1}%
- \def\linenumber{#3}% unsafe
- \doifelse{\linenumberingparameter\c!width}\v!margin
- {\d_page_lines_width\leftmarginwidth}
- {\d_page_lines_width\linenumberingparameter\c!width}%
- \d_page_lines_distance\linenumberingparameter\c!distance\relax
- \ifcase#2\relax\or\hskip\d_page_lines_distance\fi\relax
- \ifnum\c_page_lines_location=\plusfive
- \scratchdimen\dimexpr#4\scaledpoint-\d_page_lines_distance\relax
- \c_page_lines_location\plusone
+\setuvalue{\??linenumberinghandler\v!outer}%
+ {\ifodd\realpageno
+ \ifx\p_align\v!inner
+ \page_line_handle_right\v!flushleft\leftmarginwidth\leftmargindistance
+ \else\ifx\p_align\v!outer
+ \page_line_handle_right\v!flushright\leftmarginwidth\leftmargindistance
+ \else
+ \page_line_handle_right\p_align\leftmarginwidth\leftmargindistance
+ \fi\fi
\else
- \scratchdimen\zeropoint
- \fi
- \ifcase\c_page_lines_alignment
- \c_page_lines_location\zerocount % middle
- \or
- \c_page_lines_location\plusone % left
- \or
- \c_page_lines_location\plustwo % right
- \fi
- \ifconditional\tracelinenumbering\ruledhbox\else\hbox\fi to \d_page_lines_width
- {\ifcase\c_page_lines_location
- \hss % middle
- \or
- % left
- \or
- \hss % right
- \or
- \doifoddpageelse\relax\hss % inner
- \or
- \doifoddpageelse\hss\relax % outer
- \fi
- \ifconditional\c_page_lines_fake_number
- % we need to reserve space
- \else
- \uselinenumberingstyleandcolor\c!style\c!color
- \linenumberingparameter\c!command
- {\linenumberingparameter\c!left
- \convertnumber{\linenumberingparameter\c!conversion}{#3}%
- \linenumberingparameter\c!right}%
- \fi
- \ifcase\c_page_lines_location
- \hss % middle
- \or
- \hss % left
- \or
- % right
- \or
- \doifoddpageelse\hss\relax % inner
- \or
- \doifoddpageelse\relax\hss % outer
- \fi}%
- \ifcase#2\relax
- \hskip-\scratchdimen
- \or
- \hskip-\scratchdimen
- \or
- \hskip\dimexpr\d_page_lines_distance-\scratchdimen\relax
- \fi
- \relax
- \the\everylinenumber
- \endgroup}
+ \ifx\p_align\v!inner
+ \page_line_handle_left\v!flushright\rightmarginwidth\rightmargindistance
+ \else\ifx\p_align\v!outer
+ \page_line_handle_left\v!flushleft\rightmarginwidth\rightmargindistance
+ \else
+ \page_line_handle_left\p_align\rightmarginwidth\rightmargindistance
+ \fi\fi
+ \fi}
+
+\def\page_line_handle_begin#align%
+ {\rlap
+ {\kern\d_page_lines_distance
+ \page_lines_number_inject#align\zeropoint
+ \the\everylinenumber}}
+
+\def\page_line_handle_end#align%
+ {\rlap
+ {\kern\d_page_lines_line_width\relax
+ \llap
+ {\page_lines_number_inject#align\zeropoint
+ \kern\d_page_lines_distance
+ \the\everylinenumber}}}
+
+\setuvalue{\??linenumberinghandler\v!begin}{\page_line_handle_begin\p_align}
+\setuvalue{\??linenumberinghandler\v!end }{\page_line_handle_end \p_align}
+\setuvalue{\??linenumberinghandler\v!text }{\page_line_handle_begin\p_align}
+
+\setuevalue{\??linenumberinghandler\v!inleft }{\getvalue{\??linenumberinghandler\v!left }}
+\setuevalue{\??linenumberinghandler\v!inmargin}{\getvalue{\??linenumberinghandler\v!left }}
+\setuevalue{\??linenumberinghandler\v!margin }{\getvalue{\??linenumberinghandler\v!left }}
+\setuevalue{\??linenumberinghandler\v!inright }{\getvalue{\??linenumberinghandler\v!right}}
% referencing: \permithyphenation, also removes leading spaces (new per 29-11-2013)
@@ -523,7 +517,6 @@
\expandafter\gobbleoneargument
\fi}
-
\def\page_lines_reference_show_start_indeed#1%
{\setbox\scratchbox\hbox{\llap
{\vrule\s!width\onepoint\s!depth\strutdp\s!height.8\strutht\raise.85\strutht\hbox{\llap{\tt\txx#1}}}}%
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..41897f6dd 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}
@@ -540,6 +542,7 @@
{\ctxcommand{mixfinalize()}%
\setbox\b_page_mix_collected\vbox \bgroup
\ifvoid\b_page_mix_preceding \else
+ \page_postprocessors_linenumbers_deepbox\b_page_mix_preceding
\box\b_page_mix_preceding
\global\d_page_mix_preceding_height\zeropoint
\nointerlineskip
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-run.mkiv b/tex/context/base/page-run.mkiv
index dabf37252..1f2551ebc 100644
--- a/tex/context/base/page-run.mkiv
+++ b/tex/context/base/page-run.mkiv
@@ -79,13 +79,27 @@ local function todimen(name,unit,fmt)
return number.todimen(tex.dimen[name],unit,fmt)
end
-function commands.showlayoutvariables(options)
-
- if options == "" then
+local function checkedoptions(options)
+ if type(options) == "table" then
+ return options
+ elseif not options or options == "" then
options = "pt,cm"
end
+ options = utilities.parsers.settings_to_hash(options)
+ local n = 4
+ for k, v in table.sortedhash(options) do
+ local m = tonumber(k)
+ if m then
+ n = m
+ end
+ end
+ options.n = n
+ return options
+end
+
+function commands.showlayoutvariables(options)
- local options = utilities.parsers.settings_to_hash(options)
+ options = checkedoptions(options)
local dimensions = { "pt", "bp", "cm", "mm", "dd", "cc", "pc", "nd", "nc", "sp", "in" }
@@ -215,6 +229,8 @@ end
function commands.showlayout(options)
+ options = checkedoptions(options)
+
if tex.count.textlevel == 0 then
commands.showlayoutvariables(options)
@@ -225,7 +241,7 @@ function commands.showlayout(options)
context.bgroup()
context.showframe()
context.setuplayout { marking = interfaces.variables.on }
- for i=1,4 do
+ for i=1,(options.n or 4) do
commands.showlayoutvariables(options)
context.page()
end
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.lua b/tex/context/base/publ-ini.lua
index 6bf6714da..e25c57e29 100644
--- a/tex/context/base/publ-ini.lua
+++ b/tex/context/base/publ-ini.lua
@@ -120,13 +120,17 @@ statistics.register("publications load time", function()
end)
luatex.registerstopactions(function()
- logspushtarget("logfile")
- logsnewline()
- report("start used btx commands")
- logsnewline()
+ local done = false
local undefined = csname_id("undefined*crap")
for name, dataset in sortedhash(datasets) do
for command, n in sortedhash(dataset.commands) do
+ if not done then
+ logspushtarget("logfile")
+ logsnewline()
+ report("start used btx commands")
+ logsnewline()
+ done = true
+ end
local c = csname_id(command)
if c and c ~= undefined then
report("%-20s %-20s % 5i %s",name,command,n,"known")
@@ -140,10 +144,12 @@ luatex.registerstopactions(function()
end
end
end
- logsnewline()
- report("stop used btxcommands")
- logsnewline()
- logspoptarget()
+ if done then
+ logsnewline()
+ report("stop used btx commands")
+ logsnewline()
+ logspoptarget()
+ end
end)
-- multipass, we need to sort because hashing is random per run and not per
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..48449d690 100644
--- a/tex/context/base/s-inf-03.mkiv
+++ b/tex/context/base/s-inf-03.mkiv
@@ -343,6 +343,10 @@ show("global","",sameglobal.global,false,_G,builtin,"darkgreen",globals,"darkblu
for k, v in table.sortedpairs(_G) do
if not skipglobal[k] and not obsolete[k] and type(v) == "table" and not marked(v) then
+
+ -- local mt = getmetatable(v)
+ -- print("!!!!!!!!!!",k,v,mt,mt and mt.__index)
+
if basiclua[k] then show(k,"basic lua",sameglobal[k],basiclua[k],v,builtin[k],"darkred", false,false,true)
elseif extralua[k] then show(k,"extra lua",sameglobal[k],extralua[k],v,builtin[k],"darkred", false,false,true)
elseif basictex[k] then show(k,"basic tex",sameglobal[k],basictex[k],v,builtin[k],"darkred", false,false,true)
@@ -352,7 +356,6 @@ for k, v in table.sortedpairs(_G) do
end
end
-
\stopluacode
\stoptext
diff --git a/tex/context/base/s-math-repertoire.mkiv b/tex/context/base/s-math-repertoire.mkiv
index a66d7fc6d..314d23868 100644
--- a/tex/context/base/s-math-repertoire.mkiv
+++ b/tex/context/base/s-math-repertoire.mkiv
@@ -418,13 +418,13 @@
\continueifinputfile{s-math-repertoire.mkiv}
-\showmathcharacterssetbodyfonts{lucidanova,cambria,xits,modern,pagella,termes,bonum}
+\showmathcharacterssetbodyfonts{lucidanova,cambria,xits,modern,pagella,termes,bonum,schola}
\starttext
\doifelse {\getdocumentargument{bodyfont}} {} {
- \setupbodyfont[cambria, 12pt]
+ % \setupbodyfont[cambria, 12pt]
% \setupbodyfont[modern, 12pt]
% \setupbodyfont[lmvirtual, 12pt]
% \setupbodyfont[pxvirtual, 12pt]
@@ -437,6 +437,7 @@
% \setupbodyfont[lucidanova,12pt]
% \setupbodyfont[pagella, 12pt]
% \setupbodyfont[bonum, 12pt]
+ \setupbodyfont[schola, 12pt]
} {
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-ali.mkiv b/tex/context/base/spac-ali.mkiv
index cf95064a2..c13e4ca76 100644
--- a/tex/context/base/spac-ali.mkiv
+++ b/tex/context/base/spac-ali.mkiv
@@ -1035,16 +1035,38 @@
% \simplealignedbox{2cm}{right}{x}
\installcorenamespace{alignsimple}
-
-\setvalue{\??alignsimple\v!right }#1{{#1\hss}}
-\setvalue{\??alignsimple\v!left }#1{{\hss#1}}
-\setvalue{\??alignsimple\v!flushright}#1{{\hss#1}}
-\setvalue{\??alignsimple\v!flushleft }#1{{#1\hss}}
-\setvalue{\??alignsimple\v!middle }#1{{\hss#1\hss}}
+\installcorenamespace{alignsimplereverse}
+
+% todo: also handle \bgroup ... \egroup
+
+\unexpanded\def\spac_align_simple_left #1{{#1\hss}}
+\unexpanded\def\spac_align_simple_right #1{{\hss#1}}
+\unexpanded\def\spac_align_simple_middle#1{{\hss#1\hss}}
+
+\letvalue{\??alignsimple \v!right }\spac_align_simple_left
+\letvalue{\??alignsimple \v!outer }\spac_align_simple_left % not managed! see linenumbers
+\letvalue{\??alignsimple \v!flushleft }\spac_align_simple_left
+\letvalue{\??alignsimple \v!left }\spac_align_simple_right
+\letvalue{\??alignsimple \v!inner }\spac_align_simple_right % not managed! see linenumbers
+\letvalue{\??alignsimple \v!flushright}\spac_align_simple_right
+\letvalue{\??alignsimple \v!middle }\spac_align_simple_middle
+
+\letvalue{\??alignsimplereverse\v!right }\spac_align_simple_right
+\letvalue{\??alignsimplereverse\v!outer }\spac_align_simple_right % not managed! see linenumbers
+\letvalue{\??alignsimplereverse\v!flushleft }\spac_align_simple_right
+\letvalue{\??alignsimplereverse\v!left }\spac_align_simple_left
+\letvalue{\??alignsimplereverse\v!inner }\spac_align_simple_left % not managed! see linenumbers
+\letvalue{\??alignsimplereverse\v!flushright}\spac_align_simple_left
+\letvalue{\??alignsimplereverse\v!middle }\spac_align_simple_middle
\unexpanded\def\simplealignedbox#1#2%
{\hbox to #1\csname\??alignsimple\ifcsname\??alignsimple#2\endcsname#2\else\v!right\fi\endcsname}
+\newconditional\alignsimplelefttoright \settrue\alignsimplelefttoright
+
+\unexpanded\def\simplereversealignedbox#1#2%
+ {\hbox to #1\csname\??alignsimplereverse\ifcsname\??alignsimplereverse#2\endcsname#2\else\v!left\fi\endcsname}
+
% \installnamespace{alignsets}
%
% \setvalue{\??alignsets\v!right }#1#2{\let#1\relax\let#2\hss }
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..3f1fd5c82 100644
--- a/tex/context/base/spac-ver.lua
+++ b/tex/context/base/spac-ver.lua
@@ -8,7 +8,8 @@ if not modules then modules = { } end modules ['spac-ver'] = {
-- we also need to call the spacer for inserts!
--- todo: directly set skips
+-- todo: use lua nodes with lua data (>0.79)
+-- see ** can go when 0.79
-- this code dates from the beginning and is kind of experimental; it
-- will be optimized and improved soon
@@ -120,8 +121,8 @@ builders.vspacing = vspacing
local vspacingdata = vspacing.data or { }
vspacing.data = vspacingdata
-vspacingdata.snapmethods = vspacingdata.snapmethods or { }
-local snapmethods = vspacingdata.snapmethods --maybe some older code can go
+local snapmethods = vspacingdata.snapmethods or { }
+vspacingdata.snapmethods = snapmethods
storage.register("builders/vspacing/data/snapmethods", snapmethods, "builders.vspacing.data.snapmethods")
@@ -535,14 +536,15 @@ local categories = allocate {
[5] = 'disable',
[6] = 'nowhite',
[7] = 'goback',
- [8] = 'together'
+ [8] = 'together', -- not used (?)
+ [9] = 'overlay',
}
vspacing.categories = categories
function vspacing.tocategories(str)
local t = { }
- for s in gmatch(str,"[^, ]") do
+ for s in gmatch(str,"[^, ]") do -- use lpeg instead
local n = tonumber(s)
if n then
t[categories[n]] = true
@@ -553,7 +555,7 @@ function vspacing.tocategories(str)
return t
end
-function vspacing.tocategory(str)
+function vspacing.tocategory(str) -- can be optimized
if type(str) == "string" then
return set.tonumber(vspacing.tocategories(str))
else
@@ -584,15 +586,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 +606,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 +642,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 +776,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]
@@ -853,7 +856,16 @@ end
-- penalty only works well when before skip
-local discard, largest, force, penalty, add, disable, nowhite, goback, together = 0, 1, 2, 3, 4, 5, 6, 7, 8 -- move into function when upvalue 60 issue
+local discard = 0
+local largest = 1
+local force = 2
+local penalty = 3
+local add = 4
+local disable = 5
+local nowhite = 6
+local goback = 7
+local together = 8 -- not used (?)
+local overlay = 9
-- [whatsits][hlist][glue][glue][penalty]
@@ -885,6 +897,108 @@ local function specialpenalty(start,penalty)
end
end
+local function check_experimental_overlay(head,current) -- todo
+ local p = nil
+ local c = current
+ local n = nil
+
+setfield(head,"prev",nil) -- till we have 0.79 **
+
+ local function overlay(p, n, s, mvl)
+ local c = getprev(n)
+ while c and c ~= p do
+ local p = getprev(c)
+ free_node(c)
+ c = p
+ end
+ setfield(n,"prev",nil)
+ if not mvl then
+ setfield(p,"next",n)
+ end
+ local p_ht = getfield(p,"height")
+ local p_dp = getfield(p,"depth")
+ local n_ht = getfield(n,"height")
+ local delta = n_ht + s + p_dp
+ local k = new_kern(-delta)
+ if trace_vspacing then
+ report_vspacing("overlaying, prev height: %p, prev depth: %p, next height: %p, skips: %p, move up: %p",p_ht,p_dp,n_ht,s,delta)
+ end
+ if n_ht > p_ht then
+ -- we should adapt pagetotal ! (need a hook for that)
+ setfield(p,"height",n_ht)
+ end
+ return k
+ end
+
+ while c do
+ local id = getid(c)
+ if id == glue_code or id == penalty_code or id == kern_code then
+ -- skip (actually, remove)
+ c = getnext(c)
+ elseif id == hlist_code then
+ n = c
+ break
+ else
+ break
+ end
+ end
+ if n then
+ -- we have a next line
+ c = current
+ while c do
+ local id = getid(c)
+ if id == glue_code or id == penalty_code then
+ c = getprev(c)
+ elseif id == hlist_code then
+ p = c
+ break
+ else
+ break
+ end
+ end
+ if not p then
+ if a_snapmethod == a_snapvbox then
+ -- quit, we're not on the mvl
+ else
+ -- messy
+ local c = tonut(texlists.page_head)
+ local s = 0
+ while c do
+ local id = getid(c)
+ if id == glue_code then
+ if p then
+ s = s + getfield(getfield(c,"glue_spec"),"width")
+ end
+ elseif id == kern_code then
+ if p then
+ s = s + getfield(c,"kern")
+ end
+ elseif id == penalty_code then
+ -- skip (actually, remove)
+ elseif id == hlist_code then
+ p = c
+ s = 0
+ else
+ p = nil
+ s = 0
+ end
+ c = getnext(c)
+ end
+ if p and p ~= n then
+ local k = overlay(p,n,s,true)
+ insert_node_before(n,n,k)
+ return k, getnext(n)
+ end
+ end
+ elseif p ~= n then
+ local k = overlay(p,n,0,false )
+ insert_node_after(p,p,k)
+ return head, getnext(n)
+ end
+ end
+ return remove_node(head, current, true)
+end
+
local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also pass tail
if trace then
reset_tracing(head)
@@ -900,7 +1014,17 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
if penalty_data then
local p = new_penalty(penalty_data)
if trace then trace_done("flushed due to " .. why,p) end
+if penalty_data >= 10000 then -- or whatever threshold?
+ local prev = getprev(current)
+ if getid(prev) == glue_code then -- maybe go back more, or maybe even push back before any glue
+ -- tricky case: spacing/grid-007.tex: glue penalty glue
+ head = insert_node_before(head,prev,p)
+ else
+ head = insert_node_before(head,current,p)
+ end
+else
head = insert_node_before(head,current,p)
+end
end
if glue_data then
local spec = getfield(glue_data,"spec")
@@ -1059,6 +1183,10 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also
elseif sc == discard then
if trace then trace_skip("discard",sc,so,sp,current) end
head, current = remove_node(head, current, true)
+ elseif sc == overlay then
+ -- todo (overlay following line over previous
+ if trace then trace_skip("overlay",sc,so,sp,current) end
+ head, current = check_experimental_overlay(head,current,a_snapmethod)
elseif ignore_following then
if trace then trace_skip("disabled",sc,so,sp,current) end
head, current = remove_node(head, current, true)
@@ -1403,3 +1531,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..0c84958be 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
@@ -542,6 +546,8 @@
\ignorespaces
\let\spac_lines_stop_correction\spac_lines_stop_correction_yes}
+% still not ok ... will move to the lua end ... needs a final solution
+
\unexpanded\def\spac_lines_stop_correction_yes
{\removeunwantedspaces
\egroup
@@ -549,6 +555,11 @@
\blank[\v!white]%
\snaptogrid\hbox{\box\scratchbox}%
\else
+\blank[\v!nowhite]%
+\ifdim\parskip>\zeropoint
+ % too fuzzy otherwise
+\else
+ % doesn't like whitespace
\ifdim\d_spac_prevdepth<\maxdimen
\unless\ifdim\d_spac_prevdepth<\zeropoint
\ifdim\d_spac_prevdepth<\strutdp \relax
@@ -562,6 +573,7 @@
\fi
\fi
\fi
+\fi
\ifdim\pagegoal<\maxdimen
\blank[\v!white,\the\d_spac_lines_correction_before]% \blank[\v!white]\dotopbaselinecorrection
\fi
@@ -1154,6 +1166,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 +1341,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 +1767,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 +1823,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 ...
@@ -1860,6 +1876,14 @@
\fi\fi
\relax}
+% \strut \hfill first line \blank[overlay] second line \hfill \strut
+%
+% \ruledvbox {
+% \strut \hfill line 1 \blank[overlay]
+% line 2 \hfill \strut \blank[overlay]
+% \strut \hfill line 3 \hfill \strut
+% }
+
\definevspacing[\v!preference][penalty:-500] % goodbreak
\definevspacing[\v!samepage] [penalty:10000] % nobreak
\definevspacing[\v!max] [category:1]
@@ -1867,6 +1891,8 @@
\definevspacing[\v!disable] [category:5]
\definevspacing[\v!nowhite] [category:6]
\definevspacing[\v!back] [category:7]
+% together [category:8]
+\definevspacing[\v!overlay] [category:9]
\definevspacing[\v!always] [category:0]
\definevspacing[\v!weak] [order:0]
\definevspacing[\v!strong] [order:100]
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index ae09bb5ae..f7a228bfc 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..547c0e785 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/status-mkiv.lua b/tex/context/base/status-mkiv.lua
index 339bc24f6..07e912a88 100644
--- a/tex/context/base/status-mkiv.lua
+++ b/tex/context/base/status-mkiv.lua
@@ -3207,6 +3207,12 @@ return {
},
{
category = "lua",
+ filename = "font-inj",
+ loading = "font-lib",
+ status = "okay",
+ },
+ {
+ category = "lua",
filename = "font-ldr",
loading = "on demand",
status = "okay",
@@ -4089,6 +4095,11 @@ return {
},
{
category = "lua",
+ filename = "node-ppt",
+ status = "todo",
+ },
+ {
+ category = "lua",
filename = "node-pro",
status = "todo",
},
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..098b863b9 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}%
@@ -1009,8 +1009,21 @@
\strc_itemgroups_between_command
\fi}
-\unexpanded\def\strc_itemgroups_start_item[#1]% we can reuse more
- {\def\currentitemreference{#1}%
+% c_strc_itemgroups_concat:
+%
+% the problem is that we use leftskip so concat cannot reliable take the height into
+% account; it's .. rather tricky when white space in there anyway (due to \par) .. so
+% we rely on a special blank method
+%
+% \startitemize[n]
+% \item bla
+% \item \startitemize[a]
+% \item bla $\displaystyle\int^{x^{y^4}}$ \item bla
+% \stopitemize
+% \stopitemize
+
+\unexpanded\def\strc_itemgroups_start_item[#reference]% we can reuse more
+ {\def\currentitemreference{#reference}%
\ifconditional\c_strc_itemgroups_text
% begin of item
\else
@@ -1026,10 +1039,12 @@
\strc_itemgroups_start_item_next
\fi
\ifconditional\c_strc_itemgroups_concat
- % \vskip-\dimexpr\lastskip+\lineheight\relax
- \vskip-\lastskip % we cannot use a \dimexpr here because
- \vskip-\lineheight % then we loose the stretch and shrink
- \nobreak
+ % \vskip-\lastskip % we cannot use a \dimexpr here because
+ % \vskip-\lineheight % then we loose the stretch and shrink
+ % \nobreak
+ %
+ \blank[\v!overlay]% new per 2014-03-27
+ %
\setfalse\c_strc_itemgroups_concat
\fi
\dostarttagged\t!item\empty
diff --git a/tex/context/base/strc-lab.mkiv b/tex/context/base/strc-lab.mkiv
index ce4cdcc5e..3e6617126 100644
--- a/tex/context/base/strc-lab.mkiv
+++ b/tex/context/base/strc-lab.mkiv
@@ -58,10 +58,15 @@
{\normalexpanded{\defineconstruction[#1][#3][\s!handler=\v!label,\c!level=#2]}%
\setevalue{\??label#1:\s!parent}{\??label#3}}%
\ifconditional\c_strc_constructions_define_commands
- \setuevalue{\e!next #1}{\strc_labels_next {#1}{\number#2}}% obsolete
- \setuevalue{\c!reset#1}{\strc_labels_reset {#1}{\number#2}}% obsolete
- %setuevalue{\c!set #1}{\strc_labels_set {#1}{\number#2}}% obsolete
- \setuevalue {#1}{\strc_labels_command{#1}}%
+ \setuevalue{\e!next #1}{\strc_labels_next {#1}{\number#2}}% obsolete
+ \setuevalue{\v!reset #1}{\strc_labels_reset {#1}{\number#2}}% obsolete % should be \e!reset anyway
+ %setuevalue{\c!set #1}{\strc_labels_set {#1}{\number#2}}% obsolete
+ \ifcsname\v!current#1\endcsname
+ % we play safe
+ \else
+ \setuevalue{\v!current#1}{\strc_labels_current{#1}}% % obsolete % should be \e!current anyway
+ \fi
+ \setuevalue {#1}{\strc_labels_command{#1}}%
\fi}
% todo: \strc_labels_command for user
@@ -103,6 +108,8 @@
\let\p_strc_constructions_title \empty
\let\p_strc_constructions_number\empty
+\newconditional\c_strc_constructions_number_keep
+
\setvalue{\??constructioninitializer\v!label}%
{\let\currentlabel \currentconstruction
\let\constructionparameter \labelparameter
@@ -117,7 +124,9 @@
\iftrialtypesetting
\strc_counters_save\currentconstructionnumber
\fi
- \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
+ \ifconditional\c_strc_constructions_number_keep \else
+ \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
+ \fi
\else
\setfalse\c_strc_constructions_number_state
\fi
@@ -137,11 +146,12 @@
%D Interfaces:
-\let\strc_labels_command\strc_descriptions_command
+\unexpanded\def\strc_labels_command{\setfalse\c_strc_constructions_number_keep\strc_descriptions_command}
+\unexpanded\def\strc_labels_current{\settrue \c_strc_constructions_number_keep\strc_descriptions_command}
-\unexpanded\def\strc_labels_next {\strc_constructions_next_indeed \namedlabelparameter} % #1#2
-\unexpanded\def\strc_labels_reset{\strc_constructions_reset_indeed\namedlabelparameter} % #1#2
-%unexpanded\def\strc_labels_set {\strc_constructions_set_indeed \namedlabelparameter} % #1#2
+\unexpanded\def\strc_labels_next {\strc_constructions_next_indeed \namedlabelparameter} % #1#2
+\unexpanded\def\strc_labels_reset {\strc_constructions_reset_indeed\namedlabelparameter} % #1#2
+%unexpanded\def\strc_labels_set {\strc_constructions_set_indeed \namedlabelparameter} % #1#2
% similar to enumerations
diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua
index d86368b6a..16160e273 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,22 @@ local function initializer()
end
end
-job.register('structures.lists.collected', tobesaved, initializer)
+local function finalizer()
+ local flaginternals = references.flaginternals
+ local usedviews = references.usedviews
+ for i=1,#tobesaved do
+ local r = tobesaved[i].references
+ if r then
+ local i = r.internal
+ local f = flaginternals[i]
+ if f then
+ r.used = usedviews[i] or true
+ end
+ end
+ end
+end
+
+job.register('structures.lists.collected', tobesaved, initializer, finalizer)
local groupindices = table.setmetatableindex("table")
@@ -139,11 +156,11 @@ end
-- we could use t (as hash key) in order to check for dup entries
-function lists.addto(t)
+function lists.addto(t) -- maybe more more here (saves parsing at the tex end)
local m = t.metadata
local u = t.userdata
if u and type(u) == "string" then
- t.userdata = helpers.touserdata(u) -- nicer at the tex end
+ t.userdata = helpers.touserdata(u)
end
local numberdata = t.numberdata
local group = numberdata and numberdata.group
@@ -158,6 +175,10 @@ function lists.addto(t)
numberdata.numbers = cached[groupindex].numberdata.numbers
end
end
+ local setcomponent = references.setcomponent
+ if setcomponent then
+ setcomponent(t) -- can be inlined
+ end
local r = t.references
local i = r and r.internal or 0 -- brrr
local p = pushed[i]
@@ -167,10 +188,6 @@ function lists.addto(t)
pushed[i] = p
r.listindex = p
end
- local setcomponent = references.setcomponent
- if setcomponent then
- setcomponent(t) -- might move to the tex end
- end
if group then
groupindices[name][group] = p
end
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..60ab66c98 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
@@ -756,7 +760,9 @@
%appendtoks \notesenabledfalse \to \everymarking
\appendtoks \notesenabledfalse \to \everybeforepagebody
-\appendtoks \notesenabledfalse \to \everystructurelist % quick hack
+\appendtoks \notesenabledfalse \to \everystructurelist % quick hack
+\appendtoks \notesenabledfalse \to \everysimplifycommands % quick hack
+\appendtoks \notesenabledfalse \to \everypreroll % quick hack
%D Often we need to process the whole set of notes and to make that
%D fast, we use a token register:
@@ -1242,6 +1248,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
@@ -1298,6 +1305,7 @@
\strc_notes_set_bodyfont
\setbox\scratchbox\hbox
{\strc_notes_flush_inserts}%
+ \page_postprocessors_linenumbers_deepbox\scratchbox
\setbox\scratchbox\hbox
{\setupcurrentnote
[\c!location=,
@@ -1778,19 +1786,19 @@
{\dodoubleempty\strc_notes_symbol}
\def\strc_notes_symbol[#tag][#reference]%
- {\dontleavehmode
- \begingroup
- \edef\currentnote{#tag}%
- \usenotestyleandcolor\c!textstyle\c!textcolor
- \ifnotesenabled
+ {\ifnotesenabled
+ \dontleavehmode
+ \begingroup
+ \edef\currentnote{#tag}%
+ \usenotestyleandcolor\c!textstyle\c!textcolor
\ifsecondargument
\unskip
\noteparameter\c!textcommand{\in[#reference]}% command here?
\else
\noteparameter\c!textcommand\lastnotesymbol % check if command double
\fi
- \fi
- \endgroup}
+ \endgroup
+ \fi}
\unexpanded\def\note
{\dodoubleempty\strc_notes_note}
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..6802027e6 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",
@@ -480,6 +487,7 @@
% currentstructurecomponent => \strc_current_ or just \m_strc_
+
\unexpanded\def\strc_counters_register_component#1#2#3#4#5#6#7[#8][#9]% maybe also nolist
{\begingroup
%
@@ -504,119 +512,153 @@
\fi
%
\ifx\p_hascaption\v!yes
- \xdef\currentstructurecomponentname {#3\s!name}%
- \xdef\currentstructurecomponentlevel {#3\c!level}%
- \edef\currentstructurecomponentexpansion {#3\c!expansion}%
- \xdef\currentstructurecomponentxmlsetup {#3\c!xmlsetup}%
- \xdef\currentstructurecomponentcatcodes {#3\s!catcodes}%
- \xdef\currentstructurecomponentlabel {#3\c!label}%
- \xdef\currentstructurecomponentreference {#3\c!reference}%
- \xdef\currentstructurecomponentreferenceprefix{#3\c!referenceprefix}%
- \ifx\currentstructurecomponentexpansion\s!xml
- \xmlstartraw
- \xdef\currentstructurecomponenttitle {#3\c!title}%
- \xdef\currentstructurecomponentbookmark{#3\c!bookmark}%
- \xdef\currentstructurecomponentmarking {#3\c!marking}%
- \xdef\currentstructurecomponentlist {#3\c!list}%
- \xmlstopraw
- \ifx\currentstructurecomponentlist\empty
- \globallet\currentstructurecomponentlist\currentstructurecomponenttitle
- \fi
- \globallet\currentstructurecomponentcoding\s!xml
+ \strc_counters_register_component_list{#1}{#3}{#4}{#9}%
+ \else\ifx\currentstructurecomponentreference\empty
+ \strc_counters_register_component_none
+ \else
+ \strc_counters_register_component_page{#3}%
+ \fi\fi
+ \endgroup}
+
+\def\strc_counters_register_component_none
+ {\glet\m_strc_counters_last_registered_index \relax
+ \glet\m_strc_counters_last_registered_attribute \attributeunsetvalue
+ \glet\m_strc_counters_last_registered_synchronize\relax}
+
+\def\strc_counters_register_component_page#1%
+ {\xdef\currentstructurecomponentreference {#1\c!reference}%
+ \xdef\currentstructurecomponentreferenceprefix{#1\c!referenceprefix}%
+ % maybe have a helper in strc-ref.mkvi
+ \setnextinternalreference
+ \ctxcommand{setreferenceattribute(% can be helper with less passed
+ "\s!page",
+ "\currentstructurecomponentreferenceprefix",
+ "\currentstructurecomponentreference",
+ {
+ references = {
+ internal = \nextinternalreference,
+ block = "\currentsectionblock",
+ section = structures.sections.currentid(),
+ },
+ metadata = {
+ kind = "page",
+ },
+ },
+ "\interactionparameter\c!focus")
+ }%
+ \xdef\m_strc_counters_last_registered_attribute {\the\lastdestinationattribute}%
+ \glet\m_strc_counters_last_registered_index \relax
+ \glet\m_strc_counters_last_registered_synchronize\relax}
+
+\def\strc_counters_register_component_list#1#2#3#4%
+ {\xdef\currentstructurecomponentname {#2\s!name}%
+ \xdef\currentstructurecomponentlevel {#2\c!level}%
+ \edef\currentstructurecomponentexpansion {#2\c!expansion}%
+ \xdef\currentstructurecomponentxmlsetup {#2\c!xmlsetup}%
+ \xdef\currentstructurecomponentcatcodes {#2\s!catcodes}%
+ \xdef\currentstructurecomponentlabel {#2\c!label}%
+ \xdef\currentstructurecomponentreference {#2\c!reference}%
+ \xdef\currentstructurecomponentreferenceprefix{#2\c!referenceprefix}%
+ \ifx\currentstructurecomponentexpansion\s!xml
+ \xmlstartraw
+ \xdef\currentstructurecomponenttitle {#2\c!title}%
+ \xdef\currentstructurecomponentbookmark{#2\c!bookmark}%
+ \xdef\currentstructurecomponentmarking {#2\c!marking}%
+ \xdef\currentstructurecomponentlist {#2\c!list}%
+ \xmlstopraw
+ \ifx\currentstructurecomponentlist\empty
+ \globallet\currentstructurecomponentlist\currentstructurecomponenttitle
+ \fi
+ \globallet\currentstructurecomponentcoding\s!xml
+ \else
+ \ifx\currentstructurecomponentexpansion\v!yes
+ \xdef\currentstructurecomponenttitle {#2\c!title}%
+ \xdef\currentstructurecomponentbookmark{#2\c!bookmark}%
+ \xdef\currentstructurecomponentmarking {#2\c!marking}%
+ \xdef\currentstructurecomponentlist {#2\c!list}%
\else
- \ifx\currentstructurecomponentexpansion\v!yes
- \xdef\currentstructurecomponenttitle {#3\c!title}%
- \xdef\currentstructurecomponentbookmark{#3\c!bookmark}%
- \xdef\currentstructurecomponentmarking {#3\c!marking}%
- \xdef\currentstructurecomponentlist {#3\c!list}%
- \else
- \xdef\currentstructurecomponenttitle {#4\c!title}%
- \xdef\currentstructurecomponentbookmark{#4\c!bookmark}%
- \xdef\currentstructurecomponentmarking {#4\c!marking}%
- \xdef\currentstructurecomponentlist {#4\c!list}%
- \iflocation \ifx\currentstructurecomponentbookmark\empty
- \begingroup
- \simplifycommands
- \xdef\currentstructurecomponentbookmark{\detokenize\expandafter{\normalexpanded{#3\c!title}}}%
- \endgroup
- \fi \fi
- \fi
- \ifx\currentstructurecomponentlist\empty
- \globallet\currentstructurecomponentlist\currentstructurecomponenttitle
- \fi
- \globallet\currentstructurecomponentcoding\s!tex
+ \xdef\currentstructurecomponenttitle {#3\c!title}%
+ \xdef\currentstructurecomponentbookmark{#3\c!bookmark}%
+ \xdef\currentstructurecomponentmarking {#3\c!marking}%
+ \xdef\currentstructurecomponentlist {#3\c!list}%
+ \iflocation \ifx\currentstructurecomponentbookmark\empty
+ \begingroup
+ \simplifycommands
+ \xdef\currentstructurecomponentbookmark{\detokenize\expandafter{\normalexpanded{#2\c!title}}}%
+ \endgroup
+ \fi \fi
\fi
- %
- \setnextinternalreference
- \xdef\m_strc_counters_last_registered_index{\ctxcommand{addtolist{
- metadata = {
- kind = "#1",
- name = "\currentname",
- level = structures.sections.currentlevel(),
- catcodes = \the\ifx\currentstructurecomponentcatcodes\empty\catcodetable\else\csname\currentstructurecomponentcatcodes\endcsname\fi,
- coding = "\currentstructurecomponentcoding",
- \ifx\currentstructurecomponentcoding\s!xml
- xmlroot = "\xmldocument",
- \fi
- \ifx\currentstructurecomponentxmlsetup\empty \else
- xmlsetup = "\currentstructurexmlsetup",
- \fi
- },
- references = {
- internal = \nextinternalreference,
- block = "\currentsectionblock",
- reference = "\currentstructurecomponentreference",
- referenceprefix = "\currentstructurecomponentreferenceprefix",
- section = structures.sections.currentid(),
- },
- titledata = {
- label = \!!bs\detokenize\expandafter{\currentstructurecomponentlabel }\!!es,
- title = \!!bs\detokenize\expandafter{\currentstructurecomponenttitle }\!!es,
- \ifx\currentstructurecomponentbookmark\currentstructurecomponenttitle \else
- bookmark = \!!bs\detokenize\expandafter{\currentstructurecomponentbookmark }\!!es,
- \fi
- \ifx\currentstructurecomponentmarking\currentstructurecomponenttitle \else
- marking = \!!bs\detokenize\expandafter{\currentstructurecomponentmarking }\!!es,
- \fi
- \ifx\currentstructurecomponentlist\currentstructurecomponenttitle \else
- list = \!!bs\detokenize\expandafter{\currentstructurecomponentlist}\!!es,
- \fi
- },
+ \ifx\currentstructurecomponentlist\empty
+ \globallet\currentstructurecomponentlist\currentstructurecomponenttitle
+ \fi
+ \globallet\currentstructurecomponentcoding\s!tex
+ \fi
+ %
+ \setnextinternalreference
+ \xdef\m_strc_counters_last_registered_index{\ctxcommand{addtolist{
+ metadata = {
+ kind = "#1",
+ name = "\currentname",
+ level = structures.sections.currentlevel(),
+ catcodes = \the\ifx\currentstructurecomponentcatcodes\empty\catcodetable\else\csname\currentstructurecomponentcatcodes\endcsname\fi,
+ coding = "\currentstructurecomponentcoding",
+ \ifx\currentstructurecomponentcoding\s!xml
+ xmlroot = "\xmldocument",
+ \fi
+ \ifx\currentstructurecomponentxmlsetup\empty \else
+ xmlsetup = "\currentstructurexmlsetup",
+ \fi
+ },
+ references = {
+ internal = \nextinternalreference,
+ block = "\currentsectionblock",
+ reference = "\currentstructurecomponentreference",
+ referenceprefix = "\currentstructurecomponentreferenceprefix",
+ section = structures.sections.currentid(),
+ },
+ titledata = {
+ label = \!!bs\detokenize\expandafter{\currentstructurecomponentlabel }\!!es,
+ title = \!!bs\detokenize\expandafter{\currentstructurecomponenttitle }\!!es,
+ \ifx\currentstructurecomponentbookmark\currentstructurecomponenttitle \else
+ bookmark = \!!bs\detokenize\expandafter{\currentstructurecomponentbookmark}\!!es,
+ \fi
+ \ifx\currentstructurecomponentmarking\currentstructurecomponenttitle \else
+ marking = \!!bs\detokenize\expandafter{\currentstructurecomponentmarking }\!!es,
+ \fi
+ \ifx\currentstructurecomponentlist\currentstructurecomponenttitle \else
+ list = \!!bs\detokenize\expandafter{\currentstructurecomponentlist}\!!es,
+ \fi
+ },
\ifx\p_hasnumber\v!yes
- prefixdata = {
- prefix = "#3\c!prefix",
- separatorset = "#3\c!prefixseparatorset",
- conversion = \!!bs#3\c!prefixconversion\!!es,
- conversionset = "#3\c!prefixconversionset",
- set = "#3\c!prefixset",
- % segments = "#3\c!prefixsegments",
- segments = "\p_prefixsegments",
- connector = \!!bs#3\c!prefixconnector\!!es,
- },
- numberdata = { % more helpers here, like compact elsewhere
- numbers = structures.counters.compact("\currentcounter",nil,true),
- group = "#3\c!group",
- groupsuffix = \!!bs#3\c!groupsuffix\!!es,
- counter = "\currentcounter",
- separatorset = "#3\c!numberseparatorset",
- conversion = \!!bs#3\c!numberconversion\!!es,
- conversionset = "#3\c!numberconversionset",
- starter = \!!bs#3\c!numberstarter\!!es,
- stopper = \!!bs#3\c!numberstopper\!!es,
- segments = "#3\c!numbersegments",
- },
+ prefixdata = {
+ prefix = "#2\c!prefix",
+ separatorset = "#2\c!prefixseparatorset",
+ conversion = \!!bs#2\c!prefixconversion\!!es,
+ conversionset = "#2\c!prefixconversionset",
+ set = "#2\c!prefixset",
+ % segments = "#2\c!prefixsegments",
+ segments = "\p_prefixsegments",
+ connector = \!!bs#2\c!prefixconnector\!!es,
+ },
+ numberdata = { % more helpers here, like compact elsewhere
+ numbers = structures.counters.compact("\currentcounter",nil,true),
+ group = "#2\c!group",
+ groupsuffix = \!!bs#2\c!groupsuffix\!!es,
+ counter = "\currentcounter",
+ separatorset = "#2\c!numberseparatorset",
+ conversion = \!!bs#2\c!numberconversion\!!es,
+ conversionset = "#2\c!numberconversionset",
+ starter = \!!bs#2\c!numberstarter\!!es,
+ stopper = \!!bs#2\c!numberstopper\!!es,
+ segments = "#2\c!numbersegments",
+ },
\fi
- 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)}}%
- \xdef\m_strc_counters_last_registered_synchronize{\ctxlatecommand{enhancelist(\m_strc_counters_last_registered_index)}}%
- \else
- \glet\m_strc_counters_last_registered_index \relax
- \glet\m_strc_counters_last_registered_attribute \attributeunsetvalue
- \glet\m_strc_counters_last_registered_synchronize\relax
- \fi
- \endgroup}
+ userdata = \!!bs\detokenize{#4}\!!es % will be converted to table at the lua end
+ }
+ }}%
+ \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)}}}
\let\m_strc_counters_last_registered_index \relax
\let\m_strc_counters_last_registered_attribute \relax
@@ -764,4 +806,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..0c8bb6e53 100644
--- a/tex/context/base/strc-ref.lua
+++ b/tex/context/base/strc-ref.lua
@@ -16,7 +16,7 @@ if not modules then modules = { } end modules ['strc-ref'] = {
local format, find, gmatch, match, strip = string.format, string.find, string.gmatch, string.match, string.strip
local floor = math.floor
-local rawget, tonumber = rawget, tonumber
+local rawget, tonumber, type = rawget, tonumber, type
local lpegmatch = lpeg.match
local insert, remove, copytable = table.insert, table.remove, table.copy
local formatters = string.formatters
@@ -44,7 +44,13 @@ local report_importing = logs.reporter("references","importing")
local report_empty = logs.reporter("references","empty")
local variables = interfaces.variables
-local constants = interfaces.constants
+local v_default = variables.default
+local v_url = variables.url
+local v_file = variables.file
+local v_unknown = variables.unknown
+local v_page = variables.page
+local v_auto = variables.auto
+
local context = context
local commands = commands
@@ -52,11 +58,6 @@ local texgetcount = tex.getcount
local texsetcount = tex.setcount
local texconditionals = tex.conditionals
-local v_default = variables.default
-local v_url = variables.url
-local v_file = variables.file
-local v_unknown = variables.unknown
-local v_yes = variables.yes
local productcomponent = resolvers.jobs.productcomponent
local justacomponent = resolvers.jobs.justacomponent
@@ -91,6 +92,9 @@ local tobesaved = allocate()
local collected = allocate()
local tobereferred = allocate()
local referred = allocate()
+local usedinternals = allocate()
+local flaginternals = allocate()
+local usedviews = allocate()
references.derived = derived
references.specials = specials
@@ -103,6 +107,9 @@ references.tobesaved = tobesaved
references.collected = collected
references.tobereferred = tobereferred
references.referred = referred
+references.usedinternals = usedinternals
+references.flaginternals = flaginternals
+references.usedviews = usedviews
local splitreference = references.splitreference
local splitprefix = references.splitcomponent -- replaces: references.splitprefix
@@ -111,6 +118,22 @@ local componentsplitter = references.componentsplitter
local currentreference = nil
+local txtcatcodes = catcodes.numbers.txtcatcodes -- or just use "txtcatcodes"
+local context_delayed = context.delayed
+
+local ctx_pushcatcodes = context.pushcatcodes
+local ctx_popcatcodes = context.popcatcodes
+local ctx_dofinishsomereference = context.dofinishsomereference
+local ctx_dofromurldescription = context.dofromurldescription
+local ctx_dofromurlliteral = context.dofromurlliteral
+local ctx_dofromfiledescription = context.dofromfiledescription
+local ctx_dofromfileliteral = context.dofromfileliteral
+local ctx_expandreferenceoperation = context.expandreferenceoperation
+local ctx_expandreferencearguments = context.expandreferencearguments
+local ctx_getreferencestructureprefix = context.getreferencestructureprefix
+local ctx_convertnumber = context.convertnumber
+local ctx_emptyreference = context.emptyreference
+
storage.register("structures/references/defined", references.defined, "structures.references.defined")
local initializers = { }
@@ -119,6 +142,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
@@ -129,12 +153,32 @@ local function initializer() -- can we use a tobesaved as metatable for collecte
for i=1,#initializers do
initializers[i](tobesaved,collected)
end
+ for prefix, list in next, collected do
+ for tag, data in next, list do
+ local r = data.references
+ local i = r.internal
+ if i then
+ internals[i] = c
+ usedinternals[i] = r.used
+ end
+ end
+ end
end
local function finalizer()
for i=1,#finalizers do
finalizers[i](tobesaved)
end
+ for prefix, list in next, tobesaved do
+ for tag, data in next, list do
+ local r = data.references
+ local i = r.internal
+ local f = flaginternals[i]
+ if f then
+ r.used = usedviews[i] or true
+ end
+ end
+ end
end
job.register('structures.references.collected', tobesaved, initializer, finalizer)
@@ -148,6 +192,38 @@ local function initializer() -- can we use a tobesaved as metatable for collecte
nofreferred = #referred
end
+-- no longer fone this way
+
+-- references.resolvers = references.resolvers or { }
+-- local resolvers = references.resolvers
+--
+-- function resolvers.section(var)
+-- local vi = lists.collected[var.i[2]]
+-- if vi then
+-- var.i = vi
+-- var.r = (vi.references and vi.references.realpage) or (vi.pagedata and vi.pagedata.realpage) or 1
+-- else
+-- var.i = nil
+-- var.r = 1
+-- end
+-- end
+--
+-- resolvers.float = resolvers.section
+-- resolvers.description = resolvers.section
+-- resolvers.formula = resolvers.section
+-- resolvers.note = resolvers.section
+--
+-- function resolvers.reference(var)
+-- local vi = var.i[2]
+-- if vi then
+-- var.i = vi
+-- var.r = (vi.references and vi.references.realpage) or (vi.pagedata and vi.pagedata.realpage) or 1
+-- else
+-- var.i = nil
+-- var.r = 1
+-- end
+-- end
+
-- We make the array sparse (maybe a finalizer should optionally return a table) because
-- there can be quite some page links involved. We only store one action number per page
-- which is normally good enough for what we want (e.g. see above/below) and we do
@@ -215,8 +291,6 @@ local function referredpage(n)
return texgetcount("realpageno")
end
--- setmetatableindex(referred,function(t,k) return referredpage(k) end )
-
references.referredpage = referredpage
function references.registerpage(n) -- called in the backend code
@@ -246,16 +320,15 @@ 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
-function references.currentorder(kind,name)
+local function currentorder(kind,name)
return orders[kind] and orders[kind][name] or lastorder
end
@@ -266,20 +339,27 @@ local function setcomponent(data)
local references = data and data.references
if references then
references.component = component
+ if references.referenceprefix == component then
+ references.referenceprefix = nil
+ end
end
return component
end
-- but for the moment we do it here (experiment)
end
-commands.setnextinternalreference = references.setnextinternal
+references.setnextorder = setnextorder
+references.setnextinternal = setnextinternal
+references.currentorder = currentorder
+references.setcomponent = setcomponent
+
+commands.setnextreferenceorder = setnextorder
+commands.setnextinternalreference = setnextinternal
function commands.currentreferenceorder(kind,name)
- context(references.currentorder(kind,name))
+ context(currentorder(kind,name))
end
-references.setcomponent = setcomponent
-
function references.set(kind,prefix,tag,data)
-- setcomponent(data)
local pd = tobesaved[prefix] -- nicer is a metatable
@@ -288,21 +368,6 @@ function references.set(kind,prefix,tag,data)
tobesaved[prefix] = pd
end
local n = 0
- -- for ref in gmatch(tag,"[^,]+") do
- -- if ref ~= "" then
- -- if check_duplicates and pd[ref] then
- -- if prefix and prefix ~= "" then
- -- report_references("redundant reference %a in namespace %a",ref,prefix)
- -- else
- -- report_references("redundant reference %a",ref)
- -- end
- -- else
- -- n = n + 1
- -- pd[ref] = data
- -- context.dofinishsomereference(kind,prefix,ref)
- -- end
- -- end
- -- end
local function action(ref)
if ref == "" then
-- skip
@@ -315,7 +380,7 @@ function references.set(kind,prefix,tag,data)
else
n = n + 1
pd[ref] = data
- context.dofinishsomereference(kind,prefix,ref)
+ ctx_dofinishsomereference(kind,prefix,ref)
end
end
process_settings(tag,action)
@@ -333,127 +398,85 @@ commands.enhancereference = references.enhance
-- -- -- related to strc-ini.lua -- -- --
-references.resolvers = references.resolvers or { }
-local resolvers = references.resolvers
-
-local function getfromlist(var)
- local vi = var.i
- if vi then
- vi = vi[3] or lists.collected[vi[2]]
- if vi then
- local r = vi.references and vi.references
- if r then
- r = r.realpage
- end
- if not r then
- r = vi.pagedata and vi.pagedata
- if r then
- r = r.realpage
- end
- end
- var.i = vi
- var.r = r or 1
- else
- var.i = nil
- var.r = 1
- end
- else
- var.i = nil
- var.r = 1
- end
-end
-
--- resolvers.section = getfromlist
--- resolvers.float = getfromlist
--- resolvers.description = getfromlist
--- resolvers.formula = getfromlist
--- resolvers.note = getfromlist
-
-setmetatableindex(resolvers,function(t,k)
- local v = getfromlist
- resolvers[k] = v
- return v
-end)
-
-function resolvers.reference(var)
- local vi = var.i[2] -- check
- if vi then
- var.i = vi
- var.r = (vi.references and vi.references.realpage) or (vi.pagedata and vi.pagedata.realpage) or 1
- else
- var.i = nil
- var.r = 1
- end
-end
+-- no metatable here .. better be sparse
local function register_from_lists(collected,derived,pages,sections)
- local g = derived[""] if not g then g = { } derived[""] = g end -- global
+ local derived_g = derived[""] -- global
+ if not derived_g then
+ derived_g = { }
+ derived[""] = derived_g
+ end
for i=1,#collected do
- local entry = collected[i]
- local m, r = entry.metadata, entry.references
- if m and r then
- local reference = r.reference or ""
- local prefix = r.referenceprefix or ""
- local component = r.component and r.component or ""
- if reference ~= "" then
- local kind, realpage = m.kind, r.realpage
- if kind and realpage then
- local d = derived[prefix]
- if not d then
- d = { }
- derived[prefix] = d
- end
- local c = derived[component]
- if not c then
- c = { }
- derived[component] = c
- end
- local t = { kind, i, entry }
- -- for s in gmatch(reference,"%s*([^,]+)") do
- -- if trace_referencing then
- -- report_references("list entry %a provides %a reference %a on realpage %a",i,kind,s,realpage)
- -- end
- -- c[s] = c[s] or t -- share them
- -- d[s] = d[s] or t -- share them
- -- g[s] = g[s] or t -- first wins
- -- end
- local function action(s)
- if trace_referencing then
- report_references("list entry %a provides %a reference %a on realpage %a",i,kind,s,realpage)
+ local entry = collected[i]
+ local metadata = entry.metadata
+ if metadata then
+ local kind = metadata.kind
+ if kind then
+ local references = entry.references
+ if references then
+ local reference = references.reference
+ if reference and reference ~= "" then
+ local realpage = references.realpage
+ if realpage then
+ local prefix = references.referenceprefix
+ local component = references.component
+ local derived_p = nil
+ local derived_c = nil
+ if prefix and prefix ~= "" then
+ derived_p = derived[prefix]
+ if not derived_p then
+ derived_p = { }
+ derived[prefix] = derived_p
+ end
+ end
+ if component and component ~= "" and component ~= prefix then
+ derived_c = derived[component]
+ if not derived_c then
+ derived_c = { }
+ derived[component] = derived_c
+ end
+ end
+ local function action(s)
+ if trace_referencing then
+ report_references("list entry %a provides %a reference %a on realpage %a",i,kind,s,realpage)
+ end
+ if derived_p and not derived_p[s] then
+ derived_p[s] = entry
+ end
+ if derived_c and not derived_c[s] then
+ derived_c[s] = entry
+ end
+ if not derived_g[s] then
+ derived_g[s] = entry -- first wins
+ end
+ end
+ process_settings(reference,action)
end
- c[s] = c[s] or t -- share them
- d[s] = d[s] or t -- share them
- g[s] = g[s] or t -- first wins
end
- process_settings(reference,action)
end
end
end
end
--- inspect(derived)
+ -- inspect(derived)
end
references.registerinitializer(function() register_from_lists(lists.collected,derived) end)
-- urls
-references.urls = references.urls or { }
-references.urls.data = references.urls.data or { }
+local urls = references.urls or { }
+references.urls = urls
+local urldata = urls.data or { }
+urls.data = urldata
-local urls = references.urls.data
-
-function references.urls.define(name,url,file,description)
+function urls.define(name,url,file,description)
if name and name ~= "" then
- urls[name] = { url or "", file or "", description or url or file or ""}
+ urldata[name] = { url or "", file or "", description or url or file or ""}
end
end
-local pushcatcodes = context.pushcatcodes
-local popcatcodes = context.popcatcodes
-local txtcatcodes = catcodes.numbers.txtcatcodes -- or just use "txtcatcodes"
-
-function references.urls.get(name)
- local u = urls[name]
+function urls.get(name)
+ local u = urldata[name]
if u then
local url, file = u[1], u[2]
if file and file ~= "" then
@@ -465,58 +488,58 @@ function references.urls.get(name)
end
function commands.geturl(name)
- local url = references.urls.get(name)
+ local url = urls.get(name)
if url and url ~= "" then
- pushcatcodes(txtcatcodes)
+ ctx_pushcatcodes(txtcatcodes)
context(url)
- popcatcodes()
+ ctx_popcatcodes()
end
end
-- function commands.gethyphenatedurl(name,...)
--- local url = references.urls.get(name)
+-- local url = urls.get(name)
-- if url and url ~= "" then
-- hyphenatedurl(url,...)
-- end
-- end
function commands.doifurldefinedelse(name)
- commands.doifelse(urls[name])
+ commands.doifelse(urldata[name])
end
-commands.useurl= references.urls.define
+commands.useurl= urls.define
-- files
-references.files = references.files or { }
-references.files.data = references.files.data or { }
-
-local files = references.files.data
+local files = references.files or { }
+references.files = files
+local filedata = files.data or { }
+files.data = filedata
-function references.files.define(name,file,description)
+function files.define(name,file,description)
if name and name ~= "" then
- files[name] = { file or "", description or file or "" }
+ filedata[name] = { file or "", description or file or "" }
end
end
-function references.files.get(name,method,space) -- method: none, before, after, both, space: yes/no
- local f = files[name]
+function files.get(name,method,space) -- method: none, before, after, both, space: yes/no
+ local f = filedata[name]
if f then
context(f[1])
end
end
function commands.doiffiledefinedelse(name)
- commands.doifelse(files[name])
+ commands.doifelse(filedata[name])
end
-commands.usefile= references.files.define
+commands.usefile= files.define
-- helpers
function references.checkedfile(whatever) -- return whatever if not resolved
if whatever then
- local w = files[whatever]
+ local w = filedata[whatever]
if w then
return w[1]
else
@@ -527,7 +550,7 @@ end
function references.checkedurl(whatever) -- return whatever if not resolved
if whatever then
- local w = urls[whatever]
+ local w = urldata[whatever]
if w then
local u, f = w[1], w[2]
if f and f ~= "" then
@@ -543,11 +566,11 @@ end
function references.checkedfileorurl(whatever,default) -- return nil, nil if not resolved
if whatever then
- local w = files[whatever]
+ local w = filedata[whatever]
if w then
return w[1], nil
else
- local w = urls[whatever]
+ local w = urldata[whatever]
if w then
local u, f = w[1], w[2]
if f and f ~= "" then
@@ -563,25 +586,25 @@ end
-- programs
-references.programs = references.programs or { }
-references.programs.data = references.programs.data or { }
+local programs = references.programs or { }
+references.programs = programs
+local programdata = programs.data or { }
+programs.data = programdata
-local programs = references.programs.data
-
-function references.programs.define(name,file,description)
+function programs.define(name,file,description)
if name and name ~= "" then
- programs[name] = { file or "", description or file or ""}
+ programdata[name] = { file or "", description or file or ""}
end
end
-function references.programs.get(name)
- local f = programs[name]
+function programs.get(name)
+ local f = programdata[name]
return f and f[1]
end
function references.checkedprogram(whatever) -- return whatever if not resolved
if whatever then
- local w = programs[whatever]
+ local w = programdata[whatever]
if w then
return w[1]
else
@@ -590,10 +613,10 @@ function references.checkedprogram(whatever) -- return whatever if not resolved
end
end
-commands.defineprogram = references.programs.define
+commands.defineprogram = programs.define
function commands.getprogram(name)
- local f = programs[name]
+ local f = programdata[name]
if f then
context(f[1])
end
@@ -602,11 +625,11 @@ end
-- shared by urls and files
function references.whatfrom(name)
- context((urls[name] and v_url) or (files[name] and v_file) or v_unknown)
+ context((urldata[name] and v_url) or (filedata[name] and v_file) or v_unknown)
end
function references.from(name)
- local u = urls[name]
+ local u = urldata[name]
if u then
local url, file, description = u[1], u[2], u[3]
if description ~= "" then
@@ -618,7 +641,7 @@ function references.from(name)
return url
end
else
- local f = files[name]
+ local f = filedata[name]
if f then
local file, description = f[1], f[2]
if description ~= "" then
@@ -631,25 +654,25 @@ function references.from(name)
end
function commands.from(name)
- local u = urls[name]
+ local u = urldata[name]
if u then
local url, file, description = u[1], u[2], u[3]
if description ~= "" then
- context.dofromurldescription(description)
+ ctx_dofromurldescription(description)
-- ok
elseif file and file ~= "" then
- context.dofromurlliteral(url .. "/" .. file)
+ ctx_dofromurlliteral(url .. "/" .. file)
else
- context.dofromurlliteral(url)
+ ctx_dofromurlliteral(url)
end
else
- local f = files[name]
+ local f = filedata[name]
if f then
local file, description = f[1], f[2]
if description ~= "" then
- context.dofromfiledescription(description)
+ ctx_dofromfiledescription(description)
else
- context.dofromfileliteral(file)
+ ctx_dofromfileliteral(file)
end
end
end
@@ -657,7 +680,7 @@ end
function references.define(prefix,reference,list)
local d = defined[prefix] if not d then d = { } defined[prefix] = d end
- d[reference] = { "defined", list }
+ d[reference] = list
end
function references.reset(prefix,reference)
@@ -678,33 +701,92 @@ commands.resetreference = references.reset
-- to what extend do we check the non prefixed variant
-local strict = false
+-- local strict = false
+--
+-- local function resolve(prefix,reference,args,set) -- we start with prefix,reference
+-- if reference and reference ~= "" then
+-- if not set then
+-- set = { prefix = prefix, reference = reference }
+-- else
+-- 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
+-- local ri = r[i]
+-- local d
+-- if strict then
+-- d = defined[prefix] or defined[""]
+-- d = d and d[ri]
+-- else
+-- d = defined[prefix]
+-- d = d and d[ri]
+-- if not d then
+-- d = defined[""]
+-- d = d and d[ri]
+-- end
+-- end
+-- if d then
+-- resolve(prefix,d,nil,set)
+-- else
+-- local var = splitreference(ri)
+-- if var then
+-- var.reference = ri
+-- local vo, vi = var.outer, var.inner
+-- if not vo and vi then
+-- -- to be checked
+-- if strict then
+-- d = defined[prefix] or defined[""]
+-- d = d and d[vi]
+-- else
+-- d = defined[prefix]
+-- d = d and d[vi]
+-- if not d then
+-- d = defined[""]
+-- d = d and d[vi]
+-- end
+-- end
+-- --
+-- if d then
+-- resolve(prefix,d,var.arguments,set) -- args can be nil
+-- else
+-- if args then var.arguments = args end
+-- set[#set+1] = var
+-- end
+-- else
+-- if args then var.arguments = args end
+-- set[#set+1] = var
+-- end
+-- if var.has_tex then
+-- set.has_tex = true
+-- end
+-- else
+-- -- report_references("funny pattern %a",ri)
+-- end
+-- end
+-- end
+-- return set
+-- else
+-- return { }
+-- end
+-- end
+
+setmetatableindex(defined,"table")
local function resolve(prefix,reference,args,set) -- we start with prefix,reference
if reference and reference ~= "" then
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
local ri = r[i]
- local d
- if strict then
- d = defined[prefix] or defined[""]
- d = d and d[ri]
- else
- d = defined[prefix]
- d = d and d[ri]
- if not d then
- d = defined[""]
- d = d and d[ri]
- end
- end
+ local d = defined[prefix][ri] or defined[""][ri]
if d then
- resolve(prefix,d[2],nil,set)
+ resolve(prefix,d,nil,set)
else
local var = splitreference(ri)
if var then
@@ -712,20 +794,10 @@ local function resolve(prefix,reference,args,set) -- we start with prefix,refere
local vo, vi = var.outer, var.inner
if not vo and vi then
-- to be checked
- if strict then
- d = defined[prefix] or defined[""]
- d = d and d[vi]
- else
- d = defined[prefix]
- d = d and d[vi]
- if not d then
- d = defined[""]
- d = d and d[vi]
- end
- end
+ d = defined[prefix][vi] or defined[""][vi]
--
if d then
- resolve(prefix,d[2],var.arguments,set) -- args can be nil
+ resolve(prefix,d,var.arguments,set) -- args can be nil
else
if args then var.arguments = args end
set[#set+1] = var
@@ -760,21 +832,18 @@ function commands.setreferencearguments(k,v)
references.currentset[k].arguments = v
end
-local expandreferenceoperation = context.expandreferenceoperation
-local expandreferencearguments = context.expandreferencearguments
-
function references.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex
local currentset = references.currentset
if currentset and currentset.has_tex then
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
@@ -856,8 +925,8 @@ end
local externalfiles = { }
-table.setmetatableindex(externalfiles, function(t,k)
- local v = files[k]
+setmetatableindex(externalfiles, function(t,k)
+ local v = filedata[k]
if not v then
v = { k, k }
end
@@ -865,7 +934,7 @@ table.setmetatableindex(externalfiles, function(t,k)
return v
end)
-table.setmetatableindex(externals,function(t,k) -- either or not automatically
+setmetatableindex(externals, function(t,k) -- either or not automatically
local filename = externalfiles[k][1] -- filename
local fullname = file.replacesuffix(filename,"tuc")
if lfs.isfile(fullname) then -- todo: use other locator
@@ -952,22 +1021,6 @@ local function loadproductreferences(productname,componentname,utilitydata)
ptarget = { }
productreferences[prefix] = ptarget
end
- -- for s in gmatch(reference,"%s*([^,]+)") do
- -- if ptarget then
- -- if trace_importing then
- -- report_importing("registering %s reference, kind %a, name %a, prefix %a, reference %a",
- -- "product",kind,productname,prefix,s)
- -- end
- -- ptarget[s] = ptarget[s] or entry
- -- end
- -- if ctarget then
- -- if trace_importing then
- -- report_importing("registering %s reference, kind %a, name %a, prefix %a, referenc %a",
- -- "component",kind,productname,prefix,s)
- -- end
- -- ctarget[s] = ctarget[s] or entry
- -- end
- -- end
local function action(s)
if ptarget then
if trace_importing then
@@ -1062,7 +1115,7 @@ references.registerinitializer(function(tobesaved,collected)
productdata.components = componentlist(job.structure.collected) or { }
end)
-function structures.references.loadpresets(product,component) -- we can consider a special components hash
+function references.loadpresets(product,component) -- we can consider a special components hash
if product and component and product~= "" and component ~= "" and not productdata.product then -- maybe: productdata.filename ~= filename
productdata.product = product
productdata.component = component
@@ -1082,7 +1135,7 @@ function structures.references.loadpresets(product,component) -- we can consider
end
end
-structures.references.productdata = productdata
+references.productdata = productdata
local useproduct = commands.useproduct
@@ -1096,7 +1149,7 @@ if useproduct then
if trace_referencing or trace_importing then
report_references("loading presets for component %a of product %a",component,product)
end
- structures.references.loadpresets(product,component)
+ references.loadpresets(product,component)
end
end
end
@@ -1194,7 +1247,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
@@ -1204,114 +1257,105 @@ local function identify_arguments(set,var,i)
return var
end
-local function identify_inner(set,var,prefix,collected,derived,tobesaved)
+-- needs checking: if we don't do too much (redundant) checking now
+-- inner ... we could move the prefix logic into the parser so that we have 'm for each entry
+-- foo:bar -> foo == prefix (first we try the global one)
+-- -:bar -> ignore prefix
+
+local function finish_inner(var,p,i)
+ var.kind = "inner"
+ var.i = i
+ var.p = p
+ var.r = (i.references and i.references.realpage) or (i.pagedata and i.pagedata.realpage) or 1
+ return var
+end
+
+local function identify_inner(set,var,prefix,collected,derived)
local inner = var.inner
- local outer = var.outer
- -- inner ... we could move the prefix logic into the parser so that we have 'm for each entry
- -- foo:bar -> foo == prefix (first we try the global one)
- -- -:bar -> ignore prefix
- local p, i = prefix, nil
- local splitprefix, splitinner
-- the next test is a safeguard when references are auto loaded from outer
- if inner then
- splitprefix, splitinner = lpegmatch(prefixsplitter,inner)
+ if not inner or inner == "" then
+ return false
end
- -- these are taken from other anonymous references
+ local splitprefix, splitinner = lpegmatch(prefixsplitter,inner)
if splitprefix and splitinner then
+ -- we check for a prefix:reference instance in the regular set of collected
+ -- references; a special case is -: which forces a lookup in the global list
if splitprefix == "-" then
- i = collected[""]
- i = i and i[splitinner]
- if i then
- p = ""
- end
- else
- i = collected[splitprefix]
- i = i and i[splitinner]
+ local i = collected[""]
if i then
- p = splitprefix
+ i = i[splitinner]
+ if i then
+ return finish_inner(var,"",i)
+ end
end
end
- end
- -- todo: strict here
- if not i then
- i = collected[prefix]
- i = i and i[inner]
- if i then
- p = prefix
- end
- end
- if not i and prefix ~= "" then
- i = collected[""]
- i = i and i[inner]
+ local i = collected[splitprefix]
if i then
- p = ""
+ i = i[splitinner]
+ if i then
+ return finish_inner(var,splitprefix,i)
+ end
end
- end
- if i then
- var.i = { "reference", i }
- resolvers.reference(var)
- var.kind = "inner"
- var.p = p
- elseif derived then
- -- these are taken from other data structures (like lists)
- if splitprefix and splitinner then
+ if derived then
+ -- next we look for a reference in the regular set of collected references
+ -- using the prefix that is active at this moment (so we overload the given
+ -- these are taken from other data structures (like lists)
if splitprefix == "-" then
- i = derived[""]
- i = i and i[splitinner]
+ local i = derived[""]
if i then
- p = ""
+ i = i[splitinner]
+ if i then
+ return finish_inner(var,"",i)
+ end
end
- else
- i = derived[splitprefix]
- i = i and i[splitinner]
+ end
+ local i = derived[splitprefix]
+ if i then
+ i = i[splitinner]
if i then
- p = splitprefix
+ return finish_inner(var,splitprefix,i)
end
end
end
- if not i then
- i = derived[prefix]
- i = i and i[inner]
- if i then
- p = prefix
- end
+ end
+ -- we now ignore the split prefix and treat the whole inner as a potential
+ -- referenice into the global list
+ local i = collected[prefix]
+ if i then
+ i = i[inner]
+ if i then
+ return finish_inner(var,prefix,i)
end
- if not i and prefix ~= "" then
- i = derived[""]
- i = i and i[inner]
+ end
+ if not i and derived then
+ -- and if not found we look in the derived references
+ local i = derived[prefix]
+ if i then
+ i = i[inner]
if i then
- p = ""
+ return finish_inner(var,prefix,i)
end
end
+ end
+ return false
+end
+
+local function unprefixed_inner(set,var,prefix,collected,derived,tobesaved)
+ local inner = var.inner
+ local s = specials[inner]
+ if s then
+ var.kind = "special"
+ else
+ local i = (collected and collected[""] and collected[""][inner]) or
+ (derived and derived [""] and derived [""][inner]) or
+ (tobesaved and tobesaved[""] and tobesaved[""][inner])
if i then
var.kind = "inner"
- var.i = i
- var.p = p
- local ri = resolvers[i[1]]
- if ri then
- ri(var)
- else
- -- can't happen as we catch it with a metatable now
- report_references("unknown inner resolver for %a",i[1])
- end
+ var.p = ""
+ var.i = i
+ var.r = (i.references and i.references.realpage) or (i.pagedata and i.pagedata.realpage) or 1
else
- -- no prefixes here
- local s = specials[inner]
- if s then
- var.kind = "special"
- else
- i = (collected and collected[""] and collected[""][inner]) or
- (derived and derived [""] and derived [""][inner]) or
- (tobesaved and tobesaved[""] and tobesaved[""][inner])
- if i then
- var.kind = "inner"
- var.i = { "reference", i }
- resolvers.reference(var)
- var.p = ""
- else
- var.error = "unknown inner or special"
- end
- end
+ var.error = "unknown inner or special"
end
end
return var
@@ -1322,9 +1366,8 @@ local function identify_outer(set,var,i)
local inner = var.inner
local external = externals[outer]
if external then
- local v = copytable(var)
- v = identify_inner(set,v,nil,external)
- if v.i and not v.error then
+ local v = identify_inner(set,var,nil,external)
+ if v then
v.kind = "outer with inner"
set.external = true
if trace_identifying then
@@ -1332,9 +1375,8 @@ local function identify_outer(set,var,i)
end
return v
end
- v = copytable(var)
- local v = identify_inner(set,v,v.outer,external)
- if v.i and not v.error then
+ local v = identify_inner(set,var,var.outer,external)
+ if v then
v.kind = "outer with inner"
set.external = true
if trace_identifying then
@@ -1345,8 +1387,8 @@ local function identify_outer(set,var,i)
end
local external = productdata.componentreferences[outer]
if external then
- local v = identify_inner(set,copytable(var),nil,external)
- if v.i and not v.error then
+ local v = identify_inner(set,var,nil,external)
+ if v then
v.kind = "outer with inner"
set.external = true
if trace_identifying then
@@ -1373,6 +1415,8 @@ local function identify_outer(set,var,i)
local arguments = var.arguments
local operation = var.operation
if inner then
+ -- tricky: in this case we can only use views when we're sure that all inners
+ -- are flushed in the outer document so that should become an option
if arguments then
-- outer::inner{argument}
var.kind = "outer with inner with arguments"
@@ -1380,9 +1424,9 @@ local function identify_outer(set,var,i)
-- outer::inner
var.kind = "outer with inner"
end
- var.i = { "reference", inner }
- resolvers.reference(var)
+ var.i = inner
var.f = outer
+ var.r = (inner.references and inner.references.realpage) or (inner.pagedata and inner.pagedata.realpage) or 1
if trace_identifying then
report_identify_outer(set,var,i,"2e")
end
@@ -1419,57 +1463,62 @@ local function identify_outer(set,var,i)
return var
end
+-- todo: avoid copy
+
local function identify_inner_or_outer(set,var,i)
-- here we fall back on product data
local inner = var.inner
if inner and inner ~= "" then
- local v = identify_inner(set,copytable(var),set.prefix,collected,derived,tobesaved)
- if v.i and not v.error then
- v.kind = "inner" -- check this
+
+ -- first we look up in collected and derived using the current prefix
+
+ local prefix = set.prefix
+
+ local v = identify_inner(set,var,set.prefix,collected,derived)
+ if v then
if trace_identifying then
report_identify_outer(set,v,i,"4a")
end
return v
end
- -- these get auto prefixes but are loaded in the document so they are
- -- internal .. we also set the realpage (for samepage analysis)
+ -- nest we look at each component (but we can omit the already consulted one
local components = job.structure.components
if components then
- for i=1,#components do
- local component = components[i]
- local data = collected[component]
- local vi = data and data[inner]
- if vi then
--- var = copytable(var)
--- var.kind = "inner"
--- var.i = vi
--- var.p = component
--- runners.inner(var.r = vi.references.realpage
--- if trace_identifying then
--- report_identify_outer(set,var,i,"4x")
--- end
--- return var
-local v = identify_inner(set,copytable(var),component,collected) -- is copy needed ?
-if v.i and not v.error then
- v.kind = "inner"
- if trace_identifying then
- report_identify_outer(set,var,i,"4x")
- end
- return v
-end
+ for c=1,#components do
+ local component = components[c]
+ if component ~= prefix then
+ local v = identify_inner(set,var,component,collected,derived)
+ if v then
+ if trace_identifying then
+ report_identify_outer(set,var,i,"4b")
+ end
+ return v
+ end
end
end
end
+ -- as a last resort we will consult the global lists
+
+ local v = unprefixed_inner(set,var,"",collected,derived,tobesaved)
+ if v then
+ if trace_identifying then
+ report_identify_outer(set,v,i,"4c")
+ end
+ return v
+ end
+
+ -- not it gets bad ... we need to look in external files ... keep in mind that
+ -- we can best use explicit references for this ... we might issue a warning
+
local componentreferences = productdata.componentreferences
local productreferences = productdata.productreferences
local components = productdata.components
if components and componentreferences then
- -- for component, data in next, productdata.componentreferences do -- better do this in order of processing:
- for i=1,#components do
- local component = components[i]
+ for c=1,#components do
+ local component = components[c]
local data = componentreferences[component]
if data then
local d = data[""]
@@ -1480,7 +1529,7 @@ end
var.kind = "outer with inner"
set.external = true
if trace_identifying then
- report_identify_outer(set,var,i,"4b")
+ report_identify_outer(set,var,i,"4d")
end
return var
end
@@ -1500,7 +1549,7 @@ end
var.kind = "outer with inner"
set.external = true
if trace_identifying then
- report_identify_outer(set,var,i,"4c")
+ report_identify_outer(set,var,i,"4e")
end
return var
end
@@ -1515,7 +1564,7 @@ end
var.kind = "outer with inner"
set.external = true
if trace_identifying then
- report_identify_outer(set,var,i,"4d")
+ report_identify_outer(set,var,i,"4f")
end
return var
end
@@ -1526,30 +1575,18 @@ end
var.error = "no inner"
end
if trace_identifying then
- report_identify_outer(set,var,i,"4e")
+ report_identify_outer(set,var,i,"4g")
end
return var
end
--- local function identify_inner_or_outer(set,var,i)
--- -- we might consider first checking with a prefix prepended and then without
--- -- which is better for fig:oeps
--- local var = do_identify_inner_or_outer(set,var,i)
--- if var.error then
--- local prefix = set.prefix
--- if prefix and prefix ~= "" then
--- var.inner = prefix .. ':' .. var.inner
--- var.error = nil
--- return do_identify_inner_or_outer(set,var,i)
--- end
--- end
--- return var
--- end
-
local function identify_inner_component(set,var,i)
-- we're in a product (maybe ignore when same as component)
local component = var.component
- identify_inner(set,var,component,collected,derived,tobesaved)
+ local v = identify_inner(set,var,component,collected,derived)
+ if not v then
+ var.error = "unknown inner in component"
+ end
if trace_identifying then
report_identify_outer(set,var,i,"5a")
end
@@ -1685,53 +1722,51 @@ 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 = v_auto -- only page|auto now
+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
- innermethod = m
- elseif m == true or m == v_yes then
- innermethod = "page"
- end
+ if toboolean(m) or m == v_page then
+ innermethod = v_page
+ else
+ innermethod = v_auto
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
+directives.register("references.linkmethod", function(v) -- page auto
references.setinnermethod(v)
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 == v_auto 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 +1774,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 then
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
--
@@ -1800,10 +1847,22 @@ end
references.getcurrentprefixspec = getcurrentprefixspec
function commands.getcurrentprefixspec(default)
- context.getreferencestructureprefix(getcurrentprefixspec(default))
+ ctx_getreferencestructureprefix(getcurrentprefixspec(default))
end
-function references.filter(name,...) -- number page title ...
+local genericfilters = { }
+local userfilters = { }
+local textfilters = { }
+local fullfilters = { }
+local sectionfilters = { }
+
+filters.generic = genericfilters
+filters.user = userfilters
+filters.text = textfilters
+filters.full = fullfilters
+filters.section = sectionfilters
+
+local function filterreference(name,...) -- number page title ...
local data = currentreference and currentreference.i -- maybe we should take realpage from here
if data then
if name == "realpage" then
@@ -1812,8 +1871,8 @@ function references.filter(name,...) -- number page title ...
else -- assumes data is table
local kind = type(data) == "table" and data.metadata and data.metadata.kind
if kind then
- local filter = filters[kind] or filters.generic
- filter = filter and (filter[name] or filter.unknown or filters.generic[name] or filters.generic.unknown)
+ local filter = filters[kind] or genericfilters
+ filter = filter and (filter[name] or filter.unknown or genericfilters[name] or genericfilters.unknown)
if filter then
if trace_referencing then
report_references("name %a, kind %a, using dedicated filter",name,kind)
@@ -1833,18 +1892,24 @@ function references.filter(name,...) -- number page title ...
end
end
-function references.filterdefault()
- return references.filter("default",getcurrentprefixspec(v_default))
+local function filterreferencedefault()
+ return filterreference("default",getcurrentprefixspec(v_default))
end
+references.filter = filterreference
+references.filterdefault = filterreferencedefault
+
+commands.filterreference = filterreference
+commands.filterdefaultreference = filterreferencedefault
+
function commands.currentreferencedefault(tag)
- if not tag then tag = "default" end
- references.filter(tag,context.delayed(getcurrentprefixspec(tag)))
+ if not tag then
+ tag = "default"
+ end
+ filterreference(tag,context_delayed(getcurrentprefixspec(tag)))
end
-filters.generic = { }
-
-function filters.generic.title(data)
+function genericfilters.title(data)
if data then
local titledata = data.titledata or data.useddata
if titledata then
@@ -1853,7 +1918,7 @@ function filters.generic.title(data)
end
end
-function filters.generic.text(data)
+function genericfilters.text(data)
if data then
local entries = data.entries or data.useddata
if entries then
@@ -1862,7 +1927,7 @@ function filters.generic.text(data)
end
end
-function filters.generic.number(data,what,prefixspec) -- todo: spec and then no stopper
+function genericfilters.number(data,what,prefixspec) -- todo: spec and then no stopper
if data then
numberdata = lists.reordered(data) -- data.numberdata
if numberdata then
@@ -1877,16 +1942,16 @@ function filters.generic.number(data,what,prefixspec) -- todo: spec and then no
end
end
-filters.generic.default = filters.generic.text
+genericfilters.default = genericfilters.text
-function filters.generic.page(data,prefixspec,pagespec)
+function genericfilters.page(data,prefixspec,pagespec)
local pagedata = data.pagedata
if pagedata then
local number, conversion = pagedata.number, pagedata.conversion
if not number then
-- error
elseif conversion then
- context.convertnumber(conversion,number)
+ ctx_convertnumber(conversion,number)
else
context(number)
end
@@ -1895,14 +1960,12 @@ function filters.generic.page(data,prefixspec,pagespec)
end
end
-filters.user = { }
-
-function filters.user.unknown(data,name)
+function userfilters.unknown(data,name)
if data then
local userdata = data.userdata
local userkind = userdata and userdata.kind
if userkind then
- local filter = filters[userkind] or filters.generic
+ local filter = filters[userkind] or genericfilters
filter = filter and (filter[name] or filter.unknown)
if filter then
filter(data,name)
@@ -1916,9 +1979,7 @@ function filters.user.unknown(data,name)
end
end
-filters.text = { }
-
-function filters.text.title(data)
+function textfilters.title(data)
helpers.title(data.entries.text or "?",data.metadata)
end
@@ -1928,18 +1989,14 @@ end
-- helpers.title(data.entries.text or "?",data.metadata)
-- end
-function filters.text.page(data,prefixspec,pagespec)
+function textfilters.page(data,prefixspec,pagespec)
helpers.prefixpage(data,prefixspec,pagespec)
end
-filters.full = { }
-
-filters.full.title = filters.text.title
-filters.full.page = filters.text.page
+fullfilters.title = textfilters.title
+fullfilters.page = textfilters.page
-filters.section = { }
-
-function filters.section.number(data,what,prefixspec)
+function sectionfilters.number(data,what,prefixspec)
if data then
local numberdata = data.numberdata
if not numberdata then
@@ -1951,7 +2008,7 @@ function filters.section.number(data,what,prefixspec)
local references = data.references
if trace_empty then
report_empty("reference %a has a hidden number",references.reference)
- context.emptyreference() -- maybe an option
+ ctx_emptyreference() -- maybe an option
end
else
sections.typesetnumber(numberdata,"number",prefixspec,numberdata)
@@ -1959,18 +2016,18 @@ function filters.section.number(data,what,prefixspec)
end
end
-filters.section.title = filters.generic.title
-filters.section.page = filters.generic.page
-filters.section.default = filters.section.number
+sectionfilters.title = genericfilters.title
+sectionfilters.page = genericfilters.page
+sectionfilters.default = sectionfilters.number
--- filters.note = { default = filters.generic.number }
--- filters.formula = { default = filters.generic.number }
--- filters.float = { default = filters.generic.number }
--- filters.description = { default = filters.generic.number }
--- filters.item = { default = filters.generic.number }
+-- filters.note = { default = genericfilters.number }
+-- filters.formula = { default = genericfilters.number }
+-- filters.float = { default = genericfilters.number }
+-- filters.description = { default = genericfilters.number }
+-- filters.item = { default = genericfilters.number }
setmetatableindex(filters, function(t,k) -- beware, test with rawget
- local v = { default = filters.generic.number } -- not copy as it might be extended differently
+ local v = { default = genericfilters.number } -- not copy as it might be extended differently
t[k] = v
return v
end)
@@ -2164,7 +2221,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
@@ -2226,9 +2283,6 @@ end
-- needs a better split ^^^
-commands.filterreference = references.filter
-commands.filterdefaultreference = references.filterdefault
-
-- done differently now:
function references.export(usedname) end
diff --git a/tex/context/base/strc-ref.mkvi b/tex/context/base/strc-ref.mkvi
index 85c6a0729..76d79b802 100644
--- a/tex/context/base/strc-ref.mkvi
+++ b/tex/context/base/strc-ref.mkvi
@@ -193,12 +193,12 @@
\globallet\currentreferencecoding\s!tex
\fi
% beware, the structures.references.set writes a
- % \setnextinternalreference
+ \setnextinternalreference
\strc_references_start_destination_nodes
\ctxcommand{setreferenceattribute("\currentreferencekind", "\referenceprefix","\currentreferencelabels",
{
references = {
- % internal = \nextinternalreference, % no need for an internal as we have an explicit
+ internal = \nextinternalreference,
block = "\currentsectionblock",
section = structures.sections.currentid(),
},
@@ -243,9 +243,11 @@
\lastdestinationattribute\attributeunsetvalue
\else
\strc_references_start_destination_nodes
- \ctxcommand{setreferenceattribute("\s!page", "\referenceprefix","\currentreferencelabels",
+\setnextinternalreference
+ \ctxcommand{setreferenceattribute("\s!page", "\referenceprefix","\currentreferencelabels",
{
references = {
+ internal = \nextinternalreference,
block = "\currentsectionblock",
section = structures.sections.currentid(),
},
@@ -264,9 +266,11 @@
\unexpanded\def\strc_references_direct_full#labels#text%
{\ifreferencing
\strc_references_start_destination_nodes
- \ctxcommand{setreferenceattribute("\s!full", "\referenceprefix","#labels",
+\setnextinternalreference
+ \ctxcommand{setreferenceattribute("\s!full", "\referenceprefix","#labels",
{
references = {
+ internal = \nextinternalreference,
block = "\currentsectionblock",
section = structures.sections.currentid(),
},
@@ -947,11 +951,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..122892104 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
@@ -101,8 +103,11 @@
{\setfalse\c_strc_bookmarks_preroll}
\def\strc_sectioning_autobookmark#1%
- {\nodestostring\tempstring{#1}%
- \globallet\currentstructurebookmark\tempstring}
+ {\begingroup
+ \the\everypreroll
+ \nodestostring\tempstring{#1}%
+ \globallet\currentstructurebookmark\tempstring
+ \endgroup}
% so it's an experiment
@@ -130,9 +135,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 +148,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 +175,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 +223,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 +238,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 +305,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 +440,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 +583,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 +768,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 +1044,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 +1124,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 +1159,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..308e4b6fc 100644
--- a/tex/context/base/syst-aux.mkiv
+++ b/tex/context/base/syst-aux.mkiv
@@ -128,10 +128,16 @@
\newif\if!!doned \newif\if!!donee \newif\if!!donef
\def\!!zerocount {0} % alongside \zerocount
-\def\!!minusone {-1} % alongside \minusone
-\def\!!plusone {1} % alongside \plusone
-\def\!!plustwo {2} % alongside \plustwo
-\def\!!plusthree {3} % alongside \plusthree
+\def\!!minusone {-1} % ...
+\def\!!plusone {1} % ...
+\def\!!plustwo {2} % ...
+\def\!!plusthree {3} % ...
+\def\!!plusfour {4} % ...
+\def\!!plusfive {5} % ...
+\def\!!plussix {6} % ...
+\def\!!plusseven {7} % ...
+\def\!!pluseight {8} % ...
+\def\!!plusnine {9} % alongside \plusnine
\setnewconstant \uprotationangle 0
\setnewconstant\rightrotationangle 90
@@ -346,6 +352,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-ini.mkiv b/tex/context/base/syst-ini.mkiv
index 38c34556a..fda873d3c 100644
--- a/tex/context/base/syst-ini.mkiv
+++ b/tex/context/base/syst-ini.mkiv
@@ -301,7 +301,7 @@
%D 128-1023 are private and should not be touched.
\let\attributeunsetvalue\c_syst_min_counter_value % used to be \minusone
-\normalprotected\def\newattribute{\syst_basics_allocate\c_syst_min_allocated_attribute\attribute\attributedef\c_syst_max_allocated_register}
+\normalprotected\def\newattribute{\syst_basics_allocate\c_syst_last_allocated_attribute\attribute\attributedef\c_syst_max_allocated_register}
%D Not used by \CONTEXT\ but for instance \PICTEX\ needs it. It's a trick to force
%D strings instead of tokens that take more memory. It's a trick to trick to force
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-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv
index 42c61f16c..3734e5647 100644
--- a/tex/context/base/tabl-ntb.mkiv
+++ b/tex/context/base/tabl-ntb.mkiv
@@ -1500,7 +1500,6 @@
\fi
\fi}
-
\def\tabl_ntb_check_heights_one
{\dorecurse\c_tabl_ntb_maximum_row
{\c_tabl_ntb_current_row_three\recurselevel\relax
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..d9daefe69 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
@@ -573,8 +572,8 @@ function xtables.reflow_height()
local total = totalheight + totaldepth
local leftover = settings.textheight - total
if leftover > 0 then
- local leftheight = (totalheight / total ) * leftover / #heights
- local leftdepth = (totaldepth / total ) * leftover / #depths
+ local leftheight = (totalheight / total) * leftover / #heights
+ local leftdepth = (totaldepth / total) * leftover / #depths
for i=1,nofrows do
heights[i] = heights[i] + leftheight
depths [i] = depths [i] + leftdepth
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..75ce08232 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") -- enabled but optimized for quick abort
+appendaction ("shipouts", "normalizers", "nodes.properties.delayed") -- enabled but optimized for quick abort
+
-- speedup: only kick in when used
disableaction("processors", "languages.replacements.handler")
diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua
index 4cc48c4a5..af4f7c643 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")
+----- report_tex = logs.reporter("tex error")
+----- 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,19 @@ function tracers.knownlist(name)
return l and #l > 0
end
-function tracers.showlines(filename,linenumber,offset,errorstr)
+local savedluaerror = nil
+
+local function errorreporter(luaerror)
+ if luaerror then
+ logs.enable("lua error") --
+ return logs.reporter("lua error")
+ else
+ logs.enable("tex error")
+ return logs.reporter("tex error")
+ end
+end
+
+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 +124,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
@@ -159,30 +157,84 @@ function tracers.showlines(filename,linenumber,offset,errorstr)
end
end
-function tracers.printerror(offset)
- local inputstack = resolvers.inputstack
- local filename = inputstack[#inputstack] or status.filename
- local linenumber = tonumber(status.linenumber) or 0
+-- this will work ok in >=0.79
+
+-- todo: last tex error has ! prepended
+-- todo: some nested errors have two line numbers
+-- todo: collect errorcontext in string (after code cleanup)
+-- todo: have a separate status.lualinenumber
+
+-- todo: \starttext bla \blank[foo] bla \stoptext
+
+local function processerror(offset)
+ local inputstack = resolvers.inputstack
+ local filename = inputstack[#inputstack] or status.filename
+ local linenumber = tonumber(status.linenumber) or 0
+ --
+ -- print("[[ last tex error: " .. tostring(status.lasterrorstring) .. " ]]")
+ -- print("[[ last lua error: " .. tostring(status.lastluaerrorstring) .. " ]]")
+ -- print("[[ start errorcontext ]]")
+ -- tex.show_context()
+ -- print("\n[[ stop errorcontext ]]")
+ --
+ local lasttexerror = status.lasterrorstring or "?"
+ local lastluaerror = status.lastluaerrorstring or lasttexerror
+ local luaerrorline = match(lastluaerror,[[lua%]?:.-(%d+)]]) or (lastluaerror and find(lastluaerror,"?:0:",1,true) and 0)
+ local report = errorreporter(luaerrorline)
+ tracers.printerror {
+ filename = filename,
+ linenumber = linenumber,
+ lasttexerror = lasttexerror,
+ lastluaerror = lastluaerror,
+ luaerrorline = luaerrorline,
+ offset = tonumber(offset) or 10,
+ }
+end
+
+-- so one can overload the printer if (really) needed
+
+function tracers.printerror(specification)
+ local filename = specification.filename
+ local linenumber = specification.linenumber
+ local lasttexerror = specification.lasttexerror
+ local lastluaerror = specification.lastluaerror
+ local luaerrorline = specification.luaerrorline
+ local offset = specification.offset
+ local report = errorreporter(luaerrorline)
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)
+-- report("error on line %s in file %s:\n\n%s",linenumber,filename,lasttexerror)
+ 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() processerror(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-log.lua b/tex/context/base/trac-log.lua
index 0d0b66260..45cc550d4 100644
--- a/tex/context/base/trac-log.lua
+++ b/tex/context/base/trac-log.lua
@@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['trac-log'] = {
license = "see context related readme files"
}
+-- In fact all writes could go through lua and we could write the console and
+-- terminal handler in lua then. Ok, maybe it's slower then, so a no-go.
+
-- if tex and (tex.jobname or tex.formatname) then
--
-- -- quick hack, awaiting speedup in engine (8 -> 6.4 sec for --make with console2)
@@ -535,9 +538,10 @@ local function setblocked(category,value)
v.state = value
end
else
- states = utilities.parsers.settings_to_hash(category)
+ states = utilities.parsers.settings_to_hash(category,type(states)=="table" and states or nil)
for c, _ in next, states do
- if data[c] then
+ local v = data[c]
+ if v then
v.state = value
else
c = topattern(c,true,true)
diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua
index 420e9a00d..eb5373ee3 100644
--- a/tex/context/base/trac-vis.lua
+++ b/tex/context/base/trac-vis.lua
@@ -32,6 +32,7 @@ local formatters = string.formatters
-- todo: global switch (so no attributes)
-- todo: maybe also xoffset, yoffset of glyph
-- todo: inline concat (more efficient)
+-- todo: tags can also be numbers (just add to hash)
local nodecodes = nodes.nodecodes
local disc_code = nodecodes.disc
@@ -43,6 +44,7 @@ local glue_code = nodecodes.glue
local penalty_code = nodecodes.penalty
local whatsit_code = nodecodes.whatsit
local user_code = nodecodes.user
+local math_code = nodecodes.math
local gluespec_code = nodecodes.gluespec
local kerncodes = nodes.kerncodes
@@ -58,6 +60,7 @@ local leftskip_code = gluecodes.leftskip
local rightskip_code = gluecodes.rightskip
local whatsitcodes = nodes.whatsitcodes
+local mathcodes = nodes.mathcodes
local nuts = nodes.nuts
local tonut = nuts.tonut
@@ -98,8 +101,10 @@ local unsetvalue = attributes.unsetvalue
local current_font = font.current
-local exheights = fonts.hashes.exheights
-local emwidths = fonts.hashes.emwidths
+local fonthashes = fonts.hashes
+local chardata = fonthashes.characters
+local exheights = fonthashes.exheights
+local emwidths = fonthashes.emwidths
local pt_factor = number.dimenfactors.pt
local nodepool = nuts.pool
@@ -138,6 +143,7 @@ local trace_fontkern
local trace_strut
local trace_whatsit
local trace_user
+local trace_math
local report_visualize = logs.reporter("visualize")
@@ -157,21 +163,22 @@ local modes = {
simplevbox = 1024 + 2,
simplevtop = 1024 + 4,
user = 2048,
+ math = 4096,
}
local modes_makeup = { "hbox", "vbox", "kern", "glue", "penalty" }
local modes_boxes = { "hbox", "vbox" }
-local modes_all = { "hbox", "vbox", "kern", "glue", "penalty", "fontkern", "whatsit", "glyph", "user" }
+local modes_all = { "hbox", "vbox", "kern", "glue", "penalty", "fontkern", "whatsit", "glyph", "user", "math" }
local usedfont, exheight, emwidth
-local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user
+local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math
local enabled = false
local layers = { }
local preset_boxes = modes.hbox + modes.vbox
local preset_makeup = preset_boxes + modes.kern + modes.glue + modes.penalty
-local preset_all = preset_makeup + modes.fontkern + modes.whatsit + modes.glyph + modes.user
+local preset_all = preset_makeup + modes.fontkern + modes.whatsit + modes.glyph + modes.user + modes.math
function visualizers.setfont(id)
usedfont = id or current_font()
@@ -208,6 +215,7 @@ local function enable()
l_whatsit = layers.whatsit
l_glyph = layers.glyph
l_user = layers.user
+ l_math = layers.math
nodes.tasks.enableaction("shipouts","nodes.visualizers.handler")
report_visualize("enabled")
enabled = true
@@ -301,6 +309,7 @@ local c_skip_a = "trace:c"
local c_skip_b = "trace:m"
local c_glyph = "trace:o"
local c_white = "trace:w"
+local c_math = "trace:r"
local c_positive_d = "trace:db"
local c_negative_d = "trace:dr"
@@ -311,6 +320,7 @@ local c_skip_a_d = "trace:dc"
local c_skip_b_d = "trace:dm"
local c_glyph_d = "trace:do"
local c_white_d = "trace:dw"
+local c_math_d = "trace:dr"
local function sometext(str,layer,color,textcolor) -- we can just paste verbatim together .. no typesteting needed
local text = fast_hpack_string(str,usedfont)
@@ -369,8 +379,7 @@ local function fontkern(head,current)
end
local w_cache = { }
-
-local tags = {
+local tags = {
open = "FIC",
write = "FIW",
close = "FIC",
@@ -417,15 +426,38 @@ local function whatsit(head,current)
return head, current
end
+local u_cache = { }
+
local function user(head,current)
local what = getsubtype(current)
- local info = w_cache[what]
+ local info = u_cache[what]
if info then
-- print("hit user")
else
info = sometext(formatters["U:%s"](what),usedfont)
setattr(info,a_layer,l_user)
- w_cache[what] = info
+ u_cache[what] = info
+ end
+ head, current = insert_node_after(head,current,copy_list(info))
+ return head, current
+end
+
+local m_cache = { }
+local tags = {
+ beginmath = "B",
+ endmath = "E",
+}
+
+local function math(head,current)
+ local what = getsubtype(current)
+ local info = m_cache[what]
+ if info then
+ -- print("hit math")
+ else
+ local tag = mathcodes[what]
+ info = sometext(formatters["M:%s"](tag and tags[tag] or what),usedfont,nil,c_math_d)
+ setattr(info,a_layer,l_math)
+ m_cache[what] = info
end
head, current = insert_node_after(head,current,copy_list(info))
return head, current
@@ -439,7 +471,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
@@ -538,6 +570,7 @@ end
local function ruledglyph(head,current,previous)
local wd = getfield(current,"width")
+ -- local wd = chardata[getfield(current,"font")][getfield(current,"char")].width
if wd ~= 0 then
local ht = getfield(current,"height")
local dp = getfield(current,"depth")
@@ -720,6 +753,7 @@ local function visualize(head,vertical)
local trace_glyph = false
local trace_simple = false
local trace_user = false
+ local trace_math = false
local current = head
local previous = nil
local attr = unsetvalue
@@ -742,6 +776,7 @@ local function visualize(head,vertical)
trace_glyph = false
trace_simple = false
trace_user = false
+ trace_math = false
else -- dead slow:
trace_hbox = hasbit(a, 1)
trace_vbox = hasbit(a, 2)
@@ -755,6 +790,7 @@ local function visualize(head,vertical)
trace_glyph = hasbit(a, 512)
trace_simple = hasbit(a,1024)
trace_user = hasbit(a,2048)
+ trace_math = hasbit(a,4096)
end
attr = a
end
@@ -829,9 +865,13 @@ local function visualize(head,vertical)
head, current = whatsit(head,current)
end
elseif id == user_code then
- if trace_whatsit then
+ if trace_user then
head, current = user(head,current)
end
+ elseif id == math_code then
+ if trace_math then
+ head, current = math(head,current)
+ end
end
previous = current
current = getnext(current)
@@ -860,7 +900,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 +971,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-imp-texgyre.mkiv b/tex/context/base/type-imp-texgyre.mkiv
index 24185f41d..b2aaa3629 100644
--- a/tex/context/base/type-imp-texgyre.mkiv
+++ b/tex/context/base/type-imp-texgyre.mkiv
@@ -153,7 +153,7 @@
\definetypeface [\typescriptone] [\s!rm] [\s!serif] [\typescriptone] [\s!default]
\definetypeface [\typescriptone] [\s!ss] [\s!sans] [helvetica] [\s!default] [\s!rscale=0.9]
\definetypeface [\typescriptone] [\s!tt] [\s!mono] [modern] [\s!default] [\s!rscale=1.05]
- \definetypeface [\typescriptone] [\s!mm] [\s!math] [times] [\s!default]
+ \definetypeface [\typescriptone] [\s!mm] [\s!math] [termes] [\s!default]
\quittypescriptscanning
\stoptypescript
@@ -161,7 +161,7 @@
\definetypeface [\typescriptone] [\s!rm] [\s!serif] [\typescriptone] [\s!default]
\definetypeface [\typescriptone] [\s!ss] [\s!sans] [modern] [\s!default] [\s!rscale=1.075]
\definetypeface [\typescriptone] [\s!tt] [\s!mono] [modern] [\s!default] [\s!rscale=1.075]
- \definetypeface [\typescriptone] [\s!mm] [\s!math] [palatino] [\s!default]
+ \definetypeface [\typescriptone] [\s!mm] [\s!math] [pagella] [\s!default]
\quittypescriptscanning
\stoptypescript
@@ -169,7 +169,7 @@
\definetypeface [\typescriptone] [\s!rm] [\s!serif] [\typescriptone] [\s!default]
\definetypeface [\typescriptone] [\s!ss] [\s!sans] [modern] [\s!default] [\s!rscale=1.1]
\definetypeface [\typescriptone] [\s!tt] [\s!mono] [modern] [\s!default] [\s!rscale=1.1]
- \definetypeface [\typescriptone] [\s!mm] [\s!math] [modern] [\s!default] [\s!rscale=1.1]
+ \definetypeface [\typescriptone] [\s!mm] [\s!math] [schola] [\s!default] [\s!rscale=1.1]
\quittypescriptscanning
\stoptypescript
@@ -277,3 +277,12 @@
\stoptypescript
\stoptypescriptcollection
+
+\starttypescriptcollection[texgyre-math-schola]
+
+ \starttypescript [\s!math][schoolbook,schola][\s!all]
+ \loadfontgoodies[texgyre]
+ \definefontsynonym[\s!MathRoman][file:texgyre-schola-math-regular.otf][\s!features=\s!math\mathsizesuffix]
+ \stoptypescript
+
+\stoptypescriptcollection
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..f9a65c6ba 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
@@ -108,7 +107,7 @@ methods[2] = function(head,start) -- ( => (-
local tmp
head, start, tmp = remove_node(head,start)
head, start = insert_node_before(head,start,new_disc())
- setfield(start,"attr",copy_nodelist(getfield(tmp,"attr")))
+ setfield(start,"attr",copy_nodelist(getfield(tmp,"attr"))) -- just a copy will do
setfield(start,"replace",tmp)
local tmp = copy_node(tmp)
local hyphen = copy_node(tmp)
@@ -126,7 +125,7 @@ methods[3] = function(head,start) -- ) => -)
local tmp
head, start, tmp = remove_node(head,start)
head, start = insert_node_before(head,start,new_disc())
- setfield(start,"attr",copy_nodelist(getfield(tmp,"attr")))
+ setfield(start,"attr",copy_nodelist(getfield(tmp,"attr"))) -- just a copy will do
setfield(start,"replace",tmp)
local tmp = copy_node(tmp)
local hyphen = copy_node(tmp)
@@ -144,7 +143,7 @@ methods[4] = function(head,start) -- - => - - -
local tmp
head, start, tmp = remove_node(head,start)
head, start = insert_node_before(head,start,new_disc())
- setfield(start,"attr",copy_nodelist(getfield(tmp,"attr")))
+ setfield(start,"attr",copy_nodelist(getfield(tmp,"attr"))) -- just a copy will do
setfield(start,"pre",copy_node(tmp))
setfield(start,"post",copy_node(tmp))
setfield(start,"replace",tmp)
@@ -172,7 +171,7 @@ methods[5] = function(head,start,settings) -- x => p q r
if middle then
setfield(start,"replace",(tonodes(tostring(middle),font,attr)))
end
- setfield(start,"attr",copy_nodelist(attr)) -- todo: critical only
+ setfield(start,"attr",copy_nodelist(attr)) -- todo: critical only -- just a copy will do
free_node(tmp)
insert_break(head,start,10000,10000)
end
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..73b00f033 100644
--- a/tex/context/base/typo-dua.lua
+++ b/tex/context/base/typo-dua.lua
@@ -80,6 +80,7 @@ local getfield = nuts.getfield
local setfield = nuts.setfield
local remove_node = nuts.remove
+local copy_node = nuts.copy
local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
@@ -106,7 +107,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)
@@ -708,20 +709,26 @@ local function apply_to_list(list,size,head,pardir)
elseif id == glue_code then
if enddir and getsubtype(current) == parfillskip_code then
-- insert the last enddir before \parfillskip glue
- head = insert_node_before(head,current,new_textdir(enddir))
+ local d = new_textdir(enddir)
+-- setfield(d,"attr",copy_node(getfield(current,"attr")))
+ head = insert_node_before(head,current,d)
enddir = false
done = true
end
elseif id == whatsit_code then
if begindir and getsubtype(current) == localpar_code then
-- local_par should always be the 1st node
- head, current = insert_node_after(head,current,new_textdir(begindir))
+ local d = new_textdir(begindir)
+-- setfield(d,"attr",copy_node(getfield(current,"attr")))
+ head, current = insert_node_after(head,current,d)
begindir = nil
done = true
end
end
if begindir then
- head = insert_node_before(head,current,new_textdir(begindir))
+ local d = new_textdir(begindir)
+-- setfield(d,"attr",copy_node(getfield(current,"attr")))
+ head = insert_node_before(head,current,d)
done = true
end
local skip = entry.skip
@@ -731,7 +738,9 @@ local function apply_to_list(list,size,head,pardir)
end
end
if enddir then
- head, current = insert_node_after(head,current,new_textdir(enddir))
+ local d = new_textdir(enddir)
+-- setfield(d,"attr",copy_node(getfield(current,"attr")))
+ head, current = insert_node_after(head,current,d)
done = true
end
if not entry.remove then
diff --git a/tex/context/base/typo-dub.lua b/tex/context/base/typo-dub.lua
index 4dc0f21fb..b6581137b 100644
--- a/tex/context/base/typo-dub.lua
+++ b/tex/context/base/typo-dub.lua
@@ -65,10 +65,12 @@ 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
local remove_node = nuts.remove
+local copy_node = nuts.copy
local insert_node_after = nuts.insert_after
local insert_node_before = nuts.insert_before
@@ -97,11 +99,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)
@@ -817,20 +819,26 @@ local function apply_to_list(list,size,head,pardir)
elseif id == glue_code then
if enddir and getsubtype(current) == parfillskip_code then
-- insert the last enddir before \parfillskip glue
- head = insert_node_before(head,current,new_textdir(enddir))
+ local d = new_textdir(enddir)
+-- setfield(d,"attr",copy_node(getfield(current,"attr")))
+ head = insert_node_before(head,current,d)
enddir = false
done = true
end
elseif id == whatsit_code then
if begindir and getsubtype(current) == localpar_code then
-- local_par should always be the 1st node
- head, current = insert_node_after(head,current,new_textdir(begindir))
+ local d = new_textdir(begindir)
+-- setfield(d,"attr",copy_node(getfield(current,"attr")))
+ head, current = insert_node_after(head,current,d)
begindir = nil
done = true
end
end
if begindir then
- head = insert_node_before(head,current,new_textdir(begindir))
+ local d = new_textdir(begindir)
+-- setfield(d,"attr",copy_node(getfield(current,"attr")))
+ head = insert_node_before(head,current,d)
done = true
end
local skip = entry.skip
@@ -840,7 +848,9 @@ local function apply_to_list(list,size,head,pardir)
end
end
if enddir then
- head, current = insert_node_after(head,current,new_textdir(enddir))
+ local d = new_textdir(enddir)
+-- setfield(d,"attr",copy_node(getfield(current,"attr")))
+ head, current = insert_node_after(head,current,d)
done = true
end
if not entry.remove then
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-sci.lua b/tex/context/base/util-sci.lua
new file mode 100644
index 000000000..98b05fe75
--- /dev/null
+++ b/tex/context/base/util-sci.lua
@@ -0,0 +1,262 @@
+local gsub, sub, find = string.gsub, string.sub, string.find
+local concat = table.concat
+local formatters = string.formatters
+local lpegmatch = lpeg.match
+local setmetatableindex = table.setmetatableindex
+
+local scite = scite or { }
+utilities.scite = scite
+
+local report = logs.reporter("scite")
+
+local lexerroot = file.dirname(resolvers.find_file("scite-context-lexer.lua"))
+
+local knownlexers = {
+ tex = "tex", mkiv = "tex", mkvi = "tex", mkxi = "tex", mkix = "tex", mkii = "tex", cld = "tex",
+ lua = "lua", lfg = "lua", lus = "lua",
+ w = "web", ww = "web",
+ c = "cpp", h = "cpp", cpp = "cpp", hpp = "cpp", cxx = "cpp", hxx = "cpp",
+ xml = "xml", lmx = "xml", ctx = "xml", xsl = "xml", xsd = "xml", rlx = "xml", css = "xml", dtd = "xml",
+ bib = "bibtex",
+ rme = "txt",
+ -- todo: pat/hyp ori
+}
+
+lexer = nil -- main lexer, global (for the moment needed for themes)
+
+local function loadscitelexer()
+ if not lexer then
+ dir.push(lexerroot)
+ lexer = dofile("scite-context-lexer.lua")
+ dofile("themes/scite-context-theme.lua")
+ dir.pop()
+ end
+ return lexer
+end
+
+local loadedlexers = setmetatableindex(function(t,k)
+ local l = knownlexers[k] or k
+ dir.push(lexerroot)
+ loadscitelexer()
+ local v = lexer.load(formatters["scite-context-lexer-%s"](l))
+ dir.pop()
+ t[l] = v
+ t[k] = v
+ return v
+end)
+
+scite.loadedlexers = loadedlexers
+scite.knownlexers = knownlexers
+scite.loadscitelexer = loadscitelexer
+
+local f_fore_bold = formatters['.%s { display: inline ; font-weight: bold ; color: #%s%s%s ; }']
+local f_fore_none = formatters['.%s { display: inline ; font-weight: normal ; color: #%s%s%s ; }']
+local f_none_bold = formatters['.%s { display: inline ; font-weight: bold ; }']
+local f_none_none = formatters['.%s { display: inline ; font-weight: normal ; }']
+local f_div_class = formatters['<div class="%s">%s</div>']
+local f_linenumber = formatters['\n<div class="linenumber">%s</div>']
+local f_div_number = formatters['.linenumber { display: inline-block ; font-weight: normal ; width: %sem ; margin-right: 2em ; padding-right: .25em ; text-align: right ; background-color: #C7C7C7 ; }']
+
+local replacer_regular = lpeg.replacer {
+ ["<"] = "&lt;",
+ [">"] = "&gt;",
+ ["&"] = "&amp;",
+}
+
+local linenumber = 0
+
+local replacer_numbered = lpeg.replacer {
+ ["<"] = "&lt;",
+ [">"] = "&gt;",
+ ["&"] = "&amp;",
+ [lpeg.patterns.newline] = function() linenumber = linenumber + 1 return f_linenumber(linenumber) end,
+}
+
+local css = nil
+
+local function exportcsslexing()
+ if not css then
+ loadscitelexer()
+ local function black(f)
+ return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == '00')
+ end
+ local result, r = { }, 0
+ for k, v in table.sortedhash(lexer.context.styles) do
+ local bold = v.bold
+ local fore = v.fore
+ r = r + 1
+ if fore and not black(fore) then
+ if bold then
+ result[r] = f_fore_bold(k,fore[1],fore[2],fore[3])
+ else
+ result[r] = f_fore_none(k,fore[1],fore[2],fore[3])
+ end
+ else
+ if bold then
+ result[r] = f_none_bold(k)
+ else
+ result[r] = f_none_none(k)
+ end
+ end
+ end
+ css = concat(result,"\n")
+ end
+ return css
+end
+
+local function exportwhites()
+ return setmetatableindex(function(t,k)
+ local v = find(k,"white") and true or false
+ t[k] = v
+ return v
+ end)
+end
+
+local function exportstyled(lexer,text,numbered)
+ local result = lexer.lex(lexer,text,0)
+ local start = 1
+ local whites = exportwhites()
+ local buffer, b = { "<pre>" }, 1
+ linenumber = 1
+ local replacer = numbered and replacer_numbered or replacer_regular
+ if numbered then
+ b = b + 1
+ buffer[b] = f_linenumber(1)
+ end
+ local n = #result
+ for i=1,n,2 do
+ local ii = i + 1
+ local style = result[i]
+ local position = result[ii]
+ local txt = sub(text,start,position-1)
+ if ii == n then
+ txt = gsub(txt,"[%s]+$","")
+ end
+ txt = lpegmatch(replacer,txt)
+ b = b + 1
+ if whites[style] then
+ buffer[b] = txt
+ else
+ buffer[b] = f_div_class(style,txt)
+ end
+ start = position
+ end
+ buffer[b+1] = "</pre>"
+ buffer = concat(buffer)
+ return buffer
+end
+
+local function exportcsslinenumber()
+ return f_div_number(#tostring(linenumber)/2+1)
+end
+
+local htmlfile = utilities.templates.replacer([[
+<?xml version="1.0"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <title>context util-sci web page: text</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+ <style type="text/css"><!--
+%lexingstyles%
+%numberstyles%
+ --></style>
+ <body>
+%lexedcontent%
+ </body>
+</html>
+]])
+
+function scite.tohtml(data,lexname,numbered)
+ return htmlfile {
+ lexedcontent = exportstyled(loadedlexers[lexname],data or "",numbered), -- before numberstyles
+ lexingstyles = exportcsslexing(),
+ numberstyles = exportcsslinenumber(),
+ }
+end
+
+function scite.filetohtml(filename,lexname,targetname,numbered)
+ io.savedata(targetname or "util-sci.html",scite.tohtml(io.loaddata(filename),lexname or file.suffix(filename),numbered))
+end
+
+function scite.css()
+ return exportcsslexing() .. "\n" .. exportcsslinenumber()
+end
+
+function scite.html(data,lexname,numbered)
+ return exportstyled(loadedlexers[lexname],data or "",numbered)
+end
+
+local f_tree_entry = formatters['<a href="%s" class="dir-entry">%s</a>']
+
+local htmlfile = utilities.templates.replacer([[
+<?xml version="1.0"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <title>context util-sci web page: text</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+ <style type="text/css"><!--
+%styles%
+ --></style>
+ <body>
+ <pre>
+%dirlist%
+ </pre>
+ </body>
+</html>
+]])
+
+function scite.converttree(sourceroot,targetroot,numbered)
+ if lfs.isdir(sourceroot) then
+ statistics.starttiming()
+ local skipped = { }
+ local noffiles = 0
+ dir.makedirs(targetroot)
+ local function scan(sourceroot,targetroot)
+ local tree = { }
+ for name in lfs.dir(sourceroot) do
+ if name ~= "." and name ~= ".." then
+ local sourcename = file.join(sourceroot,name)
+ local targetname = file.join(targetroot,name)
+ local mode = lfs.attributes(sourcename,'mode')
+ if mode == 'file' then
+ local filetype = file.suffix(sourcename)
+ local basename = file.basename(name)
+ local targetname = file.replacesuffix(targetname,"html")
+ if knownlexers[filetype] then
+ report("converting file %a to %a",sourcename,targetname)
+ scite.filetohtml(sourcename,nil,targetname,numbered)
+ noffiles = noffiles + 1
+ tree[#tree+1] = f_tree_entry(file.basename(targetname),basename)
+ else
+ skipped[filetype] = true
+ report("no lexer for %a",sourcename)
+ end
+ else
+ dir.makedirs(targetname)
+ scan(sourcename,targetname)
+ tree[#tree+1] = f_tree_entry(file.join(name,"files.html"),name)
+ end
+ end
+ end
+ report("saving tree in %a",treename)
+ local htmldata = htmlfile {
+ dirlist = concat(tree,"\n"),
+ styles = "",
+ }
+ io.savedata(file.join(targetroot,"files.html"),htmldata)
+ end
+ scan(sourceroot,targetroot)
+ if next(skipped) then
+ report("skipped filetypes: %a",table.concat(table.sortedkeys(skipped)," "))
+ end
+ statistics.stoptiming()
+ report("conversion time for %s files: %s",noffiles,statistics.elapsedtime())
+ end
+end
+
+-- scite.filetohtml("strc-sec.mkiv",nil,"e:/tmp/util-sci.html",true)
+-- scite.filetohtml("syst-aux.mkiv",nil,"e:/tmp/util-sci.html",true)
+
+-- scite.converttree("t:/texmf/tex/context","e:/tmp/html/context",true)
+
+return scite
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/fonts/texgyre.lfg b/tex/context/fonts/texgyre.lfg
index 7782aa509..785982037 100644
--- a/tex/context/fonts/texgyre.lfg
+++ b/tex/context/fonts/texgyre.lfg
@@ -26,5 +26,11 @@ return {
"tgbonummath-regular.otf",
"tgbonum-math.otf",
},
+ ["texgyre-schola-math-regular.otf"] = {
+ "texgyreschola-math.otf", -- beta
+ "texgyrescholamath-regular.otf",
+ "tgscholamath-regular.otf",
+ "tgschola-math.otf",
+ },
},
}
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/patterns/lang-it.lua b/tex/context/patterns/lang-it.lua
index 20ab48fbf..fb6a9d893 100644
--- a/tex/context/patterns/lang-it.lua
+++ b/tex/context/patterns/lang-it.lua
@@ -38,7 +38,7 @@ return {
%\
% This work consists of the single file hyph-it.tex.\
%\
-% \\versionnumber{4.8i} \\versiondate{2011/08/16}\
+% \\versionnumber{4.9} \\versiondate{2014/04/22}\
%\
% These hyphenation patterns for the Italian language are supposed to comply\
% with the Recommendation UNI 6461 on hyphenation issued by the Italian\
@@ -47,6 +47,7 @@ return {
% liability is disclaimed.\
%\
% ChangeLog:\
+% - 2014-04-22 - Add few pattherns involving `h'\
% - 2011-08-16 - Change the licence from GNU LGPL into LPPL v1.3.\
% - 2010-05-24 - Fix for Italian patterns for proper hyphenation of -ich and Ljubljana.\
% - 2008-06-09 - Import of original ithyph.tex into hyph-utf8 package.\
@@ -56,11 +57,11 @@ return {
},
["patterns"]={
["characters"]="'abcdefghijklmnopqrstuvwxyz’",
- ["data"]=".a3p2n .anti1 .anti3m2n .bio1 .ca4p3s .circu2m1 .contro1 .di2s3cine .e2x1eu .fran2k3 .free3 .li3p2sa .narco1 .opto1 .orto3p2 .para1 .poli3p2 .pre1 .p2s .re1i2scr .sha2re3 .tran2s3c .tran2s3d .tran2s3l .tran2s3n .tran2s3p .tran2s3r .tran2s3t .su2b3lu .su2b3r .wa2g3n .wel2t1 2'2 2’2 a1ia a1ie a1io a1iu a1uo a1ya 2at. e1iu e2w o1ia o1ie o1io o1iu 1b 2bb 2bc 2bd 2bf 2bm 2bn 2bp 2bs 2bt 2bv b2l b2r 2b. 2b' 2b’ 1c 2cb 2cc 2cd 2cf 2ck 2cm 2cn 2cq 2cs 2ct 2cz 2chh c2h 2ch. 2ch'. 2ch’. 2ch''. 2ch’’. 2chb ch2r 2chn c2l c2r 2c. 2c' 2c’ .c2 1d 2db 2dd 2dg 2dl 2dm 2dn 2dp d2r 2ds 2dt 2dv 2dw 2d. 2d' 2d’ .d2 1f 2fb 2fg 2ff 2fn f2l f2r 2fs 2ft 2f. 2f' 2f’ 1g 2gb 2gd 2gf 2gg g2h g2l 2gm g2n 2gp g2r 2gs 2gt 2gv 2gw 2gz 2gh2t 2g. 2g' 2g’ 1h 2hb 2hd 2hh hi3p2n h2l 2hm 2hn 2hr 2hv 2h. 2h' 2h’ 1j 2j. 2j' 2j’ 1k 2kg 2kf k2h 2kk k2l 2km k2r 2ks 2kt 2k. 2k' 2k’ 1l 2lb 2lc 2ld 2l3f2 2lg l2h l2j 2lk 2ll 2lm 2ln 2lp 2lq 2lr 2ls 2lt 2lv 2lw 2lz 2l. 2l'. 2l’. 2l'' 2l’’ 1m 2mb 2mc 2mf 2ml 2mm 2mn 2mp 2mq 2mr 2ms 2mt 2mv 2mw 2m. 2m' 2m’ 1n 2nb 2nc 2nd 2nf 2ng 2nk 2nl 2nm 2nn 2np 2nq 2nr 2ns n2s3fer 2nt 2nv 2nz n2g3n 2nheit 2n. 2n' 2n’ 1p 2pd p2h p2l 2pn 3p2ne 2pp p2r 2ps 3p2sic 2pt 2pz 2p. 2p' 2p’ 1q 2qq 2q. 2q' 2q’ 1r 2rb 2rc 2rd 2rf r2h 2rg 2rk 2rl 2rm 2rn 2rp 2rq 2rr 2rs 2rt r2t2s3 2rv 2rx 2rw 2rz 2r. 2r' 2r’ 1s2 2shm 2sh. 2sh' 2sh’ 2s3s s4s3m 2s3p2n 2stb 2stc 2std 2stf 2stg 2stm 2stn 2stp 2sts 2stt 2stv 2sz 4s. 4s'. 4s’. 4s'' 4s’’ 1t 2tb 2tc 2td 2tf 2tg t2h t2l 2tm 2tn 2tp t2r t2s 3t2sch 2tt t2t3s 2tv 2tw t2z 2tzk tz2s 2t. 2t'. 2t’. 2t'' 2t’’ 1v 2vc v2l v2r 2vv 2v. 2v'. 2v’. 2v'' 2v’’ 1w w2h wa2r 2w1y 2w. 2w' 2w’ 1x 2xb 2xc 2xf 2xh 2xm 2xp 2xt 2xw 2x. 2x' 2x’ y1ou y1i 1z 2zb 2zd 2zl 2zn 2zp 2zt 2zs 2zv 2zz 2z. 2z'. 2z’. 2z'' 2z’’ .z2",
- ["length"]=1806,
+ ["data"]=".a3p2n .anti1 .anti3m2n .bio1 .ca4p3s .circu2m1 .contro1 .di2s3cine .e2x1eu .fran2k3 .free3 .li3p2sa .narco1 .opto1 .orto3p2 .para1 .ph2l .ph2r .poli3p2 .pre1 .p2s .re1i2scr .sha2re3 .tran2s3c .tran2s3d .tran2s3l .tran2s3n .tran2s3p .tran2s3r .tran2s3t .su2b3lu .su2b3r .wa2g3n .wel2t1 2'2 2’2 a1ia a1ie a1io a1iu a1uo a1ya 2at. e1iu e2w o1ia o1ie o1io o1iu 1b 2bb 2bc 2bd 2bf 2bm 2bn 2bp 2bs 2bt 2bv b2l b2r 2b. 2b' 2b’ 1c 2cb 2cc 2cd 2cf 2ck 2cm 2cn 2cq 2cs 2ct 2cz 2chh c2h 2ch. 2ch'. 2ch’. 2ch''. 2ch’’. 2chb ch2r 2chn c2l c2r 2c. 2c' 2c’ .c2 1d 2db 2dd 2dg 2dl 2dm 2dn 2dp d2r 2ds 2dt 2dv 2dw 2d. 2d' 2d’ .d2 1f 2fb 2fg 2ff 2fn f2l f2r 2fs 2ft 2f. 2f' 2f’ 1g 2gb 2gd 2gf 2gg g2h g2l 2gm g2n 2gp g2r 2gs 2gt 2gv 2gw 2gz 2gh2t 2g. 2g' 2g’ .h2 1h 2hb 2hd 2hh hi3p2n h2l 2hm 2hn 2hr 2hv 2h. 2h' 2h’ .j2 1j 2j. 2j' 2j’ .k2 1k 2kg 2kf k2h 2kk k2l 2km k2r 2ks 2kt 2k. 2k' 2k’ 1l 2lb 2lc 2ld 2l3f2 2lg l2h l2j 2lk 2ll 2lm 2ln 2lp 2lq 2lr 2ls 2lt 2lv 2lw 2lz 2l. 2l'. 2l’. 2l'' 2l’’ 1m 2mb 2mc 2mf 2ml 2mm 2mn 2mp 2mq 2mr 2ms 2mt 2mv 2mw 2m. 2m' 2m’ 1n 2nb 2nc 2nd 2nf 2ng 2nk 2nl 2nm 2nn 2np 2nq 2nr 2ns n2s3fer 2nt 2nv 2nz n2g3n 2nheit 2n. 2n' 2n’ 1p 2pd p2h p2l 2pn 3p2ne 2pp p2r 2ps 3p2sic 2pt 2pz 2p. 2p' 2p’ 1q 2qq 2q. 2q' 2q’ 1r 2rb 2rc 2rd 2rf r2h 2rg 2rk 2rl 2rm 2rn 2rp 2rq 2rr 2rs 2rt r2t2s3 2rv 2rx 2rw 2rz 2r. 2r' 2r’ 1s2 2shm 2sh. 2sh' 2sh’ 2s3s s4s3m 2s3p2n 2stb 2stc 2std 2stf 2stg 2stm 2stn 2stp 2sts 2stt 2stv 2sz 4s. 4s'. 4s’. 4s'' 4s’’ .t2 1t 2tb 2tc 2td 2tf 2tg t2h 2th. t2l 2tm 2tn 2tp t2r t2s 3t2sch 2tt t2t3s 2tv 2tw t2z 2tzk tz2s 2t. 2t'. 2t’. 2t'' 2t’’ 1v 2vc v2l v2r 2vv 2v. 2v'. 2v’. 2v'' 2v’’ 1w w2h wa2r 2w1y 2w. 2w' 2w’ 1x 2xb 2xc 2xf 2xh 2xm 2xp 2xt 2xw 2x. 2x' 2x’ y1ou y1i 1z 2zb 2zd 2zl 2zn 2zp 2zt 2zs 2zv 2zz 2z. 2z'. 2z’. 2z'' 2z’’ .z2",
+ ["length"]=1839,
["minhyphenmax"]=1,
["minhyphenmin"]=1,
- ["n"]=377,
+ ["n"]=384,
},
["version"]="1.001",
} \ No newline at end of file
diff --git a/tex/context/patterns/lang-it.pat b/tex/context/patterns/lang-it.pat
index 78a127aa7..12a9edf33 100644
--- a/tex/context/patterns/lang-it.pat
+++ b/tex/context/patterns/lang-it.pat
@@ -21,6 +21,8 @@
.opto1
.orto3p2
.para1
+.ph2l
+.ph2r
.poli3p2
.pre1
.p2s
@@ -137,6 +139,7 @@ g2r
2gh2t
2g.
2g'
+.h2
1h
2hb
2hd
@@ -149,9 +152,11 @@ h2l
2hv
2h.
2h'
+.j2
1j
2j.
2j'
+.k2
1k
2kg
2kf
@@ -288,6 +293,7 @@ s4s3m
4s.
4s'.
4s''
+.t2
1t
2tb
2tc
@@ -295,6 +301,7 @@ s4s3m
2tf
2tg
t2h
+2th.
t2l
2tm
2tn
diff --git a/tex/context/patterns/lang-it.rme b/tex/context/patterns/lang-it.rme
index 6cfe6896a..2a2fb60d5 100644
--- a/tex/context/patterns/lang-it.rme
+++ b/tex/context/patterns/lang-it.rme
@@ -32,7 +32,7 @@ Italian hyphenation patterns
%
% This work consists of the single file hyph-it.tex.
%
-% \versionnumber{4.8i} \versiondate{2011/08/16}
+% \versionnumber{4.9} \versiondate{2014/04/22}
%
% These hyphenation patterns for the Italian language are supposed to comply
% with the Recommendation UNI 6461 on hyphenation issued by the Italian
@@ -41,6 +41,7 @@ Italian hyphenation patterns
% liability is disclaimed.
%
% ChangeLog:
+% - 2014-04-22 - Add few pattherns involving `h'
% - 2011-08-16 - Change the licence from GNU LGPL into LPPL v1.3.
% - 2010-05-24 - Fix for Italian patterns for proper hyphenation of -ich and Ljubljana.
% - 2008-06-09 - Import of original ithyph.tex into hyph-utf8 package.
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