summaryrefslogtreecommitdiff
path: root/tex/context/base
diff options
context:
space:
mode:
authorMarius <mariausol@gmail.com>2010-08-14 15:56:20 +0300
committerMarius <mariausol@gmail.com>2010-08-14 15:56:20 +0300
commitb469b8ec1b494ab72cd462bfc539ce01440e6aaf (patch)
tree3a9c3fb8433c5f75020fef1d531bedb7c948f66c /tex/context/base
parent39e30629c15ae4a899532d84c4abea127f2847a6 (diff)
downloadcontext-b469b8ec1b494ab72cd462bfc539ce01440e6aaf.tar.gz
beta 2010.08.10 17:14
Diffstat (limited to 'tex/context/base')
-rw-r--r--tex/context/base/attr-div.lua143
-rw-r--r--tex/context/base/back-ini.lua2
-rw-r--r--tex/context/base/back-ini.mkiv10
-rw-r--r--tex/context/base/buff-ini.lua3
-rw-r--r--tex/context/base/buff-ver.mkiv26
-rw-r--r--tex/context/base/char-def.lua2
-rw-r--r--tex/context/base/char-ini.lua11
-rw-r--r--tex/context/base/colo-icc.lua118
-rw-r--r--tex/context/base/colo-ini.lua65
-rw-r--r--tex/context/base/colo-ini.mkiv1
-rw-r--r--tex/context/base/cont-new.tex2
-rw-r--r--tex/context/base/context.mkiv1
-rw-r--r--tex/context/base/context.tex2
-rw-r--r--tex/context/base/core-con.lua249
-rw-r--r--tex/context/base/core-con.mkiv121
-rw-r--r--tex/context/base/core-ctx.mkiv2
-rw-r--r--tex/context/base/data-env.lua2
-rw-r--r--tex/context/base/enco-agr.mkii2
-rw-r--r--tex/context/base/enco-ans.mkii2
-rw-r--r--tex/context/base/enco-ec.mkii2
-rw-r--r--tex/context/base/enco-qx.mkii2
-rw-r--r--tex/context/base/font-afm.lua8
-rw-r--r--tex/context/base/font-ctx.lua122
-rw-r--r--tex/context/base/font-def.lua3
-rw-r--r--tex/context/base/font-enh.lua4
-rw-r--r--tex/context/base/font-gds.lua12
-rw-r--r--tex/context/base/font-ini.lua1
-rw-r--r--tex/context/base/font-ini.mkiv6
-rw-r--r--tex/context/base/font-otd.lua1
-rw-r--r--tex/context/base/font-otf.lua24
-rw-r--r--tex/context/base/font-ott.lua56
-rw-r--r--tex/context/base/font-syn.lua29
-rw-r--r--tex/context/base/font-tfm.lua4
-rw-r--r--tex/context/base/grph-inc.lua3
-rw-r--r--tex/context/base/java-ini.lua36
-rw-r--r--tex/context/base/l-aux.lua68
-rw-r--r--tex/context/base/l-io.lua33
-rw-r--r--tex/context/base/l-lpeg.lua42
-rw-r--r--tex/context/base/l-number.lua18
-rw-r--r--tex/context/base/l-table.lua43
-rw-r--r--tex/context/base/l-unicode.lua12
-rw-r--r--tex/context/base/lang-wrd.lua9
-rw-r--r--tex/context/base/lpdf-col.lua101
-rw-r--r--tex/context/base/lpdf-epd.lua25
-rw-r--r--tex/context/base/lpdf-pdx.lua652
-rw-r--r--tex/context/base/lpdf-pdx.mkiv58
-rw-r--r--tex/context/base/lpdf-ren.lua121
-rw-r--r--tex/context/base/lpdf-tag.lua14
-rw-r--r--tex/context/base/luat-bwc.lua27
-rw-r--r--tex/context/base/luat-cod.lua14
-rw-r--r--tex/context/base/luat-fmt.lua20
-rw-r--r--tex/context/base/luat-lib.mkiv1
-rw-r--r--tex/context/base/lxml-lpt.lua20
-rw-r--r--tex/context/base/lxml-xml.lua14
-rw-r--r--tex/context/base/m-punk.mkiv358
-rw-r--r--tex/context/base/m-units.tex19
-rw-r--r--tex/context/base/math-noa.lua61
-rw-r--r--tex/context/base/math-tag.lua35
-rw-r--r--tex/context/base/meta-ini.mkiv55
-rw-r--r--tex/context/base/mlib-pps.lua137
-rw-r--r--tex/context/base/mult-aux.mkiv165
-rw-r--r--tex/context/base/mult-cld.lua81
-rw-r--r--tex/context/base/mult-de.tex2
-rw-r--r--tex/context/base/mult-def.lua13
-rw-r--r--tex/context/base/mult-en.tex2
-rw-r--r--tex/context/base/mult-fr.tex2
-rw-r--r--tex/context/base/mult-it.tex2
-rw-r--r--tex/context/base/mult-mcs.tex4
-rw-r--r--tex/context/base/mult-mde.tex4
-rw-r--r--tex/context/base/mult-men.tex4
-rw-r--r--tex/context/base/mult-mes.lua6
-rw-r--r--tex/context/base/mult-mfr.tex4
-rw-r--r--tex/context/base/mult-mit.tex4
-rw-r--r--tex/context/base/mult-mnl.tex4
-rw-r--r--tex/context/base/mult-mno.tex4
-rw-r--r--tex/context/base/mult-mpe.tex4
-rw-r--r--tex/context/base/mult-mro.tex4
-rw-r--r--tex/context/base/mult-nl.tex2
-rw-r--r--tex/context/base/mult-ro.tex2
-rw-r--r--tex/context/base/mult-sys.tex2
-rw-r--r--tex/context/base/node-acc.lua10
-rw-r--r--tex/context/base/node-aux.lua6
-rw-r--r--tex/context/base/node-bck.lua6
-rw-r--r--tex/context/base/node-dir.lua1
-rw-r--r--tex/context/base/node-fin.lua22
-rw-r--r--tex/context/base/node-fnt.lua8
-rw-r--r--tex/context/base/node-ini.lua79
-rw-r--r--tex/context/base/node-mig.lua12
-rw-r--r--tex/context/base/node-pro.lua4
-rw-r--r--tex/context/base/node-ref.lua10
-rw-r--r--tex/context/base/node-res.lua28
-rw-r--r--tex/context/base/node-rul.lua45
-rw-r--r--tex/context/base/node-ser.lua8
-rw-r--r--tex/context/base/node-shp.lua19
-rw-r--r--tex/context/base/node-spl.lua16
-rw-r--r--tex/context/base/node-tra.lua137
-rw-r--r--tex/context/base/node-tsk.lua2
-rw-r--r--tex/context/base/node-tst.lua17
-rw-r--r--tex/context/base/node-typ.lua6
-rw-r--r--tex/context/base/pack-rul.mkiv90
-rw-r--r--tex/context/base/page-lin.lua44
-rw-r--r--tex/context/base/page-lin.mkiv60
-rw-r--r--tex/context/base/page-mul.mkii8
-rw-r--r--tex/context/base/page-mul.mkiv51
-rw-r--r--tex/context/base/scrn-nav.mkiv1
-rw-r--r--tex/context/base/spac-ver.lua99
-rw-r--r--tex/context/base/strc-bkm.lua99
-rw-r--r--tex/context/base/strc-bkm.mkiv50
-rw-r--r--tex/context/base/strc-blk.lua4
-rw-r--r--tex/context/base/strc-des.mkiv20
-rw-r--r--tex/context/base/strc-doc.lua124
-rw-r--r--tex/context/base/strc-ini.lua5
-rw-r--r--tex/context/base/strc-itm.mkiv22
-rw-r--r--tex/context/base/strc-lst.lua91
-rw-r--r--tex/context/base/strc-lst.mkiv15
-rw-r--r--tex/context/base/strc-not.lua4
-rw-r--r--tex/context/base/strc-not.mkii2
-rw-r--r--tex/context/base/strc-not.mkiv110
-rw-r--r--tex/context/base/strc-ref.lua5
-rw-r--r--tex/context/base/strc-ref.mkiv344
-rw-r--r--tex/context/base/strc-reg.mkiv2
-rw-r--r--tex/context/base/strc-ren.mkiv15
-rw-r--r--tex/context/base/strc-sec.mkiv7
-rw-r--r--tex/context/base/strc-syn.mkiv7
-rw-r--r--tex/context/base/strc-tag.lua3
-rw-r--r--tex/context/base/syst-ext.mkii4
-rw-r--r--tex/context/base/tabl-ntb.mkiv8
-rw-r--r--tex/context/base/tabl-tbl.mkiv14
-rw-r--r--tex/context/base/task-ini.lua4
-rw-r--r--tex/context/base/trac-set.lua55
-rw-r--r--tex/context/base/type-dejavu.mkiv16
-rw-r--r--tex/context/base/type-otf.mkii34
-rw-r--r--tex/context/base/type-otf.mkiv74
-rw-r--r--tex/context/base/typo-brk.lua6
-rw-r--r--tex/context/base/typo-cap.lua6
-rw-r--r--tex/context/base/typo-dig.lua6
-rw-r--r--tex/context/base/typo-krn.lua18
-rw-r--r--tex/context/base/typo-mir.lua12
-rw-r--r--tex/context/base/typo-rep.lua5
-rw-r--r--tex/context/base/typo-spa.lua4
-rw-r--r--tex/context/base/unic-003.mkii2
-rw-r--r--tex/context/base/xetx-utf.mkii5
142 files changed, 3668 insertions, 1672 deletions
diff --git a/tex/context/base/attr-div.lua b/tex/context/base/attr-div.lua
index e618a35c1..4397936d9 100644
--- a/tex/context/base/attr-div.lua
+++ b/tex/context/base/attr-div.lua
@@ -14,7 +14,10 @@ local format, gmatch = string.format, string.gmatch
local concat = table.concat
local texsprint = tex.sprint
-local report_attributes = logs.new("attributes")
+local report_attributes = logs.new("attributes")
+local report_colors = logs.new("colors")
+local report_transparencies = logs.new("transparencies")
+local report_viewerlayers = logs.new("viewerlayers")
local ctxcatcodes = tex.ctxcatcodes
local unsetvalue = attributes.unsetvalue
@@ -70,6 +73,7 @@ colors.selector = attributes.private('colormodel')
colors.default = 1
colors.main = nil
colors.triggering = true
+colors.supported = true
storage.register("colors/values", colors.values, "colors.values")
storage.register("colors/registered", colors.registered, "colors.registered")
@@ -248,7 +252,7 @@ local function cmykcolor(...) cmykcolor = nodeinjections.cmykcolor return cmykco
local function spotcolor(...) spotcolor = nodeinjections.spotcolor return spotcolor(...) end
local function extender(colors,key)
- if key == "none" then
+ if colors.supported and key == "none" then
local d = graycolor(0)
colors.none = d
return d
@@ -256,31 +260,33 @@ local function extender(colors,key)
end
local function reviver(data,n)
- local v = values[n]
- local d
- if not v then
- local gray = graycolor(0)
- d = { gray, gray, gray, gray }
- report_attributes("unable to revive color %s",n or "?")
- else
- local kind = v[1]
- if kind == 2 then
- local gray= graycolor(v[2])
+ if colors.supported then
+ local v = values[n]
+ local d
+ if not v then
+ local gray = graycolor(0)
d = { gray, gray, gray, gray }
- elseif kind == 3 then
- local gray, rgb, cmyk = graycolor(v[2]), rgbcolor(v[3],v[4],v[5]), cmykcolor(v[6],v[7],v[8],v[9])
- d = { rgb, gray, rgb, cmyk }
- elseif kind == 4 then
- local gray, rgb, cmyk = graycolor(v[2]), rgbcolor(v[3],v[4],v[5]), cmykcolor(v[6],v[7],v[8],v[9])
- d = { cmyk, gray, rgb, cmyk }
- elseif kind == 5 then
- local spot = spotcolor(v[10],v[11],v[12],v[13])
- -- d = { spot, gray, rgb, cmyk }
- d = { spot, spot, spot, spot }
+ report_attributes("unable to revive color %s",n or "?")
+ else
+ local kind = colors.forcedmodel(v[1])
+ if kind == 2 then
+ local gray= graycolor(v[2])
+ d = { gray, gray, gray, gray }
+ elseif kind == 3 then
+ local gray, rgb, cmyk = graycolor(v[2]), rgbcolor(v[3],v[4],v[5]), cmykcolor(v[6],v[7],v[8],v[9])
+ d = { rgb, gray, rgb, cmyk }
+ elseif kind == 4 then
+ local gray, rgb, cmyk = graycolor(v[2]), rgbcolor(v[3],v[4],v[5]), cmykcolor(v[6],v[7],v[8],v[9])
+ d = { cmyk, gray, rgb, cmyk }
+ elseif kind == 5 then
+ local spot = spotcolor(v[10],v[11],v[12],v[13])
+ -- d = { spot, gray, rgb, cmyk }
+ d = { spot, spot, spot, spot }
+ end
end
+ data[n] = d
+ return d
end
- data[n] = d
- return d
end
setmetatable(colors, { __index = extender })
@@ -325,8 +331,18 @@ shipouts.handle_color = nodes.install_attribute_handler {
resolver = function() return colors.main end,
}
-function colors.enable()
- tasks.enableaction("shipouts","shipouts.handle_color")
+function colors.enable(value)
+ if value == false or not colors.supported then
+ tasks.disableaction("shipouts","shipouts.handle_color")
+ else
+ tasks.enableaction("shipouts","shipouts.handle_color")
+ end
+end
+
+function colors.forcesupport(value) -- can move to attr-div
+ colors.supported = value
+ report_colors("color is %ssupported",value and "" or "not ")
+ colors.enable(value)
end
-- transparencies
@@ -337,6 +353,7 @@ transparencies.data = transparencies.data or { }
transparencies.values = transparencies.values or { }
transparencies.triggering = true
transparencies.attribute = attributes.private('transparency')
+transparencies.supported = true
storage.register("transparencies/registered", transparencies.registered, "transparencies.registered")
storage.register("transparencies/values", transparencies.values, "transparencies.values")
@@ -377,7 +394,7 @@ function transparencies.register(name,a,t,force) -- name is irrelevant here (can
end
local function extender(transparencies,key)
- if key == "none" then
+ if colors.supported and key == "none" then
local d = inject_transparency(0)
transparencies.none = d
return d
@@ -385,16 +402,20 @@ local function extender(transparencies,key)
end
local function reviver(data,n)
- local v = values[n]
- local d
- if not v then
- d = inject_transparency(0)
+ if transparencies.supported then
+ local v = values[n]
+ local d
+ if not v then
+ d = inject_transparency(0)
+ else
+ d = inject_transparency(n)
+ register_transparency(n,v[1],v[2])
+ end
+ data[n] = d
+ return d
else
- d = inject_transparency(n)
- register_transparency(n,v[1],v[2])
+ return ""
end
- data[n] = d
- return d
end
setmetatable(transparencies, { __index = extender })
@@ -414,8 +435,18 @@ shipouts.handle_transparency = nodes.install_attribute_handler {
processor = states.process,
}
-function transparencies.enable()
- tasks.enableaction("shipouts","shipouts.handle_transparency")
+function transparencies.enable(value) -- nil is enable
+ if value == false or not transparencies.supported then
+ tasks.disableaction("shipouts","shipouts.handle_transparency")
+ else
+ tasks.enableaction("shipouts","shipouts.handle_transparency")
+ end
+end
+
+function transparencies.forcesupport(value) -- can move to attr-div
+ transparencies.supported = value
+ report_transparencies("transparency is %ssupported",value and "" or "not ")
+ transparencies.enable(value)
end
--- colorintents: overprint / knockout
@@ -591,6 +622,8 @@ viewerlayers.registered = viewerlayers.registered or { }
viewerlayers.values = viewerlayers.values or { }
viewerlayers.listwise = viewerlayers.listwise or { }
viewerlayers.attribute = attributes.private("viewerlayer")
+viewerlayers.supported = true
+viewerlayers.hasorder = true
storage.register("viewerlayers/registered", viewerlayers.registered, "viewerlayers.registered")
storage.register("viewerlayers/values", viewerlayers.values, "viewerlayers.values")
@@ -604,7 +637,7 @@ local template = "%s"
-- stacked
local function extender(viewerlayers,key)
- if key == "none" then
+ if viewerlayers.supported and key == "none" then
local d = nodeinjections.stoplayer()
viewerlayers.none = d
return d
@@ -612,13 +645,15 @@ local function extender(viewerlayers,key)
end
local function reviver(data,n)
- local v = values[n]
- if v then
- local d = nodeinjections.startlayer(v)
- data[n] = d
- return d
- else
- logs.report("viewerlayers","error, unknown reference '%s'",tostring(n))
+ if viewerlayers.supported then
+ local v = values[n]
+ if v then
+ local d = nodeinjections.startlayer(v)
+ data[n] = d
+ return d
+ else
+ logs.report("viewerlayers","error, unknown reference '%s'",tostring(n))
+ end
end
end
@@ -649,6 +684,20 @@ shipouts.handle_viewerlayer = nodes.install_attribute_handler {
processor = states.stacked,
}
-function viewerlayers.enable()
- tasks.enableaction("shipouts","shipouts.handle_viewerlayer")
+function viewerlayers.enable(value)
+ if value == false or not viewerlayers.supported then
+ tasks.disableaction("shipouts","shipouts.handle_viewerlayer")
+ else
+ tasks.enableaction("shipouts","shipouts.handle_viewerlayer")
+ end
+end
+
+function viewerlayers.forcesupport(value)
+ viewerlayers.supported = value
+ report_viewerlayers("viewerlayers are %ssupported",value and "" or "not ")
+ viewerlayers.enable(value)
+end
+
+function viewerlayers.setfeatures(hasorder)
+ viewerlayers.hasorder = hasorder
end
diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua
index 655500055..7331758ac 100644
--- a/tex/context/base/back-ini.lua
+++ b/tex/context/base/back-ini.lua
@@ -94,6 +94,8 @@ backends.codeinjections = {
mergereferences = nothing,
mergelayers = nothing,
+ setformat = nothing,
+ getformatoption = nothing,
}
backends.registrations = {
diff --git a/tex/context/base/back-ini.mkiv b/tex/context/base/back-ini.mkiv
index b7bbdb56f..db37cf61f 100644
--- a/tex/context/base/back-ini.mkiv
+++ b/tex/context/base/back-ini.mkiv
@@ -165,4 +165,14 @@
\unexpanded\def\setupoutput[#1]{} % will be command line switch
+%D New:
+
+\newtoks\everysetupbackend
+
+\def\backendparameter#1{\csname\ifcsname\??bc#1\endcsname\??bc#1\else\s!empty\fi\endcsname}
+
+\def\setupbackend[#1]%
+ {\getparameters[\??bc][#1]%
+ \the\everysetupbackend}
+
\protect \endinput
diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua
index b3ab0c2a7..0cf8c8804 100644
--- a/tex/context/base/buff-ini.lua
+++ b/tex/context/base/buff-ini.lua
@@ -59,7 +59,6 @@ function buffers.append(name, str)
data[name] = (data[name] or "") .. str
end
-
buffers.flags.store_as_table = true
-- to be sorted out: crlf + \ ; slow now
@@ -314,7 +313,7 @@ end
local printer = (lpeg.patterns.textline/texprint)^0
function buffers.get(name)
- local b = buffers.data[name]
+ local b = data[name]
if b then
if type(b) == "table" then
for i=1,#b do
diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv
index 59b484983..8c4e7a557 100644
--- a/tex/context/base/buff-ver.mkiv
+++ b/tex/context/base/buff-ver.mkiv
@@ -21,6 +21,10 @@
\ifdefined\stoplinenumbering \else \let\stoplinenumbering \relax \fi
\ifdefined\setuplinenumbering\else \unexpanded\def\setuplinenumbering[#1]{} \fi
+\definesystemattribute[verbatim-line] \chardef\verbatimlineattribute \dogetattributeid{verbatim-line}
+
+\appendtoksonce \attribute\verbatimlineattribute \attributeunsetvalue \to \everyforgetall
+
% D \macros
% D {iflinepar}
% D
@@ -606,19 +610,6 @@
\def\doverbatimgoodbreak
{\ifoptimizeverbatim\penalty\linepenalty\fi}
-% \def\doflushverbatimline
-% {\expandafter\dodoverbatimline\expandafter{\savedverbatimline}}
-% \def\doverbatimbeginofline#1% linenumber (optional provided by mkiv / todo)
-% {\dontleavehmode
-% \strut
-% \the\everyline}
-% \def\doverbatimendofline
-% {\par}
-% \def\doverbatimemptyline
-% {\strut
-% \par}
-% \let\handleverbatimline=\relax
-
% we need this hack because otherwise verbatim skips
% the first line (everything after the initial command)
@@ -1177,8 +1168,12 @@
\def\doverbatimendofinline
{\the\everyverbatimendofinline}
+\newcount\nofverbatimlines
+
\def\doverbatimbeginofline#1% linenumber
- {\bgroup % due to pretty status
+ {\global\advance\nofverbatimlines\plusone
+ \attribute\verbatimlineattribute\nofverbatimlines
+ \bgroup % due to pretty status
\iflinepar\else\EveryPar{}\fi
\noindent % was wrong: \dontleavehmode
\xdef\dokeepverbatimlinedata % hm, still needed?
@@ -1196,7 +1191,8 @@
\def\doverbatimendofline
{%\endverbatimline
\global\lineparfalse
- \obeyedline\par}
+ \obeyedline\par
+ \attribute\verbatimlineattribute\attributeunsetvalue}
\def\doverbatimemptyline
{\strut
diff --git a/tex/context/base/char-def.lua b/tex/context/base/char-def.lua
index 99ac18978..38769404a 100644
--- a/tex/context/base/char-def.lua
+++ b/tex/context/base/char-def.lua
@@ -8696,7 +8696,7 @@ characters.data={
[0x0390]={
adobename="iotadieresistonos",
category="ll",
- contextname="greekiotadialytikatonos",
+ contextname="greekiotadialytikatonos", -- double
description="GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS",
direction="l",
linebreak="al",
diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua
index 5c4a40bad..e61f1ce78 100644
--- a/tex/context/base/char-ini.lua
+++ b/tex/context/base/char-ini.lua
@@ -566,12 +566,17 @@ end
function characters.uccode(n) return data[n].uccode or n end
function characters.lccode(n) return data[n].lccode or n end
-function characters.flush(n)
+function characters.flush(n,direct)
local c = data[n]
if c and c.contextname then
- texsprint(texcatcodes, "\\"..c.contextname)
+ c = "\\" .. c.contextname
else
- texsprint(utfchar(n))
+ c = utfchar(n)
+ end
+ if direct then
+ return c
+ else
+ texsprint(c)
end
end
diff --git a/tex/context/base/colo-icc.lua b/tex/context/base/colo-icc.lua
new file mode 100644
index 000000000..724ff3241
--- /dev/null
+++ b/tex/context/base/colo-icc.lua
@@ -0,0 +1,118 @@
+if not modules then modules = { } end modules ['colo-ini'] = {
+ version = 1.000,
+ comment = "companion to colo-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local char, byte, gsub, match, format, strip = string.char, string.byte, string.gsub, string.match, string.format, string.strip
+local readstring, readnumber = io.readstring, io.readnumber
+
+colors = colors or { } -- can also be used in mtxrun
+
+local R, Cs, lpegmatch = lpeg.R, lpeg.Cs, lpeg.match
+
+local invalid = R(char(0)..char(31))
+local cleaned = invalid^0 * Cs((1-invalid)^0)
+
+function colors.iccprofile(filename,verbose)
+ local fullname = resolvers.find_file(filename,"icc") or ""
+ if fullname == "" then
+ local locate = resolvers.finders.loc -- not in mtxrun
+ if locate then
+ fullname = locate(filename) -- could be specific to the project
+ end
+ end
+ if fullname == "" then
+ return nil, false, format("profile '%s' cannot be found",filename)
+ end
+ local f = io.open(fullname,"rb")
+ if not f then
+ return nil, false, format("profile '%s'cannot be loaded",fullname)
+ end
+ local header = {
+ size = readnumber(f,4),
+ cmmtype = readnumber(f,4),
+ version = readnumber(f,4),
+ deviceclass = strip(readstring(f,4)),
+ colorspace = strip(readstring(f,4)),
+ connectionspace = strip(readstring(f,4)),
+ datetime = {
+ year = readnumber(f,2),
+ month = readnumber(f,2),
+ day = readnumber(f,2),
+ hour = readnumber(f,2),
+ minutes = readnumber(f,2),
+ seconds = readnumber(f,2),
+ },
+ filesignature = strip(readstring(f,4)),
+ platformsignature = strip(readstring(f,4)),
+ options = readnumber(f,4),
+ devicemanufacturer = strip(readstring(f,4)),
+ devicemodel = strip(readstring(f,4)),
+ deviceattributes = readnumber(f,4),
+ renderingintent = readnumber(f,4),
+ illuminantxyz = {
+ x = readnumber(f,4),
+ y = readnumber(f,4),
+ z = readnumber(f,4),
+ },
+ profilecreator = readnumber(f,4),
+ id = strip(readstring(f,16)),
+ }
+ local tags = { }
+ for i=1,readnumber(f,128,4) do
+ tags[readstring(f,4)] = {
+ offset = readnumber(f,4),
+ length = readnumber(f,4),
+ }
+ end
+ local o = header.options
+ header.options =
+ o == 0 and "embedded" or
+ o == 1 and "dependent" or "unknown"
+ local d = header.deviceattributes
+ header.deviceattributes = {
+ [number.hasbit(d,1) and "transparency" or "reflective"] = true,
+ [number.hasbit(d,2) and "mate" or "glossy" ] = true,
+ [number.hasbit(d,3) and "negative" or "positive" ] = true,
+ [number.hasbit(d,4) and "bw" or "color" ] = true,
+ }
+ local r = header.renderingintent
+ header.renderingintent =
+ r == 0 and "perceptual" or
+ r == 1 and "relative" or
+ r == 2 and "saturation" or
+ r == 3 and "absolute" or "unknown"
+ for tag, spec in next, tags do
+ if tag then
+ local offset, length = spec.offset, spec.length
+ local kind = readstring(f,offset,4)
+ if kind == "text" or kind == "desc" then
+ local str = readstring(f,length-4)
+ tags[tag] = {
+ data = str,
+ cleaned = lpegmatch(cleaned,str),
+ }
+ else
+ if verbose then
+ logs.simple("ignoring tag '%s' or type '%s' in profile '%s'",tag,kind,fullname)
+ end
+ tags[tag] = nil
+ end
+ end
+ end
+ f:close()
+ local profile = {
+ filename = filename,
+ fullname = fullname,
+ header = header,
+ tags = tags,
+ }
+ return profile, true, format("profile '%s' loaded",fullname)
+end
+
+--~ local profile, error, message = colors.iccprofile("ussheetfedcoated.icc")
+--~ print(error,message)
+--~ table.print(profile)
diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua
index 30b18983d..28ce4ac6a 100644
--- a/tex/context/base/colo-ini.lua
+++ b/tex/context/base/colo-ini.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['colo-ini'] = {
license = "see context related readme files"
}
-local type = type
+local type, tonumber = type, tonumber
local concat = table.concat
local format, gmatch, gsub, lower, match, find = string.format, string.gmatch, string.gsub, string.lower, string.match, string.find
local texsprint = tex.sprint
@@ -14,6 +14,8 @@ local ctxcatcodes = tex.ctxcatcodes
local trace_define = false trackers.register("colors.define",function(v) trace_define = v end)
+local report_colors = logs.new("colors")
+
local settings_to_hash_strict = aux.settings_to_hash_strict
colors = colors or { }
@@ -133,6 +135,60 @@ local transparent = {
exclusion = 12,
}
+-- backend driven limitations
+
+colors.supported = true -- always true
+transparencies.supported = true
+
+local gray_okay, rgb_okay, cmyk_okay, spot_okay, multichannel_okay, forced = true, true, true, true, true, false
+
+function colors.forcesupport(gray,rgb,cmyk,spot,multichannel) -- pdfx driven
+ gray_okay, rgb_okay, cmyk_okay, spot_okay, multichannel_okay, forced = gray, rgb, cmyk, spot, multichannel, true
+ report_colors("supported models: gray=%s, rgb=%s, cmyk=%s, spot=%s", -- multichannel=%s
+ tostring(gray), tostring(rgb), tostring(cmyk), tostring(spot)) -- tostring(multichannel)
+end
+
+local function forcedmodel(model) -- delayed till the backend but mp directly
+ if not forced then
+ return model
+ elseif model == 2 then -- gray
+ if gray_okay then
+ -- okay
+ elseif cmyk_okay then
+ return 4
+ elseif rgb_okay then
+ return 3
+ end
+ elseif model == 3 then -- rgb
+ if rgb_okay then
+ -- okay
+ elseif cmyk_okay then
+ return 4
+ elseif gray_okay then
+ return 2
+ end
+ elseif model == 4 then -- cmyk
+ if cmyk_okay then
+ -- okay
+ elseif rgb_okay then
+ return 3
+ elseif gray_okay then
+ return 2
+ end
+ elseif model == 5 then -- spot
+ if cmyk_okay then
+ return 4
+ elseif rgb_okay then
+ return 3
+ elseif gray_okay then
+ return 2
+ end
+ end
+ return model
+end
+
+colors.forcedmodel = forcedmodel
+
-- By coupling we are downward compatible. When we decouple we need to do more tricky
-- housekeeping (e.g. persist color independent transparencies when color bound ones
-- are nil.)
@@ -319,13 +375,14 @@ function colors.definemultitonecolor(name,multispec,colorspec,selfspec)
end
end
-function colors.mp(model,ca,ta,default)
- local cv = colors.value(ca) -- faster when direct colors.values[ca]
+function colors.mp(model,ca,ta,default) -- will move to mlib-col
+ local cv = colors.supported and colors.value(ca) -- faster when direct colors.values[ca]
if cv then
- local tv = transparencies.value(ta)
+ local tv = transparencies.supported and transparencies.value(ta)
if model == 1 then
model = cv[1]
end
+ model = forcedmodel(model)
if tv then
if model == 2 then
return format("transparent(%s,%s,(%s,%s,%s))",tv[1],tv[2],cv[3],cv[4],cv[5])
diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv
index 1bceb5aa7..0d1dd50e5 100644
--- a/tex/context/base/colo-ini.mkiv
+++ b/tex/context/base/colo-ini.mkiv
@@ -20,6 +20,7 @@
%D different approach, this module only implements a few generic mechanisms.
\registerctxluafile{colo-ini}{1.000}
+\registerctxluafile{colo-icc}{1.000}
\registerctxluafile{lpdf-col}{1.000}
\unprotect
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex
index cae797270..b59c65679 100644
--- a/tex/context/base/cont-new.tex
+++ b/tex/context/base/cont-new.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2010.07.30 11:35}
+\newcontextversion{2010.08.10 17:14}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 13e091ea8..9590eb652 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -70,6 +70,7 @@
\loadcorefile{mult-def}
\loadmarkfile{mult-chk}
\loadmarkfile{mult-cld}
+\loadmarkfile{mult-aux}
\loadmarkfile{luat-ini}
diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex
index 4abee1332..5e3324eb7 100644
--- a/tex/context/base/context.tex
+++ b/tex/context/base/context.tex
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2010.07.30 11:35}
+\edef\contextversion{2010.08.10 17:14}
%D For those who want to use this:
diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua
index f8f54e9e7..257de625b 100644
--- a/tex/context/base/core-con.lua
+++ b/tex/context/base/core-con.lua
@@ -23,6 +23,23 @@ local tonumber, tostring = tonumber, tostring
local ctxcatcodes = tex.ctxcatcodes
+local function flush(...)
+ texsprint(ctxcatcodes,...)
+end
+
+function converters.convert(method,n,direct)
+ local method = converters[method]
+ if method then
+ return method(n,direct)
+ else
+ return direct and n or flush(n)
+ end
+end
+
+function converters.numberst(n,direct)
+ return direct and n or flush(n)
+end
+
converters = converters or { }
languages = languages or { }
@@ -123,24 +140,61 @@ counters['kr-c'] = counters['korean-circle']
local fallback = utf.byte('0')
-local function chr(n,m)
- if n > 0 and n < 27 then
- texsprint(utfchar(n+m))
- end
+local function chr(n,m,direct)
+ local s = (n > 0 and n < 27 and utfchar(n+m)) or ""
+ if direct then return s else flush(s) end
end
-local function chrs(n,m)
+
+--~ local function chrs(n,m,direct)
+--~ if n > 26 then
+--~ chrs(floor((n-1)/26),m)
+--~ n = (n-1)%26 + 1
+--~ end
+--~ flush(utfchar(n+m))
+--~ end
+
+local function chrs(n,m,direct,t)
+ if not t then
+ t = { }
+ end
if n > 26 then
- chrs(floor((n-1)/26),m)
+ chrs(floor((n-1)/26),m,direct,t)
n = (n-1)%26 + 1
end
- texsprint(utfchar(n+m))
+ t[#t+1] = utfchar(n+m)
+ if n <= 26 then
+ if direct then
+ return concat(t)
+ else
+ flush(concat(t))
+ end
+ end
end
-local function maxchrs(n,m,cmd)
+
+--~ local function maxchrs(n,m,cmd,direct)
+--~ if n > m then
+--~ maxchrs(floor((n-1)/m),m,cmd)
+--~ n = (n-1)%m + 1
+--~ end
+--~ flush(format("%s{%s}",cmd,n))
+--~ end
+
+local function maxchrs(n,m,cmd,direct,t) -- direct is not ok
+ if not t then
+ t = { }
+ end
if n > m then
maxchrs(floor((n-1)/m),m,cmd)
n = (n-1)%m + 1
end
- texsprint(ctxcatcodes, format("%s{%s}",cmd,n))
+ t[#t+1] = format("%s{%s}",cmd,n)
+ if n <= m then
+ if direct then
+ return concat(t)
+ else
+ flush(concat(t))
+ end
+ end
end
converters.chr = chr
@@ -158,7 +212,7 @@ converters.maxchrs = maxchrs
--~ n = (n-1)%max+1
--~ end
--~ n = chr(n,mapping)
---~ texsprint(ctxcatcodes,escapes[n] or utfchar(n))
+--~ flush(escapes[n] or utfchar(n))
--~ end
--~ local lccodes, uccodes = characters.lccode, characters.uccode
@@ -183,35 +237,52 @@ converters.maxchrs = maxchrs
--~ do_alphabetic(n,counters[code] or counters['**'],uppercased)
--~ end
---
+local flushcharacter = characters and characters.flush or function(s) return utfchar(s) end
+local lowercharacter = characters and characters.lccode or function(s) return s end
+local uppercharacter = characters and characters.uccode or function(s) return s end
-local function do_alphabetic(n,mapping,mapper)
- local chr = mapper(mapping[n] or fallback)
+local function do_alphabetic(n,mapping,mapper,direct,verbose,t)
+ if not t then
+ t = { }
+ end
+ local chr = mapping[n] or fallback
+ if mapper then
+ chr = mapper(chr)
+ end
local max = #mapping
if n > max then
- do_alphabetic(floor((n-1)/max),mapping,mapper)
+ do_alphabetic(floor((n-1)/max),mapping,mapper,direct,verbose,t)
n = (n-1)%max+1
end
- characters.flush(chr)
+ if verbose or type(chr) ~= "number" then
+ t[#t+1] = chr
+ else
+ t[#t+1] = utfchar(chr) -- flushcharacter(chr,true) -- force direct here; can't we just use utfchar(chr) nowadays?
+ end
+ if n <= max then
+ if direct then
+ return concat(t)
+ else
+ flush(concat(t))
+ end
+ end
end
-function converters.alphabetic(n,code)
- do_alphabetic(n,counters[code] or counters['**'],characters.lccode)
+function converters.alphabetic(n,code,direct)
+ return do_alphabetic(n,counters[code] or counters['**'],lowercharacter,direct)
end
-
-function converters.Alphabetic(n,code)
- do_alphabetic(n,counters[code] or counters['**'],characters.uccode)
+function converters.Alphabetic(n,code,direct)
+ return do_alphabetic(n,counters[code] or counters['**'],uppercharacter,direct)
end
---
-
-function converters.character (n) chr (n,96) end
-function converters.Character (n) chr (n,64) end
-function converters.characters(n) chrs(n,96) end
-function converters.Characters(n) chrs(n,64) end
+function converters.character (n,direct) return chr (n,96,direct) end
+function converters.Character (n,direct) return chr (n,64,direct) end
+function converters.characters(n,direct) return chrs(n,96,direct) end
+function converters.Characters(n,direct) return chrs(n,64,direct) end
-function converters.weekday(day,month,year)
- texsprint(date("%w",time{year=year,month=month,day=day})+1)
+function converters.weekday(day,month,year,direct)
+ local s = date("%w",time{year=year,month=month,day=day}) + 1
+ if direct then return s else flush(s) end
end
function converters.isleapyear(year)
@@ -219,7 +290,8 @@ function converters.isleapyear(year)
end
function converters.leapyear(year)
- if converters.isleapyear(year) then texsprint(1) else texsprint(0) end
+ local s = converters.isleapyear(year) and 1 or 0
+ if direct then return s else flush(s) end
end
local days = {
@@ -227,16 +299,19 @@ local days = {
[true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
}
-function converters.nofdays(year,month)
- texsprint(days[converters.isleapyear(year)][month])
+function converters.nofdays(year,month,direct)
+ local s = days[converters.isleapyear(year)][month]
+ if direct then return s else flush(s) end
end
-function converters.year () texsprint(date("%Y")) end
-function converters.month () texsprint(date("%m")) end
-function converters.hour () texsprint(date("%H")) end
-function converters.minute () texsprint(date("%M")) end
-function converters.second () texsprint(date("%S")) end
-function converters.textime() texsprint(tonumber(date("%H"))*60+tonumber(date("%M"))) end
+function converters.year (direct) local s = date("%Y") if direct then return s else flush(s) end end
+function converters.year (direct) local s = date("%Y") if direct then return s else flush(s) end end
+function converters.month (direct) local s = date("%m") if direct then return s else flush(s) end end
+function converters.hour (direct) local s = date("%H") if direct then return s else flush(s) end end
+function converters.minute (direct) local s = date("%M") if direct then return s else flush(s) end end
+function converters.second (direct) local s = date("%S") if direct then return s else flush(s) end end
+function converters.textime(direct) local s = tonumber(date("%H")) * 60 + tonumber(date("%M"))
+ if direct then return s else flush(s) end end
local roman = {
{ [0] = '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' },
@@ -248,13 +323,12 @@ local function toroman(n)
if n >= 4000 then
return toroman(floor(n/1000)) .. " " .. toroman(n%1000)
else
- return rep("M",floor(n/1000)) .. roman[3][floor((n%1000)/100)] ..
- roman[2][floor((n%100)/10)] .. roman[1][floor((n% 10)/1)]
+ return rep("M",floor(n/1000)) .. roman[3][floor((n%1000)/100)] .. roman[2][floor((n%100)/10)] .. roman[1][floor((n% 10)/1)]
end
end
-function converters.romannumerals(n) return texsprint(lower(toroman(n))) end
-function converters.Romannumerals(n) return texsprint( toroman(n) ) end
+function converters.romannumerals(n,direct) local s = lower(toroman(n)) if direct then return s else flush(s) end end
+function converters.Romannumerals(n,direct) local s = toroman(n) if direct then return s else flush(s) end end
converters.toroman = toroman
@@ -304,8 +378,8 @@ function converters.toabjad(n,what)
end
end
-function converters.abjadnumerals (n) return texsprint(converters.toabjad(n,false)) end
-function converters.abjadnodotnumerals(n) return texsprint(converters.toabjad(n,true)) end
+function converters.abjadnumerals (n,direct) local s = converters.toabjad(n,false) if direct then return s else flush(s) end end
+function converters.abjadnodotnumerals(n,direct) local s = converters.toabjad(n,true ) if direct then return s else flush(s) end end
local vector = {
normal = {
@@ -363,61 +437,6 @@ local vector = {
}
}
---~ function tochinese(n,name) -- normal, caps, all
---~ local result = { }
---~ local vector = vector[name] or vector.normal
---~ while true do
---~ if n == 0 then
---~ break
---~ elseif n >= 100000000 then
---~ local m = floor(n/100000000)
---~ if m > 1 then result[#result+1] = tochinese(m) end
---~ result[#result+1] = vector[100000000]
---~ n = n % 100000000
---~ elseif n >= 10000000 then
---~ result[#result+1] = tochinese(floor(n/10000))
---~ result[#result+1] = vector[10000]
---~ n = n % 10000
---~ elseif n >= 1000000 then
---~ result[#result+1] = tochinese(floor(n/10000))
---~ result[#result+1] = vector[10000]
---~ n = n % 10000
---~ elseif n >= 100000 then
---~ result[#result+1] = tochinese(floor(n/10000))
---~ result[#result+1] = vector[10000]
---~ n = n % 10000
---~ elseif n >= 10000 then
---~ local m = floor(n/10000)
---~ if m > 1 then result[#result+1] = vector[m] end
---~ result[#result+1] = vector[10000]
---~ n = n % 10000
---~ elseif n >= 1000 then
---~ local m = floor(n/1000)
---~ if m > 1 then result[#result+1] = vector[m] end
---~ result[#result+1] = vector[1000]
---~ n = n % 1000
---~ elseif n >= 100 then
---~ local m = floor(n/100)
---~ if m > 1 then result[#result+1] = vector[m] end
---~ result[#result+1] = vector[100]
---~ n = n % 100
---~ elseif n >= 10 then
---~ local m = floor(n/10)
---~ if vector[m*10] then
---~ result[#result+1] = vector[m*10]
---~ else
---~ result[#result+1] = vector[m]
---~ result[#result+1] = vector[10]
---~ end
---~ n = n % 10
---~ else
---~ result[#result+1] = vector[n]
---~ break
---~ end
---~ end
---~ return concat(result)
---~ end
-
local function tochinese(n,name) -- normal, caps, all
-- improved version by Li Yanrui
local result = { }
@@ -500,9 +519,9 @@ end
--~ print(v,tochinese(v),tochinese(v,"all"),tochinese(v,"cap"))
--~ end
-function converters.chinesenumerals (n) return texsprint(tochinese(n,"normal")) end
-function converters.chinesecapnumerals(n) return texsprint(tochinese(n,"cap" )) end
-function converters.chineseallnumerals(n) return texsprint(tochinese(n,"all" )) end
+function converters.chinesenumerals (n) local s = tochinese(n,"normal") if direct then return s else flush(s) end end
+function converters.chinesecapnumerals(n) local s = tochinese(n,"cap" ) if direct then return s else flush(s) end end
+function converters.chineseallnumerals(n) local s = tochinese(n,"all" ) if direct then return s else flush(s) end end
--~ Well, since the one asking for this didn't test it the following code is not
--~ enabled.
@@ -603,3 +622,31 @@ function converters.chineseallnumerals(n) return texsprint(tochinese(n,"all" )
--~
--~ print(gregorian_to_jalali(2009,02,24))
--~ print(jalali_to_gregorian(1387,12,06))
+
+converters.sequences = converters.sequences or { }
+
+storage.register("converters/sequences", converters.sequences, "converters.sequences")
+
+local sequences = converters.sequences
+
+function converters.define(name,set)
+ sequences[name] = aux.settings_to_array(set)
+end
+
+function converters.convert(method,n,direct) -- todo: language
+ local converter = converters[method]
+ if converter then
+ return converter(n,direct)
+ else
+ local lowermethod = lower(method)
+ local linguistic = counters[lowermethod]
+ local sequence = sequences[method]
+ if linguistic then
+ return do_alphabetic(n,linguistic,lowermethod == method and lowercharacter or uppercharacter,direct,false)
+ elseif sequence then
+ return do_alphabetic(n,sequence,false,direct,true)
+ else
+ return direct and n or flush(n)
+ end
+ end
+end
diff --git a/tex/context/base/core-con.mkiv b/tex/context/base/core-con.mkiv
index 2d2e5d5d7..364372a46 100644
--- a/tex/context/base/core-con.mkiv
+++ b/tex/context/base/core-con.mkiv
@@ -149,8 +149,8 @@
%D
%D Why should we only honour the romans, and not the greek?
-\let\greeknumerals\gobbleoneargument
-\let\Greeknumerals\gobbleoneargument
+% \let\greeknumerals\gobbleoneargument
+% \let\Greeknumerals\gobbleoneargument
%D \macros
%D {oldstylenumerals,oldstyleromannumerals}
@@ -586,83 +586,91 @@
%D \defineconversion [en] [whatever] [\something]
%D \stoptyping
-% \def\dodefineconversion[#1][#2]%
-% {\ConvertConstantAfter\doifinstringelse{,}{#2}
-% {\scratchcounter=0
+% we can consider conversions to be global in which case we can
+% delegate to lua
+
+% \unexpanded\def\defineconversion
+% {\dotripleempty\dodefineconversion}
+%
+% \def\dodefineconversion[#1][#2][#3]%
+% {\ifthirdargument
+% \dododefineconversion[#1][#2][#3]%
+% \else
+% \dododefineconversion[][#1][#2]%
+% \fi}
+%
+% \def\dododefineconversion[#1][#2][#3]%
+% {\ConvertConstantAfter\doifinstringelse{,}{#3}
+% {\scratchcounter\zerocount
% \def\docommand##1%
-% {\advance\scratchcounter 1
-% \setvalue{\??cv#1\the\scratchcounter}{##1}}%
-% \processcommalist[#2]\docommand
-% \setvalue{\??cv#1}##1{\csname\??cv#1##1\endcsname}}
-% {\setvalue{\??cv#1}{#2}}}
+% {\advance\scratchcounter \plusone
+% \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
+% \processcommalist[#3]\docommand
+% \setevalue{\??cv#1#2}##1%
+% {\noexpand\docheckedconversion{#1#2}{\the\scratchcounter}{##1}}}
+% {\setvalue{\??cv#1#2}{#3}}}
+%
+% \def\docheckedconversion#1#2#3% class maxnumber number
+% {\executeifdefined{\??cv#1#3}\unknown}
+%
+% %D When Gerben reported problems with footnote numbering per page,
+% %D Taco came with the following wrap around solution. So, let's
+% %D overload the checked conversion macro
%
-% \unexpanded\def\defineconversion%
-% {\dodoubleargument\dodefineconversion}
+% %D Taco's modulo code is implemented in the system module
+% %D \type {syst-con}.
+%
+% \def\docheckedconversion#1#2#3% class maxnumber number
+% {\executeifdefined{\??cv#1\modulatednumber{#2}{#3}}\unknown}
\unexpanded\def\defineconversion
{\dotripleempty\dodefineconversion}
-\def\dodefineconversion[#1][#2][#3]%
+\def\dodefineconversion[#1][#2][#3]% from now on global (maybe local again some day)
{\ifthirdargument
- \dododefineconversion[#1][#2][#3]%
+ \dododefineconversion{#1#2}{#1:#2}{#3}%
\else
- \dododefineconversion[][#1][#2]%
+ \dododefineconversion{#1}{#1}{#2}%
\fi}
-%D \starttyping
-%D \def\dododefineconversion[#1][#2][#3]%
-%D {\ConvertConstantAfter\doifinstringelse{,}{#3}
-%D {\scratchcounter\zerocount
-%D \def\docommand##1%
-%D {\advance\scratchcounter \plusone
-%D \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
-%D \processcommalist[#3]\docommand
-%D \setvalue{\??cv#1#2}##1{\executeifdefined{\??cv#1#2##1}\unknown}} % catch out-of-range numbers
-%D {\setvalue{\??cv#1#2}{#3}}}
-%D \stoptyping
-
-%D This approach has the disadvantage that when you run out of
-%D symbols you get unknown results. The following implementation
-%D permits overloading of the converter:
-
-\def\dododefineconversion[#1][#2][#3]%
+\def\dododefineconversion#1#2#3%
{\ConvertConstantAfter\doifinstringelse{,}{#3}
- {\scratchcounter\zerocount
- \def\docommand##1%
- {\advance\scratchcounter \plusone
- \setvalue{\??cv#1#2\the\scratchcounter}{##1}}%
- \processcommalist[#3]\docommand
- \setevalue{\??cv#1#2}##1%
- {\noexpand\docheckedconversion{#1#2}{\the\scratchcounter}{##1}}}
- {\setvalue{\??cv#1#2}{#3}}}
-
-\def\docheckedconversion#1#2#3% class maxnumber number
- {\executeifdefined{\??cv#1#3}\unknown}
-
-%D When Gerben reported problems with footnote numbering per page,
-%D Taco came with the following wrap around solution. So, let's
-%D overload the checked conversion macro:
+ {\ctxlua{converters.define("#2",\!!bs\detokenize{#3}\!!es)}%
+ \setgvalue{\??cv#1}{\docheckedconversion{#2}}}
+ {\setgvalue{\??cv#1}{#3}}}
-\def\docheckedconversion#1#2#3% class maxnumber number
- {\executeifdefined{\??cv#1\modulatednumber{#2}{#3}}\unknown}
-
-%D Taco's modulo code is implemented in the system module
-%D \type {syst-con}.
+\def\docheckedconversion#1#2%
+ {\ctxlua{converters.convert("#1",#2)}}
%D If a conversion is just a font switch then we need to make sure
%D that the number is indeed end up as number in the input, so we
%D need to handle the second argument.
+% \def\convertnumber#1#2%
+% {\csname\??cv
+% \ifcsname\??cv\currentlanguage#1\endcsname
+% \currentlanguage#1%
+% \else\ifcsname\??cv#1\endcsname
+% #1%
+% \else
+% \s!default
+% \fi\fi
+% \endcsname{\number#2}}
+
\def\convertnumber#1#2%
- {\csname\??cv
+ {\csname\??cv % we want a fully expandable (no if interference)
\ifcsname\??cv\currentlanguage#1\endcsname
\currentlanguage#1%
+ \@EA\firstoftwoarguments % dirty, gobble {#1}
\else\ifcsname\??cv#1\endcsname
#1%
+ \@EAEAEA\firstoftwoarguments % dirty, gobble {#1}
\else
- \s!default
+ ->\s!default
\fi\fi
- \endcsname{\number#2}}
+ \endcsname{#1}{\number#2}}
+
+\letvalue{\??cv->\s!default}\docheckedconversion
\def\doifconversiondefinedelse#1%
{\ifcsname\??cv\currentlanguage#1\endcsname
@@ -762,9 +770,6 @@
\defineconversion [g] [\greeknumerals]
\defineconversion [G] [\Greeknumerals]
-\defineconversion [arabicnumerals] [\arabicnumerals]
-\defineconversion [persiannumerals] [\persiannumerals]
-
\defineconversion [abjadnumerals] [\abjadnumerals]
\defineconversion [abjadnodotnumerals] [\adjadnodotnumerals]
\defineconversion [abjadnaivenumerals] [\adjadnaivenumerals]
diff --git a/tex/context/base/core-ctx.mkiv b/tex/context/base/core-ctx.mkiv
index 9bf456952..56d17ec88 100644
--- a/tex/context/base/core-ctx.mkiv
+++ b/tex/context/base/core-ctx.mkiv
@@ -23,6 +23,6 @@
% \prependtoks\loadctxpreplist\to\everyjob
-\appendtoks\loadctxpreplist\to\everystarttext
+\appendtoks\loadctxpreplist\to\everystarttext % maybe too late but don't change it now
\protect \endinput
diff --git a/tex/context/base/data-env.lua b/tex/context/base/data-env.lua
index f99cb47f5..f3997b989 100644
--- a/tex/context/base/data-env.lua
+++ b/tex/context/base/data-env.lua
@@ -31,6 +31,7 @@ formats['pfb'] = 'T1FONTS' suffixes['pfb'] = { 'pfb', '
formats['vf'] = 'VFFONTS' suffixes['vf'] = { 'vf' }
formats['fea'] = 'FONTFEATURES' suffixes['fea'] = { 'fea' }
formats['cid'] = 'FONTCIDMAPS' suffixes['cid'] = { 'cid', 'cidmap' }
+formats['icc'] = 'ICCPROFILES' suffixes['icc'] = { 'icc' }
formats['texmfscripts'] = 'TEXMFSCRIPTS' suffixes['texmfscripts'] = { 'rb', 'pl', 'py' }
formats['lua'] = 'LUAINPUTS' suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
formats['lib'] = 'CLUAINPUTS' suffixes['lib'] = (os.libsuffix and { os.libsuffix }) or { 'dll', 'so' }
@@ -46,6 +47,7 @@ alternatives['truetype fonts'] = 'ttf'
alternatives['truetype collections'] = 'ttc'
alternatives['truetype dictionary'] = 'dfont'
alternatives['type1 fonts'] = 'pfb'
+alternatives['icc profiles'] = 'icc'
--[[ldx--
<p>If you wondered about some of the previous mappings, how about
diff --git a/tex/context/base/enco-agr.mkii b/tex/context/base/enco-agr.mkii
index cfd86dfd3..1dbb9b577 100644
--- a/tex/context/base/enco-agr.mkii
+++ b/tex/context/base/enco-agr.mkii
@@ -16,6 +16,8 @@
\definecasemaps 87 to 90 lc +32 uc 0
\definecasemaps 91 to 255 lc 0 uc 0
+ \definecaseself 4 % apostrofe
+
\stopmapping
\startencoding[agr]
diff --git a/tex/context/base/enco-ans.mkii b/tex/context/base/enco-ans.mkii
index 7a48b5b55..88baf0ad0 100644
--- a/tex/context/base/enco-ans.mkii
+++ b/tex/context/base/enco-ans.mkii
@@ -40,7 +40,7 @@
% \definecaseself 129 % quotesingle
% \definecaseself 130 % quotesinglebase
% \definecaseself 145 % quoteleft
-% \definecaseself 146 % quoteright
+\definecaseself 146 % quoteright
\stopmapping
diff --git a/tex/context/base/enco-ec.mkii b/tex/context/base/enco-ec.mkii
index 1ac41cadf..f0964897f 100644
--- a/tex/context/base/enco-ec.mkii
+++ b/tex/context/base/enco-ec.mkii
@@ -56,7 +56,7 @@
% \definecaseself 39 % quotesingle
% \definecaseself 13 % quotesinglebase
% \definecaseself 96 % quoteleft
-% \definecaseself 39 % quoteright
+\definecaseself 39 % quoteright
%D So far for the mapping.
diff --git a/tex/context/base/enco-qx.mkii b/tex/context/base/enco-qx.mkii
index 407d60bd7..798a18249 100644
--- a/tex/context/base/enco-qx.mkii
+++ b/tex/context/base/enco-qx.mkii
@@ -75,6 +75,8 @@
\definecasemaps 217 to 222 lc +32 uc 0
\definecasemaps 249 to 254 lc 0 uc -32
+\definecaseself 39 % quoteright
+
\stopmapping
\startencoding[qx]
diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua
index 072b3e59f..75b3cddef 100644
--- a/tex/context/base/font-afm.lua
+++ b/tex/context/base/font-afm.lua
@@ -480,7 +480,8 @@ function afm.copy_to_tfm(data)
local metadata, luatex = data.metadata, data.luatex
local unicodes, indices = luatex.unicodes, luatex.indices
local characters, parameters, descriptions = { }, { }, { }
- -- todo : merge into tfm
+ local mode = data.mode or "base"
+ -- todo : merge into tfm
for u, i in next, indices do
local d = glyphs[i]
characters[u] = { }
@@ -561,6 +562,7 @@ function afm.copy_to_tfm(data)
unicodes = unicodes,
luatex = luatex,
encodingbytes = 2,
+ mode = mode,
filename = filename,
fontname = fontname,
fullname = fullname,
@@ -602,7 +604,7 @@ function afm.set_features(tfmdata)
local afmdata = shared.afmdata
local features = shared.features
if features and next(features) then
- local mode = tfmdata.mode or fonts.mode
+ local mode = tfmdata.mode or features.mode or "base"
local initializers = fonts.initializers
local fi = initializers[mode]
local fiafm = fi and fi.afm
@@ -623,7 +625,7 @@ function afm.set_features(tfmdata)
report_afm("initializing feature %s to %s for mode %s for font %s",f,tostring(value),mode or 'unknown',tfmdata.name or 'unknown')
end
fiafm[f](tfmdata,value)
- mode = tfmdata.mode or fonts.mode
+ mode = tfmdata.mode or features.mode or "base"
fiafm = initializers[mode].afm
end
end
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
index 5e4d598f1..a6945e39d 100644
--- a/tex/context/base/font-ctx.lua
+++ b/tex/context/base/font-ctx.lua
@@ -18,8 +18,12 @@ local round = math.round
local ctxcatcodes = tex.ctxcatcodes
local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end)
+local trace_usage = false trackers.register("fonts.usage", function(v) trace_usage = v end)
+local trace_mapfiles = false trackers.register("fonts.mapfiles", function(v) trace_mapfiles = v end)
-local report_define = logs.new("define fonts")
+local report_define = logs.new("define fonts")
+local report_usage = logs.new("fonts usage")
+local report_mapfiles = logs.new("mapfiles")
local tfm = fonts.tfm
local define = fonts.define
@@ -37,6 +41,9 @@ local merged = specify.context_merged
local synonyms = specify.synonyms
local triggers = fonts.triggers
+-- Beware, number can be shared between redefind features but as it is
+-- applied only for special cases it probably doesn't matter.
+
--[[ldx--
<p>So far we haven't really dealt with features (or whatever we want
to pass along with the font definition. We distinguish the following
@@ -113,7 +120,8 @@ local function preset_context(name,parent,features) -- currently otf only
if v then t[k] = v end
end
-- needed for dynamic features
- local number = (setups[name] and setups[name].number) or 0
+ -- maybe number should always be renewed as we can redefine features
+ local number = (setups[name] and setups[name].number) or 0 -- hm, numbers[name]
if number == 0 then
number = #numbers + 1
numbers[number] = name
@@ -233,6 +241,7 @@ function fonts.withset(name,what)
end
tex_attribute[0] = done
end
+
function fonts.withfnt(name,what)
local font = current_font()
local hash = font .. "*" .. name .. "*" .. what
@@ -248,18 +257,59 @@ function specify.show_context(name)
return setups[name] or setups[numbers[name]] or setups[numbers[tonumber(name)]] or { }
end
-local function split_context(features)
+-- todo: support a,b,c
+
+local function split_context(features) -- preset_context creates dummy here
return setups[features] or (preset_context(features,"","") and setups[features])
end
+--~ local splitter = lpeg.splitat("=")
+
+--~ local function split_context(features)
+--~ local setup = setups[features]
+--~ if setup then
+--~ return setup
+--~ elseif find(features,",") 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
+--~ local k, v = lpegmatch(splitter,feature)
+--~ if k and v then
+--~ if not merge then
+--~ merge = { k = v }
+--~ else
+--~ merge[k] = v
+--~ end
+--~ end
+--~ else
+--~ local s = setups[feature]
+--~ if not s then
+--~ -- skip
+--~ elseif not merge then
+--~ merge = s
+--~ else
+--~ for k, v in next, s do
+--~ merge[k] = v
+--~ end
+--~ end
+--~ end
+--~ end
+--~ setup = merge and preset_context(features,"",merge) and setups[features]
+--~ -- actually we have to nil setups[features] in order to permit redefinitions
+--~ setups[features] = nil
+--~ end
+--~ return setup or (preset_context(features,"","") and setups[features]) -- creates dummy
+--~ end
+
specify.split_context = split_context
function specify.context_tostring(name,kind,separator,yes,no,strict,omit) -- not used
return aux.hash_to_string(table.merged(fonts[kind].features.default or {},setups[name] or {}),separator,yes,no,strict,omit)
end
-local splitter = lpeg.splitat(",")
-
function specify.starred(features) -- no longer fallbacks here
local detail = features.detail
if detail and detail ~= "" then
@@ -396,7 +446,7 @@ function define.command_2(global,cs,str,size,classfeatures,fontfeatures,classfal
report_define("defining %s with id %s as \\%s (features: %s/%s, fallbacks: %s/%s)",name,id,cs,classfeatures,fontfeatures,classfallbacks,fontfallbacks)
end
-- resolved (when designsize is used):
- texsprint(ctxcatcodes,format("\\def\\somefontsize{%isp}",tfmdata.size))
+ texsprint(ctxcatcodes,format("\\def\\somefontsize{%isp}",tfmdata.size or 655360))
--~ if specification.fallbacks then
--~ fonts.collections.prepare(specification.fallbacks)
--~ end
@@ -511,6 +561,9 @@ local loaded = { -- prevent loading (happens in cont-sys files)
function fonts.map.loadfile(name)
name = file.addsuffix(name,"map")
if not loaded[name] then
+ if trace_mapfiles then
+ report_mapfiles("loading map file '%s'",name)
+ end
pdf.mapfile(name)
loaded[name] = true
end
@@ -526,6 +579,9 @@ function fonts.map.loadline(how,line)
how = "= " .. line
end
if not loaded[how] then
+ if trace_mapfiles then
+ report_mapfiles("processing map line '%s'",line)
+ end
pdf.mapline(how)
loaded[how] = true
end
@@ -611,3 +667,57 @@ function fonts.show_font_parameters()
end
end
+function fonts.report_defined_fonts()
+ if trace_usage then
+ local t = { }
+ for id, data in table.sortedhash(fonts.ids) do
+ t[#t+1] = {
+ format("%03i",id),
+ format("%09i",data.size or 0),
+ data.type or "real",
+ (data.mode or "base") .. "mode",
+ data.auto_expand and "expanded" or "",
+ data.auto_protrude and "protruded" or "",
+ data.has_math and "math" or "",
+ data.extend_factor and "extended" or "",
+ data.slant_factor and "slanted" or "",
+ data.name or "",
+ data.psname or "",
+ data.fullname or "",
+ data.hash or "",
+ }
+ end
+ aux.formatcolumns(t," ")
+ report_usage()
+ report_usage("defined fonts:")
+ report_usage()
+ for k=1,#t do
+ report_usage(t[k])
+ end
+ end
+end
+
+luatex.register_stop_actions(fonts.report_defined_fonts)
+
+function fonts.report_used_features()
+ -- numbers, setups, merged
+ if trace_usage then
+ local t = { }
+ for i=1,#numbers do
+ local name = numbers[i]
+ local setup = setups[name]
+ local n = setup.number
+ setup.number = nil -- we have no reason to show this
+ t[#t+1] = { i, name, table.sequenced(setup,false,true) } -- simple mode
+ setup.number = n -- restore it (normally not needed as we're done anyway)
+ end
+ aux.formatcolumns(t," ")
+ report_usage()
+ report_usage("defined featuresets:")
+ report_usage()
+ for k=1,#t do
+ report_usage(t[k])
+ end
+ end
+end
+luatex.register_stop_actions(fonts.report_used_features)
diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua
index ea5b69a6b..e3c7d934a 100644
--- a/tex/context/base/font-def.lua
+++ b/tex/context/base/font-def.lua
@@ -559,7 +559,7 @@ function define.register(fontdata,id)
end
fonts.identifiers[id] = fontdata
fonts.characters [id] = fontdata.characters
- fonts.quads [id] = fontdata.parameters.quad
+ fonts.quads [id] = fontdata.parameters and fontdata.parameters.quad
-- todo: extra functions, e.g. setdigitwidth etc in list
tfm.internalized[hash] = id
end
@@ -637,7 +637,6 @@ function define.read(specification,size,id) -- id can be optional, name can alre
fontdata.encodingname or "unicode",
fontdata.fullname or "?",
file.basename(fontdata.filename or "?"))
-
end
statistics.stoptiming(fonts)
return fontdata
diff --git a/tex/context/base/font-enh.lua b/tex/context/base/font-enh.lua
index 137044f5b..31f2b2387 100644
--- a/tex/context/base/font-enh.lua
+++ b/tex/context/base/font-enh.lua
@@ -68,7 +68,7 @@ function tfm.set_features(tfmdata)
-- local tfmdata = shared.tfmdata
local features = shared.features
if features and next(features) then
- local mode = tfmdata.mode or fonts.mode
+ local mode = tfmdata.mode or features.mode or "base"
local fi = fonts.initializers[mode]
if fi and fi.tfm then
local function initialize(list) -- using tex lig and kerning
@@ -81,7 +81,7 @@ function tfm.set_features(tfmdata)
report_define("initializing feature %s to %s for mode %s for font %s",f,tostring(value),mode or 'unknown',tfmdata.name or 'unknown')
end
fi.tfm[f](tfmdata,value)
- mode = tfmdata.mode or fonts.mode
+ mode = tfmdata.mode or features.mode or "base"
fi = fonts.initializers[mode]
end
end
diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua
index f0d52974a..79a1417d3 100644
--- a/tex/context/base/font-gds.lua
+++ b/tex/context/base/font-gds.lua
@@ -90,21 +90,21 @@ end
-- featuresets
-local function flattened(t,tt)
+local function flattened_features(t,tt)
-- first set value dominates
local tt = tt or { }
for i=1,#t do
local ti = t[i]
if type(ti) == "table" then
- flattened(ti,tt)
+ flattened_features(ti,tt)
elseif tt[ti] == nil then
tt[ti] = true
end
end
for k, v in next, t do
- if type(k) ~= "number" then
+ if type(k) ~= "number" then -- not tonumber(k)
if type(v) == "table" then
- flattened(v,tt)
+ flattened_features(v,tt)
elseif tt[k] == nil then
tt[k] = v
end
@@ -113,11 +113,11 @@ local function flattened(t,tt)
return tt
end
-fonts.flattened_features = flattened
+fonts.flattened_features = flattened_features
function fonts.goodies.prepare_features(goodies,name,set)
if set then
- local ff = fonts.flattened_features(set)
+ local ff = flattened_features(set)
local fullname = goodies.name .. "::" .. name
local n, s = preset_context(fullname,"",ff)
goodies.featuresets[name] = s -- set
diff --git a/tex/context/base/font-ini.lua b/tex/context/base/font-ini.lua
index 94522130c..290d031f9 100644
--- a/tex/context/base/font-ini.lua
+++ b/tex/context/base/font-ini.lua
@@ -34,7 +34,6 @@ fonts.qua = fonts.qua or { } fonts.quads = fonts.qua -- aka quaddata
fonts.tfm = fonts.tfm or { }
-fonts.mode = 'base'
fonts.private = 0xF0000 -- 0x10FFFF
fonts.verbose = false -- more verbose cache tables
diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv
index e08f5bdd9..abcfba8d8 100644
--- a/tex/context/base/font-ini.mkiv
+++ b/tex/context/base/font-ini.mkiv
@@ -2748,9 +2748,9 @@
% for the moment here, this will change but we need it for mk.tex
-\definefontfeature[math-text] [virtualmath][ssty=no]
-\definefontfeature[math-script] [virtualmath][ssty=1,mathsize=yes]
-\definefontfeature[math-scriptscript][virtualmath][ssty=2,mathsize=yes]
+\definefontfeature[math-text] [virtualmath][mathalternates=yes,ssty=no]
+\definefontfeature[math-script] [virtualmath][mathalternates=yes,ssty=1,mathsize=yes]
+\definefontfeature[math-scriptscript][virtualmath][mathalternates=yes,ssty=2,mathsize=yes]
\definefontfeature [math-nostack-text] [math-text] [nostackmath=yes]
\definefontfeature [math-nostack-script] [math-script] [nostackmath=yes]
diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua
index 1eee45aaa..62522f916 100644
--- a/tex/context/base/font-otd.lua
+++ b/tex/context/base/font-otd.lua
@@ -58,6 +58,7 @@ function otf.set_dynamics(font,dynamics,attribute)
features = tfmdata.shared.features
}
tfmdata.mode = "node"
+ tfmdata.dynamics = true -- handy for tracing
tfmdata.language = language
tfmdata.script = script
tfmdata.shared.features = { }
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index 5749d8fd7..5e1117acb 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -1388,22 +1388,23 @@ end
-- for context this will become a task handler
+local lists = { -- why local
+ fonts.triggers,
+ fonts.processors,
+ fonts.manipulators,
+}
+
function otf.set_features(tfmdata,features)
local processes = { }
if features and next(features) then
- local lists = { -- why local
- fonts.triggers,
- fonts.processors,
- fonts.manipulators,
- }
- local mode = tfmdata.mode or fonts.mode -- or features.mode
+ local mode = tfmdata.mode or features.mode or "base"
local initializers = fonts.initializers
local fi = initializers[mode]
if fi then
local fiotf = fi.otf
if fiotf then
local done = { }
- for l=1,4 do
+ for l=1,#lists do
local list = lists[l]
if list then
for i=1,#list do
@@ -1415,7 +1416,7 @@ function otf.set_features(tfmdata,features)
report_otf("initializing feature %s to %s for mode %s for font %s",f,tostring(value),mode or 'unknown', tfmdata.fullname or 'unknown')
end
fiotf[f](tfmdata,value) -- can set mode (no need to pass otf)
- mode = tfmdata.mode or fonts.mode -- keep this, mode can be set local !
+ mode = tfmdata.mode or features.mode or "base"
local im = initializers[mode]
if im then
fiotf = initializers[mode].otf
@@ -1428,11 +1429,12 @@ function otf.set_features(tfmdata,features)
end
end
end
+tfmdata.mode = mode
local fm = fonts.methods[mode] -- todo: zonder node/mode otf/...
if fm then
local fmotf = fm.otf
if fmotf then
- for l=1,4 do
+ for l=1,#lists do
local list = lists[l]
if list then
for i=1,#list do
@@ -1535,7 +1537,8 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th
local glyphs, pfminfo, metadata = data.glyphs or { }, data.pfminfo or { }, data.metadata or { }
local luatex = data.luatex
local unicodes = luatex.unicodes -- names to unicodes
- local indices = luatex.indices
+ local indices = luatex.indices local mode = data.mode or "base"
+
local characters, parameters, math_parameters, descriptions = { }, { }, { }, { }
local designsize = metadata.designsize or metadata.design_size or 100
if designsize == 0 then
@@ -1677,6 +1680,7 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th
designsize = (designsize/10)*65536,
spacer = "500 units",
encodingbytes = 2,
+ mode = mode,
filename = filename,
fontname = fontname,
fullname = fullname,
diff --git a/tex/context/base/font-ott.lua b/tex/context/base/font-ott.lua
index c56e98498..638fd8efc 100644
--- a/tex/context/base/font-ott.lua
+++ b/tex/context/base/font-ott.lua
@@ -691,38 +691,40 @@ otf.meanings.checkers = {
local checkers = otf.meanings.checkers
function otf.meanings.normalize(features)
- local h = { }
- for k,v in next, features do
- k = lower(k)
- if k == "language" or k == "lang" then
- v = gsub(lower(v),"[^a-z0-9%-]","")
- if not languages[v] then
- h.language = to_languages[v] or "dflt"
- else
- h.language = v
- end
- elseif k == "script" then
- v = gsub(lower(v),"[^a-z0-9%-]","")
- if not scripts[v] then
- h.script = to_scripts[v] or "dflt"
- else
- h.script = v
- end
- else
- if type(v) == "string" then
- local b = v:is_boolean()
- if type(b) == "nil" then
- v = tonumber(v) or lower(v)
+ if features then
+ local h = { }
+ for k,v in next, features do
+ k = lower(k)
+ if k == "language" or k == "lang" then
+ v = gsub(lower(v),"[^a-z0-9%-]","")
+ if not languages[v] then
+ h.language = to_languages[v] or "dflt"
else
- v = b
+ h.language = v
+ end
+ elseif k == "script" then
+ v = gsub(lower(v),"[^a-z0-9%-]","")
+ if not scripts[v] then
+ h.script = to_scripts[v] or "dflt"
+ else
+ h.script = v
+ end
+ else
+ if type(v) == "string" then
+ local b = v:is_boolean()
+ if type(b) == "nil" then
+ v = tonumber(v) or lower(v)
+ else
+ v = b
+ end
end
+ k = to_features[k] or k
+ local c = checkers[k]
+ h[k] = c and c(v) or v
end
- k = to_features[k] or k
- local c = checkers[k]
- h[k] = c and c(v) or v
end
+ return h
end
- return h
end
-- When I feel the need ...
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua
index b698fe27f..23030588e 100644
--- a/tex/context/base/font-syn.lua
+++ b/tex/context/base/font-syn.lua
@@ -1466,32 +1466,3 @@ function names.getlookups(pattern,name,reload)
end
return lastlookups
end
-
-function table.formatcolumns(result)
- if result and #result > 0 then
- local widths = { }
- local first = result[1]
- local n = #first
- for i=1,n do
- widths[i] = 0
- end
- for i=1,#result do
- local r = result[i]
- for j=1,n do
- local w = #r[j]
- if w > widths[j] then
- widths[j] = w
- end
- end
- end
- for i=1,n do
- widths[i] = "%-" .. widths[i] .. "s"
- end
- local template = concat(widths," ")
- for i=1,#result do
- local str = format(template,unpack(result[i]))
- result[i] = string.strip(str)
- end
- end
- return result
-end
diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua
index 83f07e9f4..57e10f3b1 100644
--- a/tex/context/base/font-tfm.lua
+++ b/tex/context/base/font-tfm.lua
@@ -253,6 +253,10 @@ function tfm.do_scale(tfmtable, scaledpoints, relativeid)
local hasitalic = tfmtable.has_italic
local descriptions = tfmtable.descriptions or { }
--
+ if hasmath then
+ t.has_math = true -- this will move to elsewhere
+ end
+ --
t.parameters = { }
t.characters = { }
t.MathConstants = { }
diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua
index 6fa611694..8b81099a5 100644
--- a/tex/context/base/grph-inc.lua
+++ b/tex/context/base/grph-inc.lua
@@ -988,7 +988,8 @@ local gifconverter = { }
figures.converters.gif = gifconverter
figures.programs.convert = {
- command = "convert" -- imagemagick
+ command = "convert" -- imagemagick
+ -- command = "gm convert" -- graphicmagick
}
function gifconverter.pdf(oldname,newname)
diff --git a/tex/context/base/java-ini.lua b/tex/context/base/java-ini.lua
index f64a8a18f..61b57cbc5 100644
--- a/tex/context/base/java-ini.lua
+++ b/tex/context/base/java-ini.lua
@@ -7,7 +7,8 @@ if not modules then modules = { } end modules ['java-ini'] = {
}
local format = string.format
-local lpegmatch = lpeg.match
+local concat = table.concat
+local lpegmatch, lpegP, lpegR, lpegS, lpegC = lpeg.match, lpeg.P, lpeg.R, lpeg.S, lpeg.C
javascripts = javascripts or { }
javascripts.codes = javascripts.codes or { }
@@ -22,20 +23,20 @@ local function storefunction(s)
functions[s] = true
end
-local uses = lpeg.P("uses")
-local used = lpeg.P("used")
-local left = lpeg.P("{")
-local right = lpeg.P("}")
-local space = lpeg.S(" \r\n")
+local uses = lpegP("uses")
+local used = lpegP("used")
+local left = lpegP("{")
+local right = lpegP("}")
+local space = lpegS(" \r\n")
local spaces = space^0
-local braced = left * lpeg.C((1-right-space)^1) * right
-local unbraced = lpeg.C((1-space)^1)
+local braced = left * lpegC((1-right-space)^1) * right
+local unbraced = lpegC((1-space)^1)
local name = spaces * (braced + unbraced) * spaces
-local any = lpeg.P(1)
-local script = lpeg.C(any^1)
-local funct = lpeg.P("function")
-local leftp = lpeg.P("(")
-local rightp = lpeg.P(")")
+local any = lpegP(1)
+local script = lpegC(any^1)
+local funct = lpegP("function")
+local leftp = lpegP("(")
+local rightp = lpegP(")")
local fname = spaces * funct * spaces * (((1-space-left)^1)/storefunction) * spaces * leftp
local parsecode = name * ((uses * name) + lpeg.Cc("")) * spaces * script
@@ -85,6 +86,8 @@ function javascripts.usepreamblenow(name) -- now later
end
end
+local splitter = lpeg.Ct(lpeg.splitat(lpeg.patterns.commaspacer))
+
function javascripts.code(name,arguments)
local c = codes[name]
if c then
@@ -99,9 +102,12 @@ function javascripts.code(name,arguments)
end
local f = functions[name]
if f then
- -- temporary hack, i need a more clever approach
if arguments then
- return format("%s(%s)",name,'"' .. arguments.gsub(arguments,'%s*,%s*','"%1",') .. '"')
+ local args = lpegmatch(splitter,arguments)
+ for i=1,#args do -- can be a helper
+ args[i] = format("%q",args[i])
+ end
+ return format("%s(%s)",name,concat(args,","))
else
return format("%s()",name)
end
diff --git a/tex/context/base/l-aux.lua b/tex/context/base/l-aux.lua
index aeea79173..28d4f88b2 100644
--- a/tex/context/base/l-aux.lua
+++ b/tex/context/base/l-aux.lua
@@ -163,14 +163,24 @@ function aux.array_to_string(a,separator)
end
end
-function aux.settings_to_set(str,t)
+function aux.settings_to_set(str,t) -- tohash?
t = t or { }
- for s in gmatch(str,"%s*([^,]+)") do
+ for s in gmatch(str,"%s*([^, ]+)") do -- space added
t[s] = true
end
return t
end
+function aux.simple_hash_to_string(h, separator)
+ local t = { }
+ for k, v in table.sortedhash(h) do
+ if v then
+ t[#t+1] = k
+ end
+ end
+ return concat(t,separator or ",")
+end
+
local value = lbrace * lpeg.C((nobrace + nested)^0) * rbrace
local pattern = lpeg.Ct((space + value)^0)
@@ -255,3 +265,57 @@ end
--~ end
--~ return reminder, cache
--~ end
+
+function aux.formatcolumns(result,between)
+ if result and #result > 0 then
+ between = between or " "
+ local widths, numbers = { }, { }
+ local first = result[1]
+ local n = #first
+ for i=1,n do
+ widths[i] = 0
+ end
+ for i=1,#result do
+ local r = result[i]
+ for j=1,n do
+ local rj = r[j]
+ local tj = type(rj)
+ if tj == "number" then
+ numbers[j] = true
+ end
+ if tj ~= "string" then
+ rj = tostring(rj)
+ r[j] = rj
+ end
+ local w = #rj
+ if w > widths[j] then
+ widths[j] = w
+ end
+ end
+ end
+ for i=1,n do
+ local w = widths[i]
+ if numbers[i] then
+ if w > 80 then
+ widths[i] = "%s" .. between
+ else
+ widths[i] = "%0" .. w .. "i" .. between
+ end
+ else
+ if w > 80 then
+ widths[i] = "%s" .. between
+ elseif w > 0 then
+ widths[i] = "%-" .. w .. "s" .. between
+ else
+ widths[i] = "%s"
+ end
+ end
+ end
+ local template = string.strip(concat(widths))
+ for i=1,#result do
+ local str = format(template,unpack(result[i]))
+ result[i] = string.strip(str)
+ end
+ end
+ return result
+end
diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua
index 66e279309..89227a63f 100644
--- a/tex/context/base/l-io.lua
+++ b/tex/context/base/l-io.lua
@@ -185,3 +185,36 @@ function io.ask(question,default,options)
end
end
end
+
+function io.readnumber(f,n,m)
+ if m then
+ f:seek("set",n)
+ n = m
+ end
+ if n == 1 then
+ return byte(f:read(1))
+ elseif n == 2 then
+ local a, b = byte(f:read(2),1,2)
+ return 256*a + b
+ elseif n == 4 then
+ local a, b, c, d = byte(f:read(4),1,4)
+ return 256^3 * a + 256^2 * b + 256*c + d
+ elseif n == 8 then
+ local a, b = readnumber(f,4), readnumber(f,4)
+ return 256 * b + c
+ elseif n == 12 then
+ local a, b, c = readnumber(f,4), readnumber(f,4), readnumber(f,4)
+ return 256^2 * a + 256 * b + c
+ else
+ return 0
+ end
+end
+
+function io.readstring(f,n,m)
+ if m then
+ f:seek("set",n)
+ n = m
+ end
+ local str = gsub(f:read(n),"%z","")
+ return str
+end
diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua
index 05bbebab9..cffcc86e1 100644
--- a/tex/context/base/l-lpeg.lua
+++ b/tex/context/base/l-lpeg.lua
@@ -38,7 +38,8 @@ patterns.hexadecimal = P("0x") * R("09","AF","af")^1
patterns.lowercase = R("az")
patterns.uppercase = R("AZ")
patterns.letter = patterns.lowercase + patterns.uppercase
-patterns.space = S(" ")
+patterns.space = P(" ")
+patterns.tab = P("\t")
patterns.eol = S("\n\r")
patterns.spacer = S(" \t\f\v") -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto)
patterns.newline = crlf + cr + lf
@@ -49,6 +50,9 @@ patterns.nonwhitespace = 1 - patterns.whitespace
patterns.utf8 = patterns.utf8one + patterns.utf8two + patterns.utf8three + patterns.utf8four
patterns.utfbom = P('\000\000\254\255') + P('\255\254\000\000') + P('\255\254') + P('\254\255') + P('\239\187\191')
patterns.validutf8 = patterns.utf8^0 * P(-1) * Cc(true) + Cc(false)
+patterns.comma = P(",")
+patterns.commaspacer = P(",") * patterns.spacer^0
+patterns.period = P(".")
patterns.undouble = P('"')/"" * (1-P('"'))^0 * P('"')/""
patterns.unsingle = P("'")/"" * (1-P("'"))^0 * P("'")/""
@@ -169,15 +173,41 @@ local function f4(s) local c1, c2, c3, c4 = f1(s,1,4) return ((c1 * 64 + c2) * 6
patterns.utf8byte = patterns.utf8one/f1 + patterns.utf8two/f2 + patterns.utf8three/f3 + patterns.utf8four/f4
+--~ local str = " a b c d "
+
+--~ local s = lpeg.stripper(lpeg.R("az")) print("["..lpeg.match(s,str).."]")
+--~ local s = lpeg.keeper(lpeg.R("az")) print("["..lpeg.match(s,str).."]")
+--~ local s = lpeg.stripper("ab") print("["..lpeg.match(s,str).."]")
+--~ local s = lpeg.keeper("ab") print("["..lpeg.match(s,str).."]")
+
local cache = { }
function lpeg.stripper(str)
- local s = cache[str]
- if not s then
- s = Cs(((S(str)^1)/"" + 1)^0)
- cache[str] = s
+ if type(str) == "string" then
+ local s = cache[str]
+ if not s then
+ s = Cs(((S(str)^1)/"" + 1)^0)
+ cache[str] = s
+ end
+ return s
+ else
+ return Cs(((str^1)/"" + 1)^0)
+ end
+end
+
+local cache = { }
+
+function lpeg.keeper(str)
+ if type(str) == "string" then
+ local s = cache[str]
+ if not s then
+ s = Cs((((1-S(str))^1)/"" + 1)^0)
+ cache[str] = s
+ end
+ return s
+ else
+ return Cs((((1-str)^1)/"" + 1)^0)
end
- return s
end
function lpeg.replacer(t)
diff --git a/tex/context/base/l-number.lua b/tex/context/base/l-number.lua
index a1249f055..7a59e1b2a 100644
--- a/tex/context/base/l-number.lua
+++ b/tex/context/base/l-number.lua
@@ -56,3 +56,21 @@ function number.bits(n,zero)
end
return t
end
+
+--~ http://ricilake.blogspot.com/2007/10/iterating-bits-in-lua.html
+
+function number.bit(p)
+ return 2 ^ (p - 1) -- 1-based indexing
+end
+
+function number.hasbit(x, p) -- typical call: if hasbit(x, bit(3)) then ...
+ return x % (p + p) >= p
+end
+
+function number.setbit(x, p)
+ return hasbit(x, p) and x or x + p
+end
+
+function number.clearbit(x, p)
+ return hasbit(x, p) and x - p or x
+end
diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua
index 23477c655..c3ef364a5 100644
--- a/tex/context/base/l-table.lua
+++ b/tex/context/base/l-table.lua
@@ -126,7 +126,7 @@ end
table.sortedkeys = sortedkeys
table.sortedhashkeys = sortedhashkeys
-function table.sortedhash(t)
+local function sortedhash(t)
local s = sortedhashkeys(t) -- maybe just sortedkeys
local n = 0
local function kv(s)
@@ -137,7 +137,8 @@ function table.sortedhash(t)
return kv, s
end
-table.sortedpairs = table.sortedhash
+table.sortedhash = sortedhash
+table.sortedpairs = sortedhash
function table.append(t, list)
for _,v in next, list do
@@ -832,12 +833,26 @@ function table.count(t)
return n
end
-function table.swapped(t)
- local s = { }
+function table.swapped(t,s)
+ local n = { }
+ if s then
+--~ for i=1,#s do
+--~ n[i] = s[i]
+--~ end
+ for k, v in next, s do
+ n[k] = v
+ end
+ end
+--~ for i=1,#t do
+--~ local ti = t[i] -- don't ask but t[i] can be nil
+--~ if ti then
+--~ n[ti] = i
+--~ end
+--~ end
for k, v in next, t do
- s[v] = k
+ n[v] = k
end
- return s
+ return n
end
--~ function table.are_equal(a,b)
@@ -860,7 +875,7 @@ function table.hexed(t,seperator)
return concat(tt,seperator or " ")
end
-function table.reverse_hash(h)
+function table.reverse_hash(h) -- needs another name
local r = { }
for k,v in next, h do
r[v] = lower(gsub(k," ",""))
@@ -908,10 +923,18 @@ function table.insert_after_value(t,value,extra)
insert(t,#t+1,extra)
end
-function table.sequenced(t,sep)
+function table.sequenced(t,sep,simple) -- hash only
local s = { }
- for k, v in next, t do -- indexed?
- s[#s+1] = k .. "=" .. tostring(v)
+ for k, v in sortedhash(t) do
+ if simple then
+ if v == true then
+ s[#s+1] = k
+ elseif v and v~= "" then
+ s[#s+1] = k .. "=" .. tostring(v)
+ end
+ else
+ s[#s+1] = k .. "=" .. tostring(v)
+ end
end
return concat(s, sep or " | ")
end
diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua
index 0c5a60142..dc78f7325 100644
--- a/tex/context/base/l-unicode.lua
+++ b/tex/context/base/l-unicode.lua
@@ -32,7 +32,7 @@ end
utf = utf or unicode.utf8
local concat, utfchar, utfgsub = table.concat, utf.char, utf.gsub
-local char, byte, find, bytepairs = string.char, string.byte, string.find, string.bytepairs
+local char, byte, find, bytepairs, utfvalues, format = string.char, string.byte, string.find, string.bytepairs, string.utfvalues, string.format
-- 0 EF BB BF UTF-8
-- 1 FF FE UTF-16-little-endian
@@ -197,3 +197,13 @@ function unicode.utf8_to_utf16(str,littleendian)
return char(254,255) .. utfgsub(str,".",big)
end
end
+
+function unicode.utfcodes(str)
+ local t = { }
+ for k,v in string.utfvalues(str) do
+ t[#t+1] = format("0x%04X",k)
+ end
+ return concat(t,separator or " ")
+end
+
+--~ print(unicode.utfcodes(str))
diff --git a/tex/context/base/lang-wrd.lua b/tex/context/base/lang-wrd.lua
index c2b5ff6ac..6e3caed12 100644
--- a/tex/context/base/lang-wrd.lua
+++ b/tex/context/base/lang-wrd.lua
@@ -23,13 +23,14 @@ words.threshold = 4
local set_attribute = node.set_attribute
local unset_attribute = node.unset_attribute
local traverse_nodes = node.traverse
-local node_id = node.id
local wordsdata = words.data
local chardata = characters.data
-local glyph_node = node_id('glyph')
-local disc_node = node_id('disc')
-local kern_node = node_id('kern')
+local nodecodes = nodes.nodecodes
+
+local glyph_node = nodecodes.glyph
+local disc_node = nodecodes.disc
+local kern_node = nodecodes.kern
words.colors = {
["known"] = "green",
diff --git a/tex/context/base/lpdf-col.lua b/tex/context/base/lpdf-col.lua
index 18aa848ff..fc2b9cabc 100644
--- a/tex/context/base/lpdf-col.lua
+++ b/tex/context/base/lpdf-col.lua
@@ -16,37 +16,43 @@ local registercolor = colors.register
local registertransparancy = transparencies.register
local colorsvalue = colors.value
local transparenciesvalue = transparencies.value
+local forcedmodel = colors.forcedmodel
-- Literals needed to inject code in the mp stream, we cannot use attributes there
-- since literals may have qQ's, much may go away once we have mplib code in place.
--
-- This module assumes that some functions are defined in the colors namespace
--- which mostlikely will be loaded later.
+-- which most likely will be loaded later.
function lpdf.color(model,ca,default) -- todo: use gray when no color
- local cv = colorsvalue(ca)
- if cv then
- if model == 1 then
- model = cv[1]
- end
- if model == 2 then
- local s = cv[2]
- return format("%s g %s G",s,s)
- elseif model == 3 then
- local r, g, b = cv[3], cv[4], cv[5]
- return format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b)
- elseif model == 4 then
- local c, m, y, k = cv[6],cv[7],cv[8],cv[9]
- return format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k)
- else
- local n,f,d,p = cv[10],cv[11],cv[12],cv[13]
- if type(p) == "string" then
- p = gsub(p,","," ") -- brr misuse of spot
+ if colors.supported then
+ local cv = colorsvalue(ca)
+ if cv then
+ if model == 1 then
+ model = cv[1]
end
- return format("/%s cs /%s CS %s SCN %s scn",n,n,p,p)
+ model = forcedmodel(model)
+ if model == 2 then
+ local s = cv[2]
+ return format("%s g %s G",s,s)
+ elseif model == 3 then
+ local r, g, b = cv[3], cv[4], cv[5]
+ return format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b)
+ elseif model == 4 then
+ local c, m, y, k = cv[6],cv[7],cv[8],cv[9]
+ return format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k)
+ else
+ local n,f,d,p = cv[10],cv[11],cv[12],cv[13]
+ if type(p) == "string" then
+ p = gsub(p,","," ") -- brr misuse of spot
+ end
+ return format("/%s cs /%s CS %s SCN %s scn",n,n,p,p)
+ end
+ else
+ return format("%s g %s G",default or 0,default or 0)
end
else
- return format("%s g %s G",default or 0,default or 0)
+ return ""
end
end
@@ -54,11 +60,15 @@ function lpdf.transparency(ct,default) -- kind of overlaps with transparencycode
-- beware, we need this hack because normally transparencies are not
-- yet registered and therefore the number is not not known ... we
-- might use the attribute number itself in the future
- local ct = transparenciesvalue(ct)
- if ct then
- return format("/Tr%s gs",registertransparancy(nil,ct[1],ct[2],true))
+ if transparencies.supported then
+ local ct = transparenciesvalue(ct)
+ if ct then
+ return format("/Tr%s gs",registertransparancy(nil,ct[1],ct[2],true))
+ else
+ return "/Tr0 gs"
+ end
else
- return "/Tr0 gs"
+ return ""
end
end
@@ -68,6 +78,7 @@ function lpdf.colorvalue(model,ca,default)
if model == 1 then
model = cv[1]
end
+ model = forcedmodel(model)
if model == 2 then
return format("%s",cv[2])
elseif model == 3 then
@@ -88,6 +99,7 @@ function lpdf.fdfcolor(model,ca,default)
if model == 1 then
model = cv[1]
end
+ model = forcedmodel(model)
if model == 2 then
return format("[%s]",cv[2])
elseif model == 3 then
@@ -108,6 +120,7 @@ function lpdf.colorspace(model,ca)
if model == 1 then
model = cv[1]
end
+ model = forcedmodel(model)
if model == 2 then
return "DeviceGray"
elseif model == 3 then
@@ -125,23 +138,47 @@ local intransparency = false
local pdfcolor = lpdf.color
function lpdf.rgbcode(model,r,g,b)
- return pdfcolor(model,registercolor(nil,'rgb',r,g,b))
+ if colors.supported then
+ return pdfcolor(model,registercolor(nil,'rgb',r,g,b))
+ else
+ return ""
+ end
end
+
function lpdf.cmykcode(model,c,m,y,k)
- return pdfcolor(model,registercolor(nil,'cmyk',c,m,y,k))
+ if colors.supported then
+ return pdfcolor(model,registercolor(nil,'cmyk',c,m,y,k))
+ else
+ return ""
+ end
end
+
function lpdf.graycode(model,s)
- return pdfcolor(model,registercolor(nil,'gray',s))
+ if colors.supported then
+ return pdfcolor(model,registercolor(nil,'gray',s))
+ else
+ return ""
+ end
end
+
function lpdf.spotcode(model,n,f,d,p)
- return pdfcolor(model,registercolor(nil,'spot',n,f,d,p)) -- incorrect
+ if colors.supported then
+ return pdfcolor(model,registercolor(nil,'spot',n,f,d,p)) -- incorrect
+ else
+ return ""
+ end
end
+
function lpdf.transparencycode(a,t)
- intransparency = true
- return format("/Tr%s gs",registertransparancy(nil,a,t,true)) -- true forces resource
+ if transparencies.supported then
+ intransparency = true
+ return format("/Tr%s gs",registertransparancy(nil,a,t,true)) -- true forces resource
+ else
+ return ""
+ end
end
function lpdf.finishtransparencycode()
- if intransparency then
+ if transparencies.supported and intransparency then
intransparency = false
return "/Tr0 gs" -- we happen to know this -)
else
diff --git a/tex/context/base/lpdf-epd.lua b/tex/context/base/lpdf-epd.lua
index 23ab0674c..680c39e18 100644
--- a/tex/context/base/lpdf-epd.lua
+++ b/tex/context/base/lpdf-epd.lua
@@ -20,6 +20,13 @@ local setmetatable, rawset = setmetatable, rawset
-- getNum getString getBool getName getRef
-- getResourceDict getMediaBox getCropBox getBleedBox getTrimBox getArtBox
-- getPageRef getKindName findDestgetNumPages getDests getPage getCatalog getAnnots
+--
+-- needed:
+--
+-- add accessor methods to the resource dict
+-- a function to mark objects as to be included
+
+lpdf = lpdf or { }
-- -- -- helpers -- -- --
@@ -100,17 +107,17 @@ local basic_resources_access = { -- == dictionary_access
end
}
-local basic_box_access = {
+local basic_box_access = { -- here it makes sense to do the rawset
__index = function(t,k)
local d = t.__data__
- if k == "all" then return { d.x1, d.y1, d.x2, d.y2 }
- elseif k == "width" then return d.x2 - d.x1
- elseif k == "height" then return d.y2 - d.y1
- elseif k == 1 then return d.x1
- elseif k == 2 then return d.y1
- elseif k == 3 then return d.x2
- elseif k == 4 then return d.y2
- else return 0 end
+ if k == "all" then return { d.x1, d.y1, d.x2, d.y2 }
+ elseif k == "width" then return d.x2 - d.x1
+ elseif k == "height" then return d.y2 - d.y1
+ elseif k == 1 or k == "llx" then return d.x1
+ elseif k == 2 or k == "lly" then return d.y1
+ elseif k == 3 or k == "urx" then return d.x2
+ elseif k == 4 or k == "lly" then return d.y2
+ else return 0 end
end
}
diff --git a/tex/context/base/lpdf-pdx.lua b/tex/context/base/lpdf-pdx.lua
index db1217c53..dbf8eadf2 100644
--- a/tex/context/base/lpdf-pdx.lua
+++ b/tex/context/base/lpdf-pdx.lua
@@ -6,7 +6,10 @@ if not modules then modules = { } end modules ['lpdf-pdx'] = {
license = "see context related readme files",
}
-local trace_colorprofiles = false trackers.register("backend.colorprofiles", function(v) trace_colorprofiles = v end)
+-- context --directives="backend.format=PDF/X-1a:2001" --trackers=backend.format yourfile
+
+local trace_pdfx = false trackers.register("backend.pdfx", function(v) trace_pdfx = v end)
+local trace_format = false trackers.register("backend.format", function(v) trace_format = v end)
local report_backends = logs.new("backends")
@@ -22,7 +25,10 @@ local pdfstring = lpdf.string
local pdfverbose = lpdf.verbose
local pdfobject = lpdf.object
-local lower, gmatch = string.lower, string.gmatch
+local addtoinfo, injectxmpinfo, insertxmpinfo = lpdf.addtoinfo, lpdf.injectxmpinfo, lpdf.insertxmpinfo
+
+local lower, gmatch, format, find = string.lower, string.gmatch, string.format, string.find
+local concat, serialize = table.concat, table.serialize
local channels = {
gray = 1,
@@ -38,90 +44,587 @@ local prefixes = {
cmyk = "DefaultCMYK",
}
-local profiles = { }
-local defaults = { }
-local intents = pdfarray()
-local lastprofile = nil
-
-function codeinjections.useinternalICCprofile(colorspace,filename)
- local name = lower(file.basename(filename))
- local profile = profiles[name]
- if not profile then
- local colorspace = lower(colorspace)
- local filename = resolvers.findctxfile(filename) or ""
- local channel = channels[colorspace]
- if channel and filename ~= "" then
- local a = pdfdictionary { N = channel }
- profile = pdfobject {
- compresslevel = 0,
- immediate = true, -- !
- type = "stream",
- file = filename,
- attr = a(),
- }
- profiles[name] = profile
+local pdfxspecification, pdfxformat = nil, nil
+
+-- * correspondent document wide flags (write once) needed for permission tests
+
+local pdfx = {
+ ["version"] = {
+ external_icc_profiles = 1.4, -- 'p' in name; URL reference of output intent
+ jbig2_compression = 1.4,
+ jpeg2000_compression = 1.5, -- not supported yet
+ nchannel_colorspace = 1.6, -- 'n' in name; n-channel colorspace support
+ open_prepress_interface = 1.3, -- 'g' in name; reference to external graphics
+ opentype_fonts = 1.6,
+ optional_content = 1.5,
+ transparency = 1.4,
+ object_compression = 1.5,
+ },
+ ["default"] = {
+ pdf_version = 1.7, -- todo: block tex primitive
+ format_name = "default",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ spot_colors = true,
+ calibrated_rgb_colors = true, -- unknown
+ cielab_colors = true, -- unknown
+ nchannel_colorspace = true, -- unknown
+ internal_icc_profiles = true, -- controls profile inclusion
+ external_icc_profiles = true, -- controls profile inclusion
+ include_intents = true,
+ open_prepress_interface = true, -- unknown
+ opentype_fonts = true, -- out of our control
+ optional_content = true, -- todo: block at lua level
+ transparency = true, -- todo: block at lua level
+ jbig2_compression = true, -- todo: block at lua level
+ jpeg2000_compression = true, -- todo: block at lua level
+ inject_metadata = function()
+ -- nothing
+ end
+ },
+ ["pdf/x-1a:2001"] = {
+ pdf_version = 1.3,
+ format_name = "PDF/X-1a:2001",
+ gray_scale = true,
+ cmyk_colors = true,
+ spot_colors = true,
+ internal_icc_profiles = true,
+ inject_metadata = function()
+ addtoinfo("GTS_PDFXVersion","PDF/X-1a:2001")
+ injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2001</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
+ end
+ },
+ ["pdf/x-1a:2003"] = {
+ pdf_version = 1.4,
+ format_name = "PDF/X-1a:2003",
+ gray_scale = true,
+ cmyk_colors = true,
+ spot_colors = true,
+ internal_icc_profiles = true,
+ inject_metadata = function()
+ addtoinfo("GTS_PDFXVersion","PDF/X-1a:2003")
+ injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2003</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
+ end
+ },
+ ["pdf/x-3:2002"] = {
+ pdf_version = 1.3,
+ format_name = "PDF/X-3:2002",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ inject_metadata = function()
+ addtoinfo("GTS_PDFXVersion","PDF/X-3:2002")
+ end
+ },
+ ["pdf/x-3:2003"] = {
+ pdf_version = 1.4,
+ format_name = "PDF/X-3:2003",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ jbig2_compression = true,
+ inject_metadata = function()
+ addtoinfo("GTS_PDFXVersion","PDF/X-3:2003")
+ end
+ },
+ ["pdf/x-4"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-4",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ inject_metadata = function()
+ injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
+ insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false)
+ insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:RenditionClass>default</xmpMM:RenditonClass>",false)
+ end
+ },
+ ["pdf/x-4p"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-4p",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ external_icc_profiles = true,
+ include_intents = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ nchannel_colorspace = false,
+ inject_metadata = function()
+ injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4p</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
+ insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",false)
+ insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:RenditionClass>default</xmpMM:RenditonClass>",false)
+ end
+ },
+ ["pdf/x-5g"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-5g",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ open_prepress_interface = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ inject_metadata = function()
+ -- todo
+ end
+ },
+ ["pdf/x-5pg"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-5pg",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ external_icc_profiles = true,
+ include_intents = true,
+ open_prepress_interface = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ inject_metadata = function()
+ -- todo
+ end
+ },
+ ["pdf/x-5n"] = {
+ pdf_version = 1.6,
+ format_name = "PDF/X-5n",
+ gray_scale = true,
+ cmyk_colors = true,
+ rgb_colors = true,
+ calibrated_rgb_colors = true,
+ spot_colors = true,
+ cielab_colors = true,
+ internal_icc_profiles = true,
+ include_intents = true,
+ opentype_fonts = true,
+ optional_content = true,
+ transparency = true,
+ jbig2_compression = true,
+ jpeg2000_compression = true,
+ nchannel_colorspace = true,
+ inject_metadata = function()
+ -- todo
+ end
+ }
+}
+
+lpdf.pdfx = pdfx -- it does not hurt to have this one visible
+
+local filenames = {
+ "colorprofiles.xml",
+ "colorprofiles.lua",
+}
+
+local function locatefile(filename)
+ local fullname = resolvers.find_file(filename,"icc")
+ if not fullname or fullname == "" then
+ fullname = resolvers.finders.loc(filename) -- could be specific to the project
+ end
+ return fullname or ""
+end
+
+local function loadprofile(name,filename)
+ local profile = false
+ local databases = filename and filename ~= "" and aux.settings_to_array(filename) or filenames
+ for i=1,#databases do
+ local filename = locatefile(databases[i])
+ if filename and filename ~= "" then
+ local suffix = file.extname(filename)
+ local lname = lower(name)
+ if suffix == "xml" then
+ local xmldata = xml.load(filename) -- no need for caching it
+ if xmldata then
+ profile = xml.filter(xmldata,format('xml://profiles/profile/(info|filename)[lower(text())=="%s"]/../table()',lname))
+ end
+ elseif suffix == "lua" then
+ local luadata = loadfile(filename)
+ luadata = ludata and luadata()
+ if luadata then
+ profile = luadata[name] or luadata[lname] -- hashed
+ if not profile then
+ for i=1,#luadata do
+ local li = luadata[i]
+ if lower(li.info) == lname then -- indexed
+ profile = li
+ break
+ end
+ end
+ end
+ end
+ end
+ if profile then
+ if next(profile) then
+ report_backends("profile specification '%s' loaded from '%s'",name,filename)
+ return profile
+ elseif trace_pdfx then
+ report_backends("profile specification '%s' loaded from '%s' but empty",name,filename)
+ end
+ return false
+ end
end
end
- lastprofile = profile
- return profile
+ report_backends("profile specification '%s' not found in '%s'",name,concat(filenames, ", "))
end
-function codeinjections.useexternalICCprofile(colorspace,name,urls,checksum,version)
- local profile = profiles[name]
- if not profile then
+local function urls(url)
+ if not url or url == "" then
+ return nil
+ else
local u = pdfarray()
- for url in gmatch(urls,"([^, ]+)") do
- u[#u+1] = pdfdictionary {
- FS = pdfconstant("URL"),
- F = pdfstring(url),
+ for url in gmatch(url,"([^, ]+)") do
+ if find(url,"^http") then
+ u[#u+1] = pdfdictionary {
+ FS = pdfconstant("URL"),
+ F = pdfstring(url),
+ }
+ end
+ end
+ return u
+ end
+end
+
+local function profilename(filename)
+ return lower(file.basename(filename))
+end
+
+local internalprofiles = { }
+
+local function handleinternalprofile(s,include)
+ local filename, colorspace = s.filename or "", s.colorspace or ""
+ if filename == "" or colorspace == "" then
+ report_backends("error in internal profile specification: %s",serialize(s,false))
+ else
+ local tag = profilename(filename)
+ local profile = internalprofiles[tag]
+ if not profile then
+ local colorspace = lower(colorspace)
+ if include then
+ -- local fullname = resolvers.findctxfile(filename) or ""
+ local fullname = locatefile(filename)
+ local channel = channels[colorspace] or nil
+ if fullname == "" then
+ report_backends("error, couldn't locate profile '%s'",filename)
+ elseif not channel then
+ report_backends("error, couldn't resolve channel entry for colorspace '%s'",colorspace)
+ else
+ local a = pdfdictionary { N = channel }
+ profile = pdfobject { -- does a flush too
+ compresslevel = 0,
+ immediate = true, -- !
+ type = "stream",
+ file = fullname,
+ attr = a(),
+ }
+ internalprofiles[tag] = profile
+ if trace_pdfx then
+ report_backends("including '%s' color profile from '%s'",colorspace,fullname)
+ end
+ end
+ else
+ internalprofiles[tag] = true
+ if trace_pdfx then
+ report_backends("not including '%s' color profile '%s'",colorspace,filename)
+ end
+ end
+ end
+ return profile
+ end
+end
+
+local externalprofiles = { }
+
+local function handleexternalprofile(s,include) -- specification (include ignored here)
+ local name, url, filename, checksum, version, colorspace =
+ s.info or s.filename or "", s.url or "", s.filename or "", s.checksum or "", s.version or "", s.colorspace or ""
+ if false then -- somehow leads to invalid pdf
+ local iccprofile = colors.iccprofile(filename)
+ if iccprofile then
+ name = name ~= "" and name or iccprofile.tags.desc.cleaned or ""
+ url = url ~= "" and url or iccprofile.tags.dmnd.cleaned or ""
+ checksum = checksum ~= "" and checksum or file.checksum(iccprofile.fullname) or ""
+ version = version ~= "" and version or iccprofile.header.version or ""
+ colorspace = colorspace ~= "" and colorspace or iccprofile.header.colorspace or ""
+ end
+ -- table.print(iccprofile)
+ end
+ if name == "" or url == "" or checksum == "" or version == "" or colorspace == "" or filename == "" then
+ local profile = handleinternalprofile(s)
+ if profile then
+ report_backends("incomplete external profile specification, falling back to internal")
+ else
+ report_backends("error in external profile specification: %s",serialize(s,false))
+ end
+ else
+ local tag = profilename(filename)
+ local profile = externalprofiles[tag]
+ if not profile then
+ local d = pdfdictionary {
+ ProfileName = name, -- not file name!
+ ProfileCS = colorspace,
+ URLs = urls(url), -- array containing at least one URL
+ CheckSum = pdfverbose { "<", lower(checksum), ">" }, -- 16byte MD5 hash
+ ICCVersion = pdfverbose { "<", version, ">" }, -- bytes 8..11 from the header of the ICC profile, as a hex string
}
+ profile = pdfflushobject(d)
+ externalprofiles[tag] = profile
end
- local d = pdfdictionary {
- ProfileName = name, -- not file name!
- ProfileCS = colorspace,
- URLs = u, -- array containing at least one URL
- CheckSum = pdfverbose { "<", checksum, ">" }, -- 16byte MD5 hash
- ICCVersion = pdfverbose { "<", version, ">" }, -- bytes 8..11 from the header of the ICC profile, as a hex string
- }
- local n = pdfflushobject(d)
- profiles[name] = n
- lastprofile = n
- return n
+ return profile
end
end
-local loaded = { }
+local loadeddefaults = { }
-function codeinjections.useICCdefaultprofile(colorspace,filename)
- local colorspace = lower(colorspace)
- if not loaded[colorspace] then
- local n = codeinjections.useinternalICCprofile(colorspace,filename)
- if n then
+local function handledefaultprofile(s) -- specification
+ local filename, colorspace = s.filename or "", lower(s.colorspace or "")
+ if filename == "" or colorspace == "" then
+ report_backends("error in default profile specification: %s",serialize(s,false))
+ elseif not loadeddefaults[colorspace] then
+ local tag = profilename(filename)
+ local n = internalprofiles[tag] -- or externalprofiles[tag]
+ if n == true then -- not internalized
+ report_backends("no default profile '%s' for colorspace '%s'",filename,colorspace)
+ elseif n then
local a = pdfarray {
pdfconstant("ICCBased"),
pdfreference(n),
}
-- used in page /Resources, so this must be inserted at runtime
lpdf.adddocumentcolorspace(prefixes[colorspace],pdfreference(pdfflushobject(a)))
- if trace_colorprofiles then
- report_backends("including color profile '%s' from '%s'",colorspace,filename)
+ loadeddefaults[colorspace] = true
+ report_backends("setting '%s' as default '%s' color space",filename,colorspace)
+ else
+ report_backends("no default profile '%s' for colorspace '%s'",filename,colorspace)
+ end
+ elseif trace_pdfx then
+ report_backends("a default '%s' colorspace is already in use",colorspace)
+ end
+end
+
+local loadedintents, intents = { }, pdfarray()
+
+local function handleoutputintent(s)
+ local name, url, filename, id, outputcondition, info = s.info or s.filename or "", s.url or "", s.filename or "", s.id or "", s.outputcondition or "", s.info or ""
+ if name == "" or id == "" then
+ report_backends("error in output intent specification: %s",serialize(s,false))
+ elseif not loadedintents[name] then
+ local tag = profilename(filename)
+ local internal, external = internalprofiles[tag], externalprofiles[tag]
+ if internal or external then
+ local d = {
+ Type = pdfconstant("OutputIntent"),
+ S = pdfconstant("GTS_PDFX"),
+ OutputConditionIdentifier = id,
+ RegistryName = url,
+ OutputCondition = outputcondition,
+ Info = info,
+ }
+ if internal and internal ~= true then
+ d.DestOutputProfile = pdfreference(internal)
+ elseif external and external ~= true then
+ d.DestOutputProfileRef = pdfreference(external)
+ else
+ report_backends("omitting reference to profile for intent '%s'",name)
+ end
+ intents[#intents+1] = pdfreference(pdfflushobject(pdfdictionary(d)))
+ if trace_pdfx then
+ report_backends("setting output intent to '%s' with id '%s' (entry %s)",name,id,#intents)
+ end
+ else
+ report_backends("invalid output intent '%s'",name)
+ end
+ loadedintents[name] = true
+ elseif trace_pdfx then
+ report_backends("an output intent with name '%s' is already in use",name)
+ end
+end
+
+local function handleiccprofile(message,name,filename,how,options,alwaysinclude)
+ if name and name ~= "" then
+ local list = aux.settings_to_array(name)
+ for i=1,#list do
+ local name = list[i]
+ local profile = loadprofile(name,filename)
+ if trace_pdfx then
+ report_backends("handling %s '%s'",message,name)
+ end
+ if profile then
+ if pdfxspecification.cmyk_colors then
+ profile.colorspace = profile.colorspace or "CMYK"
+ else
+ profile.colorspace = profile.colorspace or "RGB"
+ end
+ local external = pdfxspecification.external_icc_profiles
+ local internal = pdfxspecification.internal_icc_profiles
+ local include = pdfxspecification.include_intents
+ local always, never = options[variables.always], options[variables.never]
+ if always or alwaysinclude then
+ if trace_pdfx then
+ report_backends("forcing internal profiles") -- can make preflight unhappy
+ end
+ -- internal, external = true, false
+ internal, external = not never, false
+ elseif never then
+ if trace_pdfx then
+ report_backends("forcing external profiles") -- can make preflight unhappy
+ end
+ internal, external = false, true
+ end
+ if external then
+ if trace_pdfx then
+ report_backends("handling external profiles cf. '%s'",name)
+ end
+ handleexternalprofile(profile,false)
+ else
+ if trace_pdfx then
+ report_backends("handling internal profiles cf. '%s'",name)
+ end
+ if internal then
+ handleinternalprofile(profile,always or include)
+ else
+ report_backends("no profile inclusion for '%s'",pdfxformat)
+ end
+ end
+ how(profile)
+ elseif trace_pdfx then
+ report_backends("unknown profile '%s'",name)
+ end
+ end
+ end
+end
+
+local function flushoutputintents()
+ if #intents > 0 then
+ lpdf.addtocatalog("OutputIntents",pdfreference(pdfflushobject(intents)))
+ end
+end
+
+lpdf.registerdocumentfinalizer(flushoutputintents,2,"output intents")
+
+directives.register("backend.format", function(v)
+ codeinjections.setformat(v)
+end)
+
+function codeinjections.setformat(s)
+ local format, level, profile, intent, option, filename =
+ s.format or "", s.level or "", s.profile or "", s.intent or "", s.option or "", s.file or ""
+ if format == "" then
+ -- we ignore this as we hook it in \everysetupbackend
+ else
+ local spec = pdfx[lower(format)]
+ if spec then
+ pdfxspecification, pdfxformat = spec, spec.format_name
+ report_backends("setting format to '%s'",pdfxformat)
+ local pdf_version, inject_metadata = spec.pdf_version * 10, spec.inject_metadata
+ local majorversion, minorversion = math.div(pdf_version,10), math.mod(pdf_version,10)
+ local objectcompression = pdf_version >= 15
+ tex.pdfcompresslevel = level and tonumber(level) or tex.pdfobjcompresslevel -- keep default
+ tex.pdfobjcompresslevel = objectcompression and tex.pdfobjcompresslevel or 0 -- keep default
+ tex.pdfmajorversion = majorversion
+ tex.pdfminorversion = minorversion
+ report_backends("forcing pdf version %s.%s, compression level %s, object compression %sabled",
+ majorversion,minorversion,tex.pdfcompresslevel,compression and "en" or "dis")
+ --
+ -- context.setupcolors { -- not this way
+ -- cmyk = spec.cmyk_colors and variables.yes or variables.no,
+ -- rgb = spec.rgb_colors and variables.yes or variables.no,
+ -- }
+ --
+ colors.forcesupport(
+ spec.gray_scale or false,
+ spec.rgb_colors or false,
+ spec.cmyk_colors or false,
+ spec.spot_colors or false,
+ spec.nchannel_colorspace or false
+ )
+ transparencies.forcesupport(
+ spec.transparency or false
+ )
+ viewerlayers.forcesupport(
+ spec.optional_content or false
+ )
+ viewerlayers.setfeatures(
+ spec.has_order or false -- new
+ )
+ --
+ -- spec.jbig2_compression : todo, block in image inclusion
+ -- spec.jpeg2000_compression : todo, block in image inclusion
+ --
+ if type(inject_metadata) == "function" then
+ inject_metadata()
+ end
+ local options = aux.settings_to_hash(option)
+ handleiccprofile("color profile",profile,filename,handledefaultprofile,options,true)
+ handleiccprofile("output intent",intent,filename,handleoutputintent,options,false)
+ if trace_format then
+ for k, v in table.sortedhash(pdfx.default) do
+ local v = pdfxspecification[k]
+ if type(v) ~= "function" then
+ report_backends("%s = %s",k,tostring(v or false))
+ end
+ end
end
- elseif trace_colorprofiles then
- report_backends("no color profile '%s' in '%s'",colorspace,filename)
+ function codeinjections.setformat(noname)
+ report_backends("error, format is already set to '%s', ignoring '%s'",pdfxformat,noname)
+ end
+ else
+ report_backends("error, format '%s' is not supported",format)
end
- loaded = true
- elseif trace_colorprofiles then
- report_backends("color profile '%s' is already included",colorspace)
end
end
+function codeinjections.getformatoption(key)
+ return pdfxspecification and pdfxspecification[key]
+end
+
--~ The following is somewhat cleaner but then we need to flag that there are
--~ color spaces set so that the page flusher does not optimize the (at that
--~ moment) still empty array away. So, next(d_colorspaces) should then become
--~ a different test, i.e. also on flag. I'll add that when we need more forward
--~ referencing.
--~
---~ local function embedprofile = codeinjections.useICCdefaultprofile
+--~ local function embedprofile = handledefaultprofile
--~
--~ local function flushembeddedprofiles()
--~ for colorspace, filename in next, defaults do
@@ -129,37 +632,8 @@ end
--~ end
--~ end
--~
---~ function codeinjections.useICCdefaultprofile(colorspace,filename)
---~ defaults[lower(colorspace)] = filename
+--~ local function handledefaultprofile(s)
+--~ defaults[lower(s.colorspace)] = s.filename
--~ end
--~
--~ lpdf.registerdocumentfinalizer(flushembeddedprofiles,1,"embedded color profiles")
-
-function codeinjections.usePDFXoutputintent(id,name,reference,outputcondition,info)
- local d = {
- Type = pdfconstant("OutputIntent"),
- S = pdfconstant("GTS_PDFX"),
- OutputConditionIdentifier = id,
- RegistryName = name,
- OutputCondition = outputcondition,
- Info = info,
- }
- local icc = lastprofile
- if reference == variables.yes then
- d["DestOutputProfileRef"] = pdfreference(icc)
- else
- d["DestOutputProfile"] = pdfreference(icc)
- end
- intents[#intents+1] = pdfreference(pdfflushobject(pdfdictionary(d)))
- if trace_colorprofiles then
- report_backends("adding output intent '%s' with id '%s' (entry %s)",name,id,#intents)
- end
-end
-
-local function flushoutputintents()
- if #intents > 0 then
- lpdf.addtocatalog("OutputIntents",pdfreference(pdfflushobject(intents)))
- end
-end
-
-lpdf.registerdocumentfinalizer(flushoutputintents,2,"output intents")
diff --git a/tex/context/base/lpdf-pdx.mkiv b/tex/context/base/lpdf-pdx.mkiv
index 738cb3f58..cd13ba24c 100644
--- a/tex/context/base/lpdf-pdx.mkiv
+++ b/tex/context/base/lpdf-pdx.mkiv
@@ -13,55 +13,19 @@
\writestatus{loading}{ConTeXt Backend Macros / PDF-X}
-\unprotect
-
-% declare default color space
-% all device based entries of the same CS are mapped to the defined ICCprofile then;
-% i.e. /DeviceRGB --> /ICCBased RGB profile
-% TODO: allow multiple default profiles (one per CS)
-%
-% external ICC profile dictionary (PDF/X-4p and PDF/X-5p)
-%
-% - ProfileName (not file name!)
-% - URLs (array containing at least one URL); the keyword FSA is wrong!
-% - CheckSum (16byte MD5 hash)
-% - ProfileCS (GRAY,RGB,CMYK)
-% - ICCVersion (bytes 8..11 from the header of the ICC profile, as a hex string)
-
\registerctxluafile{lpdf-pdx}{1.001}
-\def\douseinternalICCprofile[#1]%
- {\getparameters[\??ic][colorspace=,filename=,#1]%
- \ctxlua{backends.codeinjections.useinternalICCprofile(
- "\@@iccolorspace","\@@icfilename")}}
-
-% create a dictionary for an external ICC profile (PDF/X-4p and PDF/X-5pg only)
-% the referenced ICC profile is not embedded
-
-\def\douseexternalICCprofile[#1]%
- {\getparameters[\??ic][colorspace=,name=,url=,checksum=,version=,#1]%
- \ctxlua{backends.codeinjections.useexternalICCprofile(
- "\@@iccolorspace","\@@icname","\@@icurl","\@@icchecksum","\@@icversion")}}
-
-% use an ICC profile as default colorspace for all device dependend colors;
-% all device based entries of the same CS are mapped to the defined ICCprofile then;
-% i.e. /DeviceRGB --> /ICCBased RGB profile; always embed the profile!
-
-\def\douseICCdefaultprofile[#1]%
- {\getparameters[\??ic][colorspace=,filename=,#1]%
- \ctxlua{backends.codeinjections.useICCdefaultprofile(
- "\@@iccolorspace","\@@icfilename")}}
-
-% embedding rules for output intent profile differ for the PDF/X versions
-
-\def\dousePDFXoutputintent[#1]%
- {\getparameters[\??ic][reference=\v!yes,outputcondition=,info=,id=,name=,#1]%
- \ctxlua{backends.codeinjections.usePDFXoutputintent(
- "\@@icid","\@@icname","\@@icreference","\@@icoutputcondition","\@@icinfo")}}
+\unprotect
-\def\useinternalICCprofile{\dosingleempty\douseinternalICCprofile}
-\def\useexternalICCprofile{\dosingleempty\douseexternalICCprofile}
-\def\useICCdefaultprofile {\dosingleempty\douseICCdefaultprofile }
-\def\usePDFXoutputintent {\dosingleempty\dousePDFXoutputintent }
+\appendtoks
+ \doifsomething{\backendparameter\c!format}
+ {\ctxlua{backends.codeinjections.setformat {
+ format = "\backendparameter\c!format",
+ level = "\backendparameter\c!level",
+ option = "\backendparameter\c!option",
+ profile = "\backendparameter\c!profile",
+ intent = "\backendparameter\c!intent",
+ }}}%
+\to \everysetupbackend
\protect \endinput
diff --git a/tex/context/base/lpdf-ren.lua b/tex/context/base/lpdf-ren.lua
index 0e4e34c2a..f942ec2c9 100644
--- a/tex/context/base/lpdf-ren.lua
+++ b/tex/context/base/lpdf-ren.lua
@@ -29,11 +29,12 @@ local executers = jobreferences.executers
local variables = interfaces.variables
-local pdfconstant = lpdf.constant
-local pdfdictionary = lpdf.dictionary
-local pdfarray = lpdf.array
-local pdfreference = lpdf.reference
-local pdfflushobject = lpdf.flushobject
+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 pdf_ocg = pdfconstant("OCG")
local pdf_ocmd = pdfconstant("OCMD")
@@ -54,23 +55,84 @@ function backends.pdf.layerreference(name)
return pdfln[name]
end
+-- only flush layers that are used
+
+--~ function codeinjections.defineviewerlayer(specification)
+--~ if textlayers then
+--~ local tag = specification.tag
+--~ -- todo: reserve
+--~ local n = pdfdictionary {
+--~ Type = pdf_ocg,
+--~ Name = specification.title or "unknown",
+--~ Intent = ((specification.kind > 0) and pdf_design) or nil, -- disable layer hiding by user
+--~ Usage = ((specification.printable == variables.no) and lpdf_usage) or nil , -- printable or not
+--~ }
+--~ local nr = pdfreference(pdfflushobject(n))
+--~ pdfln[tag] = nr -- was n
+--~ local d = pdfdictionary {
+--~ Type = pdf_ocmd,
+--~ OCGs = pdfarray { nr },
+--~ }
+--~ local dr = pdfreference(pdfflushobject(d))
+--~ pdfld[tag] = dr
+--~ textlayers[#textlayers+1] = nr
+--~ if specification.visible == variables.start then
+--~ videlayers[#videlayers+1] = nr
+--~ else
+--~ hidelayers[#hidelayers+1] = nr
+--~ end
+--~ pagelayers[tag] = dr -- check
+--~ end
+--~ end
+
+--~ local function flushtextlayers()
+--~ if textlayers and #textlayers > 0 then
+--~ local d = pdfdictionary {
+--~ OCGs = textlayers,
+--~ D = pdfdictionary {
+--~ Order = textlayers,
+--~ ON = videlayers,
+--~ OFF = hidelayers,
+--~ },
+--~ }
+--~ lpdf.addtocatalog("OCProperties",d)
+--~ textlayers = nil
+--~ end
+--~ end
+
+--~ local function flushpagelayers() -- we can share these
+--~ if next(pagelayers) then
+--~ lpdf.addtopageresources("Properties",pagelayers)
+--~ end
+--~ end
+
+local pagelayers, pagelayersreference, cache = nil, nil, { }
+
function codeinjections.defineviewerlayer(specification)
- if textlayers then
+ if viewerlayers.supported and textlayers then
+ if not pagelayers then
+ pagelayers = pdfdictionary()
+ pagelayersreference = pdfreserveobject()
+ end
local tag = specification.tag
-- todo: reserve
- local n = pdfdictionary {
+ local nn = pdfreserveobject()
+ local nr = pdfreference(nn)
+ local nd = pdfdictionary {
Type = pdf_ocg,
Name = specification.title or "unknown",
Intent = ((specification.kind > 0) and pdf_design) or nil, -- disable layer hiding by user
Usage = ((specification.printable == variables.no) and lpdf_usage) or nil , -- printable or not
}
- local nr = pdfreference(pdfflushobject(n))
+ cache[#cache+1] = { nn, nd }
pdfln[tag] = nr -- was n
- local d = pdfdictionary {
+ local dn = pdfreserveobject()
+ local dr = pdfreference(dn)
+ local dd = pdfdictionary {
Type = pdf_ocmd,
OCGs = pdfarray { nr },
}
- local dr = pdfreference(pdfflushobject(d))
+ cache[#cache+1] = { dn, dd }
pdfld[tag] = dr
textlayers[#textlayers+1] = nr
if specification.visible == variables.start then
@@ -83,23 +145,34 @@ function codeinjections.defineviewerlayer(specification)
end
local function flushtextlayers()
- if textlayers and #textlayers > 0 then
- local d = pdfdictionary {
- OCGs = textlayers,
- D = pdfdictionary {
- Order = textlayers,
- ON = videlayers,
- OFF = hidelayers,
- },
- }
- lpdf.addtocatalog("OCProperties",d)
- textlayers = nil
+ if viewerlayers.supported then
+ if pagelayers then
+ pdfflushobject(pagelayersreference,pagelayers)
+ end
+ for i=1,#cache do
+ local ci = cache[i]
+ pdfflushobject(ci[1],ci[2])
+ end
+ if textlayers and #textlayers > 0 then -- we can group them if needed, like: layout
+ local d = pdfdictionary {
+ OCGs = textlayers,
+ D = pdfdictionary {
+ Name = "Document",
+ Order = (viewerlayers.hasorder and textlayers) or nil,
+ ON = videlayers,
+ OFF = hidelayers,
+ BaseState = pdfconstant("On"),
+ },
+ }
+ lpdf.addtocatalog("OCProperties",d)
+ textlayers = nil
+ end
end
end
-local function flushpagelayers()
- if next(pagelayers) then
- lpdf.addtopageresources("Properties",pagelayers)
+local function flushpagelayers() -- we can share these
+ if pagelayers then
+ lpdf.addtopageresources("Properties",pdfreference(pagelayersreference)) -- we could cache this
end
end
diff --git a/tex/context/base/lpdf-tag.lua b/tex/context/base/lpdf-tag.lua
index 591def8b1..c5c480458 100644
--- a/tex/context/base/lpdf-tag.lua
+++ b/tex/context/base/lpdf-tag.lua
@@ -27,12 +27,14 @@ local pdfpagereference = lpdf.pagereference
local new_pdfliteral = nodes.pdfliteral
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
-local glyph = node.id("glyph")
-local glue = node.id("glue")
-local disc = node.id("disc")
-local whatsit = node.id("whatsit")
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local glyph = nodecodes.glyph
+local glue = nodecodes.glue
+local disc = nodecodes.disc
+local whatsit = nodecodes.whatsit
local a_tagged = attributes.private('tagged')
local a_image = attributes.private('image')
diff --git a/tex/context/base/luat-bwc.lua b/tex/context/base/luat-bwc.lua
new file mode 100644
index 000000000..e41f241dc
--- /dev/null
+++ b/tex/context/base/luat-bwc.lua
@@ -0,0 +1,27 @@
+if not modules then modules = { } end modules ['luat-bwc'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- backward compatibility
+
+local box = tex.box
+
+tex.wd = { } setmetatable(tex.wd, {
+ __index = function(t,k) local bk = box[k] return bk and bk.width or 0 end,
+ __newindex = function(t,k,v) local bk = box[k] if bk then bk.width = v end end,
+}
+
+tex.ht = { } setmetatable(tex.ht, {
+ __index = function(t,k) local bk = box[k] return bk and bk.height or 0 end,
+ __newindex = function(t,k,v) local bk = box[k] if bk then bk.height = v end end,
+}
+
+tex.dp = { } setmetatable(tex.dp, {
+ __index = function(t,k) local bk = box[k] return bk and bk.depth or 0 end,
+ __newindex = function(t,k,v) local bk = box[k] if bk then bk.depth = v end end,
+}
+
diff --git a/tex/context/base/luat-cod.lua b/tex/context/base/luat-cod.lua
index a5239e7ae..8d61c269a 100644
--- a/tex/context/base/luat-cod.lua
+++ b/tex/context/base/luat-cod.lua
@@ -95,6 +95,20 @@ if not environment.luafilechunk then
end
+if not environment.engineflags then
+ local engineflags = { }
+ for i=-10,#arg do
+ local a = arg[i]
+ if a then
+ local flag, content = match(a,"^%-%-([^=]+)=?(.-)$")
+ if flag then
+ engineflags[flag] = content or ""
+ end
+ end
+ end
+ environment.engineflags = engineflags
+end
+
-- We need a few premature callbacks in the format generator. We
-- also do this when the format is loaded as otherwise we get
-- a kpse error when disabled. Thi sis en angine issue that will
diff --git a/tex/context/base/luat-fmt.lua b/tex/context/base/luat-fmt.lua
index d9c0e38c8..07a7a1490 100644
--- a/tex/context/base/luat-fmt.lua
+++ b/tex/context/base/luat-fmt.lua
@@ -8,6 +8,21 @@ if not modules then modules = { } end modules ['luat-fmt'] = {
-- helper for mtxrun
+local quote = string.quote
+
+local function primaryflags()
+ local trackers = environment.argument("trackers")
+ local directives = environment.argument("directives")
+ local flags = ""
+ if trackers and trackers ~= "" then
+ flags = flags .. "--trackers=" .. quote(trackers)
+ end
+ if directives and directives ~= "" then
+ flags = flags .. "--directives=" .. quote(directives)
+ end
+ return flags
+end
+
function environment.make_format(name)
-- change to format path (early as we need expanded paths)
local olddir = lfs.currentdir()
@@ -68,8 +83,7 @@ function environment.make_format(name)
return
end
-- generate format
- local q = string.quote
- local command = string.format("luatex --ini --lua=%s %s %sdump",q(usedluastub),q(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
+ local command = string.format("luatex --ini %s --lua=%s %s %sdump",primaryflags(),quote(usedluastub),quote(fulltexsourcename),os.platform == "unix" and "\\\\" or "\\")
logs.simple("running command: %s\n",command)
os.spawn(command)
-- remove related mem files
@@ -108,7 +122,7 @@ function environment.run_format(name,data,more)
logs.simple("no luc/lua with name: %s",barename)
else
local q = string.quote
- local command = string.format("luatex --fmt=%s --lua=%s %s %s",q(barename),q(luaname),q(data),more ~= "" and q(more) or "")
+ local command = string.format("luatex %s --fmt=%s --lua=%s %s %s",primaryflags(),quote(barename),quote(luaname),quote(data),more ~= "" and quote(more) or "")
logs.simple("running command: %s",command)
os.spawn(command)
end
diff --git a/tex/context/base/luat-lib.mkiv b/tex/context/base/luat-lib.mkiv
index 2a9d5ecd3..3018d32e2 100644
--- a/tex/context/base/luat-lib.mkiv
+++ b/tex/context/base/luat-lib.mkiv
@@ -51,6 +51,7 @@
\registerctxluafile{luat-env}{1.001}
\registerctxluafile{luat-exe}{1.001}
\registerctxluafile{luat-iop}{1.001}
+\registerctxluafile{luat-bwc}{1.001}
\registerctxluafile{lxml-tab}{1.001}
\registerctxluafile{lxml-lpt}{1.001}
diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua
index c3ec2370a..983d631e9 100644
--- a/tex/context/base/lxml-lpt.lua
+++ b/tex/context/base/lxml-lpt.lua
@@ -145,17 +145,19 @@ apply_axis['child'] = function(list)
for l=1,#list do
local ll = list[l]
local dt = ll.dt
- local en = 0
- for k=1,#dt do
- local dk = dt[k]
- if dk.tg then
- collected[#collected+1] = dk
- dk.ni = k -- refresh
- en = en + 1
- dk.ei = en
+ if dt then -- weird that this is needed
+ local en = 0
+ for k=1,#dt do
+ local dk = dt[k]
+ if dk.tg then
+ collected[#collected+1] = dk
+ dk.ni = k -- refresh
+ en = en + 1
+ dk.ei = en
+ end
end
+ ll.en = en
end
- ll.en = en
end
return collected
end
diff --git a/tex/context/base/lxml-xml.lua b/tex/context/base/lxml-xml.lua
index f791ec0f8..6080e4207 100644
--- a/tex/context/base/lxml-xml.lua
+++ b/tex/context/base/lxml-xml.lua
@@ -10,6 +10,7 @@ local finalizers = xml.finalizers.xml
local xmlfilter = xml.filter -- we could inline this one for speed
local xmltostring = xml.tostring
local xmlserialize = xml.serialize
+local xmlcollected = xml.collected
local function first(collected) -- wrong ?
return collected and collected[1]
@@ -286,3 +287,16 @@ end
xml.all = xml.filter
xml.index = xml.position
xml.found = xml.filter
+
+-- a nice one:
+
+local function totable(x)
+ local t = { }
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg] = xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
+end
+
+xml.table = totable
+finalizers.table = totable
diff --git a/tex/context/base/m-punk.mkiv b/tex/context/base/m-punk.mkiv
index 6099ee6f4..3ea738003 100644
--- a/tex/context/base/m-punk.mkiv
+++ b/tex/context/base/m-punk.mkiv
@@ -17,190 +17,195 @@
% ConTeXt MkIV kernel.
\startluacode
-do
- local concat = table.concat
- local chardata = characters.data
- local fontdata = fonts.ids
+local concat = table.concat
+local chardata = characters.data
+local fontdata = fonts.ids
- fonts.mp = fonts.mp or { }
+fonts.mp = fonts.mp or { }
- fonts.mp.version = fonts.mp.version or 1.11
- fonts.mp.inline = true
- fonts.mp.cache = containers.define("fonts", "mp", fonts.mp.version, true)
+fonts.mp.version = fonts.mp.version or 1.15
+fonts.mp.inline = true
+fonts.mp.cache = containers.define("fonts", "mp", fonts.mp.version, true)
- metapost.characters = metapost.characters or { }
+metapost.characters = metapost.characters or { }
-- todo: use table share as in otf
- local characters, descriptions = { }, { }
- local factor, l, n, w, h, d, total, variants = 100, { }, 0, 0, 0, 0, 0, 0, true
-
- -- A next version of mplib will provide the tfm font information which
- -- gives better glyph dimensions, plus additional kerning information.
-
- local flusher = {
- startfigure = function(chrnum,llx,lly,urx,ury)
- l, n = { }, chrnum
- w, h, d = urx - llx, ury, -lly
- total = total + 1
- inline = fonts.mp.inline
- end,
- flushfigure = function(t)
- for i=1, #t do
- l[#l+1] = t[i]
- end
- end,
- stopfigure = function()
- local cd = chardata[n]
- if inline then
- descriptions[n] = {
- -- unicode = n,
- name = cd and cd.adobename,
- width = w*100,
- height = h*100,
- depth = d*100,
- boundingbox = { 0, -d, w, h },
- }
- characters[n] = {
- commands = { -- todo: xforms, should happen in backend
- { "special", "pdf: " .. concat(l," ") },
- }
- }
- else
- descriptions[n] = {
- -- unicode = n,
- name = cd and cd.adobename,
- width = w*100,
- height = h*100,
- depth = d*100,
- boundingbox = { 0, -d, w, h },
- }
- characters[n] = {
- commands = {
- { "image", { stream = concat(l," "), bbox = { 0, -d*65536, w*65536, h*65536 } } },
- }
- }
- end
+local characters, descriptions = { }, { }
+local factor, l, n, w, h, d, total, variants = 100, { }, 0, 0, 0, 0, 0, 0, true
+
+-- A next version of mplib will provide the tfm font information which
+-- gives better glyph dimensions, plus additional kerning information.
+
+local flusher = {
+ startfigure = function(chrnum,llx,lly,urx,ury)
+ l, n = { }, chrnum
+ w, h, d = urx - llx, ury, -lly
+ total = total + 1
+ inline = fonts.mp.inline
+ end,
+ flushfigure = function(t)
+ for i=1, #t do
+ l[#l+1] = t[i]
end
- }
-
- metapost.characters.instances = metapost.characters.instances or 10
-
- function metapost.characters.process(mpxformat, name, instances, scalefactor)
- statistics.starttiming(metapost.characters)
- scalefactor = scalefactor or 1
- instances = instances or metapost.characters.instances or 10
- local fontname = file.removesuffix(file.basename(name))
- local hash = file.robustname(string.format("%s %05i %03i", fontname, scalefactor*1000, instances))
- local lists = containers.read(fonts.mp.cache, hash)
- if not lists then
- statistics.starttiming(flusher)
- -- we can use a format per font
- local data = io.loaddata(resolvers.find_file(name))
- metapost.reset(mpxformat)
- metapost.set_outer_color(2) -- no outer color and no reset either
- lists = { }
- for i=1,instances do
- list = { }
- characters, descriptions = { }, { }
- metapost.process(
- mpxformat,
- {
- "randomseed := " .. i*10 .. ";",
- "scale_factor := " .. scalefactor .. " ;",
- data
- },
- false,
- flusher
- )
- lists[i] = {
- designsize = 655360,
- name = string.format("%s-%03i",hash,i),
- parameters = {
- slant = 0,
- space = 333 * scalefactor,
- space_stretch = 166.5 * scalefactor,
- space_shrink = 111 * scalefactor,
- x_height = 431 * scalefactor,
- quad =1000 * scalefactor,
- extra_space = 0
- },
- ["type"] = "virtual",
- characters = characters,
- descriptions = descriptions,
- -- embedding = "subset",
- -- mkiv:
- spacer = "space",
- unit = 1000,
- shared = { },
- unique = { },
+ end,
+ stopfigure = function()
+ local cd = chardata[n]
+ if inline then
+ descriptions[n] = {
+ -- unicode = n,
+ name = cd and cd.adobename,
+ width = w*100,
+ height = h*100,
+ depth = d*100,
+ boundingbox = { 0, -d, w, h },
+ }
+ characters[n] = {
+ commands = { -- todo: xforms, should happen in backend
+ { "special", "pdf: " .. concat(l," ") },
}
- end
- metapost.reset(mpxformat) -- saves memory
- lists = containers.write(fonts.mp.cache, hash, lists)
- statistics.stoptiming(flusher)
+ }
+ else
+ descriptions[n] = {
+ -- unicode = n,
+ name = cd and cd.adobename,
+ width = w*100,
+ height = h*100,
+ depth = d*100,
+ boundingbox = { 0, -d, w, h },
+ }
+ characters[n] = {
+ commands = {
+ { "image", { stream = concat(l," "), bbox = { 0, -d*65536, w*65536, h*65536 } } },
+ }
+ }
end
- variants = variants + #lists
- statistics.stoptiming(metapost.characters)
- return lists
end
-
- function fonts.vf.aux.combine.commands.metafont(g,v)
- local size = g.specification.size
- local data = metapost.characters.process(v[2],v[3],v[4],size/655360)
- local list, t = { }, { }
- for d=1,#data do
- t = data[d]
- t = fonts.tfm.scale(t, -1000)
- local id = font.nextid()
- t.fonts = { { id = id } }
- fontdata[id] = t
- fonts.vf.aux.compose_characters(t)
- list[d] = font.define(t)
+}
+
+metapost.characters.instances = metapost.characters.instances or 10
+
+function metapost.characters.process(mpxformat, name, instances, scalefactor)
+ statistics.starttiming(metapost.characters)
+ scalefactor = scalefactor or 1
+ instances = instances or metapost.characters.instances or 10
+ local fontname = file.removesuffix(file.basename(name))
+ local hash = file.robustname(string.format("%s %05i %03i", fontname, scalefactor*1000, instances))
+ local lists = containers.read(fonts.mp.cache, hash)
+ if not lists then
+ statistics.starttiming(flusher)
+ -- we can use a format per font
+ local data = io.loaddata(resolvers.find_file(name))
+ metapost.reset(mpxformat)
+ metapost.set_outer_color(2) -- no outer color and no reset either
+ lists = { }
+ for i=1,instances do
+ characters, descriptions = { }, { }
+ metapost.process(
+ mpxformat,
+ {
+ "randomseed := " .. i*10 .. ";",
+ "scale_factor := " .. scalefactor .. " ;",
+ data
+ },
+ false,
+ flusher
+ )
+ lists[i] = {
+ designsize = 655360,
+ name = string.format("%s-%03i",hash,i),
+ parameters = {
+ slant = 0,
+ space = 333 * scalefactor,
+ space_stretch = 166.5 * scalefactor,
+ space_shrink = 111 * scalefactor,
+ x_height = 431 * scalefactor,
+ quad =1000 * scalefactor,
+ extra_space = 0
+ },
+ ["type"] = "virtual",
+ characters = characters,
+ descriptions = descriptions,
+ -- embedding = "subset",
+ -- mkiv:
+ spacer = "space",
+ unit = 1000,
+ shared = { },
+ unique = { },
+ }
end
- for k=1,#t do
- g[k] = t[k] -- kind of replace, when not present, make nil
- end
- g.virtualized = true
- g.variants = list
+ metapost.reset(mpxformat) -- saves memory
+ lists = containers.write(fonts.mp.cache, hash, lists)
+ statistics.stoptiming(flusher)
end
+ variants = variants + #lists
+ statistics.stoptiming(metapost.characters)
+ return lists
+end
- fonts.define.methods.install( "punk", {
- { "metafont", "mfplain", "punkfont.mp", 10 },
- } )
-
- typesetting.cases.actions[99] = function(current)
- local used = fontdata[current.font].variants
- if used then
- local f = math.random(1,#used)
- current.font = used[f]
- return current, true
- else
- return current, false
- end
+function fonts.vf.aux.combine.commands.metafont(g,v)
+ local size = g.specification.size
+ local data = metapost.characters.process(v[2],v[3],v[4],size/655360)
+ local list, t = { }, { }
+ for d=1,#data do
+ t = data[d]
+ t = fonts.tfm.scale(t, -1000)
+ local id = font.nextid()
+ t.fonts = { { id = id } }
+ fontdata[id] = t
+ fonts.vf.aux.compose_characters(t)
+ list[d] = font.define(t)
end
+ for k, v in next, t do
+ g[k] = v -- kind of replace, when not present, make nil
+ end
+ g.virtualized = true
+ g.variants = list
+end
- metapost.characters.flusher = flusher
-
- statistics.register("metapost font generation", function()
- local time = statistics.elapsedtime(flusher)
- if total > 0 then
- return string.format("%i glyphs, %.3f seconds runtime, %i glyphs/second", total, time, total/time)
- else
- return string.format("%i glyphs, %.3f seconds runtime", total, time)
- end
- end)
+fonts.define.methods.install( "punk", {
+ { "metafont", "mfplain", "punkfont.mp", 10 },
+} )
+fonts.define.methods.install( "punkbold", {
+ { "metafont", "mfplain", "punkfont-bold.mp", 10 },
+} )
+fonts.define.methods.install( "punkslanted", {
+ { "metafont", "mfplain", "punkfont-slanted.mp", 10 },
+} )
+fonts.define.methods.install( "punkboldslanted", {
+ { "metafont", "mfplain", "punkfont-boldslanted.mp", 10 },
+} )
+
+typesetting.cases.actions[99] = function(current)
+ local used = fontdata[current.font].variants
+ if used then
+ local f = math.random(1,#used)
+ current.font = used[f]
+ return current, true
+ else
+ return current, false
+ end
+end
- statistics.register("metapost font loading",function()
- local time = statistics.elapsedtime(metapost.characters)
- if variants > 0 then
- return string.format("%.3f seconds, %i instances, %0.3f instances/second", time, variants, variants/time)
- else
- return string.format("%.3f seconds, %i instances", time, variants)
- end
- end)
+metapost.characters.flusher = flusher
-end
+statistics.register("metapost font generation", function()
+ local time = statistics.elapsedtime(flusher)
+ if total > 0 then
+ return string.format("%i glyphs, %.3f seconds runtime, %i glyphs/second", total, time, total/time)
+ else
+ return string.format("%i glyphs, %.3f seconds runtime", total, time)
+ end
+end)
+
+statistics.register("metapost font loading",function()
+ local time = statistics.elapsedtime(metapost.characters)
+ if variants > 0 then
+ return string.format("%.3f seconds, %i instances, %0.3f instances/second", time, variants, variants/time)
+ else
+ return string.format("%.3f seconds, %i instances", time, variants)
+ end
+end)
\stopluacode
\unexpanded\def\EnableRandomPunk {\setcharactercasing[99]}
@@ -209,25 +214,18 @@ end
\unexpanded\def\StopRandomPunk {\endgroup}
\starttypescript [serif] [punk] [default]
- \setups[font:fallback:serif] % no style variants yet
- \definefontsynonym [Serif] [demo@punk]
+ \definefontsynonym [Serif] [demo@punk]
+ \definefontsynonym [SerifBold] [demobold@punkbold]
+ \definefontsynonym [SerifSlanted] [demoslanted@punkslanted]
+ \definefontsynonym [SerifBoldSlanted] [demoboldslanted@punkboldslanted]
+ \definefontsynonym [SerifItalic] [SerifSlanted]
+ \definefontsynonym [SerifBoldItalic] [SerifBoldSlanted]
\stoptypescript
\starttypescript [punk]
\definetypeface [punk] [rm] [serif] [punk] [default]
\stoptypescript
-% \definefontfeature[punknova][mode=node,script=latn,rand=yes,kern=yes,liga=yes,tlig=yes]
-
-% \starttypescript [serif] [punknova]
-% \setups[font:fallback:serif] % no style variants yet, actually it's a sans
-% \definefontsynonym [Serif] [file:punknova] [features=punknova]
-% \stoptypescript
-
-% \starttypescript [punknova]
-% \definetypeface [punknova] [rm] [serif] [punknova] [default]
-% \stoptypescript
-
\endinput
\usetypescript[punk]
diff --git a/tex/context/base/m-units.tex b/tex/context/base/m-units.tex
index d186c542b..36fa45d84 100644
--- a/tex/context/base/m-units.tex
+++ b/tex/context/base/m-units.tex
@@ -377,6 +377,17 @@
\def\Peta {\dimensionprefix{P}}
\def\Exa {\dimensionprefix{E}}
+%D and binary prefixes:
+
+\def\Kibi {\dimensionprefix{Ki}}
+\def\Mebi {\dimensionprefix{Mi}}
+\def\Gibi {\dimensionprefix{Gi}}
+\def\Tebi {\dimensionprefix{Ti}}
+\def\Pebi {\dimensionprefix{Pi}}
+\def\Exbi {\dimensionprefix{Ei}}
+\def\Zebi {\dimensionprefix{Zi}}
+\def\Yobi {\dimensionprefix{Yi}}
+
%D and operators:
\def\Times {\dimensionnopfix{\iftextdimensions.\else\cdot\fi}}
@@ -384,7 +395,7 @@
\def\Per {\dimensionmidfix{/}}
\def\OutOf {\dimensionnopfix{:}}
-%D and suffixes:
+%D and suffixes:
\def\Linear {\dimensionpower{1}}
\def\Square {\dimensionpower{2}}
@@ -665,10 +676,10 @@
%D Computer memory is specified in Bytes:
-\getvalue{\v!unit} [Baud] {Baud} {Baud (Bit/s)}
-\getvalue{\v!unit} [Bit] {Bit} {Bit}
+\getvalue{\v!unit} [Bit] {bit} {Bit}
+\getvalue{\v!unit} [Baud] {Bd} {Baud (Bit/s)}
-\getvalue{\v!unit} [Byte] {Byte} {Byte}
+\getvalue{\v!unit} [Byte] {B} {Byte}
\getvalue{\v!unit} [kByte] {\Kilo \Byte} {kilo Byte}
\getvalue{\v!unit} [MByte] {\Mega \Byte} {mega Byte}
\getvalue{\v!unit} [GByte] {\Giga \Byte} {giga Byte}
diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua
index 2b4f9b6fa..19cc94ea7 100644
--- a/tex/context/base/math-noa.lua
+++ b/tex/context/base/math-noa.lua
@@ -19,6 +19,7 @@ local has_attribute = node.has_attribute
local mlist_to_hlist = node.mlist_to_hlist
local font_of_family = node.family_font
local fontdata = fonts.identifiers
+local nodecodes = nodes.nodecodes
local format, rep = string.format, string.rep
local utfchar, utfbyte = utf.char, utf.byte
@@ -31,6 +32,8 @@ local trace_analyzing = false trackers.register("math.analyzing", function(v)
local report_noads = logs.new("mathematics")
+-- todo: nodes.noadcodes
+
local noad_ord = 0
local noad_op_displaylimits = 1
local noad_op_limits = 2
@@ -47,34 +50,34 @@ local noad_vcenter = 12
-- obsolete:
--
--- math_ord = node.id("ord") -- attr nucleus sub sup
--- math_op = node.id("op") -- attr nucleus sub sup subtype
--- math_bin = node.id("bin") -- attr nucleus sub sup
--- math_rel = node.id("rel") -- attr nucleus sub sup
--- math_punct = node.id("punct") -- attr nucleus sub sup
---
--- math_open = node.id("open") -- attr nucleus sub sup
--- math_close = node.id("close") -- attr nucleus sub sup
---
--- math_inner = node.id("inner") -- attr nucleus sub sup
--- math_vcenter = node.id("vcenter") -- attr nucleus sub sup
--- math_under = node.id("under") -- attr nucleus sub sup
--- math_over = node.id("over") -- attr nucleus sub sup
-
-local math_noad = node.id("noad") -- attr nucleus sub sup
-
-local math_accent = node.id("accent") -- attr nucleus sub sup accent
-local math_radical = node.id("radical") -- attr nucleus sub sup left degree
-local math_fraction = node.id("fraction") -- attr nucleus sub sup left right
-
-local math_box = node.id("sub_box") -- attr list
-local math_sub = node.id("sub_mlist") -- attr list
-local math_char = node.id("math_char") -- attr fam char
-local math_text_char = node.id("math_text_char") -- attr fam char
-local math_delim = node.id("delim") -- attr small_fam small_char large_fam large_char
-local math_style = node.id("style") -- attr style
-local math_choice = node.id("choice") -- attr display text script scriptscript
-local math_fence = node.id("fence") -- attr subtype
+-- math_ord = nodecodes.ord") -- attr nucleus sub sup
+-- math_op = nodecodes.op") -- attr nucleus sub sup subtype
+-- math_bin = nodecodes.bin") -- attr nucleus sub sup
+-- math_rel = nodecodes.rel") -- attr nucleus sub sup
+-- math_punct = nodecodes.punct") -- attr nucleus sub sup
+--_
+-- math_open = nodecodes.open") -- attr nucleus sub sup
+-- math_close = nodecodes.close") -- attr nucleus sub sup
+--_
+-- math_inner = nodecodes.inner") -- attr nucleus sub sup
+-- math_vcenter = nodecodes.vcenter") -- attr nucleus sub sup
+-- math_under = nodecodes.under") -- attr nucleus sub sup
+-- math_over = nodecodes.over") -- attr nucleus sub sup
+
+local math_noad = nodecodes.noad -- attr nucleus sub sup
+
+local math_accent = nodecodes.accent -- attr nucleus sub sup accent
+local math_radical = nodecodes.radical -- attr nucleus sub sup left degree
+local math_fraction = nodecodes.fraction -- attr nucleus sub sup left right
+
+local math_box = nodecodes.sub_box -- attr list
+local math_sub = nodecodes.sub_mlist -- attr list
+local math_char = nodecodes.math_char -- attr fam char
+local math_text_char = nodecodes.math_text_char -- attr fam char
+local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char
+local math_style = nodecodes.style -- attr style
+local math_choice = nodecodes.choice -- attr display text script scriptscript
+local math_fence = nodecodes.fence -- attr subtype
local simple_noads = table.tohash {
math_noad,
@@ -366,7 +369,7 @@ end
fonts.otf.tables.features['mathalternates'] = 'Additional math alternative shapes'
-fonts.otf.features.register('mathalternates',true)
+fonts.otf.features.register('mathalternates') -- true
table.insert(fonts.triggers,"mathalternates")
fonts.initializers.base.otf.mathalternates = fonts.initializers.common.mathalternates
diff --git a/tex/context/base/math-tag.lua b/tex/context/base/math-tag.lua
index 7180435f5..7960c014f 100644
--- a/tex/context/base/math-tag.lua
+++ b/tex/context/base/math-tag.lua
@@ -9,26 +9,27 @@ if not modules then modules = { } end modules ['math-tag'] = {
local has_attribute = nodes.has_attribute
local set_attribute = nodes.set_attribute
local set_attributes = nodes.set_attributes
-
local traverse_nodes = node.traverse
-local math_noad = node.id("noad") -- attr nucleus sub sup
-local math_noad = node.id("noad") -- attr nucleus sub sup
-local math_accent = node.id("accent") -- attr nucleus sub sup accent
-local math_radical = node.id("radical") -- attr nucleus sub sup left degree
-local math_fraction = node.id("fraction") -- attr nucleus sub sup left right
-local math_box = node.id("sub_box") -- attr list
-local math_sub = node.id("sub_mlist") -- attr list
-local math_char = node.id("math_char") -- attr fam char
-local math_text_char = node.id("math_text_char") -- attr fam char
-local math_delim = node.id("delim") -- attr small_fam small_char large_fam large_char
-local math_style = node.id("style") -- attr style
-local math_choice = node.id("choice") -- attr display text script scriptscript
-local math_fence = node.id("fence") -- attr subtype
+local nodecodes = nodes.nodecodes
+
+local math_noad = nodecodes.noad -- attr nucleus sub sup
+local math_noad = nodecodes.noad -- attr nucleus sub sup
+local math_accent = nodecodes.accent -- attr nucleus sub sup accent
+local math_radical = nodecodes.radical -- attr nucleus sub sup left degree
+local math_fraction = nodecodes.fraction -- attr nucleus sub sup left right
+local math_box = nodecodes.sub_box -- attr list
+local math_sub = nodecodes.sub_mlist -- attr list
+local math_char = nodecodes.math_char -- attr fam char
+local math_text_char = nodecodes.math_text_char -- attr fam char
+local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char
+local math_style = nodecodes.style -- attr style
+local math_choice = nodecodes.choice -- attr display text script scriptscript
+local math_fence = nodecodes.fence -- attr subtype
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
-local glyph = node.id("glyph")
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local glyph = nodecodes.glyph
local a_tagged = attributes.private('tagged')
diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv
index 1072cb8f2..c44be4282 100644
--- a/tex/context/base/meta-ini.mkiv
+++ b/tex/context/base/meta-ini.mkiv
@@ -199,36 +199,10 @@
{\let\handleuseMPgraphic \thirdofthreearguments
\let\handlereusableMPgraphic\thirdofthreearguments}
-\let\MPdrawingdata\empty
-
\newif\ifMPdrawingdone \MPdrawingdonefalse
-\def\resetMPdrawing
- {\globallet\MPdrawingdata\empty
- \global\MPdrawingdonefalse}
-
-\def\pushMPdrawing
- {\globalpushmacro\MPdrawingdata
- \globallet\MPdrawingdata\empty}
-
-\def\popMPdrawing
- {\globalpopmacro\MPdrawingdata}
-
-\def\getMPdrawing{\dosinglegroupempty\dogetMPdrawing}
-
-\def\startMPdrawing
- {\dosingleempty\dostartMPdrawing}
-
-\long\def\dostartMPdrawing[#1]#2\stopMPdrawing
- {\relax
- \bgroup
- \enableincludeMPgraphics
- \presetMPdefinitions % in case #2 has measures
- \doifelse{#1}{-}{\convertargument#2\to\asciia}{\long\def\asciia{#2}}%
- \long\xdef\MPdrawingdata{\MPdrawingdata\asciia}%
- \egroup}
-
-\let\stopMPdrawing\relax
+\def\finalizeMPdrawing
+ {\MPdrawingdonetrue}
\let\MPdrawingdata\empty
@@ -264,6 +238,14 @@
\let\stopMPdrawing\relax
+\long\def\MPdrawing#1%
+ {\relax
+ \bgroup
+ \enableincludeMPgraphics
+ \presetMPdefinitions
+ \long\xdef\MPdrawingdata{\MPdrawingdata#1}%
+ \egroup}
+
\let\stopMPclip\relax
\long\def\startMPclip#1#2\stopMPclip % todo: store at the lua end or just store less
@@ -771,6 +753,23 @@
\let\stopMPcode\relax
+\def\MPcode{\dosinglegroupempty\doMPcode}
+
+\def\doMPcode
+ {\iffirstargument
+ \expandafter\dodoMPcode
+ \else
+ \expandafter\nodoMPcode
+ \fi}
+
+\def\dodoMPcode#1#2%
+ {\beginMPgraphicgroup{#1::\s!dummy}% name does not matter
+ \processMPgraphic{#2}%
+ \endMPgraphicgroup}
+
+\def\nodoMPcode#1#2%
+ {\processMPgraphic{#2}}
+
% a bit nasty (also needed for compatibility:
% \startMPrun input mp-www.mp ; \stopMPrun
diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua
index f00c99cdb..9d6b4eb7a 100644
--- a/tex/context/base/mlib-pps.lua
+++ b/tex/context/base/mlib-pps.lua
@@ -278,23 +278,12 @@ end
--
-- normalize(ca,cb) fails for spotcolors
-function metapost.specials.cs(specification,object,result,flusher) -- spot colors?
- -- a mess, not dynamic anyway
- nofshades = nofshades + 1
- flusher.flushfigure(result)
- result = { }
- local t = lpegmatch(specificationsplitter,specification)
- -- we need a way to move/scale
- local ca = lpegmatch(colorsplitter,t[4])
- local cb = lpegmatch(colorsplitter,t[8])
+local function checkandconvert(ca,cb)
+ local name = format("MpSh%s",nofshades)
if round(ca[1]*10000) == 123 then ca = metapost.colorspec(ca) end
if round(cb[1]*10000) == 123 then cb = metapost.colorspec(cb) end
- local name = format("MplSh%s",nofshades)
- local domain = { tonumber(t[1]), tonumber(t[2]) }
- local coordinates = { tonumber(t[5]), tonumber(t[6]), tonumber(t[7]), tonumber(t[9]), tonumber(t[10]), tonumber(t[11]) }
if type(ca) == "string" then
- -- backend specific (will be renamed)
- lpdf.circularshade(name,domain,{ 0 },{ 1 },1,"DeviceGray",coordinates)
+ return { 0 }, { 1 }, "DeviceGray", name
else
if #ca > #cb then
normalize(ca,cb)
@@ -307,38 +296,43 @@ function metapost.specials.cs(specification,object,result,flusher) -- spot color
end
if model == "rgb" then
if #ca == 4 then
- ca[1], ca[2], ca[3] = cmyktorgb(ca[1],ca[2],ca[3],ca[4])
- cb[1], cb[2], cb[3] = cmyktorgb(cb[1],cb[2],cb[3],cb[4])
- ca[4], cb[4] = nil, nil
+ ca = { cmyktorgb(ca[1],ca[2],ca[3],ca[4]) }
+ cb = { cmyktorgb(cb[1],cb[2],cb[3],cb[4]) }
elseif #ca == 1 then
local a, b = 1-ca[1], 1-cb[1]
- ca[1], ca[2], ca[3] = a, a, a
- cb[1], cb[2], cb[3] = b, b, b
+ ca = { a, a, a }
+ cb = { b, b, b }
end
- -- backend specific (will be renamed)
- lpdf.circularshade(name,domain,ca,cb,1,"DeviceRGB",coordinates)
+ return ca, cb, "DeviceRGB", name
elseif model == "cmyk" then
if #ca == 3 then
- ca[1], ca[2], ca[3], ca[4] = rgbtocmyk(ca[1],ca[2],ca[3])
- cb[1], cb[2], cb[3], ca[4] = rgbtocmyk(cb[1],cb[2],cb[3])
+ ca = { rgbtocmyk(ca[1],ca[2],ca[3]) }
+ cb = { rgbtocmyk(cb[1],cb[2],cb[3]) }
elseif #ca == 1 then
- ca[1], ca[2], ca[3], ca[4] = 0, 0, 0, ca[1]
- cb[1], cb[2], cb[3], ca[4] = 0, 0, 0, ca[1]
+ ca = { 0, 0, 0, ca[1] }
+ cb = { 0, 0, 0, ca[1] }
end
- -- backend specific (will be renamed)
- lpdf.circularshade(name,domain,ca,cb,1,"DeviceCMYK",coordinates)
+ return ca, cb, "DeviceCMYK", name
else
if #ca == 4 then
- ca[1] = cmyktogray(ca[1],ca[2],ca[3],ca[4])
- cb[1] = cmyktogray(cb[1],cb[2],cb[3],cb[4])
+ ca = { cmyktogray(ca[1],ca[2],ca[3],ca[4]) }
+ cb = { cmyktogray(cb[1],cb[2],cb[3],cb[4]) }
elseif #ca == 3 then
- ca[1] = rgbtogray(ca[1],ca[2],ca[3])
- cb[1] = rgbtogray(cb[1],cb[2],cb[3])
+ ca = { rgbtogray(ca[1],ca[2],ca[3]) }
+ cb = { rgbtogray(cb[1],cb[2],cb[3]) }
end
-- backend specific (will be renamed)
- lpdf.circularshade(name,domain,ca,cb,1,"DeviceGRAY",coordinates)
+ return ca, cb, "DeviceGray", name
end
end
+end
+
+local function resources(object,name,flusher,result)
+ -- There is no real need for flushing in between, so:
+ --
+ -- flusher.flushfigure(result)
+ -- local result = { }
+ --
local before = function()
result[#result+1] = "q /Pattern cs"
return object, result
@@ -351,75 +345,30 @@ function metapost.specials.cs(specification,object,result,flusher) -- spot color
return object, before, nil, after
end
+-- todo: we need a way to move/scale
+
+function metapost.specials.cs(specification,object,result,flusher) -- spot colors?
+ nofshades = nofshades + 1
+ local t = lpegmatch(specificationsplitter,specification)
+ local ca = lpegmatch(colorsplitter,t[4])
+ local cb = lpegmatch(colorsplitter,t[8])
+ local domain = { tonumber(t[1]), tonumber(t[2]) }
+ local coordinates = { tonumber(t[5]), tonumber(t[6]), tonumber(t[7]), tonumber(t[9]), tonumber(t[10]), tonumber(t[11]) }
+ local ca, cb, colorspace, name = checkandconvert(ca,cb)
+ lpdf.circularshade(name,domain,ca,cb,1,colorspace,coordinates) -- backend specific (will be renamed)
+ return resources(object,name,flusher,result) -- object, before, nil, after
+end
+
function metapost.specials.ls(specification,object,result,flusher)
nofshades = nofshades + 1
- flusher.flushfigure(result)
- result = { }
local t = lpegmatch(specificationsplitter,specification)
- -- we need a way to move/scale
local ca = lpegmatch(colorsplitter,t[4])
local cb = lpegmatch(colorsplitter,t[7])
- if round(ca[1]*10000) == 123 then ca = metapost.colorspec(ca) end
- if round(cb[1]*10000) == 123 then cb = metapost.colorspec(cb) end
- local name = format("MpSh%s",nofshades)
local domain = { tonumber(t[1]), tonumber(t[2]) }
local coordinates = { tonumber(t[5]), tonumber(t[6]), tonumber(t[8]), tonumber(t[9]) }
- if type(ca) == "string" then
- -- backend specific (will be renamed)
- lpdf.linearshade(name,domain,{ 0 },{ 1 },1,"DeviceGray",coordinates)
- else
- if #ca > #cb then
- normalize(ca,cb)
- elseif #ca < #cb then
- normalize(cb,ca)
- end
- local model = colors.model
- if model == "all" then
- model= (#ca == 4 and "cmyk") or (#ca == 3 and "rgb") or "gray"
- end
- if model == "rgb" then
- if #ca == 4 then
- ca[1], ca[2], ca[3] = cmyktorgb(ca[1],ca[2],ca[3],ca[4])
- cb[1], cb[2], cb[3] = cmyktorgb(cb[1],cb[2],cb[3],cb[4])
- elseif #ca == 1 then
- local a, b = 1-ca[1], 1-cb[1]
- ca[1], ca[2], ca[3] = a, a, a
- cb[1], cb[2], cb[3] = b, b, b
- end
- -- backend specific (will be renamed)
- lpdf.linearshade(name,domain,ca,cb,1,"DeviceRGB",coordinates)
- elseif model == "cmyk" then
- if #ca == 3 then
- ca[1], ca[2], ca[3], ca[4] = rgbtocmyk(ca[1],ca[2],ca[3])
- cb[1], cb[2], cb[3], ca[4] = rgbtocmyk(cb[1],cb[2],cb[3])
- elseif #ca == 1 then
- ca[1], ca[2], ca[3], ca[4] = 0, 0, 0, ca[1]
- cb[1], cb[2], cb[3], ca[4] = 0, 0, 0, ca[1]
- end
- -- backend specific (will be renamed)
- lpdf.linearshade(name,domain,ca,cb,1,"DeviceCMYK",coordinates)
- else
- if #ca == 4 then
- ca[1] = cmyktogray(ca[1],ca[2],ca[3],ca[4])
- cb[1] = cmyktogray(cb[1],cb[2],cb[3],cb[4])
- elseif #ca == 3 then
- ca[1] = rgbtogray(ca[1],ca[2],ca[3])
- cb[1] = rgbtogray(cb[1],cb[2],cb[3])
- end
- -- backend specific (will be renamed)
- lpdf.linearshade(name,domain,ca,cb,1,"DeviceGRAY",coordinates)
- end
- end
- local before = function()
- result[#result+1] = "q /Pattern cs"
- return object, result
- end
- local after = function()
- result[#result+1] = format("W n /%s sh Q", name)
- return object, result
- end
- object.color, object.type = nil, nil
- return object, before, nil, after
+ local ca, cb, colorspace, name = checkandconvert(ca,cb)
+ lpdf.linearshade(name,domain,ca,cb,1,colorspace,coordinates) -- backend specific (will be renamed)
+ return resources(object,name,flusher,result) -- object, before, nil, after
end
-- no need for a before here
diff --git a/tex/context/base/mult-aux.mkiv b/tex/context/base/mult-aux.mkiv
new file mode 100644
index 000000000..c364c3507
--- /dev/null
+++ b/tex/context/base/mult-aux.mkiv
@@ -0,0 +1,165 @@
+%D \module
+%D [ file=mult-aux,
+%D version=2010.08.2,
+%D title=\CONTEXT\ Multilingual Macros,
+%D subtitle=Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright=PRAGMA]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D A generalization of \MKIV-like inheritance. Just something to play
+%D with (interface might change).
+
+\unprotect
+
+%D \starttyping
+%D \unprotect
+%D \def\????aa{@@@@aa}
+%D
+%D \installparameterhandler \????aa {whatever}
+%D \installsetuphandler \????aa {whatever}
+%D \installdefinehandler \????aa {whatever} \????aa % #3 == defaultroot
+%D \installattributehandler \????aa {whatever}
+%D
+%D % \installcommandhandler \????aa {whatever} \????aa
+%D \protect
+%D
+%D % \whateverparameter \c!test
+%D % \whateverparameterhash \c!test
+%D % \namedwhateverparameter \mycurrentwhatever \c!test
+%D % \dosetwhateverattributes \c!style \c!color
+%D % \everydefinewhatever (sets \currentwhatever)
+%D % \everypresetwhatever (can be used to reset parameters as we can redefine)
+%D % \everysetupwhatever (sets \currentwhatever)
+%D
+%D \starttext
+%D \definewhatever[first] \definewhatever[second][first]
+%D test: \def\currentwhatever{first} \whateverparameter{method} \par
+%D \setupwhatever [method=unset] test: \def\currentwhatever{first} \whateverparameter{method} \par
+%D \setupwhatever[first] [method=first] test: \def\currentwhatever{first} \whateverparameter{method} \par
+%D test: \def\currentwhatever{second} \whateverparameter{method} \par
+%D \setupwhatever[second][method=second] test: \def\currentwhatever{second} \whateverparameter{method} \par
+%D \stoptext
+%D \stoptyping
+
+% problem: every* could clash
+
+% faster but assumes \c!always
+%
+% \unexpanded\def\doinstallparameterhandler#1#2#3#4#5#6#7#8#9% \??aa {whatever} \current..
+% {\def#3##1{\csname#6{#1#2}##1\endcsname}%
+% \def#4##1{#7{#1#2}##1}%
+% \def#5##1##2{\csname#6{#1##2}##1\endcsname}%
+% \def#6##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#8\csname##1\s!parent\endcsname##2\fi}%
+% \def#7##1##2{\ifcsname##1##2\endcsname ##1\else\expandafter#9\csname##1\s!parent\endcsname##2\fi}%
+% \def#8##1##2{\ifx##1\relax\s!empty\else#6{##1}##2\fi}%
+% \def#9##1##2{\ifx##1\relax \else#7{##1}##2\fi}}
+
+\unexpanded\def\doinstallparameterhandler#1#2#3#4#5#6#7#8#9% \??aa {whatever} \current..
+ {\def#3##1{\csname#6{#1#2}{##1}\endcsname}%
+ \def#4##1{#7{#1#2}{##1}}%
+ \def#5##1##2{\csname#6{#1##1}{##2}\endcsname}%
+ \def#6##1##2{\ifcsname##1##2\endcsname##1##2\else\expandafter#8\csname##1\s!parent\endcsname{##2}\fi}%
+ \def#7##1##2{\ifcsname##1##2\endcsname ##1\else\expandafter#9\csname##1\s!parent\endcsname{##2}\fi}%
+ \def#8##1##2{\ifx##1\relax\s!empty\else#6{##1}{##2}\fi}%
+ \def#9##1##2{\ifx##1\relax \else#7{##1}{##2}\fi}}
+
+% todo: \def\detokenized...parameter#1{\detokenize\expandafter\expandafter\expandafter{\csname#1#2\endcsname}} % always root
+
+\def\installparameterhandler#1#2%
+ {\normalexpanded
+ {\doinstallparameterhandler
+ {\noexpand#1}% \??aa
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname #2parameter\endcsname % can move
+ \expandafter\noexpand\csname #2parameterhash\endcsname % can move
+ \expandafter\noexpand\csname named#2parameter\endcsname % can move
+ \expandafter\noexpand\csname do#2parameter\endcsname
+ \expandafter\noexpand\csname do#2parameterhash\endcsname
+ \expandafter\noexpand\csname do#2parentparameter\endcsname
+ \expandafter\noexpand\csname do#2parentparameterhash\endcsname}}
+
+% faster but assumes \c!always
+%
+% \unexpanded\def\doinstallattributehandler#1#2#3% #1 not used here
+% {\expandafter\def\csname doset#2attributes\endcsname##1##2% style color
+% {\edef\fontattributehash {#3##1}%
+% \edef\colorattributehash{#3##2}%
+% \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash ##1\fi
+% \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash##2\fi}}
+
+\unexpanded\def\doinstallattributehandler#1#2#3% #1 not used here
+ {\expandafter\def\csname doset#2attributes\endcsname##1##2% style color
+ {\edef\fontattributehash {#3{##1}}%
+ \edef\colorattributehash{#3{##2}}%
+ \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash {##1}\fi
+ \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash{##2}\fi}}
+
+\def\installattributehandler#1#2%
+ {\normalexpanded
+ {\doinstallattributehandler
+ {\noexpand#1}% \??aa
+ {\noexpand#2}% whatever
+ \expandafter\noexpand\csname #2parameterhash\endcsname}}
+
+\unexpanded\def\doinstalldefinehandler#1#2#3#4#5#6#7%
+ {\unexpanded\expandafter\def\csname define#2\endcsname{\dodoubleempty#5}%
+ \expandafter\newtoks\csname everydefine#2\endcsname
+ \def#5[##1][##2]%
+ {\edef#4{##1}%
+ \the#6% predefine
+ \ifsecondargument
+ \getparameters[#1#4][\s!parent=#1,##2]%
+ \else
+ \getparameters[#1#4][\s!parent=#3]%
+ \fi
+ \the#7}}
+
+\def\installdefinehandler#1#2#3%
+ {\normalexpanded
+ {\doinstalldefinehandler
+ {\noexpand#1}% \??aa
+ {#2}% whatever
+ {#3}% root
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname dodefine#2\endcsname
+ \expandafter\noexpand\csname everypreset#2\endcsname
+ \expandafter\noexpand\csname everydefine#2\endcsname}}
+
+\unexpanded\def\doinstallsetuphandler#1#2#3#4#5%
+ {\unexpanded\expandafter\def\csname setup#2\endcsname{\dodoubleempty#4}%
+ \expandafter\newtoks\csname everysetup#2\endcsname
+ \def#4[##1][##2]%
+ {\ifsecondargument
+ \def\docommand####1% we will have a simple one as well
+ {\edef#3{##1#1}%
+ \getparameters[#1#3][##2]%
+ \the#5}%
+ \processcommalist[##1]\docommand
+ \else
+ \let#3\empty
+ \getparameters[#1][##1]%
+ \the#5%
+ \fi}}
+
+\def\installsetuphandler#1#2%
+ {\normalexpanded
+ {\doinstallsetuphandler
+ {\noexpand#1}% \??aa
+ {#2}% whatever
+ \expandafter\noexpand\csname current#2\endcsname
+ \expandafter\noexpand\csname dosetup#2\endcsname
+ \expandafter\noexpand\csname everysetup#2\endcsname}}
+
+\def\installcommandhandler#1#2#3% \??self name \??parent (can be \??self)
+ {\installparameterhandler{#1}{#2}%
+ \installdefinehandler {#1}{#2}#3%
+ \installsetuphandler {#1}{#2}%
+ \installattributehandler{#1}{#2}}
+
+\protect
+
diff --git a/tex/context/base/mult-cld.lua b/tex/context/base/mult-cld.lua
index a9fb1ff1c..9e7f94287 100644
--- a/tex/context/base/mult-cld.lua
+++ b/tex/context/base/mult-cld.lua
@@ -19,10 +19,10 @@ if not modules then modules = { } end modules ['mult-cld'] = {
context = context or { }
local format, concat = string.format, table.concat
-local next, type = next, type
+local next, type, tostring = next, type, tostring
local texsprint, texiowrite, ctxcatcodes = tex.sprint, texio.write, tex.ctxcatcodes
-local flush = texsprint or function(cct,...) print(table.concat{...}) end
+local flush = texsprint or function(cct,...) print(concat{...}) end
local _stack_, _n_ = { }, 0
@@ -64,7 +64,7 @@ trackers.register("context.intercept", function(v) if v then context.trace(true)
local trace_context = logs.new("context")
-local function writer(k,...)
+local function writer(k,...) -- we can optimize for 1 argument
if k then
flush(ctxcatcodes,k)
local t = { ... }
@@ -75,8 +75,6 @@ local function writer(k,...)
local typ = type(ti)
if ti == nil then
-- next
- elseif typ == "function" then
- flush(ctxcatcodes,"{\\mkivflush{" .. _store_(ti) .. "}}")
elseif typ == "string" or typ == "number" then
flush(ctxcatcodes,"{",ti,"}")
elseif typ == "table" then
@@ -102,6 +100,8 @@ local function writer(k,...)
end
flush(ctxcatcodes,"]")
end
+ elseif typ == "function" then
+ flush(ctxcatcodes,"{\\mkivflush{" .. _store_(ti) .. "}}")
-- elseif typ == "boolean" then
-- flush(ctxcatcodes,"\n")
elseif ti == true then
@@ -120,6 +120,77 @@ local function writer(k,...)
end
end
+local function newwriter(command,first,...) -- 5% faster than just ... and separate flush of command
+ if not command then
+ -- error
+ elseif not first then
+ flush(ctxcatcodes,command)
+ else
+ local t = { first, ... }
+ for i=1,#t do
+ if i == 2 then
+ command = ""
+ end
+ local ti = t[i]
+ local typ = type(ti)
+ if ti == nil then
+ flush(ctxcatcodes,command)
+ elseif typ == "string" or typ == "number" then
+ flush(ctxcatcodes,command,"{",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
+ flush(ctxcatcodes,",",k,'=',v)
+ else
+ flush(ctxcatcodes,command,"[",k,'=',v)
+ done = true
+ end
+ end
+ flush(ctxcatcodes,"]")
+ elseif tn == 1 then -- some 20% faster than the next loop
+ local tj = ti[1]
+ if type(tj) == "function" then
+ flush(ctxcatcodes,command,"[\\mkivflush{",_store_(tj),"}]")
+ else
+ flush(ctxcatcodes,command,"[",tj,"]")
+ end
+ else -- is concat really faster than flushes here?
+ for j=1,tn do
+ local tj = ti[j]
+ if type(tj) == "function" then
+ ti[j] = "\\mkivflush{" .. _store_(tj) .. "}"
+ end
+ end
+ flush(ctxcatcodes,command,"[",concat(ti,","),"]")
+ end
+ elseif typ == "function" then
+ flush(ctxcatcodes,command,"{\\mkivflush{",_store_(ti),"}}")
+ -- elseif typ == "boolean" then
+ -- flush(ctxcatcodes,"\n")
+ elseif ti == true then
+ flush(ctxcatcodes,command,"\n")
+ elseif typ == false then
+ -- if force == "direct" then
+ flush(ctxcatcodes,command,tostring(ti))
+ -- end
+ elseif typ == "thread" then
+ flush(ctxcatcodes,command)
+ trace_context("coroutines not supported as we cannot yeild across boundaries")
+ else
+ flush(ctxcatcodes,command)
+ trace_context("error: %s gets a weird argument %s",command,tostring(ti))
+ end
+ end
+ end
+end
+
+experiments.register("context.writer",function()
+ writer = newwriter
+end)
+
-- -- --
local function indexer(t,k)
diff --git a/tex/context/base/mult-de.tex b/tex/context/base/mult-de.tex
index 608fdb1f8..a924c0bec 100644
--- a/tex/context/base/mult-de.tex
+++ b/tex/context/base/mult-de.tex
@@ -656,6 +656,7 @@
\setinterfaceconstant{footer}{fusszeile}
\setinterfaceconstant{footerdistance}{fusszeilenabstand}
\setinterfaceconstant{footerstate}{fusszeilenstatus}
+\setinterfaceconstant{force}{zwinge}
\setinterfaceconstant{foregroundcolor}{foregroundcolor}
\setinterfaceconstant{foregroundstyle}{foregroundstyle}
\setinterfaceconstant{format}{formatieren}
@@ -854,6 +855,7 @@
\setinterfaceconstant{previous}{vorige}
\setinterfaceconstant{previousnumber}{vorigenummer}
\setinterfaceconstant{process}{process}
+\setinterfaceconstant{profile}{profile}
\setinterfaceconstant{pubsep}{pubsep}
\setinterfaceconstant{radius}{radius}
\setinterfaceconstant{random}{zufaellig}
diff --git a/tex/context/base/mult-def.lua b/tex/context/base/mult-def.lua
index d877ad0f2..1614301ac 100644
--- a/tex/context/base/mult-def.lua
+++ b/tex/context/base/mult-def.lua
@@ -7783,6 +7783,16 @@ return {
["pe"]="رنگ‌پیش‌زمینه",
["ro"]="foregroundcolor",
},
+ ["force"]={
+ ["cs"]="sila",
+ ["de"]="zwinge",
+ ["en"]="force",
+ ["fr"]="force",
+ ["it"]="forza",
+ ["nl"]="forceer",
+ ["pe"]="اجبار",
+ ["ro"]="fortat",
+ },
["foregroundstyle"]={
["cs"]="foregroundstyle",
["de"]="foregroundstyle",
@@ -9412,6 +9422,9 @@ return {
["pe"]="پردازش",
["ro"]="process",
},
+ ["profile"]={
+ ["en"]="profile",
+ },
["radius"]={
["cs"]="polomer",
["de"]="radius",
diff --git a/tex/context/base/mult-en.tex b/tex/context/base/mult-en.tex
index cbaeb50d6..094678d1e 100644
--- a/tex/context/base/mult-en.tex
+++ b/tex/context/base/mult-en.tex
@@ -656,6 +656,7 @@
\setinterfaceconstant{footer}{footer}
\setinterfaceconstant{footerdistance}{footerdistance}
\setinterfaceconstant{footerstate}{footerstate}
+\setinterfaceconstant{force}{force}
\setinterfaceconstant{foregroundcolor}{foregroundcolor}
\setinterfaceconstant{foregroundstyle}{foregroundstyle}
\setinterfaceconstant{format}{format}
@@ -854,6 +855,7 @@
\setinterfaceconstant{previous}{previous}
\setinterfaceconstant{previousnumber}{previousnumber}
\setinterfaceconstant{process}{process}
+\setinterfaceconstant{profile}{profile}
\setinterfaceconstant{pubsep}{pubsep}
\setinterfaceconstant{radius}{radius}
\setinterfaceconstant{random}{random}
diff --git a/tex/context/base/mult-fr.tex b/tex/context/base/mult-fr.tex
index 05b4ed1db..52dfab7e4 100644
--- a/tex/context/base/mult-fr.tex
+++ b/tex/context/base/mult-fr.tex
@@ -656,6 +656,7 @@
\setinterfaceconstant{footer}{pdp}
\setinterfaceconstant{footerdistance}{dsitancepdp}
\setinterfaceconstant{footerstate}{etatpdp}
+\setinterfaceconstant{force}{force}
\setinterfaceconstant{foregroundcolor}{couleurpremierplan}
\setinterfaceconstant{foregroundstyle}{stylepremierplan}
\setinterfaceconstant{format}{formatter}
@@ -854,6 +855,7 @@
\setinterfaceconstant{previous}{precedent}
\setinterfaceconstant{previousnumber}{numeroprecedent}
\setinterfaceconstant{process}{process}
+\setinterfaceconstant{profile}{profile}
\setinterfaceconstant{pubsep}{pubsep}
\setinterfaceconstant{radius}{rayon}
\setinterfaceconstant{random}{aleatoire}
diff --git a/tex/context/base/mult-it.tex b/tex/context/base/mult-it.tex
index 5bac8d0b0..fe9534c08 100644
--- a/tex/context/base/mult-it.tex
+++ b/tex/context/base/mult-it.tex
@@ -656,6 +656,7 @@
\setinterfaceconstant{footer}{piedipagina}
\setinterfaceconstant{footerdistance}{distanzapdp}
\setinterfaceconstant{footerstate}{statopdp}
+\setinterfaceconstant{force}{forza}
\setinterfaceconstant{foregroundcolor}{coloreprimopiano}
\setinterfaceconstant{foregroundstyle}{foregroundstyle}
\setinterfaceconstant{format}{format}
@@ -854,6 +855,7 @@
\setinterfaceconstant{previous}{precedente}
\setinterfaceconstant{previousnumber}{numeroprecedente}
\setinterfaceconstant{process}{process}
+\setinterfaceconstant{profile}{profile}
\setinterfaceconstant{pubsep}{pubsep}
\setinterfaceconstant{radius}{raggio}
\setinterfaceconstant{random}{casuale}
diff --git a/tex/context/base/mult-mcs.tex b/tex/context/base/mult-mcs.tex
index 98c392c9f..27fbd37dd 100644
--- a/tex/context/base/mult-mcs.tex
+++ b/tex/context/base/mult-mcs.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{neznama reference --}
+\setinterfacemessage{references}{30}{neznamy objekt --}
\setinterfacemessage{references}{3}{neznamy typ reference --}
\setinterfacemessage{references}{2}{duplicitni reference -- na strane --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{nedovolena reference --}
-\setinterfacemessage{references}{30}{neznamy objekt --}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{reference}
diff --git a/tex/context/base/mult-mde.tex b/tex/context/base/mult-mde.tex
index 4da89ba33..2819c1ed5 100644
--- a/tex/context/base/mult-mde.tex
+++ b/tex/context/base/mult-mde.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{unbekannte Referenz --}
+\setinterfacemessage{references}{30}{unbekanntes Object --}
\setinterfacemessage{references}{3}{unbekannte Referenz Typ --}
\setinterfacemessage{references}{2}{doppelte Referenz -- auf Seite --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{illegale Referenz --}
-\setinterfacemessage{references}{30}{unbekanntes Object --}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{referenzen}
diff --git a/tex/context/base/mult-men.tex b/tex/context/base/mult-men.tex
index 4c1bc9942..c9c56bcc5 100644
--- a/tex/context/base/mult-men.tex
+++ b/tex/context/base/mult-men.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{unknown reference --}
+\setinterfacemessage{references}{30}{unknown object --}
\setinterfacemessage{references}{3}{unknown reference type --}
\setinterfacemessage{references}{2}{duplicate reference -- on page --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{illegal reference --}
-\setinterfacemessage{references}{30}{unknown object --}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{references}
diff --git a/tex/context/base/mult-mes.lua b/tex/context/base/mult-mes.lua
index 5c8129711..50c764785 100644
--- a/tex/context/base/mult-mes.lua
+++ b/tex/context/base/mult-mes.lua
@@ -1363,6 +1363,12 @@ return {
["no"]="ulovlig referanse --",
["ro"]="referinta eronata --",
},
+ ["5"]={
+ ["en"]="number of unknown references: --",
+ },
+ ["6"]={
+ ["en"]="number of illegal references: --",
+ },
["files"]={ "core-obj.tex", "core-ref.tex", "strc-ref.tex" },
["title"]={
["cs"]="reference",
diff --git a/tex/context/base/mult-mfr.tex b/tex/context/base/mult-mfr.tex
index 78e4f9f17..7fee954c0 100644
--- a/tex/context/base/mult-mfr.tex
+++ b/tex/context/base/mult-mfr.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{réference -- inconnue}
+\setinterfacemessage{references}{30}{objet -- inconnu}
\setinterfacemessage{references}{3}{type -- de réference inconnu}
\setinterfacemessage{references}{2}{réference -- dupliquée à la page --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{réference -- inconnue}
-\setinterfacemessage{references}{30}{objet -- inconnu}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{réferences}
diff --git a/tex/context/base/mult-mit.tex b/tex/context/base/mult-mit.tex
index 6d2a8f516..9d09e2676 100644
--- a/tex/context/base/mult-mit.tex
+++ b/tex/context/base/mult-mit.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{riferimento sconosciuto --}
+\setinterfacemessage{references}{30}{oggetto sconosciuto --}
\setinterfacemessage{references}{3}{riferimento di tipo sconosciuto --}
\setinterfacemessage{references}{2}{riferimento duplicato -- a pagina --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{riferimento illecito --}
-\setinterfacemessage{references}{30}{oggetto sconosciuto --}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{riferimenti}
diff --git a/tex/context/base/mult-mnl.tex b/tex/context/base/mult-mnl.tex
index b8204a40b..fb527d4ad 100644
--- a/tex/context/base/mult-mnl.tex
+++ b/tex/context/base/mult-mnl.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{onbekende verwijzing --}
+\setinterfacemessage{references}{30}{onbekend object --}
\setinterfacemessage{references}{3}{type verwijzing -- onbekend}
\setinterfacemessage{references}{2}{dubbele verwijzing -- op pagina --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{verboden verwijzing --}
-\setinterfacemessage{references}{30}{onbekend object --}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{verwijzingen}
diff --git a/tex/context/base/mult-mno.tex b/tex/context/base/mult-mno.tex
index ee6fd3273..bbbc3a658 100644
--- a/tex/context/base/mult-mno.tex
+++ b/tex/context/base/mult-mno.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{ukjent referanse --}
+\setinterfacemessage{references}{30}{ukjent objekt --}
\setinterfacemessage{references}{3}{ukjent referansetype --}
\setinterfacemessage{references}{2}{duplikat referanse -- pø side --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{ulovlig referanse --}
-\setinterfacemessage{references}{30}{ukjent objekt --}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{referanser}
diff --git a/tex/context/base/mult-mpe.tex b/tex/context/base/mult-mpe.tex
index 4c1bc9942..c9c56bcc5 100644
--- a/tex/context/base/mult-mpe.tex
+++ b/tex/context/base/mult-mpe.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{unknown reference --}
+\setinterfacemessage{references}{30}{unknown object --}
\setinterfacemessage{references}{3}{unknown reference type --}
\setinterfacemessage{references}{2}{duplicate reference -- on page --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{illegal reference --}
-\setinterfacemessage{references}{30}{unknown object --}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{references}
diff --git a/tex/context/base/mult-mro.tex b/tex/context/base/mult-mro.tex
index da96a23a4..70673c317 100644
--- a/tex/context/base/mult-mro.tex
+++ b/tex/context/base/mult-mro.tex
@@ -1,8 +1,10 @@
\setinterfacemessage{references}{1}{referinta necunoscuta --}
+\setinterfacemessage{references}{30}{obiect necunoscut --}
\setinterfacemessage{references}{3}{tip necunoscut de referinta --}
\setinterfacemessage{references}{2}{referinta duplicat -- la pagina --}
+\setinterfacemessage{references}{5}{number of unknown references: --}
\setinterfacemessage{references}{4}{referinta eronata --}
-\setinterfacemessage{references}{30}{obiect necunoscut --}
+\setinterfacemessage{references}{6}{number of illegal references: --}
\setinterfacemessage{references}{25}{references from document '--' are not imported (export again)}
\setinterfacemessage{references}{24}{references from document '--' are not exported}
\setinterfacemessage{references}{title}{referinte}
diff --git a/tex/context/base/mult-nl.tex b/tex/context/base/mult-nl.tex
index 58c106a22..4b08fcdaa 100644
--- a/tex/context/base/mult-nl.tex
+++ b/tex/context/base/mult-nl.tex
@@ -656,6 +656,7 @@
\setinterfaceconstant{footer}{voet}
\setinterfaceconstant{footerdistance}{voetafstand}
\setinterfaceconstant{footerstate}{voetstatus}
+\setinterfaceconstant{force}{forceer}
\setinterfaceconstant{foregroundcolor}{voorgrondkleur}
\setinterfaceconstant{foregroundstyle}{voorgrondletter}
\setinterfaceconstant{format}{formatteer}
@@ -854,6 +855,7 @@
\setinterfaceconstant{previous}{vorige}
\setinterfaceconstant{previousnumber}{vorigenummer}
\setinterfaceconstant{process}{proces}
+\setinterfaceconstant{profile}{profile}
\setinterfaceconstant{pubsep}{pubsep}
\setinterfaceconstant{radius}{straal}
\setinterfaceconstant{random}{willekeur}
diff --git a/tex/context/base/mult-ro.tex b/tex/context/base/mult-ro.tex
index 48993ae1f..8eae4e4b5 100644
--- a/tex/context/base/mult-ro.tex
+++ b/tex/context/base/mult-ro.tex
@@ -656,6 +656,7 @@
\setinterfaceconstant{footer}{subsol}
\setinterfaceconstant{footerdistance}{distantasubsol}
\setinterfaceconstant{footerstate}{staresubsol}
+\setinterfaceconstant{force}{fortat}
\setinterfaceconstant{foregroundcolor}{foregroundcolor}
\setinterfaceconstant{foregroundstyle}{foregroundstyle}
\setinterfaceconstant{format}{format}
@@ -854,6 +855,7 @@
\setinterfaceconstant{previous}{precendent}
\setinterfaceconstant{previousnumber}{numarprecedent}
\setinterfaceconstant{process}{process}
+\setinterfaceconstant{profile}{profile}
\setinterfaceconstant{pubsep}{pubsep}
\setinterfaceconstant{radius}{raza}
\setinterfaceconstant{random}{aleator}
diff --git a/tex/context/base/mult-sys.tex b/tex/context/base/mult-sys.tex
index 8b00b8d73..4f0f6c28b 100644
--- a/tex/context/base/mult-sys.tex
+++ b/tex/context/base/mult-sys.tex
@@ -450,11 +450,13 @@
\definesystemvariable {as} % AlignmentSwitch
\definesystemvariable {at} % ATtachments
\definesystemvariable {ba} % synchronisatieBAlk
+\definesystemvariable {bc} % BaCkend
\definesystemvariable {be} % startstop (BeginEnd)
\definesystemvariable {bj} % BlokJe
\definesystemvariable {bk} % Blokken (floats)
\definesystemvariable {bl} % BLanko
\definesystemvariable {bg} % BleedinG
+\definesystemvariable {bm} % BookMark
\definesystemvariable {bo} % BlankO (definitions)
\definesystemvariable {bp} % BreakPoint
\definesystemvariable {br} % sideBaR
diff --git a/tex/context/base/node-acc.lua b/tex/context/base/node-acc.lua
index f5c33a793..fc0c5fb0f 100644
--- a/tex/context/base/node-acc.lua
+++ b/tex/context/base/node-acc.lua
@@ -10,10 +10,12 @@ local traverse_nodes, traverse_id, has_attribute, copy_node = node.traverse, nod
nodes.accessibility = nodes.accessibility or { }
-local glue = node.id("glue")
-local glyph = node.id("glyph")
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
+local nodecodes = nodes.nodecodes
+
+local glue = nodecodes.glue
+local glyph = nodecodes.glyph
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
local function injectspaces(head)
local p
diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua
index 5ddf31e25..4b57bf225 100644
--- a/tex/context/base/node-aux.lua
+++ b/tex/context/base/node-aux.lua
@@ -11,8 +11,10 @@ local gsub, format = string.gsub, string.format
local free_node, hpack_nodes, node_fields, traverse_nodes = node.free, node.hpack, node.fields, node.traverse
local has_attribute, set_attribute, unset_attribute, has_attribute = node.has_attribute, node.set_attribute, node.unset_attribute,node.has_attribute
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
function nodes.repack_hlist(list,...)
local temp, b = hpack_nodes(list,...)
diff --git a/tex/context/base/node-bck.lua b/tex/context/base/node-bck.lua
index 94fbac85f..593be8492 100644
--- a/tex/context/base/node-bck.lua
+++ b/tex/context/base/node-bck.lua
@@ -9,8 +9,10 @@ if not modules then modules = { } end modules ['node-bck'] = {
-- beware, this one takes quite some runtime, so we need a status flag
-- maybe some page related state
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
local has_attribute = node.has_attribute
local set_attribute = node.set_attribute
diff --git a/tex/context/base/node-dir.lua b/tex/context/base/node-dir.lua
index 05e4835e5..3f65c75b1 100644
--- a/tex/context/base/node-dir.lua
+++ b/tex/context/base/node-dir.lua
@@ -15,7 +15,6 @@ adapted and now has the mappings as comments. This lua file is
based on that file.
]]--
-
nodes = nodes or { }
nodes.is_mirrored = {
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua
index 74b8daf2a..004d72765 100644
--- a/tex/context/base/node-fin.lua
+++ b/tex/context/base/node-fin.lua
@@ -10,21 +10,19 @@ if not modules then modules = { } end modules ['node-fin'] = {
local next, type, format = next, type, string.format
local texsprint = tex.sprint
-
local ctxcatcodes = tex.ctxcatcodes
+local has_attribute, copy_node = node.has_attribute, node.copy
+local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
-local glyph = node.id('glyph')
-local disc = node.id('disc')
-local glue = node.id('glue')
-local rule = node.id('rule')
-local whatsit = node.id('whatsit')
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
-
-local has_attribute = node.has_attribute
-local copy_node = node.copy
+local nodecodes = nodes.nodecodes
-local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+local glyph = nodecodes.glyph
+local disc = nodecodes.disc
+local glue = nodecodes.glue
+local rule = nodecodes.rule
+local whatsit = nodecodes.whatsit
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
states = states or { }
shipouts = shipouts or { }
diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua
index 594cfc1a1..ad7af592f 100644
--- a/tex/context/base/node-fnt.lua
+++ b/tex/context/base/node-fnt.lua
@@ -12,12 +12,12 @@ local next, type = next, type
local trace_characters = false trackers.register("nodes.characters", function(v) trace_characters = v end)
-local glyph = node.id('glyph')
+local traverse_id, has_attribute = node.traverse_id, node.has_attribute
+local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
-local traverse_id = node.traverse_id
-local has_attribute = node.has_attribute
+local nodecodes = nodes.nodecodes
-local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
+local glyph = nodecodes.glyph
fonts = fonts or { }
fonts.tfm = fonts.tfm or { }
diff --git a/tex/context/base/node-ini.lua b/tex/context/base/node-ini.lua
index 8f507e9b1..836c43860 100644
--- a/tex/context/base/node-ini.lua
+++ b/tex/context/base/node-ini.lua
@@ -52,20 +52,71 @@ also ignore the empty nodes. [This is obsolete!]</p>
nodes = nodes or { }
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
-local glyph = node.id('glyph')
-local glue = node.id('glue')
-local penalty = node.id('penalty')
-local kern = node.id('kern')
-local whatsit = node.id('whatsit')
-
-local traverse_id = node.traverse_id
-local traverse = node.traverse
-local free_node = node.free
-local remove_node = node.remove
-local insert_node_before = node.insert_before
-local insert_node_after = node.insert_after
+local traverse, traverse_id = node.traverse, node.traverse_id
+local free_node, remove_node = node.free, node.remove
+local insert_node_before, insert_node_after = node.insert_before, node.insert_after
+
+-- there will be more of this:
+
+local skipcodes = {
+ [ 0] = "userskip",
+ [ 1] = "lineskip",
+ [ 2] = "baselineskip",
+ [ 3] = "parskip",
+ [ 4] = "abovedisplayskip",
+ [ 5] = "belowdisplayskip",
+ [ 6] = "abovedisplayshortskip",
+ [ 7] = "belowdisplayshortskip",
+ [ 8] = "leftskip",
+ [ 9] = "rightskip",
+ [10] = "topskip",
+ [11] = "splittopskip",
+ [12] = "tabskip",
+ [13] = "spaceskip",
+ [14] = "xspaceskip",
+ [15] = "parfillskip",
+ [16] = "thinmuskip",
+ [17] = "medmuskip",
+ [18] = "thickmuskip",
+}
+
+local noadcodes = {
+ [ 0] = "ord",
+ [ 1] = "op_displaylimits",
+ [ 2] = "op_limits",
+ [ 3] = "op_nolimits",
+ [ 4] = "bin",
+ [ 5] = "rel",
+ [ 6] = "open",
+ [ 7] = "close",
+ [ 8] = "punct",
+ [ 9] = "inner",
+ [10] = "under",
+ [11] = "over",
+ [12] = "vcenter",
+}
+
+local nodecodes = node.types()
+local whatsitcodes = node.whatsits()
+
+skipcodes = table.swapped(skipcodes,skipcodes)
+noadcodes = table.swapped(noadcodes,noadcodes)
+nodecodes = table.swapped(nodecodes,nodecodes)
+whatsitcodes = table.swapped(whatsitcodes,whatsitcodes)
+
+nodes.skipcodes = skipcodes
+nodes.gluecodes = skipcodes -- more official
+nodes.noadcodes = noadcodes
+nodes.nodecodes = nodecodes
+nodes.whatsitcodes = whatsitcodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local glyph = nodecodes.glyph
+local glue = nodecodes.glue
+local penalty = nodecodes.penalty
+local kern = nodecodes.kern
+local whatsit = nodecodes.whatsit
function nodes.remove(head, current, free_too)
local t = current
diff --git a/tex/context/base/node-mig.lua b/tex/context/base/node-mig.lua
index c014c8de4..c2d6e8eca 100644
--- a/tex/context/base/node-mig.lua
+++ b/tex/context/base/node-mig.lua
@@ -8,15 +8,17 @@ if not modules then modules = { } end modules ['node-mig'] = {
local format = string.format
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
-local insert = node.id('ins')
-local mark = node.id('mark')
-
local has_attribute = node.has_attribute
local set_attribute = node.set_attribute
local remove_nodes = nodes.remove
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local insert = nodecodes.ins
+local mark = nodecodes.mark
+
local migrated = attributes.private("migrated")
local trace_migrations = false trackers.register("nodes.migrations", function(v) trace_migrations = v end)
diff --git a/tex/context/base/node-pro.lua b/tex/context/base/node-pro.lua
index c7c02b414..d10d2ebe4 100644
--- a/tex/context/base/node-pro.lua
+++ b/tex/context/base/node-pro.lua
@@ -24,10 +24,6 @@ nodes.processors = nodes.processors or { }
-- vbox: grouptype: vbox vtop output split_off split_keep | box_type: exactly|aditional
-- hbox: grouptype: hbox adjusted_hbox(=hbox_in_vmode) | box_type: exactly|aditional
-lists = lists or { }
-chars = chars or { }
-words = words or { } -- not used yet
-
local actions = tasks.actions("processors",4)
local n = 0
diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua
index a25cf1f4a..3c0d03f82 100644
--- a/tex/context/base/node-ref.lua
+++ b/tex/context/base/node-ref.lua
@@ -30,10 +30,12 @@ local trace_destinations = false trackers.register("nodes.destinations", functi
local report_backends = logs.new("backends")
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
-local glue = node.id("glue")
-local whatsit = node.id("whatsit")
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local glue = nodecodes.glue
+local whatsit = nodecodes.whatsit
local new_kern = nodes.kern
diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua
index 546f56916..bafa5e159 100644
--- a/tex/context/base/node-res.lua
+++ b/tex/context/base/node-res.lua
@@ -19,14 +19,10 @@ for debugging <l n='luatex'/> node management.</p>
nodes = nodes or { }
-nodes.whatsits = { } -- table.swapped(node.whatsits())
+local whatsitcodes = nodes.whatsitcodes
+local skipcodes = nodes.skipcodes
local reserved = { }
-local whatsits = nodes.whatsits
-
-for k, v in next, node.whatsits() do
- whatsits[k], whatsits[v] = v, k -- two way
-end
local function register_node(n)
reserved[#reserved+1] = n
@@ -72,19 +68,19 @@ local penalty = register_node(new_node("penalty"))
local glue = register_node(new_node("glue")) -- glue.spec = nil
local glue_spec = register_node(new_node("glue_spec"))
local glyph = register_node(new_node("glyph",0))
-local textdir = register_node(new_node("whatsit",whatsits.dir)) -- 7 (6 is local par node)
+local textdir = register_node(new_node("whatsit",whatsitcodes.dir)) -- 7 (6 is local par node)
local rule = register_node(new_node("rule"))
-local latelua = register_node(new_node("whatsit",whatsits.late_lua)) -- 35
-local user_n = register_node(new_node("whatsit",whatsits.user_defined)) user_n.type = 100 -- 44
-local user_l = register_node(new_node("whatsit",whatsits.user_defined)) user_l.type = 110 -- 44
-local user_s = register_node(new_node("whatsit",whatsits.user_defined)) user_s.type = 115 -- 44
-local user_t = register_node(new_node("whatsit",whatsits.user_defined)) user_t.type = 116 -- 44
+local latelua = register_node(new_node("whatsit",whatsitcodes.late_lua)) -- 35
+local user_n = register_node(new_node("whatsit",whatsitcodes.user_defined)) user_n.type = 100 -- 44
+local user_l = register_node(new_node("whatsit",whatsitcodes.user_defined)) user_l.type = 110 -- 44
+local user_s = register_node(new_node("whatsit",whatsitcodes.user_defined)) user_s.type = 115 -- 44
+local user_t = register_node(new_node("whatsit",whatsitcodes.user_defined)) user_t.type = 116 -- 44
local left_margin_kern = register_node(new_node("margin_kern",0))
local right_margin_kern = register_node(new_node("margin_kern",1))
-local lineskip = register_node(new_node("glue",1))
-local baselineskip = register_node(new_node("glue",2))
-local leftskip = register_node(new_node("glue",8))
-local rightskip = register_node(new_node("glue",9))
+local lineskip = register_node(new_node("glue",skipcodes.lineskip))
+local baselineskip = register_node(new_node("glue",skipcodes.baselineskip))
+local leftskip = register_node(new_node("glue",skipcodes.leftskip))
+local rightskip = register_node(new_node("glue",skipcodes.rightskip))
local temp = register_node(new_node("temp",0))
local noad = register_node(new_node("noad"))
diff --git a/tex/context/base/node-rul.lua b/tex/context/base/node-rul.lua
index 5e1df2da4..e981b83b4 100644
--- a/tex/context/base/node-rul.lua
+++ b/tex/context/base/node-rul.lua
@@ -11,9 +11,11 @@ if not modules then modules = { } end modules ['node-rul'] = {
--
-- todo: make robust for layers ... order matters
-local glyph = node.id("glyph")
-local disc = node.id("disc")
-local rule = node.id("rule")
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local disc = nodecodes.disc
+local rule = nodecodes.rule
function nodes.strip_range(first,last) -- todo: dir
if first and last then -- just to be sure
@@ -62,29 +64,34 @@ local a_color = attributes.private('color')
local a_transparency = attributes.private('transparency')
local a_colorspace = attributes.private('colormodel')
-local glyph = node.id("glyph")
-local disc = node.id("disc")
-local glue = node.id("glue")
-local penalty = node.id("penalty")
-local kern = node.id("kern")
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
-local rule = node.id("rule")
-local whatsit = node.id("whatsit")
-
-local new_rule = nodes.rule
-local new_kern = nodes.kern
-local new_glue = nodes.glue
-
local insert_before, insert_after, strip_range = node.insert_before, node.insert_after, nodes.strip_range
local list_dimensions, has_attribute, set_attribute = node.dimensions, node.has_attribute, node.set_attribute
local hpack_nodes = node.hpack
+local skipcodes, nodecodes = nodes.skipcodes, nodes.nodecodes
local dimenfactor = fonts.dimenfactor
local texwrite = tex.write
local fontdata = fonts.ids
local variables = interfaces.variables
+local glyph = nodecodes.glyph
+local disc = nodecodes.disc
+local glue = nodecodes.glue
+local penalty = nodecodes.penalty
+local kern = nodecodes.kern
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local rule = nodecodes.rule
+local whatsit = nodecodes.whatsit
+
+local userskip = skipcodes.userskip
+local spaceskip = skipcodes.spaceskip
+local xspaceskip = skipcodes.xspaceskip
+
+local new_rule = nodes.rule
+local new_kern = nodes.kern
+local new_glue = nodes.glue
+
-- we can use this one elsewhere too
--
-- todo: functions: word, sentence
@@ -161,7 +168,9 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd
l = n
elseif id == glue then
-- catch \underbar{a} \underbar{a} (subtype test is needed)
- if continue and has_attribute(n,attribute) and n.subtype == 0 then
+ local subtype = n.subtype
+ if continue and has_attribute(n,attribute) and
+ (subtype == userskip or subtype == spaceskip or subskip == xspaceskip) then
l = n
else
head, done = flush(head,f,l,d,level,parent,strip), true
diff --git a/tex/context/base/node-ser.lua b/tex/context/base/node-ser.lua
index e632e92da..b6e72f9fb 100644
--- a/tex/context/base/node-ser.lua
+++ b/tex/context/base/node-ser.lua
@@ -13,13 +13,15 @@ local type, format, concat = type, string.format, table.concat
local ctxcatcodes = tex.ctxcatcodes
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
-
local traverse = node.traverse
local node_fields = node.fields
local node_type = node.type
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+
local expand = table.tohash {
"list", -- list_ptr & ins_ptr & adjust_ptr
"pre", --
diff --git a/tex/context/base/node-shp.lua b/tex/context/base/node-shp.lua
index 50b16efa5..1066ab064 100644
--- a/tex/context/base/node-shp.lua
+++ b/tex/context/base/node-shp.lua
@@ -6,15 +6,16 @@ if not modules then modules = { } end modules ['node-shp'] = {
license = "see context related readme files"
}
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
-local disc = node.id('disc')
-local mark = node.id('mark')
-local kern = node.id('kern')
-local glue = node.id('glue')
-
-local free_node = node.free
-local remove_node = node.remove
+local free_node, remove_node = node.free, node.remove
+
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local disc = nodecodes.disc
+local mark = nodecodes.mark
+local kern = nodecodes.kern
+local glue = nodecodes.glue
local function cleanup_page(head) -- rough
local start = head
diff --git a/tex/context/base/node-spl.lua b/tex/context/base/node-spl.lua
index d6ecdfa13..de1935a03 100644
--- a/tex/context/base/node-spl.lua
+++ b/tex/context/base/node-spl.lua
@@ -33,13 +33,6 @@ local report_fonts = logs.new("fonts")
local report_splitter = logs.new("splitter")
local report_optimizer = logs.new("optimizer")
-local glyph = node.id("glyph")
-local glue = node.id("glue")
-local kern = node.id("kern")
-local disc = node.id("disc")
-local hlist = node.id("hlist")
-local whatsit = node.id("whatsit")
-
local find_node_tail = node.tail or node.slide
local free_node = node.free
local free_nodelist = node.flush_list
@@ -56,6 +49,15 @@ local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
local repack_hlist = nodes.repack_hlist
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local glue = nodecodes.glue
+local kern = nodecodes.kern
+local disc = nodecodes.disc
+local hlist = nodecodes.hlist
+local whatsit = nodecodes.whatsit
+
local starttiming = statistics.starttiming
local stoptiming = statistics.stoptiming
diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua
index d2d02c8df..5134611c4 100644
--- a/tex/context/base/node-tra.lua
+++ b/tex/context/base/node-tra.lua
@@ -11,8 +11,9 @@ if not modules then modules = { } end modules ['node-tra'] = {
might become a runtime module instead. This module will be cleaned up!</p>
--ldx]]--
-local utf = unicode.utf8
-local format, match, concat, rep, utfchar = string.format, string.match, table.concat, string.rep, utf.char
+local utfchar = utf.char
+local concat = table.concat
+local format, match, gmatch, concat, rep = string.format, string.match, string.gmatch, table.concat, string.rep
local ctxcatcodes = tex.ctxcatcodes
@@ -21,20 +22,14 @@ local report_nodes = logs.new("nodes")
fonts = fonts or { }
fonts.tfm = fonts.tfm or { }
fonts.ids = fonts.ids or { }
+fonts.chr = fonts.chr or { }
nodes = nodes or { }
nodes.tracers = nodes.tracers or { }
nodes.tracers.characters = nodes.tracers.characters or { }
nodes.tracers.steppers = nodes.tracers.steppers or { }
-local glyph = node.id('glyph')
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
-local disc = node.id('disc')
-local glue = node.id('glue')
-local kern = node.id('kern')
-local rule = node.id('rule')
-local whatsit = node.id('whatsit')
+local tracers = nodes.tracers
local copy_node_list = node.copy_list
local hpack_node_list = node.hpack
@@ -45,8 +40,19 @@ local traverse_nodes = node.traverse
local texsprint = tex.sprint
local fontdata = fonts.ids
-
-function nodes.tracers.characters.collect(head,list,tag,n)
+local fontchar = fonts.chr
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local disc = nodecodes.disc
+local glue = nodecodes.glue
+local kern = nodecodes.kern
+local rule = nodecodes.rule
+local whatsit = nodecodes.whatsit
+
+function tracers.characters.collect(head,list,tag,n)
n = n or 0
local ok, fn = false, nil
while head do
@@ -75,7 +81,7 @@ function nodes.tracers.characters.collect(head,list,tag,n)
end
end
-function nodes.tracers.characters.equal(ta, tb)
+function tracers.characters.equal(ta, tb)
if #ta ~= #tb then
return false
else
@@ -89,7 +95,7 @@ function nodes.tracers.characters.equal(ta, tb)
return true
end
-function nodes.tracers.characters.string(t)
+function tracers.characters.string(t)
local tt = { }
for i=1,#t do
tt[i] = utfchar(t[i][1])
@@ -97,7 +103,7 @@ function nodes.tracers.characters.string(t)
return concat(tt,"")
end
-function nodes.tracers.characters.unicodes(t,decimal)
+function tracers.characters.unicodes(t,decimal)
local tt = { }
for i=1,#t do
local n = t[i][1]
@@ -112,7 +118,7 @@ function nodes.tracers.characters.unicodes(t,decimal)
return concat(tt," ")
end
-function nodes.tracers.characters.indices(t,decimal)
+function tracers.characters.indices(t,decimal)
local tt = { }
for i=1,#t do
local n = t[i][3]
@@ -127,20 +133,20 @@ function nodes.tracers.characters.indices(t,decimal)
return concat(tt," ")
end
-function nodes.tracers.characters.start()
+function tracers.characters.start()
local npc = nodes.process_characters
local list = { }
function nodes.process_characters(head)
local n = #list
- nodes.tracers.characters.collect(head,list,'before',n)
+ tracers.characters.collect(head,list,'before',n)
local h, d = npc(head)
- nodes.tracers.characters.collect(head,list,'after',n)
+ tracers.characters.collect(head,list,'after',n)
if #list > n then
list[#list+1] = { }
end
return h, d
end
- function nodes.tracers.characters.stop()
+ function tracers.characters.stop()
tracers.list['characters'] = list
local variables = {
['title'] = 'ConTeXt Character Processing Information',
@@ -156,14 +162,14 @@ end
local stack = { }
-function nodes.tracers.start(tag)
+function tracers.start(tag)
stack[#stack+1] = tag
- local tracer = nodes.tracers[tag]
+ local tracer = tracers[tag]
if tracer and tracer.start then
tracer.start()
end
end
-function nodes.tracers.stop()
+function tracers.stop()
local tracer = stack[#stack]
if tracer and tracer.stop then
tracer.stop()
@@ -175,15 +181,15 @@ end
local collection, collecting, messages = { }, false, { }
-function nodes.tracers.steppers.start()
+function tracers.steppers.start()
collecting = true
end
-function nodes.tracers.steppers.stop()
+function tracers.steppers.stop()
collecting = false
end
-function nodes.tracers.steppers.reset()
+function tracers.steppers.reset()
for i=1,#collection do
local c = collection[i]
if c then
@@ -193,18 +199,18 @@ function nodes.tracers.steppers.reset()
collection, messages = { }, { }
end
-function nodes.tracers.steppers.nofsteps()
+function tracers.steppers.nofsteps()
return tex.write(#collection)
end
-function nodes.tracers.steppers.glyphs(n,i)
+function tracers.steppers.glyphs(n,i)
local c = collection[i]
if c then
tex.box[n] = hpack_node_list(copy_node_list(c))
end
end
-function nodes.tracers.steppers.features()
+function tracers.steppers.features()
-- local f = first_character(collection[1])
-- if f then -- something fishy with first_character
local f = collection[1]
@@ -235,13 +241,13 @@ function nodes.tracers.steppers.features()
end
end
-function nodes.tracers.fontchar(font,char)
+function tracers.fontchar(font,char)
local n = nodes.glyph()
n.font, n.char, n.subtype = font, char, 256
node.write(n)
end
-function nodes.tracers.steppers.codes(i,command)
+function tracers.steppers.codes(i,command)
local c = collection[i]
while c do
local id = c.id
@@ -260,7 +266,7 @@ function nodes.tracers.steppers.codes(i,command)
end
end
-function nodes.tracers.steppers.messages(i,command,split)
+function tracers.steppers.messages(i,command,split)
local list = messages[i] -- or { "no messages" }
if list then
for i=1,#list do
@@ -277,9 +283,9 @@ end
-- hooks into the node list processor (see otf)
-function nodes.tracers.steppers.check(head)
+function tracers.steppers.check(head)
if collecting then
- nodes.tracers.steppers.reset()
+ tracers.steppers.reset()
local n = copy_node_list(head)
nodes.inject_kerns(n,nil,"trace",true)
nodes.protect_glyphs(n) -- can be option
@@ -287,7 +293,7 @@ function nodes.tracers.steppers.check(head)
end
end
-function nodes.tracers.steppers.register(head)
+function tracers.steppers.register(head)
if collecting then
local nc = #collection+1
if messages[nc] then
@@ -299,7 +305,7 @@ function nodes.tracers.steppers.register(head)
end
end
-function nodes.tracers.steppers.message(str,...)
+function tracers.steppers.message(str,...)
str = format(str,...)
if collecting then
local n = #collection + 1
@@ -332,7 +338,7 @@ function nodes.check_glyphs(head,message)
return false
end
-function nodes.tosequence(start,stop,compact)
+local function tosequence(start,stop,compact)
if start then
local t = { }
while start do
@@ -341,7 +347,7 @@ function nodes.tosequence(start,stop,compact)
local c = start.char
if compact then
if start.components then
- t[#t+1] = nodes.tosequence(start.components,nil,compact)
+ t[#t+1] = tosequence(start.components,nil,compact)
else
t[#t+1] = utfchar(c)
end
@@ -379,6 +385,8 @@ function nodes.tosequence(start,stop,compact)
end
end
+nodes.tosequence = tosequence
+
function nodes.report(t,done)
if done then
if status.output_active then
@@ -474,3 +482,56 @@ function nodes.list_to_utf(h,joiner)
end
return concat(w)
end
+
+local what = { [0] = "unknown", "line", "box", "indent", "row", "cell" }
+
+local function show_boxes(n,symbol,depth)
+ depth, symbol = depth or 0, symbol or "."
+ for n in traverse_nodes(n) do
+ local id = n.id
+ if id == hlist or id == vlist then
+ local s = n.subtype
+ logs.simple(rep(symbol,depth) .. what[s] or s)
+ show_boxes(n.list,symbol,depth+1)
+ end
+ end
+end
+
+nodes.show_boxes = show_boxes
+
+local threshold = 65536
+
+function toutf(list,result)
+ for n in traverse_nodes(list) do
+ local id = n.id
+ if id == glyph then
+ local c = n.char
+ local fc = fontchar[n.font]
+ if fc then
+ local u = fc[c].tounicode
+ if u then
+ for s in gmatch(u,"..") do
+ result[#result+1] = utfchar(tonumber(s,16))
+ end
+ else
+ result[#result+1] = utfchar(c)
+ end
+ else
+ result[#result+1] = utfchar(c)
+ end
+ elseif id == disc then
+ toutf(n.replace,result)
+ elseif id == hlist or id == vlist then
+ toutf(n.list,result)
+ elseif id == glue and n.subtype == 0 and n.spec.width > threshold then
+ result[#result+1] = " "
+ elseif id == kern and n.kern > threshold then
+ result[#result+1] = " "
+ end
+ end
+ return result
+end
+
+function nodes.toutf(list)
+ return concat(toutf(list,{}))
+end
diff --git a/tex/context/base/node-tsk.lua b/tex/context/base/node-tsk.lua
index 66f691ec8..b47bceef1 100644
--- a/tex/context/base/node-tsk.lua
+++ b/tex/context/base/node-tsk.lua
@@ -115,8 +115,8 @@ function tasks.actions(name,n) -- we optimize for the number or arguments (no ..
if data then
if n == 0 then
return function(head)
- local runner = data.runner
total = total + 1 -- will go away
+ local runner = data.runner
if not runner then
created = created + 1
if trace_tasks then
diff --git a/tex/context/base/node-tst.lua b/tex/context/base/node-tst.lua
index d7ea96f26..c7e79c48f 100644
--- a/tex/context/base/node-tst.lua
+++ b/tex/context/base/node-tst.lua
@@ -6,16 +6,17 @@ if not modules then modules = { } end modules ['node-tst'] = {
license = "see context related readme files"
}
-local glue = node.id("glue")
-local penalty = node.id("penalty")
-local kern = node.id("kern")
-local glyph = node.id("glyph")
-local whatsit = node.id("whatsit")
-local hlist = node.id("hlist")
-
local find_node_tail = node.tail or node.slide
-local chardata = characters.data
+local chardata = characters.data
+local nodecodes = nodes.nodecodes
+
+local glue = nodecodes.glue
+local penalty = nodecodes.penalty
+local kern = nodecodes.kern
+local glyph = nodecodes.glyph
+local whatsit = nodecodes.whatsit
+local hlist = nodecodes.hlist
function nodes.the_left_margin(n) -- todo: three values
while n do
diff --git a/tex/context/base/node-typ.lua b/tex/context/base/node-typ.lua
index 5ab6b6975..b807e6aae 100644
--- a/tex/context/base/node-typ.lua
+++ b/tex/context/base/node-typ.lua
@@ -10,9 +10,7 @@ if not modules then modules = { } end modules ['node-typ'] = {
local utfvalues = string.utfvalues
-local newglyph = nodes.glyph
-local newglue = nodes.glue
-
+local newglyph, newglue = nodes.glyph, nodes.glue
local hpack, vpack = node.hpack, node.vpack
typesetting = typesetting or { }
@@ -21,7 +19,7 @@ local function tonodes(str,fontid,spacing) -- don't use this
local head, prev = nil, nil
for s in utfvalues(str) do
local next
- if spacing and s == 32 then
+ if spacing and s == 32 then
next = newglue(spacing or 64*1024*10)
else
next = newglyph(fontid or 1,s)
diff --git a/tex/context/base/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv
index 272ef0544..b0e9f858d 100644
--- a/tex/context/base/pack-rul.mkiv
+++ b/tex/context/base/pack-rul.mkiv
@@ -612,8 +612,6 @@
\def\inheritlocalframed[#1]#2[#3]{\letvalue{#1\s!parent}#3}
\def\copylocalframed [#1]#2[#3]{\setvalue{#1\s!parent}{#3}}
-\let\setuplocalframed\getparameters % obsolete
-
\presetlocalframed[\??ol]
\newcount\framednesting
@@ -627,23 +625,33 @@
\unexpanded\def\setupframed
{\dodoubleempty\dosetupframed}
-\def\dosetupframed
+% \def\dosetupframed
+% {\ifsecondargument
+% \@EA\dodoublesetupframed
+% \else
+% \@EA\dosinglesetupframed
+% \fi}
+
+% we can consider setting the parent of the regular framed to
+% something else in the otr so that we isolate it there
+
+\def\dosetupframed[#1][#2]%
{\ifsecondargument
- \@EA\dodoublesetupframed
+ \getparameters[\??ol#1][#2]%
\else
- \@EA\dosinglesetupframed
+ \getparameters[\??ol][#1]%
\fi}
-\def\dosinglesetupframed[#1][#2]%
- {\getparameters[\??ol][#1]}
+% \def\dosinglesetupframed[#1][#2]%
+% {\getparameters[\??ol][#1]}
-\def\dodoublesetupframed[#1][#2]%
- {\bgroup
- \let\dodoubleempty\empty
- \def\doframed[##1]{\gdef\globalredefinedframed{\dodoubleempty\doframed[##1,#2]}}%
- \getvalue{#1}%
- \egroup
- \letvalue{#1}\globalredefinedframed}
+% \def\dodoublesetupframed[#1][#2]%
+% {\bgroup
+% \let\dodoubleempty\empty
+% \def\doframed[##1]{\gdef\globalredefinedframed{\dodoubleempty\doframed[##1,#2]}}%
+% \getvalue{#1}%
+% \egroup
+% \letvalue{#1}\globalredefinedframed}
%D \startbuffer
%D \setupframed [framecolor=yellow] \framed{A}
@@ -655,7 +663,6 @@
%D
%D \startbuffer
%D \presetlocalframed[myframed]
-%D \setuplocalframed[myframed][width=4cm,height=2cm]
%D \localframed[myframed][framecolor=green]{oeps}
%D \stopbuffer
%D
@@ -884,7 +891,7 @@
% todo: protect local \framednames
-\unexpanded\def\startlocalframed[#1][#2]%
+\unexpanded\def\startlocalframed[#1][#2]% it should be possible to set \@@framed before calling this which saves a [] scan
{\bgroup
\inframedtrue
\edef\@@framed{#1}%
@@ -2829,17 +2836,49 @@
%D One can also define simple framed texts, using:
%D
%D \showsetup{defineframed}
+%D
+%D As suggested by Wolfgang we can now use the new \MKIV\ inheritance
+%D model instead of passing a combination of arguments. This also
+%D also simplified the \type {\setupframed} command. There are
+%D certainly more places where such improvements can be made.
+
+% \unexpanded\def\defineframed
+% {\dodoubleempty\dodefineframed}
+%
+% \def\dodefineframed[#1][#2]%
+% {\iffirstargument
+% \setuvalue{#1}{\dodoubleempty\doframed[#2]}%
+% \fi}
+%
+% \def\doframed[#1][#2]%
+% {\framed[#1,#2]}
-\unexpanded\def\defineframed
+\def\defineframed
{\dodoubleempty\dodefineframed}
\def\dodefineframed[#1][#2]%
- {\iffirstargument
- \setuvalue{#1}{\dodoubleempty\doframed[#2]}%
- \fi}
+ {\ifcsname\??ol:#1\endcsname
+ % already defined, keeps settings
+ \else
+ \expandafter\newcount\csname\??ol:#1\endcsname % \the\everypresetframed
+ \fi
+ \getparameters[\??ol#1][\s!parent=\??ol,#2]%
+ \setuvalue{#1}{\doframed[#1]}}% % \the\everydefineframed
+
+\def\doframed[#1]% we can speed up startlocalframed by using \currentlocalframed
+ {\bgroup
+ \expandafter\let\expandafter\tempframedcount\csname\??ol:#1\endcsname
+ \advance\tempframedcount\plusone
+ \expandafter\def\csname\??ol#1:\the\tempframedcount\s!parent\endcsname{\??ol#1}% \copylocalframed
+ \dodoubleempty\startlocalframed[\??ol#1:\the\tempframedcount]}
-\def\doframed[#1][#2]%
- {\framed[#1,#2]}
+%D We can do:
+%D
+%D \starttyping
+%D \defineframed[\v!framed]
+%D \stoptyping
+%D
+%D but the existing one is ok as well (less csname messy too).
%D \macros
%D {textrule, starttextrule, setuptextrules}
@@ -3521,6 +3560,9 @@
\setuplinewidth
[\v!medium]
+% We could omit the empty setings but that is some 10% slower due to
+% extra testing in the chain.
+
\setupframed
[\c!width=\v!fit,
\c!height=\v!broad,
@@ -3554,12 +3596,12 @@
\c!align=,
\c!bottom=\vss,
\c!top=,
- \c!strut=\v!yes,
\c!autostrut=\v!yes,
\c!location=\v!normal,
\c!orientation=,
\c!autowidth=\v!yes,
- \c!setups=]
+ \c!setups=,
+ \c!strut=\v!yes]
\setupscreens
[%\c!factor=1.0, % obsolete
diff --git a/tex/context/base/page-lin.lua b/tex/context/base/page-lin.lua
index e11730eae..f8daa84f4 100644
--- a/tex/context/base/page-lin.lua
+++ b/tex/context/base/page-lin.lua
@@ -27,11 +27,16 @@ storage.register("lines/data", nodes.lines.data, "nodes.lines.data")
-- if there is demand for it, we can support multiple numbering streams
-- and use more than one attibute
-local hlist, vlist, whatsit = node.id('hlist'), node.id('vlist'), node.id('whatsit')
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local whatsit = nodecodes.whatsit
local display_math = attributes.private('display-math')
local line_number = attributes.private('line-number')
local line_reference = attributes.private('line-reference')
+local verbatim_line = attributes.private('verbatim-line')
local current_list = { }
local cross_references = { }
@@ -45,8 +50,6 @@ local hpack_node = node.hpack
local insert_node_after = node.insert_after
local insert_node_before = node.insert_before
-local whatsit = node.id("whatsit")
-
local data = nodes.lines.data
local last = #data
@@ -147,21 +150,28 @@ end
local the_left_margin = nodes.the_left_margin
-local function check_number(n,a,skip) -- move inline
+local function check_number(n,a,skip,sameline)
local d = data[a]
if d then
- local s = d.start or 1
+ local tag, skipflag, s = d.tag or "", 0, d.start or 1
current_list[#current_list+1] = { n, s }
- if not skip and s % d.step == 0 then
- local tag = d.tag or ""
- texsprint(ctxcatcodes, format("\\makenumber{%s}{%s}{%s}{%s}{%s}{%s}\\endgraf",tag,s,n.shift,n.width,the_left_margin(n.list),n.dir))
+ if sameline then
+ skipflag = 0
+ if trace_numbers then
+ report_lines("skipping broken line number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no")
+ end
+ elseif not skip and s % d.step == 0 then
+ skipflag, d.start = 1, s + 1 -- (d.step or 1)
if trace_numbers then
report_lines("making number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no")
end
else
- texsprint(ctxcatcodes, "\\skipnumber\\endgraf")
+ skipflag, d.start = 0, s + 1 -- (d.step or 1)
+ if trace_numbers then
+ report_lines("skipping line number %s for setup %s: %s (%s)",#current_list,a,s,d.continue or "no")
+ end
end
- d.start = s + 1 -- (d.step or 1)
+ context.makelinenumber(tag,skipflag,s,n.shift,n.width,the_left_margin(n.list),n.dir)
end
end
@@ -170,12 +180,13 @@ function nodes.lines.boxed.stage_one(n)
local head = texbox[n]
if head then
local list = head.list
- local last_a, skip = nil, false
+ local last_a, last_v, skip = nil, -1, false
for n in traverse_id(hlist,list) do -- attr test here and quit as soon as zero found
if n.height == 0 and n.depth == 0 then
-- skip funny hlists
else
- local a = has_attribute(n.list,line_number)
+ local list = n.list
+ local a = has_attribute(list,line_number)
if a and a > 0 then
if last_a ~= a then
if data[a].method == variables.next then
@@ -188,10 +199,13 @@ function nodes.lines.boxed.stage_one(n)
check_number(n,a,skip)
end
else
- -- the following test fails somehow (change in luatex?)
- -- if node.first_character(n.list) then
+ local v = has_attribute(list,verbatim_line)
+ if not v or v ~= last_v then
+ last_v = v
check_number(n,a,skip)
- -- end
+ else
+ check_number(n,a,skip,true)
+ end
end
skip = false
end
diff --git a/tex/context/base/page-lin.mkiv b/tex/context/base/page-lin.mkiv
index 51f027639..e9df56aa6 100644
--- a/tex/context/base/page-lin.mkiv
+++ b/tex/context/base/page-lin.mkiv
@@ -42,11 +42,7 @@
% id nr shift width leftskip dir
-% \def\mkskiplinenumber #1#2#3#4#6#5{}
-% \def\mkleftlinenumber #1#2#3#4#5#6{\hbox{\llap{#2\quad\hskip#3\scaledpoint}}}
-% \def\mkrightlinenumber#1#2#3#4#5#6{\hbox{\rlap{\hskip#4\scaledpoint\hskip#3\scaledpoint\quad#2}}}
-
-\let\makenumber\gobblesixarguments
+\let\makelinenumber\gobblesevenarguments
\newconditional\boxcontentneedsprocessing
@@ -235,8 +231,6 @@
% number placement
-\let\mkskiplinenumber \gobblesixarguments
-
\def\mkdoinnerlinenumber{\doifoddpageelse\mkdoleftlinenumber\mkdorightlinenumber}
\def\mkdoouterlinenumber{\doifoddpageelse\mkdorightlinenumber\mkdoleftlinenumber}
@@ -278,47 +272,53 @@
\expandafter\mkdobeginlinenumber
\fi}
+\newconditional\faketextlinenumber
+
\def\mkaddtextlinenumbers#1#2#3% box col max
{\bgroup
\chardef\linenumberbox #1\relax
\chardef\linenumbercolumn #2\relax
\chardef\linenumberlastcolumn#3\relax
\fullrestoreglobalbodyfont
- \def\skipnumber{\hbox{}}%
- \let\makenumber\maketextlinenumber
+ \let\makelinenumber\maketextlinenumber
\mkprocesstextlinenumbers\linenumberbox
\egroup}
-\def\maketextlinenumber#1%
+\def\maketextlinenumber#1#2%
{\edef\currentlinenumbering{#1}%
+ \ifcase#2\relax
+ \settrue \faketextlinenumber
+ \else
+ \setfalse\faketextlinenumber
+ \fi
\chardef\linenumberlocation \executeifdefined{\??rn:l:\linenumberparameter\c!location}\plusone % left
\chardef\linenumberalignment\executeifdefined{\??rn:a:\linenumberparameter\c!align }\plusfive % auto
\ifcase\linenumberlastcolumn\relax
- \let\domakenumber\mkskiplinenumber
+ \settrue \faketextlinenumber
\or
% one column
\ifcase\linenumberlocation
- \let\domakenumber\mkskiplinenumber
+ \settrue \faketextlinenumber
% hm
\or
- \let\domakenumber\mkleftlinenumber
+ \let\domakelinenumber\mkleftlinenumber
\or
- \let\domakenumber\mkrightlinenumber
+ \let\domakelinenumber\mkrightlinenumber
\or % inner
- \let\domakenumber\mkdoinnerlinenumber
+ \let\domakelinenumber\mkdoinnerlinenumber
\or % outer
- \let\domakenumber\mkdoouterlinenumber
+ \let\domakelinenumber\mkdoouterlinenumber
\or % text
- \let\domakenumber\mkdotextlinenumber
+ \let\domakelinenumber\mkdotextlinenumber
\or
- \let\domakenumber\mkdobeginlinenumber
+ \let\domakelinenumber\mkdobeginlinenumber
\or
- \let\domakenumber\mkdoendlinenumber
+ \let\domakelinenumber\mkdoendlinenumber
\fi
\else\ifcase\linenumbercolumn\relax
- \let\domakenumber\mkskiplinenumber
+ \settrue \faketextlinenumber
\or
- \let\domakenumber\mkleftlinenumber
+ \let\domakelinenumber\mkleftlinenumber
\ifcase\linenumberlocation\or
\chardef\linenumberlocation\plusone
\or
@@ -335,7 +335,7 @@
\chardef\linenumberlocation\plusone % todo
\fi
\else
- \let\domakenumber\mkrightlinenumber
+ \let\domakelinenumber\mkrightlinenumber
\ifcase\linenumberlocation\or
\chardef\linenumberlocation\plustwo
\or
@@ -350,7 +350,7 @@
\chardef\linenumberlocation\plustwo % todo
\fi
\fi\fi
- \domakenumber{#1}}
+ \domakelinenumber{#1}}
\def\mkdotextlinenumber #1#2#3#4#5#6% beware, one needs so compensate for this in the width !
{\hbox{\dosomelinenumber{#1}{2}{#2}{#5}\hskip#3\scaledpoint}}
@@ -420,11 +420,15 @@
\or
\doifoddpageelse\hss\relax % outer
\fi
- \linenumberattributes\c!style\c!color
- {\linenumberparameter\c!command
- {\linenumberparameter\c!left
- \convertnumber{\linenumberparameter\c!conversion}{#3}%
- \linenumberparameter\c!right}}%
+ \ifconditional\faketextlinenumber
+ % we need to reserve space
+ \else
+ \linenumberattributes\c!style\c!color
+ {\linenumberparameter\c!command
+ {\linenumberparameter\c!left
+ \convertnumber{\linenumberparameter\c!conversion}{#3}%
+ \linenumberparameter\c!right}}%
+ \fi
\ifcase\linenumberlocation
\hss % middle
\or
diff --git a/tex/context/base/page-mul.mkii b/tex/context/base/page-mul.mkii
index c78af074a..801ae5d65 100644
--- a/tex/context/base/page-mul.mkii
+++ b/tex/context/base/page-mul.mkii
@@ -1179,11 +1179,11 @@
\egroup}
\def\multicolumnseject
- {\ifdim\pagetotal>\textheight
- \eject % new
- \else
+ {%\ifdim\pagetotal>\textheight
+ % \eject % new, but wrong as fails on mixed-001.tex (wrong pagetotal at this point)
+ %\else
\allowbreak
- \fi}
+ }%\fi}
%D The multicolumn mechanism is incorporated in a \CONTEXT\
%D interface, which acts like:
diff --git a/tex/context/base/page-mul.mkiv b/tex/context/base/page-mul.mkiv
index 791f328c5..ff0c9e502 100644
--- a/tex/context/base/page-mul.mkiv
+++ b/tex/context/base/page-mul.mkiv
@@ -1028,30 +1028,27 @@
\dontshowcomposition
\widowpenalty\zerocount
\setbox0\vbox{\unvbox\normalpagebox}%
-\ifdim\ht0>\openlineheight % at least one line
- \ifnum\minbalancetoplines<2 % balance anyway
- \donetrue
- \else % check criterium to available lines
- \getnoflines{\ht0}%
- \divide\noflines \nofcolumns \relax
- \ifnum\noflines<\minbalancetoplines \relax
- \dimen0\ht0
- \advance\dimen0 \ht\firsttopcolumnbox
- \advance\dimen0 \openlineheight \relax % let's play safe
- \ifdim\dimen0>\columntextheight % column exceeding text height
- \donetrue
- \else % it seems to fit
- \donefalse
- \fi
- \else % balance indeed
- \donetrue
- \fi
+ \ifdim\ht0>\openlineheight % at least one line
+ \ifnum\minbalancetoplines<2 % balance anyway
+ \donetrue
+ \else % check criterium to available lines
+ \getnoflines{\ht0}%
+ \divide\noflines \nofcolumns \relax
+ \ifnum\noflines<\minbalancetoplines \relax
+ % let's play safe
+ \ifdim\dimexpr\ht0+\ht\firsttopcolumnbox+\openlineheight\relax>\columntextheight
+ \donetrue % column exceeding text height
+ \else
+ \donefalse % it seems to fit
+ \fi
+ \else % balance indeed
+ \donetrue
+ \fi
+ \fi
+ \else % balancing does not make sense
+ \donefalse
\fi
-\else % balancing does not make sense
- \donefalse
-\fi
-\ifdone % start balancing
- %\ifdim\ht0>\openlineheight
+ \ifdone % start balancing, was: \ifdim\ht0>\openlineheight
\dimen0\ht0
\advance\dimen0 \topskip
\advance\dimen0 -\baselineskip
@@ -1174,11 +1171,11 @@
\egroup}
\def\multicolumnseject
- {\ifdim\pagetotal>\textheight
- \eject % new
- \else
+ {%\ifdim\pagetotal>\textheight
+ % \eject % new, but wrong as fails on mixed-001.tex (wrong pagetotal at this point)
+ %\else
\allowbreak
- \fi}
+ }%\fi}
%D The multicolumn mechanism is incorporated in a \CONTEXT\
%D interface, which acts like:
diff --git a/tex/context/base/scrn-nav.mkiv b/tex/context/base/scrn-nav.mkiv
index 264e3ded2..04b404a78 100644
--- a/tex/context/base/scrn-nav.mkiv
+++ b/tex/context/base/scrn-nav.mkiv
@@ -217,7 +217,6 @@
[\c!state=\v!stop,
\c!page=\v!no,
\c!click=\v!yes,
- \c!display=,
\c!openaction=,
\c!closeaction=,
\c!openpageaction=,
diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua
index e06cb0ded..571e9f3ca 100644
--- a/tex/context/base/spac-ver.lua
+++ b/tex/context/base/spac-ver.lua
@@ -72,13 +72,15 @@ local hpack_node = node.hpack
local vpack_node = node.vpack
local writable_spec = nodes.writable_spec
-local glyph = node.id("glyph")
-local penalty = node.id("penalty")
-local kern = node.id("kern")
-local glue = node.id('glue')
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
-local adjust = node.id('adjust')
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local penalty = nodecodes.penalty
+local kern = nodecodes.kern
+local glue = nodecodes.glue
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
+local adjust = nodecodes.adjust
vspacing = vspacing or { }
vspacing.data = vspacing.data or { }
@@ -157,8 +159,8 @@ function vspacing.define_snap_method(name,method)
tex.write(n)
end
---~ local rule_id = node.id("rule")
---~ local vlist_id = node.id("vlist")
+--~ local rule_id = nodecodes.rule
+--~ local vlist_id = nodecodes.vlist
--~ function nodes.makevtop(n)
--~ if n.id == vlist_id then
--~ local list = n.list
@@ -530,47 +532,18 @@ end
-- alignment box begin_of_par vmode_par hmode_par insert penalty before_display after_display
-local user_skip = 0
-local line_skip = 1
-local baseline_skip = 2
-local par_skip = 3
-local above_display_skip = 4
-local below_display_skip = 5
-local above_display_short_skip = 6
-local below_display_short_skip = 7
-local left_skip_code = 8
-local right_skip_code = 9
-local top_skip_code = 10
-local split_top_skip_code = 11
-local tab_skip_code = 12
-local space_skip_code = 13
-local xspace_skip_code = 14
-local par_fill_skip_code = 15
-local thin_mu_skip_code = 16
-local med_mu_skip_code = 17
-local thick_mu_skip_code = 18
-
-local skips = {
- [ 0] = "user_skip",
- [ 1] = "line_skip",
- [ 2] = "baseline_skip",
- [ 3] = "par_skip",
- [ 4] = "above_display_skip",
- [ 5] = "below_display_skip",
- [ 6] = "above_display_short_skip",
- [ 7] = "below_display_short_skip",
- [ 8] = "left_skip_code",
- [ 9] = "right_skip_code",
- [10] = "top_skip_code",
- [11] = "split_top_skip_code",
- [12] = "tab_skip_code",
- [13] = "space_skip_code",
- [14] = "xspace_skip_code",
- [15] = "par_fill_skip_code",
- [16] = "thin_mu_skip_code",
- [17] = "med_mu_skip_code",
- [18] = "thick_mu_skip_code",
-}
+local skipcodes = nodes.skipcodes
+
+local userskip_code = skipcodes.userskip
+local lineskip_code = skipcodes.lineskip
+local baselineskip_code = skipcodes.baselineskip
+local parskip_code = skipcodes.parskip
+local abovedisplayskip_code = skipcodes.abovedisplayskip
+local belowdisplayskip_code = skipcodes.belowdisplayskip
+local abovedisplayshortskip_code = skipcodes.abovedisplayshortskip
+local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip
+local topskip_code = skipcodes.topskip
+local splittopskip_code = skipcodes.splittopskip
local free_glue_node = free_node
local discard, largest, force, penalty, add, disable, nowhite, goback, together = 0, 1, 2, 3, 4, 5, 6, 7, 8
@@ -706,7 +679,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail
elseif id ~= glue then
flush("something else")
current = current.next
- elseif subtype == user_skip then -- todo, other subtypes, like math
+ elseif subtype == userskip_code then -- todo, other subtypes, like math
local sc = has_attribute(current,skip_category) -- has no default, no unset (yet)
local so = has_attribute(current,skip_order ) or 1 -- has 1 default, no unset (yet)
local sp = has_attribute(current,skip_penalty ) -- has no default, no unset (yet)
@@ -832,7 +805,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail
if sc == force then
force_glue = true
end
- elseif subtype == line_skip then
+ elseif subtype == lineskip_code then
if snap then
local s = has_attribute(current,snap_method)
if s and s ~= 0 then
@@ -853,7 +826,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail
flush("lineskip")
end
current = current.next
- elseif subtype == baseline_skip then
+ elseif subtype == baselineskip_code then
if snap then
local s = has_attribute(current,snap_method)
if s and s ~= 0 then
@@ -874,7 +847,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail
flush("baselineskip")
end
current = current.next
- elseif subtype == par_skip then
+ elseif subtype == parskip_code then
-- parskip always comes later
if ignore_whitespace then
if trace then trace_natural("ignored parskip",current) end
@@ -892,7 +865,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail
if trace then trace_natural("honored parskip",current) end
head, current, glue_data = remove_node(head, current)
end
- elseif subtype == top_skip_code or subtype == split_top_skip_code then
+ elseif subtype == topskip_code or subtype == splittopskip_code then
if snap then
local s = has_attribute(current,snap_method)
if s and s ~= 0 then
@@ -911,25 +884,25 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail
flush("topskip")
end
current = current.next
- elseif subtype == above_display_skip then
+ elseif subtype == abovedisplayskip_code then
--
if trace then trace_skip("above display skip (normal)",sc,so,sp,current) end
flush("above display skip (normal)")
current = current.next
--
- elseif subtype == below_display_skip then
+ elseif subtype == belowdisplayskip_code then
--
if trace then trace_skip("below display skip (normal)",sc,so,sp,current) end
flush("below display skip (normal)")
current = current.next
--
- elseif subtype == above_display_short_skip then
+ elseif subtype == abovedisplayshortskip_code then
--
if trace then trace_skip("above display skip (short)",sc,so,sp,current) end
flush("above display skip (short)")
current = current.next
--
- elseif subtype == below_display_short_skip then
+ elseif subtype == belowdisplayshortskip_code then
--
if trace then trace_skip("below display skip (short)",sc,so,sp,current) end
flush("below display skip (short)")
@@ -937,7 +910,7 @@ local function collapser(head,where,what,trace,snap) -- maybe also pass tail
--
else -- other glue
if snap and trace_vsnapping and current.spec.writable and current.spec.width ~= 0 then
- report_snapper("%s of %s (kept)",skips[subtype],current.spec.width)
+ report_snapper("%s of %s (kept)",skipcodes[subtype],current.spec.width)
--~ current.spec.width = 0
end
if trace then trace_skip(format("some glue (%s)",subtype),sc,so,sp,current) end
@@ -1083,8 +1056,10 @@ end
local attribute = attributes.private('graphicvadjust')
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
+local nodecodes = nodes.nodecodes
+
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
local remove_node = nodes.remove
local hpack_node = node.hpack
diff --git a/tex/context/base/strc-bkm.lua b/tex/context/base/strc-bkm.lua
index 79ed867de..5fe9325a6 100644
--- a/tex/context/base/strc-bkm.lua
+++ b/tex/context/base/strc-bkm.lua
@@ -16,8 +16,9 @@ local texsprint, utfvalues = tex.sprint, string.utfvalues
local ctxcatcodes = tex.ctxcatcodes
-local lists = structure.lists
-local levelmap = structure.sections.levelmap
+local lists = structure.lists
+local levelmap = structure.sections.levelmap
+local variables = interfaces.variables
structure.bookmarks = structure.bookmarks or { }
@@ -25,11 +26,29 @@ local bookmarks = structure.bookmarks
bookmarks.method = "internal" -- or "page"
-local names, opened = "", ""
-
-function bookmarks.register(n,o)
- if names == "" then names = n else names = names .. "," .. n end
- if opened == "" then opened = o else opened = opened .. "," .. o end
+local names, opened, forced, numbered = { }, { }, { }, { }
+
+function bookmarks.register(settings)
+ local force = settings.force == variables.yes
+ local number = settings.number == variables.yes
+ local allopen = settings.opened == variables.all
+ for k, v in next, aux.settings_to_hash(settings.names or "") do
+ names[k] = true
+ if force then
+ forced[k] = true
+ if allopen then
+ opened[k] = true
+ end
+ end
+ if number then
+ numbered[k] = true
+ end
+ end
+ if not allopen then
+ for k, v in next, aux.settings_to_hash(settings.opened or "") do
+ opened[k] = true
+ end
+ end
end
function bookmarks.overload(name,text)
@@ -63,23 +82,32 @@ end
-- todo: collect specs and collect later i.e. multiple places
+local numberspec = { }
+
+function structure.bookmarks.setup(spec)
+ -- table.merge(numberspec,spec)
+ for k, v in next, spec do
+ numberspec[k] = v
+ end
+end
+
function bookmarks.place()
- if names ~= "" then
- local list = lists.filter(names,"all",nil,lists.collected)
- local lastlevel = 1
+ if next(names) then
+ local list = lists.filter_collected(names,"all",nil,lists.collected,forced)
if #list > 0 then
- local opened, levels = aux.settings_to_set(opened), { }
+ local levels, lastlevel = { }, 1
for i=1,#list do
local li = list[i]
local metadata = li.metadata
local name = metadata.name
- if not metadata.nolist then -- and levelmap[name] then
+ if not metadata.nolist or forced[name] then -- and levelmap[name] then
local titledata = li.titledata
if titledata then
local structural = levelmap[name]
lastlevel = structural or lastlevel
local title = titledata.bookmark
if not title or title == "" then
+ -- We could typeset the title and then convert it.
if not structural then
-- placeholder, todo: bookmarklabel
title = name .. ": " .. (titledata.title or "?")
@@ -87,47 +115,34 @@ function bookmarks.place()
title = titledata.title or "?"
end
end
+ if numbered[name] then
+ local sectiondata = jobsections.collected[li.references.section]
+ local numberdata = li.numberdata
+ if sectiondata and numberdata and not numberdata.hidenumber then
+ -- we could typeset the number and convert it
+ title = concat(structure.sections.typesetnumber(sectiondata,"direct",numberspec,sectiondata)) .. " " .. title
+ end
+ end
levels[#levels+1] = {
lastlevel,
- stripped(title),
+ stripped(title), -- can be replaced by converter
li.references, -- has internal and realpage
allopen or opened[name]
}
end
end
end
- backends.codeinjections.addbookmarks(levels,bookmarks.method)
+ bookmarks.finalize(levels)
end
function bookmarks.place() end -- prevent second run
end
end
-lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1,"bookmarks")
+function bookmarks.finalize(levels)
+ -- This function can be overloaded by an optional converter
+ -- that uses nodes.toutf on a typeset stream. This is something
+ -- that we will support when the main loop has become a coroutine.
+ backends.codeinjections.addbookmarks(levels,bookmarks.method)
+end
--- bkm
---~ function nodes.toutf(list)
---~ local t= { }
---~ for n in node.traverse(list) do
---~ local id = n.id
---~ if id == node.id("glyph") then
---~ local c = n.char
---~ local f = fonts.ids[n.font]
---~ if f then
---~ local u = f.characters[c].tounicode
---~ if u then
---~ for s in string.gmatch(u,"..") do
---~ t[#t+1] = utf.char(tonumber(s,16))
---~ end
---~ else
---~ t[#t+1] = utf.char(c)
---~ end
---~ else
---~ t[#t+1] = utf.char(c)
---~ end
---~ elseif id == node.id("glue") then
---~ t[#t+1] = " "
---~ end
---~ end
---~ return table.concat(t,"")
---~ end
---~ print(nodes.toutf(tex.box[999].list))
+lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1,"bookmarks")
diff --git a/tex/context/base/strc-bkm.mkiv b/tex/context/base/strc-bkm.mkiv
index 77854738d..f0cfa2a2f 100644
--- a/tex/context/base/strc-bkm.mkiv
+++ b/tex/context/base/strc-bkm.mkiv
@@ -55,18 +55,56 @@
%D Placement \unknown\ look how simple compared to \MKII:
+\newtoks \everysetupbookmarks
+
+\def\bookmarkparameter#1{\ifcsname\??bm#1\endcsname\csname\??bm#1\endcsname\fi}
+
+\unexpanded\def\setupbookmarks[#1]%
+ {\getparameters[\??bm][#1]%
+ \the\everysetupbookmarks}
+
\unexpanded\def\placebookmarks
- {\dodoubleempty\doplacebookmarks}
+ {\dotripleempty\doplacebookmarks}
-\def\doplacebookmarks[#1][#2]%
+\def\doplacebookmarks[#1][#2][#3]%
{\iflocation
- \iffirstargument
- \ctxlua{structure.bookmarks.register("#1","#2")}%
- \else
- \normalexpanded{\noexpand\placebookmarks[\getvalue{\??ih\v!content\c!list}]}%
+ \begingroup
+ \edef\askednames{#1}%
+ \edef\askedopened{#2}%
+ \ifx\askednames\empty
+ \edef\askednames{\getvalue{\??ih\v!content\c!list}}%
\fi
+ \ifx\askednames\empty
+ \let\askednames\v!all
+ \fi
+ \ifthirdargument
+ \getparameters[\??bm][#3]%
+ \else\ifsecondargument
+ \doifassignmentelse{#2}{\let\askedopened\empty\getparameters[\??bm][#2]}\donothing
+ \fi\fi
+ \ctxlua{structure.bookmarks.register {
+ names = "\askednames",
+ opened = "\askedopened",
+ force = "\bookmarkparameter\c!force",
+ number = "\bookmarkparameter\c!number",
+ }}%
+ \endgroup
\fi}
+\setupbookmarks
+ [\c!force=\v!no, % it's easier to force that to inhibit
+ \c!number=\v!yes] % might become v!no
+
+\appendtoks
+ \ctxlua{structure.bookmarks.setup {
+ separatorset = "\bookmarkparameter\c!numberseparatorset",
+ conversionset = "\bookmarkparameter\c!numberconversionset",
+ starter = \!!bs\bookmarkparameter\c!numberstarter\!!es,
+ stopper = \!!bs\bookmarkparameter\c!numberstopper\!!es,
+ segments = "\bookmarkparameter\c!numbersegments",
+ }}%
+\to \everysetupbookmarks
+
% \prependtoks\ctxlua{structure.bookmarks.place()}\to\everystoptext % too late
% \prependtoks\ctxlua{structure.bookmarks.place()}\to\everylastbackendshipout % okay but not nice
diff --git a/tex/context/base/strc-blk.lua b/tex/context/base/strc-blk.lua
index 2589190eb..25c4f2cae 100644
--- a/tex/context/base/strc-blk.lua
+++ b/tex/context/base/strc-blk.lua
@@ -73,8 +73,6 @@ function blocks.setstate(state,name,tag)
end
end
---~ filter_collected(names, criterium, number, collected)
-
function blocks.select(state,name,tag,criterium)
criterium = criterium or "text"
if find(tag,"=") then tag = "" end
@@ -83,7 +81,7 @@ function blocks.select(state,name,tag,criterium)
local tags = not all and aux.settings_to_set(tag)
local hide = state == "process"
local n = structure.sections.number_at_depth(criterium)
- local result = structure.lists.filter_collected("all", criterium, n, collected)
+ local result = structure.lists.filter_collected("all", criterium, n, collected, { })
for i=1,#result do
local ri = result[i]
local metadata = ri.metadata
diff --git a/tex/context/base/strc-des.mkiv b/tex/context/base/strc-des.mkiv
index 42ea701f0..d528ffae9 100644
--- a/tex/context/base/strc-des.mkiv
+++ b/tex/context/base/strc-des.mkiv
@@ -374,13 +374,14 @@
\def\@@stopdescription
{\@@placedescriptionclosesymbol
- \par % else we loose
-\dostoptagged
-\dostoptagged
+ \doifnot{\descriptionparameter\c!display}\v!no\par
+ \dostoptagged
+ \dostoptagged
\endgroup
\descriptionparameter\c!after % which currentdescription is taken here?
- \egroup % temporary hack
- \checknextindentation[\descriptionparameter\c!indentnext]
+ \normalexpanded
+ {\egroup % temporary hack
+ \noexpand\checknextindentation[\descriptionparameter\c!indentnext]}%
\dorechecknextindentation}
\def\@@dodescription
@@ -422,12 +423,12 @@
\ifcsname @@description\currentdescriptionlocation\endcsname \else
\let\currentdescriptionlocation\v!left
\fi
-\dostarttagged\t!description\currentdescription
-\dostarttagged\t!descriptiontag\empty
+ \dostarttagged\t!description\currentdescription
+ \dostarttagged\t!descriptiontag\empty
\@@dostartdescription
\csname @@description\currentdescriptionlocation\endcsname
-\dostoptagged
-\dostarttagged\t!descriptioncontent\empty} % args not needed
+ \dostoptagged
+ \dostarttagged\t!descriptioncontent\empty} % args not needed
\def\@@makedescription[#1]#2%
{\postponenotes % new, assumes grouping
@@ -1048,6 +1049,7 @@
\c!titleright=),
\c!closesymbol=,
\c!closecommand=\wordright,
+ \c!display=\v!yes,
\c!command=,
\c!titlecommand=]
diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua
index 0c5cea64f..3b696fbb0 100644
--- a/tex/context/base/strc-doc.lua
+++ b/tex/context/base/strc-doc.lua
@@ -39,6 +39,9 @@ local sections = structure.sections
local sets = structure.sets
local processors = structure.processors
+local sprintprocessor = processors.sprint
+local ignoreprocessor = processors.ignore
+
-- -- -- document -- -- --
local data
@@ -471,6 +474,51 @@ end
-- sign=positive => also zero
-- sign=hang => llap sign
+--~ todo: test this
+--~
+--~ local function process(index,numbers,ownnumbers,criterium,separatorset,conversion,conversionset,index,entry,preceding,done) -- todo: result
+--~ -- todo: too much (100 steps)
+--~ local number = numbers and (numbers[index] or 0)
+--~ local ownnumber = ownnumbers and ownnumbers[index] or ""
+--~ if number > criterium or (ownnumber ~= "") then
+--~ local block = (entry.block ~= "" and entry.block) or sections.currentblock() -- added
+--~ if preceding then
+--~ local separator = sets.get("structure:separators",block,separatorset,preceding,".")
+--~ if result then
+--~ result[#result+1] = ignoreprocessor(separator)
+--~ else
+--~ sprintprocessor(ctxcatcodes,separator)
+--~ end
+--~ preceding = false
+--~ end
+--~ if result then
+--~ if ownnumber ~= "" then
+--~ result[#result+1] = ownnumber
+--~ elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups)
+--~ result[#result+1] = converters.convert(conversion,number,true)
+--~ else
+--~ local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
+--~ result[#result+1] = converters.convert(theconversion,number,true)
+--~ end
+--~ else
+--~ if ownnumber ~= "" then
+--~ sprintprocessor(ctxcatcodes,ownnumber)
+--~ elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups)
+--~ texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number))
+--~ -- context.convertnumber(conversion,number)
+--~ else
+--~ local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
+--~ sprintprocessor(ctxcatcodes,theconversion,function(str)
+--~ return format("\\convertnumber{%s}{%s}",str or "numbers",number)
+--~ end)
+--~ end
+--~ end
+--~ return index, true -- preceding, done
+--~ else
+--~ return preceding or false, done
+--~ end
+--~ end
+
function sections.typesetnumber(entry,kind,...) -- kind='section','number','prefix'
if entry and entry.hidenumber ~= true then -- can be nil
local separatorset = ""
@@ -535,7 +583,7 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
local numbers, ownnumbers = entry.numbers, entry.ownnumbers
if numbers then
local done, preceding = false, false
- local function process(index) -- move to outer
+ local function process(index,result) -- move to outer
-- todo: too much (100 steps)
local number = numbers and (numbers[index] or 0)
local ownnumber = ownnumbers and ownnumbers[index] or ""
@@ -544,22 +592,35 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
if preceding then
local separator = sets.get("structure:separators",block,separatorset,preceding,".")
if separator then
- processors.sprint(ctxcatcodes,separator)
+ if result then
+ result[#result+1] = ignoreprocessor(separator)
+ else
+ sprintprocessor(ctxcatcodes,separator)
+ end
end
preceding = false
end
- if ownnumber ~= "" then
- processors.sprint(ctxcatcodes,ownnumber)
- -- elseif conversion and conversion ~= "" then
- -- texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number))
- elseif conversion and conversion ~= "" then
- -- traditional (e.g. used in itemgroups)
- texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number))
+ if result then
+ if ownnumber ~= "" then
+ result[#result+1] = ownnumber
+ elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups)
+ result[#result+1] = converters.convert(conversion,number,true)
+ else
+ local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
+ result[#result+1] = converters.convert(theconversion,number,true)
+ end
else
- local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
- processors.sprint(ctxcatcodes,theconversion,function(str)
- return format("\\convertnumber{%s}{%s}",str or "numbers",number)
- end)
+ if ownnumber ~= "" then
+ sprintprocessor(ctxcatcodes,ownnumber)
+ elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups)
+ texsprint(ctxcatcodes,format("\\convertnumber{%s}{%s}",conversion,number))
+ --~ context.convertnumber(conversion,number)
+ else
+ local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers")
+ sprintprocessor(ctxcatcodes,theconversion,function(str)
+ return format("\\convertnumber{%s}{%s}",str or "numbers",number)
+ end)
+ end
end
preceding, done = index, true
else
@@ -567,11 +628,20 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
end
end
--
+ local result = kind == "direct" and { }
+ if result then
+ connector = false
+ end
+ --
local prefixlist = set and sets.getall("structure:prefixes","",set) -- "" == block
if starter then
- processors.sprint(ctxcatcodes,starter)
+ if result then
+ result[#result+1] = ignoreprocessor(starter)
+ else
+ sprintprocessor(ctxcatcodes,starter)
+ end
end
- if prefixlist and (kind == 'section' or kind == 'prefix') then
+ if prefixlist and (kind == 'section' or kind == 'prefix' or kind == 'direct') then
-- find valid set (problem: for sectionnumber we should pass the level)
-- if kind == "section" then
-- no holes
@@ -616,7 +686,7 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
local prefix = prefixlist[k]
local index = sections.getlevel(prefix) or k
if index >= firstprefix and index <= lastprefix then
- process(index)
+ process(index,result)
end
end
-- else
@@ -631,15 +701,24 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref
else
-- also holes check
for prefix=firstprefix,lastprefix do
- process(prefix)
+ process(prefix,result)
end
end
--
if done and connector and kind == 'prefix' then
- processors.sprint(ctxcatcodes,connector)
+ if result then
+ -- can't happen as we're in 'direct'
+ else
+ sprintprocessor(ctxcatcodes,connector)
+ end
elseif done and stopper then
- processors.sprint(ctxcatcodes,stopper)
+ if result then
+ result[#result+1] = ignoreprocessor(stopper)
+ else
+ sprintprocessor(ctxcatcodes,stopper)
+ end
end
+ return result -- a table !
else
-- report_structure("error: no numbers")
end
@@ -686,13 +765,18 @@ function sections.findnumber(depth,what)
end
end
-function sections.fullnumber(depth,what,raw)
+function sections.fullnumber(depth,what)
local sectiondata = sections.findnumber(depth,what)
if sectiondata then
sections.typesetnumber(sectiondata,'section',sectiondata)
end
end
+--~ function sections.directnumber(depth,what)
+--~ local sectiondata = sections.findnumber(depth,what)
+--~ return sectiondata and sections.typesetnumber(sectiondata,'direct',sectiondata) or ""
+--~ end
+
function sections.getnumber(depth,what) -- redefined here
local sectiondata = sections.findnumber(depth,what)
texwrite((sectiondata and sectiondata.numbers[depth]) or 0)
diff --git a/tex/context/base/strc-ini.lua b/tex/context/base/strc-ini.lua
index 36650cd54..f36f79672 100644
--- a/tex/context/base/strc-ini.lua
+++ b/tex/context/base/strc-ini.lua
@@ -232,6 +232,11 @@ function processors.apply(str)
end
end
+function processors.ignore(str)
+ local p, s = lpegmatch(splitter,str)
+ return s or str
+end
+
-- -- -- sets -- -- --
structure.sets = structure.sets or { }
diff --git a/tex/context/base/strc-itm.mkiv b/tex/context/base/strc-itm.mkiv
index e012ce447..40a515a34 100644
--- a/tex/context/base/strc-itm.mkiv
+++ b/tex/context/base/strc-itm.mkiv
@@ -104,7 +104,7 @@
})
}%
\xdef\currentitemattribute{\number\lastdestinationattribute}%
- \begingroup\attribute\destinationattribute\currentitemattribute\kern\zeropoint\endgroup % todo
+ \begingroup\attribute\destinationattribute\currentitemattribute\kern\zeropoint\endgroup % todo, apply attribute to symbol
\fi}
@@ -1258,19 +1258,23 @@
% \item {test} is this okay?
% \stopitemize
-\def\complexitem[#1]#2\par % todo: no two pass data
- {\startitemgroup[#1]%
- \complexdoitemgroupitem[]\begstrut#2\endstrut\par
+% \def\complexitem[#1]#2\par % todo: no two pass data
+% {\startitemgroup[#1]%
+% \complexdoitemgroupitem[]\begstrut#2\endstrut\par
+% \stopitemgroup}
+
+\def\complexitem[#1]#2\par
+ {\doifsomethingelse{#1}{\startitemgroup[#1]}{\startitemgroup[\v!itemize]}%
+ \startitem#2\stopitem
\stopitemgroup}
+\setvalue{\e!start\v!item}%
+ {\startitemgroup[\v!itemize]\startitem
+ \setvalue{\e!stop \v!item}{\endgraf\stopitemgroup}} % inside, else overloaded
+
\definecomplexorsimpleempty\item
\definecomplexorsimpleempty\doitemgroupitem
-\def\complexhead[#1]#2\par#3\par
- {\startitemgroup[#1]%
- \complexdoitemgrouphead[]\begstrut#2\endstrut\par\begstrut#3\endstrut\par
- \stopitemgroup}
-
% the next solution accepts \head test \type{x{x}x} test ...
\let\doenditemhead\relax
diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua
index 6af062134..c2c3c41b8 100644
--- a/tex/context/base/strc-lst.lua
+++ b/tex/context/base/strc-lst.lua
@@ -124,25 +124,25 @@ function lists.enhance(n)
end
end
-function lists.enforce(n)
- -- todo: symbolic names for counters
- local l = cached[n]
- if l then
- --
- l.directives = nil -- might change
- -- save in the right order (happens at shipout)
- lists.tobesaved[#lists.tobesaved+1] = l
- -- default enhancer (cross referencing)
- l.references.realpage = texcount.realpageno
- -- specific enhancer (kind of obsolete)
- local kind = l.metadata.kind
- local enhancer = kind and lists.enhancers[kind]
- if enhancer then
- enhancer(l)
- end
- return l
- end
-end
+--~ function lists.enforce(n)
+--~ -- todo: symbolic names for counters
+--~ local l = cached[n]
+--~ if l then
+--~ --
+--~ l.directives = nil -- might change
+--~ -- save in the right order (happens at shipout)
+--~ lists.tobesaved[#lists.tobesaved+1] = l
+--~ -- default enhancer (cross referencing)
+--~ l.references.realpage = texcount.realpageno
+--~ -- specific enhancer (kind of obsolete)
+--~ local kind = l.metadata.kind
+--~ local enhancer = kind and lists.enhancers[kind]
+--~ if enhancer then
+--~ enhancer(l)
+--~ end
+--~ return l
+--~ end
+--~ end
-- we can use level instead but we can also decide to remove level from the metadata
@@ -163,17 +163,17 @@ end
-- will be split
-local function filter_collected(names, criterium, number, collected, nested)
+local function filter_collected(names, criterium, number, collected, forced, nested) -- names is hash or string
local numbers, depth = documents.data.numbers, documents.data.depth
- local hash, result, all, detail = { }, { }, not names or names == "" or names == variables.all, nil
- names, criterium = gsub(names," ",""), gsub(criterium," ","")
- if trace_lists then
- report_lists("filtering names: %s, criterium: %s, number: %s",names,criterium,number or "-")
+ local result, detail = { }, nil
+ criterium = gsub(criterium," ","") -- not needed
+ forced = forced or { } -- todo: also on other branched, for the moment only needed for bookmarks
+ if type(names) == "string" then
+ names = aux.settings_to_hash(names)
end
- if not all then
- for s in gmatch(names,"[^, ]+") do -- sort of settings to hash
- hash[s] = true
- end
+ local all = not next(names) or names[variables.all] or false
+ if trace_lists then
+ report_lists("filtering names: %s, criterium: %s, number: %s",aux.simple_hash_to_string(names),criterium,number or "-")
end
if criterium == variables.intro then
-- special case, no structure yet
@@ -184,15 +184,16 @@ local function filter_collected(names, criterium, number, collected, nested)
result[#result+1] = v
end
end
- elseif criterium == variables.all or criterium == variables.text then
+ elseif all or criterium == variables.all or criterium == variables.text then
for i=1,#collected do
local v = collected[i]
local r = v.references
if r then
- local sectionnumber = (r.section == 0) or jobsections.collected[r.section]
- if sectionnumber then -- and not sectionnumber.hidenumber then
- local metadata = v.metadata
- if metadata and not metadata.nolist and (all or hash[metadata.name or false]) then
+ local metadata = v.metadata
+ if metadata then
+ local name = metadata.name or false
+ local sectionnumber = (r.section == 0) or jobsections.collected[r.section]
+ if forced[name] or (sectionnumber and not metadata.nolist and (all or names[name])) then -- and not sectionnumber.hidenumber then
result[#result+1] = v
end
end
@@ -200,7 +201,7 @@ local function filter_collected(names, criterium, number, collected, nested)
end
elseif criterium == variables.current then
if depth == 0 then
- return filter_collected(names,variables.intro,number,collected)
+ return filter_collected(names,variables.intro,number,collected,forced)
else
for i=1,#collected do
local v = collected[i]
@@ -211,7 +212,7 @@ local function filter_collected(names, criterium, number, collected, nested)
local cnumbers = sectionnumber.numbers
local metadata = v.metadata
if cnumbers then
- if metadata and not metadata.nolist and (all or hash[metadata.name or false]) and #cnumbers > depth then
+ if metadata and not metadata.nolist and (all or names[metadata.name or false]) and #cnumbers > depth then
local ok = true
for d=1,depth do
local cnd = cnumbers[d]
@@ -232,7 +233,7 @@ local function filter_collected(names, criterium, number, collected, nested)
elseif criterium == variables.here then
-- this is quite dirty ... as cnumbers is not sparse we can misuse #cnumbers
if depth == 0 then
- return filter_collected(names,variables.intro,number,collected)
+ return filter_collected(names,variables.intro,number,collected,forced)
else
for i=1,#collected do
local v = collected[i]
@@ -244,7 +245,7 @@ local function filter_collected(names, criterium, number, collected, nested)
local metadata = v.metadata
if cnumbers then
--~ print(#cnumbers, depth, table.concat(cnumbers))
- if metadata and not metadata.nolist and (all or hash[metadata.name or false]) and #cnumbers >= depth then
+ if metadata and not metadata.nolist and (all or names[metadata.name or false]) and #cnumbers >= depth then
local ok = true
for d=1,depth do
local cnd = cnumbers[d]
@@ -264,7 +265,7 @@ local function filter_collected(names, criterium, number, collected, nested)
end
elseif criterium == variables.previous then
if depth == 0 then
- return filter_collected(names,variables.intro,number,collected)
+ return filter_collected(names,variables.intro,number,collected,forced)
else
for i=1,#collected do
local v = collected[i]
@@ -275,7 +276,7 @@ local function filter_collected(names, criterium, number, collected, nested)
local cnumbers = sectionnumber.numbers
local metadata = v.metadata
if cnumbers then
- if metadata and not metadata.nolist and (all or hash[metadata.name or false]) and #cnumbers >= depth then
+ if metadata and not metadata.nolist and (all or names[metadata.name or false]) and #cnumbers >= depth then
local ok = true
for d=1,depth-1 do
local cnd = cnumbers[d]
@@ -296,11 +297,11 @@ local function filter_collected(names, criterium, number, collected, nested)
elseif criterium == variables["local"] then -- not yet ok
local nested = nesting[#nesting]
if nested then
- return filter_collected(names,nested.name,nested.number,collected,nested)
+ return filter_collected(names,nested.name,nested.number,collected,forced,nested)
elseif sections.autodepth(documents.data.numbers) == 0 then
- return filter_collected(names,variables.all,number,collected)
+ return filter_collected(names,variables.all,number,collected,forced)
else
- return filter_collected(names,variables.current,number,collected)
+ return filter_collected(names,variables.current,number,collected,forced)
end
else -- sectionname, number
-- not the same as register
@@ -321,7 +322,7 @@ local function filter_collected(names, criterium, number, collected, nested)
local metadata = v.metadata
local cnumbers = sectionnumber.numbers
if cnumbers then
- if (all or hash[metadata.name or false]) and #cnumbers >= depth and matching_till_depth(depth,cnumbers,parent) then
+ if (all or names[metadata.name or false]) and #cnumbers >= depth and matching_till_depth(depth,cnumbers,parent) then
result[#result+1] = v
end
end
@@ -342,8 +343,8 @@ end
lists.filter_collected = filter_collected
-function lists.filter(names, criterium, number)
- return filter_collected(names, criterium, number, lists.collected)
+function lists.filter(names, criterium, number, forced)
+ return filter_collected(names, criterium, number, lists.collected, forced)
end
lists.result = { }
diff --git a/tex/context/base/strc-lst.mkiv b/tex/context/base/strc-lst.mkiv
index 83faf75a7..5db22d1d7 100644
--- a/tex/context/base/strc-lst.mkiv
+++ b/tex/context/base/strc-lst.mkiv
@@ -577,13 +577,18 @@
\def\domakelistelement#1#2#3#4% ref internal command data
{\dontleavehmode
- \iflocation % we cannot tewak \iflocation as we nest
+ \iflocation % we cannot tweak \iflocation as we nest
\doifelse{\listparameter\c!interaction}{#1}
- {\directgoto{\setlocationcolor\??ia#4}[internal(#2)]}% was \directgotobox
- {#3{#4}}%
- \else
+ {\begingroup
+ \doif{\namedstructureheadparameter\currentlist\c!interaction}\v!list
+ {\dosetsimplepagereference{bck:#2}%
+ \attribute\destinationattribute\currentdestinationattribute}%
+ \directgoto{\setlocationcolor\??ia#4}[internal(#2)]% we can get the attribute instead so then we don't need a goto
+ \endgroup}% was \directgotobox
+ {#3{#4}}%
+ \else
#3{#4}%
- \fi}
+ \fi}
\def\dodofreelistelement#1#2#3#4#5#6#7#8%
{\listparameter\c!before% can be \hskip
diff --git a/tex/context/base/strc-not.lua b/tex/context/base/strc-not.lua
index 466bc7a03..f0bf6cab3 100644
--- a/tex/context/base/strc-not.lua
+++ b/tex/context/base/strc-not.lua
@@ -304,7 +304,11 @@ function notes.flush(tag,whatkind) -- store and postpone
if trace_notes then
report_notes("flushing state %s of %s from %s to %s",whatkind,tag,ns,#nd)
end
+ -- todo: as registers: start, stop, inbetween
for i=ns,#nd do
+ if i > ns then
+ texsprint(ctxcatcodes,format("\\betweennoteitself{%s}",tag))
+ end
texsprint(ctxcatcodes,format("\\handlenoteitself{%s}{%s}",tag,i))
end
end
diff --git a/tex/context/base/strc-not.mkii b/tex/context/base/strc-not.mkii
index f6fae3378..a47d796e0 100644
--- a/tex/context/base/strc-not.mkii
+++ b/tex/context/base/strc-not.mkii
@@ -285,8 +285,6 @@
% todo: make sure less calls, is quite some code
-% BEWARE, OVERLOADED IN cont-new.mkiv
-
\def\dochecknote % only to be called locally, some bools will become class-ones
{% for the moment no mixed text/endnotes modes, so we use
% \footnoteparameter and not \noteparameter (**)
diff --git a/tex/context/base/strc-not.mkiv b/tex/context/base/strc-not.mkiv
index 58229a54f..0a631ce0c 100644
--- a/tex/context/base/strc-not.mkiv
+++ b/tex/context/base/strc-not.mkiv
@@ -195,6 +195,8 @@
%\c!next=\autoinsertnextspace
\c!prefix=\v!no,
%\c!continue=\v!no,
+ \c!paragraph=\v!no,
+ \c!inbetween=\hskip1em,
\c!n=1]
\setupnotes
@@ -338,8 +340,8 @@
% compatibility (will go away)
-\newif\ifendnotes
-\newif\ifbottomnotes
+\newif\ifbottomnotes % still used in page-one.mkiv
+%newif\endnotes % no longer used
% locations:
@@ -371,18 +373,21 @@
\def\dochecknote
{% node states
- \setnotelocation\plusone
- \setnoteposition\plustwo
+ \setnotelocation\plusone % page
+ \setnoteposition\plustwo % high
\normalexpanded{\noexpand\rawprocesscommalist[\noteparameter\c!location]}\dosetcheckednote
% compatibility hack
- \ifnum\noteparameter\s!noteloc=\plusfive \endnotestrue \else \endnotesfalse \fi
+ %ifnum\noteparameter\s!noteloc=\plusfive \endnotestrue \else \endnotesfalse \fi
\ifnum\noteparameter\s!notepos=\plustwo \bottomnotestrue \else \bottomnotesfalse \fi
% set column multiplier
\edef\currentnotenofcolumns{\noteparameter\c!n}%
\ifx\currentnotenofcolumns\empty
\let\currentnotenofcolumns\!!plusone
\fi
- \ifcase\noteparameter\s!noteloc\or
+ \ifcase\noteparameter\s!noteloc
+ % can't happen
+ \scratchcounter\plusone
+ \or
% page
\scratchcounter \currentnotenofcolumns
\or
@@ -399,6 +404,9 @@
\scratchcounter\currentnotenofcolumns
\fi
% column factor
+ \ifcase\scratchcounter
+ \scratchcounter\plusone
+ \fi
\global\count\currentnoteins\plusthousand
\global\count\currentnoteins\numexpr\plusthousand/\scratchcounter\relax
% maximize height
@@ -704,18 +712,28 @@
\normalexpanded{\noexpand\ctxlatelua{structure.notes.setsymbolpage("#1",#2,#3)}}%
\fi}
-\def\handlenoteinsert#1#2%
+\def\handlenoteinsert#1#2% tg, id
{\begingroup
\edef\currentnote{#1}%
\the\everybeforenoteinsert
\insert\currentnoteins\bgroup
\the\everyinsidenoteinsert
\doprocesslocalsetups{\noteparameter\c!setups}% experimental
- \handlenoteitself{#1}{#2}%
+ \doifelse{\noteparameter\c!paragraph}\v!yes
+ {\nointerlineskip
+ \startvboxtohbox
+ \handlenoteitself{#1}{#2}%
+ % add some slack
+ \stopvboxtohbox}
+ {\handlenoteitself{#1}{#2}}%
\egroup
\the\everyafternoteinsert
\endgroup}
+\def\betweennoteitself#1% tg
+ {\edef\currentnote{#1}%
+ \doif{\noteparameter\c!paragraph}\v!yes\dobetweenparagraphnotes}
+
\def\handlenoteitself#1#2% tg, id
{\edef\currentdescription{#1}%
\edef\currentnote{#1}%
@@ -750,10 +768,8 @@
%D mainly because endnotes had to be supported.} that is,
%D automatically (vise versa) and by user supplied reference.
-\newcount\internalnotereference
-
-\let\startpushnote=\relax
-\let\stoppushnote =\relax
+\let\startpushnote\relax
+\let\stoppushnote \relax
\newsignal\notesignal
\newcount \notepenalty
@@ -783,9 +799,9 @@
\splitmaxdepth\strutdp % not actually needed here
\leftmargindistance\noteparameter\c!margindistance
\rightmargindistance\leftmargindistance
- \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ?
- \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ?
- \fi
+% \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ?
+% \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ?
+% \fi
\to \everyinsidenoteinsert
% not: \appendtoks \setnotehsize \to \everyinsidenoteinsert (spoils columns)
@@ -836,6 +852,47 @@
\unexpanded\def\unvboxed {\ifvmode\unvbox \else\box \fi}
\unexpanded\def\unvcopied{\ifvmode\unvcopy\else\copy\fi}
+% idea: tag with attr and then just flush them again
+
+\def\dobetweenparagraphnotes % should not be too much
+ {\noteparameter\c!inbetween}
+
+\def\doflushgobalnotes
+ {\doifelse{\noteparameter\c!paragraph}\v!yes
+ {\vbox
+ {\beginofshapebox
+ \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins
+ \endofshapebox
+ %\doreshapebox{\box\shapebox}{}{}{}% get rid of penalties etc
+ \gdef\dodobetweenparagraphnotes{\glet\dodobetweenparagraphnotes\dobetweenparagraphnotes}% shape works reverse
+ \doreshapebox{\hbox{\unhbox\shapebox\dodobetweenparagraphnotes}}{}{}{}% get rid of penalties etc
+ \innerflushshapebox
+ \convertvboxtohbox}}
+ {\iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins}}
+
+\def\dodoplacenoteinserts
+ {\ifcase\noteparameter\c!n\relax
+ % should not happen
+ \or
+ \doglobalflushnotesnormal
+ \else
+ \doglobalflushnotescolums
+ \fi}
+
+\def\doglobalflushnotesnormal
+ {%\iftrialtypesetting\copy\else\box\fi\currentnoteins
+ \doflushgobalnotes
+ \obeydepth} % (a) added , since split footnotes will not align properly
+
+\def\doglobalflushnotescolums
+ {\edef\currentnotewidth{\noteparameter\c!width}%
+ \doifdimensionelse\currentnotewidth\donothing
+ {\edef\currentnotewidth{\the\hsize}}%
+ \startsimplecolumns[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\currentnotewidth]%
+ %\iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins % compare with local
+ \doflushgobalnotes
+ \stopsimplecolumns}
+
\def\doplacenoteinserts
{\relax\ifdim\ht\currentnoteins>\zeropoint\relax
\ifnum\noteparameter\s!noteloc=\plusfive
@@ -845,24 +902,15 @@
\whitespace
\noteparameter\c!before
\fi
-% \bgroup
-% \setupalign[\noteparameter\c!align]%
+ % \bgroup
+ % \setupalign[\noteparameter\c!align]%
\placenoterule % alleen in ..mode
-% \par
-% \egroup
+ % \par
+ % \egroup
\bgroup
\setnotebodyfont
\setbox\scratchbox\hbox
- {% this should be checked, smells like a mix-up
- % does not split: \ifcase\noteparameter\c!n\unvbox\else\box\fi\currentnoteins
- \ifcase\noteparameter\c!n\relax
- \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins % is this needed?
- \or
- \iftrialtypesetting\copy\else\box\fi\currentnoteins
- \obeydepth % (a) added , since split footnotes will not align properly
- \else
- \iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteins
- \fi}%
+ {\dodoplacenoteinserts}%
\setbox\scratchbox\hbox
{\localframed
[\??vn\currentnote]
@@ -995,7 +1043,7 @@
\the\everyplacelocalnotes
% beware, we cannot trust setting \currentnote here
\getparameters[\??vn#2][\c!width=\v!fit,\c!height=\v!fit,\c!strut=\v!no,\c!offset=\v!overlay,#1]% we only need a selective one
- \donotealternative{#2}%
+ \dolocalnotealternative{#2}%
\endgroup
\dochecknote} % we need to restore the old state
@@ -1065,7 +1113,7 @@
\def\doifnotescollected#1%
{\ctxlua{structure.notes.doifcontent("#1")}}
-\def\donotealternative#1%
+\def\dolocalnotealternative#1%
{\edef\currentnote{#1}%
\doifnotescollected\currentnote
{\endgraf
diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua
index 8fab48697..03c755f57 100644
--- a/tex/context/base/strc-ref.lua
+++ b/tex/context/base/strc-ref.lua
@@ -922,7 +922,7 @@ function jobreferences.doifelse(prefix,reference,highlight,newwindow,layer)
end
function jobreferences.setinternalreference(prefix,tag,internal,view)
- local t = { }
+ local t = { } -- maybe add to current
if tag then
if prefix and prefix ~= "" then
prefix = prefix .. ":"
@@ -943,12 +943,11 @@ function jobreferences.setinternalreference(prefix,tag,internal,view)
return destination
end
-function jobreferences.getinternalreference(n) -- n points into list
+function jobreferences.getinternalreference(n) -- n points into list (todo: registers)
local l = structure.lists.collected[n]
texsprint(ctxcatcodes,(l and l.references.internal) or n)
end
-
--
function jobreferences.get_current_metadata(tag)
diff --git a/tex/context/base/strc-ref.mkiv b/tex/context/base/strc-ref.mkiv
index 91e975ea9..408673f83 100644
--- a/tex/context/base/strc-ref.mkiv
+++ b/tex/context/base/strc-ref.mkiv
@@ -127,8 +127,11 @@
\def\dododosetreference#1#2#3#4% kind labels userdata text -> todo: userdata
{\ifreferencing
+ % we could have a more efficient one for page references but for the moment
+ % we don't care too much
\edef\currentreferencekind{#1}%
\edef\currentreferencelabels{#2}%
+ \edef\currentreferenceuserdata{#3}%
\edef\currentreferenceexpansion{\@@rfexpansion}% {\referenceparameter\c!expansion}
\ifx\currentreferencelabels\empty \else
\ifx\currentreferenceexpansion\s!xml
@@ -153,19 +156,24 @@
block = "\currentstructureblock",
section = structure.sections.currentid(),
},
- metadata = {
- kind = "#1",
- catcodes = \the\catcodetable,
- xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text
+ metadata = { % we could assume page to have no metadata
+ kind = "#1",
+ \ifx\currentreferencekind\s!page\else
+ catcodes = \the\catcodetable,
+ xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text
+ \fi
},
\ifx\currentreferencedata\empty\else
entries = {
text = \!!bs\currentreferencedata\!!es
},
\fi
- userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es)
+ \ifx\currentreferenceuserdata\empty\else
+ userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es)
+ \fi
},"\@@iafocus")
}%
+ % todo: optional
\xdef\currentdestinationattribute{\number\lastdestinationattribute}%
\begingroup\attribute\destinationattribute\currentdestinationattribute\hbox{}\endgroup % todo
\fi
@@ -174,6 +182,34 @@
\def\defaultreferencepage#1{[[[#1]]]}
\def\defaultreferencetext#1{[[[#1]]]}
+%D For internal usage:
+
+\def\dosetsimplepagereference#1% label
+ {\iflocation
+ \ctxlua{jobreferences.setandgetattribute("\s!page", "\referenceprefix","#1",
+ {
+ references = {
+ % block = "\currentstructureblock",
+ % section = structure.sections.currentid(),
+ },
+ metadata = { % we could assume page to have no metadata
+ kind = "\s!page",
+ },
+ },"\@@iafocus")
+ }%
+ \xdef\currentdestinationattribute{\number\lastdestinationattribute}%
+ \else
+ \xdef\currentdestinationattribute{\number\attributeunsetvalue}%
+ \fi}
+
+\def\dogetsimplepagereference#1%
+ {\iflocation
+ \ctxlua{jobreferences.inject("\referenceprefix","#1",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}%
+ \xdef\currentreferenceattribute{\number\lastreferenceattribute}%
+ \else
+ \xdef\currentreferenceattribute{\number\attributeunsetvalue}%
+ \fi}
+
%D These macros depend on three other ones,
%D \type {\makesectionformat}, that generated \type
%D {\sectionformat}, \type {\pagenumber}. The not yet used
@@ -453,14 +489,26 @@
%D An unknown reference is reported on the screen, in the log
%D file and, when enabled, in the left margin of the text.
-\def\reportreferenceerror#1#2% only once (keep track in lua)
+\def\reportreferenceerror#1#2#3% only once (keep track in lua)
{\ifinpagebody \else
- \doifconcepttracing{\doifsomething{#2}{\inleft{\infofont\doboundtext{#2}{\dimexpr\leftmarginwidth-2em\relax}{..}->}}}%
+ \doifconcepttracing{\doifsomething{#3}{\inleft{\infofont\doboundtext{#3}{\dimexpr\leftmarginwidth-2em\relax}{..}->}}}%
\fi
- \showmessage\m!references{#1}{[\referenceprefix][#2]}}
+ \global\advance#1\plusone
+ \showmessage\m!references{#2}{[\referenceprefix][#3]}}
-\def\unknownreference{\reportreferenceerror1}
-\def\illegalreference{\reportreferenceerror4}
+\newcount\nofunknownreferences
+\newcount\nofillegalreferences
+
+\def\unknownreference{\reportreferenceerror\nofunknownreferences1}
+\def\illegalreference{\reportreferenceerror\nofillegalreferences4}
+
+\def\reportreferenceproblems
+ {\ifcase\nofunknownreferences\else\showmessage\m!references5{\number\nofunknownreferences}\fi
+ \ifcase\nofillegalreferences\else\showmessage\m!references6{\number\nofillegalreferences}\fi}
+
+\appendtoks
+ \reportreferenceproblems
+\to \everystoptext
%D When a reference is not found, we typeset a placeholder
%D (two glyphs are often enough to represent the reference
@@ -541,7 +589,10 @@
{\ctxlua{jobreferences.currentorder("#1","#2")}}
\def\thisissomeinternal#1#2% tag reference (only for old time sake)
- {\begingroup\attribute\destinationattribute\ctxlua{jobreferences.mark("#1:#2")}\hbox{}\endgroup}
+ {\begingroup
+ \ctxlua{jobreferences.setinternalreference("","#1:#2")}%
+ \hbox attr \destinationattribute\lastdestinationattribute{}%
+ \endgroup}
\def\gotosomeinternal#1#2#3#4%
{\ifinternalnamedreferences
@@ -866,8 +917,11 @@
%D The other alternatives just conform their names: only the
%D label, only the text, or the label and the text.
+% \def\dounknownreference#1#2[#3]%
+% {\unknownreference{#3}\dotextprefix{#2}\dummyreference}%
+
\def\dounknownreference#1#2[#3]%
- {\unknownreference{#3}\dotextprefix{#2}\dummyreference}%
+ {\unknownreference{#3}\dotextprefix{#2}{\leftofreference\dummyreference\rightofreference}}
\def\docompletereference#1#2[#3]%
{\goto{\dotextprefix{#2}#1}[#3]}
@@ -885,114 +939,15 @@
\let\dowantedreference\docompletereference
-%D \macros
-%D {definereferenceformat}
-%D
-%D The next few macros were made for for David Arnold and Taco
-%D Hoekwater. They can be used for predefining reference
-%D texts, and thereby stimulate efficiency.
-%D
-%D [more documentation will be added]
-%D
-%D \starttyping
-%D \definereferenceformat[informula] [left=(,right=),text=formula]
-%D \definereferenceformat[informulas] [left=(,right=),text=formulas]
-%D \definereferenceformat[andformula] [left=(,right=),text=and]
-%D \definereferenceformat[andformulas][left=(,right=),text=and]
-%D
-%D \informula [b] and \informula [for:c]
-%D the \informula {formulas}[b] \informula {and} [for:c]
-%D the \informulas {formulas}[b] \informula {and} [for:c]
-%D the \informulas [b] \informula {en} [for:c]
-%D the \informulas [b] \andformula [for:c]
-%D \stoptyping
-%D
-%D Instead of a text, one can specify a label, which should
-%D be defined with \type {\setuplabeltext}.
-
-% todo: inherit; probably not yet mkiv okay
-
-\unexpanded\def\definereferenceformat
- {\dodoubleargument\dodefinereferenceformat}
-
-\def\dodefinereferenceformat[#1][#2]%
- {\iffirstargument
- \getparameters[\??rf#1]
- [\c!left=, % of the number
- \c!right=, % of the number
- \c!text=, % before the number
- \c!label=, % can be {left}{right}
- \c!command=\in,
- #2]%
- \setuvalue{#1}{\dontleavehmode\doexecutereferenceformat{#1}}%
- \fi}
-
-\def\noexecutelabelreferenceformat#1%
- {\doifvaluesomething{\??rf#1\c!text}{\gdef\textofreference{\csname\??rf#1\c!text\endcsname}}%
- \csname\??rf#1\c!command\endcsname}
-
-\def\doexecutelabelreferenceformat#1%
- {\csname\??rf#1\c!command\endcsname
- {\leftlabeltext {\csname\??rf#1\c!label\endcsname}}%
- {\rightlabeltext{\csname\??rf#1\c!label\endcsname}}}
-
-\def\doexecutereferenceformat#1%
- {\gdef\leftofreference {\csname\??rf#1\c!left \endcsname}%
- \gdef\rightofreference{\csname\??rf#1\c!right\endcsname}%
- \glet\textofreference\empty % otherwise ~ added
- \doifelsevaluenothing{\??rf#1\c!label}\noexecutelabelreferenceformat\doexecutelabelreferenceformat{#1}}
-
-\newtoks\everyresetreferenceformat
-
-\def\resetreferenceformat
- {\the\everyresetreferenceformat}
-
-\appendtoks
- \glet\leftofreference \relax
- \glet\rightofreference\relax
- \glet\textofreference \relax
-\to \everyresetreferenceformat
+\unexpanded\def\dospecialin{\dontleavehmode\begingroup\doinatreference\currentreferencedefault} % ends in \doinatreference
+\unexpanded\def\dospecialat{\dontleavehmode\begingroup\doinatreference\currentreferencepage } % ends in \doinatreference
-\resetreferenceformat
-
-% fails on metafun {\leftofreference#1\ignorespaces#3\removeunwantedspaces\rightofreference}{#2}[#4]%
-%
-% \def\dodododoinatreference#1#2#3[#4]% no \removeunwantedspaces (fails on metafun)
-% {\ifx\next\bgroup
-% \dododododoinatreference{\leftofreference#1\ignorespaces#3\rightofreference}{#2}[#4]%
-% \else
-% \dododododoinatreference{\leftofreference#1\rightofreference}{#2#3}[#4]%
-% \fi}
-%
-% \def\dododododoinatreference#1#2[#3]%
-% {\dontleavehmode % replaces \leaveoutervmode
-% \begingroup
-% \postponenotes
-% \doifreferencefoundelse{#3}
-% {\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#3]}%
-% {\dounknownreference{#1}{#2}[#3]}%
-% \endgroup}
-
-% \starttext
-% \definereferenceformat[inxx] [left=(,right=),text=txt]
-% \setupinteraction[state=start]
-% \chapter[one]{xx}
-% [\goto{state}[file(mk-last-state)]]
-% [\goto{state} [file(mk-last-state)]]
-% [\at{page} [one]]
-% [\at{page}[one]]
-% [\at{page}{okay}[one]]
-% [\inxx{a}{b}[one]]
-% \stoptext
+\newtoks\leftreferencetoks \newtoks\defaultleftreferencetoks \glet\leftofreference \relax
+\newtoks\rightreferencetoks \newtoks\defaultrightreferencetoks \glet\rightofreference\relax
-\unexpanded\def\dospecialin{\let\currentreferencecontent\currentreferencedefault\doinatreference}
-\unexpanded\def\dospecialat{\let\currentreferencecontent\currentreferencepage \doinatreference}
-
-\newtoks\leftreferencetoks % needs a reset too?
-\newtoks\rightreferencetoks
-
-\def\doinatreference
- {\futurelet\next\doinatreferenceone}
+\def\doinatreference#1%
+ {\let\currentreferencecontent#1%
+ \futurelet\next\doinatreferenceone}
\def\doinatreferenceone
{\ifx\next\bgroup
@@ -1017,8 +972,8 @@
\def\dodoinatreferencenone
{\dodoinatreferenceindeed
- {\leftofreference\currentreferencecontent\rightofreference}
- {}}
+ {\the\defaultleftreferencetoks\leftofreference\currentreferencecontent\rightofreference}
+ {\the\defaultrightreferencetoks}}
\def\dodoinatreferenceleft
{\dodoinatreferenceindeed
@@ -1026,22 +981,126 @@
{\the\leftreferencetoks}}
\def\dodoinatreferenceboth
- {\dodoinatreferenceindeed
+ {\doifnothing{\the\leftreferencetoks}
+ {\leftreferencetoks\defaultleftreferencetoks}%
+ \dodoinatreferenceindeed
{\leftofreference\currentreferencecontent\the\rightreferencetoks\rightofreference}
{\the\leftreferencetoks}}
+% lefttext left <ref> right righttext
+
+\newtoks\everyresetinatreference
+
\def\dodoinatreferenceindeed#1#2#3[#4]% #3 gobbles space
- {\dontleavehmode % replaces \leaveoutervmode
- \begingroup
+ {%\dontleavehmode\begingroup % already done
\postponenotes
\doifreferencefoundelse{#4}
{\doifelsenothing{#1}\dosymbolreference\dowantedreference{#1}{#2}[#4]}%
{\dounknownreference{#1}{#2}[#4]}%
- \resetreferenceformat
+ \the\everyresetinatreference
\endgroup}
\let\dosymbolreference\dowantedreference
+\appendtoks
+ \glet\leftofreference \relax
+ \glet\rightofreference\relax
+\to \everyresetinatreference
+
+%D \macros
+%D {definereferenceformat}
+%D
+%D The next few macros were made for for David Arnold and Taco
+%D Hoekwater. They can be used for predefining reference
+%D texts, and thereby stimulate efficiency.
+%D
+%D \starttyping
+%D \definereferenceformat[informula] [left=(,right=),text=formula]
+%D \definereferenceformat[informulas] [left=(,right=),text=formulas]
+%D \definereferenceformat[andformula] [left=(,right=),text=and]
+%D \definereferenceformat[andformulas][left=(,right=),text=and]
+%D
+%D \informula [b] and \informula [for:c]
+%D the \informula {formulas}[b] \informula {and} [for:c]
+%D the \informulas {formulas}[b] \informula {and} [for:c]
+%D the \informulas [b] \informula {en} [for:c]
+%D the \informulas [b] \andformula [for:c]
+%D \stoptyping
+%D
+%D Instead of a text, one can specify a label, which should
+%D be defined with \type {\setuplabeltext}.
+%D
+%D
+%D Watch out: the second argument is somewhat special and mostly
+%D meant for a suffix to a number:
+%D
+%D \startbuffer
+%D \definereferenceformat [intesta] [left=(,right=),text=Whatever~]
+%D \definereferenceformat [intestb] [left=(,right=),label=figure]
+%D
+%D \placeformula[x]\startformula a \stopformula
+%D
+%D \starttabulate[|||||]
+%D \NC \in [x] \NC \in {left}[x] \NC \in {}{right}[x] \NC \in {left}{right}[x] \NC \NR
+%D \NC \intesta[x] \NC \intesta{left}[x] \NC \intesta{}{right}[x] \NC \intesta{left}{right}[x] \NC \NR
+%D \NC \intestb[x] \NC \intestb{left}[x] \NC \intestb{}{right}[x] \NC \intestb{left}{right}[x] \NC \NR
+%D \stoptabulate
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+% todo: inherit
+
+\let\currentreferenceformat\empty
+
+\def\referenceformatparameter#1% some day we will add inheritance
+ {\ifcsname\??rf\currentreferenceformat#1\endcsname\csname\??rf\currentreferenceformat#1\expandafter\endcsname\fi}
+
+\unexpanded\def\definereferenceformat
+ {\dodoubleargument\dodefinereferenceformat}
+
+% left right text label
+
+\def\dodefinereferenceformat[#1][#2]%
+ {\iffirstargument
+ \getparameters[\??rf#1][\c!left=,\c!right=,\c!text=,\c!label=,#2]%
+ \setuvalue{#1}{\doexecutereferenceformat{#1}}%
+ \fi}
+
+\def\doexecutereferenceformat#1%
+ {\dontleavehmode\begingroup % ends in \doinatreference
+ \edef\currentreferenceformat{#1}%
+ \gdef\leftofreference {\referenceformatparameter\c!left }%
+ \gdef\rightofreference{\referenceformatparameter\c!right}%
+ % we can make a helper for this .. we will use the new parameter handler anyway
+ % but at least aditya can play with it now
+ \doifsomething{\referenceformatparameter\c!style}
+ {\dosetfontattribute{\??rf\currentreferenceformat}\c!style
+ \let\@@iastyle\empty}%
+ \doifsomething{\referenceformatparameter\c!color}
+ {\dosetcolorattribute{\??rf\currentreferenceformat}\c!color
+ \let\@@iacontrastcolor\empty
+ \let\@@iacolor \empty}%
+ %
+ \doifsomethingelse{\referenceformatparameter\c!label}
+ {\defaultleftreferencetoks {\leftlabeltext {\referenceformatparameter\c!label}}%
+ \defaultrightreferencetoks{\rightlabeltext{\referenceformatparameter\c!label}}}%
+ {\defaultleftreferencetoks {\referenceformatparameter\c!text}%
+ \defaultrightreferencetoks\emptytoks}%
+ \doinatreference\currentreferencedefault} % we can make \currentreferencedefault configurable
+
+% \starttext
+% \definereferenceformat[inxx] [left=(,right=),text=txt]
+% \setupinteraction[state=start]
+% \chapter[one]{xx}
+% [\goto{state}[file(mk-last-state)]]
+% [\goto{state} [file(mk-last-state)]]
+% [\at{page} [one]]
+% [\at{page}[one]]
+% [\at{page}{okay}[one]]
+% [\inxx{a}{b}[one]]
+% \stoptext
+
%D In interactive documents going to a specific location is not
%D bound to cross references. The \type{\goto} commands can be
%D used to let users access another part of the document. In
@@ -1081,14 +1140,16 @@
\begingroup
\attribute\referenceattribute\attributeunsetvalue
\iflocation
-\dostarttagged\t!link\empty
+ \dostarttagged\t!link\empty % not here
\ctxlua{jobreferences.inject("\referenceprefix","#2",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}%
-\dostoptagged
\setlocationattributes\??ia
\setstrut % can be option
\attribute\referenceattribute\lastreferenceattribute
+ #1%
+ \dostoptagged
+ \else
+ #1%
\fi
- #1%
\endgroup}
\def\dodirectgotohtdp#1[#2]% no test for valid references
@@ -1096,9 +1157,9 @@
\begingroup
\attribute\referenceattribute\attributeunsetvalue
\iflocation
-\dostarttagged\t!link\empty
+ \dostarttagged\t!link\empty
\ctxlua{jobreferences.inject("\referenceprefix","#2",\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax,\extrareferencearguments)}%
-\dostoptagged
+ \dostoptagged
\setlocationattributes\??ia
\attribute\referenceattribute\lastreferenceattribute
\fi
@@ -1113,9 +1174,9 @@
\iflocation
\ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}%
{\expandtexincurrentreference
-\dostarttagged\t!link\empty
+ \dostarttagged\t!link\empty
\ctxlua{jobreferences.injectcurrentset(\number\ht\strutbox,\number\dp\strutbox)}%
-\dostoptagged
+ \dostoptagged
\setlocationattributes\??ia
\setstrut % can be option
\attribute\referenceattribute\lastreferenceattribute}%
@@ -1132,9 +1193,9 @@
\iflocation
\ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}%
{\expandtexincurrentreference
-\dostarttagged\t!link\empty
+ \dostarttagged\t!link\empty
\ctxlua{jobreferences.injectcurrentset(\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax)}%
-\dostoptagged
+ \dostoptagged
\setlocationattributes\??ia
\attribute\referenceattribute\lastreferenceattribute}%
{\unknownreference{#3}}%
@@ -1147,9 +1208,9 @@
\begingroup
\attribute\referenceattribute\attributeunsetvalue
\iflocation
-\dostarttagged\t!link\empty
+ \dostarttagged\t!link\empty
\ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}%
-\dostoptagged
+ \dostoptagged
\setlocationattributes\??ia
\hbox attr \referenceattribute \lastreferenceattribute {#1}%
\else
@@ -1162,9 +1223,9 @@
\begingroup
\attribute\referenceattribute\attributeunsetvalue
\iflocation
-\dostarttagged\t!link\empty
+ \dostarttagged\t!link\empty
\ctxlua{jobreferences.inject("\referenceprefix","#3",nil,nil,\extrareferencearguments)}%
-\dostoptagged
+ \dostoptagged
\setlocationcolorspec{#1}% no consequence for strut
\hbox attr \referenceattribute \lastreferenceattribute {#2}%
\else
@@ -1177,9 +1238,9 @@
\begingroup
\attribute\referenceattribute\attributeunsetvalue
\iflocation
-\dostarttagged\t!link\empty
+ \dostarttagged\t!link\empty
\ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}%
-\dostoptagged
+ \dostoptagged
\hbox attr \referenceattribute \lastreferenceattribute {#1}%
\else
#1%
@@ -1193,9 +1254,9 @@
\iflocation
\ctxlua{jobreferences.doifelse("\referenceprefix","#2",\extrareferencearguments)}%
{\expandtexincurrentreference
-\dostarttagged\t!link\empty
+ \dostarttagged\t!link\empty
\ctxlua{jobreferences.injectcurrentset(nil,nil)}%
-\dostoptagged
+ \dostoptagged
\setlocationattributes\??ia
\hbox attr \referenceattribute \lastreferenceattribute {#1}}%
{\unknownreference{#2}}%
@@ -1215,7 +1276,6 @@
{\unknownreference{#3}}%
\endgroup}
-
%D An reference to another document can be specified as a file
%D or as an \URL. Both are handled by the same mechanism and
%D can be issued by saying something like:
diff --git a/tex/context/base/strc-reg.mkiv b/tex/context/base/strc-reg.mkiv
index 413ccb81a..dc37423de 100644
--- a/tex/context/base/strc-reg.mkiv
+++ b/tex/context/base/strc-reg.mkiv
@@ -268,6 +268,8 @@
\xdef\currentregistersynchronize{\ctxlatelua{jobregisters.enhance("\currentregister",\currentregisternumber)}}%
\fi
\currentregistersynchronize % here?
+ % needs thinking ... bla\index{bla}. will break before the . but adding a
+ % penalty is also no solution
\attribute\destinationattribute\lastdestinationattribute \forcecolorhack % no \strut as it will be removed during cleanup
\endgroup}
diff --git a/tex/context/base/strc-ren.mkiv b/tex/context/base/strc-ren.mkiv
index 3a60a34a3..ad972d9e6 100644
--- a/tex/context/base/strc-ren.mkiv
+++ b/tex/context/base/strc-ren.mkiv
@@ -123,7 +123,13 @@
% \newif\ifemptyhead
% \newif\ifdisplaysectionhead
-\def\structureheadattribute{\iflocation attr \destinationattribute \currentstructureattribute\fi}
+\let\currentstructurereferenceattribute\attributeunsetvalue
+
+\def\structureheadattribute
+ {\iflocation
+ attr \destinationattribute \currentstructureattribute
+ attr \referenceattribute \currentstructurereferenceattribute
+ \fi}
\def\doplacestructureheadtext#1#2#3% nodes, text, endstuff
{\beginheadplacement
@@ -132,6 +138,9 @@
\setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute to \zeropoint {#1}%
\makestrutofbox\sectionheadbox
\else
+ \doif{\namedstructureheadparameter\currentstructurehead\c!interaction}\v!list
+ {\dogetsimplepagereference{bck:\nextinternalreference}%
+ \let\currentstructurereferenceattribute\currentreferenceattribute}%
\setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute
{\doresettructureheadnumbercontent
\ifcase\headtimingmode\or#1\fi % outerside font determines distance
@@ -147,6 +156,9 @@
\setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute to \zeropoint{#1}%
\makestrutofbox\sectionheadbox
\else % = needed
+ \doif{\namedstructureheadparameter\currentstructurehead\c!interaction}\v!list
+ {\dogetsimplepagereference{bck:\nextinternalreference}%
+ \let\currentstructurereferenceattribute\currentreferenceattribute}%
\setbox\sectionheadbox\ifvertical\vbox\else\hbox\fi \structureheadattribute
{\ifcase\headtimingmode\or#1\fi
\dosetfontattribute{\??nh\currentstructurehead}\c!style
@@ -154,6 +166,7 @@
\fi
\endheadplacement{#4}}
+
\unexpanded\def\placestructureheadnumbertext
{\doplacestructureheadnumbertext\empty\getstructureheadnumber\getstructureheadtitle\getstructureheadsyncs}
diff --git a/tex/context/base/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv
index 2dd602448..fe2a0fddc 100644
--- a/tex/context/base/strc-sec.mkiv
+++ b/tex/context/base/strc-sec.mkiv
@@ -52,8 +52,9 @@
% interface
-\def\structureheadparameter #1{\csname\dostructureheadparameter{\??nh\currentstructurehead}#1\endcsname}
-\def\structureheadparameterhash#1{\dostructureheadparameterhash {\??nh\currentstructurehead}#1}
+\def\structureheadparameter #1{\csname\dostructureheadparameter{\??nh\currentstructurehead}#1\endcsname}
+\def\structureheadparameterhash #1{\dostructureheadparameterhash {\??nh\currentstructurehead}#1}
+\def\namedstructureheadparameter#1#2{\csname\dostructureheadparameter{\??nh#1}#2\endcsname}
\def\dostructureheadparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\dostructureheadparentparameter \csname#1\s!parent\endcsname#2\fi}
\def\dostructureheadparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\dostructureheadparentparameterhash\csname#1\s!parent\endcsname#2\fi}
@@ -377,6 +378,8 @@
\let\currentstructureheadlevel \!!zerocount
\let\currentstructureheadcounter \!!zerocount
+% here we could inherit as well but it's a bit complex
+
\def\doregisterstructurehead#1#2#3% name data userdata
{\structurecomponent
[\c!label={\structureheadparameter\c!label},
diff --git a/tex/context/base/strc-syn.mkiv b/tex/context/base/strc-syn.mkiv
index 65f517437..0866ea209 100644
--- a/tex/context/base/strc-syn.mkiv
+++ b/tex/context/base/strc-syn.mkiv
@@ -114,7 +114,7 @@
\fi
\setuvalue{#1}{\definesynonym[\v!yes][#1]}% \name
\fi
- \getparameters[\??sm#1][\s!parent=\??sm,\s!multi={#2}]%
+ \getparameters[\??sm#1][\s!parent=\??sm,\s!single={#1},\s!multi={#2}]%
\presetheadtext[#2=\Word{#2}]% changes the \if...argument
%\ctxlua{joblists.define('#1')}%
\setvalue{\e!setup #2\e!endsetup}{\dodoubleargument\getparameters[\??sm#1]}% to be obsolete
@@ -207,8 +207,9 @@
\def\completelistofsynonyms
{\dodoubleempty\docompletelistofsynonyms}
-\def\docompletelistofsynonyms[#1][#2]% expansion needed to avoid v! (due to french active !)
- {\normalexpanded{\systemsuppliedchapter[#1]{\noexpand\headtext{\synonymparameter\s!single}}}%
+\def\docompletelistofsynonyms[#1][#2]%
+ {\edef\currentsynonym{#1}%
+ \normalexpanded{\systemsuppliedchapter[#1]{\noexpand\headtext{\synonymparameter\s!multi}}}%
\doplacelistofsynonyms[#1][#2]%
\page[\v!yes]}
diff --git a/tex/context/base/strc-tag.lua b/tex/context/base/strc-tag.lua
index 4381fc529..d69525bc9 100644
--- a/tex/context/base/strc-tag.lua
+++ b/tex/context/base/strc-tag.lua
@@ -28,7 +28,8 @@ local tags, labels, stack, chain, ids, enabled = { }, { }, { }, { }, { }, false
structure.tags.taglist = tags -- can best be hidden
function structure.tags.start(tag,label,detail)
- labels[label or tag] = tag
+--~ labels[label or tag] = tag
+ labels[tag] = label ~= "" and label or tag
if detail and detail ~= "" then
tag = tag .. ":" .. detail
end
diff --git a/tex/context/base/syst-ext.mkii b/tex/context/base/syst-ext.mkii
index 73fb98b72..745478526 100644
--- a/tex/context/base/syst-ext.mkii
+++ b/tex/context/base/syst-ext.mkii
@@ -4991,9 +4991,9 @@
\def\comparedimensioneps#1#2%
{\chardef\compresult
- \ifdim\dimexpr(#1-#2)<\roudingeps
+ \ifdim\dimexpr#1-#2\relax<\roudingeps
\zerocount
- \else\ifdim\dimexpr(#2-#1)<\roudingeps
+ \else\ifdim\dimexpr#2-#1\relax<\roudingeps
\zerocount
\else\ifdim#1<#2%
\plusone
diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv
index 67d20a615..e183e5552 100644
--- a/tex/context/base/tabl-ntb.mkiv
+++ b/tex/context/base/tabl-ntb.mkiv
@@ -721,10 +721,10 @@
% permits \expanded{\bTD ... \eTD}
-\unexpanded\def\eTR{\ignorespaces} % handy in case we use a macro to generate rows
-\unexpanded\def\eTD{\ignorespaces}
-\unexpanded\def\eTH{\ignorespaces}
-\unexpanded\def\eTN{\ignorespaces}
+\let\bTR\relax \unexpanded\def\eTR{\ignorespaces} % handy in case we use a macro to generate rows
+\let\bTD\relax \unexpanded\def\eTD{\ignorespaces}
+\let\bTH\relax \unexpanded\def\eTH{\ignorespaces}
+\let\bTN\relax \unexpanded\def\eTN{\ignorespaces}
\unexpanded\def\eTABLE % beware, we need to get rid of spurious spaces when in hmode
{% tricky and dirty order -)
diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv
index 007338146..196a21850 100644
--- a/tex/context/base/tabl-tbl.mkiv
+++ b/tex/context/base/tabl-tbl.mkiv
@@ -696,8 +696,8 @@
[\c!unit,\c!distance,\c!before,\c!bodyfont,\c!after,
\c!inner,\c!indenting,\c!frame,\c!split,\c!header,\c!title,
\c!margin,\c!align,\c!rulecolor,\c!rulethickness,EQ]%
- \setvalue{\e!start#1::#2}{\dofinalstarttabulate[#1][#2][#3]}%
- \setvalue{\e!start#1}{\bgroup\dosubstarttabulate[#1]}%
+ \setuvalue{\e!start#1::#2}{\dofinalstarttabulate[#1][#2][#3]}%
+ \setuvalue{\e!start#1}{\bgroup\dosubstarttabulate[#1]}%
\letvalue{\??tt#1-\v!header}\empty
\letvalue{\??tt#1-\v!footer }\empty
\else\ifsecondargument
@@ -752,14 +752,14 @@
\TABLEnoalign{\kern-\lineheight}%
\fi}
-\setvalue{\e!start\v!tabulatehead}%
+\setuvalue{\e!start\v!tabulatehead}%
{\dosingleempty\dostartstarttabulatehead}
\def\dostartstarttabulatehead[#1]%
{\processcontent{\e!stop\v!tabulatehead}\next
{\letvalue{\??tt\iffirstargument#1\else\v!tabulate\fi::-\v!header}\next}}
-\setvalue{\e!start\v!tabulatetail}%
+\setuvalue{\e!start\v!tabulatetail}%
{\dosingleempty\dostartstarttabulatetail}
\def\dostartstarttabulatetail[#1]%
@@ -772,9 +772,13 @@
\def\dodosubstarttabulate[#1][#2]%
{\csname\e!start#1::\ifcsname\e!start#1::#2\endcsname#2\fi\endcsname}
-\setvalue{\e!start\v!tabulate}%
+\setuvalue{\e!start\v!tabulate}%
{\bgroup\dodoubleempty\donormalstarttabulate}
+\setuvalue{\e!stop\v!tabulate }{}
+\setuvalue{\e!stop\v!tabulatehead}{}
+\setuvalue{\e!stop\v!tabulatetail}{}
+
\bgroup
\gdef\donormalstarttabulate[#1][#2]%
diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua
index 4c5ac401d..a04736487 100644
--- a/tex/context/base/task-ini.lua
+++ b/tex/context/base/task-ini.lua
@@ -14,7 +14,7 @@ if not modules then modules = { } end modules ['task-ini'] = {
tasks.appendaction("processors", "normalizers", "fonts.collections.process") -- todo
tasks.appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled
-tasks.appendaction("processors", "characters", "chars.handle_mirroring") -- disabled
+tasks.appendaction("processors", "characters", "mirroring.handler") -- disabled
tasks.appendaction("processors", "characters", "typesetting.cases.handler") -- disabled
tasks.appendaction("processors", "characters", "typesetting.breakpoints.handler") -- disabled
tasks.appendaction("processors", "characters", "scripts.preprocess")
@@ -76,7 +76,7 @@ tasks.disableaction("processors", "chars.handle_breakpoints")
tasks.disableaction("processors", "typesetting.cases.handler")
tasks.disableaction("processors", "typesetting.digits.handler")
tasks.disableaction("processors", "typesetting.breakpoints.handler")
-tasks.disableaction("processors", "chars.handle_mirroring")
+tasks.disableaction("processors", "mirroring.handler")
tasks.disableaction("processors", "languages.words.check")
tasks.disableaction("processors", "typesetting.spacings.handler")
tasks.disableaction("processors", "typesetting.kerns.handler")
diff --git a/tex/context/base/trac-set.lua b/tex/context/base/trac-set.lua
index a9c55f954..e7498ea85 100644
--- a/tex/context/base/trac-set.lua
+++ b/tex/context/base/trac-set.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['trac-set'] = {
local type, next, tostring = type, next, tostring
local concat = table.concat
-local format, find, lower, gsub = string.format, string.find, string.lower, string.gsub
+local format, find, lower, gsub, simpleesc = string.format, string.find, string.lower, string.gsub, string.simpleesc
local is_boolean = string.is_boolean
setters = { }
@@ -80,7 +80,7 @@ local function set(t,what,newvalue)
for name, functions in next, data do
if done[name] then
-- prevent recursion due to wildcards
- elseif find(name,w) then
+ elseif find(name,simpleesc(w)) then
done[name] = true
for i=1,#functions do
functions[i](value)
@@ -144,14 +144,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(tostring(what)))
+ enable(t,what)
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(tostring(what)))
+ disable(t,what)
t.disable, t.done = e, { }
end
@@ -215,36 +215,50 @@ trackers = setters.new("trackers")
directives = setters.new("directives")
experiments = setters.new("experiments")
+-- experiment
+
+if trackers and environment and environment.engineflags.trackers then
+ trackers.enable(environment.engineflags.trackers)
+end
+if directives and environment and environment.engineflags.directives then
+ directives.enable(environment.engineflags.directives)
+end
+
-- nice trick: we overload two of the directives related functions with variants that
-- do tracing (itself using a tracker) .. proof of concept
+local function report(...) -- messy .. chicken or egg
+ local p = (commands and commands.writestatus) or (logs and logs.report)
+ if p then p(...) end
+end
+
local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end)
-local e = directives.enable
-local d = directives.disable
+local enable = directives.enable
+local disable = directives.disable
function directives.enable(...)
- (commands.writestatus or logs.report)("directives","enabling: %s",concat({...}," "))
- e(...)
+ report("directives","enabling: %s",concat({...}," "))
+ enable(...)
end
function directives.disable(...)
- (commands.writestatus or logs.report)("directives","disabling: %s",concat({...}," "))
- d(...)
+ report("directives","disabling: %s",concat({...}," "))
+ disable(...)
end
-local e = experiments.enable
-local d = experiments.disable
+local enable = experiments.enable
+local disable = experiments.disable
function experiments.enable(...)
- (commands.writestatus or logs.report)("experiments","enabling: %s",concat({...}," "))
- e(...)
+ report("experiments","enabling: %s",concat({...}," "))
+ enable(...)
end
function experiments.disable(...)
- (commands.writestatus or logs.report)("experiments","disabling: %s",concat({...}," "))
- d(...)
+ report("experiments","disabling: %s",concat({...}," "))
+ disable(...)
end
-- a useful example
@@ -252,3 +266,12 @@ end
directives.register("system.nostatistics", function(v)
statistics.enable = not v
end)
+
+-- experiment
+
+if trackers and environment and environment.engineflags.trackers then
+ trackers.enable(environment.engineflags.trackers)
+end
+if directives and environment and environment.engineflags.directives then
+ directives.enable(environment.engineflags.directives)
+end
diff --git a/tex/context/base/type-dejavu.mkiv b/tex/context/base/type-dejavu.mkiv
index 116d3ca4c..ac83123db 100644
--- a/tex/context/base/type-dejavu.mkiv
+++ b/tex/context/base/type-dejavu.mkiv
@@ -16,25 +16,25 @@
\starttypescript [serif] [dejavu] [name]
\setups[font:fallback:serif]
\definefontsynonym [Serif] [name:dejavuserif] [features=default]
- \definefontsynonym [SerifBold] [name:dejavuserifitalic] [features=default]
- \definefontsynonym [SerifItalic] [name:dejavuserifbold] [features=default]
+ \definefontsynonym [SerifBold] [name:dejavuserifbold] [features=default]
+ \definefontsynonym [SerifItalic] [name:dejavuserifitalic] [features=default]
\definefontsynonym [SerifBoldItalic] [name:dejavuserifbolditalic] [features=default]
\stoptypescript
\starttypescript [sans] [dejavu] [name]
\setups[font:fallback:sans]
\definefontsynonym [Sans] [name:dejavusans] [features=default]
- \definefontsynonym [SansBold] [name:dejavusansoblique] [features=default]
- \definefontsynonym [SansItalic] [name:dejavusansbold] [features=default]
+ \definefontsynonym [SansBold] [name:dejavusansbold] [features=default]
+ \definefontsynonym [SansItalic] [name:dejavusansoblique] [features=default]
\definefontsynonym [SansBoldItalic] [name:dejavusansboldoblique] [features=default]
\stoptypescript
\starttypescript [mono] [dejavu] [name]
\setups[font:fallback:mono]
- \definefontsynonym [Mono] [name:dejavusansmono] [features=default]
- \definefontsynonym [MonoBold] [name:dejavusansmonooblique] [features=default]
- \definefontsynonym [MonoItalic] [name:dejavusansmonobold] [features=default]
- \definefontsynonym [MonoBoldItalic] [name:dejavusansmonoboldoblique] [features=default]
+ \definefontsynonym [Mono] [name:dejavusansmono] [features=none]
+ \definefontsynonym [MonoBold] [name:dejavusansmonobold] [features=none]
+ \definefontsynonym [MonoItalic] [name:dejavusansmonooblique] [features=none]
+ \definefontsynonym [MonoBoldItalic] [name:dejavusansmonoboldoblique] [features=none]
\stoptypescript
\starttypescript[dejavu]
diff --git a/tex/context/base/type-otf.mkii b/tex/context/base/type-otf.mkii
index cfda29fd7..05a6d3987 100644
--- a/tex/context/base/type-otf.mkii
+++ b/tex/context/base/type-otf.mkii
@@ -839,6 +839,23 @@
\usemathcollection[default]
\stoptypescript
+ \starttypescript [math] [times] [name]
+ \definefontsynonym [MathRoman] [Times-Roman-Upright]
+ \definefontsynonym [MathExtension] [Times-Math-Extension]
+ \definefontsynonym [MathItalic] [Times-Math-Italic]
+ \definefontsynonym [MathSymbol] [Times-Math-Symbols]
+ \definefontsynonym [MathAlpha] [Times-Math-SymbolsA]
+ \definefontsynonym [MathBeta] [Times-Math-SymbolsB]
+ \stoptypescript
+
+ \starttypescript [math] [times] [name]
+ \definefontsynonym [OldStyle] [MathItalic]
+ \definefontsynonym [Fraktur] [eufm10]
+ \definefontsynonym [Blackboard] [MathBeta]
+ \definefontsynonym [Gothic] [eufm10]
+ \definefontsynonym [Calligraphic] [eusm10]
+ \stoptypescript
+
\starttypescript [math] [palatino] [all]
\definefontsynonym [Palatino-Roman-Upright] [pxr]
\definefontsynonym [Palatino-Roman-Italic] [pxi]
@@ -860,6 +877,23 @@
\usemathcollection[default]
\stoptypescript
+ \starttypescript [math] [palatino] [name]
+ \definefontsynonym [MathRoman] [Palatino-Roman-Upright]
+ \definefontsynonym [MathExtension] [Palatino-Math-Extension]
+ \definefontsynonym [MathItalic] [Palatino-Math-Italic]
+ \definefontsynonym [MathSymbol] [Palatino-Math-Symbols]
+ \definefontsynonym [MathAlpha] [Palatino-Math-SymbolsA]
+ \definefontsynonym [MathBeta] [Palatino-Math-SymbolsB]
+ \stoptypescript
+
+ \starttypescript [math] [palatino] [name]
+ \definefontsynonym [OldStyle] [MathItalic]
+ \definefontsynonym [Fraktur] [eufm10]
+ \definefontsynonym [Blackboard] [MathBeta]
+ \definefontsynonym [Gothic] [eufm10]
+ \definefontsynonym [Calligraphic] [eusm10]
+ \stoptypescript
+
\stoptypescriptcollection
\starttypescriptcollection[antykwa]
diff --git a/tex/context/base/type-otf.mkiv b/tex/context/base/type-otf.mkiv
index b889e1ad2..24b9f4f6e 100644
--- a/tex/context/base/type-otf.mkiv
+++ b/tex/context/base/type-otf.mkiv
@@ -450,7 +450,7 @@
\definetypescriptprefix [f:cursor] [cursor] \definetypescriptprefix [f:courier] [cursor]
\definetypescriptprefix [f:chorus] [chorus] \definetypescriptprefix [f:chancery] [chorus] % not the full set
- \starttypescript [serif,sans,mono] [adventor,bonum,bookman,cursor,courier,heros,helvetica,pagella,palatino,schola,schoolbook,termes,times]
+ \starttypescript [serif,sans] [adventor,bonum,bookman,heros,helvetica,pagella,palatino,schola,schoolbook,termes,times]
\definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [\s!file:texgyre\typescriptprefix{f:\typescripttwo}-regular] [\s!features=\s!default]
\definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [\s!file:texgyre\typescriptprefix{f:\typescripttwo}-italic] [\s!features=\s!default]
\definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [\s!file:texgyre\typescriptprefix{f:\typescripttwo}-bold] [\s!features=\s!default]
@@ -461,6 +461,13 @@
\definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalicCaps] [\s!file:texgyre\typescriptprefix{f:\typescripttwo}-bolditalic] [\s!features=\s!smallcaps]
\stoptypescript
+ \starttypescript [mono] [cursor,courier]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Regular] [\s!file:texgyre\typescriptprefix{f:\typescripttwo}-regular] [\s!features=\s!none]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Italic] [\s!file:texgyre\typescriptprefix{f:\typescripttwo}-italic] [\s!features=\s!none]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-Bold] [\s!file:texgyre\typescriptprefix{f:\typescripttwo}-bold] [\s!features=\s!none]
+ \definefontsynonym [\typescriptprefix{n:\typescripttwo}-BoldItalic] [\s!file:texgyre\typescriptprefix{f:\typescripttwo}-bolditalic] [\s!features=\s!none]
+ \stoptypescript
+
\starttypescript [serif,calligraphy] [chorus,chancery]
\definefontsynonym [TeXGyreChorus-MediumItalic] [\s!file:texgyrechorus-mediumitalic] [\s!features=\s!default]
\stoptypescript
@@ -1458,7 +1465,7 @@
\starttypescript [lucida]
\definetypeface [lucida] [rm] [\s!serif] [lucida] [\s!default] [\s!features=\s!default]
\definetypeface [lucida] [ss] [\s!sans] [lucida] [\s!default] [\s!features=\s!default]
- \definetypeface [lucida] [tt] [\s!mono] [lucida] [\s!default] [\s!features=\s!default]
+ \definetypeface [lucida] [tt] [\s!mono] [lucida] [\s!default] [\s!features=\s!none]
\definetypeface [lucida] [hw] [\s!handwriting] [lucida] [\s!default] [\s!features=\s!default]
\definetypeface [lucida] [cg] [\s!calligraphy] [lucida] [\s!default] [\s!features=\s!default]
\definetypeface [lucida] [mm] [\s!math] [lucida] [\s!default]
@@ -1497,8 +1504,8 @@
\starttypescript[asana]
\definetypeface [\typescriptone] [rm] [\s!serif] [palatino] [\s!default]
- \definetypeface [\typescriptone] [ss] [\s!sans] [modern] [\s!default] [rscale=1.075]
- \definetypeface [\typescriptone] [tt] [\s!mono] [modern] [\s!default] [rscale=1.075]
+ \definetypeface [\typescriptone] [ss] [\s!sans] [modern] [\s!default] [\s!rscale=1.075]
+ \definetypeface [\typescriptone] [tt] [\s!mono] [modern] [\s!default] [\s!rscale=1.075]
\definetypeface [\typescriptone] [mm] [\s!math] [\typescriptone] [\s!default]
\quittypescriptscanning
\stoptypescript
@@ -1613,18 +1620,18 @@
\starttypescript [sans] [mscorearial] [name]
\setups[\s!font:\s!fallback:\s!sans]
- \definefontsynonym [\s!Sans] [\s!file:arial.ttf] [\s!features=default]
- \definefontsynonym [\s!SansBold] [\s!file:arialbd.ttf] [\s!features=default]
- \definefontsynonym [\s!SansItalic] [\s!file:ariali.ttf] [\s!features=default]
- \definefontsynonym [\s!SansBoldItalic] [\s!file:arialbi.ttf] [\s!features=default]
+ \definefontsynonym [\s!Sans] [\s!file:arial.ttf] [\s!features=\s!default]
+ \definefontsynonym [\s!SansBold] [\s!file:arialbd.ttf] [\s!features=\s!default]
+ \definefontsynonym [\s!SansItalic] [\s!file:ariali.ttf] [\s!features=\s!default]
+ \definefontsynonym [\s!SansBoldItalic] [\s!file:arialbi.ttf] [\s!features=\s!default]
\stoptypescript
\starttypescript [mono] [mscorecourier] [name]
\setups[\s!font:\s!fallback:\s!mono]
- \definefontsynonym [\s!Mono] [\s!file:cour.ttf] [\s!features=\s!default]
- \definefontsynonym [\s!MonoBold] [\s!file:courbd.ttf] [\s!features=\s!default]
- \definefontsynonym [\s!MonoItalic] [\s!file:couri.ttf] [\s!features=\s!default]
- \definefontsynonym [\s!MonoBoldItalic] [\s!file:courbi.ttf] [\s!features=\s!default]
+ \definefontsynonym [\s!Mono] [\s!file:cour.ttf] [\s!features=\s!none]
+ \definefontsynonym [\s!MonoBold] [\s!file:courbd.ttf] [\s!features=\s!none]
+ \definefontsynonym [\s!MonoItalic] [\s!file:couri.ttf] [\s!features=\s!none]
+ \definefontsynonym [\s!MonoBoldItalic] [\s!file:courbi.ttf] [\s!features=\s!none]
\stoptypescript
\starttypescript [sans] [mscoreverdana] [name]
@@ -1671,10 +1678,10 @@
\starttypescript [mono] [liberation] [name]
\setups[\s!font:\s!fallback:\s!mono]
- \definefontsynonym [\s!Mono] [\s!file:liberationmono-regular] [\s!features=\s!default]
- \definefontsynonym [\s!MonoBold] [\s!file:liberationmono-bold] [\s!features=\s!default]
- \definefontsynonym [\s!MonoItalic] [\s!file:liberationmono-italic] [\s!features=\s!default]
- \definefontsynonym [\s!MonoBoldItalic] [\s!file:liberationmono-bolditalic] [\s!features=\s!default]
+ \definefontsynonym [\s!Mono] [\s!file:liberationmono-regular] [\s!features=\s!none]
+ \definefontsynonym [\s!MonoBold] [\s!file:liberationmono-bold] [\s!features=\s!none]
+ \definefontsynonym [\s!MonoItalic] [\s!file:liberationmono-italic] [\s!features=\s!none]
+ \definefontsynonym [\s!MonoBoldItalic] [\s!file:liberationmono-bolditalic] [\s!features=\s!none]
\stoptypescript
\starttypescript[liberation]
@@ -1862,22 +1869,43 @@
\starttypescriptcollection[punk]
- \definefontfeature[punknova][mode=node,script=latn,rand=yes,kern=yes,liga=yes,tlig=yes]
+ \definefontfeature [punknova] [mode=node,script=latn,rand=yes,kern=yes,liga=yes,tlig=yes]
+ \definefontfeature [punknova-slanted] [punknova] [slant=.25]
\starttypescript [serif] [punknova]
- \setups[font:fallback:serif] % no style variants yet, actually it's a sans
- \definefontsynonym [Serif] [file:punknova] [features=punknova]
+ \definefontsynonym [Serif] [\s!file:punknova-regular] [\s!features=punknova]
+ \definefontsynonym [SerifSlanted] [\s!file:punknova-regular] [\s!features=punknova-slanted]
+ \definefontsynonym [SerifBold] [\s!file:punknova-bold] [\s!features=punknova]
+ \definefontsynonym [SerifBoldSlanted][\s!file:punknova-bold] [\s!features=punknova-slanted]
+ \definefontsynonym [SerifItalic] [SerifSlanted]
+ \definefontsynonym [SerifBoldItalic] [SerifBoldSlanted]
\stoptypescript
+ % \definefontfeature [slanted-25] [slant=.25]
+ % \starttypescript [serif] [punknova]
+ % \definefontsynonym [SerifSlanted] [\s!file:punknova-regular] [\s!features={punknova,slanted-25}]
+ % \stoptypescript
+
\starttypescript [punknova]
\definetypeface [punknova] [rm] [serif] [punknova] [default]
\stoptypescript
\stoptypescriptcollection
-% \starttypescript [math] [hvmath]
-% \definefontsynonym[MathRoman][hvmath@hvmath-math]
-% \loadfontgoodies[hvmath-math]
-% \stoptypescript
+% \starttypescriptcollection[hvmath]
+
+% \starttypescript [math] [hvmath]
+% \definefontsynonym[MathRoman][hvmath@hvmath-math]
+% \loadfontgoodies[hvmath-math]
+% \stoptypescript
+
+% \starttypescript [hvmath]
+% \definetypeface [hvmath] [ss] [sans] [heros] [default] [rscale=0.9]
+% \definetypeface [hvmath] [rm] [serif] [termes] [default]
+% \definetypeface [hvmath] [tt] [mono] [cursor] [default] [rscale=1.05]
+% \definetypeface [hvmath] [mm] [math] [hvmath] [default]
+% \stoptypescript
+
+% \stoptypescriptcollection
\protect \endinput
diff --git a/tex/context/base/typo-brk.lua b/tex/context/base/typo-brk.lua
index ee58cef68..a845599f5 100644
--- a/tex/context/base/typo-brk.lua
+++ b/tex/context/base/typo-brk.lua
@@ -33,8 +33,10 @@ local make_glyph_node = nodes.glyph
local remove_node = nodes.remove -- ! nodes
local tonodes = blobs.tonodes
-local glyph = node.id("glyph")
-local kern = node.id("kern")
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local kern = nodecodes.kern
typesetting = typesetting or {}
typesetting.breakpoints = typesetting.breakpoints or {}
diff --git a/tex/context/base/typo-cap.lua b/tex/context/base/typo-cap.lua
index 0e9068af3..3de2c5ab1 100644
--- a/tex/context/base/typo-cap.lua
+++ b/tex/context/base/typo-cap.lua
@@ -21,8 +21,10 @@ local traverse_id = node.traverse_id
local texattribute = tex.attribute
-local glyph = node.id("glyph")
-local kern = node.id("kern")
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local kern = nodecodes.kern
local fontdata = fonts.ids
local fontchar = fonts.chr
diff --git a/tex/context/base/typo-dig.lua b/tex/context/base/typo-dig.lua
index 9bc738ecf..687090074 100644
--- a/tex/context/base/typo-dig.lua
+++ b/tex/context/base/typo-dig.lua
@@ -27,8 +27,10 @@ local insert_after = node.insert_after
local texattribute = tex.attribute
-local glyph = node.id("glyph")
-local kern = node.id("kern")
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local kern = nodecodes.kern
local new_glue = nodes.glue
diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua
index b858dbc1a..27bd09e4d 100644
--- a/tex/context/base/typo-krn.lua
+++ b/tex/context/base/typo-krn.lua
@@ -23,14 +23,16 @@ local insert_node_after = node.insert_after
local make_glue_spec = nodes.glue_spec
local make_kern_node = nodes.kern
-local texattribute = tex.attribute
-
-local glyph = node.id("glyph")
-local kern = node.id("kern")
-local disc = node.id('disc')
-local glue = node.id('glue')
-local hlist = node.id('hlist')
-local vlist = node.id('vlist')
+local texattribute = tex.attribute
+
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local kern = nodecodes.kern
+local disc = nodecodes.disc
+local glue = nodecodes.glue
+local hlist = nodecodes.hlist
+local vlist = nodecodes.vlist
local fontdata = fonts.identifiers
local chardata = fonts.characters
diff --git a/tex/context/base/typo-mir.lua b/tex/context/base/typo-mir.lua
index 5ab85c7c2..f0ed7fdff 100644
--- a/tex/context/base/typo-mir.lua
+++ b/tex/context/base/typo-mir.lua
@@ -26,9 +26,11 @@ local insert_node_before = node.insert_before
local insert_node_after = node.insert_after
local remove_node = nodes.remove
-local glyph = node.id("glyph")
-local whatsit = node.id("whatsit")
-local mthnode = node.id('math')
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+local whatsit = nodecodes.whatsit
+local mthnode = nodecodes.math
local fontdata = fonts.ids
local fontchar = fonts.chr
@@ -412,12 +414,12 @@ end
--~ return false
--~ end
-chars.handle_mirroring = nodes.install_attribute_handler {
+mirroring.handler = nodes.install_attribute_handler {
name = "mirroring",
namespace = mirroring,
processor = mirroring.process,
}
function mirroring.enable()
- tasks.enableaction("processors","chars.handle_mirroring")
+ tasks.enableaction("processors","mirroring.handler")
end
diff --git a/tex/context/base/typo-rep.lua b/tex/context/base/typo-rep.lua
index 56681974e..ac93cde6f 100644
--- a/tex/context/base/typo-rep.lua
+++ b/tex/context/base/typo-rep.lua
@@ -22,10 +22,13 @@ local has_attribute = node.has_attribute
local chardata = characters.data
local collected = false
-local glyph = node.id("glyph")
local attribute = attributes.private("stripping")
local fontdata = fonts.ids
+local nodecodes = nodes.nodecodes
+
+local glyph = nodecodes.glyph
+
-- other namespace
nodes.stripping = nodes.stripping or { } local stripping = nodes.stripping
diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua
index bc964932a..b11d4e386 100644
--- a/tex/context/base/typo-spa.lua
+++ b/tex/context/base/typo-spa.lua
@@ -24,13 +24,15 @@ local insert_node_after = node.insert_after
local remove_node = nodes.remove
local make_penalty_node = nodes.penalty
local make_glue_node = nodes.glue
-local glyph = node.id("glyph")
local fontdata = fonts.identifiers
local quaddata = fonts.quads
+local nodecodes = nodes.nodecodes
local texattribute = tex.attribute
+local glyph = nodecodes.glyph
+
typesetting = typesetting or { }
typesetting.spacings = typesetting.spacings or { }
diff --git a/tex/context/base/unic-003.mkii b/tex/context/base/unic-003.mkii
index d37563d26..3f994a662 100644
--- a/tex/context/base/unic-003.mkii
+++ b/tex/context/base/unic-003.mkii
@@ -136,7 +136,7 @@
\strippedcsname \unknownchar \or
\strippedcsname \unknownchar \or % kappa alt
\strippedcsname \greekrhoalt \or
- \strippedcsname \unknownchar \or
+ \strippedcsname \greeksigmalunate \or
\strippedcsname \unknownchar \or
\strippedcsname \unknownchar \or
\strippedcsname \greekepsilonalt \else
diff --git a/tex/context/base/xetx-utf.mkii b/tex/context/base/xetx-utf.mkii
index 79bd00745..a337c9e76 100644
--- a/tex/context/base/xetx-utf.mkii
+++ b/tex/context/base/xetx-utf.mkii
@@ -1986,4 +1986,9 @@
\setXTXcharcodes "201C "201C "201C
\setXTXcharcodes "201D "201D "201D
+% patch needed for french
+
+% \setXTXcharcodes "0027 "0027 "0027
+\setXTXcharcodes "2019 "2019 "2019
+
\endinput