summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/attr-ini.lua697
-rw-r--r--tex/context/base/attr-ini.tex122
-rw-r--r--tex/context/base/char-ini.lua11
-rw-r--r--tex/context/base/char-utf.lua10
-rw-r--r--tex/context/base/colo-hex.tex4
-rw-r--r--tex/context/base/colo-ini.tex182
-rw-r--r--tex/context/base/colo-run.tex67
-rw-r--r--tex/context/base/cont-new.mkiv37
-rw-r--r--tex/context/base/cont-new.tex53
-rw-r--r--tex/context/base/context.tex11
-rw-r--r--tex/context/base/core-con.lua96
-rw-r--r--tex/context/base/core-con.mkiv60
-rw-r--r--tex/context/base/core-mat.tex2
-rw-r--r--tex/context/base/core-obj.tex10
-rw-r--r--tex/context/base/core-rul.tex49
-rw-r--r--tex/context/base/core-sec.tex39
-rw-r--r--tex/context/base/core-spa.lua26
-rw-r--r--tex/context/base/core-spa.tex130
-rw-r--r--tex/context/base/core-tab.tex41
-rw-r--r--tex/context/base/core-uti.mkiv12
-rw-r--r--tex/context/base/core-var.tex3
-rw-r--r--tex/context/base/font-afm.lua158
-rw-r--r--tex/context/base/font-def.lua75
-rw-r--r--tex/context/base/font-enc.lua21
-rw-r--r--tex/context/base/font-ini.lua3
-rw-r--r--tex/context/base/font-ini.mkiv22
-rw-r--r--tex/context/base/font-map.lua185
-rw-r--r--tex/context/base/font-otf.lua484
-rw-r--r--tex/context/base/font-syn.lua6
-rw-r--r--tex/context/base/font-tfm.lua90
-rw-r--r--tex/context/base/l-aux.lua48
-rw-r--r--tex/context/base/l-boolean.lua2
-rw-r--r--tex/context/base/l-file.lua2
-rw-r--r--tex/context/base/l-string.lua12
-rw-r--r--tex/context/base/l-table.lua36
-rw-r--r--tex/context/base/l-tex.lua2
-rw-r--r--tex/context/base/l-utils.lua7
-rw-r--r--tex/context/base/l-xml.lua887
-rw-r--r--tex/context/base/lang-ini.lua2
-rw-r--r--tex/context/base/lang-sla.mkiv4
-rw-r--r--tex/context/base/luat-cbk.lua2
-rw-r--r--tex/context/base/luat-crl.lua6
-rw-r--r--tex/context/base/luat-ini.lua17
-rw-r--r--tex/context/base/luat-ini.tex22
-rw-r--r--tex/context/base/luat-inp.lua82
-rw-r--r--tex/context/base/luat-lib.tex2
-rw-r--r--tex/context/base/luat-tex.lua34
-rw-r--r--tex/context/base/luat-tmp.lua106
-rw-r--r--tex/context/base/luat-tra.lua104
-rw-r--r--tex/context/base/lxml-ini.lua33
-rw-r--r--tex/context/base/lxml-ini.tex23
-rw-r--r--tex/context/base/meta-mis.tex2
-rw-r--r--tex/context/base/meta-pdf.lua67
-rw-r--r--tex/context/base/meta-pdf.mkiv2
-rw-r--r--tex/context/base/meta-pdf.tex49
-rw-r--r--tex/context/base/mult-con.tex12
-rw-r--r--tex/context/base/mult-sys.tex2
-rw-r--r--tex/context/base/node-ini.lua578
-rw-r--r--tex/context/base/page-flt.tex497
-rw-r--r--tex/context/base/page-imp.tex4
-rw-r--r--tex/context/base/page-ini.tex3
-rw-r--r--tex/context/base/prop-ini.tex27
-rw-r--r--tex/context/base/prop-lay.tex8
-rw-r--r--tex/context/base/prop-mis.mkii155
-rw-r--r--tex/context/base/prop-mis.mkiv46
-rw-r--r--tex/context/base/prop-mis.tex177
-rw-r--r--tex/context/base/s-abr-01.tex1
-rw-r--r--tex/context/base/spec-dpx.tex2
-rw-r--r--tex/context/base/spec-fdf.tex15
-rw-r--r--tex/context/base/spec-tpd.tex2
-rw-r--r--tex/context/base/syst-con.lua44
-rw-r--r--tex/context/base/syst-con.mkiv16
-rw-r--r--tex/context/base/toks-ini.lua58
-rw-r--r--tex/context/base/toks-ini.tex10
-rw-r--r--tex/context/interface/keys-cz.xml5
-rw-r--r--tex/context/interface/keys-de.xml5
-rw-r--r--tex/context/interface/keys-en.xml5
-rw-r--r--tex/context/interface/keys-fr.xml5
-rw-r--r--tex/context/interface/keys-it.xml5
-rw-r--r--tex/context/interface/keys-nl.xml5
-rw-r--r--tex/context/interface/keys-ro.xml5
81 files changed, 3844 insertions, 2107 deletions
diff --git a/tex/context/base/attr-ini.lua b/tex/context/base/attr-ini.lua
index 4469608c4..81ca873d9 100644
--- a/tex/context/base/attr-ini.lua
+++ b/tex/context/base/attr-ini.lua
@@ -29,11 +29,17 @@ function totokens(str)
return t
end
-function pdfliteral(str)
- local t = node.new('whatsit',8)
- t.mode = 1 -- direct
- t.data = str -- totokens(str)
- return t
+-- temp hack, will be proper driver stuff
+
+backends = backends or { }
+backends.pdf = backends.pdf or { }
+backend = backend or backends.pdf
+
+function backends.pdf.literal(str)
+ local t = node.new('whatsit',8)
+ t.mode = 1 -- direct
+ t.data = str -- totokens(str)
+ return t
end
-- shipouts
@@ -45,44 +51,44 @@ do
local hlist, vlist = node.id('hlist'), node.id('vlist')
- local function do_process_page(attribute,processor,head) -- maybe work with ranges
- local previous, stack = nil, head
- while stack do
- local id = stack.id
- if id == hlist or id == vlist then
- local content = stack.list
- if content then
- stack.list = do_process_page(attribute,processor,content)
- end
- else
- stack, previous, head = processor(attribute,stack,previous,head)
- end
- previous = stack
- stack = stack.next
- end
- return head
- end
+ local contains = node.has_attribute
+
+ nodes.trigger = false
+ nodes.triggering = false
+
+ -- we used to do the main processor loop here and call processor for each node
+ -- but eventually this was too much a slow down (1 sec on 23 for 120 pages mk)
+ -- so that we moved looping to teh processor itself; this may lead to a bit of
+ -- duplicate code once that we have more state handlers
function nodes.process_page(head)
+ local trigger = nodes.trigger
if head then
- input.start_timing(nodes)
+ input.start_timing(attributes)
local done, used = false, { }
for name, plugin in pairs(shipouts.plugins) do
local attribute = attributes.numbers[name]
if attribute then
- local initializer = plugin.initializer
- local processor = plugin.processor
- local finalizer = plugin.finalizer
- if initializer then
- initializer(attribute,head)
- end
- if processor then
- head = do_process_page(attribute,processor,head)
- end
- if finalizer then
- local ok
- ok, head, used[attribute] = finalizer(attribute,head)
- done = done or ok
+ local namespace = plugin.namespace
+ if namespace.enabled then
+ local initializer = plugin.initializer
+ local processor = plugin.processor
+ local finalizer = plugin.finalizer
+ local resolver = plugin.resolver
+ if initializer then
+ initializer(namespace,attribute,head)
+ end
+ if processor then
+ local inheritance = (resolver and resolver()) or -1
+ local ok
+ ok, head = processor(namespace,attribute,head,inheritance)
+ done = done or ok
+ end
+ if finalizer then -- no need when not ok
+ local ok
+ ok, head, used[attribute] = finalizer(namespace,attribute,head)
+ done = done or ok
+ end
end
else
texio.write_nl(string.format("undefined attribute %s",name))
@@ -92,14 +98,17 @@ do
for name, plugin in pairs(shipouts.plugins) do
local attribute = attributes.numbers[name]
if used[attribute] then
- local flusher = plugin.flusher
- if flusher then
- head = flusher(attribute,head,used[attribute])
+ local namespace = plugin.namespace
+ if namespace.enabled then
+ local flusher = plugin.flusher
+ if flusher then
+ head = flusher(namespace,attribute,head,used[attribute])
+ end
end
end
end
end
- input.stop_timing(nodes)
+ input.stop_timing(attributes)
end
return head
end
@@ -132,7 +141,7 @@ states = { }
do
- local glyph, rule, whatsit = node.id('glyph'), node.id('rule'), node.id('whatsit')
+ local glyph, rule, whatsit, hlist, vlist = node.id('glyph'), node.id('rule'), node.id('whatsit'), node.id('hlist'), node.id('vlist')
local current, used, done = 0, { }, false
@@ -140,11 +149,11 @@ do
current, used, done = 0, { }, false
end
- local contains = node.has_attribute
+ local contains, copy = node.has_attribute, node.copy
- function insert(n,stack,previous,head)
+ local function insert(n,stack,previous,head)
if n then
- n = node.copy(n)
+ n = copy(n)
n.next = stack
if previous then
previous.next = n
@@ -156,94 +165,128 @@ do
return stack, previous, head
end
- function states.finalize(what,attribute,head)
- if what.enabled and what.none and current > 0 and head.list then
- local head = head.list
- stack, previous, head = insert(what.none,list,nil,list)
+ function states.finalize(namespace,attribute,head)
+ if current > 0 and namespace.none then
+ if head.id == hlist or head.id == vlist then
+ local stack, previous, head = insert(namespace.none,head.list,nil,head.list)
+ else
+ local stack, previous, head = insert(namespace.none,head,nil,head)
+ end
+ return true, head, true
+ else
+ return false, head, false
end
- return done, head, used
end
---~ function states.process(what,attribute,stack,previous,head) -- one attribute
---~ if what.enabled then
---~ local c = contains(stack,attribute)
---~ if c then
---~ if current ~= c then
---~ local id = stack.id
---~ if id == glyph or id == rule or id == whatsit then
---~ stack, previous, head = insert(what.data[c],stack,previous,head)
---~ current, done, used[c] = c, true, true
---~ end
---~ end
---~ elseif current > 0 then
---~ stack, previous, head = insert(what.none,stack,previous,head)
---~ current, done, used[0] = 0, true, true
---~ end
---~ end
---~ return stack, previous, head
---~ end
-
- function states.process(what,attribute,stack,previous,head) -- one attribute
- if what.enabled then
+ function states.process(namespace,attribute,head,inheritance,default) -- one attribute
+ local trigger = nodes.triggering and nodes.trigger
+ local stack, previous, done, process = head, nil, false, states.process
+ while stack do
local id = stack.id
- if id == glyph or id == rule then -- or id == whatsit then
+ if id == hlist or id == vlist then
+ local content = stack.list
+ if content then
+ local ok = false
+ if trigger and contains(stack,trigger) then
+ local outer = contains(stack,attribute)
+ if outer ~= inheritance then
+ ok, stack.list = process(namespace,attribute,content,inheritance,outer)
+ else
+ ok, stack.list = process(namespace,attribute,content,inheritance,default)
+ end
+ else
+ ok, stack.list = process(namespace,attribute,content,inheritance,default)
+ end
+ done = done or ok
+ end
+ elseif id == glyph or id == rule or id == whatsit then -- special
local c = contains(stack,attribute)
if c then
- if current ~= c then
- stack, previous, head = insert(what.data[c],stack,previous,head)
+ if default and c == inheritance then
+ if current ~= default then
+ local data = namespace.data[default] or namespace.reviver(default)
+ stack, previous, head = insert(data,stack,previous,head)
+ current, done, used[default] = default, true, true
+ end
+ elseif current ~= c then
+ local data = namespace.data[c] or namespace.reviver(c)
+ stack, previous, head = insert(data,stack,previous,head)
current, done, used[c] = c, true, true
end
+ elseif default and inheritance then
+ if current ~= default then
+ local data = namespace.data[default] or namespace.reviver(default)
+ stack, previous, head = insert(data,stack,previous,head)
+ current, done, used[default] = default, true, true
+ end
elseif current > 0 then
- stack, previous, head = insert(what.none,stack,previous,head)
+ stack, previous, head = insert(namespace.none,stack,previous,head)
current, done, used[0] = 0, true, true
end
end
+ previous = stack
+ stack = stack.next
end
- return stack, previous, head
+ return done, head
end
---~ function states.selective(what,attribute,stack,previous,head) -- two attributes
---~ if what.enabled then
---~ local c = contains(stack,attribute)
---~ if c then
---~ if current ~= c then
---~ local id = stack.id
---~ if id == glyph or id == rule then -- or id == whatsit then
---~ stack, previous, head = insert(what.data[c][contains(stack,what.selector) or what.default],stack,previous,head)
---~ current, done, used[c] = c, true, true
---~ end
---~ end
---~ elseif current > 0 then
---~ local id = stack.id
---~ if id == glyph or id == rule then -- or id == whatsit then
---~ stack, previous, head = insert(what.none,stack,previous,head)
---~ current, done, used[0] = 0, true, true
---~ end
---~ end
---~ end
---~ return stack, previous, head
---~ end
+ -- we can force a selector, e.g. document wide color spaces, saves a little
- function states.selective(what,attribute,stack,previous,head) -- two attributes
- if what.enabled then
+ function states.selective(namespace,attribute,head,inheritance,default) -- two attributes
+ local trigger = nodes.triggering and nodes.trigger
+ local stack, previous, done, selective = head, nil, false, states.selective
+ local defaultselector, forcedselector, selector, reviver = namespace.default, namespace.forced, namespace.selector, namespace.reviver
+ local none = namespace.none
+ while stack do
local id = stack.id
- if id == glyph or id == rule then -- or id == whatsit then
+ if id == hlist or id == vlist then
+ local content = stack.list
+ if content then
+ local ok = false
+ if trigger and contains(stack,trigger) then
+ local outer = contains(stack,attribute)
+ if outer ~= inheritance then
+ ok, stack.list = selective(namespace,attribute,content,inheritance,outer)
+ else
+ ok, stack.list = selective(namespace,attribute,content,inheritance,default)
+ end
+ else
+ ok, stack.list = selective(namespace,attribute,content,inheritance,default)
+ end
+ done = done or ok
+ end
+ elseif id == glyph or id == rule or id == whatsit then -- special
local c = contains(stack,attribute)
if c then
- if current ~= c then
- stack, previous, head = insert(what.data[c][contains(stack,what.selector) or what.default],stack,previous,head)
+ if default and c == inheritance then
+ if current ~= default then
+ local data = namespace.data[default] or reviver(default)
+ stack, previous, head = insert(data[forcedselector or contains(stack,selector) or defaultselector],stack,previous,head)
+ current, done, used[default] = default, true, true
+ end
+ elseif current ~= c then
+ local data = namespace.data[c] or reviver(c)
+ stack, previous, head = insert(data[forcedselector or contains(stack,selector) or defaultselector],stack,previous,head)
current, done, used[c] = c, true, true
end
+ elseif default and inheritance then
+ if current ~= default then
+ local data = namespace.data[default] or reviver(default)
+ stack, previous, head = insert(data[forcedselector or contains(stack,selector) or defaultselector],stack,previous,head)
+ current, done, used[default] = default, true, true
+ end
elseif current > 0 then
- stack, previous, head = insert(what.none,stack,previous,head)
+ stack, previous, head = insert(none,stack,previous,head)
current, done, used[0] = 0, true, true
end
end
+ previous = stack
+ stack = stack.next
end
- return stack, previous, head
+ return done, head
end
- collected = { }
+ local collected = { }
function states.collect(str)
collected[#collected+1] = str
@@ -269,24 +312,40 @@ end
-- we also need to store the colorvalues because we need then in mp
-colors = colors or { }
-colors.enabled = true
-colors.data = colors.data or { }
-colors.strings = colors.strings or { }
+colors = colors or { }
+colors.data = colors.data or { }
+colors.values = colors.values or { }
colors.registered = colors.registered or { }
+colors.enabled = true
colors.weightgray = true
colors.attribute = 0
colors.selector = 0
colors.default = 1
+colors.main = nil
-input.storage.register(true,"colors/data", colors.strings, "colors.data")
+-- This is a compromis between speed and simplicity. We used to store the
+-- values and data in one array, which made in neccessary to store the
+-- converters that need node constructor into strings and evaluate them
+-- at runtime (after reading from storage). Think of:
+--
+-- colors.strings = colors.strings or { }
+--
+-- if environment.initex then
+-- colors.strings[color] = "return colors." .. colorspace .. "(" .. table.concat({...},",") .. ")"
+-- end
+--
+-- input.storage.register(true,"colors/data", colors.strings, "colors.data") -- evaluated
+--
+-- We assume that only processcolors are defined in the format.
+
+input.storage.register(false,"colors/values", colors.values, "colors.values")
input.storage.register(false,"colors/registered", colors.registered, "colors.registered")
colors.stamps = {
rgb = "r:%s:%s:%s",
cmyk = "c:%s:%s:%s:%s",
gray = "s:%s",
- spot = "p:%s:%s"
+ spot = "p:%s:%s:%s:%s"
}
colors.models = {
@@ -303,23 +362,23 @@ do
local format = string.format
local concat = table.concat
- local function rgbdata(r,g,b)
- return pdfliteral(format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b))
+ local function rgbdata(r,g,b) -- dodo: backends.pdf.rgbdata
+ return backends.pdf.literal(format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b))
end
local function cmykdata(c,m,y,k)
- return pdfliteral(format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k))
+ return backends.pdf.literal(format("%s %s %s %s k %s %s %s %s K",c,m,y,k,c,m,y,k))
end
local function graydata(s)
- return pdfliteral(format("%s g %s G",s,s))
+ return backends.pdf.literal(format("%s g %s G",s,s))
end
- local function spotdata(n,p) -- name, parent, ratio
+ local function spotdata(n,f,d,p)
if type(p) == "string" then
p = p:gsub(","," ") -- brr misuse of spot
end
- return pdfliteral(format("/%s cs /%s CS %s SCN %s scn",n,n,p,p))
+ return backends.pdf.literal(format("/%s cs /%s CS %s SCN %s scn",n,n,p,p))
end
local function rgbtocmyk(r,g,b)
@@ -349,33 +408,54 @@ do
-- default color space
function colors.gray(s)
- local gray = graydata(s)
- return { gray, gray, gray, gray, 2, s, 0, 0, 0, 0, 0, 0, 1 }
+ return { 2, s, 0, 0, 0, 0, 0, 0, 1 }
end
function colors.rgb(r,g,b)
local s = rgbtogray(r,g,b)
local c, m, y, k = rgbtocmyk(r,g,b)
- local gray, rgb, cmyk = graydata(s), rgbdata(r,g,b), cmykdata(c,m,y,k)
- return { rgb, gray, rgb, cmyk, 3, s, r, g, b, c, m, y, k }
+ return { 3, s, r, g, b, c, m, y, k }
end
function colors.cmyk(c,m,y,k)
local s = cmyktogray(c,m,y,k)
local r, g, b = cmyktorgb(c,m,y,k)
- local gray, rgb, cmyk = graydata(s), rgbdata(r,g,b), cmykdata(c,m,y,k)
- return { cmyk, gray, rgb, cmyk, 4, s, r, g, b, c, m, y, k }
+ return { 4, s, r, g, b, c, m, y, k }
end
- function colors.spot(parent,p) -- parent, ratio
- local spot = spotdata(parent,p)
- if type(p) == "string" and p:find(",") then
- -- use converted replacement (combination color)
- else
- -- todo: map gray, rgb, cmyk onto fraction*parent
+ function colors.spot(parent,f,d,p)
+--~ if type(p) == "string" and p:find(",") then
+--~ -- use converted replacement (combination color)
+--~ else
+--~ -- todo: map gray, rgb, cmyk onto fraction*parent
+--~ end
+ return { 5, .5, .5, .5, .5, 0, 0, 0, .5, parent, f, d, p }
+ end
+
+ function colors.reviver(n)
+ local d = colors.data[n]
+ if not d then
+ local v = colors.values[n]
+ if not v then
+ local gray = graydata(0)
+ d = { gray, gray, gray, gray }
+ logs.report("attributes",string.format("unable to revive color %s",n or "?"))
+ else
+ local kind, gray, rgb, cmyk = v[1], graydata(v[2]), rgbdata(v[3],v[4],v[5]), cmykdata(v[6],v[7],v[8],v[9])
+ if kind == 2 then
+ d = { gray, gray, gray, gray }
+ elseif kind == 3 then
+ d = { rgb, gray, rgb, cmyk }
+ elseif kind == 4 then
+ d = { cmyk, gray, rgb, cmyk }
+ elseif kind == 5 then
+ local spot = spotdata(v[10],v[11],v[12],v[13])
+ d = { spot, gray, rgb, cmyk }
+ end
+ end
+ colors.data[n] = d
end
- local gray, rgb, cmyk = graydata(.5), rgbdata(.5,.5,.5), cmykdata(0,0,0,.5)
- return { spot, gray, rgb, cmyk, 5 }
+ return d
end
function colors.filter(n)
@@ -386,284 +466,197 @@ do
end
--- conversion models
-
function colors.setmodel(attribute,name)
colors.selector = attributes.numbers[attribute]
colors.default = colors.models[name] or 1
return colors.default
end
-function colors.register(attribute, name, colorspace, ...)
+function colors.register(attribute, name, colorspace, ...) -- passing 9 vars is faster
local stamp = string.format(colors.stamps[colorspace], ...)
local color = colors.registered[stamp]
if not color then
- local cd = colors.data
- color = #cd+1
- cd[color] = colors[colorspace](...)
- if environment.initex then
- colors.strings[color] = "return colors." .. colorspace .. "(" .. table.concat({...},",") .. ")"
- end
+ color = #colors.values+1
+ colors.values[color] = colors[colorspace](...)
colors.registered[stamp] = color
+ colors.reviver(color)
+ end
+ if name then
+ attributes.list[attributes.numbers[attribute]][name] = color -- not grouped, so only global colors
end
- attributes.list[attributes.numbers[attribute]][name] = color
return colors.registered[stamp]
end
+function colors.value(id)
+ return colors.values[id]
+end
+
shipouts.plugins.color = {
- initializer = function(...) return states.initialize(colors,...) end,
- finalizer = function(...) return states.finalize (colors,...) end,
- processor = function(...) return states.selective (colors,...) end,
+ namespace = colors,
+ initializer = states.initialize,
+ finalizer = states.finalize ,
+ processor = states.selective ,
+ resolver = function(...) return colors.main end,
+}
+
+-- transparencies
+
+-- for the moment we manage transparencies in the pdf driver because
+-- first we need a nice interface to some pdf things
+
+transparencies = transparencies or { }
+transparencies.registered = transparencies.registered or { }
+transparencies.data = transparencies.data or { }
+transparencies.values = transparencies.values or { }
+transparencies.enabled = true
+transparencies.template = "%s:%s"
+
+input.storage.register(false, "transparencies/registered", transparencies.registered, "transparencies.registered")
+input.storage.register(false, "transparencies/data", transparencies.data, "transparencies.data")
+input.storage.register(false, "transparencies/values", transparencies.values, "transparencies.values")
+
+function transparencies.reference(n)
+ return backends.pdf.literal(string.format("/Tr%s gs",n))
+end
+
+transparencies.none = transparencies.reference(0)
+
+function transparencies.register(name,...)
+ local stamp = string.format(transparencies.template, ...)
+ local n = transparencies.registered[stamp]
+ if not n then
+ n = #transparencies.data+1
+ transparencies.data[n] = transparencies.reference(n)
+ transparencies.values[n] = { ... }
+ transparencies.registered[stamp] = n
+ states.collect(string.format("\\presetPDFtransparency{%s}{%s}",...)) -- too many, but experimental anyway
+ end
+ return transparencies.registered[stamp]
+end
+
+function transparencies.value(id)
+ return transparencies.values[id]
+end
+
+shipouts.plugins.transparency = {
+ namespace = transparencies,
+ initializer = states.initialize,
+ finalizer = states.finalize ,
+ processor = states.process ,
}
--- overprint / knockout
-overprints = { enabled = true , data = { } }
+overprints = overprints or { }
+overprints.data = overprints.data or { }
+overprints.enabled = true
+
+overprints.data[1] = backends.pdf.literal(string.format("/GSoverprint gs"))
+overprints.data[2] = backends.pdf.literal(string.format("/GSknockout gs"))
-overprints.none = pdfliteral(string.format("/GSoverprint gs"))
-overprints.data[1] = pdfliteral(string.format("/GSknockout gs"))
+overprints.none = overprints.data[1]
overprints.registered = {
- overprint = 0,
- knockout = 1,
+ overprint = 1,
+ knockout = 2,
}
function overprints.register(stamp)
+-- states.collect(tex.sprint(tex.ctxcatcodes,"\\initializePDFoverprint")) -- to be testd
return overprints.registered[stamp] or overprints.registered.overprint
end
shipouts.plugins.overprint = {
- initializer = function(...) return states.initialize(overprints,...) end,
- finalizer = function(...) return states.finalize (overprints,...) end,
- processor = function(...) return states.process (overprints,...) end,
+ namespace = overprints,
+ initializer = states.initialize,
+ finalizer = states.finalize ,
+ processor = states.process ,
}
--- negative / positive
-negatives = { enabled = true, data = { } }
+negatives = netatives or { }
+negatives.data = negatives.data or { }
+negatives.enabled = true
-negatives.none = pdfliteral(string.format("/GSpositive gs"))
-negatives.data[1] = pdfliteral(string.format("/GSnegative gs"))
+negatives.data[1] = backends.pdf.literal(string.format("/GSpositive gs"))
+negatives.data[2] = backends.pdf.literal(string.format("/GSnegative gs"))
+
+negatives.none = negatives.data[1]
negatives.registered = {
- positive = 0,
- negative = 1,
+ positive = 1,
+ negative = 2,
}
function negatives.register(stamp)
+-- states.collect(tex.sprint(tex.ctxcatcodes,"\\initializePDFnegative")) -- to be testd
return negatives.registered[stamp] or negatives.registered.positive
end
shipouts.plugins.negative = {
- initializer = function(...) return states.initialize(negatives,...) end,
- finalizer = function(...) return states.finalize (negatives,...) end,
- processor = function(...) return states.process (negatives,...) end,
+ namespace = negatives,
+ initializer = states.initialize,
+ finalizer = states.finalize,
+ processor = states.process,
}
-- effects
-effects = { enabled = true, data = { } }
-
-effects.none = pdfliteral(string.format("0 Tr"))
-effects.data[1] = pdfliteral(string.format("1 Tr"))
-effects.data[2] = pdfliteral(string.format("2 Tr"))
-effects.data[3] = pdfliteral(string.format("3 Tr"))
+effects = effects or { }
+effects.data = effects.data or { }
+effects.registered = effects.registered or { }
+effects.enabled = true
+effects.stamp = "%s:%s:%s"
+
+input.storage.register(false, "effects/registered", effects.registered, "effects.registered")
+input.storage.register(false, "effects/data", effects.data, "effects.data")
+
+function effects.register(effect,stretch,rulethickness)
+ local stamp = string.format(effects.stamp,effect,stretch,rulethickness)
+ local n = effects.registered[stamp]
+ if not n then
+ n = #effects.data+1
+ effects.data[n] = effects.reference(effect,stretch,rulethickness)
+ effects.registered[stamp] = n
+ -- states.collect("") -- nothing
+ end
+ return effects.registered[stamp]
+end
-effects.registered = {
- normal = 0,
- inner = 0,
- outer = 1,
- both = 2,
- hidden = 3,
+backends.pdf.effects = {
+ normal = 1,
+ inner = 1,
+ outer = 2,
+ both = 3,
+ hidden = 4,
}
-function effects.register(stamp)
- return effects.registered[stamp] or effects.registered.normal
+function effects.reference(effect,stretch,rulethickness) -- will move, test code, we will develop a proper model for that
+ effect = backends.pdf.effects[effects] or backends.pdf.effects['normal']
+ if stretch > 0 then
+ stretch = stretch .. " w "
+ else
+ stretch = ""
+ end
+ if rulethickness > 0 then
+ rulethickness = number.dimenfactors["bp"]*rulethickness.. " Tc "
+ else
+ rulethickness = ""
+ end
+ return backends.pdf.literal(string.format("%s%s%s Tr",stretch,rulethickness,effect)) -- watch order
end
+effects.none = effects.reference(effect,0,0)
+
shipouts.plugins.effect = {
- initializer = function(...) return states.initialize(effects,...) end,
- finalizer = function(...) return states.finalize (effects,...) end,
- processor = function(...) return states.process (effects,...) end,
+ namespace = effects,
+ initializer = states.initialize,
+ finalizer = states.finalize ,
+ processor = states.process ,
}
-- layers
--~ /OC /somename BDC
--~ EMC
-
--- transparencies
-
--- for the moment we manage transparencies in the pdf driver because
--- first we need a nice interface to some pdf things
-
-transparencies = {
- enabled = true,
- data = { },
- registered = { },
- hack = { }
-}
-
-input.storage.register(false, "transparencies/registed", transparencies.registered, "transparencies.registered")
-input.storage.register(false, "transparencies/data", transparencies.data, "transparencies.data")
-input.storage.register(false, "transparencies/hack", transparencies.hack, "transparencies.hack")
-
-function transparencies.reference(n)
- return pdfliteral(string.format("/Tr%s gs",n))
-end
-
-transparencies.none = transparencies.reference(0)
-
-transparencies.stamp = "%s:%s"
-
-function transparencies.register(...)
- local stamp = string.format(transparencies.stamp, ...)
- if not transparencies.registered[stamp] then
- local n = #transparencies.data+1
- transparencies.data[n] = transparencies.reference(n)
- transparencies.registered[stamp] = n
- states.collect(string.format("\\presetPDFtransparency{%s}{%s}",...)) -- too many, but experimental anyway
- end
- return transparencies.registered[stamp]
-end
-
-shipouts.plugins.transparency = {
- initializer = function(...) return states.initialize(transparencies,...) end,
- finalizer = function(...) return states.finalize (transparencies,...) end,
- processor = function(...) return states.process (transparencies,...) end,
-}
-
---~ shipouts.plugins.transparency.flusher = function(attribute,head,used)
---~ local max = 0
---~ for k,v in pairs(used) do
---~ end
---~ return head
---~ end
-
---~ from the time that node lists were tables and not userdata ...
---~
---~ local function do_collapse_page(stack,existing_t)
---~ if stack then
---~ local t = existing_t or { }
---~ for _, node in ipairs(stack) do
---~ if node then
---~ local kind = node[1]
---~ node[3] = nil
---~ if kind == 'hlist' or kind == 'vlist' then
---~ node[8] = do_collapse_page(node[8]) -- maybe here check for nil
---~ t[#t+1] = node
---~ elseif kind == 'inline' then -- appending literals cost too much time
---~ local nodes = node[4]
---~ if #nodes == 1 then
---~ t[#t+1] = nodes[1]
---~ else
---~ do_collapse_page(nodes,t)
---~ end
---~ else
---~ t[#t+1] = node
---~ end
---~ end
---~ end
---~ return t
---~ else
---~ return nil
---~ end
---~ end
---~
---~ local function do_process_page(attribute,processor,stack)
---~ if stack then
---~ for i, node in ipairs(stack) do
---~ if node then
---~ local kind = node[1]
---~ if kind == 'hlist' or kind == "vlist" then
---~ local content = node[8]
---~ if not content then
---~ -- nil node
---~ elseif type(content) == "table" then
---~ node[8] = do_process_page(attribute,processor,content)
---~ else
---~ node[8] = do_process_page(attribute,processor,tex.get_node_list(content))
---~ end
---~ elseif kind == 'inline' then
---~ node[4] = do_process_page(attribute,processor,node[4])
---~ else
---~ processor(attribute,stack,i,node,kind)
---~ end
---~ end
---~ end
---~ end
---~ return stack
---~ end
---~
---~ function nodes.process_page(stack,...)
---~ if stack then
---~ input.start_timing(nodes)
---~ local done, used = false, { }
---~ for name, plugin in pairs(shipouts.plugins) do
---~ local attribute = attributes.numbers[name]
---~ if attribute then
---~ local initializer = plugin.initializer
---~ local processor = plugin.processor
---~ local finalizer = plugin.finalizer
---~ if initializer then
---~ initializer(attribute,stack)
---~ end
---~ if processor then
---~ do_process_page(attribute,processor,stack)
---~ end
---~ if finalizer then
---~ local ok
---~ ok, used[attribute] = finalizer(attribute,stack)
---~ done = done or ok
---~ end
---~ else
---~ texio.write_nl(string.format("undefined attribute %s",name))
---~ end
---~ end
---~ if done then
---~ stack = do_collapse_page(stack)
---~ for name, plugin in pairs(shipouts.plugins) do
---~ local attribute = attributes.numbers[name]
---~ if used[attribute] then
---~ local flusher = plugin.flusher
---~ if flusher then
---~ flusher(attribute,stack,used[attribute])
---~ end
---~ end
---~ end
---~ else
---~ stack = true
---~ end
---~ input.stop_timing(nodes)
---~ end
---~ return stack
---~ end
---~
---~ function states.finalize(what,attribute,stack)
---~ if what.enabled then
---~ if current > 0 then
---~ local list = stack
---~ if #stack == 1 then
---~ list = stack[#stack][8]
---~ end
---~ list[#list+1], current, done, used[0] = what.none, 0, true, true
---~ end
---~ end
---~ return done, used
---~ end
---~
---~ function states.process(what,attribute,stack,i,node,kind)
---~ if what.enabled then
---~ local a = node[3]
---~ if a then
---~ local c = a[attribute]
---~ if c then
---~ if current ~= c and (kind == 'glyph' or kind == 'rule') then
---~ stack[i], current, done, used[c] = nodes.inline(what.data[c], node), c, true, true
---~ end
---~ elseif current > 0 then
---~ stack[i], current, done, used[0] = nodes.inline(what.none, node), 0, true, true
---~ end
---~ end
---~ end
---~ end
diff --git a/tex/context/base/attr-ini.tex b/tex/context/base/attr-ini.tex
index 60746d560..d579429dd 100644
--- a/tex/context/base/attr-ini.tex
+++ b/tex/context/base/attr-ini.tex
@@ -51,10 +51,15 @@
\defineattribute[mark]
\defineattribute[status]
+\defineattribute[trigger] % feature inheritance
% \defineattribute[language]
\defineattribute[skip]
\defineattribute[penalty]
+\startruntimectxluacode
+ nodes.trigger = \dogetattributeid{trigger}
+\stopruntimectxluacode
+
% \dosetattribute{status}{1}
% temp here / will be indirect ! just for testing
@@ -67,8 +72,10 @@
% 1=off 2=gray 3=spot 4=rgb 5=cmyk 6=cmy % only 1/2/4/5 are supported
%
-% we could combine this in one attribute but this is not faster and also
-% less flexible because sometimes we want to freeze the attribute bit
+% We could combine this in one attribute but this is not faster and also
+% less flexible because sometimes we want to freeze the attribute bit.
+%
+% Watch out: real color support will be implemented later.
\newcount\currentcolormodel
@@ -76,51 +83,11 @@
{\currentcolormodel\ctxlua{tex.print(colors.setmodel('colormodel','#1'))}%
\dosetattribute{colormodel}{\the\currentcolormodel}}
-\setcolormodel{all} % when no color, reset ! !
-
-\def\registerrgbcolor#1#2#3#4% r g b -- print or sprint
- {\scratchcounter\ctxlua{tex.print(colors.register('color','#1','rgb',#2,#3,#4))}%
- \setevalue{(ca:#1)}{\number\scratchcounter}%
- \setevalue{(cv:#1)}{\ctxlua{tex.print(colors.filter(\number\scratchcounter))}}%
- \setevalue{(cs:#1)}{\dosetattribute{color}{\the\scratchcounter}}}
-
-\def\registercmykcolor#1#2#3#4#5% c m y k
- {\scratchcounter\ctxlua{tex.print(colors.register('color','#1','cmyk',#2,#3,#4,#5))}%
- \setevalue{(ca:#1)}{\number\scratchcounter}%
- \setevalue{(cv:#1)}{\ctxlua{tex.print(colors.filter(\number\scratchcounter))}}%
- \setevalue{(cs:#1)}{\dosetattribute{color}{\the\scratchcounter}}}
-
-\def\registergraycolor#1#2% s
- {\scratchcounter\ctxlua{tex.print(colors.register('color','#1','gray',#2))}%
- \setevalue{(ca:#1)}{\number\scratchcounter}%
- \setevalue{(cv:#1)}{\ctxlua{tex.print(colors.filter(\number\scratchcounter))}}%
- \setevalue{(cs:#1)}{\dosetattribute{color}{\the\scratchcounter}}}
-
-\def\registerspotcolor#1#2#3% p name
- {\scratchcounter\ctxlua{tex.print(colors.register('color','#1','spot',#2,#3))}%
- \setevalue{(ca:#1)}{\number\scratchcounter}%
- \setevalue{(cv:#1)}{\ctxlua{tex.print(colors.filter(\number\scratchcounter))}}%
- \setevalue{(cs:#1)}{\dosetattribute{color}{\the\scratchcounter}}}
-
-\def\somecolorvalue #1{\csname(cv:#1)\endcsname}
-\def\somecolorswitch #1{\csname(cs:#1)\endcsname}
-\def\somecolorattribute#1{\csname(ca:#1)\endcsname}
-
-\def\getMPcolorspec#1%
- {\expandafter\expandafter\expandafter\dogetMPcolorspec\csname (cv:#1)\endcsname\relax}
-
-\def\dogetMPcolorspec#1:#2:#3:#4:#5:#6:#7:#8:#9\relax % some day we will just pass a attribute number in pre/post
- {\ifcase\currentcolormodel\or
- \ifcase#1\or#2\or(#3,#4,#5)\or(#6,#7,#8,#9)\fi\or#2\or(#3,#4,#5)\or(#6,#7,#8,#9)%
- \fi}
-
-% \registerrgbcolor {red} {1}{0}{0}
-% \registerrgbcolor {green} {0}{1}{0}
-% \registerrgbcolor {blue} {0}{0}{1}
-% \registercmykcolor {cyan} {1}{0}{0}{0}
-% \registercmykcolor {magenta} {0}{1}{0}{0}
-% \registercmykcolor {yellow} {0}{0}{1}{0}
-% \registergraycolor {black} {0}
+\setcolormodel{all}
+
+\def\registerrgbcolor #1#2#3#4{\ctxlua{colors.register('color','#1','rgb' ,#2,#3,#4)}}
+\def\registercmykcolor#1#2#3#4#5{\ctxlua{colors.register('color','#1','cmyk',#2,#3,#4,#5)}}
+\def\registergraycolor #1#2{\ctxlua{colors.register('color','#1','gray',#2)}}
% transparency
@@ -139,9 +106,12 @@
\defineattribute[overprint]
\def\registeroverprint#1#2%
- {\initializePDFoverprint % temp here
+ {\initializePDFoverprint % temp here, to be tested in la code (states.collect)
\setvalue{(os:#1)}{\dosetattribute{overprint}{\ctxlua{tex.print(overprints.register('#2'))}}}}
+\def\dotriggeroverprint#1%
+ {\csname(os:#1)\endcsname}
+
% \registeroverprint{knockout} {knockout}
% \registeroverprint{overprint}{overprint}
@@ -150,9 +120,12 @@
\defineattribute[negative]
\def\registernegative#1#2%
- {\initializePDFnegative % temp here
+ {\initializePDFnegative % temp here, to be tested in la code (states.collect)
\setvalue{(ns:#1)}{\dosetattribute{negative}{\ctxlua{tex.print(negatives.register('#2'))}}}}
+\def\dotriggernegative#1%
+ {\csname(ns:#1)\endcsname}
+
% \registernegative{positive}{positive}
% \registernegative{negative}{negative}
@@ -160,8 +133,13 @@
\defineattribute[effect]
-\def\registereffect#1%
- {\setevalue{(es:#1)}{\dosetattribute{effect}{\ctxlua{tex.print(effects.register('#1'))}}}}
+\def\registereffect#1#2#3% #2=stretch #3=rulethickness
+ {\setxvalue{(es:#1:#2:\number\dimexpr#3\relax)}%
+ {\dosetattribute{effect}{\ctxlua{tex.print(effects.register('#1',#2,\number\dimexpr#3\relax))}}}}
+
+\def\dotriggereffect#1#2#3%
+ {\ifcsname(es:#1:#2:\number\dimexpr#3\relax)\endcsname\else\registereffect{#1}{#2}{#3}\fi
+ \csname(es:#1:#2:\number\dimexpr#3\relax)\endcsname}
% \registereffect{normal}
% \registereffect{inner}
@@ -186,14 +164,48 @@
% {\ctxlua{nodes.process_page(tex.box[\number\nextbox])}%
% \primitive\shipout\box\nextbox}}
-\def\processshipoutbox#1% % hack till we have access to pdf backend
- {\setbox\nextbox\hbox{#1}%
- \ctxlua{nodes.process_page(tex.box[\number\nextbox])}%
- \hbox{\ctxlua{states.flush()}\box\nextbox}}
+\newbox\finalizedshipoutbox
+
+\def\finalizeshipoutbox#1% % hack till we have access to pdf backend
+ {\global\setbox\finalizedshipoutbox\hbox{#1}%
+ \ctxlua{nodes.process_page(tex.box[\number\finalizedshipoutbox])}%
+ \hbox{\ctxlua{states.flush()}\box\finalizedshipoutbox}}
% \def\shipout
% {\dowithnextbox{\ctxlua{tex.primitive('shipout', nodes.process_page(tex.nextbox)}}}
\let\normalshipout\shipout
+% Objects are processed indepently \unknown\ actually we may need a proper callback.
+
+\def\finalizeobjectbox#1%
+ {\ctxlua{nodes.process_page(tex.box[\number#1])}}
+
+% tricky stuff:
+
+\newcount\attributeboxcount
+
+\edef\startinheritattributes{\dosetattribute {trigger}{1}}
+\edef\stopinheritattributes {\doresetattribute{trigger}}
+
+\def\doattributedcopy {\afterassignment\dodoattributedcopy\attributeboxcount}
+\def\doattributedbox {\afterassignment\dodoattributedbox \attributeboxcount}
+
+\def\dodoattributedcopy{\startinheritattributes\ifvbox\attributeboxcount\vbox\else\hbox\fi{\unhcopy\attributeboxcount}\stopinheritattributes}
+\def\dodoattributedbox {\startinheritattributes\ifvbox\attributeboxcount\vbox\else\hbox\fi{\unhbox \attributeboxcount}\stopinheritattributes}
+
+\def\enableattributeinheritance
+ {\ctxlua{nodes.triggering=true}%
+ \let\attributedcopy\doattributedcopy
+ \let\attributedbox \doattributedbox}
+
+\def\disableattributeinheritance
+ {\ctxlua{nodes.triggering=false}%
+ \let\attributedcopy\copy
+ \let\attributedbox \box}
+
+\disableattributeinheritance
+
+% \enableattributeinheritance % will become default
+
\protect \endinput
diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua
index 0daa91c0d..d7a2044a2 100644
--- a/tex/context/base/char-ini.lua
+++ b/tex/context/base/char-ini.lua
@@ -23,10 +23,15 @@ characters = characters or { }
characters.data = characters.data or { }
characters.context = characters.context or { }
-_empty_table_ = { }
-_empty_table_.__index = function(t,k) return "" end
+do
+ local _empty_table_ = { __index = function(t,k) return "" end }
-setmetatable(characters.data,_empty_table_)
+ function table.set_empty_metatable(t)
+ setmetatable(t,_empty_table_)
+ end
+end
+
+table.set_empty_metatable(characters.data)
--[[ldx--
<p>At this point we assume that the big data table is loaded. From this
diff --git a/tex/context/base/char-utf.lua b/tex/context/base/char-utf.lua
index 79f5718fd..2d11a1794 100644
--- a/tex/context/base/char-utf.lua
+++ b/tex/context/base/char-utf.lua
@@ -62,7 +62,9 @@ end
function characters.filters.utf.collapse(str)
if characters.filters.utf.collapsing and str and #str > 1 then
- characters.filters.utf.initialize()
+ if not characters.filters.utf.initialized then -- saves a call
+ characters.filters.utf.initialize()
+ end
local tokens, first, done = { }, false, false
local cg = characters.graphemes
for second in string.utfcharacters(str) do
@@ -152,7 +154,9 @@ do
function characters.filters.utf.collapse(str)
if characters.filters.utf.collapsing and str then
if #str > 1 then
- characters.filters.utf.initialize()
+ if not characters.filters.utf.initialized then -- saves a call
+ characters.filters.utf.initialize()
+ end
local tokens, first, done = { }, false, false
for second in string.utfcharacters(str) do
if cr[second] then
@@ -257,7 +261,7 @@ end
function characters.filters.process(str)
if characters.filters.activated then
- for _,v in pairs(characters.filters.sequences) do
+ for _,v in ipairs(characters.filters.sequences) do
str = v(str)
end
return str
diff --git a/tex/context/base/colo-hex.tex b/tex/context/base/colo-hex.tex
index b493b8c6b..e60f2a0ae 100644
--- a/tex/context/base/colo-hex.tex
+++ b/tex/context/base/colo-hex.tex
@@ -11,6 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\beginLUATEX
+ \endinput
+\endLUATEX
+
\ifx\dodododefinecolor\undefined
\beginTEX \endinput \endTEX
\else
diff --git a/tex/context/base/colo-ini.tex b/tex/context/base/colo-ini.tex
index 687d41da3..4e747707f 100644
--- a/tex/context/base/colo-ini.tex
+++ b/tex/context/base/colo-ini.tex
@@ -13,9 +13,6 @@
\writestatus{loading}{Context Color Macros / initialization}
-%D To do: stroke versus fill color
-%D 1000 100 10 -> constants
-
%D Possible optimization: store level in mark instead of name
\unprotect
@@ -367,7 +364,6 @@
\fi}
\def\paletcolorspec#1%
-% {\executeifdefined{\??cr\currentpalet#1}{\executeifdefined{\??cr#1}\empty}}
{\csname\??cr\currentpalet#1\endcsname}
%D Hex color support is not enabled by default. You need to say \type
@@ -661,6 +657,12 @@
\newif\ifpermitcolormode \permitcolormodetrue
+\def\startregistercolor[#1]%
+ {\permitcolormodefalse\startcolor[#1]\permitcolormodetrue}
+
+\def\stopregistercolor
+ {\permitcolormodefalse\stopcolor\permitcolormodetrue}
+
\def\dowithcolor#1#2% #1=\action #2=color
{\ifincolor\ifpermitcolormode
\ifcsname\??cr\currentpalet#2\endcsname
@@ -1572,7 +1574,7 @@
g=>\chardef\currentcolorchannel6,%
b=>\chardef\currentcolorchannel7,%
s=>\chardef\currentcolorchannel8,%
- \v!no=>,% \currentcolorchannel0,% all colors
+ \v!no=>,% \currentcolorchannel0,% all colors
\s!default=>,% \currentcolorchannel0,% all colors
\s!unknown=>\filterspotcolortrue
\edef\currentspotcolor{\commalistelement}]%
@@ -1660,6 +1662,13 @@
\expandafter\secondoftwoarguments
\fi}
+\def\doifcolor#1%
+ {\ifcsname\??cr\ifcsname\??cr\currentpalet#1\endcsname\currentpalet\fi#1\endcsname
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
%D \macros
%D {localstartcolor,localstopcolor}
%D
@@ -2191,17 +2200,45 @@
%D don't cross page boundaries in the way color does. Therefore
%D we don't need stacks and marks. Just to be compatible with
%D color support we offer both 'global' and 'local' commands.
+%D
+%D \starttyping
+%D \def\localstartraster[#1]%
+%D {\doifelsenothing{#1}
+%D {\dostartgraymode\@@rsscreen}
+%D {\dostartgraymode{#1}}}
+%D
+%D \def\localstopraster
+%D {\dostopgraymode}
+%D
+%D \let\startraster\localstartraster
+%D \let\stopraster \localstopraster
+%D \stoptyping
+%D
+%D The next alternative is slower, since it works on top of the
+%D color (stack) mechanism, but it does provide nesting.
+
+\def\dosetrastercolor#1%
+ {\edef\@@cl@@s{#1}%
+ \ifx\@@cl@@s\empty
+ \let\@@cl@@s\@@rsscreen
+ \fi
+ \let\@@cl@@t\@@cl@@z % else we get rogue
+ \let\@@cl@@a\@@cl@@z % transpancies
+ \setevalue{\??cr\??rs}{\colorSpattern}}
+
+% beware, don't add extra grouping, else color in tables
+% fails
\def\localstartraster[#1]%
- {\doifelsenothing{#1}
- {\dostartgraymode\@@rsscreen}
- {\dostartgraymode{#1}}}
+ {\ifincolor\dosetrastercolor{#1}\localstartcolor[\??rs]\fi}
+
+\def\startraster[#1]%
+ {\ifincolor\dosetrastercolor{#1}\startcolor[\??rs]\fi}
-\def\localstopraster
- {\dostopgraymode}
+\def\localstopraster{\ifincolor\localstopcolor\fi}
+\def\stopraster {\ifincolor\stopcolor\fi}
-\let\startraster\localstartraster
-\let\stopraster \localstopraster
+\def\raster[#1]{\groupedcommand{\startraster[#1]}{\stopraster}}
%D In this documentation we will not go into too much details
%D on palets. Curious users can find more information on this
@@ -2280,22 +2317,23 @@
{\doifvaluesomething{\??pa#1}
{\setevalue{\??pa#1}{\csname\??pa#1\endcsname,}}%
\setevalue{\??pa#1}{\csname\??pa#1\endcsname##1}%
- \doifassignmentelse{##2}
- {% == \definepalet[test][xx={y=.4}]
- \definecolor[\??pa#1:##1][##2]%
- \iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi
- {\??cr#1:##1}{\csname\??cr\??pa#1:##1\endcsname}}
- {% == \definepalet[test][xx=green]
- \doifdefinedelse{\??cr##2}
- {\iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi
- {\??cr#1:##1}{\csname\??cr##2\endcsname}}
- {\letvalue{\??cr#1:##1}\colorXpattern}}}%
+ \dodefinepaletcolor{#1}{##1}{##2}}%
\def\dododefinepalet##1%
{\dodododefinepalet[##1]}%
\processcommalist[#2]\dododefinepalet}
{\doifdefined{\??pa#2}
{\expanded{\dodefinepalet[#1][\csname\??pa\??pa#2\endcsname]}}}}
+\def\dodefinepaletcolor#1#2#3%
+ {\doifassignmentelse{#3}
+ {% == \definepalet[test][xx={y=.4}]
+ \definecolor[\??pa#1:#2][#3]%
+ \iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{\??cr#1:#2}{\csname\??cr\??pa#1:#2\endcsname}}
+ {% == \definepalet[test][xx=green]
+ \doifdefinedelse{\??cr#3}
+ {\iffreezecolors\@EA\setevalue\else\@EA\setvalue\fi{\??cr#1:#2}{\csname\??cr#3\endcsname}}
+ {\letvalue{\??cr#1:#2}\colorXpattern}}}
+
\let\paletsize\!!zerocount
\def\getpaletsize[#1]%
@@ -2386,28 +2424,51 @@
\def\definecolorgroup
{\dotripleempty\dodefinecolorgroup}
-\def\dodefinecolorgroup[#1][#2][#3]%
+% \def\dodefinecolorgroup[#1][#2][#3]%
+% {\ifthirdargument
+% \processaction
+% [#2]
+% [ \v!cmyk=>\edef\currentcolorspace{C},
+% \v!rgb=>\edef\currentcolorspace{R},
+% \v!gray=>\edef\currentcolorspace{S},
+% \v!spot=>\edef\currentcolorspace{P},
+% \v!s=>\edef\currentcolorspace{S},
+% \s!unknown=>\edef\currentcolorspace{R}]%
+% \colorcount\zerocount
+% \def\dododefinecolorgroup##1%
+% {\advance\colorcount \plusone
+% \setevalue{\??cr#1:\the\colorcount}{\currentcolorspace:##1:0:0}}%
+% \processcommalist[#3]\dododefinecolorgroup
+% \else
+% \doifinstringelse{:}{#2}
+% {\definecolorgroup[#1][\v!rgb][#2]}
+% {\doloop
+% {\doifdefinedelse{\??cr#2:\recurselevel}
+% {\setevalue{\??cr#1:\recurselevel}%
+% {\csname\??cr#2:\recurselevel\endcsname}}
+% {\exitloop}}}%
+% \fi}
+
+\def\dododefinecolorgroupgray [#1][#2:#3]{\definecolor [#1:\the\colorcount][s=#2]}
+\def\dododefinecolorgrouprgb [#1][#2:#3:#4:#5]{\definecolor [#1:\the\colorcount][r=#2,g=#3,b=#4]}
+\def\dododefinecolorgroupcmyk[#1][#2:#3:#4:#5:#6]{\definecolor [#1:\the\colorcount][c=#2,m=#3=,y=#4,k=#5]}
+\def\dododefinecolorgroupspot [#1][#2:#3:#4]{\definespotolor[#1:\the\colorcount][#2][p=#3]}
+
+\def\dododefinecolorgroup#1#2%
+ {\advance\colorcount\plusone
+ \getvalue{dododefinecolorgroup\currentcolorspace}[#1][#2:0:0:0:0]}
+
+\def\dodefinecolorgroup[#1][#2][#3]% obsolete, just use palets
{\ifthirdargument
- \processaction
- [#2]
- [ \v!cmyk=>\edef\currentcolorspace{C},
- \v!rgb=>\edef\currentcolorspace{R},
- \v!gray=>\edef\currentcolorspace{S},
- \v!spot=>\edef\currentcolorspace{P},
- \v!s=>\edef\currentcolorspace{S},
- \s!unknown=>\edef\currentcolorspace{R}]%
+ \doifelsenothing{#2}{\let\currentcolorspace\v!rgb}{\def\currentcolorspace{#2}}%
\colorcount\zerocount
- \def\dododefinecolorgroup##1%
- {\advance\colorcount \plusone
- \setevalue{\??cr#1:\the\colorcount}{\currentcolorspace:##1:0:0}}%
- \processcommalist[#3]\dododefinecolorgroup
+ \processcommalist[#3]{\dododefinecolorgroup{#1}}%
\else
\doifinstringelse{:}{#2}
{\definecolorgroup[#1][\v!rgb][#2]}
{\doloop
{\doifdefinedelse{\??cr#2:\recurselevel}
- {\setevalue{\??cr#1:\recurselevel}%
- {\csname\??cr#2:\recurselevel\endcsname}}
+ {\setevalue{\??cr#1:\recurselevel}{\csname\??cr#2:\recurselevel\endcsname}}
{\exitloop}}}%
\fi}
@@ -2443,11 +2504,11 @@
%D \hbox to \hsize
%D {\hss
%D \showcolorgroup [red] [vertical,name,number]\hss
-%D \showcolorgroup [green] [vertical,name]\hss
+%D \showcolorgroup [green] [vertical,name]\hss
%D \showcolorgroup [blue] [vertical,name]\hss
%D \showcolorgroup [cyan] [vertical,name]\hss
-%D \showcolorgroup [magenta] [vertical,name]\hss
-%D \showcolorgroup [yellow] [vertical,name]\hss}
+%D \showcolorgroup [magenta][vertical,name]\hss
+%D \showcolorgroup [yellow] [vertical,name]\hss}
%D \stoplinecorrection
%D
%D These groups are used to define palets {\em alfa} upto {\em
@@ -2584,9 +2645,6 @@
\def\doMPcolor#1:% #1 can be \relax ! ! ! i.e. an empty color
{\csname MPc\@EA\ifx\csname MPc\string#1\endcsname\relax B\else#1\fi\endcsname}
-% \def\doMPcolor#1:% #1 can be \relax ! ! ! i.e. an empty color
-% {\csname MPc\ifcsname MPc#1\endcsname#1\else B\fi\endcsname}
-
\def\MPcR{\doMPrgb}
\def\MPcC{\ifMPcmykcolors\@EA\doMPcmykY\else\@EA\doMPcmykN\fi}
\def\MPcS{\doMPgray}
@@ -2600,8 +2658,6 @@
\def\grayMP {scaledgray}
\def\spotMP {spotcolor}
-\let\processMP\spotMP % for some time, will become obsolete
-
\def\doMPtransparent#1#2:#3:#4\end
{\ifcase#2\space(#1)\else\transparentMP(#2,#3,(#1))\fi}
@@ -2617,12 +2673,6 @@
\def\doMPcmykN#1:#2:#3:#4:#5\end#6\end
{\doMPtransparent{\cmykASrgbMP(#1,#2,#3,#4,#6)}#5\end}
-% \def\doMPspotY#1:#2:#3\end#4\end
-% {\doMPtransparent{\spotMP("#1",#2)}#3\end}
-%
-% \def\doMPspotN#1:#2:#3\end#4\end
-% {\scaledMPcolor{#2}{#1}}
-
\def\doMPspotY#1:#2:#3:#4:#5\end#6\end % best make #3 same as #1 when empty
{\doMPtransparent{multitonecolor("#1",#2,"#3","#4")}#5\end}
@@ -2635,6 +2685,8 @@
\def\unknownMPcolor
{(0,0,0)}
+\let\processMP\spotMP % for some time, will become obsolete, brrr
+
%D \macros
%D {PDFcolor,FDFcolor}
%D
@@ -2644,30 +2696,6 @@
\def\PDFcolorvalue#1{\handlecolorwith\doPDFcolorvalue\csname\??cr#1\endcsname:::::::\end}
\def\FDFcolor #1{\handlecolorwith\doFDFcolor \csname\??cr#1\endcsname:::::::\end}
-% \def\doPDFcolor#1:#2:#3:#4:#5:#6:#7:#8\end
-% {\if #1R#2 #3 #4 rg%
-% \else\if#1C#2 #3 #4 #5 k%
-% \else\if#1S#2 g%
-% \else\if#1P#3 g% todo
-% \else 0 g%
-% \fi\fi\fi\fi}
-%
-% \def\doPDFcolorvalue#1:#2:#3:#4:#5:#6:#7:#8\end
-% {\if #1R#2 #3 #4%
-% \else\if#1C#2 #3 #4 #5%
-% \else\if#1S#2%
-% \else\if#1P#3%
-% \else 0%
-% \fi\fi\fi\fi}
-%
-% \def\doFDFcolor#1:#2:#3:#4:#5:#6:#7:#8\end
-% {[\if #1R#2 #3 #4%
-% \else\if#1C#2 #3 #4 #5%
-% \else\if#1S#2%
-% \else\if#1P#3% todo
-% \else 0%
-% \fi\fi\fi\fi]}
-
\def\doPDFcolor#1:#2:#3:#4:#5:#6:#7:#8\end
{\if #1R#2 #3 #4 rg%
\else\if#1C#2 #3 #4 #5 k%
@@ -2795,8 +2823,6 @@
\let\negatedcolorcomponent\firstofoneargument
-\beginETEX
-
\def\negatedcolorcomponent#1%
{\ifdim\dimexpr\onepoint-#1\onepoint\relax<\zeropoint
\!!zerocount
@@ -2807,6 +2833,4 @@
\def\negatecolorcomponent#1% #1 = \macro
{\edef#1{\negatedcolorcomponent{#1}}}
-\endETEX
-
\protect \endinput
diff --git a/tex/context/base/colo-run.tex b/tex/context/base/colo-run.tex
index 0b44f2ee5..9cb797c4d 100644
--- a/tex/context/base/colo-run.tex
+++ b/tex/context/base/colo-run.tex
@@ -98,7 +98,7 @@
{\dodoubleargument\doshowcolorgroup}
\gdef\doshowcolorgroup[#1][#2]%
- {\doifdefined{\??cr#1:1}
+ {\doifcolor{#1:1}
{\doifinsetelse\v!vertical{#2}
{\showverticalcolorgroup[#1][#2]}
{\showhorizontalcolorgroup[#1][#2]}}}
@@ -119,8 +119,8 @@
\graycolor[#1:##1]{\vrule\!!width4em\!!height\zeropoint\!!depth\strutdp}\cr
\doifinset\v!value{#2}{\colorvalue{#1:##1}\strut}\crcr}}
\def\doshowgroup##1%
- {\doifdefined{\??cr#1:##1}
- {\vbox{\dodoshowgroup{##1}}}}
+ {\doifcolor{#1:##1}
+ {\vbox{\dodoshowgroup{##1}}}}%
\hbox
{\doifinset\v!name{#2}
{\strut
@@ -137,12 +137,12 @@
\setuppalet
\tabskip\zeropoint
\def\rule
- {\vrule\!!width2.5em\!!height\strutht\!!depth\strutdp}
+ {\vrule\!!width2.5em\!!height\strutht\!!depth\strutdp}%
\def\doshowgroup##1%
- {\doifdefined{\??cr#1:##1}
+ {\doifcolor{#1:##1}
{\doifinset\v!number{#2}{##1\hskip.5em}&
\color[#1:##1]{\rule}\graycolor[#1:##1]{\rule}&
- \doifinset\v!value{#2}{\hskip.5em\colorvalue{#1:##1}}\crcr}}
+ \doifinset\v!value{#2}{\hskip.5em\colorvalue{#1:##1}}\crcr}}%
\halign
{\hss##&\hss##\hss&##\hss\cr
&\doifinset\v!name{#2}{\strut#1}&\crcr
@@ -210,7 +210,7 @@
{\dosingleargument\docomparecolorgroup}
\gdef\docomparecolorgroup[#1]%
- {\doifdefined{\??cr#1:1}
+ {\doifcolor{#1:1}
{\hbox
{\dodocomparecolorgroup\color[#1]%
\quad
@@ -220,7 +220,7 @@
{\localvbox
{\!!counta\zerocount
\dorecurse{15}
- {\doifdefined{\??cr#2:\recurselevel}{\advance\!!counta\plusone}}
+ {\doifcolor{#2:\recurselevel}{\advance\!!counta\plusone}}
\!!widtha2em\relax
\hsize\!!counta\!!widtha
\def\rule
@@ -236,36 +236,37 @@
\endgraf}
\dorecurse\!!counta{\dododocomparecolorgroup\recurselevel}}}
-% \def\execcolorRCSP#1:{\csname execcolor#1\endcsname} -> \execcolorR
-
\gdef\dogetcolorcomponents#1%
{\doifelsenothing{#1}
- {\global\globalscratchtoks{\TB}}
- {\startnointerference
- \localcolortrue
- \def\doexeccolorR ##1:##2:##3:##4:##5\od{\global\globalscratchtoks{\NC\Od#1 \NC\Nm #1 \NC a=\Do##4 \enspace t=\Do##5 \NC r=\Do##1 \enspace g=\Do##2 \enspace b=\Do##3 \NC\NR}}%
- \def\doexeccolorC##1:##2:##3:##4:##5:##6\od{\global\globalscratchtoks{\NC\Od#1 \NC\Nm #1 \NC a=\Do##5 \enspace t=\Do##6 \NC c=\Do##1 \enspace m=\Do##2 \enspace y=\Do##3 \enspace k=\Do##4 \NC\NR}}%
- \def\doexeccolorS ##1:##2:##3\od{\global\globalscratchtoks{\NC\Od#1 \NC\Nm #1 \NC a=\Do##2 \enspace t=\Do##3 \NC s=\Do##1 \NC\NR}}%
- %\def\doexeccolorP##1:##2:##3:##4:##5:##6\od{\global\globalscratchtoks{\NC\Od#1 \NC\Nm #1 \NC a=\Do##5 \enspace t=\Do##6 \NC p=\Do##4 \enspace f=\Do##2 \enspace d=\Do##3 \enspace n=##1 \NC\NR}}%
- \def\doexeccolorP##1:##2:##3:##4:##5:##6\od{\global\globalscratchtoks{\NC\Od#1 \NC\Nm #1 \NC a=\Do##5 \enspace t=\Do##6 \NC p=\Do##4 \enspace n=##1 \NC\NR}}%
- \let\doexeccolorPindex\doexeccolorP
- \backgroundline[#1]{}%
- \stopnointerference}%
- \appendetoks\the\globalscratchtoks\to\scratchtoks}
+ {\appendtoks
+ \TB
+ \to \scratchtoks}
+ {\appendtoks
+ \NC\showcolorbar[#1]\NC#1\NC\transparencycomponents{#1}\NC\colorcomponents{#1}\NC \NR
+ \to \scratchtoks}}
+
+% \gdef\showcolorcomponents[#1]%
+% {\bgroup
+% \def\bars##1{\backgroundline[##1]{\strut\enspace\color[white]{white}\enspace\color[black]{black}\enspace}}%
+% \scratchtoks\emptytoks
+% \appendtoks\starttabulate[|l|l|l|l|]\to\scratchtoks
+% \appendtoks\NC color \NC name \NC transparency \NC specification \NC\NR\TB\to\scratchtoks
+% \processcommacommand[#1]\dogetcolorcomponents
+% \appendtoks\stoptabulate\to\scratchtoks
+% \tt\the\scratchtoks
+% \egroup}
-\newdimen\colorcomponentwidth % for my eyes only
+\gdef\showcolorbar[#1]%
+ {\backgroundline[#1]{\strut\enspace\color[white]{white}\enspace\color[black]{black}\enspace}}
\gdef\showcolorcomponents[#1]%
- {\bgroup
- \def\Od##1 {\backgroundline[##1]{\strut\enspace\color[white]{white}\enspace\color[black]{black}\enspace}}%
- \def\Do##1 {\twodigitrounding{##1}}%
- \def\Nm##1 {\ifdim\colorcomponentwidth>\zeropoint\hbox to \colorcomponentwidth\fi{##1}}%
- \scratchtoks\emptytoks
- \appendtoks\starttabulate[|l|l|l|p|]\to\scratchtoks
- \appendtoks\NC color \NC name \NC transparency \NC specification \NC\NR\TB\to\scratchtoks
+ {\begingroup
+ \scratchtoks{\TB}%
\processcommacommand[#1]\dogetcolorcomponents
- \appendtoks\stoptabulate\to\scratchtoks
- \tt\the\scratchtoks
- \egroup}
+ \starttabulate[|lT|lT|lT|lT|]
+ \NC color \NC name \NC transparency \NC specification \NC\NR
+ \the\scratchtoks
+ \stoptabulate
+ \endgroup}
\protect \endinput
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 0a4803c4a..a3296003a 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -15,7 +15,7 @@
\writestatus\m!lua{tfm over afm, wide fonts not yet supported}
\to \everystoptext
-\ctxlua { fonts.define.method = 2 } % normally 3
+% \ctxlua { fonts.define.method = 2 } % normally 3
\unprotect
@@ -26,21 +26,30 @@
% texmf.instance will become just texmf
\appendtoks
- \writestatus\m!lua{input load time - \ctxlua{input.loadtime(texmf.instance)} seconds}%
- \writestatus\m!lua{fonts load time - \ctxlua{input.loadtime(fonts)} seconds}%
- \writestatus\m!lua{mps conversion time - \ctxlua{input.loadtime(mptopdf)} seconds}%
- \writestatus\m!lua{node processing time - \ctxlua{input.loadtime(nodes)} second}%
- \writestatus\m!lua{used config path - \ctxlua{tex.print(cache.configpath(texmf.instance))}}%
- \writestatus\m!lua{used cache path - \ctxlua{tex.print(cache.path)}}%
- \writestatus\m!lua{modules/dumps/instances - \ctxlua{tex.print((status.luabytecodes-500).."/"..input.storage.done.."/"..status.luastates)}}%
- \writestatus\m!lua{current memory usage - \ctxlua{tex.print(status.luastate_bytes)} bytes}%
- \writestatus\m!lua{loaded fonts - \ctxlua{tex.print(fonts.logger.report())}}%
+ \writestatus\m!lua{input load time - \ctxlua{input.loadtime(texmf.instance)} seconds}%
+ \writestatus\m!lua{fonts load time - \ctxlua{input.loadtime(fonts)} seconds}%
+ \writestatus\m!lua{mps conversion time - \ctxlua{input.loadtime(mptopdf)} seconds}%
+ \writestatus\m!lua{node processing time - \ctxlua{input.loadtime(nodes)} seconds}%
+ \writestatus\m!lua{attribute processing time - \ctxlua{input.loadtime(attributes)} seconds}%
+ \writestatus\m!lua{used config path - \ctxlua{tex.print(caches.configpath(texmf.instance))}}%
+ \writestatus\m!lua{used cache path - \ctxlua{tex.print(caches.path)}}%
+ \writestatus\m!lua{modules/dumps/instances - \ctxlua{tex.print((status.luabytecodes-500).."/"..input.storage.done.."/"..status.luastates)}}%
+ \writestatus\m!lua{current memory usage - \ctxlua{tex.print(status.luastate_bytes)} bytes}%
+ \writestatus\m!lua{loaded fonts - \ctxlua{tex.print(fonts.logger.report())}}%
\to \everystoptext
\def\resettimer {\ctxlua{environment.starttime = os.clock()}}
\def\elapsedtime {\ctxlua{tex.sprint(os.clock()-environment.starttime)}}
\let\elapsedseconds \elapsedtime
+%D For me.
+
+\def\traceluausage
+ {\ctxlua{debugger.enable()}%
+ \appendtoks
+ \ctxlua{debugger.disable() debugger.showstats(texio.write,5000)}%
+ \to \everybye}
+
%D Fonts (experimental AFM loading}
% \ctxlua {
@@ -56,10 +65,7 @@
\appendtoksonce \loadallXfontmapfiles \to \everystarttext
\appendtoksonce \loadallXfontmapfiles \to \everybeforepagebody
-\def\loadallXfontmapfiles{\ctxlua {
- local s = fonts.map.flushlines("pdftex","")
- tex.sprint(tex.ctxcatcodes,s)
-}}
+\def\loadallXfontmapfiles{\ctxlua{fonts.map.flush("pdftex")}}
% \ctxlua{
% do
@@ -95,3 +101,6 @@
% }
\protect \endinput
+
+% \expanded{\defineactivecharacter \number"2000E} {\textdir TRT\relax}
+% \expanded{\defineactivecharacter \number"2000F} {\textdir TLT\relax}
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex
index 0ee61b10a..906eabec9 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{2007.08.09 13:04}
+\newcontextversion{2007.08.20 10:21}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
@@ -31,6 +31,31 @@
\let\then\relax % \ifnum1>2\then -)
+% \setupcaption [figure] [align=flushleft]
+% \setupcaption [figure-1] [align=flushleft,leftmargin=10mm]
+% \setupcaption [figure-2] [align=flushleft,leftmargin=10mm,rightmargin=-10mm,width=\textwidth]
+%
+% \startsetups somefigure
+% \ifdim\floatsetupwidth>\textwidth
+% \placesetupfloat[figure-2]
+% \else
+% \placesetupfloat[figure-1]
+% \fi
+% \stopsetups
+%
+% \placefloatwithsetups[somefigure]{}{\externalfigure[dummy][width=5cm,height=2cm]}
+
+\def\placefloatwithsetups
+ {\dotripleempty\doplacefloatwithsetups}
+
+\def\doplacefloatwithsetups[#1][#2][#3]#4%
+ {\def\floatsetupcaption {#4}%
+ \def\floatsetupcontent {\copy\nextbox}%
+ \def\floatsetupwidth {\wd\nextbox}%
+ \def\floatsetupheight {\ht\nextbox}%
+ \def\placesetupfloat[##1]{\placefloat[##1][#2][#3]{\floatsetupcaption}{\floatsetupcontent}}%
+ \dowithnextbox{\setups[#1]}\vbox}
+
\chardef\baselinegridmode=0 % option in layout / 1=permit_half_lines
\def\dodosetupwhitespace
@@ -1763,32 +1788,6 @@
\setinnerparpositions % see "techniek" for application
\to \everytabulate
-%D This alternative is slower, since it works on top of the
-%D color (stack) mechanism, but it does provide nesting.
-
-\def\dosetrastercolor#1%
- {\edef\@@cl@@s{#1}%
- \ifx\@@cl@@s\empty
- \let\@@cl@@s\@@rsscreen
- \fi
- \let\@@cl@@t\@@cl@@z % else we get rogue
- \let\@@cl@@a\@@cl@@z % transpancies
- \setevalue{\??cr\??rs}{\colorSpattern}}
-
-% beware, don't add extra grouping, else color in tables
-% fails
-
-\def\localstartraster[#1]%
- {\ifincolor\dosetrastercolor{#1}\localstartcolor[\??rs]\fi}
-
-\def\startraster[#1]%
- {\ifincolor\dosetrastercolor{#1}\startcolor[\??rs]\fi}
-
-\def\localstopraster{\ifincolor\localstopcolor\fi}
-\def\stopraster {\ifincolor\stopcolor\fi}
-
-\def\raster[#1]{\groupedcommand{\startraster[#1]}{\stopraster}}
-
\def\fontclassname#1#2%
{\ifcsname\??ff#1#2\endcsname
\fontclassname{#1}{\csname\??ff#1#2\endcsname}%
diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex
index 541ae1ead..024af80f5 100644
--- a/tex/context/base/context.tex
+++ b/tex/context/base/context.tex
@@ -42,7 +42,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2007.08.09 13:04}
+\edef\contextversion{2007.08.20 10:21}
%D For those who want to use this:
@@ -208,7 +208,6 @@
\loadmkivfile{attr-ini.tex}
\loadmkivfile{node-ini.tex}
-
%D We also use some third party macros. These are loaded by
%D saying:
@@ -300,7 +299,7 @@
\loadcorefile{spec-def.tex}
\loadcorefile{spec-var.tex}
-\loadcorefile{colo-ini.tex}
+\doiffileelse{colo-new.tex}{\loadcorefile{colo-new.tex}}{\loadcorefile{colo-ini.tex}}
\loadcorefile{colo-ext.tex}
%D For the moment we load a lot of languages. In the future
@@ -481,6 +480,8 @@
%D These macros are loaded last since they overload and|/|or
%D extend previously defined ones.
+\loadmkivfile{lxml-ini.tex}
+
\loadcorefile{xtag-ini.tex}
\loadcorefile{xtag-ext.tex}
\loadcorefile{xtag-prs.tex}
@@ -625,8 +626,8 @@
\unprotect
\beginLUATEX
\appendtoks
- \writestatus\m!lua{used config path - \ctxlua{tex.print(cache.configpath(texmf.instance))}}%
- \writestatus\m!lua{used cache path - \ctxlua{tex.print(cache.path)}}%
+ \writestatus\m!lua{used config path - \ctxlua{tex.print(caches.configpath(texmf.instance))}}%
+ \writestatus\m!lua{used cache path - \ctxlua{tex.print(caches.path)}}%
\to \everydump
\endLUATEX
\protect
diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua
index 349d33688..b6af6be9a 100644
--- a/tex/context/base/core-con.lua
+++ b/tex/context/base/core-con.lua
@@ -14,10 +14,10 @@ slower but look nicer this way.</p>
<p>Some code may move to a module in the language namespace.</p>
--ldx]]--
-convert = convert or { }
-language = language or { }
+converters = converters or { }
+languages = languages or { }
-language.counters = {
+languages.counters = {
['**'] = {
0x0061, 0x0062, 0x0063, 0x0064, 0x0065,
0x0066, 0x0067, 0x0068, 0x0069, 0x006A,
@@ -70,95 +70,99 @@ language.counters = {
}
}
-function convert.chr(n, m)
+function converters.chr(n, m)
if n > 0 and n < 27 then
tex.sprint(string.char(n+m))
end
end
-function convert.maxchrs(n,m,cmd)
+function converters.maxchrs(n,m,cmd)
if n <= m then
tex.sprint(tex.texcatcodes, cmd .. "{" .. n .. "}")
else
- convert.maxchrs(math.floor((n-1)/m),m,cmd)
+ converters.maxchrs(math.floor((n-1)/m),m,cmd)
tex.sprint(tex.texcatcodes, cmd .. "{" .. ((n-1)%m + 1) .. "}")
end
end
-function convert.chrs(n,m)
+function converters.chrs(n,m)
if n <= 26 then
tex.sprint(string.char(n+m))
else
- convert.chrs(math.floor((n-1)/26),m)
+ converters.chrs(math.floor((n-1)/26),m)
tex.sprint(string.char(((n-1)%26 + 1)+m))
end
end
-function convert.alphabetic(n,code)
- local code = language.counters[code] or language.counters['**']
- convert.do_alphabetic(n,#code,function(n) return code[n] end)
-end
+do
-function convert.Alphabetic(n,code)
- local code = language.counters[code] or language.counters['**']
- convert.do_alphabetic(n,#code,function(n) return characters.uccode(code[n]) end)
-end
+ local function do_alphabetic(n,max,chr)
+ if n <= max then
+ characters.flush(chr(n))
+ else
+ do_alphabetic(math.floor((n-1)/max),max,chr)
+ characters.flush(chr((n-1)%max+1))
+ end
+ end
-function convert.do_alphabetic(n,max,chr)
- if n <= max then
- characters.flush(chr(n))
- else
- convert.do_alphabetic(math.floor((n-1)/max),max,chr)
- characters.flush(chr((n-1)%max+1))
+ function converters.alphabetic(n,code)
+ local code = languages.counters[code] or languages.counters['**']
+ do_alphabetic(n,#code,function(n) return code[n] end)
end
+
+ function converters.Alphabetic(n,code)
+ local code = languages.counters[code] or languages.counters['**']
+ do_alphabetic(n,#code,function(n) return characters.uccode(code[n]) end)
+ end
+
end
-function convert.character(n) convert.chr (n,96) end
-function convert.Character(n) convert.chr (n,64) end
-function convert.characters(n) convert.chrs(n,96) end
-function convert.Characters(n) convert.chrs(n,64) end
+function converters.character(n) converters.chr (n,96) end
+function converters.Character(n) converters.chr (n,64) end
+function converters.characters(n) converters.chrs(n,96) end
+function converters.Characters(n) converters.chrs(n,64) end
-function convert.weekday(year,month,day)
+function converters.weekday(year,month,day)
tex.sprint(os.date("%w",os.time{year=year,month=month,day=day})+1)
end
-function convert.lpy(year)
+function converters.lpy(year)
return (year % 400 == 0) or ((year % 100 ~= 0) and (year % 4 == 0))
end
-function convert.leapyear(year)
- if convert.lpy(year) then tex.sprint(1) else tex.sprint(0) end
+function converters.leapyear(year)
+ if converters.lpy(year) then tex.sprint(1) else tex.sprint(0) end
end
-convert.mth = {
+converters.mth = {
[false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
[true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
}
-function convert.nofdays(year,month)
- tex.sprint(convert.mth[convert.lpy(year)][month])
+function converters.nofdays(year,month)
+ tex.sprint(converters.mth[converters.lpy(year)][month])
end
-function convert.year () tex.sprint(os.date("%Y")) end
-function convert.month () tex.sprint(os.date("%m")) end
-function convert.hour () tex.sprint(os.date("%H")) end
-function convert.minute () tex.sprint(os.date("%M")) end
-function convert.second () tex.sprint(os.date("%S")) end
-function convert.textime() tex.sprint(tonumber(os.date("%H"))*60+tonumber(os.date("%M"))) end
+function converters.year () tex.sprint(os.date("%Y")) end
+function converters.month () tex.sprint(os.date("%m")) end
+function converters.hour () tex.sprint(os.date("%H")) end
+function converters.minute () tex.sprint(os.date("%M")) end
+function converters.second () tex.sprint(os.date("%S")) end
+function converters.textime() tex.sprint(tonumber(os.date("%H"))*60+tonumber(os.date("%M"))) end
-convert.rom = {
+converters.rom = {
{ [0] = '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' },
{ [0] = '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC' },
{ [0] = '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM' },
}
-function convert.toroman(n)
+function converters.toroman(n)
if n >= 4000 then
- return convert.toroman(math.floor(n/1000)) .. " " .. convert.toroman(n%1000)
+ return converters.toroman(math.floor(n/1000)) .. " " .. converters.toroman(n%1000)
else
- return string.rep("M",math.floor(n/1000)) .. convert.rom[3][math.floor((n%1000)/100)] ..
- convert.rom[2][math.floor((n%100)/10)] .. convert.rom[1][math.floor((n% 10)/1)]
+ return string.rep("M",math.floor(n/1000)) .. converters.rom[3][math.floor((n%1000)/100)] ..
+ converters.rom[2][math.floor((n%100)/10)] .. converters.rom[1][math.floor((n% 10)/1)]
end
end
-function convert.romannumerals(n) return tex.sprint(string.tolower(convert.toroman(n))) end
-function convert.Romannumerals(n) return tex.sprint( convert.toroman(n) ) end
+function converters.romannumerals(n) return tex.sprint(string.lower(converters.toroman(n))) end
+function converters.Romannumerals(n) return tex.sprint( converters.toroman(n) ) end
diff --git a/tex/context/base/core-con.mkiv b/tex/context/base/core-con.mkiv
index afed14f1d..390f9c595 100644
--- a/tex/context/base/core-con.mkiv
+++ b/tex/context/base/core-con.mkiv
@@ -15,47 +15,47 @@
\registerctxluafile{core-con}{1.001}
-\def\romannumerals#1{\ctxlua{convert.romannumerals(\number#1)}}
-\def\Romannumerals#1{\ctxlua{convert.Romannumerals(\number#1)}}
+\def\romannumerals#1{\ctxlua{converters.romannumerals(\number#1)}}
+\def\Romannumerals#1{\ctxlua{converters.Romannumerals(\number#1)}}
-\def\greeknumerals#1{\ctxlua{convert.alphabetic(\number#1,"gr")}}
-\def\Greeknumerals#1{\ctxlua{convert.Alphabetic(\number#1,"gr")}}
+\def\greeknumerals#1{\ctxlua{converters.alphabetic(\number#1,"gr")}}
+\def\Greeknumerals#1{\ctxlua{converters.Alphabetic(\number#1,"gr")}}
-\def\character #1{\ctxlua{convert.character (\number#1)}}
-\def\Character #1{\ctxlua{convert.Character (\number#1)}}
-\def\characters#1{\ctxlua{convert.characters(\number#1)}}
-\def\Characters#1{\ctxlua{convert.Characters(\number#1)}}
+\def\character #1{\ctxlua{converters.character (\number#1)}}
+\def\Character #1{\ctxlua{converters.Character (\number#1)}}
+\def\characters#1{\ctxlua{converters.characters(\number#1)}}
+\def\Characters#1{\ctxlua{converters.Characters(\number#1)}}
-\def\languagecharacters#1{\ctxlua{convert.alphabetic(\number#1,"\currentlanguage")}} % new
-\def\languageCharacters#1{\ctxlua{convert.Alphabetic(\number#1,"\currentlanguage")}} % new
+\def\languagecharacters#1{\ctxlua{converters.alphabetic(\number#1,"\currentlanguage")}} % new
+\def\languageCharacters#1{\ctxlua{converters.Alphabetic(\number#1,"\currentlanguage")}} % new
-\def\getdayoftheweek#1#2#3{\normalweekday\ctxlua{convert.weekday(\number#1,\number#2,\number#3)}}
-\def\dayoftheweek #1#2#3{\doconvertday{\ctxlua{convert.weekday(\number#1,\number#2,\number#3)}}}
+\def\getdayoftheweek#1#2#3{\normalweekday\ctxlua{converters.weekday(\number#1,\number#2,\number#3)}}
+\def\dayoftheweek #1#2#3{\doconvertday{\ctxlua{converters.weekday(\number#1,\number#2,\number#3)}}}
\def\doifleapyearelse#1%
- {\ifcase\ctxlua{convert.leapyear(\number#1)}
+ {\ifcase\ctxlua{converters.leapyear(\number#1)}
\@EA\secondoftwoarguments
\else
\@EA\firstoftwoarguments
\fi}
\def\getdayspermonth#1#2%
- {\edef\numberofdays{\ctxlua{convert.nofdays(\number#1,\number#2)}}}
+ {\edef\numberofdays{\ctxlua{converters.nofdays(\number#1,\number#2)}}}
\def\dayspermonth#1#2%
- {\ctxlua{convert.nofdays(\number#1,\number#2)}}
+ {\ctxlua{converters.nofdays(\number#1,\number#2)}}
\def\calculatecurrenttime
- {\edef\currenthour {\ctxlua{convert.hour ()}}%
- \edef\currentminute{\ctxlua{convert.minute()}}%
- \edef\currentsecond{\ctxlua{convert.second()}}}
+ {\edef\currenthour {\ctxlua{converters.hour ()}}%
+ \edef\currentminute{\ctxlua{converters.minute()}}%
+ \edef\currentsecond{\ctxlua{converters.second()}}}
% problem is that we calculate with those numbers
%
-% \def\time {\numexpr\ctxlua{convert.textime()}\relax}
-% \def\year {\numexpr\ctxlua{convert.year ()}\relax}
-% \def\month{\numexpr\ctxlua{convert.month ()}\relax}
-% \def\day {\numexpr\ctxlua{convert.day ()}\relax}
+% \def\time {\numexpr\ctxlua{converters.textime()}\relax}
+% \def\year {\numexpr\ctxlua{converters.year ()}\relax}
+% \def\month{\numexpr\ctxlua{converters.month ()}\relax}
+% \def\day {\numexpr\ctxlua{converters.day ()}\relax}
% \dayoftheweek{2006}{9}{15}
% \doifleapyearelse{2000}{OK}{NOT OK}
@@ -67,17 +67,17 @@
% we could use an auxiliary macro to save some bytes in the format
%
-% \def\dolanguagecharacters#1#2{\ctxlua{convert.alphabetic(\number#2,"#1")}}
+% \def\dolanguagecharacters#1#2{\ctxlua{converters.alphabetic(\number#2,"#1")}}
% this does not belong here, but in a lang-module
-\def\arabicnumerals #1{\ctxlua{convert.alphabetic(\number#1,"arabic")}}
-\def\persiannumerals #1{\ctxlua{convert.alphabetic(\number#1,"persian")}}
-\def\thainumerals #1{\ctxlua{convert.alphabetic(\number#1,"thai")}}
-\def\devanagarinumerals#1{\ctxlua{convert.alphabetic(\number#1,"devanagari")}}
-\def\gurmurkhinumerals #1{\ctxlua{convert.alphabetic(\number#1,"gurmurkhi")}}
-\def\gujaratinumerals #1{\ctxlua{convert.alphabetic(\number#1,"gujarati")}}
-\def\tibetannumerals #1{\ctxlua{convert.alphabetic(\number#1,"tibetan")}}
+\def\arabicnumerals #1{\ctxlua{converters.alphabetic(\number#1,"arabic")}}
+\def\persiannumerals #1{\ctxlua{converters.alphabetic(\number#1,"persian")}}
+\def\thainumerals #1{\ctxlua{converters.alphabetic(\number#1,"thai")}}
+\def\devanagarinumerals#1{\ctxlua{converters.alphabetic(\number#1,"devanagari")}}
+\def\gurmurkhinumerals #1{\ctxlua{converters.alphabetic(\number#1,"gurmurkhi")}}
+\def\gujaratinumerals #1{\ctxlua{converters.alphabetic(\number#1,"gujarati")}}
+\def\tibetannumerals #1{\ctxlua{converters.alphabetic(\number#1,"tibetan")}}
\defineconversion[arabicnumerals] [\arabicnumerals]
\defineconversion[persiannumerals] [\persiannumerals]
diff --git a/tex/context/base/core-mat.tex b/tex/context/base/core-mat.tex
index c73ee1cca..b994580f9 100644
--- a/tex/context/base/core-mat.tex
+++ b/tex/context/base/core-mat.tex
@@ -2308,7 +2308,7 @@
\tabskip\zeropoint
\eqaligncolumn\zerocount % could be \scratchcounter
\processcommacommand[\mathmatrixparameter\c!align]{\advance\eqaligncolumn\plusone\dosetmatrixcolumn}%
- \scratchcounter=\ifnum\eqaligncolumn>\scratchcounter \eqaligncolumn \else \plusone \fi
+ \scratchcounter=\ifnum\eqaligncolumn>\zerocount \eqaligncolumn \else \plusone \fi
\global\eqaligncolumn\plusone
\preparemathmatrix } % uses scratchcounter
diff --git a/tex/context/base/core-obj.tex b/tex/context/base/core-obj.tex
index d8de15133..a1b0796d1 100644
--- a/tex/context/base/core-obj.tex
+++ b/tex/context/base/core-obj.tex
@@ -118,6 +118,16 @@
{\checkobjectreferences
\letbeundefined{\r!object#1::#2}}
+%D \macros
+%D {finalizeobjectbox}
+%D
+%D This one provides a hook for last minute object box processing
+%D we need this in \MKIV.
+
+\ifx\finalizeobjectbox\undefined
+ \let\finalizeobjectbox\gobbleoneargument
+\fi
+
%D Somehow there is a rounding error problem in either \PDFTEX\
%D or in viewers, or maybe it is conforming the specs. The next
%D variable compensate for it by removing the rather tight
diff --git a/tex/context/base/core-rul.tex b/tex/context/base/core-rul.tex
index 696f3f01c..ea6ff441c 100644
--- a/tex/context/base/core-rul.tex
+++ b/tex/context/base/core-rul.tex
@@ -482,7 +482,34 @@
%D by \TEX\ itself, the latter one depends on the driver. This
%D macro also support a negative offset.
-\def\dooutlinebox
+% \def\dooutlinebox
+% {\setbox\framebox\vbox % rules on top of box
+% {\scratchdimen \framedparameter\c!frameoffset\relax
+% \frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax
+% \frameddimenht\dimexpr\ht\framebox+ \scratchdimen\relax
+% \frameddimendp\dimexpr\dp\framebox+ \scratchdimen+\framedparameter\c!framedepth\relax
+% \ifdim\frameddimendp<\zeropoint
+% \advance\frameddimenht \frameddimendp
+% \scratchdimen-\frameddimendp
+% \frameddimendp\zeropoint
+% \else
+% \scratchdimen\zeropoint
+% \fi
+% \setbox\extraframebox\hbox
+% {\dostrokedbox}%
+% \setbox\extraframebox\hbox
+% {\raise\scratchdimen\vbox
+% {\moveleft\framedparameter\c!frameoffset\box\extraframebox}}%
+% \wd\extraframebox\wd\framebox
+% \ht\extraframebox\ht\framebox
+% \dp\extraframebox\dp\framebox
+% \hbox
+% {\box\framebox\hskip-\wd\extraframebox
+% \doifsomething{\framedparameter\c!framecolor}% no else needed,
+% {\color[\framedparameter\c!framecolor]}% %
+% {\box\extraframebox}}}} % but {} here
+
+\def\dooutlinebox % we needed to move the color command in order to apply attributes properly
{\setbox\framebox\vbox % rules on top of box
{\scratchdimen \framedparameter\c!frameoffset\relax
\frameddimenwd\dimexpr\wd\framebox+2\scratchdimen\relax
@@ -496,18 +523,15 @@
\scratchdimen\zeropoint
\fi
\setbox\extraframebox\hbox
- {\dostrokedbox}%
+ {\doifsomething{\framedparameter\c!framecolor}{\color[\framedparameter\c!framecolor]}{\dostrokedbox}}%
\setbox\extraframebox\hbox
{\raise\scratchdimen\vbox
- {\moveleft\framedparameter\c!frameoffset\box\extraframebox}}%
+ {\moveleft\framedparameter\c!frameoffset
+ \box\extraframebox}}%
\wd\extraframebox\wd\framebox
\ht\extraframebox\ht\framebox
\dp\extraframebox\dp\framebox
- \hbox
- {\box\framebox\hskip-\wd\extraframebox
- \doifsomething{\framedparameter\c!framecolor}% no else needed,
- {\color[\framedparameter\c!framecolor]}% %
- {\box\extraframebox}}}} % but {} here
+ \hbox{\box\framebox\hskip-\wd\extraframebox\box\extraframebox}}}
\def\dostrokedbox
{\doifelse{\framedparameter\c!framecorner}\v!rectangular
@@ -779,8 +803,6 @@
\fi
% new, experimental dirty hook
\framedparameter\c!extras
- % we need to register the (outer) color
- \startregistercolor[\framedparameter\c!foregroundcolor]%
% to get the right spacing
\doifvaluesomething{\@@framed\c!foregroundstyle}
{\@EA\doconvertfont\csname\@@framed\c!foregroundstyle\endcsname\empty}%
@@ -912,9 +934,9 @@
\else\ifx\localstrut\v!local
\setfontstrut
\else
+ \setstrut
\fi\fi\fi
\ifboxhasstrut
- \setstrut
\let\localbegstrut\begstrut
\let\localendstrut\endstrut
\let\localstrut \strut
@@ -977,6 +999,8 @@
{\ifdim\!!framedwidth >\zeropoint\the\!!framedwidth \else\zeropoint\fi}%
\edef\framedheight% a new feature, visible for user
{\ifdim\!!framedheight>\zeropoint\the\!!framedheight\else\zeropoint\fi}%
+ % we need to register the (outer) color
+ \startregistercolor[\framedparameter\c!foregroundcolor]%
% first alternative
%\def\dowithframedbox%
% {\let\postprocessframebox\relax %new
@@ -989,7 +1013,6 @@
% \let\postprocessframebox\relax %new
% \stoplocalframed}
% \next}
- % third alternative
\@@startframedorientation
\afterassignment\dodowithframebox
\setbox\framebox\next}
@@ -1039,6 +1062,7 @@
\def\stoplocalframed
{\dontshowcomposition
\@@stopframedorientation % hm, wrong place ! should rotatethe result (after reshape)
+ \stopregistercolor
\handleframedlocator\c!before\@@locallocation
\ifboxhasformat
\ifx\@@localautowidth\v!force
@@ -1071,7 +1095,6 @@
\ht\scratchbox\ht\framebox
\dp\scratchbox\dp\framebox
\setbox\framebox\box\scratchbox}%
- \stopregistercolor
\docolorframebox
\ifboxhasoffset
\dooffsetframebox
diff --git a/tex/context/base/core-sec.tex b/tex/context/base/core-sec.tex
index b92fbb21c..79ee538d7 100644
--- a/tex/context/base/core-sec.tex
+++ b/tex/context/base/core-sec.tex
@@ -1196,22 +1196,32 @@
\dosomebreak{\penalty\!!counta}%
\egroup}
+\newconditional\ignorehandlepagebreak
+
\def\handlepagebreak#1%
- {\dohandlepagebreakAA{#1}%
- \ifnum\countervalue{\??se\previoussection\@@sectie}>\zerocount\relax
- \ifnum\countervalue{\??se\@@sectie}>\zerocount
- \dohandlepagebreakB{#1}%
+ {\ifconditional\ignorehandlepagebreak
+ \setfalse\ignorehandlepagebreak
+ \else
+ \dohandlepagebreakAA{#1}%
+ \ifnum\countervalue{\??se\previoussection\@@sectie}>\zerocount\relax
+ \ifnum\countervalue{\??se\@@sectie}>\zerocount
+ \dohandlepagebreakB{#1}%
+ \else
+ \doifnotvalue{\??ko#1\c!continue}\v!yes{\dohandlepagebreakB{#1}}%
+ \fi
\else
- \doifnotvalue{\??ko#1\c!continue}\v!yes{\dohandlepagebreakB{#1}}%
+ \dohandlepagebreakB{#1}%
\fi
- \else
- \dohandlepagebreakB{#1}%
- \fi
- \dohandlepagebreakAB{#1}}
+ \dohandlepagebreakAB{#1}%
+ \fi}
-\def\handlepagebreakC#1%
- {\xdef\@@kolevel{\getvalue{\??se\@@sectie\c!level}}%
- \nobreak}
+\def\handlenopagebreak#1%
+ {\ifconditional\ignorehandlepagebreak
+ \setfalse\ignorehandlepagebreak
+ \else
+ \xdef\@@kolevel{\getvalue{\??se\@@sectie\c!level}}%
+ \nobreak
+ \fi}
\def\localheadheight {\strutht}
\def\localheaddepth {\strutdp}
@@ -1419,6 +1429,8 @@
% todo: write to list etc in both args or in enclosing h/vbox else it gets
% lost when no #1 or #2 is typeset
+% we will use variables here
+
\def\dodododoconstructhead#1[#2]#3#4% [ref] {number} {title}
{\def\currenthead{#1}% dus #1 overal vervangen
\let\finalsectionnumber\dofinalsectionnumber % overloaded ungrouped -)
@@ -1641,6 +1653,7 @@
\fi
\flushingcolumnfloatstrue
\someheadconversionfalse
+ \setfalse\ignorehandlepagebreak
\let\fullsectionnumber\limitedfullsectionnumber
% ignorespaces prevents spaces creeping in when after=\dontleavehmode
\ifdisplaysectionhead\ignorespaces\else\expandafter\GotoPar\fi}
@@ -2052,7 +2065,7 @@
{\ifhmode
\scratchcounter=\lastpenalty\unpenalty % no beauty in this
\ifdim\lastskip=\headsignal
- \handlepagebreakC{#1}%
+ \handlenopagebreak{#1}%
\global\settrue\continuoussectionhead
\else
\penalty\scratchcounter
diff --git a/tex/context/base/core-spa.lua b/tex/context/base/core-spa.lua
index c6090ab13..586a90d3d 100644
--- a/tex/context/base/core-spa.lua
+++ b/tex/context/base/core-spa.lua
@@ -238,8 +238,10 @@ do
end
end
- function collapser(head,where)
- if head then
+ -- local free = node.free
+
+ local function collapser(head,where)
+ if head and head.next then
local trace = nodes.trace_collapse
local current, tail = head, nil
local glue_order, glue_data = 0, nil
@@ -364,21 +366,21 @@ do
local head, tail = nil, nil
function nodes.flush_vertical_spacing()
- input.start_timing(nodes)
if head then
- t = collapser(head)
+ input.start_timing(nodes)
+ local t = collapser(head)
head = nil
-- tail = nil
+ input.stop_timing(nodes)
+ return t
else
- t = nil
+ return nil
end
- input.stop_timing(nodes)
- return t
end
function nodes.handle_page_spacing(t, where)
-- we need to add the latest t too, else we miss skips and such
- if t then
+ if t and t.next then
local tt = node.slide(t)
local id = tt.id
if id == glue then -- or id == penalty then -- or maybe: if not hlist or vlist
@@ -409,8 +411,12 @@ do
end
function nodes.handle_vbox_spacing(t)
- local tail = node.slide(t)
- return collapser(t,'whole')
+ if t and t.next then
+ local tail = node.slide(t)
+ return collapser(t,'whole')
+ else
+ return t
+ end
end
end
diff --git a/tex/context/base/core-spa.tex b/tex/context/base/core-spa.tex
index 159624c0d..aef7ac698 100644
--- a/tex/context/base/core-spa.tex
+++ b/tex/context/base/core-spa.tex
@@ -2387,8 +2387,7 @@
\!!height\strutheight
\!!depth \strutdepth
\hss}}%
- \struttotal\strutht
- \advance\struttotal\strutdp}
+ \struttotal\dimexpr\strutht+\strutdp\relax}
%D The dimen \type {\struttotal} holds the exact size of the
%D strut; occasionally a one scaled point difference can show
@@ -3225,52 +3224,31 @@
\beginETEX
-% \unexpanded\def\dostartattributes#1#2#3%
-% {\begingroup % geen \bgroup, anders in mathmode lege \hbox
-% \ifcsname#1#3\endcsname
-% \let\dostopattributes\@@dostopattributes
-% \startcolor[\csname#1#3\endcsname]%
-% \else
-% \let\dostopattributes\@@nostopattributes
-% \fi
-% \ifcsname#1#2\endcsname
-% \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
-% \fi}
-%
-% \unexpanded\def\@@dostopattributes%
-% {\stopcolor
-% \finishparbasedattributes
-% \endgroup}
-%
-% \unexpanded\def\@@nostopattributes%
-% {\finishparbasedattributes
-% \endgroup}
-
-\unexpanded\def\dostartattributes#1#2#3%
- {\begingroup % geen \bgroup, anders in mathmode lege \hbox
- \ifincolor
- \ifcsname#1#3\endcsname
- \let\dostopattributes\@@dostopattributes
- \doglobalstartcolor[\csname#1#3\endcsname]%
- \else
- \let\dostopattributes\@@nostopattributes
- \fi
- \else
- \let\dostopattributes\@@nostopattributes
- \fi
- \ifcsname#1#2\endcsname
- % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
- \@EA\doconvertfont\csname#1#2\@EA\endcsname
- \fi}
+ \unexpanded\def\dostartattributes#1#2#3%
+ {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+ \ifincolor
+ \ifcsname#1#3\endcsname
+ \let\dostopattributes\@@dostopattributes
+ \faststartcolor[\csname#1#3\endcsname]%
+ \else
+ \let\dostopattributes\@@nostopattributes
+ \fi
+ \else
+ \let\dostopattributes\@@nostopattributes
+ \fi
+ \ifcsname#1#2\endcsname
+ % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi}
-\unexpanded\def\@@dostopattributes
- {\doglobalstopcolor
- \finishparbasedattributes
- \endgroup}
+ \unexpanded\def\@@dostopattributes
+ {\faststopcolor
+ \finishparbasedattributes
+ \endgroup}
-\unexpanded\def\@@nostopattributes
- {\finishparbasedattributes
- \endgroup}
+ \unexpanded\def\@@nostopattributes
+ {\finishparbasedattributes
+ \endgroup}
\endETEX
@@ -3278,20 +3256,19 @@
\beginTEX
-\unexpanded\def\dosetfontattribute#1#2%
- {\@EA\ifx\csname#1#2\endcsname\relax\else
- \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
- \fi\empty}
+ \unexpanded\def\dosetfontattribute#1#2%
+ {\@EA\ifx\csname#1#2\endcsname\relax\else
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi\empty}
\endTEX
\beginETEX \ifcsname
-\unexpanded\def\dosetfontattribute#1#2%
- {\ifcsname#1#2\endcsname
- % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
- \@EA\doconvertfont\csname#1#2\@EA\endcsname
- \fi\empty}
+ \unexpanded\def\dosetfontattribute#1#2%
+ {\ifcsname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi\empty}
\endETEX
@@ -3300,24 +3277,24 @@
\beginETEX \ifcsname
-\unexpanded\def\doattributes#1#2#3#4%
- {\begingroup % geen \bgroup, anders in mathmode lege \hbox
- \ifincolor
- \ifcsname#1#3\endcsname
- \let\dostopattributes\@@dostopattributes
- \doglobalstartcolor[\csname#1#3\endcsname]%
- \else
- \let\dostopattributes\endgroup
- \fi
- \else
- \let\dostopattributes\endgroup
- \fi
- \ifcsname#1#2\endcsname
- % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
- \@EA\doconvertfont\csname#1#2\@EA\endcsname
- \fi
- {#4}%
- \dostopattributes}
+ \unexpanded\def\doattributes#1#2#3#4%
+ {\begingroup % geen \bgroup, anders in mathmode lege \hbox
+ \ifincolor
+ \ifcsname#1#3\endcsname
+ \let\dostopattributes\@@dostopattributes
+ \faststartcolor[\csname#1#3\endcsname]%
+ \else
+ \let\dostopattributes\endgroup
+ \fi
+ \else
+ \let\dostopattributes\endgroup
+ \fi
+ \ifcsname#1#2\endcsname
+ % \@EAEAEA\doconvertfont\@EA\@EA\csname#1#2\endcsname
+ \@EA\doconvertfont\csname#1#2\@EA\endcsname
+ \fi
+ {#4}%
+ \dostopattributes}
\endETEX
@@ -3963,6 +3940,13 @@
\newtoks \everyleftofalignedline
\newtoks \everyrightofalignedline
+\def\shiftalignedline#1#2#3#4% left, right, inner, outer
+ {\rightorleftpageaction
+ {\everyleftofalignedline {\hskip\dimexpr#1+#3\relax}%
+ \everyrightofalignedline{\hskip\dimexpr#2+#4\relax}}
+ {\everyleftofalignedline {\hskip\dimexpr#1+#4\relax}%
+ \everyrightofalignedline{\hskip\dimexpr#2+#3\relax}}}
+
% \def\doalignline#1#2% \\ == newline
% {\begingroup
% \setlocalhsize % new
diff --git a/tex/context/base/core-tab.tex b/tex/context/base/core-tab.tex
index 5828e85f7..edfa4b27b 100644
--- a/tex/context/base/core-tab.tex
+++ b/tex/context/base/core-tab.tex
@@ -366,13 +366,21 @@
\catcode`\|=\@@active
\catcode`\"=\@@active
+% \gdef\pushouterbarandquote
+% {\ifForgetTableBarAndQuote
+% \let|\letterbar
+% \let"\letterdoublequote
+% \ifnum\catcode`\|=\@@active \let\outertablebar |\else\let\outertablebar \relax\fi
+% \ifnum\catcode`\"=\@@active \let\outertablequote"\else\let\outertablequote\relax\fi
+% \fi}
+
\gdef\pushouterbarandquote
- {\ifForgetTableBarAndQuote
- \let|\letterbar
- \let"\letterdoublequote
- \ifnum\catcode`\|=\@@active \let\outertablebar |\else\let\outertablebar \relax\fi
- \ifnum\catcode`\"=\@@active \let\outertablequote"\else\let\outertablequote\relax\fi
- \fi}
+ {\ifForgetTableBarAndQuote
+ \ifnum\catcode`\|=\@@active \let\outertablebar |\else\let\outertablebar \relax\fi
+ \ifnum\catcode`\"=\@@active \let\outertablequote"\else\let\outertablequote\relax\fi
+ \let|\letterbar
+ \let"\letterdoublequote
+ \fi}
\gdef\popouterbarandquote
{\ifForgetTableBarAndQuote
@@ -1197,13 +1205,22 @@
\global\TABLEinbreakfalse
\firststagestartTABLE}
+% \def\stoptables
+% {\ifconditional\tablerepeattail\else\insertTABLEtail\fi
+% \finishTABLE
+% \egroup
+% \dosplittablebox\tablecontentbox
+% \flushnotes
+% \egroup}
+
\def\stoptables
- {\ifconditional\tablerepeattail\else\insertTABLEtail\fi
- \finishTABLE
- \egroup
- \dosplittablebox\tablecontentbox
- \flushnotes
- \egroup}
+ {\chuckTABLEautorow % AM: before the tail, else noalign problem
+ \ifconditional\tablerepeattail\else\insertTABLEtail\fi
+ \finishTABLE
+ \egroup
+ \dosplittablebox\tablecontentbox
+ \flushnotes
+ \egroup}
\newdimen\TABLEcaptionheight % obsolete
diff --git a/tex/context/base/core-uti.mkiv b/tex/context/base/core-uti.mkiv
index 6883f2227..a9f7982f8 100644
--- a/tex/context/base/core-uti.mkiv
+++ b/tex/context/base/core-uti.mkiv
@@ -55,6 +55,8 @@
\immediatewriteutilitytua{-- escape\space: \!!bs\space...\space\!!es}%
\immediatewriteutilitytua{-- version: \utilityversion}%
\immediatewriteutilitytua{}%
+ \immediatewriteutilitytua{-- begin of utility file}%
+ \immediatewriteutilitytua{}%
\immediatewriteutilitytua{do}%
\immediatewriteutilitytua{if job and job.version and not job.version == "\utilityversion" then return end}%
\immediatewriteutilitytua{if not job then job = { } end}%
@@ -63,6 +65,8 @@
\appendtoks
\immediatewriteutilitytua{end}%
+ \immediatewriteutilitytua{}%
+ \immediatewriteutilitytua{-- end of utility file}%
%immediate\closeout\utility@tua
\to \everycloseutilities
@@ -72,8 +76,12 @@
\ctxlua { do
if not job then job = { } end
job.version = "\utilityversion"
- local settings = loadfile("\jobname.tuc")
- if settings then settings() end
+ % local settings = loadfile("\jobname.tuc")
+ local settings = io.loaddata("\jobname.tuc")
+ if settings:find("\letterpercent -\letterpercent -\letterpercent s*end of utility file \letterpercent s$") then
+ settings = loadstring(data)
+ if settings then settings() end
+ end
end}%
\to \everyjob
diff --git a/tex/context/base/core-var.tex b/tex/context/base/core-var.tex
index 0fba2b3b3..0b0c7e2ca 100644
--- a/tex/context/base/core-var.tex
+++ b/tex/context/base/core-var.tex
@@ -279,6 +279,9 @@
\newevery \everyfontswitch \EveryFontSwitch
\newevery \everydefinedfont \relax
+\newevery \everybeforeoutput \relax
+\newevery \everyafteroutput \relax
+
\newevery \everybeforedisplayformula \relax
\def\cleanupfeatures{\the\everycleanupfeatures}
diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua
index 8afeb84e0..c4e326d0a 100644
--- a/tex/context/base/font-afm.lua
+++ b/tex/context/base/font-afm.lua
@@ -19,7 +19,7 @@ away.</p>
fonts = fonts or { }
fonts.afm = fonts.afm or { }
-fonts.afm.version = 1.10 -- incrementing this number one up will force a re-cache
+fonts.afm.version = 1.13 -- incrementing this number one up will force a re-cache
fonts.afm.syncspace = true -- when true, nicer stretch values
fonts.afm.enhance_data = true -- best leave this set to true
fonts.afm.trace_features = false
@@ -54,7 +54,7 @@ do
if designsize then data.designsize = tonumber(designsize) end
end
- local function get_charmetrics(characters,charmetrics)
+ local function get_charmetrics(data,charmetrics,vector)
local characters = data.characters
local chr, str, ind = { }, "", 0
for k,v in charmetrics:gmatch("([%a]+) +(.-) *;") do
@@ -82,10 +82,12 @@ do
chr.ligatures[plus] = becomes
end
end
- if str ~= "" then characters[str] = chr end
+ if str ~= "" then
+ characters[str] = chr
+ end
end
- local function get_kernpairs(characters,kernpairs)
+ local function get_kernpairs(data,kernpairs)
local characters = data.characters
for one, two, value in kernpairs:gmatch("KPX +(.-) +(.-) +(.-)\n") do
local chr = characters[one]
@@ -102,17 +104,41 @@ do
end
end
+ local function get_indexes(data,filename)
+ local pfbname = input.find_file(texmf.instance,file.removesuffix(file.basename(filename))..".pfb","pfb") or ""
+ if pfbname ~= "" then
+ data.luatex = data.luatex or { }
+ data.luatex.filename = pfbname
+ local pfbblob = fontforge.open(pfbname)
+ if pfbblob then
+ local characters = data.characters
+ local pfbdata = fontforge.to_table(pfbblob)
+ if pfbdata and pfbdata.glyphs then
+ for index, glyph in pairs(pfbdata.glyphs) do
+ local name = glyph.name
+ if name then
+ local char = characters[name]
+ if char then
+ char.index = index
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
function fonts.afm.read_afm(filename)
local ok, afmblob, size = input.loadbinfile(texmf.instance,filename) -- has logging
-- local ok, afmblob = true, file.readdata(filename)
if ok and afmblob then
- data = {
+ local data = {
version = version or '0',
characters = { },
filename = file.removesuffix(file.basename(filename))
}
afmblob = afmblob:gsub("StartCharMetrics(.-)EndCharMetrics", function(charmetrics)
- get_charmetrics(data,charmetrics)
+ get_charmetrics(data,charmetrics,vector)
return ""
end)
afmblob = afmblob:gsub("StartKernPairs(.-)EndKernPairs", function(kernpairs)
@@ -124,6 +150,7 @@ do
get_variables(data,fontmetrics)
return ""
end)
+ get_indexes(data,filename)
return data
else
return nil
@@ -268,11 +295,12 @@ function fonts.afm.copy_to_tfm(data)
tfm.characters[t.unicode] = t
end
end
- tfm.encodingbytes = 2
- tfm.units = 1000
- tfm.name = data.filename
- tfm.type = "real"
+ tfm.encodingbytes = data.encodingbytes or 2
tfm.fullname = data.fullname
+ tfm.filename = data.filename
+ tfm.name = data.name
+ tfm.type = "real"
+ tfm.units = 1000
tfm.stretch = stretch
tfm.slant = slant
tfm.direction = 0
@@ -341,10 +369,6 @@ function fonts.afm.copy_to_tfm(data)
end
end
-
---~ function set_x(w,h) return h*slant+w*stretch end
---~ function set_y(h) return h end
-
--[[ldx--
<p>Originally we had features kind of hard coded for <l n='afm'/>
files but since I expect to support more font formats, I decided
@@ -367,7 +391,7 @@ function fonts.afm.set_features(tfmdata)
local mode = tfmdata.mode or fonts.mode
local fi = fonts.initializers[mode]
if fi and fi.afm then
- function initialize(list) -- using tex lig and kerning
+ local function initialize(list) -- using tex lig and kerning
if list then
for _, f in ipairs(list) do
local value = features[f]
@@ -387,7 +411,7 @@ function fonts.afm.set_features(tfmdata)
end
local fm = fonts.methods[mode]
if fm and fm.afm then
- function register(list) -- node manipulations
+ local function register(list) -- node manipulations
if list then
for _, f in ipairs(list) do
if features[f] and fm.afm[f] then -- brr
@@ -406,25 +430,46 @@ function fonts.afm.set_features(tfmdata)
end
function fonts.afm.afm_to_tfm(specification)
- local afmfile = specification.filename or specification.name
- local features = specification.features.normal
- local cache_id = specification.hash
- local tfmdata = containers.read(fonts.tfm.cache, cache_id) -- cache with features applied
- if not tfmdata then
- local afmdata = fonts.afm.load(afmfile)
- if not table.is_empty(afmdata) then
- tfmdata = fonts.afm.copy_to_tfm(afmdata)
- if not table.is_empty(tfmdata) then
- tfmdata.shared = tfmdata.shared or { }
- tfmdata.unique = tfmdata.unique or { }
- tfmdata.shared.afmdata = afmdata
- tfmdata.shared.features = features
- fonts.afm.set_features(tfmdata)
+ local afmname = specification.filename or specification.name
+ local encoding, filename = afmname:match("^(.-)%-(.*)$") -- context: encoding-name.*
+ if encoding and filename and fonts.enc.known[encoding] then
+-- only when no bla-name is found
+ fonts.tfm.set_normal_feature(specification,'encoding',encoding) -- will go away
+ if fonts.trace then
+ logs.report("define font", string.format("stripping encoding prefix from filename %s",afmname))
+ end
+ afmname = filename
+ else
+ local tfmname = input.findbinfile(texmf.instance,afmname,"ofm") or ""
+ if tfmname ~= "" then
+ if fonts.trace then
+ logs.report("define font", string.format("fallback from afm to tfm for %s",afmname))
+ end
+ afmname = ""
+ end
+ end
+ if afmname == "" then
+ return nil
+ else
+ local features = specification.features.normal
+ local cache_id = specification.hash
+ local tfmdata = containers.read(fonts.tfm.cache, cache_id) -- cache with features applied
+ if not tfmdata then
+ local afmdata = fonts.afm.load(afmname)
+ if not table.is_empty(afmdata) then
+ tfmdata = fonts.afm.copy_to_tfm(afmdata)
+ if not table.is_empty(tfmdata) then
+ tfmdata.shared = tfmdata.shared or { }
+ tfmdata.unique = tfmdata.unique or { }
+ tfmdata.shared.afmdata = afmdata
+ tfmdata.shared.features = features
+ fonts.afm.set_features(tfmdata)
+ end
end
+ tfmdata = containers.write(fonts.tfm.cache,cache_id,tfmdata)
end
- tfmdata = containers.write(fonts.tfm.cache,cache_id,tfmdata)
+ return tfmdata
end
- return tfmdata
end
--[[ldx--
@@ -446,39 +491,36 @@ function fonts.tfm.set_normal_feature(specification,name,value)
end
function fonts.tfm.read_from_afm(specification)
- local name, size, tfmtable = specification.name, specification.size, nil
- local encoding, filename = name:match("^(.-)%-(.*)$") -- context: encoding-name.*
- if filename and encoding and fonts.enc.known[encoding] then
- fonts.tfm.set_normal_feature(specification,'encoding',encoding)
- else
- encoding = nil -- fonts.tfm.default_encoding
- filename = name
- end
- if filename ~= "" then
- tfmtable = fonts.afm.afm_to_tfm(specification)
- if tfmtable then
- tfmtable.name = name
- tfmtable = fonts.tfm.scale(tfmtable, size)
- filename = input.findbinfile(texmf.instance,filename,"pfb")
- if filename then
- tfmtable.format, tfmtable.filename = 'type1', filename
- else
- tfmtable.format, tfmtable.filename = 'pk', nil
- end
- if fonts.dontembed[filename] then
- tfmtable.file = nil
- end
- -- begin of map hack
+ local tfmtable = fonts.afm.afm_to_tfm(specification)
+ if tfmtable then
+ tfmtable.name = specification.name
+ tfmtable = fonts.tfm.scale(tfmtable, specification.size)
+ local afmdata = tfmtable.shared.afmdata
+ local filename = afmdata and afmdata.luatex and afmdata.luatex.filename
+ if not filename then
+ -- try to locate anyway and set afmdata.luatex.filename
+ end
+ if filename then
+ tfmtable.encodingbytes = 2
+ tfmtable.filename = input.findbinfile(texmf.instance,filename,"") or filename
+ tfmtable.fullname = afmdata.fullname or afmdata.fontname
+ tfmtable.format = 'type1'
+ tfmtable.name = afmdata.luatex.filename or tfmtable.name
+ end
+ if fonts.dontembed[filename] then
+ tfmtable.file = nil
+ end
+ if false then -- no afm with pk
local mapentry = {
name = tfmtable.name,
fullname = tfmtable.fullname,
stretch = tfmtable.stretch,
slant = tfmtable.slant,
- file = tfmtable.filename,
+ fontfile = tfmtable.filename,
}
- -- end of map hack
- fonts.map.data[name] = mapentry
+ fonts.map.data[specification.name] = mapentry
end
+ fonts.logger.save(tfmtable,'afm',specification)
end
return tfmtable
end
diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua
index 581005c8a..16b3e90b7 100644
--- a/tex/context/base/font-def.lua
+++ b/tex/context/base/font-def.lua
@@ -20,7 +20,7 @@ fonts.vf = fonts.vf or { }
fonts.used = fonts.used or { }
fonts.tfm.version = 1.01
-fonts.tfm.cache = containers.define("fonts", "tfm", fonts.tfm.version, false)
+fonts.tfm.cache = containers.define("fonts", "tfm", fonts.tfm.version, false) -- better in font-tfm
--[[ldx--
<p>Choosing a font by name and specififying its size is only part of the
@@ -73,8 +73,9 @@ and prepares a table that will move along as we proceed.</p>
--ldx]]--
function fonts.define.analyze(name, size, id)
- local specification = name or 'unknown'
- local lookup, rest = name:match("^(.-):(.+)$")
+ name = name or 'unknown'
+ local specification = name
+ local lookup, rest = specification:match("^(.-):(.+)$")
local sub = ""
if lookup == 'file' or lookup == 'name' then
name = rest
@@ -235,15 +236,19 @@ function fonts.tfm.read_and_define(name,size) -- no id
local id = fonts.tfm.internalized[hash]
if not id then
local fontdata = fonts.tfm.read(specification)
- if not fonts.tfm.internalized[hash] then
- id = font.define(fontdata)
- fonts.tfm.id[id] = fontdata
- fonts.tfm.internalized[hash] = id
- if fonts.trace then
- logs.report("define font", string.format("at 1 id %s, hash: %s",id,hash))
+ if fontdata then
+ if not fonts.tfm.internalized[hash] then
+ id = font.define(fontdata)
+ fonts.tfm.id[id] = fontdata
+ fonts.tfm.internalized[hash] = id
+ if fonts.trace then
+ logs.report("define font", string.format("at 1 id %s, hash: %s",id,hash))
+ end
+ else
+ id = fonts.tfm.internalized[hash]
end
else
- id = fonts.tfm.internalized[hash]
+ id = 0 -- signal
end
end
return fonts.tfm.id[id], id
@@ -272,7 +277,6 @@ function fonts.tfm.readers.opentype(specification,suffix,what)
if fullname and fullname ~= "" then
specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then
tfmtable = fonts.tfm.read_from_open_type(specification) -- we need to do it for all matches / todo
- fonts.logger.save(tfmtable,suffix,specification)
end
return tfmtable
else
@@ -288,23 +292,19 @@ function fonts.tfm.readers.afm(specification,method)
local fullname, tfmtable = nil, nil
method = method or fonts.define.method
if method == 2 then
- fullname = input.findbinfile(texmf.instance,specification.name,"ofm") -- ?
- if not fullname or fullname == "" then
+ fullname = input.findbinfile(texmf.instance,specification.name,"ofm") or ""
+ if fullname == "" then
tfmtable = fonts.tfm.read_from_afm(specification)
- fonts.logger.save(tfmtable,'afm',specification)
else -- redundant
specification.filename = fullname
tfmtable = fonts.tfm.read_from_tfm(specification)
- fonts.logger.save(tfmdata,'tfm',specification)
end
elseif method == 3 then -- maybe also findbinfile here
if fonts.define.auto_afm then
tfmtable = fonts.tfm.read_from_afm(specification)
- fonts.logger.save(tfmtable,'afm',specification)
end
elseif method == 4 then -- maybe also findbinfile here
tfmtable = fonts.tfm.read_from_afm(specification)
- fonts.logger.save(tfmtable,'afm',specification)
end
return tfmtable
end
@@ -312,7 +312,6 @@ end
function fonts.tfm.readers.tfm(specification)
local fullname, tfmtable = nil, nil
tfmtable = fonts.tfm.read_from_tfm(specification)
- fonts.logger.save(tfmtable,'tfm',specification)
return tfmtable
end
@@ -394,6 +393,10 @@ function fonts.define.specify.preset_context(name,features)
fonts.define.specify.context_setups[name] = t
end
+function fonts.define.specify.context_tostring(name,kind,separator,yes,no,strict)
+ return aux.hash_to_string(table.merged(fonts[kind].features.default or {},fonts.define.specify.context_setups[name] or {}),separator,yes,no,strict)
+end
+
function fonts.define.specify.split_context(features)
if fonts.define.specify.context_setups[features] then
return fonts.define.specify.context_setups[features]
@@ -472,9 +475,19 @@ function fonts.define.read(name,size,id)
else
fontdata = fonts.tfm.internalized[hash]
end
+
end
if not fontdata then
- logs.error("defining font", string.format("name: %s, loading aborted",specification.name))
+ logs.error("define font", string.format("name: %s, loading aborted",specification.name))
+ elseif fonts.trace and type(fontdata) == "table" then
+ logs.report("use font",string.format("%s font n:%s s:%s b:%s e:%s p:%s f:%s",
+ fontdata.type or "unknown",
+ fontdata.name or "?",
+ fontdata.size or "default",
+ fontdata.encodingbytes or "?",
+ fontdata.encodingname or "unicode",
+ fontdata.fullname or "?",
+ file.basename(fontdata.filename or "?")))
end
return fontdata
end
@@ -490,11 +503,25 @@ end
--~ end
function fonts.vf.find(name)
- local format = fonts.logger.format(name)
- if format == 'tfm' or format == 'ofm' then
- return input.findbinfile(texmf.instance,name,"ovf")
+ name = file.removesuffix(file.basename(name))
+ if fonts.tfm.resolve_vf then
+ local format = fonts.logger.format(name)
+ if format == 'tfm' or format == 'ofm' then
+ if fonts.trace then
+ logs.report("define font",string.format("locating vf for %s",name))
+ end
+ return input.findbinfile(texmf.instance,name,"ovf")
+ else
+ if fonts.trace then
+ logs.report("define font",string.format("vf for %s is already taken care of",name))
+ end
+ return nil -- ""
+ end
else
- return nil -- ""
+ if fonts.trace then
+ logs.report("define font",string.format("locating vf for %s",name))
+ end
+ return input.findbinfile(texmf.instance,name,"ovf")
end
end
@@ -503,4 +530,4 @@ end
--ldx]]--
callback.register('define_font' , fonts.define.read)
-callback.register('find_vf_file', fonts.vf.find )
+callback.register('find_vf_file', fonts.vf.find ) -- not that relevant any more
diff --git a/tex/context/base/font-enc.lua b/tex/context/base/font-enc.lua
index a29ed83d3..3cc6433b2 100644
--- a/tex/context/base/font-enc.lua
+++ b/tex/context/base/font-enc.lua
@@ -12,8 +12,8 @@ them in tables. But we may do so some day, for consistency.</p>
--ldx]]--
fonts.enc = fonts.enc or { }
-fonts.enc.version = 1.01
-fonts.enc.cache = containers.define("fonts", "enc", fonts.enc.version, false)
+fonts.enc.version = 1.03
+fonts.enc.cache = containers.define("fonts", "enc", fonts.enc.version, true)
fonts.enc.known = {
texnansi = true,
@@ -52,12 +52,13 @@ will be used.</p>
function fonts.enc.load(filename)
local name = file.removesuffix(filename)
local data = containers.read(fonts.enc.cache,name)
- if data then
- local vector, tag, hash = { }, "", { }
+ if not data then
+ local vector, tag, hash, unicodes = { }, "", { }, { }
local foundname = input.find_file(texmf.instance,filename,'enc')
if foundname and foundname ~= "" then
local ok, encoding, size = input.loadbinfile(texmf.instance,foundname)
if ok and encoding then
+ local enccodes = characters.context.enccodes
encoding = encoding:gsub("%%(.-)\n","")
local tag, vec = encoding:match("/(%w+)%s*%[(.*)%]%s*def")
local i = 0
@@ -69,12 +70,22 @@ function fonts.enc.load(filename)
else
-- duplicate, play safe for tex ligs and take first
end
+ if enccodes[ch] then
+ unicodes[enccodes[ch]] = i
+ end
end
i = i + 1
end
end
end
- data = containers.write(fonts.enc.cache, name, { name=name, tag=tag, vector=vector, hash=hash })
+ local data = {
+ name=name,
+ tag=tag,
+ vector=vector,
+ hash=hash,
+ unicodes=unicodes
+ }
+ data = containers.write(fonts.enc.cache, name, data)
end
return data
end
diff --git a/tex/context/base/font-ini.lua b/tex/context/base/font-ini.lua
index 16fcf7271..d4adf360b 100644
--- a/tex/context/base/font-ini.lua
+++ b/tex/context/base/font-ini.lua
@@ -49,7 +49,8 @@ do
local unset_attribute = node.unset_attribute
function fonts.color.set(n,c)
- set_attribute(n,attribute,mapping[c] or -1)
+ -- local mc = mapping[c] if mc then unset_attribute((n,attribute) else set_attribute(n,attribute,mc) end
+ set_attribute(n,attribute,mapping[c] or -1) -- also handles -1 now
end
function fonts.color.reset(n)
unset_attribute(n,attribute)
diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv
index dd597d41f..45ff3480e 100644
--- a/tex/context/base/font-ini.mkiv
+++ b/tex/context/base/font-ini.mkiv
@@ -31,12 +31,14 @@
\def\otfchar#1{\ctxlua{fonts.otf.char("#1")}}
-\registerrgbcolor {font:init} {1}{0}{0}%
-\registerrgbcolor {font:medi} {0}{1}{0}%
-\registerrgbcolor {font:fina} {0}{0}{1}%
-\registerrgbcolor {font:isol} {0}{1}{1}%
-\registerrgbcolor {font:mark} {1}{0}{1}%
-\registerrgbcolor {font:rest} {1}{1}{0}%
+%D: We cannot yet inherit because no colors are predefined.
+
+\definecolor[font:init][r=.75]
+\definecolor[font:medi][g=.75]
+\definecolor[font:fina][b=.75]
+\definecolor[font:isol][y=.75]
+\definecolor[font:mark][m=.75]
+\definecolor[font:rest][c=.75]
%D goodies:
%D
@@ -69,4 +71,12 @@
\def\doinstallfontfeature[#1][#2]%
{\ctxlua{fonts.install_feature("#1","#2")}}
+%D Not yet in \MKII.
+
+\def\fontfeatureslist
+ {\dodoubleargument\dofontfeatureslist}
+
+\def\dofontfeatureslist[#1][#2]% todo: arg voor type
+ {\ctxlua{tex.sprint(tex.ctxcatcodes,fonts.define.specify.context_tostring("#1","otf","\luaescapestring{#2}","yes","no",true))}}
+
\protect \endinput
diff --git a/tex/context/base/font-map.lua b/tex/context/base/font-map.lua
index 4aecde445..64ff268fb 100644
--- a/tex/context/base/font-map.lua
+++ b/tex/context/base/font-map.lua
@@ -11,38 +11,39 @@ if not modules then modules = { } end modules ['font-map'] = {
of obsolete. Some code may move to runtime or auxiliary modules.</p>
--ldx]]--
-fonts = fonts or { }
-fonts.map = fonts.map or { }
-fonts.map.data = fonts.map.data or { }
-fonts.map.done = fonts.map.done or { }
-fonts.map.line = fonts.map.line or { }
-fonts.map.loaded = fonts.map.loaded or { }
-fonts.map.direct = fonts.map.direct or { }
+fonts = fonts or { }
+fonts.map = fonts.map or { }
+fonts.map.data = fonts.map.data or { }
+fonts.map.encodings = fonts.map.encodings or { }
+fonts.map.done = fonts.map.done or { }
+fonts.map.loaded = fonts.map.loaded or { }
+fonts.map.direct = fonts.map.direct or { }
+fonts.map.line = fonts.map.line or { }
function fonts.map.line.pdfmapline(tag,str)
return "\\loadmapline[" .. tag .. "][" .. str .. "]"
end
function fonts.map.line.pdftex(e) -- so far no combination of slant and stretch
- if e.name and e.file then
+ if e.name and e.fontfile then
local fullname = e.fullname or ""
- if e.slant and tonumber(e.slant) ~= 0 then
+ if e.slant and e.slant ~= 0 then
if e.encoding then
- return fonts.map.line.pdfmapline("=",string.format('%s %s "%g SlantFont" <%s <%s',e.name,fullname,e.slant,e.encoding,e.file))
+ return fonts.map.line.pdfmapline("=",string.format('%s %s "%g SlantFont" <%s <%s',e.name,fullname,e.slant,e.encoding,e.fontfile))
else
- return fonts.map.line.pdfmapline("=",string.format('%s %s "%g SlantFont" <%s',e.name,fullname,e.slant,e.file))
+ return fonts.map.line.pdfmapline("=",string.format('%s %s "%g SlantFont" <%s',e.name,fullname,e.slant,e.fontfile))
end
- elseif e.stretch and tonumber(e.stretch) ~= 1 and tonumber(e.stretch) ~= 0 then
+ elseif e.stretch and e.stretch ~= 1 and e.stretch ~= 0 then
if e.encoding then
- return fonts.map.line.pdfmapline("=",string.format('%s %s "%g ExtendFont" <%s <%s',e.name,fullname,e.stretch,e.encoding,e.file))
+ return fonts.map.line.pdfmapline("=",string.format('%s %s "%g ExtendFont" <%s <%s',e.name,fullname,e.stretch,e.encoding,e.fontfile))
else
- return fonts.map.line.pdfmapline("=",string.format('%s %s "%g ExtendFont" <%s',e.name,fullname,e.stretch,e.file))
+ return fonts.map.line.pdfmapline("=",string.format('%s %s "%g ExtendFont" <%s',e.name,fullname,e.stretch,e.fontfile))
end
else
if e.encoding then
- return fonts.map.line.pdfmapline("=",string.format('%s %s <%s <%s',e.name,fullname,e.encoding,e.file))
+ return fonts.map.line.pdfmapline("=",string.format('%s %s <%s <%s',e.name,fullname,e.encoding,e.fontfile))
else
- return fonts.map.line.pdfmapline("=",string.format('%s %s <%s',e.name,fullname,e.file))
+ return fonts.map.line.pdfmapline("=",string.format('%s %s <%s',e.name,fullname,e.fontfile))
end
end
else
@@ -50,123 +51,71 @@ function fonts.map.line.pdftex(e) -- so far no combination of slant and stretch
end
end
-function fonts.map.flushlines(backend,separator)
- local t = { }
- for k,v in pairs(fonts.map.data) do
- if not fonts.map.done[k] then
- local str = fonts.map.line[backend](v)
- if str then
- t[#t+1] = str
- end
- fonts.map.done[k] = true
- end
+function fonts.map.flush(backend) -- will also erase the accumulated data
+ local flushline = fonts.map.line[backend or "pdftex"] or fonts.map.line.pdftex
+ for _, e in pairs(fonts.map.data) do
+ tex.sprint(tex.ctxcatcodes,flushline(e))
end
- return table.join(t,separator or "")
+ fonts.map.data = { }
end
-fonts.map.line.dvips = fonts.map.line.pdftex
-fonts.map.line.dvipdfmx = function() end
-
-function fonts.map.process_entries(filename, backend, handle)
- local root = xml.load(filename,true)
- if root then
- if not handle then handle = texio.write_nl end
- xml.process_attributes(root, "/fontlist/font", function(e,k)
- local str = fonts.map.line[backend](e)
- if str then
- handle(str)
- end
- end)
- end
-end
+fonts.map.line.dvips = fonts.map.line.pdftex
+fonts.map.line.dvipdfmx = function() end
function fonts.map.convert_entries(filename)
if not fonts.map.loaded[filename] then
- local root = xml.load(filename,true) -- todo: stop garbage collector
- if root then
- garbagecollector.push()
- xml.process_attributes(root, "/fontlist/font", function(e,k)
- if e.name and e.file then
- fonts.map.data[e.name] = e
- -- fonts.map.data[e.name].name = nil -- beware, deletes xml entry as well
- end
- end)
- garbagecollector.pop()
- end
+ fonts.map.data, fonts.map.encodings = fonts.map.load_file(filename,fonts.map.data, fonts.map.encodings)
fonts.map.loaded[filename] = true
end
end
-function fonts.map.direct.pdftex(filename)
- fonts.map.process_entries(filename,'pdftex',function(str)
- tex.sprint(tex.ctxcatcodes,str)
- end)
-end
-
--- the next one will go to a runtime module, no need to put this in the format
-
-function fonts.map.convert_file(filename, handle) -- when handle is string, then assume file
- local f, g = io.open(filename), nil
+function fonts.map.load_file(filename, entries, encodings)
+ entries = entries or { }
+ encodings = encodings or { }
+ local f = io.open(filename)
if f then
- if not handle then
- handle = print
- elseif type(handle) == "string" then
- g = io.open(handle,"w")
- function handle(str)
- g:write(str .. "\n")
- end
- end
- handle("<?xml version='1.0' standalone='yes'?>\n")
- handle(string.format("<!-- %s -->\n", "generated by context"))
- handle(string.format("<fontlist original='%s'>\n", filename))
- for line in f:lines() do
- local comment = line:match("^[%#%%]%s*(.*)%s*$")
- if comment then -- todo: optional
- handle(string.format(" <!-- %s -->", comment))
- elseif line:find("^\s*$") then
- handle("")
- else
- name, fullname, spec, encoding, file = line:match("^(%S+)%s+(%S-)%s*\"([^\"]-)\"%s*<%s*(%S-)%s*<%s*(%S-)%s*$")
- if not name then
- name, fullname, spec, file = line:match("^(%S+)%s+(%S-)%s*\"([^\"]-)\"%s*<%s*(%S-)%s*$")
- end
- if not name then
- name, fullname, encoding, file = line:match("^(%S+)%s+(%S-)%s*<%s*(%S-)%s*<%s*(%S-)%s*$")
- end
- if not name then
- name, fullname, file = line:match("^(%S+)%s+(%S-)%s*<%s*(%S-)%s*$")
- end
- if name and name ~= "" and file and file ~= "" then
- t = { }
- if name then t[#t+1] = string.format("name='%s'" , name) end
- if fullname and fullname ~= "" then t[#t+1] = string.format("fullname='%s'", fullname) end
- if encoding and encoding ~= "" then t[#t+1] = string.format("encoding='%s'", encoding) end
- if file then t[#t+1] = string.format("file='%s'" , file) end
- if spec then
- local a, b = spec:match("^([%d%.])%s+(%a+)$")
- if a and b and b == "ExtendFont" then t[#t+1] = string.format("slant='%s'" , a) end
- if a and b and b == "SlantFont" then t[#t+1] = string.format("stretch='%s'", a) end
+ local data = f:read("*a")
+ if data then
+ for line in data:gmatch("(.-)[\n\t]") do
+ if line:find("^[%#%%%s]") then
+ -- print(line)
+ else
+ local stretch, slant, name, fullname, fontfile, encoding
+ line = line:gsub('"(.+)"', function(s)
+ stretch = s:find('"([^"]+) ExtendFont"')
+ slant = s:find('"([^"]+) SlantFont"')
+ return ""
+ end)
+ if not name then
+ -- name fullname encoding fontfile
+ name, fullname, encoding, fontfile = line:match("^(%S+)%s+(%S*)[%s<]+(%S*)[%s<]+(%S*)%s*$")
+ end
+ if not name then
+ -- name fullname (flag) fontfile encoding
+ name, fullname, fontfile, encoding = line:match("^(%S+)%s+(%S*)[%d%s<]+(%S*)[%s<]+(%S*)%s*$")
+ end
+ if not name then
+ -- name fontfile
+ name, fontfile = line:match("^(%S+)%s+[%d%s<]+(%S*)%s*$")
+ end
+ if name then
+ if encoding == "" then encoding = nil end
+ entries[name] = {
+ name = name, -- handy
+ fullname = fullname,
+ encoding = encoding,
+ fontfile = fontfile,
+ slant = tonumber(slant),
+ stretch = tonumber(stretch)
+ }
+ encodings[name] = encoding
+ elseif line ~= "" then
+ -- print(line)
end
- handle(string.format(" <font %s/>",table.concat(t," ")))
end
end
end
- handle("\n</fontlist>")
f:close()
- if g then g:close() end
end
+ return entries, encodings
end
-
---~ fonts.map.convert_file("c:/data/develop/tex/texmf/fonts/map/dvips/lm/lm-ec.map")
---~ fonts.map.convert_file("maptest.map")
---~ fonts.map.convert_file("maptest.map", "maptest-1.xml")
---~ fonts.map.convert_file("c:/data/develop/tex/texmf/fonts/map/pdftex/updmap/pdftex.map")
---~ fonts.map.convert_file("c:/data/develop/tex/texmf/fonts/map/pdftex/updmap/pdftex.map", "maptest-2.xml")
-
---~ fonts.map.convert_entries('maptest-2.xml')
---~ fonts.map.process_entries('maptest.xml','pdftex')
-
---~ print(table.serialize(fonts.map.data))
-
---~ tex.sprint(fonts.map.flushlines("pdftex","\n"))
---~ str = fonts.map.flushlines("pdftex")
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index 8dec45481..8331a5177 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -33,7 +33,7 @@ in the <l n='otf'/> table.</p>
fonts = fonts or { }
fonts.otf = fonts.otf or { }
-fonts.otf.version = 1.56 -- incrementing this number one up will force a re-cache
+fonts.otf.version = 1.60 -- incrementing this number one up will force a re-cache
fonts.otf.tables = fonts.otf.tables or { }
fonts.otf.meanings = fonts.otf.meanings or { }
fonts.otf.enhance_data = false
@@ -727,7 +727,9 @@ function fonts.otf.load(filename,format,sub,featurefile)
fonts.otf.enhance.analyze(data,filename)
logs.report("load otf","enhance: after")
fonts.otf.enhance.after(data,filename)
- logs.report("load otf","save in cache")
+ logs.report("load otf","enhance: patch")
+ fonts.otf.enhance.patch(data,filename)
+ logs.report("load otf","saving: in cache")
data = containers.write(fonts.otf.cache, name, data)
else
logs.error("load otf","loading failed")
@@ -750,6 +752,8 @@ function fonts.otf.load(filename,format,sub,featurefile)
return data
end
+-- todo: normalize, design_size => designsize
+
function fonts.otf.enhance.analyze(data,filename)
local t = {
filename = file.basename(filename),
@@ -764,27 +768,150 @@ function fonts.otf.enhance.analyze(data,filename)
data.luatex = t
end
+function fonts.otf.load_cidmap(filename)
+ local data = io.loaddata(filename)
+ if data then
+ local unicodes, names = { }, {}
+ data = data:gsub("^(%d+)%s+(%d+)\n","")
+ for a,b in data:gmatch("(%d+)%s+([%d%a]+)\n") do
+ unicodes[tonumber(a)] = tonumber(b,16)
+ end
+ for a,b,c in data:gmatch("(%d+)%.%.(%d+)%s+([%d%a]+)%s*\n") do
+ c = tonumber(c,16)
+ for i=tonumber(a),tonumber(b) do
+ unicodes[i] = c
+ c = c + 1
+ end
+ end
+ for a,b in data:gmatch("(%d+)%s+\/(%S+)%s*\n") do
+ names[tonumber(a)] = b
+ end
+ local supplement, registry, ordering = filename:match("^(.-)%-(.-)%-()%.(.-)$")
+ return {
+ supplement = supplement,
+ registry = registry,
+ ordering = ordering,
+ filename = filename,
+ unicodes = unicodes,
+ names = names
+ }
+ else
+ return nil
+ end
+end
+
+fonts.otf.cidmaps = { }
+
+function fonts.otf.cidmap(registry,ordering,supplement)
+ local template = "%s-%s-%s.cidmap"
+ local filename = string.format(template,registry,ordering,supplement)
+ local supplement = tonumber(supplement)
+ if not fonts.otf.cidmaps[filename] then
+ for i=supplement,0,-1 do
+ logs.report("load otf",string.format("checking cidmap, registry: %s, ordering: %s, supplement: %s",registry,ordering,i))
+ filename = string.format(template,registry,ordering,i)
+ local fullname = input.find_file(texmf.instance,filename,'cid') or ""
+ if fullname ~= "" then
+ local cidmap = fonts.otf.load_cidmap(fullname)
+ if cidmap then
+ logs.report("load otf",string.format("using cidmap file %s",filename))
+ fonts.otf.cidmaps[filename] = cidmap
+ if i < supplement then
+ for j=i+1,supplement do
+ filename = string.format(template,registry,ordering,j)
+ fonts.otf.cidmaps[filename] = cidmap -- copy of ref
+ end
+ end
+ return cidmap
+ end
+ end
+ end
+ end
+ return nil
+end
+
+--~ ["cidinfo"]={
+--~ ["ordering"]="Japan1",
+--~ ["registry"]="Adobe",
+--~ ["supplement"]=6,
+--~ ["version"]=6,
+--~ },
+
function fonts.otf.enhance.before(data,filename)
local private = 0xE000
- local uni_to_int = data.map.map
- local int_to_uni = data.map.backmap
- for index, glyph in pairs(data.glyphs) do
- if index > 0 and glyph.unicodeenc == -1 then
- while uni_to_int[private] do
- private = private + 1
+ if data.subfonts and table.is_empty(data.glyphs) then
+ local cidinfo = data.cidinfo
+ if cidinfo.registry then
+ local cidmap = fonts.otf.cidmap(cidinfo.registry,cidinfo.ordering,cidinfo.supplement)
+ if cidmap then
+ local glyphs, uni_to_int, int_to_uni, nofnames, nofunicodes, zerobox = { }, { }, { }, 0, 0, { 0, 0, 0, 0 }
+ local unicodes, names = cidmap.unicodes, cidmap.names
+ for n, subfont in pairs(data.subfonts) do
+ for index, g in pairs(subfont.glyphs) do
+ if not next(g) then
+ -- dummy entry
+ else
+ local unicode, name = unicodes[index], names[index]
+ g.cidindex = n
+ g.boundingbox = g.boundingbox or zerobox
+ g.name = g.name or name or "unknown"
+ if unicode then
+ g.unicodeenc = unicode
+ uni_to_int[unicode] = index
+ int_to_uni[index] = unicode
+ nofunicodes = nofunicodes + 1
+ elseif name then
+ g.unicodeenc = -1
+ nofnames = nofnames + 1
+ end
+ glyphs[index] = g
+ end
+ end
+ subfont.glyphs = nil
+ end
+ logs.report("load otf",string.format("cid font remapped, %s unicode points, %s symbolic names, %s glyphs",nofunicodes, nofnames, nofunicodes+nofnames))
+ data.glyphs = glyphs
+ data.map = data.map or { }
+ data.map.map = uni_to_int
+ data.map.backmap = int_to_uni
+ else
+ logs.report("load otf",string.format("unable to remap cid font, missing cid file for %s",filename))
end
- uni_to_int[private] = index
- int_to_uni[index] = private
- glyph.unicodeenc = private
- logs.report("load otf",string.format("enhance: glyph %s at index %s is moved to private unicode slot %s",glyph.name,index,private))
+ else
+ logs.report("load otf",string.format("font %s has no glyphs",filename))
end
end
+ if data.map then
+ local uni_to_int = data.map.map
+ local int_to_uni = data.map.backmap
+ for index, glyph in pairs(data.glyphs) do
+ if index > 0 and glyph.unicodeenc == -1 then
+ while uni_to_int[private] do
+ private = private + 1
+ end
+ uni_to_int[private] = index
+ int_to_uni[index] = private
+ glyph.unicodeenc = private
+ if fonts.trace then
+ logs.report("load otf",string.format("enhance: glyph %s at index %s is moved to private unicode slot %s",glyph.name,index,private))
+ end
+ end
+ end
+ else
+ data.map = { map = {}, backmap = {} }
+ end
if data.ttf_tables then
for _, v in ipairs(data.ttf_tables) do
if v.data then v.data = "deleted" end
--~ if v.data then v.data = v.data:gsub("\026","\\026") end -- does not work out well
end
end
+ table.compact(data.glyphs)
+ if data.subfonts then
+ for _, subfont in pairs(data.subfonts) do
+ table.compact(subfont.glyphs)
+ end
+ end
end
function fonts.otf.enhance.after(data,filename)
@@ -792,13 +919,21 @@ function fonts.otf.enhance.after(data,filename)
for index, glyph in pairs(data.glyphs) do
if glyph.kerns then
local mykerns = { }
- for k,v in ipairs(glyph.kerns) do
- local mkl = mykerns[v.lookup]
- if not mkl then
- mkl = { [unicodes[v.char]] = v.off }
- mykerns[v.lookup] = mkl
- else
- mkl[unicodes[v.char]] = v.off
+ for k,v in pairs(glyph.kerns) do
+ local vc, vo, vl = v.char, v.off, v.lookup
+ if vc and vo and vl then -- brrr, wrong! we miss the non unicode ones
+ local uvc = unicodes[vc]
+ if uvc then
+ local mkl = mykerns[vl]
+ if not mkl then
+ mkl = { [unicodes[vc]] = vo }
+ mykerns[v.lookup] = mkl
+ else
+ mkl[unicodes[vc]] = vo
+ end
+ else
+ logs.report("load otf", string.format("problems with unicode %s of kern %s at glyph %s",vc,k,index))
+ end
end
end
glyph.mykerns = mykerns
@@ -806,6 +941,35 @@ function fonts.otf.enhance.after(data,filename)
end
end
+fonts.otf.enhance.patches = { }
+
+function fonts.otf.enhance.patch(data,filename)
+ local basename = file.basename(filename)
+ for pattern, action in pairs(fonts.otf.enhance.patches) do
+ if basename:find(pattern) then
+ action(data,filename)
+ end
+ end
+end
+
+do -- will move to a typescript
+
+ local function patch(data,filename)
+ if data.design_size == 0 then
+ local ds = (file.basename(filename)):match("(%d+)")
+ if ds then
+ logs.report("load otf",string.format("patching design size (%s)",ds))
+ data.design_size = tonumber(ds) * 10
+ end
+ end
+ end
+
+ fonts.otf.enhance.patches["^lmroman"] = patch
+ fonts.otf.enhance.patches["^lmsans"] = patch
+ fonts.otf.enhance.patches["^lmmono"] = patch
+
+end
+
function fonts.otf.analyze_class(data,class)
local classes = { }
for index, glyph in pairs(data.glyphs) do
@@ -941,7 +1105,7 @@ function fonts.otf.set_features(tfmdata)
local mode = tfmdata.mode or fonts.mode
local fi = fonts.initializers[mode]
if fi and fi.otf then
- function initialize(list) -- using tex lig and kerning
+ local function initialize(list) -- using tex lig and kerning
if list then
for _, f in ipairs(list) do
local value = features[f]
@@ -962,7 +1126,7 @@ function fonts.otf.set_features(tfmdata)
end
local fm = fonts.methods[mode]
if fm and fm.otf then
- function register(list) -- node manipulations
+ local function register(list) -- node manipulations
if list then
for _, f in ipairs(list) do
if features[f] and fm.otf[f] then -- brr
@@ -1042,39 +1206,42 @@ function fonts.otf.copy_to_tfm(data)
for k,v in pairs(data.map.map) do
-- k = unicode, v = slot
local d = data.glyphs[v]
- -- if d then
if d and (force or d.name) then
- local t = { }
- t.index = v
- t.unicode = k
- t.name = d.name or ".notdef"
- t.boundingbox = d.boundingbox or nil
- t.width = d.width or 0
- t.height = d.boundingbox[4] or 0
- t.depth = - d.boundingbox[2] or 0
- t.class = d.class
+ local t = {
+ index = v,
+ unicode = k,
+ name = d.name or ".notdef",
+ boundingbox = d.boundingbox or nil,
+ width = d.width or 0,
+ height = d.boundingbox[4] or 0,
+ depth = - d.boundingbox[2] or 0,
+ class = d.class,
+ }
if d.class == "mark" then
- t.width = -t.width
+ t.width = - t.width
end
characters[k] = t
end
end
+ local designsize = data.designsize or data.design_size or 100
+ if designsize == 0 then
+ designsize = 100
+ end
+ local spaceunits = 500
tfm.units = data.units_per_em or 1000
- -- we need a runtime lookup because of running from cdrom or zip
+ -- we need a runtime lookup because of running from cdrom or zip, brrr
tfm.filename = input.findbinfile(texmf.instance,data.luatex.filename,"") or data.luatex.filename
tfm.fullname = data.fullname or data.fontname
+ tfm.encodingbytes = 2
tfm.cidinfo = data.cidinfo
- -- if not tfm.cidinfo.registry then tfm.cidinfo.registry = "" end
tfm.cidinfo.registry = tfm.cidinfo.registry or ""
- tfm.name = file.removesuffix(file.basename(tfm.filename))
tfm.type = "real"
tfm.stretch = 0 -- stretch
tfm.slant = 0 -- slant
tfm.direction = 0
tfm.boundarychar_label = 0
tfm.boundarychar = 65536
- tfm.designsize = ((data.designsize or 100)/10)*65536
- local spaceunits = 500
+ tfm.designsize = (designsize/10)*65536
tfm.spacer = "500 units"
data.isfixedpitch = data.pfminfo and data.pfminfo.panose and data.pfminfo.panose["proportion"] == "Monospaced"
data.charwidth = nil
@@ -1084,19 +1251,25 @@ function fonts.otf.copy_to_tfm(data)
if data.isfixedpitch then
if data.glyphs[unicodes['space']] then
spaceunits, tfm.spacer = data.glyphs[unicodes['space']].width, "space"
- elseif data.glyphs[unicodes['emdash']] then
+ end
+ if not spaceunits and data.glyphs[unicodes['emdash']] then
spaceunits, tfm.spacer = data.glyphs[unicodes['emdash']].width, "emdash"
- elseif data.charwidth then
+ end
+ if not spaceunits and data.charwidth then
+ spaceunits, tfm.spacer = data.charwidth, "charwidth"
+ end
+ else
+ if data.glyphs[unicodes['space']] then
+ spaceunits, tfm.spacer = data.glyphs[unicodes['space']].width, "space"
+ end
+ if not spaceunits and data.glyphs[unicodes['emdash']] then
+ spaceunits, tfm.spacer = data.glyphs[unicodes['emdash']].width/2, "emdash/2"
+ end
+ if not spaceunits and data.charwidth then
spaceunits, tfm.spacer = data.charwidth, "charwidth"
end
- elseif data.glyphs[unicodes['space']] then
- spaceunits, tfm.spacer = data.glyphs[unicodes['space']].width, "space"
- elseif data.glyphs[unicodes['emdash']] then
- spaceunits, tfm.spacer = data.glyphs[unicodes['emdash']].width/2, "emdash/2"
- elseif data.charwidth then
- spaceunits, tfm.spacer = data.charwidth, "charwidth"
end
- spaceunits = tonumber(spaceunits)
+ spaceunits = tonumber(spaceunits) or 500 -- brrr
tfm.parameters[1] = 0 -- slant
tfm.parameters[2] = spaceunits -- space
tfm.parameters[3] = 500 -- space_stretch
@@ -1122,9 +1295,13 @@ function fonts.otf.copy_to_tfm(data)
end
if data.pfminfo and data.pfminfo.os2_xheight and data.pfminfo.os2_xheight > 0 then
tfm.parameters[5] = data.pfminfo.os2_xheight
- elseif data.glyphs[unicodes['x']] and data.glyphs[unicodes['x']].height then
- tfm.parameters[5] = data.glyphs[unicodes['x']].height
+ else
+ local x = characters[unicodes['x']]
+ if x then
+ tfm.parameters[5] = x.height
+ end
end
+ -- [6]
return tfm
else
return nil
@@ -1137,8 +1314,19 @@ function fonts.tfm.read_from_open_type(specification)
tfmtable.name = specification.name
tfmtable.sub = specification.sub
tfmtable = fonts.tfm.scale(tfmtable, specification.size)
- tfmtable.file = file.basename(specification.filename)
- tfmtable.format = specification.format
+ -- here we resolve the name; file can be relocated, so this info is not in the cache
+ local otfdata = tfmtable.shared.otfdata
+ local filename = otfdata and otfdata.luatex and otfdata.luatex.filename
+ if not filename then
+ -- try to locate anyway and set otfdata.luatex.filename
+ end
+ if filename then
+ tfmtable.encodingbytes = 2
+ tfmtable.filename = input.findbinfile(texmf.instance,filename,"") or filename
+ tfmtable.fullname = otfdata.fullname or otfdata.fontname
+ tfmtable.format = specification.format
+ end
+ fonts.logger.save(tfmtable,file.extname(specification.filename),specification)
end
return tfmtable
end
@@ -1148,27 +1336,52 @@ end
fonts.otf.default_language = 'latn'
fonts.otf.default_script = 'dflt'
-function fonts.otf.valid_feature(otfdata,language,script) -- return hash is faster
+--~ function fonts.otf.valid_feature(otfdata,language,script) -- return hash is faster
+--~ local language = language or fonts.otf.default_language
+--~ local script = script or fonts.otf.default_script
+--~ if not (script and language) then
+--~ return boolean.alwaystrue
+--~ else
+--~ language = string.padd(language:lower(),4)
+--~ script = string.padd(script:lower (),4)
+--~ local t = { }
+--~ for k,v in pairs(otfdata.luatex.subtables) do
+--~ local vv = v[script]
+--~ if vv and vv[language] then
+--~ t[k] = vv[language].valid
+--~ end
+--~ end
+--~ local always = otfdata.luatex.always_valid -- for the moment not per feature
+--~ --~ return function(kind,tag) -- is the kind test needed
+--~ --~ return always[tag] or (kind and t[kind] and t[kind][tag])
+--~ --~ end
+--~ return function(kind,tag) -- better inline
+--~ return always[tag] or (t[kind] and t[kind][tag])
+--~ end
+--~ end
+--~ end
+
+function fonts.otf.valid_feature(otfdata,language,script,feature) -- return hash is faster
local language = language or fonts.otf.default_language
local script = script or fonts.otf.default_script
if not (script and language) then
- return boolean.alwaystrue
+ return true
else
language = string.padd(language:lower(),4)
script = string.padd(script:lower (),4)
- local t = { }
- for k,v in pairs(otfdata.luatex.subtables) do
- local vv = v[script]
- if vv and vv[language] then
- t[k] = vv[language].valid
- end
- end
- local always = otfdata.luatex.always_valid -- for the moment not per feature
- return function(kind,tag) -- is the kind test needed
- return always[tag] or kind and t[kind] and t[kind][tag]
- end
+--~ local t = { }
+--~ for k,v in pairs(otfdata.luatex.subtables) do
+--~ local vv = v[script]
+--~ if vv and vv[language] then
+--~ t[k] = vv[language].valid
+--~ end
+--~ end
+ local ft = otfdata.luatex.subtables[feature]
+ local st = ft[script]
+ return false, otfdata.luatex.always_valid, st and st[language] and st[language].valid
end
end
+
function fonts.otf.some_valid_feature(otfdata,language,script,kind)
local language = language or fonts.otf.default_language
local script = script or fonts.otf.default_script
@@ -1464,13 +1677,21 @@ do
end
end
else -- check if this valid is still ok
- local valid = fonts.otf.valid_feature(otfdata,tfmdata.language,tfmdata.script)
+--~ local valid = fonts.otf.valid_feature(otfdata,tfmdata.language,tfmdata.script)
+ local forced, always, okay = fonts.otf.valid_feature(otfdata,tfmdata.language,tfmdata.script,kind)
for _,o in pairs(otfdata.glyphs) do
if o.lookups then
- for lookup, ps in pairs(o.lookups) do
- if valid(kind,lookup) then
- collect(lookup,o,ps)
- end
+--~ for lookup, ps in pairs(o.lookups) do
+--~ if valid(kind,lookup) then
+--~ collect(lookup,o,ps)
+--~ end
+--~ end
+ if forced then
+ for lookup, ps in pairs(o.lookups) do collect(lookup,o,ps) end
+ elseif okay then
+ for lookup, ps in pairs(o.lookups) do if always[lookup] or okay[lookup] then collect(lookup,o,ps) end end
+ else
+ for lookup, ps in pairs(o.lookups) do if always[lookup] then collect(lookup,o,ps) end end
end
end
end
@@ -1818,7 +2039,7 @@ end
do
- prepare = fonts.otf.features.prepare.feature
+ local prepare = fonts.otf.features.prepare.feature
function fonts.initializers.node.otf.afrc(tfm,value) return prepare(tfm,'afrc',value) end
function fonts.initializers.node.otf.akhn(tfm,value) return prepare(tfm,'akhn',value) end
@@ -1984,7 +2205,7 @@ do
-- todo: components / else subtype 0 / maybe we should be able to force this
- function toligature(start,stop,char,markflag)
+ local function toligature(start,stop,char,markflag)
if start ~= stop then
local deletemarks = markflag ~= "mark"
start.subtype = 1
@@ -2356,7 +2577,7 @@ do
return start, done
end
- chainprocs = { } -- we can probably optimize this because they're all internal lookups
+ local chainprocs = { } -- we can probably optimize this because they're all internal lookups
-- For the moment we save each looked up glyph in the sequence, which is ok because
-- each lookup in the chain has its own sequence. This saves memory. Only ligatures
@@ -3191,6 +3412,9 @@ end
do
local glyph = node.id('glyph')
+ local glue = node.id('glue')
+ local penalty = node.id('penalty')
+
local fontdata = fonts.tfm.id
local set_attribute = node.set_attribute
local has_attribute = node.has_attribute
@@ -3236,6 +3460,8 @@ do
-- arab / todo: 0640 tadwil
+ -- this info eventually will go into char-def
+
local isol = {
[0x0621] = true,
}
@@ -3377,6 +3603,122 @@ do
return head, done
end
+ -- han (chinese) (unfinished)
+
+ -- this info eventually will go into char-def
+
+ local no_init = table.tohash {
+ 0x3001, 0x3002, 0x2014, 0xFF5E, 0x2019, 0x201D, 0x3015, 0x3009,
+ 0x300B, 0x300D, 0x300F, 0x3017, 0x3011, 0x2237, 0x00B0, 0x2032,
+ 0x2033, 0xFF01, 0xFF02, 0xFF07, 0xFF09, 0xFF0C, 0xFF0E, 0xFF1A,
+ 0xFF1B, 0xFF1F, 0xFF3D, 0xFF5D,
+ }
+
+ local no_fina = table.tohash {
+ 0x2018, 0x201C, 0x3014, 0x3008, 0x300A, 0x300C, 0x300E, 0x3016,
+ 0x3010, 0xFF08, 0xFF3B, 0xFF40, 0xFF5B,
+ }
+
+ local no_xxxx = table.tohash {
+ 0x00B7, 0x00A8, 0x2026, 0xFF1E,
+ }
+
+ local allowbreak = node.new("penalty")
+ local nobreak = node.new("penalty")
+--~ local zeroskip = node.new("glue")
+
+ allowbreak.penalty = -100
+ nobreak.penalty = 10000
+--~ zeroskip.subtype = 0
+--~ zeroskip.spec = node.new('glue_spec')
+--~ zeroskip.spec.width = 0
+--~ zeroskip.spec.stretch = 0
+--~ zeroskip.spec.shrink = 0
+
+ -- an alternative is to deal with it in the line breaker
+
+ local function is_han_character(char)
+ return
+ (char>=0x04E00 and char<=0x09FFF) or
+ (char>=0x03400 and char<=0x04DFF) or
+ (char>=0x20000 and char<=0x2A6DF) or
+ (char>=0x0F900 and char<=0x0FAFF) or
+ (char>=0x2F800 and char<=0x2FA1F)
+ end
+
+ function fonts.analyzers.methods.hang(head,font) -- maybe make a special version with no trace
+ local characters = fontdata[font].characters
+ local current, done = head, false
+ local trace = fonts.color.trace
+ local prevchinese = false
+ local function unskip()
+ if prevchinese then
+ local temp = current.prev
+ while temp and temp.id == glue do
+ head, temp = nodes.delete(head,temp)
+ if temp then temp = temp.prev end
+ end
+ end
+ end
+ while current do
+ if current.id == glyph then
+ if current.font == font then
+ local char = current.char
+ if no_init[char] then
+ done = true
+ set_attribute(current,state,1) -- before
+ if trace then fcs(current,"font:init") end -- we need nice names
+ if current.prev then
+ unskip()
+ head, current = node.insert_before(head,current,node.copy(nobreak))
+ current = current.next
+ end
+ prevchinese = true
+ elseif no_fina[char] then
+ done = true
+ set_attribute(current,state,2) -- after
+ if trace then fcs(current,"font:fina") end -- we need nice names
+ if current.prev then
+ unskip()
+ head, current = node.insert_before(head,current,node.copy(allowbreak))
+ current = current.next
+ end
+ if current and current.next then
+ head, current = node.insert_after(head,current,node.copy(nobreak))
+ current = current.next
+ end
+ prevchinese = true
+ elseif no_xxxx[char] then
+ done = true
+ set_attribute(current,state,3) -- xxxx
+ if trace then fcs(current,"font:medi") end -- we need nice names
+ if current.prev then -- todo
+ unskip()
+ head, current = node.insert_before(head,current,node.copy(allowbreak))
+ current = current.next
+ end
+ prevchinese = true
+ elseif is_han_character(char) then
+ if current.prev and current.prev.id ~= penalty then
+ unskip()
+ head, current = node.insert_before(head,current,node.copy(allowbreak))
+ current = current.next
+ end
+ prevchinese = true
+ else
+ prevchinese = false
+ end
+ else
+ prevchinese = false
+ end
+ end
+ if current then
+ current = current.next
+ end
+ end
+ return head, done
+ end
+
end
-- experimental and will probably change
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua
index 77898a4a2..fdd99e6f2 100644
--- a/tex/context/base/font-syn.lua
+++ b/tex/context/base/font-syn.lua
@@ -54,6 +54,10 @@ function fonts.names.filters.afm(name)
end
end
+function fonts.names.filters.pfb(name)
+ return fontforge.info(name)
+end
+
--[[ldx--
<p>The scanner loops over the filters using the information stored in
the file databases. Watch how we check not only for the names, but also
@@ -61,7 +65,7 @@ for combination with the weight of a font.</p>
--ldx]]--
fonts.names.filters.list = {
- "otf", "ttf", "ttc", "afm"
+ "otf", "ttf", "ttc", "afm" -- pfb is quite messy, too many messages, maybe broken
}
fonts.names.filters.fixes = {
diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua
index 21a02a67b..103f71c12 100644
--- a/tex/context/base/font-tfm.lua
+++ b/tex/context/base/font-tfm.lua
@@ -23,6 +23,35 @@ fonts.triggers = fonts.triggers or { } -- brrr
supplied by <l n='luatex'/>.</p>
--ldx]]--
+fonts.tfm.resolve_vf = true -- false
+
+function fonts.tfm.enhance(tfmdata,specification)
+ local name, size = specification.name, specification.size
+ local encoding, filename = name:match("^(.-)%-(.*)$") -- context: encoding-name.*
+ if filename and encoding and fonts.enc.known[encoding] then
+ local data = fonts.enc.load(encoding)
+ if data then
+ local characters = tfmdata.characters
+ tfmdata.encoding = encoding
+ local vector = data.vector
+ for k, v in pairs(characters) do
+ v.name = vector[k]
+ v.index = k
+ end
+ for k,v in pairs(data.unicodes) do
+ if k ~= v then
+ -- if not characters[k] then
+ if fonts.trace then
+ logs.report("define font",string.format("mapping %s onto %s",k,v))
+ end
+ characters[k] = characters[v]
+ -- end
+ end
+ end
+ end
+ end
+end
+
function fonts.tfm.read_from_tfm(specification)
local fname, tfmdata = specification.filename, nil
if fname then
@@ -41,32 +70,24 @@ function fonts.tfm.read_from_tfm(specification)
if fonts.trace then
logs.report("define font",string.format("loading tfm file %s at size %s",fname,specification.size))
end
- tfmdata = font.read_tfm(fname,specification.size)
+ tfmdata = font.read_tfm(fname,specification.size) -- not cached, fast enough
if tfmdata then
---~ fonts.logger.save(tfmdata,'tfm',specification)
---~ if false then
- fname = input.findbinfile(texmf.instance, specification.name, 'ovf')
- if fname and fname ~= "" then
-callback.register('find_vf_file', nil)
- local vfdata = font.read_vf(fname,specification.size)
- if vfdata then
- local chars = tfmdata.characters
- for k,v in ipairs(vfdata.characters) do
- chars[k].commands = v.commands
- end
---~ tfmdata.type = 'virtual'
- local fnts = vfdata.fonts
- for k,v in ipairs(fnts) do
- local dummy, id = fonts.tfm.read_and_define(v.name,v.size)
- fnts[k].id = id
- if fonts.trace then
- logs.report("define font",string.format("vf file %s needs tfm file %s (id %s)", fname, v.name, id))
+ if fonts.tfm.resolve_vf then
+ fonts.logger.save(tfmdata,file.extname(fname),specification) -- strange, why here
+ fname = input.findbinfile(texmf.instance, specification.name, 'ovf')
+ if fname and fname ~= "" then
+ local vfdata = font.read_vf(fname,specification.size) -- not cached, fast enough
+ if vfdata then
+ local chars = tfmdata.characters
+ for k,v in pairs(vfdata.characters) do -- no ipairs, can have holes
+ chars[k].commands = v.commands
end
+ tfmdata.type = 'virtual'
+ tfmdata.fonts = vfdata.fonts
end
- tfmdata.fonts = fnts
end
end
---~ end
+ fonts.tfm.enhance(tfmdata,specification)
end
else
if fonts.trace then
@@ -123,13 +144,13 @@ function fonts.tfm.scale(tfmtable, scaledpoints)
local tc = t.characters
for k,v in pairs(tfmtable.characters) do
local chr = {
- unicode = v.unicode,
- name = v.name,
- index = v.index or k,
- width = scale(v.width , delta),
- height = scale(v.height, delta),
- depth = scale(v.depth , delta),
- class = v.class
+ unicode = v.unicode,
+ name = v.name,
+ index = v.index or k,
+ width = scale(v.width , delta),
+ height = scale(v.height, delta),
+ depth = scale(v.depth , delta),
+ class = v.class
}
local b = v.boundingbox -- maybe faster to have llx etc not in table
if b then
@@ -158,13 +179,15 @@ function fonts.tfm.scale(tfmtable, scaledpoints)
tp[k] = scale(v,delta)
end
end
---~ t.encodingbytes = tfmtable.encodingbytes or 2
+--~ t.encodingbytes = tfmtable.encodingbytes or 1
+--~ t.filename = t.filename or tfmtable.filename or tfmtable.file or nil
+--~ t.fullname = t.fullname or tfmtable.fullname or tfmtable.full or nil
+--~ t.name = t.name or tfmtable.name or nil
t.size = scaledpoints
t.italicangle = tfmtable.italicangle
t.ascender = scale(tfmtable.ascender or 0,delta)
t.descender = scale(tfmtable.descender or 0,delta)
- -- new / some data will move here
- t.shared = tfmtable.shared or { }
+ t.shared = tfmtable.shared or { }
if t.unique then
t.unique = table.fastcopy(tfmtable.unique)
else
@@ -180,8 +203,11 @@ we now have several readers it may be handy to know what reader is
used for which font.</p>
--ldx]]--
-function fonts.logger.save(tfmtable,source,specification)
+function fonts.logger.save(tfmtable,source,specification) -- save file name in spec here ! ! ! ! ! !
if tfmtable and specification and specification.specification then
+ if fonts.trace then
+ logs.report("define font",string.format("registering %s as %s",specification.name,source))
+ end
specification.source = source
fonts.loaded[specification.specification] = specification
fonts.used[specification.name] = source
diff --git a/tex/context/base/l-aux.lua b/tex/context/base/l-aux.lua
index 59ff42539..f5aa7e67e 100644
--- a/tex/context/base/l-aux.lua
+++ b/tex/context/base/l-aux.lua
@@ -10,7 +10,7 @@ do
hash = { }
- function set(key,value)
+ local function set(key,value)
hash[key] = value
end
@@ -34,6 +34,50 @@ do
return hash
end
+ local pattern = lpeg.Ct((space * value * comma)^1)
+
+ function aux.settings_to_array(str)
+ return lpeg.match(pattern,str)
+ end
+
+end
+
+--~ do
+--~ str = "a=1, b=2, c=3, d={abc}"
+
+--~ for k,v in pairs(aux.settings_to_hash (str)) do print(k,v) end
+--~ for k,v in pairs(aux.settings_to_array(str)) do print(k,v) end
+--~ end
+
+function aux.hash_to_string(h,separator,yes,no,strict)
+ if h then
+ local t = { }
+ for _,k in ipairs(table.sortedkeys(h)) do
+ local v = h[k]
+ if type(v) == "boolean" then
+ if yes and no then
+ if v then
+ t[#t+1] = k .. '=' .. yes
+ elseif not strict then
+ t[#t+1] = k .. '=' .. no
+ end
+ elseif v or not strict then
+ t[#t+1] = k .. '=' .. tostring(v)
+ end
+ else
+ t[#t+1] = k .. '=' .. v
+ end
+ end
+ return table.concat(t,separator or ",")
+ else
+ return ""
+ end
end
---~ print(table.serialize(aux.settings_to_hash("aaa=bbb, ccc={d,d,d}")))
+function aux.array_to_string(a,separator)
+ if a then
+ return table.concat(a,separator or ",")
+ else
+ return ""
+ end
+end
diff --git a/tex/context/base/l-boolean.lua b/tex/context/base/l-boolean.lua
index 128e1d069..e1efa4ad4 100644
--- a/tex/context/base/l-boolean.lua
+++ b/tex/context/base/l-boolean.lua
@@ -16,6 +16,8 @@ function toboolean(str)
return str == "true" or str == "yes" or str == "on" or str == "1"
elseif type(str) == "number" then
return tonumber(str) ~= 0
+ elseif type(str) == "nil" then
+ return false
else
return str
end
diff --git a/tex/context/base/l-file.lua b/tex/context/base/l-file.lua
index 67bf44b5a..496346b33 100644
--- a/tex/context/base/l-file.lua
+++ b/tex/context/base/l-file.lua
@@ -101,7 +101,7 @@ end
--~ print("a/a" .. " == " .. file.collapse_path("a/b/c/../../a"))
function file.collapse_path(str)
- local ok = false
+ local ok, n = false, 0
while not ok do
ok = true
str, n = str:gsub("[^%./]+/%.%./", function(s)
diff --git a/tex/context/base/l-string.lua b/tex/context/base/l-string.lua
index 9b594ff8a..9940de9b2 100644
--- a/tex/context/base/l-string.lua
+++ b/tex/context/base/l-string.lua
@@ -305,3 +305,15 @@ end
--~ print(is_number("+0.1"))
--~ print(is_number("-.1"))
--~ print(is_number("+.1"))
+
+function string:split_settings() -- no {} handling, see l-aux for lpeg variant
+ if self:find("=") then
+ local t = { }
+ for k,v in self:gmatch("(%a+)=([^%,]*)") do
+ t[k] = v
+ end
+ return t
+ else
+ return nil
+ end
+end
diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua
index 79d87139b..f68e29d23 100644
--- a/tex/context/base/l-table.lua
+++ b/tex/context/base/l-table.lua
@@ -65,6 +65,24 @@ function table.prepend(t, list)
end
end
+function table.merge(t, ...)
+ for _, list in ipairs({...}) do
+ for k,v in pairs(list) do
+ t[k] = v
+ end
+ end
+end
+
+function table.merged(...)
+ local tmp = { }
+ for _, list in ipairs({...}) do
+ for k,v in pairs(list) do
+ tmp[k] = v
+ end
+ end
+ return tmp
+end
+
if not table.fastcopy then
function table.fastcopy(old) -- fast one
@@ -486,6 +504,24 @@ function table.are_equal(a,b,n,m)
end
end
+function table.compact(t)
+ if t then
+ for k,v in pairs(t) do
+ if not next(v) then
+ t[k] = nil
+ end
+ end
+ end
+end
+
+function table.tohash(t)
+ local h = { }
+ for _, v in pairs(t) do -- no ipairs here
+ h[v] = true
+ end
+ return h
+end
+
--~ function table.are_equal(a,b)
--~ return table.serialize(a) == table.serialize(b)
--~ end
diff --git a/tex/context/base/l-tex.lua b/tex/context/base/l-tex.lua
index 3d87fe6e3..89925f602 100644
--- a/tex/context/base/l-tex.lua
+++ b/tex/context/base/l-tex.lua
@@ -89,7 +89,7 @@ end
if lua then do
- delayed = { } -- could also be done with closures
+ local delayed = { } -- could also be done with closures
function lua.delay(f)
delayed[#delayed+1] = f
diff --git a/tex/context/base/l-utils.lua b/tex/context/base/l-utils.lua
index 02efebe08..c4676a83d 100644
--- a/tex/context/base/l-utils.lua
+++ b/tex/context/base/l-utils.lua
@@ -113,10 +113,15 @@ function utils.merger.selfclean(name)
)
end
+utils.lua.compile_strip = true
+
function utils.lua.compile(luafile, lucfile)
-- utils.report("compiling",luafile,"into",lucfile)
os.remove(lucfile)
- local command = "-s -o " .. string.quote(lucfile) .. " " .. string.quote(luafile)
+ local command = "-o " .. string.quote(lucfile) .. " " .. string.quote(luafile)
+ if utils.lua.compile_strip then
+ command = "-s " .. command
+ end
if os.execute("texluac " .. command) == 0 then
return true
elseif os.execute("luac " .. command) == 0 then
diff --git a/tex/context/base/l-xml.lua b/tex/context/base/l-xml.lua
new file mode 100644
index 000000000..b60f521d2
--- /dev/null
+++ b/tex/context/base/l-xml.lua
@@ -0,0 +1,887 @@
+if not modules then modules = { } end modules ['l-xml'] = {
+ version = 1.001,
+ comment = "this module is the basis for the lxml-* ones",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Tthe parser used here is inspired by the variant discussed in the lua book, but
+handles comment and processing instructions, has a different structure, provides
+parent access; a first version used different tricky but was less optimized to we
+went this route.</p>
+
+<p>Expecially the lpath code is experimental, we will support some of xpath, but
+only things that make sense for us; as compensation it is possible to hook in your
+own functions. Apart from preprocessing content for <l n='context'/> we also need
+this module for process management, like handling <l n='ctx'/> and <l n='rlx'/>
+files.</p>
+
+<typing>
+a/b/c /*/c (todo: a/b/(pattern)/d)
+a/b/c/first() a/b/c/last() a/b/c/index(n) a/b/c/index(-n)
+a/b/c/text() a/b/c/text(1) a/b/c/text(-1) a/b/c/text(n)
+</typing>
+
+<p>Beware, the interface may change. For instance at, ns, tg, dt may get more
+verbose names. Once the code is stable we will also removee some tracing and
+optimize the code.</p>
+--ldx]]--
+
+xml = xml or { }
+tex = tex or { }
+
+do
+
+ -- The dreadful doctype comes in many disguises:
+ --
+ -- <!DOCTYPE Something PUBLIC "... ..." "..." [ ... ] >
+ -- <!DOCTYPE Something PUBLIC "... ..." "..." >
+ -- <!DOCTYPE Something SYSTEM "... ..." [ ... ] >
+ -- <!DOCTYPE Something SYSTEM "... ..." >
+ -- <!DOCTYPE Something [ ... ] >
+ -- <!DOCTYPE Something >
+
+ local doctype_patterns = {
+ "<!DOCTYPE%s+(.-%s+PUBLIC%s+%b\"\"%s+%b\"\"%s+%b[])%s*>",
+ "<!DOCTYPE%s+(.-%s+PUBLIC%s+%b\"\"%s+%b\"\")%s*>",
+ "<!DOCTYPE%s+(.-%s+SYSTEM%s+%b\"\"%s+%b[])%s*>",
+ "<!DOCTYPE%s+(.-%s+SYSTEM%s+%b\"\")%s*>",
+ "<!DOCTYPE%s+(.-%s%b[])%s*>",
+ "<!DOCTYPE%s+(.-)%s*>"
+ }
+
+ -- We assume no "<" which is the lunatic part of the xml spec
+ -- especially since ">" is permitted; otherwise we need a char
+ -- by char parser ... more something for later ... normally
+ -- entities will be used anyway.
+
+ local function prepare(data) -- todo: option to delete doctype stuff, comment, etc
+ -- pack (for backward compatibility)
+ if type(data) == "table" then
+ data = table.concat(data,"")
+ end
+ -- CDATA
+ data = data:gsub("<%!%[CDATA%[(.-)%]%]>", function(txt)
+ return string.format("<@cd@>%s</@cd@>",txt:to_hex())
+ end)
+ -- DOCTYPE
+ data = data:gsub("^(.-)(<[^%!%?])", function(a,b)
+ if a:find("<!DOCTYPE ") then
+ for _,v in ipairs(doctype_patterns) do
+ a = a:gsub(v, function(d) return string.format("<@dd@>%s</@dd@>",d:to_hex()) end)
+ end
+ end
+ return a .. b
+ end,1)
+ -- comment / does not catch doctype
+ data = data:gsub("<%!%-%-(.-)%-%->", function(txt)
+ return string.format("<@cm@>%s</@cm@>",txt:to_hex())
+ end)
+ -- processing instructions
+ data = data:gsub("<%?(.-)%?>", function(txt)
+ return string.format("<@pi@>%s</@pi@>",txt:to_hex())
+ end)
+ return data
+ end
+
+ local function split(s)
+ local t = {}
+ for namespace, tag, _,val in s:gmatch("(%w-):?(%w+)=([\"\'])(.-)%3") do
+ if namespace == "" then
+ t[tag] = val
+ else
+ t[tag] = val
+ end
+ end
+ return t
+ end
+
+ function xml.convert(data,no_root,collapse)
+ local data = prepare(data)
+ local stack, top = {}, {}
+ local i, j, errorstr = 1, 1, nil
+ stack[#stack+1] = top
+ top.dt = { }
+ local dt = top.dt
+ while true do
+ local ni, first, attributes, last, fulltag
+ ni, j, first, fulltag, attributes, last = data:find("<(/-)([^%s%>/]+)%s*([^>]-)%s*(/-)>", j)
+ if not ni then break end
+ local namespace, tag = fulltag:match("^(.-):(.+)$")
+ if not tag then
+ namespace, tag = "", fulltag
+ end
+ local text = data:sub(i, ni-1)
+ if (text == "") or (collapse and text:find("^%s*$")) then
+ -- no need for empty text nodes, beware, also packs <a>x y z</a>
+ -- so is not that useful unless used with empty elements
+ else
+ dt[#dt+1] = text
+ end
+ if first == "/" then
+ -- end tag
+ local toclose = table.remove(stack) -- remove top
+ top = stack[#stack]
+ if #stack < 1 then
+ errorstr = "nothing to close with " .. tag
+ break
+ end
+ if toclose.tg ~= tag then
+ errorstr = "unable to close " .. toclose.tg .. " with " .. tag
+ break
+ end
+ dt= top.dt
+ dt[#dt+1] = toclose
+ elseif last == "/" then
+ -- empty element tag
+ if attributes == "" then
+ dt[#dt+1] = { ns=namespace, tg=tag }
+ else
+ dt[#dt+1] = { ns=namespace, tg=tag, at=split(attributes) }
+ end
+ setmetatable(top, { __tostring = xml.text } )
+ dt[#dt].__p__ = top
+ else
+ -- begin tag
+ if attributes == "" then
+ top = { ns=namespace, tg=tag, dt = { } }
+ else
+ top = { ns=namespace, tg=tag, at=split(attributes), dt = { } }
+ end
+ top.__p__ = stack[#stack]
+ setmetatable(top, { __tostring = xml.text } )
+ dt = top.dt
+ stack[#stack+1] = top
+ end
+ i = j + 1
+ end
+ if not errorstr then
+ local text = data:sub(i)
+ if dt and not text:find("^%s*$") then
+ dt[#dt+1] = text
+ end
+ if #stack > 1 then
+ errorstr = "unclosed " .. stack[#stack].tg
+ end
+ end
+ if errorstr then
+ -- stack = { [1] = { tg = "error", dt = { [1] = errorstr } } }
+ stack = { { tg = "error", dt = { errorstr } } }
+ setmetatable(stack, { __tostring = xml.text } )
+ end
+ if no_root then
+ return stack[1]
+ else
+ local t = { tg = '@rt@', dt = stack[1].dt }
+ setmetatable(t, { __tostring = xml.text } )
+ return t
+ end
+ end
+
+end
+
+function xml.load(filename,collapse)
+ if type(filename) == "string" then
+ local root, f = { }, io.open(filename,'r') -- no longer 'rb'
+ if f then
+ root = xml.convert(f:read("*all"),false,collapse)
+ f:close()
+ end
+ return root
+ else
+ return xml.convert(filename:read("*all"),false,collapse)
+ end
+end
+
+function xml.toxml(data,collapse)
+ local t = { xml.convert(data,true,collapse) }
+ if #t > 1 then
+ return t
+ else
+ return t[1]
+ end
+end
+
+function xml.serialize(e, handle, textconverter, attributeconverter) -- check if string:format is faster
+ local format = string.format
+ handle = handle or (tex and tex.sprint) or io.write
+ local function flush(before,e,after)
+ handle(before)
+ for _,ee in ipairs(e.dt) do -- i added, todo iloop
+ xml.serialize(ee,handle,string.from_hex)
+ end
+ handle(after)
+ end
+ if e then
+ if e.tg then
+ if e.tg == "@pi@" then
+ flush("<?",e,"?>")
+ elseif e.tg == "@cm@" then
+ flush("<!--",e,"-->")
+ elseif e.tg == "@cd@" then
+ flush("<![CDATA[",e,"]]>")
+ elseif e.tg == "@dd@" then
+ flush("<!DOCTYPE ",e,">")
+ elseif e.tg == "@rt@" then
+ xml.serialize(e.dt,handle,textconverter,attributeconverter)
+ else
+ if e.ns ~= "" then
+ handle(format("<%s:%s",e.ns,e.tg))
+ else
+ handle(format("<%s",e.tg))
+ end
+ if e.at then
+ if attributeconverter then
+ for k,v in pairs(e.at) do
+ handle(format(' %s=%q',k,attributeconverter(v)))
+ end
+ else
+ for k,v in pairs(e.at) do
+ handle(format(' %s=%q',k,v))
+ end
+ end
+ end
+ if e.dt then
+ handle(">")
+ for k,ee in ipairs(e.dt) do -- i added, for i=1,n is faster
+ xml.serialize(ee,handle,textconverter,attributeconverter)
+ end
+ handle(format("</%s>",e.tg))
+ else
+ handle("/>")
+ end
+ end
+ elseif type(e) == "string" then
+ if textconverter then
+ handle(textconverter(e))
+ else
+ handle(e)
+ end
+ else
+ for _,ee in ipairs(e) do -- i added
+ xml.serialize(ee,handle,textconverter,attributeconverter)
+ end
+ end
+ end
+end
+
+function xml.string(e,handle)
+ if e.tg then
+ if e.dt then
+ for _,ee in ipairs(e.dt) do -- i added
+ xml.string(ee,handle)
+ end
+ end
+ else
+ handle(e)
+ end
+end
+
+function xml.save(root,name)
+ local f = io.open(name,"w")
+ if f then
+ xml.serialize(root,function(s) f:write(s) end)
+ f:close()
+ end
+end
+
+function xml.stringify(root)
+ local result = { }
+ xml.serialize(root,function(s) result[#result+1] = s end)
+ return table.concat(result,"")
+end
+
+xml.tostring = xml.stringify
+
+function xml.stringify_text(root) -- no root element
+ if root and root.dt then
+ return xml.stringify(root)
+ else
+ return ""
+ end
+end
+
+function xml.text(dt) -- no root element
+ if dt then
+ return xml.stringify(dt)
+ else
+ return ""
+ end
+end
+
+function xml.body(t) -- removes initial pi
+ if t and t.dt and t.tg == "@rt@" then
+ for k,v in ipairs(t.dt) do
+ if type(v) == "table" and v.tg ~= "@pi@" then
+ return v
+ end
+ end
+ end
+ return t
+end
+
+-- call: e[k] = xml.empty() or xml.empty(e,k)
+
+function xml.empty(e,k) -- erases an element but keeps the table intact
+ if e and k then
+ e[k] = ""
+ return e[k]
+ else
+ return ""
+ end
+end
+
+-- call: e[k] = xml.assign(t) or xml.assign(e,k,t)
+
+function xml.assign(e,k,t) -- assigns xml tree / more testing will be done
+ if e and k then
+ if type(t) == "table" then
+ e[k] = xml.body(t)
+ else
+ e[k] = t -- no parsing
+ end
+ return e[k]
+ else
+ return xml.body(t)
+ end
+end
+
+-- 0=nomatch 1=match 2=wildcard 3=ancestor
+
+-- "tag"
+-- "tag1/tag2/tag3"
+-- "*/tag1/tag2/tag3"
+-- "/tag1/tag2/tag3"
+-- "/tag1/tag2|tag3"
+-- "tag[@att='value']
+-- "tag1|tag2[@att='value']
+
+xml.trace_lpath = false
+
+function xml.tag(e)
+ return e.tg or ""
+end
+
+function xml.att(e,a)
+ return (e.at and e.at[a]) or ""
+end
+
+xml.attribute = xml.att
+
+do
+
+ local cache = { }
+
+ local function fault ( ) return 0 end
+ local function wildcard( ) return 2 end
+ local function result (b) if b then return 1 else return 0 end end
+
+ -- we can avoid functions: m[i] = number|function
+
+ function xml.lpath(str) --maybe @rt@ special
+ str = str or "*"
+ local m = cache[str]
+ if not m then
+ -- todo: text()
+ if not str then
+ if xml.trace_lpath then print("lpath", "no string", "wildcard") end
+ m = {
+ function(e)
+ if xml.trace_lpath then print(2, 1, "wildcard", e.tg) end
+ return 2
+ end
+ }
+ elseif type(str) == "table" then
+ if xml.trace_lpath then print("lpath", "table" , "inherit") end
+ m = str
+ else
+ if str == "" or str == "*" then
+ if xml.trace_lpath then print("lpath", "empty or *", "wildcard") end
+ m = {
+ function(e)
+ if xml.trace_lpath then print(2, 2, "wildcard", e.tg) end
+ return 2
+ end
+ }
+ else
+ m = { }
+ if str:find("^/") then
+ -- done in split
+ else
+ if xml.trace_lpath then print("lpath", "/", "wildcard") end
+ m[#m+1] = function(e,i)
+ if xml.trace_lpath then print(2, 3, "wildcard", e.tg) end
+ return 2
+ end
+ end
+ for v in str:gmatch("([^/]+)") do
+ if v == "" or v == "*" then
+ if #m > 0 then -- when not, then we get problems with root being second (after <?xml ...?> (we could start at dt[2])
+ if xml.trace_lpath then print("lpath", "empty or *", "wildcard") end
+ m[#m+1] = function(e,i)
+ if xml.trace_lpath then print(2, 4, "wildcard", e.ns, e.tg) end
+ return 2
+ end
+ end
+ elseif v == ".." then
+ if xml.trace_lpath then print("lpath", "..", "ancestor") end
+ m[#m+1] = function(e,i)
+ if xml.trace_lpath then print(3, 5, "ancestor", e.__p__.tg) end
+ return 3
+ end
+ else
+ local n, a, t = v:match("^(.-)%[@(.-)=(.-)%]$")
+ if n and a and t then
+ local s = ""
+ local ns, tg = n:match("^(.-):(.+)$")
+ if tg then
+ s, n = ns, tg
+ end
+ -- t = t:gsub("^([\'\"])([^%1]*)%1$", "%2") -- todo
+ t = t:gsub("^\'(.*)\'$", "%1") -- todo
+ t = t:gsub("^\"(.*)\"$", "%1") -- todo
+ if v:find("|") then
+ -- todo: ns ! ! ! ! ! ! ! ! !
+ local tt = n:split("|")
+ if xml.trace_lpath then print("lpath", "match", t, n) end
+ m[#m+1] = function(e,i)
+ for _,v in ipairs(tt) do -- i added, todo: iloop
+ if e.at and e.tg == v and e.at[a] == t then
+ if xml.trace_lpath then print(1, 6, "element ", v, "attribute", t) end
+ return 1
+ end
+ end
+ if xml.trace_lpath then print(1, 6, "no match") end
+ return 0
+ end
+ else
+ if xml.trace_lpath then print("lpath", "match", t, n) end
+ m[#m+1] = function(e,i)
+ if e.at and e.ns == s and e.tg == n and e.at[a] == t then
+ if xml.trace_lpath then print(1, 7, "element ", n, "attribute", t) end
+ return 1
+ else
+ if xml.trace_lpath then print(1, 7, "no match") end
+ return 0
+ end
+ end
+ end
+ elseif v:find("|") then
+ local tt = v:split("|")
+ for k,v in ipairs(tt) do -- i added, iloop is faster
+ if xml.trace_lpath then print("lpath", "or match", v) end
+ local ns, tg = v:match("^(.-):(.+)$")
+ if not tg then
+ ns, tg = "", v
+ end
+ tt[k] = function(e,i)
+ if ns == e.ns and tg == e.tg then
+ if xml.trace_lpath then print(1, 8, "element ", ns, tg) end
+ return 1
+ else
+ if xml.trace_lpath then print(1, 8, "no match", ns, tg) end
+ return 0
+ end
+ end
+ end
+ m[#m+1] = function(e,i)
+ for _,v in ipairs(tt) do -- i added, iloop is faster
+ if v(e,i) then
+ return 1
+ end
+ end
+ return 0
+ end
+ else
+ if xml.trace_lpath then print("lpath", "match", v) end
+ local ns, tg = v:match("^(.-):(.+)$")
+ if not tg then
+ ns, tg = "", v
+ end
+ m[#m+1] = function(e,i)
+ if ns == e.ns and tg == e.tg then
+ if xml.trace_lpath then print(1, 9, "element ", ns, tg) end
+ return 1
+ else
+ if xml.trace_lpath then print(1, 9, "no match", ns, tg) end
+ return 0
+ end
+ end
+ end
+ end
+ end
+ end
+ if xml.trace_lpath then print("lpath", "result", str, "size", #m) end
+ end
+ cache[str] = m
+ end
+ return m
+ end
+
+ function xml.traverse_tree(root,pattern,handle,reverse,index,wildcard)
+ if root and root.dt then
+ index = index or 1
+ local match = pattern[index] or wildcard
+--~ local prev = pattern[index-1] or fault -- better use the wildcard
+ local traverse = xml.traverse_tree
+ local rootdt = root.dt
+ local start, stop, step = 1, #rootdt, 1
+ if reverse and index == #pattern then
+ start, stop, step = stop, start, -1
+ end
+ for k=start,stop,step do
+ local e = rootdt[k]
+ if e.tg then
+ local m = (type(match) == "function" and match(e,index)) or match
+ if m == 1 then -- match
+ if index < #pattern then
+ if not traverse(e,pattern,handle,reverse,index+1) then return false end
+ elseif handle(rootdt,k) then
+ return false
+ end
+ elseif m == 2 then -- wildcard (not ok, now same as 3)
+ if index < #pattern then
+ if not traverse(e,pattern,handle,reverse,index+1,true) then return false end
+ elseif handle(rootdt,k) then
+ return false
+ end
+ elseif m == 3 then -- ancestor
+ local ep = e.__p__
+ if index < #pattern then
+ if not traverse(ep,pattern,handle,reverse,index+1) then return false end
+ elseif handle(rootdt,k) then
+ return false
+ end
+--~ elseif prev(e,index) == 2 then -- wildcard
+--~ if not traverse(e,pattern,handle,reverse,index) then return false end
+ elseif wildcard then -- maybe two kind of wildcards: * ** //
+ if not traverse(e,pattern,handle,reverse,index,wildcard) then return false end
+ end
+ else
+ local edt = e.dt
+ if edt then
+ -- todo ancester
+ for kk=1,#edt do
+ local ee = edt[kk]
+ if match(ee,index) > 0 then
+ if index < #pattern then
+ if not traverse(ee,pattern,handle,reverse,index+1) then return false end
+ elseif handle(rootdt,k) then
+--~ elseif handle(edt,kk) then
+ return false
+ end
+ elseif prev(ee) == 2 then
+ if not traverse(ee,pattern,handle,reverse,index) then return false end
+ end
+ end
+ end
+ end
+ end
+ end
+ return true
+ end
+
+ local traverse, lpath, convert = xml.traverse_tree, xml.lpath, xml.convert
+
+ xml.filters = { }
+
+ function xml.filters.default(root,pattern)
+ local ee, kk
+ traverse(root, lpath(pattern), function(e,k) ee,kk = e,k return true end)
+ return ee and ee[kk], ee, kk
+ end
+ function xml.filters.reverse(root,pattern)
+ local ee, kk
+ traverse(root, lpath(pattern), function(e,k) ee,kk = e,k return true end,'reverse')
+ return ee and ee[kk], ee, kk
+ end
+ function xml.filters.count(root, pattern)
+ local n = 0
+ traverse(root, lpath(pattern), function(e,k) n = n + 1 end)
+ return n
+ end
+ function xml.filters.first(root,pattern)
+ local ee, kk
+ traverse(root, lpath(pattern), function(e,k) ee,kk = e,k return true end)
+ return ee and ee[kk], ee, kk
+ end
+ function xml.filters.last(root,pattern)
+ local ee, kk
+ traverse(root, lpath(pattern), function(e,k) ee,kk = e,k return true end, 'reverse')
+ return ee and ee[kk], ee, kk
+ end
+ function xml.filters.index(root,pattern,arguments)
+ local ee, kk, reverse, i = nil, ni, false, tonumber(arguments or '1') or 1
+ if i and i ~= 0 then
+ if i < 0 then
+ reverse, i = true, -i
+ end
+ traverse(root, lpath(pattern), function(e,k) ee, kk, i = e, k , i-1 return i == 0 end, reverse)
+ if i > 0 then
+ return nil, nil, nil
+ else
+ return ee and ee[kk], ee, kk
+ end
+ else
+ return nil, nil, nil
+ end
+ end
+ function xml.filters.attributes(root,pattern,arguments)
+ local ee, kk
+ traverse(root, lpath(pattern), function(e,k) ee,kk = e,k return true end)
+ local ekat = ee and ee[kk] and ee[kk].at
+ if ekat then
+ if arguments then
+ return ekat[arguments] or "", ee, kk
+ else
+ return ekat, ee, kk
+ end
+ else
+ return {}, ee, kk
+ end
+ end
+ function xml.filters.text(root,pattern,arguments)
+ local ek, ee, kk = xml.filters.index(root,pattern,arguments)
+ return (ek and ek.dt and ek.dt[1]) or ""
+ end
+
+ function xml.filter(root,pattern)
+ local pat, fun, arg = pattern:match("^(.+)/(.-)%((.*)%)$")
+ if fun then
+ return (xml.filters[fun] or xml.filters.default)(root,pat,arg)
+ else
+ pat, arg = pattern:match("^(.+)/@(.-)$")
+ if arg then
+ return xml.filters.attributes(root,pat,arg)
+ else
+ return xml.filters.default(root,pattern)
+ end
+ end
+ end
+
+ xml.filters.position = xml.filters.index
+
+ -- these may go away
+
+ xml.index_element = xml.filters.index
+ xml.count_elements = xml.filters.count
+ xml.first_element = xml.filters.first
+ xml.last_element = xml.filters.last
+ xml.index_text = xml.filters.text
+ xml.first_text = function (root,pattern) return xml.filters.text(root,pattern, 1) end
+ xml.last_text = function (root,pattern) return xml.filters.text(root,pattern,-1) end
+
+ -- so far
+
+ function xml.get_text(root,pattern,reverse)
+ local ek
+ traverse(root, lpath(pattern), function(e,k) ek = e and e[k] end, reverse)
+ return (ek and ek.dt and ek.dt[1]) or ""
+ end
+
+ function xml.each_element(root, pattern, handle, reverse)
+ local ok
+ traverse(root, lpath(pattern), function(e,k) ok = true handle(e[k],e,k) end, reverse)
+ return ok
+ end
+
+ function xml.get_element(root,pattern,reverse)
+ local ee, kk
+ traverse(root, lpath(pattern), function(e,k) ee,kk = e,k end, reverse)
+ return ee and ee[kk], ee, kk
+ end
+
+ function xml.all_elements(root, pattern, handle, reverse)
+ local t = { }
+ traverse(root, lpath(pattern), function(e,k) t[#t+1] = e[k] end)
+ return t
+ end
+
+ function xml.all_texts(root, pattern, handle, reverse)
+ local t = { }
+ traverse(root, lpath(pattern), function(e,k)
+ local ek = e[k]
+ t[#t+1] = (ek and ek.dt and ek.dt[1]) or ""
+ end)
+ return t
+ end
+
+ -- array for each
+
+ function xml.insert_element(root, pattern, element, before) -- todo: element als functie
+ if root and element then
+ local matches, collect = { }, nil
+ if type(element) == "string" then
+ element = convert(element,true)
+ end
+ if element and element.td == "@rt@" then
+ element = element.dt
+ end
+ if element then
+ if before then
+ collect = function(e,k) matches[#matches+1] = { e, element, k } end
+ else
+ collect = function(e,k) matches[#matches+1] = { e, element, k + 1 } end
+ end
+ traverse(root, lpath(pattern), collect)
+ for i=#matches,1,-1 do
+ local m = matches[i]
+ local t, element, at = m[1],m[2],m[3]
+ -- when string, then element is { dt = { ... }, { ... } }
+ if element.tg then
+ table.insert(t,at,element) -- untested
+ elseif element.dt then
+ for _,v in ipairs(element.dt) do -- i added
+ table.insert(t,at,v)
+ at = at + 1
+ end
+ end
+ end
+ end
+ end
+ end
+
+ -- first, last, each
+
+ xml.insert_element_after = xml.insert_element
+ xml.insert_element_before = function(r,p,e) xml.insert_element(r,p,e,true) end
+
+ function xml.delete_element(root, pattern)
+ local matches, deleted = { }, { }
+ local collect = function(e,k) matches[#matches+1] = { e, k } end
+ traverse(root, lpath(pattern), collect)
+ for i=#matches,1,-1 do
+ local m = matches[i]
+ deleted[#deleted+1] = table.remove(m[1],m[2])
+ end
+ return deleted
+ end
+
+ function xml.replace_element(root, pattern, element)
+ if type(element) == "string" then
+ element = convert(element,true)
+ end
+ if element and element.td == "@rt@" then
+ element = element.dt
+ end
+ if element then
+ local collect = function(e,k)
+ e[k] = element.dt -- maybe not clever enough
+ end
+ traverse(root, lpath(pattern), collect)
+ end
+ end
+
+ function xml.process(root, pattern, handle)
+ traverse(root, lpath(pattern), function(e,k)
+ if e[k].dt then
+ for k,v in ipairs(e[k].dt) do if v.tg then handle(v) end end -- i added
+ end
+ end)
+ end
+
+ -- function xml.process_attributes(root, pattern, handle)
+ -- traverse(root, lpath(pattern), function(e,k) handle(e[k].at) end)
+ -- end
+
+ function xml.process_attributes(root, pattern, handle)
+ traverse(root, lpath(pattern), function(e,k)
+ local ek = e[k]
+ local a = ek.at or { }
+ handle(a)
+ if next(a) then
+ ek.at = a
+ else
+ ek.at = nil
+ end
+ end)
+ end
+
+ function xml.package(tag,attributes,data)
+ local n, t = tag:match("^(.-):(.+)$")
+ if attributes then
+ return { ns = n or "", tg = t or tag, dt = data or "", at = attributes }
+ else
+ return { ns = n or "", tg = t or tag, dt = data or "" }
+ end
+ end
+
+ -- some special functions, handy for the manual:
+
+ function xml.gsub(t,old,new)
+ if t.dt then
+ for k,v in ipairs(t.dt) do
+ if type(v) == "string" then
+ t.dt[k] = v:gsub(old,new)
+ else
+ xml.gsub(v,old,new)
+ end
+ end
+ end
+ end
+
+ function xml.strip_leading_spaces(ek, e, k) -- cosmetic, for manual
+ if e and k and e[k-1] and type(e[k-1]) == "string" then
+ local s = e[k-1]:match("\n(%s+)")
+ xml.gsub(ek,"\n"..string.rep(" ",#s),"\n")
+ end
+ end
+
+ function xml.serialize_path(root,lpath,handle)
+ local ek, e, k = xml.first_element(root,lpath)
+ ek = table.copy(ek)
+ xml.strip_leading_spaces(ek,e,k)
+ xml.serialize(ek,handle)
+ end
+
+end
+
+xml.count = xml.filters.count
+xml.index = xml.filters.index
+xml.first = xml.filters.first
+xml.last = xml.filters.last
+
+xml.each = xml.each_element
+xml.all = xml.all_elements
+
+xml.insert = xml.insert_element_after
+xml.after = xml.insert_element_after
+xml.before = xml.insert_element_before
+xml.delete = xml.delete_element
+xml.replace = xml.replace_element
+
+-- a few helpers, the may move to lxml modules
+
+function xml.include(xmldata,element,attribute,pathlist,collapse)
+ element = element or 'ctx:include'
+ attribute = attribute or 'name'
+ pathlist = pathlist or { '.' }
+ local function include(ek,e,k)
+ local name = (ek.at and ek.at[attribute]) or ""
+ if name ~= "" then
+ -- maybe file lookup in tree
+ local fullname
+ for _, path in ipairs(pathlist) do
+ if path == '.' then
+ fullname = name
+ else
+ fullname = file.join(path,name)
+ end
+ local f = io.open(fullname)
+ if f then
+ xml.assign(e,k,xml.load(f,collapse))
+ f:close()
+ break
+ else
+ xml.empty(e,k)
+ end
+ end
+ else
+ xml.empty(e,k)
+ end
+ end
+ while xml.each(xmldata, element, include) do end
+end
+
diff --git a/tex/context/base/lang-ini.lua b/tex/context/base/lang-ini.lua
index 5259a085e..aa00a8fd1 100644
--- a/tex/context/base/lang-ini.lua
+++ b/tex/context/base/lang-ini.lua
@@ -108,7 +108,7 @@ do
local bynode = node.traverse
local bychar = string.utfcharacters
- function reconstruct(prev,str,fnt)
+ local function reconstruct(prev,str,fnt)
local done = false
if #str < 4 then
-- too short
diff --git a/tex/context/base/lang-sla.mkiv b/tex/context/base/lang-sla.mkiv
index dfa56bab5..479012615 100644
--- a/tex/context/base/lang-sla.mkiv
+++ b/tex/context/base/lang-sla.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\def\sloveniancharacters#1{\ctxlua{convert.alphabetic(\number#1,"sl")}}
-\def\slovenianCharacters#1{\ctxlua{convert.Alphabetic(\number#1,"sl")}}
+\def\sloveniancharacters#1{\ctxlua{converters.alphabetic(\number#1,"sl")}}
+\def\slovenianCharacters#1{\ctxlua{converters.Alphabetic(\number#1,"sl")}}
\endinput
diff --git a/tex/context/base/luat-cbk.lua b/tex/context/base/luat-cbk.lua
index a6145ec3b..efb534d7d 100644
--- a/tex/context/base/luat-cbk.lua
+++ b/tex/context/base/luat-cbk.lua
@@ -104,7 +104,7 @@ do
garbagecollector.trace = false
garbagecollector.tune = false -- for the moment
- function report(format)
+ local function report(format)
if garbagecollector.trace then
-- texio.write_nl(string.format(format,level,status.luastate_bytes))
texio.write_nl(string.format(format,level,collectgarbage("count")))
diff --git a/tex/context/base/luat-crl.lua b/tex/context/base/luat-crl.lua
index 9d15b4896..129832765 100644
--- a/tex/context/base/luat-crl.lua
+++ b/tex/context/base/luat-crl.lua
@@ -4,10 +4,10 @@
-- copyright: PRAGMA ADE / ConTeXt Development Team
-- license : see context related readme files
-if not versions then versions = { } end versions['luat-crl'] = 1.001
-if not curl then curl = { } end
+if not versions then versions = { } end versions['luat-crl'] = 1.001
+if not curl then curl = { } end
-curl.cachepath = cache.setpath(texmf.instance,"curl")
+curl.cachepath = caches.setpath(texmf.instance,"curl")
curl.cached = { }
diff --git a/tex/context/base/luat-ini.lua b/tex/context/base/luat-ini.lua
index 022055e7f..e7757d51b 100644
--- a/tex/context/base/luat-ini.lua
+++ b/tex/context/base/luat-ini.lua
@@ -7,5 +7,20 @@ if not modules then modules = { } end modules ['luat-ini'] = {
}
--[[ldx--
-<p>We cannot load anything yet.</p>
+<p>We cannot load anything yet. However what we will do us reserve a fewtables.
+These can be used for runtime user data or third party modules and will not be
+cluttered by macro package code.</p>
+--ldx]]--
+
+userdata = userdata or { }
+thirddata = thirddata or { }
+document = document or { }
+
+--[[ldx--
+<p>Please create a namespace within these tables before using them!</p>
+
+<typing>
+userdata ['my.name'] = { }
+thirddata['tricks' ] = { }
+</typing>
--ldx]]--
diff --git a/tex/context/base/luat-ini.tex b/tex/context/base/luat-ini.tex
index 800950baf..3b0a61e62 100644
--- a/tex/context/base/luat-ini.tex
+++ b/tex/context/base/luat-ini.tex
@@ -41,27 +41,25 @@
%D A few more goodies:
-\def\dostartlua#1%
+\long\def\dostartlua#1%
{\begingroup
\obeylualines
- \directlua#1\iftrue{\else}\fi}
+ \dodostartlua{#1}}
-\def\dostoplua
- {\iffalse{\else}\fi
- \endgroup}
+\long\def\dodostartlua#1#2\stoplua
+ {\expanded{\endgroup\noexpand\directlua#1{#2}}}
-\def\dostartluacode#1%
+\long\def\dostartluacode#1%
{\begingroup
\obeylualines
\obeyluatokens
- \directlua#1\iftrue{\else}\fi}
+ \dodostartluacode{#1}}
-\def\dostopluacode % no unexpanded, else no } seen
- {\iffalse{\else}\fi
- \endgroup}
+\long\def\dodostartluacode#1#2\stopluacode
+ {\expanded{\endgroup\noexpand\directlua#1{#2}}}
-\def\startlua {\dostartlua \zerocount} \def\stoplua {\dostoplua}
-\def\startluacode{\dostartluacode\zerocount} \def\stopluacode {\dostopluacode}
+\def\startlua {\dostartlua \zerocount}
+\def\startluacode{\dostartluacode\zerocount}
%D Some delayed definitions:
diff --git a/tex/context/base/luat-inp.lua b/tex/context/base/luat-inp.lua
index 6551d1011..541bde5c3 100644
--- a/tex/context/base/luat-inp.lua
+++ b/tex/context/base/luat-inp.lua
@@ -72,6 +72,7 @@ input.formats['pfb'] = 'T1FONTS' input.suffixes['pfb'] = { 'pfb', 'pfa' }
input.formats['vf'] = 'VFFONTS' input.suffixes['vf'] = { 'vf' }
input.formats['fea'] = 'FONTFEATURES' input.suffixes['fea'] = { 'fea' }
+input.formats['cid'] = 'FONTCIDMAPS' input.suffixes['cid'] = { 'cid', 'cidmap' }
input.formats ['texmfscripts'] = 'TEXMFSCRIPTS' -- new
input.suffixes['texmfscripts'] = { 'rb', 'pl', 'py' } -- 'lua'
@@ -79,10 +80,10 @@ input.suffixes['texmfscripts'] = { 'rb', 'pl', 'py' } -- 'lua'
input.formats ['lua'] = 'LUAINPUTS' -- new
input.suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
--- here we catch a few new thingies
+-- here we catch a few new thingies (todo: add these paths to context.tmf)
function input.checkconfigdata(instance)
- function fix(varname,default)
+ local function fix(varname,default)
local proname = varname .. "." .. instance.progname or "crap"
if not instance.environment[proname] and not instance.variables[proname] == "" and not instance.environment[varname] and not instance.variables[varname] == "" then
instance.variables[varname] = default
@@ -90,6 +91,7 @@ function input.checkconfigdata(instance)
end
fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS")
fix("FONTFEATURES", ".;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
end
-- backward compatible ones
@@ -98,6 +100,8 @@ input.alternatives = { }
input.alternatives['map files'] = 'map'
input.alternatives['enc files'] = 'enc'
+input.alternatives['cid files'] = 'cid'
+input.alternatives['fea files'] = 'fea'
input.alternatives['opentype fonts'] = 'otf'
input.alternatives['truetype fonts'] = 'ttf'
input.alternatives['truetype collections'] = 'ttc'
@@ -609,8 +613,11 @@ function input.generators.tex(instance,specification)
full = spec
end
for name in directory(full) do
- if name == '.' or name == ".." then
- -- skip
+ if name:find("^%.") then
+ -- skip
+ elseif name:find("[%~%`%!%#%$%%%^%&%*%(%)%=%{%}%[%]%:%;\"\'%|%|%<%>%,%?\n\r\t]") then
+ -- texio.write_nl("skipping " .. name)
+ -- skip
else
mode = attributes(full..name,'mode')
if mode == "directory" then
@@ -1407,7 +1414,7 @@ function input.aux.find_file(instance,filename) -- todo : plugin (scanners, chec
pathname = pathname:gsub("([%-%.])","%%%1") -- this also influences
pathname = pathname:gsub("/+$", '/.*') -- later usage of pathname
pathname = pathname:gsub("//", '/.-/')
- expr = "^" .. pathname
+ local expr = "^" .. pathname
-- input.debug('?',expr)
for _, f in pairs(filelist) do
if f:find(expr) then
@@ -1529,7 +1536,8 @@ end
function input.find_given_files(instance,filename)
local bname, result = file.basename(filename), { }
for k, hash in ipairs(instance.hashes) do
- local blist = instance.files[hash.tag][bname]
+ local files = instance.files[hash.tag]
+ local blist = files[bname]
if not blist then
local rname = "remap:"..bname
blist = files[rname]
@@ -1596,9 +1604,11 @@ function input.find_wildcard_files(instance,filename) -- todo: remap:
if name:find("%*") then
for k, hash in ipairs(instance.hashes) do
for kk, hh in pairs(files[hash.tag]) do
- if (kk:lower()):find(name) then
- if doit(hh,kk,hash,allresults) then done = true end
- if done and not allresults then break end
+ if not kk:find("^remap:") then
+ if (kk:lower()):find(name) then
+ if doit(hh,kk,hash,allresults) then done = true end
+ if done and not allresults then break end
+ end
end
end
end
@@ -1812,7 +1822,7 @@ function input.validators.visibility.context(path, name)
path = path[1] or path -- some day a loop
return not (
path:find("latex") or
- path:find("doc") or
+-- path:find("doc") or
path:find("tex4ht") or
path:find("source") or
-- path:find("config") or
@@ -1869,17 +1879,49 @@ function input.with_files(instance,pattern,handle)
end
end
-function input.update_script(oldname,newname) -- oldname -> own.name, not per se a suffix
+--~ function input.update_script(oldname,newname) -- oldname -> own.name, not per se a suffix
+--~ newname = file.addsuffix(newname,"lua")
+--~ local newscript = input.clean_path(input.find_file(instance, newname))
+--~ local oldscript = input.clean_path(oldname)
+--~ input.report("old script", oldscript)
+--~ input.report("new script", newscript)
+--~ if oldscript ~= newscript and (oldscript:find(file.removesuffix(newname).."$") or oldscript:find(newname.."$")) then
+--~ local newdata = io.loaddata(newscript)
+--~ if newdata then
+--~ input.report("old script content replaced by new content")
+--~ io.savedata(oldscript,newdata)
+--~ end
+--~ end
+--~ end
+
+function input.update_script(instance,oldname,newname) -- oldname -> own.name, not per se a suffix
+ local scriptpath = "scripts/context/lua"
newname = file.addsuffix(newname,"lua")
- newscript = input.clean_path(input.find_file(instance, newname))
- oldscript = input.clean_path(oldname)
- input.report("old script", oldscript)
- input.report("new script", newscript)
- if oldscript ~= newscript and (oldscript:find(file.removesuffix(newname).."$") or oldscript:find(newname.."$")) then
- newdata = io.loaddata(newscript)
- if newdata then
- input.report("old script content replaced by new content")
- io.savedata(oldscript,newdata)
+ local oldscript = input.clean_path(oldname)
+ input.report("to be replaced old script", oldscript)
+ local newscripts = input.find_files(instance, newname) or { }
+ if #newscripts == 0 then
+ input.report("unable to locate new script")
+ else
+ for _, newscript in ipairs(newscripts) do
+ newscript = input.clean_path(newscript)
+ input.report("checking new script", newscript)
+ if oldscript == newscript then
+ input.report("old and new script are the same")
+ elseif not newscript:find(scriptpath) then
+ input.report("new script should come from",scriptpath)
+ elseif not (oldscript:find(file.removesuffix(newname).."$") or oldscript:find(newname.."$")) then
+ input.report("invalid new script name")
+ else
+ local newdata = io.loaddata(newscript)
+ if newdata then
+ input.report("old script content replaced by new content")
+ io.savedata(oldscript,newdata)
+ break
+ else
+ input.report("unable to load new script")
+ end
+ end
end
end
end
diff --git a/tex/context/base/luat-lib.tex b/tex/context/base/luat-lib.tex
index 6c5c63227..84b5bcfff 100644
--- a/tex/context/base/luat-lib.tex
+++ b/tex/context/base/luat-lib.tex
@@ -49,7 +49,7 @@
\registerctxluafile{l-utils} {1.001}
\registerctxluafile{l-tex} {1.001}
\registerctxluafile{l-xml} {1.001}
-\registerctxluafile{l-xmlctx} {1.001}
+%registerctxluafile{l-xmlctx} {1.001}
\registerctxluafile{luat-cbk} {1.001}
\registerctxluafile{luat-lib} {1.001}
diff --git a/tex/context/base/luat-tex.lua b/tex/context/base/luat-tex.lua
index 8e770f9de..1b2412594 100644
--- a/tex/context/base/luat-tex.lua
+++ b/tex/context/base/luat-tex.lua
@@ -60,7 +60,7 @@ if texconfig and not texlua then
t = {
utftype = u, -- may go away
lines = l,
- current = 0,
+ current = 0, -- line number, not really needed
handle = nil,
noflines = #l,
close = function()
@@ -68,15 +68,23 @@ if texconfig and not texlua then
input.show_close(filename)
end,
reader = function(self)
- if not self then self = t end
- if self.current >= #self.lines then
+ self = self or t
+ local current, lines = self.current, self.lines
+ if current >= #lines then
return nil
else
- self.current = self.current + 1
- if input.filters.utf_translator then
- return input.filters.utf_translator(self.lines[t.current])
+ self.current = current + 1
+ local line = lines[self.current]
+ if line == "" then
+ return ""
else
- return self.lines[self.current]
+ local translator = input.filters.utf_translator
+ -- return (translator and translator(line)) or line
+ if translator then
+ return translator(line)
+ else
+ return line
+ end
end
end
end
@@ -86,13 +94,15 @@ if texconfig and not texlua then
-- todo: file;name -> freeze / eerste regel scannen -> freeze
t = {
reader = function(self)
- if not self then self = t end -- not used
- if input.filters.dynamic_translator then
- return input.filters.dynamic_translator(file_handle:read())
+ local line = file_handle:read()
+ if line == "" then
+ return ""
elseif input.filters.utf_translator then
- return input.filters.utf_translator(file_handle:read())
+ return input.filters.utf_translator(line)
+ elseif input.filters.dynamic_translator then
+ return input.filters.dynamic_translator(line)
else
- return file_handle:read()
+ return line
end
end,
close = function()
diff --git a/tex/context/base/luat-tmp.lua b/tex/context/base/luat-tmp.lua
index 84966bd2c..58a195986 100644
--- a/tex/context/base/luat-tmp.lua
+++ b/tex/context/base/luat-tmp.lua
@@ -22,30 +22,30 @@ being written at the same time is small. We also need to extend
luatools with a recache feature.</p>
--ldx]]--
-cache = cache or { }
-dir = dir or { }
-texmf = texmf or { }
-
-cache.path = cache.path or nil
-cache.base = cache.base or "luatex-cache"
-cache.more = cache.more or "context"
-cache.direct = false -- true is faster but may need huge amounts of memory
-cache.trace = false
-cache.tree = false
-cache.temp = cache.temp or os.getenv("TEXMFCACHE") or os.getenv("HOME") or os.getenv("HOMEPATH") or os.getenv("VARTEXMF") or os.getenv("TEXMFVAR") or os.getenv("TMP") or os.getenv("TEMP") or os.getenv("TMPDIR") or nil
-cache.paths = cache.paths or { cache.temp }
-
-if not cache.temp or cache.temp == "" then
+caches = caches or { }
+dir = dir or { }
+texmf = texmf or { }
+
+caches.path = caches.path or nil
+caches.base = caches.base or "luatex-cache"
+caches.more = caches.more or "context"
+caches.direct = false -- true is faster but may need huge amounts of memory
+caches.trace = false
+caches.tree = false
+caches.temp = caches.temp or os.getenv("TEXMFCACHE") or os.getenv("HOME") or os.getenv("HOMEPATH") or os.getenv("VARTEXMF") or os.getenv("TEXMFVAR") or os.getenv("TMP") or os.getenv("TEMP") or os.getenv("TMPDIR") or nil
+caches.paths = caches.paths or { caches.temp }
+
+if not caches.temp or caches.temp == "" then
print("\nFATAL ERROR: NO VALID TEMPORARY PATH\n")
os.exit()
end
-function cache.configpath(instance)
+function caches.configpath(instance)
return input.expand_var(instance,"TEXMFCNF")
end
-function cache.treehash(instance)
- local tree = cache.configpath(instance)
+function caches.treehash(instance)
+ local tree = caches.configpath(instance)
if not tree or tree == "" then
return false
else
@@ -53,49 +53,49 @@ function cache.treehash(instance)
end
end
-function cache.setpath(instance,...)
- if not cache.path then
+function caches.setpath(instance,...)
+ if not caches.path then
if lfs and instance then
- for _,v in pairs(cache.paths) do
+ for _,v in pairs(caches.paths) do
for _,vv in pairs(input.expanded_path_list(instance,v)) do
if lfs.isdir(vv) then
- cache.path = vv
+ caches.path = vv
break
end
end
- if cache.path then break end
+ if caches.path then break end
end
end
- if not cache.path then
- cache.path = cache.temp
+ if not caches.path then
+ caches.path = caches.temp
end
- cache.path = input.clean_path(cache.path) -- to be sure
+ caches.path = input.clean_path(caches.path) -- to be sure
if lfs then
- cache.tree = cache.tree or cache.treehash(instance)
- if cache.tree then
- cache.path = dir.mkdirs(cache.path,cache.base,cache.more,cache.tree)
+ caches.tree = caches.tree or caches.treehash(instance)
+ if caches.tree then
+ caches.path = dir.mkdirs(caches.path,caches.base,caches.more,caches.tree)
else
- cache.path = dir.mkdirs(cache.path,cache.base,cache.more)
+ caches.path = dir.mkdirs(caches.path,caches.base,caches.more)
end
end
end
- if not cache.path then
- cache.path = '.'
+ if not caches.path then
+ caches.path = '.'
end
- cache.path = input.clean_path(cache.path)
+ caches.path = input.clean_path(caches.path)
if lfs and not table.is_empty({...}) then
- local pth = dir.mkdirs(cache.path,...)
+ local pth = dir.mkdirs(caches.path,...)
return pth
end
- return cache.path
+ return caches.path
end
-function cache.setluanames(path,name)
+function caches.setluanames(path,name)
return path .. "/" .. name .. ".tma", path .. "/" .. name .. ".tmc"
end
-function cache.loaddata(path,name)
- local tmaname, tmcname = cache.setluanames(path,name)
+function caches.loaddata(path,name)
+ local tmaname, tmcname = caches.setluanames(path,name)
local loader = loadfile(tmcname) or loadfile(tmaname)
if loader then
return loader()
@@ -104,18 +104,18 @@ function cache.loaddata(path,name)
end
end
-function cache.is_writable(filepath,filename)
- local tmaname, tmcname = cache.setluanames(filepath,filename)
+function caches.is_writable(filepath,filename)
+ local tmaname, tmcname = caches.setluanames(filepath,filename)
return file.is_writable(tmaname)
end
-function cache.savedata(filepath,filename,data,raw) -- raw needed for file cache
- local tmaname, tmcname = cache.setluanames(filepath,filename)
+function caches.savedata(filepath,filename,data,raw) -- raw needed for file cache
+ local tmaname, tmcname = caches.setluanames(filepath,filename)
local reduce, simplify = true, true
if raw then
reduce, simplify = false, false
end
- if cache.direct then
+ if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',true,true))
else
table.tofile (tmaname, data,'return',true,true) -- maybe not the last true
@@ -127,7 +127,7 @@ end
if tex and texconfig and texconfig.formatname and texconfig.formatname == "" then
if not texconfig.luaname then texconfig.luaname = "cont-en.lua" end
- texconfig.formatname = cache.setpath(instance,"format") .. "/" .. texconfig.luaname:gsub("%.lu.$",".fmt")
+ texconfig.formatname = caches.setpath(instance,"format") .. "/" .. texconfig.luaname:gsub("%.lu.$",".fmt")
end
--[[ldx--
@@ -149,7 +149,7 @@ containers.trace = false
do -- local report
local function report(container,tag,name)
- if cache.trace or containers.trace or container.trace then
+ if caches.trace or containers.trace or container.trace then
logs.report(string.format("%s cache",container.subcategory),string.format("%s: %s",tag,name or 'invalid'))
end
end
@@ -163,7 +163,7 @@ do -- local report
enabled = enabled,
version = version or 1.000,
trace = false,
- path = cache.setpath(texmf.instance,category,subcategory),
+ path = caches.setpath(texmf.instance,category,subcategory),
}
else
return nil
@@ -171,13 +171,13 @@ do -- local report
end
function containers.is_usable(container, name)
- return container.enabled and cache.is_writable(container.path, name)
+ return container.enabled and caches.is_writable(container.path, name)
end
function containers.is_valid(container, name)
if name and name ~= "" then
- local cs = container.storage[name]
- return cs and not table.is_empty(cs) and cs.cache_version == container.version
+ local storage = container.storage[name]
+ return storage and not table.is_empty(storage) and storage.cache_version == container.version
else
return false
end
@@ -185,7 +185,7 @@ do -- local report
function containers.read(container,name)
if container.enabled and not container.storage[name] then
- container.storage[name] = cache.loaddata(container.path,name)
+ container.storage[name] = caches.loaddata(container.path,name)
if containers.is_valid(container,name) then
report(container,"loaded",name)
else
@@ -204,7 +204,7 @@ do -- local report
if container.enabled then
local unique, shared = data.unique, data.shared
data.unique, data.shared = nil, nil
- cache.savedata(container.path, name, data)
+ caches.savedata(container.path, name, data)
report(container,"saved",name)
data.unique, data.shared = unique, shared
end
@@ -229,7 +229,7 @@ function input.aux.save_data(instance, dataname, check)
for cachename, files in pairs(instance[dataname]) do
local name
if input.usecache then
- name = file.join(cache.setpath(instance,"trees"),md5.hex(cachename))
+ name = file.join(caches.setpath(instance,"trees"),md5.hex(cachename))
else
name = file.join(cachename,dataname)
end
@@ -321,7 +321,7 @@ end
function input.aux.load_data(instance,pathname,dataname,filename)
local luaname, lucname, pname, fname
if input.usecache then
- pname, fname = cache.setpath(instance,"trees"), md5.hex(pathname)
+ pname, fname = caches.setpath(instance,"trees"), md5.hex(pathname)
filename = file.join(pname,fname)
else
if not filename or (filename == "") then
@@ -357,7 +357,7 @@ input.automounted = input.automounted or { }
function input.automount(instance,usecache)
local mountpaths = input.simplified_list(input.expansion(instance,'TEXMFMOUNT'))
if table.is_empty(mountpaths) and usecache then
- mountpaths = { cache.setpath(instance,"mount") }
+ mountpaths = { caches.setpath(instance,"mount") }
end
if not table.is_empty(mountpaths) then
input.starttiming(instance)
diff --git a/tex/context/base/luat-tra.lua b/tex/context/base/luat-tra.lua
index 90756d359..f5c077f41 100644
--- a/tex/context/base/luat-tra.lua
+++ b/tex/context/base/luat-tra.lua
@@ -8,61 +8,79 @@ if not versions then versions = { } end versions['luat-tra'] = 1.001
debugger = { }
-debugger.counters = { }
-debugger.names = { }
-
-function debugger.hook()
- local f = debug.getinfo(2,"f").func
- if debugger.counters[f] == nil then
- debugger.counters[f] = 1
- debugger.names[f] = debug.getinfo(2,"Sn")
- else
- debugger.counters[f] = debugger.counters[f] + 1
+do
+
+ local counters = { }
+ local names = { }
+ local getinfo = debug.getinfo
+
+ local function hook()
+ local f = getinfo(2,"f").func
+ if f then
+ if counters[f] == nil then
+ counters[f] = 1
+--~ names[f] = debug.getinfo(2,"Sn")
+--~ names[f] = debug.getinfo(2,"n")
+ names[f] = debug.getinfo(f)
+ else
+ counters[f] = counters[f] + 1
+ end
+ end
end
-end
-function debugger.getname(func)
- local n = debugger.names[func]
- if n.what == "C" then
- return n.name
+ local function getname(func)
+ local n = names[func]
+ if n then
+ if n.what == "C" then
+ return n.name or '<luacall>'
+ else
+ -- source short_src linedefined what name namewhat nups func
+ local name = n.name or n.namewhat or n.what
+ if not name or name == "" then name = "?" end
+ return string.format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name)
+ end
+ else
+ return "unknown"
+ end
end
- local lc = string.format("[%s]:%s", n.short_src, n.linedefined)
- if n.namewhat ~= "" then
- return string.format("%s (%s)", lc, n.name)
- else
- return lc
+
+ function debugger.showstats(printer,threshold)
+ printer = printer or texio.write or print
+ threshold = threshold or 0
+ local total, grandtotal, functions = 0, 0, 0
+ printer("\n") -- ugly but ok
+ for func, count in pairs(counters) do
+ if count > threshold then
+ printer(string.format("%8i %s\n", count, getname(func)))
+ total = total + count
+ end
+ grandtotal = grandtotal + count
+ functions = functions + 1
+ end
+ printer(string.format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold))
end
-end
-function debugger.showstats(printer,threshold)
- if not printer then printer = print end
- if not threshold then threshold = 0 end
- for func, count in pairs(debugger.counters) do
- if count > threshold then
- printer(string.format("%8i %s\n", count, debugger.getname(func)))
+ function debugger.savestats(filename,threshold)
+ local f = io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str) end,threshold)
+ f:close()
end
end
-end
-function debugger.savestats(filename,threshold)
- local f = io.open(filename,'w')
- if f then
- debugger.showstats(function(str) f:write(str) end,threshold)
- f:close()
+ function debugger.enable()
+ debug.sethook(hook,"c")
end
-end
-function debugger.enable()
- debug.sethook(debugger.hook,"c")
-end
+ function debugger.disable()
+ debug.sethook()
+ --~ counters[debug.getinfo(2,"f").func] = nil
+ end
-function debugger.disable()
- debug.sethook()
---~ debugger.counters[debug.getinfo(2,"f").func] = nil
-end
+ function debugger.tracing()
+ return tonumber((os.env['MTX.TRACE.CALLS'] or os.env['MTX_TRACE_CALLS'] or 0)) > 0
+ end
-function debugger.tracing()
- return tonumber((os.env['MTX.TRACE.CALLS'] or os.env['MTX_TRACE_CALLS'] or 0)) > 0
end
--~ debugger.enable()
diff --git a/tex/context/base/lxml-ini.lua b/tex/context/base/lxml-ini.lua
new file mode 100644
index 000000000..f2a42eeea
--- /dev/null
+++ b/tex/context/base/lxml-ini.lua
@@ -0,0 +1,33 @@
+if not modules then modules = { } end modules ['lxml-ini'] = {
+ version = 1.001,
+ comment = "companion to lxml-ini.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+document = document or { }
+document.xml = document.xml or { }
+
+lxml = { }
+lxml.loaded = { }
+
+function lxml.root(id)
+ return lxml.loaded[id]
+end
+
+function lxml.load(id,filename)
+ lxml.loaded[id] = xml.load(filename)
+end
+
+function lxml.first(id,pattern)
+ tex.sprint(xml.tostring(xml.first_text(lxml.loaded[id],pattern)))
+end
+
+function lxml.last(id,pattern)
+ tex.sprint(xml.tostring(xml.last_text (lxml.loaded[id],pattern)))
+end
+
+function lxml.index(id,pattern,i)
+ tex.sprint(xml.tostring(xml.index_text(lxml.loaded[id],pattern,i)))
+end
diff --git a/tex/context/base/lxml-ini.tex b/tex/context/base/lxml-ini.tex
new file mode 100644
index 000000000..3f21bf0fa
--- /dev/null
+++ b/tex/context/base/lxml-ini.tex
@@ -0,0 +1,23 @@
+%D \module
+%D [ file=lxml-ini,
+%D version=2007.08.17,
+%D title=\CONTEXT\ \LUA\ based \XML\ Support,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{Context L-XML Macros (initialization)}
+
+\registerctxluafile{lxml-ini}{1.001}
+
+\def\xmlload #1#2{\ctxlua{lxml.load ("#1","#2")}}
+\def\xmlfirst #1#2{\ctxlua{lxml.first("#1","#2")}}
+\def\xmllast #1#2{\ctxlua{lxml.last ("#1","#2")}}
+\def\xmlindex#1#2#3{\ctxlua{lxml.index("#1","#2",#3)}}
+
+\endinput
diff --git a/tex/context/base/meta-mis.tex b/tex/context/base/meta-mis.tex
index 6b39fa0dd..29ab43007 100644
--- a/tex/context/base/meta-mis.tex
+++ b/tex/context/base/meta-mis.tex
@@ -27,7 +27,7 @@
currentpicture := currentpicture shifted (-4cm,0) ;
fill fullcircle scaled 3cm withcolor cmyk(0,0,1,0) ;
fill fullcircle scaled 2cm withcolor cmyk(0,1,0,0) ;
- fill fullcircle scaled 1cm withcolor cmyk(0,0,1,0) ;
+ fill fullcircle scaled 1cm withcolor cmyk(1,0,0,0) ;
currentpicture := currentpicture shifted (-4cm,0) ;
draw fullcircle scaled 3cm dashed evenly ;
draw fullcircle scaled 2cm dashed withdots ;
diff --git a/tex/context/base/meta-pdf.lua b/tex/context/base/meta-pdf.lua
index 56e09bb1f..3a745da17 100644
--- a/tex/context/base/meta-pdf.lua
+++ b/tex/context/base/meta-pdf.lua
@@ -105,7 +105,7 @@ end
function mptopdf.steps.convert()
mptopdf.data = mptopdf.data:gsub("%c%((.-)%) (.-) (.-) fshow", function(str,font,scale)
- table.insert(mptopdf.texts,{mptopdf.steps.descape(str), font, scale})
+ mptopdf.texts[mptopdf.texts+1] = {mptopdf.steps.descape(str), font, scale}
return "\n" .. #mptopdf.texts .. " textext"
end)
mptopdf.data = mptopdf.data:gsub("%[%s*(.-)%s*%]", function(str)
@@ -165,17 +165,17 @@ function mptopdf.flushpath(cmd)
local function concat(px, py)
return (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d
end
- for _,v in pairs(mptopdf.stack.path) do
+ for _,v in ipairs(mptopdf.stack.path) do
v[1],v[2] = concat(v[1],v[2])
if #v == 7 then
v[3],v[4] = concat(v[3],v[4])
v[5],v[6] = concat(v[5],v[6])
end
- table.insert(path, table.concat(v," "))
+ path[#path+1] = table.concat(v," ")
end
else
- for _,v in pairs(mptopdf.stack.path) do
- table.insert(path, table.concat(v," "))
+ for _,v in ipairs(mptopdf.stack.path) do
+ path[#path+1] = table.concat(v," ")
end
end
mptopdf.flushconcat()
@@ -363,23 +363,52 @@ end
--~ end
--~ end
-function mp.setrgbcolor(r,g,b) -- extra check
- r, g = tonumber(r), tonumber(g) -- needed when we use lpeg
- if r == 0.0123 and g < 0.01 then
- mptopdf.texcode("\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
- elseif r == 0.123 and r < 0.1 then
- mptopdf.texcode("\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
- else
- mptopdf.texcode("\\MPSrgb{" .. r .. "}{" .. g .. "}{" .. b .. "}")
+if ctx and ctx.aux and ctx.aux.definecolor then
+
+ logs.report("mptopdf", "using attribute based mps colors")
+
+ -- todo: convert pdf specials to lua code
+
+ function mp.setrgbcolor(r,g,b) -- extra check
+ r, g, b = tonumber(r), tonumber(g), tonumber(b) -- needed when we use lpeg
+ if r == 0.0123 and g < 0.01 then
+ mptopdf.texcode("\\doresetattribute{transparency}\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
+ elseif r == 0.123 and r < 0.1 then
+ mptopdf.texcode("\\doresetattribute{transparency}\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
+ else
+ mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'rgb',r,g,b) .. "}")
+ end
end
-end
-function mp.setcmykcolor(c,m,y,k)
- mptopdf.texcode("\\MPScmyk{" .. c .. "}{" .. m .. "}{" .. y .. "}{" .. k .. "}")
-end
+ function mp.setcmykcolor(c,m,y,k)
+ mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'cmyk',tonumber(c),tonumber(m),tonumber(y),tonumber(k)) .. "}")
+ end
+
+ function mp.setgray(s)
+ mptopdf.texcode("\\doresetattribute{transparency}\\dosetattribute{color}{" .. colors.register('color',nil,'gray',tonumber(s)) .. "}")
+ end
+
+else
+
+ function mp.setrgbcolor(r,g,b) -- extra check
+ r, g = tonumber(r), tonumber(g) -- needed when we use lpeg
+ if r == 0.0123 and g < 0.01 then
+ mptopdf.texcode("\\MPSspecial{" .. g*10000 .. "}{" .. b*10000 .. "}")
+ elseif r == 0.123 and r < 0.1 then
+ mptopdf.texcode("\\MPSspecial{" .. g* 1000 .. "}{" .. b* 1000 .. "}")
+ else
+ mptopdf.texcode("\\MPSrgb{" .. r .. "}{" .. g .. "}{" .. b .. "}")
+ end
+ end
+
+ function mp.setcmykcolor(c,m,y,k)
+ mptopdf.texcode("\\MPScmyk{" .. c .. "}{" .. m .. "}{" .. y .. "}{" .. k .. "}")
+ end
+
+ function mp.setgray(s)
+ mptopdf.texcode("\\MPSgray{" .. s .. "}")
+ end
-function mp.setgray(s)
- mptopdf.texcode("\\MPSgray{" .. s .. "}")
end
function mp.specials(version,signal,factor) -- 2.0 123 1000
diff --git a/tex/context/base/meta-pdf.mkiv b/tex/context/base/meta-pdf.mkiv
index dadf760a6..d10734547 100644
--- a/tex/context/base/meta-pdf.mkiv
+++ b/tex/context/base/meta-pdf.mkiv
@@ -24,8 +24,6 @@
% 7.4 : mkiv, simulated clean direct lua from mp
% 0.3 : time taken by tex to handle converted code
-% Maybe delayed load, only at first call of the converter.
-
\registerctxluafile{meta-pdf}{1.003}
%D Plugin.
diff --git a/tex/context/base/meta-pdf.tex b/tex/context/base/meta-pdf.tex
index ad4a57fd9..8ac736818 100644
--- a/tex/context/base/meta-pdf.tex
+++ b/tex/context/base/meta-pdf.tex
@@ -811,7 +811,7 @@
{\global\let\MPresolvedspace\MPcmykspace
\xdef\MPresolvedcolor{##1 ##2 ##3 ##4}}%
\def\dostartspotcolormode##1##2%
- {\global\let\MPspotspace\empty
+ {\global\let\MPspotspace\empty % left over ?
\xdef\MPresolvedspace{##1}%
\xdef\MPresolvedcolor{##2}%
\global\let\MPspotspace\MPresolvedspace}% signal
@@ -961,4 +961,51 @@
% filldraw boundingbox currentpicture enlarged -3cm withpen pencircle scaled 1pt withcolor .5white ;
% \stopMPcode
+% This code will move to meta-pdf.mkiv and the call to lua will move to the
+% converter code (saves a lua call). We will do this when we made the final
+% move to attribute bases color .
+
+\ifx\colorversion\undefined \else \ifnum\colorversion>\plusone
+
+ \def\dohandleMPgraycolor #1{\dosetattribute{color}{\ctxlua{tex.sprint(colors.register('color',nil,'gray',#1))}}}
+ \def\dohandleMPrgbcolor #1#2#3{\dosetattribute{color}{\ctxlua{tex.sprint(colors.register('color',nil,'rgb' ,#1,#2,#3))}}}
+ \def\dohandleMPcmykcolor#1#2#3#4{\dosetattribute{color}{\ctxlua{tex.sprint(colors.register('color',nil,'cmyk',#1,#2,#3,#4))}}}
+ \def\dohandleMPspotcolor#1#2#3#4{\dosetattribute{color}{\ctxlua{tex.sprint(colors.register('color',nil,'spot',"#1",#2,"#3","#4"))}}}
+
+ \def\dohandleMPgraytransparency #1#2#3{\dosetattribute{color}{\ctxlua{tex.sprint(colors.register('color',nil,'gray',#1))}}%
+ \dosetattribute{transparency}{\ctxlua{tex.sprint(transparencies.register(nil,#2,#3))}}}
+ \def\dohandleMPrgbtransparency #1#2#3#4#5{\dosetattribute{color}{\ctxlua{tex.sprint(colors.register('color',nil,'rgb' ,#1,#2,#3))}}%
+ \dosetattribute{transparency}{\ctxlua{tex.sprint(transparencies.register(nil,#4,#5))}}}
+ \def\dohandleMPcmyktransparency#1#2#3#4#5#6{\dosetattribute{color}{\ctxlua{tex.sprint(colors.register('color',nil,'cmyk',#1,#2,#3,#4))}}%
+ \dosetattribute{transparency}{\ctxlua{tex.sprint(transparencies.register(nil,#5,#6))}}}
+ \def\dohandleMPspottransparency#1#2#3#4#5#6{\dosetattribute{color}{\ctxlua{tex.sprint(colors.register('color',nil,'spot',"#1",#2,"#3","#4"))}}%
+ \dosetattribute{transparency}{\ctxlua{tex.sprint(transparencies.register(nil,#5,#6))}}}
+
+ % \dostartgraycolormode\!!zerocount} % kind of hackery initialization
+
+ \def\resolveMPgraycolor#1\to#2%
+ {\global\let\MPresolvedspace\MPgrayspace
+ \edef#2{\ctxlua{tex.sprint(ctx.pdfcolorvalue(\number\currentcolormodel,colors.register('color',nil,'gray',#1)))}}}
+
+ \def\resolveMPrgbcolor#1#2#3\to#4%
+ {\global\let\MPresolvedspace\MPrgbspace
+ \edef#4{\ctxlua{tex.sprint(ctx.pdfcolorvalue(\number\currentcolormodel,colors.register('color',nil,'rgb' ,#1,#2,#3)))}}}
+
+ \def\resolveMPcmykcolor#1#2#3#4\to#5%
+ {\global\let\MPresolvedspace\MPcmykspace
+ \edef#5{\ctxlua{tex.sprint(ctx.pdfcolorvalue(\number\currentcolormodel,colors.register('color',nil,'cmyk',#1,#2,#3,#4)))}}}
+
+ \def\resolveMPspotcolor#1#2#3#4\to#5%
+ {\xdef\MPresolvedspace{#1}%
+ \xdef\MPresolvedcolor{#4}%
+ \global\let\MPspotspace\MPresolvedspace
+ \edef#5{\ctxlua{tex.sprint(ctx.pdfcolorvalue(\number\currentcolormodel,colors.register('color',nil,'spot',"#1",#2,"#3","#4")))}}}
+
+ \let\MPSgray\dohandleMPgraycolor
+ \let\MPSrgb \dohandleMPrgbcolor
+ \let\MPScmyk\dohandleMPcmykcolor
+ \let\MPspot \dohandleMPspotcolor
+
+\fi \fi
+
\protect \endinput
diff --git a/tex/context/base/mult-con.tex b/tex/context/base/mult-con.tex
index 043d5fb6e..22103e615 100644
--- a/tex/context/base/mult-con.tex
+++ b/tex/context/base/mult-con.tex
@@ -736,6 +736,10 @@ subsubsubsubsubsubject: subsubsubsubsubonderwerp subsubsubsubsub
ausgleichen rovnovaha
bilanciamento balanta
equilibre
+ bookmark: bookmark bookmark
+ bookmark zalozka
+ segnalibro semncarte
+ marquepage
wfactor: bfactor wfactor
bfaktor sfaktor
wfactor factorw
@@ -1160,6 +1164,14 @@ subsubsubsubsubsubject: subsubsubsubsubonderwerp subsubsubsubsub
linkerrand levyokraj
marginesinistro marginestanga
margegauche
+ innermargin: binnenmarge innermargin
+ innermargin innermargin
+ margineinterno innermargin
+ margeinterieure
+ outermargin: buitenmarge outermargin
+ outermargin outermargin
+ margineesterno outermargin
+ margeexterieure
leftmargindistance: linkermargeafstand leftmargindistance
linkerrandabstand vzdalenostlevehookraje
distanzamarginesinistro distantamarginestanga
diff --git a/tex/context/base/mult-sys.tex b/tex/context/base/mult-sys.tex
index f10e91cfe..74538a2aa 100644
--- a/tex/context/base/mult-sys.tex
+++ b/tex/context/base/mult-sys.tex
@@ -177,6 +177,8 @@
\definesystemconstant {layer}
\definesystemconstant {effect}
\definesystemconstant {negative}
+\definesystemconstant {color}
+\definesystemconstant {transparency}
\definesystemconstant {black}
\definesystemconstant {white}
diff --git a/tex/context/base/node-ini.lua b/tex/context/base/node-ini.lua
index 77835e04b..4ef9e05eb 100644
--- a/tex/context/base/node-ini.lua
+++ b/tex/context/base/node-ini.lua
@@ -11,8 +11,8 @@ if not modules then modules = { } end modules ['node-ini'] = {
implement a few helper functions.</p>
--ldx]]--
-nodes = nodes or { }
-nodes.trace = false
+nodes = nodes or { }
+nodes.trace = false
-- handy helpers
@@ -59,7 +59,7 @@ nodes.processors.char = { }
nodes.processors.char.proc = { }
function nodes.report(t,done)
- if nodes.trace then
+ if nodes.trace then -- best also test this before calling
if done then
if status.output_active then
texio.write(string.format("<++ %s>",nodes.count(t)))
@@ -296,6 +296,309 @@ if not fonts then fonts = { } end
if not fonts.tfm then fonts.tfm = { } end
if not fonts.tfm.id then fonts.tfm.id = { } end
+do
+
+ local glyph, hlist, vlist = node.id('glyph'), node.id('hlist'), node.id('vlist')
+ local pushmarks = false
+
+ function nodes.process_glyphs(head)
+ if status.output_active then -- not ok, we need a generic blocker, pagebody ! / attr tex.attibutes
+ -- 25% calls
+ return true
+ elseif not head then
+ -- 25% calls
+ return true
+ elseif not head.next and (head.id == hlist or head.id == vlist) then
+ return head
+ else
+ -- either next or not, but definitely no already processed list
+ input.start_timing(nodes)
+ local usedfonts, found, fontdata, done = { }, false, fonts.tfm.id, false
+ for n in node.traverse_id(glyph,head) do
+ local font = n.font
+ if not usedfonts[font] then
+ local shared = fontdata[font].shared
+ if shared and shared.processors then
+ usedfonts[font], found = shared.processors, true
+ end
+ end
+ end
+ if found then
+ local tail = head
+ if head.next then
+ tail = node.slide(head)
+ else
+ head.prev = nil
+ end
+ for font, processors in pairs(usedfonts) do
+ if pushmarks then
+ local h, d = fonts.pushmarks(head,font)
+ head, done = head or h, done or d
+ end
+ for _, processor in ipairs(processors) do
+ local h, d = processor(head,font)
+ head, done = head or h, done or d
+ end
+ if pushmarks then
+ local h, d = fonts.popmarks(head,font)
+ head, done = head or h, done or d
+ end
+ end
+ end
+ input.stop_timing(nodes)
+ if nodes.trace then
+ nodes.report(head,done)
+ end
+ if done then
+ return head -- something changed
+ elseif head then
+ return true -- nothing changed
+ else
+ return false -- delete list
+ end
+ end
+ end
+
+end
+
+-- 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
+
+do
+
+ local contains, set, attribute = node.has_attribute, node.set_attribute, tex.attribute
+
+ function nodes.inherit_attributes(n)
+ if n then
+ local i = 1
+ while true do
+ local a = attribute[i]
+ if a < 0 then
+ break
+ else
+ local ai = contains(n,i)
+ if not ai then
+ set(n,i,a)
+ end
+ i = i + 1
+ end
+ end
+ end
+ end
+
+end
+
+callback.register('pre_linebreak_filter', nodes.process_glyphs)
+callback.register('hpack_filter', nodes.process_glyphs)
+
+--~ callback.register('pre_linebreak_filter', function(t,...)
+--~ print("pre_linebreak_filter",...)
+--~ return nodes.process_glyphs(t)
+--~ end )
+--~ callback.register('hpack_filter', function(t,...)
+--~ print("hpack_filter",...)
+--~ return nodes.process_glyphs(t)
+--~ end )
+
+function nodes.length(head)
+ if head then
+ local m = 0
+ for n in node.traverse(head) do
+ m = m + 1
+ end
+ return m
+ else
+ return 0
+ end
+end
+
+do
+
+--~ function nodes.totable(n)
+--~ local function totable(n)
+--~ local f, tt = node.fields(n.id,n.subtype), { }
+--~ for _,v in ipairs(f) do
+--~ local nv = n[v]
+--~ if nv then
+--~ local tnv = type(nv)
+--~ if tnv == "string" or tnv == "number" then
+--~ tt[v] = nv
+--~ else -- userdata
+--~ tt[v] = nodes.totable(nv)
+--~ end
+--~ end
+--~ end
+--~ return tt
+--~ end
+--~ local t = { }
+--~ while n do
+--~ t[#t+1] = totable(n)
+--~ n = n.next
+--~ end
+--~ return t
+--~ end
+
+ local expand = {
+ list = true,
+ pre = true,
+ post = true,
+ spec = true,
+ attr = true,
+ components = true,
+ }
+
+ -- flat: don't use next, but indexes
+ -- verbose: also add type
+
+ function nodes.totable(n,flat,verbose)
+ local function totable(n,verbose)
+ local f = node.fields(n.id,n.subtype)
+ local tt = { }
+ for _,v in ipairs(f) do
+ if n[v] then
+ if v == "ref_count" then
+ -- skip
+ elseif expand[v] then -- or: type(n[v]) ~= "string" or type(n[v]) ~= "number"
+ tt[v] = nodes.totable(n[v],flat,verbose)
+ else
+ tt[v] = n[v]
+ end
+ end
+ end
+ if verbose then
+ tt.type = node.type(tt.id)
+ end
+ return tt
+ end
+ if n then
+ if flat then
+ local t = { }
+ while n do
+ t[#t+1] = totable(n,verbose)
+ n = n.next
+ end
+ return t
+ else
+ local t = totable(n,verbose)
+ if n.next then
+ t.next = nodes.totable(n.next,flat,verbose)
+ end
+ return t
+ end
+ else
+ return { }
+ end
+ end
+
+ local function key(k)
+ if type(k) == "number" then
+ return "["..k.."]"
+ else
+ return k
+ end
+ end
+
+ local function serialize(root,name,handle,depth,m)
+ handle = handle or print
+ if depth then
+ depth = depth .. " "
+ handle(("%s%s={"):format(depth,key(name)))
+ else
+ depth = ""
+ if type(name) == "string" then
+ if name == "return" then
+ handle("return {")
+ else
+ handle(name .. "={")
+ end
+ elseif type(name) == "number" then
+ handle("[" .. name .. "]={")
+ else
+ handle("t={")
+ end
+ end
+ if root then
+ local fld
+ if root.id then
+ fld = node.fields(root.id,root.subtype)
+ else
+ fld = table.sortedkeys(root)
+ end
+ if type(root) == 'table' and root['type'] then -- userdata or table
+ handle(("%s %s=%q,"):format(depth,'type',root['type']))
+ end
+ for _,k in ipairs(fld) do
+ if k then
+ local v = root[k]
+ local t = type(v)
+ if t == "number" then
+ handle(("%s %s=%s,"):format(depth,key(k),v))
+ elseif t == "string" then
+ handle(("%s %s=%q,"):format(depth,key(k),v))
+ elseif v then -- userdata or table
+ serialize(v,k,handle,depth,m+1)
+ end
+ end
+ end
+ if root['next'] then -- userdata or table
+ serialize(root['next'],'next',handle,depth,m+1)
+ end
+ end
+ if m and m > 0 then
+ handle(("%s},"):format(depth))
+ else
+ handle(("%s}"):format(depth))
+ end
+ end
+
+ function nodes.serialize(root,name)
+ local t = { }
+ local function flush(s)
+ t[#t+1] = s
+ end
+ serialize(root, name, flush, nil, 0)
+ return table.concat(t,"\n")
+ end
+
+ function nodes.serializebox(n,flat,verbose)
+ return nodes.serialize(nodes.totable(tex.box[n],flat,verbose))
+ -- return nodes.serialize(tex.box[n])
+ end
+
+ function nodes.visualizebox(...)
+ -- tex.sprint(tex.ctxcatcodes,"\\starttyping\n" .. nodes.serializebox(...) .. "\n\\stoptyping\n")
+ tex.print(tex.ctxcatcodes,"\\starttyping")
+ tex.print(nodes.serializebox(...))
+ tex.print("\\stoptyping")
+ end
+
+end
+
+if not node.list_has_attribute then
+
+ function node.list_has_attribute(list,attribute)
+ if list and attribute then
+ for n in node.traverse(list) do
+ local a = has_attribute(n,attribute)
+ if a then return a end
+ end
+ end
+ return false
+ end
+
+end
+
+function nodes.pack_list(head)
+ local t = { }
+ for n in node.traverse(head) do
+ t[#t+1] = tostring(n)
+ end
+ return t
+end
+
+-- old code
+
+
--~ function nodes.do_process_glyphs(stack)
--~ if not stack or #stack == 0 then
--~ return false
@@ -634,272 +937,3 @@ if not fonts.tfm.id then fonts.tfm.id = { } end
--~ end
--~ end
-
-do
-
- local glyph = node.id('glyph')
- local pushmarks = false
-
- function do_process_glyphs(head) -- beware, we need to handle shifted heads -- todo
- if not head then
- return head
- end
- local usedfonts, found, fontdata = { }, false, fonts.tfm.id
- for n in node.traverse_id(glyph,head) do
- local font = n.font
- if not usedfonts[font] then
- local shared = fontdata[font].shared
- if shared and shared.processors then
- usedfonts[font], found = shared.processors, true
- end
- end
- end
- if not found then
- return head, false
- else
- local tail, done = node.slide(head), false
- for font, processors in pairs(usedfonts) do
- if pushmarks then
- local h, d = fonts.pushmarks(head,font)
- head, done = head or h, done or d
- end
- for _, processor in ipairs(processors) do
- local h, d = processor(head,font)
- head, done = head or h, done or d
- end
- if pushmarks then
- local h, d = fonts.popmarks(head,font)
- head, done = head or h, done or d
- end
- end
- return head, done
- end
- end
-
- function nodes.process_glyphs(head)
- if status.output_active then -- not ok, we need a generic blocker, pagebody ! / attr tex.attibutes
- return true
- else
- input.start_timing(nodes)
- local head, done = do_process_glyphs(head)
- input.stop_timing(nodes)
- nodes.report(head,done)
- if done then
- return head -- something changed
- elseif head then
- return true -- nothing changed
- else
- return false -- delete list
- end
- end
- end
-
-end
-
--- 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
-
-callback.register('pre_linebreak_filter', nodes.process_glyphs)
-callback.register('hpack_filter', nodes.process_glyphs)
-
---~ callback.register('pre_linebreak_filter', function(t,...)
---~ print("pre_linebreak_filter",...)
---~ return nodes.process_glyphs(t)
---~ end )
---~ callback.register('hpack_filter', function(t,...)
---~ print("hpack_filter",...)
---~ return nodes.process_glyphs(t)
---~ end )
-
-function nodes.length(head)
- if head then
- local m = 0
- for n in node.traverse(head) do
- m = m + 1
- end
- return m
- else
- return 0
- end
-end
-
-do
-
---~ function nodes.totable(n)
---~ function totable(n)
---~ local f, tt = node.fields(n.id,n.subtype), { }
---~ for _,v in ipairs(f) do
---~ local nv = n[v]
---~ if nv then
---~ local tnv = type(nv)
---~ if tnv == "string" or tnv == "number" then
---~ tt[v] = nv
---~ else -- userdata
---~ tt[v] = nodes.totable(nv)
---~ end
---~ end
---~ end
---~ return tt
---~ end
---~ local t = { }
---~ while n do
---~ t[#t+1] = totable(n)
---~ n = n.next
---~ end
---~ return t
---~ end
-
- local expand = {
- list = true,
- pre = true,
- post = true,
- spec = true,
- attr = true,
- components = true,
- }
-
- -- flat: don't use next, but indexes
- -- verbose: also add type
-
- function nodes.totable(n,flat,verbose)
- function totable(n,verbose)
- local f = node.fields(n.id,n.subtype)
- local tt = { }
- for _,v in ipairs(f) do
- if n[v] then
- if v == "ref_count" then
- -- skip
- elseif expand[v] then -- or: type(n[v]) ~= "string" or type(n[v]) ~= "number"
- tt[v] = nodes.totable(n[v],flat,verbose)
- else
- tt[v] = n[v]
- end
- end
- end
- if verbose then
- tt.type = node.type(tt.id)
- end
- return tt
- end
- if flat then
- local t = { }
- while n do
- t[#t+1] = totable(n,verbose)
- n = n.next
- end
- return t
- else
- local t = totable(n,verbose)
- if n.next then
- t.next = nodes.totable(n.next,flat,verbose)
- end
- return t
- end
- end
-
- local function key(k)
- if type(k) == "number" then
- return "["..k.."]"
- else
- return k
- end
- end
-
- local function serialize(root,name,handle,depth,m)
- handle = handle or print
- if depth then
- depth = depth .. " "
- handle(("%s%s={"):format(depth,key(name)))
- else
- depth = ""
- if type(name) == "string" then
- if name == "return" then
- handle("return {")
- else
- handle(name .. "={")
- end
- elseif type(name) == "number" then
- handle("[" .. name .. "]={")
- else
- handle("t={")
- end
- end
- if root then
- local fld
- if root.id then
- fld = node.fields(root.id,root.subtype)
- else
- fld = table.sortedkeys(root)
- end
- if type(root) == 'table' and root['type'] then -- userdata or table
- handle(("%s %s=%q,"):format(depth,'type',root['type']))
- end
- for _,k in ipairs(fld) do
- if k then
- local v = root[k]
- local t = type(v)
- if t == "number" then
- handle(("%s %s=%s,"):format(depth,key(k),v))
- elseif t == "string" then
- handle(("%s %s=%q,"):format(depth,key(k),v))
- elseif v then -- userdata or table
- serialize(v,k,handle,depth,n+1)
- end
- end
- end
- if root['next'] then -- userdata or table
- serialize(root['next'],'next',handle,depth,n+1)
- end
- end
- if m and m > 0 then
- handle(("%s},"):format(depth))
- else
- handle(("%s}"):format(depth))
- end
- end
-
- function nodes.serialize(root,name)
- local t = { }
- local function flush(s)
- t[#t+1] = s
- end
- serialize(root, name, flush, nil, nil)
- return table.concat(t,"\n")
- end
-
- function nodes.serializebox(n,flat,verbose)
- return nodes.serialize(nodes.totable(tex.box[n],flat,verbose))
- -- return nodes.serialize(tex.box[n])
- end
-
- function nodes.visualizebox(...)
- -- tex.sprint(tex.ctxcatcodes,"\\starttyping\n" .. nodes.serializebox(...) .. "\n\\stoptyping\n")
- tex.print(tex.ctxcatcodes,"\\starttyping")
- tex.print(nodes.serializebox(...))
- tex.print("\\stoptyping")
- end
-
-end
-
-if not node.list_has_attribute then
-
- function node.list_has_attribute(list,attribute)
- if list and attribute then
- for n in node.traverse(list) do
- local a = has_attribute(n,attribute)
- if a then return a end
- end
- end
- return false
- end
-
-end
-
-function nodes.pack_list(head)
- local t = { }
- for n in node.traverse(head) do
- t[#t+1] = tostring(n)
- end
- return t
-end
-
diff --git a/tex/context/base/page-flt.tex b/tex/context/base/page-flt.tex
index 6ebade65d..157864d44 100644
--- a/tex/context/base/page-flt.tex
+++ b/tex/context/base/page-flt.tex
@@ -186,6 +186,9 @@
\def\floatparameter #1{\csname\??fl\currentfloat#1\endcsname}
\def\floatcaptionparameter#1{\csname\??kj\currentfloat#1\endcsname}
+% \def\floatparameter #1{\csname \ifcsname\??fl\currentfloat#1\endcsname\??fl\currentfloat\else\??bk\fi#1\endcsname}
+% \def\floatcaptionparameter#1{\csname\??kj\ifcsname\??kj\currentfloat#1\endcsname \currentfloat \fi#1\endcsname}
+
% for the moment we need to define the parameters anyway, first we need to implement a
% proper parent chain (also for framed); no problem now that machines are fast (tests
% show that this may save 20 k or more in the format)
@@ -194,7 +197,7 @@
% \def\floatcaptionparameter#1{\executeifdefined{\??kj\currentfloat#1}{\csname\??bk#1\endcsname}}
\def\setupfloats
- {\dodoubleargument\getparameters[\??bk]}
+ {\dodoubleargument\getparameters[\??bk]} % funny, why not \??fl, must be a reason
\def\setupcaptions
{\dodoubleargument\getparameters[\??kj]}
@@ -233,7 +236,7 @@
{\edef\currentfloat{#1}%
\doifelsenothing\currentfloat
{\let\currentfloat\v!figure}
- {\doifundefined{\??fl#1\c!default}{\let\currentfloat\v!figure}}%
+ {}% {\doifundefined{\??fl#1\c!default}{\let\currentfloat\v!figure}}%
\doifelsenothing{#2}
{\edef\floatlocation{\floatparameter\c!default}}
{\edef\floatlocation{#2}}%
@@ -320,7 +323,7 @@
\global\chardef\textfloatmethod\floatparameter\c!textmethod
\global\chardef\sidefloatalign\zerocount
\globallet\floatrotation\!!zerocount
- \calculatefloatskips{#1}%
+ \calculatefloatskips
\ifparfloat
\processaction
[\floatparameter\c!sidealign]
@@ -510,41 +513,41 @@
% pas op, maxbreedte niet instellen als plaats=links/rechts
-\def\setlocalfloatdimensions#1#2#3#4% experimental / #3 box number #4 prefix
+\def\setlocalfloatdimensions#1#2#3% experimental / #3 box number #4 prefix
{\global\sidefloatshift \zeropoint % duplicate
\global\sidefloatmaximum\zeropoint\relax % duplicate
\ifextrafloatactions
\ifdim\sidefloatdownshift=\zeropoint\else
- #4\setbox#3\vbox
+ #3\setbox#2\vbox
{\vskip\sidefloatdownshift\nointerlineskip\box#3}%
\fi
\doifsomething{\floatparameter\c!minwidth}
{\scratchdimen\floatparameter\c!minwidth\relax
- \ifdim\wd#3<\scratchdimen
- #4\setbox#3\hbox to \scratchdimen
+ \ifdim\wd#2<\scratchdimen
+ #3\setbox#2\hbox to \scratchdimen
{\doifnot{\floatparameter\c!location}\v!left \hss
- \box#3%
+ \box#2%
\doifnot{\floatparameter\c!location}\v!right\hss}%
\fi}%
% todo: rand / rug
- \doifinset\v!hanging{#2}
- {\doifcommonelse{\v!inleft,\v!leftmargin}{#2}
+ \doifinset\v!hanging{#1}
+ {\doifcommonelse{\v!inleft,\v!leftmargin}{#1}
{\letvalue{\??fl\currentfloat\c!maxwidth}\leftmarginwidth}%
- {\doifcommon{\v!inright,\v!rightmargin}{#2}
+ {\doifcommon{\v!inright,\v!rightmargin}{#1}
{\letvalue{\??fl\currentfloat\c!maxwidth}\rightmarginwidth}}}%
\doifsomething{\floatparameter\c!maxwidth}
{\scratchdimen\floatparameter\c!maxwidth\relax
- \ifdim\wd#3>\scratchdimen
+ \ifdim\wd#2>\scratchdimen
\doifcommonelse{\v!inright,\v!rightmargin,\v!rightedge
- \v!inleft,\v!leftmargin,\v!leftedge}{#2}
+ \v!inleft,\v!leftmargin,\v!leftedge}{#1}
{\global\sidefloatmaximum\scratchdimen}
- {#4\setbox#3\hbox to \scratchdimen
- {\doifcommonelse{\v!right,\v!left}{#2}
- {\doifnotinset\v!right{#2}\hss
- \box#3%
- \doifnotinset\v!left{#2}\hss}%
+ {#3\setbox#2\hbox to \scratchdimen
+ {\doifcommonelse{\v!right,\v!left}{#1}
+ {\doifnotinset\v!right{#1}\hss
+ \box#2%
+ \doifnotinset\v!left{#1}\hss}%
{\doifnot{\floatparameter\c!location}\v!left\hss
- \box#3%
+ \box#2%
\doifnot{\floatparameter\c!location}\v!right\hss}}}%
\fi}%
\fi}
@@ -582,18 +585,22 @@
[#1]
[%\c!width=8\lineheight, % 15\bodyfontsize,
%\c!height=6\lineheight, % 10\bodyfontsize,
-\c!offset=\v!overlay,
-\c!width=\v!fit,
-\c!height=\v!fit,
+ \c!offset=\v!overlay,
+ \c!width=\v!fit,
+ \c!height=\v!fit,
\c!minwidth=,
\c!maxwidth=,
\c!maxheight=,
\c!criterium=,
-% inherited
+ % inherited
\c!sidespacebefore=\@@bksidespacebefore,
\c!sidespaceafter=\@@bksidespaceafter,
\c!sidealign=\@@bksidealign, % \v!line
\c!margin=\@@bkmargin,
+ \c!leftmargin=\@@bkleftmargin,
+ \c!rightmargin=\@@bkrightmargin,
+ \c!innermargin=\@@bkinnermargin,
+ \c!outermargin=\@@bkoutermargin,
\c!leftmargindistance=\@@bkleftmargindistance,
\c!rightmargindistance=\@@bkrightmargindistance,
\c!frame=\@@bkframe,
@@ -612,6 +619,7 @@
%\c!local=\@@bklocal,
\c!textmethod=\@@bktextmethod,
\c!sidemethod=\@@bksidemethod,
+ \c!method=\@@bkmethod,
\c!pageboundaries=,
\c!default=]%
\setupcaption
@@ -627,9 +635,9 @@
%\c!before=\@@kjbefore,
\c!inbetween=\@@kjinbetween,
%\c!after=\@@kjafter,
-\c!spacebefore=\@@kjspacebefore,
-\c!spaceinbetween=\@@kjspaceinbetween,
-\c!spaceafter=\@@kjspaceafter,
+ \c!spacebefore=\@@kjspacebefore,
+ \c!spaceinbetween=\@@kjspaceinbetween,
+ \c!spaceafter=\@@kjspaceafter,
\c!width=\@@kjwidth,
\c!minwidth=\@@kjminwidth,
\c!align=\@@kjalign,
@@ -642,16 +650,17 @@
\c!stopper=\@@kjstopper,
\c!suffix=\@@kjsuffix, % hook
\c!command=\@@kjcommand,
- \c!conversion=\@@kjconversion
+ \c!conversion=\@@kjconversion,
+ \c!leftmargin=\@@kjleftmargin,
+ \c!rightmargin=\@@kjrightmargin,
+ \c!outermargin=\@@kjoutermargin,
+ \c!innermargin=\@@kjinnermargin,
+ \c!setups=\@@kjsetups,
]%
\definenumber % \definelabel
[#1]
[\c!text=#1,
\c!location=\v!intext,
-% \c!way=\getvalue{\??kj#1\c!way},
-% \c!blockway=\getvalue{\??kj#1\c!blockway},
-% \c!sectionnumber=\getvalue{\??kj#1\c!sectionnumber},
-% \c!conversion=\getvalue{\??kj#1\c!conversion}]%
\c!way=\floatcaptionparameter\c!way,
\c!blockway=\floatcaptionparameter\c!blockway,
\c!sectionnumber=\floatcaptionparameter\c!sectionnumber,
@@ -684,17 +693,19 @@
\c!maxwidth,\c!maxheight,\c!minwidth,
\c!margin,\c!sidespacebefore,\c!sidespaceafter,\c!sidealign,
\c!leftmargindistance,\c!rightmargindistance,\c!criterium,
+ \c!leftmargin,\c!rightmargin,\c!innermargin,\c!outermargin,
\c!frame,\c!radius,\c!corner,\c!location,\c!background,\c!framecolor,
\c!backgroundscreen,\c!backgroundcolor,\c!backgroundoffset,
\c!topframe,\c!bottomframe,\c!leftframe,\c!rightframe,
\c!frameoffset,\c!pageboundaries,\c!default,
- \c!textmethod,\c!sidemethod]%
+ \c!textmethod,\c!sidemethod,\c!method]%
\copyparameters[\??kj#1][\??kj#3]
[\c!location,\c!before,\c!inbetween,\c!after,
\c!spacebefore,\c!spaceinbetween,\c!spaceafter,
\c!width,\c!headstyle,\c!headcolor,\c!style,\c!color,
\c!textstyle,\c!textcolor,\c!minwidth,
- \c!align,\c!number,\c!way,\c!blockway,
+ \c!align,\c!number,\c!way,\c!blockway,\c!setups,
+ \c!leftmargin,\c!rightmargin,\c!innermargin,\c!outermargin,
\c!sectionnumber,\c!separator,\c!stopper,\c!suffix,\c!distance,\c!conversion]%
\definenumber[#1][#3]%
\presetlabeltext[#1=\labeltext{#3}]%
@@ -710,6 +721,7 @@
\c!maxwidth,\c!maxheight,\c!minwidth,
\c!margin,\c!sidespacebefore,\c!sidespaceafter,\c!sidealign,
\c!leftmargindistance,\c!rightmargindistance,\c!criterium,
+ \c!leftmargin,\c!rightmargin,\c!innermargin,\c!outermargin,
\c!frame,\c!radius,\c!corner,\c!location,\c!background,\c!framecolor,
\c!backgroundscreen,\c!backgroundcolor,\c!backgroundoffset,
\c!topframe,\c!bottomframe,\c!leftframe,\c!rightframe,
@@ -720,7 +732,8 @@
\c!spacebefore,\c!spaceinbetween,\c!spaceafter,
\c!width,\c!headstyle,\c!headcolor,\c!style,\c!color,
\c!textstyle,\c!textcolor,\c!minwidth,
- \c!align,\c!number,\c!way,\c!blockway,
+ \c!leftmargin,\c!rightmargin,\c!innermargin,\c!outermargin,
+ \c!align,\c!number,\c!way,\c!blockway,\c!setups,
\c!sectionnumber,\c!separator,\c!stopper,\c!suffix,\c!distance,\c!conversion]%
\definenumber[#1][#3]%
\presetlabeltext[#1=\labeltext{#3}]%
@@ -867,35 +880,6 @@
\def\doinsertfloatinfo
{\dofloatinfomessage<4{\the\totalnoffloats}}
-% \def\dogetfloat
-% {\ifsomefloatwaiting
-% \global\setbox\floatlist\vbox
-% {\unvbox\floatlist
-% \global\setbox\globalscratchbox\lastbox}%
-% \ifcenterfloatbox
-% \ifdim\wd\globalscratchbox<\hsize
-% \setbox\floatbox\hbox to \hsize{\hss\box\globalscratchbox\hss}%
-% \else
-% \setbox\floatbox\box\globalscratchbox % local !
-% % retain special alignments
-% \ifinsidecolumns
-% \ifdim\wd\floatbox>\makeupwidth
-% \wd\floatbox\makeupwidth
-% \fi
-% \fi
-% \fi
-% \else
-% \setbox\floatbox\box\globalscratchbox % local !
-% \fi
-% \global\advance\savednoffloats \minusone
-% \ifcase\savednoffloats
-% \global\somefloatwaitingfalse
-% \fi
-% \else
-% \global\savednoffloats\zerocount
-% \global\setbox\floatbox\box\voidb@x
-% \fi}
-
\def\dogetfloat
{\ifsomefloatwaiting
\global\setbox\floatlist\vbox
@@ -1233,7 +1217,7 @@
% voor het plaatsen van tabellen en figuren (klopt niet
% meer).
%
-% \dofloat {plaats} {label1} {label2} {kader}
+% \dofloat {plaats} {label1} {label2}
%
% \docompletefloat {nummer} {referentie} {lijst}
% {plaats} {label1} {label2} {inhoud}
@@ -1270,17 +1254,17 @@
{\setbox0\vbox{\whitespace\expanded{\blank[#2]}}%
\global#1\ht0}}}
-\def\calculatefloatskips#1% todo floatparam
- {{\docalculatefloatskip\floattopskip \@@bkspacebefore
- \docalculatefloatskip\floatbottomskip \@@bkspaceafter
- \docalculatefloatskip\sidefloattopskip {\getvalue{\??fl#1\c!sidespacebefore}}% \@@bksidespacebefore
- \docalculatefloatskip\sidefloatbottomskip{\getvalue{\??fl#1\c!sidespaceafter}}% \@@bksidespaceafter
- \gdef\sidefloattopoffset{\openstrutdepth}% was \def
- \global\floatsideskip \getvalue{\??fl#1\c!margin}%
- \global\sidefloatleftshift \getvalue{\??fl#1\c!leftmargindistance}%
- \global\sidefloatrightshift\getvalue{\??fl#1\c!rightmargindistance}%
- \global\noftopfloats\@@bkntop \relax
- \global\nofbotfloats\@@bknbottom\relax}}
+\def\calculatefloatskips
+ {{\docalculatefloatskip\floattopskip \@@bkspacebefore
+ \docalculatefloatskip\floatbottomskip \@@bkspaceafter
+ \docalculatefloatskip\sidefloattopskip {\floatparameter\c!sidespacebefore}%
+ \docalculatefloatskip\sidefloatbottomskip{\floatparameter\c!sidespaceafter }%
+ \gdef \sidefloattopoffset{\openstrutdepth}% was \def
+ \global\floatsideskip \floatparameter\c!margin
+ \global\sidefloatleftshift \floatparameter\c!leftmargindistance
+ \global\sidefloatrightshift\floatparameter\c!rightmargindistance
+ \global\noftopfloats \@@bkntop \relax
+ \global\nofbotfloats \@@bknbottom\relax}}
\let\floatcaptionsuffix\empty % an optional suffix
\let\floatcaptionnumber\empty % a logical counter
@@ -1338,20 +1322,20 @@
\let\placefloatlabeltext \placefloatcaptiontext
\let\placefloatlabelreference \placefloatcaptionreference
-\def\borderedfloatbox#1%
- {\localframed[\??fl#1][\c!location=\v!normal]{\box\floatbox}}
+\def\borderedfloatbox
+ {\localframed[\??fl\currentfloat][\c!location=\v!normal]{\box\floatbox}}
\newbox\captionbox
-\def\putcompletecaption#1#2#3%
+\def\putcompletecaption#1#2%
{\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}%
% \floatcaptionparameter\c!before % test for side effects first
\noindent
- \xdef\lastcaptiontag{\strut#2}%
- \dostartattributes{\??kj#1}\c!style\c!color\empty
+ \xdef\lastcaptiontag{\strut#1}%
+ \dostartattributes{\??kj\currentfloat}\c!style\c!color\empty
\ifnofloatnumber
\else
- \hbox{\doattributes{\??kj#1}\c!headstyle\c!headcolor{\strut#2}}%
+ \hbox{\doattributes{\??kj\currentfloat}\c!headstyle\c!headcolor{\strut#1}}%
\ifnofloatcaption \else \ifemptyfloatcaption \else
\doifelsenothing{\floatcaptionparameter\c!spaceinbetween}
{\scratchskip\floatcaptionparameter\c!distance\relax
@@ -1363,10 +1347,10 @@
\globallet\lastcaptionht\!!zeropoint
\globallet\lastcaptiondp\!!zeropoint
\else
- \doattributes{\??kj#1}\c!textstyle\c!textcolor
+ \doattributes{\??kj\currentfloat}\c!textstyle\c!textcolor
{\xdef\lastcaptionht{\strutheight}%
\xdef\lastcaptiondp{\strutdepth}%
- \begstrut#3\endstrut\endgraf}%
+ \begstrut#2\endstrut\endgraf}%
\fi
\dostopattributes
% \floatcaptionparameter\c!after % test for side effects first
@@ -1389,10 +1373,42 @@
%\stelblokkopjesin[\c!align=\v!left]
%\stelblokkopjesin[\c!align=\v!right]
-\def\docheckcaptioncontent#1#2#3#4%
+
+% \definefloat [figure-1] [figure]
+% \definefloat [figure-2] [figure]
+% \setupfloat [figure-1] [location=left,leftmargin=10mm]
+% \setupfloat [figure-2] [location=left,leftmargin=-5mm]
+% \setupcaption [figure-1] [align=flushleft]
+% \setupcaption [figure-2] [align=flushleft,leftmargin=15mm]
+%
+% \startsetups somefigure
+% \ifdim\wd\nextbox>\textwidth
+% \placefloat[figure-2][][]{}{\box\nextbox}
+% \else
+% \placefloat[figure-1][][]{}{\box\nextbox}
+% \fi
+% \stopsetups
+%
+% \def\setupswithbox[#1]{\dowithnextbox{\setups[#1]}\vbox}
+%
+% test \setupswithbox[somefigure]{\framed[width=3cm] {}} test
+% test \setupswithbox[somefigure]{\framed[width=\dimexpr\textwidth+3cm\relax]{}} test
+
+\def\dosetcaptionthings
+ {\setups[\floatcaptionparameter\c!setups]% expanded ?
+% \advance\leftskip \floatcaptionparameter\c!leftmargin
+% \advance\rightskip\floatcaptionparameter\c!rightmargin
+ \relax}
+
+\def\dofakecaptionthings
+ {\hbox{\dosetcaptionthings\hskip\leftskip\hskip\rightskip}}
+
+\def\docheckcaptioncontent#1#2%
{\ifnofloatcaption \else
\setbox\tempcaptionbox\hbox
- {\trialtypesettingtrue\notesenabledfalse\putcompletecaption{#4}{#2}{#3}}%
+ {\trialtypesettingtrue
+ \notesenabledfalse
+ \putcompletecaption{#1}{#2}}%
% new, \placefigure{\XMLflush{somecaption}}{} passes earlier empty check
% so here we misuse the scratch box; actually this means that the previous
% test can go away (some day, when i redo this module)
@@ -1401,6 +1417,8 @@
\ifnofloatnumber
\global\nofloatcaptiontrue
\fi
+ \else
+ \setbox\tempcaptionbox\hbox{\dosetcaptionthings\hskip\leftskip\box\tempcaptionbox}% yet incomplete
\fi
\fi}
@@ -1408,56 +1426,21 @@
\ifx\moveboxontogrid\undefined \let\movecaptionontogrid\gobblethreearguments \fi
-% \def\dosetpagfloat#1#2#3#4% \copy wegwerken
-% {\bgroup
-% \setlocalfloathsize
-% \ifnum\floatrotation>0
-% \swapdimens\hsize\vsize
-% \fi
-% \forgetall
-% \postponenotes
-% \dontcomplain
-% \setbox\tempfloatbox\vbox{\borderedfloatbox{#4}}%
-% \def\locatefloat
-% {\chardef\alignstrutmode\zerocount
-% \alignedline{\floatparameter\c!location}\v!middle}%
-% \docheckcaptioncontent{#1}{#2}{#3}{#4}%
-% \ifnofloatcaption
-% \dopreparenocaption{#1}{#2}{#3}{#4}%
-% \edef\width{\the\wd\floatbox}%
-% \doglobal\addlocalbackgroundtobox\floatbox
-% \else
-% % todo: installable maken, variant/method=auto vs macro
-% \doifinsetelse{\floatcaptionparameter\c!location}{\v!high,\v!middle,\v!low}
-% {\dopreparesidecaption{#1}{#2}{#3}{#4}}
-% {\doifelse{\floatcaptionparameter\c!minwidth}\v!fit
-% {\doifelse{\floatcaptionparameter\c!width}\v!max
-% {\dopreparestackcaptionmax{#1}{#2}{#3}{#4}}
-% {\ifdim\wd\tempcaptionbox>\wd\tempfloatbox % wider caption
-% \doifelse{\floatcaptionparameter\c!width}\v!fit
-% {\dopreparestackcaptionaut{#1}{#2}{#3}{#4}}
-% {\dopreparestackcaptionwid{#1}{#2}{#3}{#4}}%
-% \else
-% \dopreparestackcaptionmin{#1}{#2}{#3}{#4}%
-% \fi}}
-% {\dopreparestackcaptionfix{#1}{#2}{#3}{#4}}}% new, special effects (see icare)
-% \edef\width{\the\wd\tempfloatbox}%
-% \addlocalbackgroundtobox\tempfloatbox
-% \setbox\tempcaptionbox\hbox{\floatcaptionparameter\c!command{\box\tempcaptionbox}}%
-% \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht
-% \addlocalbackgroundtobox\tempcaptionbox
-% \buildfloatbox
-% \fi
-% \ifnum\floatrotation>0
-% \global\setbox\floatbox\vbox
-% {\rotate[\c!rotation=\floatrotation]{\box\floatbox}}%
-% \edef\width{\the\wd\tempfloatbox}%
-% \else
-% \postcenterfloatbox\width
-% \fi
-% \egroup}
-
-\def\dosetpagfloat#1#2#3#4% \copy wegwerken
+\def\locatefloatbox
+ {\chardef\alignstrutmode\zerocount
+ \shiftalignedline
+ {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}%
+ {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}%
+ \alignedline{\floatparameter\c!location}\v!middle}
+
+\def\locatecaptionbox
+ {\chardef\alignstrutmode\zerocount
+ \shiftalignedline
+ {\floatcaptionparameter\c!leftmargin }{\floatcaptionparameter\c!rightmargin}%
+ {\floatcaptionparameter\c!innermargin}{\floatcaptionparameter\c!outermargin}%
+ \alignedline{\floatparameter\c!location}\v!middle}
+
+\def\dosetpagfloat#1#2#3% \copy wegwerken
{\bgroup
\setlocalfloathsize
\ifnum\floatrotation>0
@@ -1466,25 +1449,31 @@
\forgetall
\postponenotes
\dontcomplain
- \setbox\tempfloatbox\vbox{\borderedfloatbox{#4}}%
- \def\locatefloat
- {\chardef\alignstrutmode\zerocount
- \alignedline{\floatparameter\c!location}\v!middle}%
- \docheckcaptioncontent{#1}{#2}{#3}{#4}%
- \ifnofloatcaption
- \dopreparenocaption{#1}{#2}{#3}{#4}%
- \edef\width{\the\wd\floatbox}%
- \doglobal\addlocalbackgroundtobox\floatbox
- \else
- % todo: installable maken, variant/method=auto vs macro
- \dopreparedocaption{#1}{#2}{#3}{#4}%
- \settracedcaptionbox
- \edef\width{\the\wd\tempfloatbox}%
- \addlocalbackgroundtobox\tempfloatbox
- \setbox\tempcaptionbox\hbox{\floatcaptionparameter\c!command{\box\tempcaptionbox}}%
- \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht
- \addlocalbackgroundtobox\tempcaptionbox
- \buildfloatbox
+ \setbox\tempfloatbox\vbox{\borderedfloatbox}%
+ \let\locatefloat \locatefloatbox
+ \let\locatecaption\locatecaptionbox
+ \docheckcaptioncontent{#2}{#3}%
+ \ifcase\floatparameter\c!method
+ \or % automatic
+ \ifnofloatcaption
+ \dopreparenocaption{#1}{#2}{#3}%
+ \edef\width{\the\wd\floatbox}%
+ \doglobal\addlocalbackgroundtobox\floatbox
+ \else
+ % todo: installable maken, variant/method=auto vs macro
+ \dopreparedocaption{#1}{#2}{#3}%
+ \settracedcaptionbox
+ \edef\width{\the\wd\tempfloatbox}%
+ \addlocalbackgroundtobox\tempfloatbox
+ \setbox\tempcaptionbox\hbox
+ {\dosetcaptionthings
+ \floatcaptionparameter\c!command{\box\tempcaptionbox}}%
+ \moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht
+ \addlocalbackgroundtobox\tempcaptionbox
+ \buildfloatbox
+ \fi
+ \or % semi automatic
+ \or % manual
\fi
\ifnum\floatrotation>0
\global\setbox\floatbox\vbox
@@ -1498,31 +1487,31 @@
\def\captionminwidth {15\bodyfontsize}
\def\captionovershoot {2em}
-\def\dopreparenocaption#1#2#3#4%
+\def\dopreparenocaption#1#2#3%
{\global\setbox\floatbox\vbox % pas op als wd groter dan hsize
{\ifinsidecolumns\ifdim\wd\tempfloatbox>\hsize
\let\locatefloat\relax
\fi\fi
\locatefloat{\copy\tempfloatbox}}}
-\def\dopreparedocaption#1#2#3#4%
+\def\dopreparedocaption#1#2#3%
{\doifinsetelse{\floatcaptionparameter\c!location}{\v!top,\v!bottom}
{\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max}
{\doifelse{\floatcaptionparameter\c!minwidth}\v!fit
{\doifelse{\floatcaptionparameter\c!width}\v!max
- {\dopreparestackcaptionmax{#1}{#2}{#3}{#4}}
+ {\dopreparestackcaptionmax{#1}{#2}{#3}}
{\ifdim\wd\tempcaptionbox>\wd\tempfloatbox % wider caption
\doifelse{\floatcaptionparameter\c!width}\v!fit
- {\dopreparestackcaptionaut{#1}{#2}{#3}{#4}}
- {\dopreparestackcaptionwid{#1}{#2}{#3}{#4}}%
+ {\dopreparestackcaptionaut{#1}{#2}{#3}}
+ {\dopreparestackcaptionwid{#1}{#2}{#3}}%
\else
- \dopreparestackcaptionmin{#1}{#2}{#3}{#4}%
+ \dopreparestackcaptionmin{#1}{#2}{#3}%
\fi}}
- {\dopreparestackcaptionfix{#1}{#2}{#3}{#4}}}%
- {\dopreparesidewidthcaption{#1}{#2}{#3}{#4}}}% new, special effects (see icare)
+ {\dopreparestackcaptionfix{#1}{#2}{#3}}}%
+ {\dopreparesidewidthcaption{#1}{#2}{#3}}}% new, special effects (see icare)
{\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max}
- {\dopreparesideautocaption{#1}{#2}{#3}{#4}}
- {\dopreparesidewidthcaption{#1}{#2}{#3}{#4}}}}
+ {\dopreparesideautocaption{#1}{#2}{#3}}
+ {\dopreparesidewidthcaption{#1}{#2}{#3}}}}
% \def\dosettempcaptionbox
% {\dosetraggedvbox{\floatcaptionparameter\c!align}%
@@ -1530,11 +1519,12 @@
\def\dosettempcaptionbox
{\setbox\tempcaptionbox\vbox\bgroup
- %expanded{\setupalign[\v!new,\v!reset,\floatcaptionparameter\c!align,\v!old]}% wrong! see icare
- \expanded{\setupalign[\v!reset,\floatcaptionparameter\c!align]}% i need to check what reset does
- \let\next}
+ %expanded{\setupalign[\v!new,\v!reset,\floatcaptionparameter\c!align,\v!old]}% wrong! see icare
+ \expanded{\setupalign[\v!reset,\floatcaptionparameter\c!align]}% i need to check what reset does
+ \dosetcaptionthings
+ \let\next}
-\def\dopreparesideautocaption#1#2#3#4%
+\def\dopreparesideautocaption#1#2#3%
{\scratchdimen\dimexpr\hsize-\wd\tempfloatbox-\@@bkmargin\relax % was \tfskipsize\relax
\ifdim\wd\tempcaptionbox>\scratchdimen
\ifdim\wd\tempcaptionbox<1.3\scratchdimen
@@ -1543,35 +1533,35 @@
\fi
\dosettempcaptionbox
{\hsize\scratchdimen
- \putcompletecaption{#4}{#2}{#3}}}
+ \putcompletecaption{#2}{#3}}}
-\def\dopreparesidewidthcaption#1#2#3#4%
+\def\dopreparesidewidthcaption#1#2#3%
{\dosettempcaptionbox
{\hsize\floatcaptionparameter\c!width
- \putcompletecaption{#4}{#2}{#3}}}
+ \putcompletecaption{#2}{#3}}}
-\def\dopreparestackcaptionfix#1#2#3#4%
+\def\dopreparestackcaptionfix#1#2#3%
{\dosettempcaptionbox
{\hsize\floatcaptionparameter\c!minwidth % special effects
- \putcompletecaption{#4}{#2}{#3}}}
+ \putcompletecaption{#2}{#3}}}
-\def\dopreparestackcaptionmax#1#2#3#4%
+\def\dopreparestackcaptionmax#1#2#3%
{\dosettempcaptionbox
{\hsize\wd\tempfloatbox
- \putcompletecaption{#4}{#2}{#3}}}
+ \putcompletecaption{#2}{#3}}}
-\def\dopreparestackcaptionwid#1#2#3#4%
+\def\dopreparestackcaptionwid#1#2#3%
{\dosettempcaptionbox
{\hsize\floatcaptionparameter\c!width
- \putcompletecaption{#4}{#2}{#3}}}
+ \putcompletecaption{#2}{#3}}}
-\def\dopreparestackcaptionmin#1#2#3#4%
+\def\dopreparestackcaptionmin#1#2#3%
{\dosettempcaptionbox
{\hsize\wd\tempfloatbox
\doifnothing{\floatcaptionparameter\c!align}\raggedcenter % on purpose overloads align !
- \putcompletecaption{#4}{#2}{#3}}}
+ \putcompletecaption{#2}{#3}}}
-\def\dopreparestackcaptionaut#1#2#3#4%
+\def\dopreparestackcaptionaut#1#2#3%
{\doifsomething{\floatcaptionparameter\c!align}
{\doifnotinset{\v!middle}{\floatcaptionparameter\c!align}%
{\let\captionovershoot\!!zeropoint}}%
@@ -1582,7 +1572,7 @@
{\trialtypesettingtrue
\hsize\captionhsize
\notesenabledfalse
- \putcompletecaption{#4}{#2}{#3}}%
+ \putcompletecaption{#2}{#3}}%
\ifdim\ht\scratchbox>\lineheight % more lines
\dosettempcaptionbox
{\hsize\captionhsize
@@ -1590,11 +1580,11 @@
\ifdim\hsize<\captionminwidth\relax
\hsize\captionhsize
\fi
- \putcompletecaption{#4}{#2}{#3}}%
+ \putcompletecaption{#2}{#3}}%
\else
\dosettempcaptionbox
{\hsize\captionhsize
- \putcompletecaption{#4}{#2}{#3}}%
+ \putcompletecaption{#2}{#3}}%
\fi
\else
% float is smaller of equal to \hsize
@@ -1609,30 +1599,30 @@
\advance\scratchdimen 3em % an average word length
\ifdim\scratchdimen<\hsize \hsize\scratchdimen \fi
\notesenabledfalse
- \putcompletecaption{#4}{#2}{#3}}%
+ \putcompletecaption{#2}{#3}}%
\ifdim\ht\scratchbox>\lineheight
% at least an average word longer than a line
\dosettempcaptionbox
{\scratchdimen\captionhsize
\advance\scratchdimen \captionovershoot
\ifdim\scratchdimen<\hsize \hsize\scratchdimen \fi
- \putcompletecaption{#4}{#2}{#3}}%
+ \putcompletecaption{#2}{#3}}%
\else
% just over a line, don't use an overshoot % % % todo: outer/inner and such
\doifcommonelse{\floatcaptionparameter\c!align}{\v!left,\v!right,\v!flushleft,\v!flushright}
{\dosettempcaptionbox
{\hsize\captionhsize
% strange : \raggedcenter
- \putcompletecaption{#4}{#2}{#3}}}
+ \putcompletecaption{#2}{#3}}}
{% nicer
\dosettempcaptionbox
{\hsize\captionhsize
\doifnothing{\floatcaptionparameter\c!align}\raggedcenter% overloads
- \putcompletecaption{#4}{#2}{#3}}}%
+ \putcompletecaption{#2}{#3}}}%
\fi
\fi}
-\def\dopreparesidecaption#1#2#3#4%
+\def\dopreparesidecaption#1#2#3%
{\scratchdimen\dimexpr\hsize-\wd\tempfloatbox-\@@bkmargin\relax % was \tfskipsize\relax
\ifdim\wd\tempcaptionbox>\scratchdimen
\ifdim\wd\tempcaptionbox<1.3\scratchdimen
@@ -1642,7 +1632,7 @@
\dosettempcaptionbox % \setbox\tempcaptionbox\vbox
{\hsize\scratchdimen
\doifnothing{\floatcaptionparameter\c!align}\raggedright % on purpose overloads align !
- \putcompletecaption{#4}{#2}{#3}}}
+ \putcompletecaption{#2}{#3}}}
\newdimen\tempfloatheight
\newdimen\tempfloatwidth
@@ -1781,62 +1771,6 @@
\def\dofloatboxmiddlebuilder
{\dofloatboxnextbuilder{\vfill\box\tempcaptionbox\vfill}}
-% \def\dofloatboxnormalstackbuilder#1#2#3#4% hbox needed
-% {\tempfloatwidth\wd\tempfloatbox
-% \ifparfloat
-% \hbox{#3}\dofloatboxbetweenstack\hbox{#4}%
-% \else
-% \hbox{#1}\dofloatboxbetweenstack\hbox{#2}%
-% \fi}
-
-% \def\dofloatboxgridstackbuilder#1#2#3#4%
-% {\dp\tempcaptionbox\strutdepth
-% \setbox\scratchbox\vbox
-% {\tempfloatwidth\wd\tempfloatbox
-% \ifparfloat
-% #3\vss\dofloatboxbetweenstack#4%
-% \else
-% #1\vss\dofloatboxbetweenstack#2%
-% \fi}%
-% \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
-% \vbox to \noflines\lineheight{\unvbox\scratchbox}}
-
-% \def\dofloatboxstretchstackbuilder#1#2#3#4%
-% {\dp\tempcaptionbox\strutdepth
-% \setbox\scratchbox\vbox
-% {\locatefloat{\copy#1}%
-% \locatefloat{\copy#2}}%
-% \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
-% \vbox to \noflines\lineheight
-% {\tempfloatwidth\wd\tempfloatbox
-% \ifparfloat
-% #3\vss\dofloatboxbetweenstack\vss#4%
-% \else
-% #1\vss\dofloatboxbetweenstack\vss#2%
-% \fi}}
-
-% \def\dofloatboxtopbuilder
-% {\let\next\dofloatboxnormalstackbuilder
-% \expanded{\processallactionsinset[\floatcaptionparameter\c!location]}
-% [ \v!grid=>\let\next\dofloatboxgridstackbuilder,
-% \v!stretch=>\let\next\dofloatboxstretchstackbuilder]%
-% \next
-% {\locatetextfloat{\box\tempcaptionbox}}
-% {\locatefloat {\box\tempfloatbox }}
-% {\locatesidefloat{\box\tempcaptionbox}}
-% {\hbox {\box\tempfloatbox }}}
-
-% \def\dofloatboxbottombuilder
-% {\let\next\dofloatboxnormalstackbuilder
-% \expanded{\processallactionsinset[\floatcaptionparameter\c!location]}
-% [ \v!grid=>\let\next\dofloatboxgridstackbuilder,
-% \v!stretch=>\let\next\dofloatboxstretchstackbuilder]%
-% \next
-% {\locatefloat {\box\tempfloatbox }}
-% {\locatetextfloat{\box\tempcaptionbox}}
-% {\hbox {\box\tempfloatbox }}
-% {\locatesidefloat{\box\tempcaptionbox}}}
-
% \definefloat
% [lefty][lefties][figure]
% \setupfloat
@@ -1917,8 +1851,8 @@
\def\dofloatboxstretchtopstackbuilder
{\dp\tempcaptionbox\strutdepth
\setbox\scratchbox\vbox
- {\locatefloat{\copy\tempcaptionbox}%
- \locatefloat{\copy\tempfloatbox }}%
+ {\locatecaption{\copy\tempcaptionbox}%
+ \locatefloat {\copy\tempfloatbox }}%
\getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
\vbox to \noflines\lineheight
{\tempfloatwidth\wd\tempfloatbox
@@ -1935,8 +1869,8 @@
\def\dofloatboxstretchbotstackbuilder
{\dp\tempcaptionbox\strutdepth
\setbox\scratchbox\vbox
- {\locatefloat{\copy\tempfloatbox }%
- \locatefloat{\copy\tempcaptionbox}}%
+ {\locatefloat {\copy\tempfloatbox }%
+ \locatecaption{\copy\tempcaptionbox}}%
\getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy
\vbox to \noflines\lineheight
{\tempfloatwidth\wd\tempfloatbox
@@ -1964,8 +1898,8 @@
\v!stretch=>\let\next\dofloatboxstretchstackbuilder]%
\next}
-\def\relocatecaptionright#1{\locatefloat{\hbox to \tempfloatwidth{\hss#1}}}
-\def\relocatecaptionleft #1{\locatefloat{\hbox to \tempfloatwidth{#1\hss}}}
+\def\relocatecaptionright#1{\locatecaption{\hbox to \tempfloatwidth{\hss#1}}}
+\def\relocatecaptionleft #1{\locatecaption{\hbox to \tempfloatwidth{#1\hss}}}
\long\def\installfloatboxbuilder#1#2{\setvalue{\??kj:#1}{#2}}
@@ -1980,7 +1914,7 @@
\executeifdefined{\??kj:\floatcaptionarrangement}{\getvalue{\??kj:\s!default}}}}
\def\locatetextfloat
- {\let\next\locatefloat
+ {\let\next\locatecaption
\expanded{\processallactionsinset[\floatcaptionparameter\c!location]}
[ \v!left=>\let\next\relocatecaptionleft,
\v!right=>\let\next\relocatecaptionright,
@@ -2041,19 +1975,19 @@
\box\floatbox
\ifdone\hskip\effectiverightskip\fi\hss}}
-\def\dosetparfloat#1#2#3#4%
+\def\dosetparfloat#1#2#3%
{\bgroup
\forgetall
\postponenotes
\dontcomplain
%\showcomposition
- \setbox\tempfloatbox\vbox{\borderedfloatbox{#4}}%
+ \setbox\tempfloatbox\vbox{\borderedfloatbox}%
\addlocalbackgroundtobox\tempfloatbox % no \doglobal
- \docheckcaptioncontent{#1}{#2}{#3}{#4}%
+ \docheckcaptioncontent{#2}{#3}%
\ifnofloatcaption
\global\setbox\floatbox\vbox{\box\tempfloatbox}%
\else
- \dopreparedosidecaption{#1}{#2}{#3}{#4}%
+ \dopreparedosidecaption{#1}{#2}{#3}%
\settracedcaptionbox
\setbox\tempcaptionbox\hbox{\floatcaptionparameter\c!command{\box\tempcaptionbox}}%
\moveboxontogrid\tempcaptionbox{\floatcaptionparameter\c!grid}\lastcaptionht
@@ -2062,24 +1996,29 @@
\fi
\egroup}
-\def\dopreparedosidecaption#1#2#3#4% will be enhanced
+\def\dopreparedosidecaption#1#2#3% will be enhanced
{\doifelse{\floatcaptionparameter\c!width}\v!max
{\dosettempcaptionbox
- {\hsize\wd\tempfloatbox\putcompletecaption{#4}{#2}{#3}}}%
+ {\hsize\wd\tempfloatbox
+ \putcompletecaption{#2}{#3}}}%
{\doifelse{\floatcaptionparameter\c!width}\v!fit
{\ifdim\wd\tempcaptionbox>\wd\tempfloatbox\relax
\setbox\tempcaptionbox\vbox
- {\forgetall\hsize\wd\tempfloatbox\putcompletecaption{#4}{#2}{#3}}%
+ {\forgetall % needed?
+ \hsize\wd\tempfloatbox
+ \dosetcaptionthings
+ \putcompletecaption{#2}{#3}}%
\else
\setbox\tempcaptionbox\hbox to \wd\tempfloatbox
{\hss\box\tempcaptionbox\hss}%
\fi}
{\dosettempcaptionbox
{\hsize\floatcaptionparameter\c!width % \wd\tempfloatbox
- \putcompletecaption{#4}{#2}{#3}}}}}
+ \putcompletecaption{#2}{#3}}}}}
\def\buildsidefloatbox
- {\let\locatefloat\relax
+ {\let\locatefloat \relax
+ \let\locatecaption\relax
\def\locatesidefloat##1%
{\begingroup
\chardef\alignstrutmode\zerocount
@@ -2090,16 +2029,12 @@
\newif\ifparfloat
-\long\def\dosetfloatbox#1#2#3#4% todo : \global\setbox
+\long\def\dosetfloatbox#1#2#3% todo : \global\setbox
{\ifvisible
\par
\edef\floatcaptiondirectives{\floatparameter\c!location,\floatcaptionparameter\c!location}%
- \ifparfloat
- \@EA\dosetparfloat % {#1}{#2}{#3}{#4}%
- \else
- \@EA\dosetpagfloat % {#1}{#2}{#3}{#4}%
- \fi{#1}{#2}{#3}{#4}%
- \setlocalfloatdimensions{#4}{#1}\floatbox\global % tzt arg 3/4 weg
+ \ifparfloat\@EA\dosetparfloat\else\@EA\dosetpagfloat\fi{#1}{#2}{#3}%
+ \setlocalfloatdimensions{#1}\floatbox\global % tzt arg 3/4 weg
\setbox\floatbox\hbox
{\dosavefloatdata\restoretextcolor{\box\floatbox}}%
\global\floatheight\ht\floatbox
@@ -2126,8 +2061,8 @@
\newcounter\noxfloatlocations
-\long\def\dofloat#1#2#3#4%
- {\dosetfloatbox{#1}{#2}{#3}{#4}%
+\long\def\dofloat#1#2#3%
+ {\dosetfloatbox{#1}{#2}{#3}%
\dogetfloatbox{#1}\empty}
\let\naturalfloatheight\!!zeropoint
@@ -2159,7 +2094,7 @@
\vss % gets rid of the depth (unless tabulate)
\rawpagereference\s!flt{#2}}%
\egroup
- \dofloat{#4}{}{#6}{#1}%
+ \dofloat{#4}{}{#6}%
\else
\doglobal\convertargument#6\to\asciititle % \asciititle is global
\ifnofloatnumber
@@ -2167,7 +2102,7 @@
{\unvbox\floatbox % no \vss, keep the depth
\rawreference\s!flt{#2}{{}{\asciititle}}}%
\egroup
- \dofloat{#4}{}{#6}{#1}%
+ \dofloat{#4}{}{#6}%
\else
\preparefloatnumber{#1}%
\global\setbox\floatbox\vbox
@@ -2177,7 +2112,7 @@
\dowritetolist{#3}{\composedsectionnumber}{#6}{#3}}%
\egroup
\preparefullnumber{\??kj#1}\composedsectionnumber\preparednumber
- \dofloat{#4}{\labeltexts{#5}{\preparednumber}}{#6}{#1}%
+ \dofloat{#4}{\labeltexts{#5}{\preparednumber}}{#6}%
\fi
\fi
\global\insidefloatfalse}
@@ -2454,13 +2389,18 @@
\c!before=, % not used (yet)
\c!inbetween={\blank[\v!medium]},
\c!after=, % not used (yet)
-\c!spacebefore=,
-\c!spaceinbetween=, % replaces fuzzy inbetween dual usage
-\c!spaceafter=,
+ \c!spacebefore=,
+ \c!spaceinbetween=, % replaces fuzzy inbetween dual usage
+ \c!spaceafter=,
\c!width=\v!fit,
\c!minwidth=\v!fit, % id est: the width of the floatbox in some cases
\c!headstyle=\v!bold,
\c!headcolor=,
+ \c!leftmargin=\zeropoint,
+ \c!rightmargin=\zeropoint,
+ \c!outermargin=\zeropoint,
+ \c!innermargin=\zeropoint,
+ \c!setups=,
\c!style=\v!normal,
\c!color=,
\c!textstyle=,
@@ -2505,6 +2445,11 @@
\c!sidemethod=\ifgridsnapping2\else1\fi, % 0=raw 1=safe (.99pg) 2=tight (-1pt)
\c!indentnext=\v!no,
\c!margin=1em,
+ \c!method=1,
+ \c!leftmargin=\zeropoint, % displacement in 'normal floats'
+ \c!rightmargin=\zeropoint, % idem
+ \c!innermargin=\zeropoint, % idem
+ \c!outermargin=\zeropoint, % idem
\c!leftmargindistance=\zeropoint,
\c!rightmargindistance=\@@bkleftmargindistance,
\c!ntop=2,
diff --git a/tex/context/base/page-imp.tex b/tex/context/base/page-imp.tex
index 3acf201bc..039f36f4c 100644
--- a/tex/context/base/page-imp.tex
+++ b/tex/context/base/page-imp.tex
@@ -144,7 +144,7 @@
\let\pagestoshipout\empty % {1,3,6}
\chardef\whichpagetoshipout=0 % 0=all 1=odd 2=even
-\ifx\processshipoutbox\undefined \let\processshipoutbox\firstofoneargument \fi
+\ifx\finalizeshipoutbox\undefined \let\finalizeshipoutbox\firstofoneargument \fi
\def\actualshipout#1%
{\global\advance\shippedoutpages\plusone
@@ -172,7 +172,7 @@
\vskip\scratchdimen
\hskip\scratchdimen
\hbox % \setbox0=\box.. is nicer
- {\setbox0\hbox{\processshipoutbox{#1}}% just in case there are objects there, hook for testing
+ {\setbox0\hbox{\finalizeshipoutbox{#1}}% just in case there are objects there, hook for testing
\setbox\scratchbox\hbox
{% before the main one !
\ifcase\realfolio \or
diff --git a/tex/context/base/page-ini.tex b/tex/context/base/page-ini.tex
index a51395730..2582f2dc0 100644
--- a/tex/context/base/page-ini.tex
+++ b/tex/context/base/page-ini.tex
@@ -780,9 +780,6 @@
%D Some hooks:
-\newtoks \everybeforeoutput
-\newtoks \everyafteroutput
-
\output{\inotrtrue\the\everybeforeoutput\the\mainoutput\the\everyafteroutput}
\installoutput\synchronizeoutput % maybe add pagediscards
diff --git a/tex/context/base/prop-ini.tex b/tex/context/base/prop-ini.tex
index db6a45c8d..b7aef6e18 100644
--- a/tex/context/base/prop-ini.tex
+++ b/tex/context/base/prop-ini.tex
@@ -39,14 +39,6 @@
{\csname\s!check\currentpropertytype property\endcsname
\global\expandafter\let\csname\??py\s!check\currentproperty\endcsname\empty}
-% \def\checkproperty[#1]%
-% {\bgroup
-% \def\currentproperty{#1}%
-% \docheckproperty
-% \egroup}
-%
-% oeps, was wrong, no reset
-
\def\checkproperty[#1]%
{\bgroup
\def\currentproperty{#1}%
@@ -122,14 +114,14 @@
\doifelsevalue{\??py#1\c!method}\v!command
{\doifelsevalue{\??py#1\c!global}\v!yes
{\setgvalue{\e!start#1}{\dostartproperty{#1}}%
- \letgvalue{\e!stop#1}\dostopproperty}%
+ \letgvalue{\e!stop #1}\dostopproperty}%
{\setgvalue{\e!start#1}{\dostartgproperty{#1}}%
- \letgvalue{\e!stop#1}\dostopgproperty}}%
+ \letgvalue{\e!stop #1}\dostopgproperty}}%
{\doifelsevalue{\??py#1\c!global}\v!yes
{\setgvalue{\e!start#2}[##1]{\dostartproperty{##1}}%
- \letgvalue{\e!stop#2}\dostopproperty}%
+ \letgvalue{\e!stop #2}\dostopproperty}%
{\setgvalue{\e!start#2}[##1]{\dostartgproperty{##1}}%
- \letgvalue{\e!stop#2}\dostopgproperty}}}
+ \letgvalue{\e!stop #2}\dostopgproperty}}}
\def\nododefineproperty[#1][#2][#3]%
{}
@@ -146,17 +138,6 @@
\getparameters[\??py][#1]%
\fi}
-% \def\propertyparameter#1% expands to #1 when not defined (see \define...)
-% {\csname\??py
-% \ifcsname\??py\currentproperty#1\endcsname
-% \currentproperty#1%
-% \else\ifcsname\??py\currentpropertytype#1\endcsname
-% \currentpropertytype#1%
-% \else
-% :n:\currentproperty
-% \fi\fi
-% \endcsname}
-
\letvalue{\??py\s!empty}\empty
% beware, normally \*parameter concerns the current one
diff --git a/tex/context/base/prop-lay.tex b/tex/context/base/prop-lay.tex
index 0e5038d19..f29298976 100644
--- a/tex/context/base/prop-lay.tex
+++ b/tex/context/base/prop-lay.tex
@@ -17,14 +17,6 @@
\unprotect
-% \def\checklayerproperty
-% {\dodefineviewerlayer
-% \currentproperty % tag
-% {\checkedpropertyparameter\c!title\currentproperty}%
-% {\checkedpropertyparameter\c!state\v!start}% visible or hidden
-% {0}% type (1=frozen)
-% {0}}% printable
-
\def\checklayerproperty
{\doifelse{\checkedpropertyparameter\v!printable\currentproperty}\v!no
{\def\printviewerlayer{0}}
diff --git a/tex/context/base/prop-mis.mkii b/tex/context/base/prop-mis.mkii
new file mode 100644
index 000000000..3b372546d
--- /dev/null
+++ b/tex/context/base/prop-mis.mkii
@@ -0,0 +1,155 @@
+%D \module
+%D [ file=prop-mis,
+%D version=2004.05.29, % some code moved from private modules
+%D title=\CONTEXT\ Property Macros,
+%D subtitle=Miscelaneous,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D Overprint cum suis.
+
+\definepropertyhandler \v!overprint {\dostartoverprint}
+\definepropertyhandler \v!knockout {\dostopoverprint }
+
+\def\startoverprintproperty
+ {\ifincolor
+ \propertyhandler\currentproperty
+ \dooverprintmark\currentproperty
+ \fi}
+
+\def\stopoverprintproperty
+ {\ifincolor
+ \ifcase\currentpropertylevel\or
+ \dostopoverprint
+ \dooverprintmark\empty
+ \else
+ \propertyhandler\previousproperty
+ \dooverprintmark\previousproperty
+ \fi
+ \fi}
+
+\rawnewmark\overprintmark
+
+\def\dooverprintmark#1%
+ {\ifinpagebody \else \ifinframed \else
+ \expanded{\rawsetmark\noexpand\overprintmark{#1}}%
+ \fi \fi}
+
+\def\pushoverprintproperty
+ {\doifsomething{\rawgetbotmark\overprintmark}\dostopoverprint}
+
+\def\popoverprintproperty
+ {\doifsomething{\rawgetbotmark\overprintmark}%
+ {\propertyhandler{\rawgetbotmark\overprintmark}}}
+
+\def\popsplitoverprintproperty
+ {\getsplitmarks\overprintmark % hier wel
+ \doifsomething{\rawgetsplitbotmark\overprintmark}%
+ {\propertyhandler{\rawgetsplitbotmark\overprintmark}}}
+
+\appendtoks \pushoverprintproperty \to \everypushproperties
+\appendtoks \popoverprintproperty \to \everypopproperties
+\appendtoks \popsplitoverprintproperty \to \everypopsplitproperties
+
+%D Negative cum suis.
+
+\definepropertyhandler \v!negative {\dostartnegative}
+\definepropertyhandler \v!positive {\dostopnegative }
+
+\def\startnegativeproperty
+ {\ifincolor
+ \propertyhandler\currentproperty
+ \donegativemark\currentproperty
+ \fi}
+
+\def\stopnegativeproperty
+ {\ifincolor
+ \ifcase\currentpropertylevel\or
+ \dostopnegative
+ \donegativemark\empty
+ \else
+ \propertyhandler\previousproperty
+ \donegativemark\previousproperty
+ \fi
+ \fi}
+
+\rawnewmark\negativemark
+
+\def\donegativemark#1%
+ {\ifinpagebody \else \ifinframed \else
+ \expanded{\rawsetmark\noexpand\negativemark{#1}}%
+ \fi \fi}
+
+\def\pushnegativeproperty
+ {\doifsomething{\rawgetbotmark\negativemark}\dostopnegative}
+
+\def\popnegativeproperty
+ {\doifsomething{\rawgetbotmark\overprintmark}%
+ {\propertyhandler{\rawgetbotmark\negativemark}}}
+
+\def\popsplitnegativeproperty
+ {\getsplitmarks\negativemark % hier wel
+ \doifsomething{\rawgetsplitbotmark\negativemark}%
+ {\propertyhandler{\rawgetsplitbotmark\negativemark}}}
+
+\appendtoks \pushnegativeproperty \to \everypushproperties
+\appendtoks \popnegativeproperty \to \everypopproperties
+\appendtoks \popsplitnegativeproperty \to \everypopsplitproperties
+
+%D Effects.
+
+\definepropertyhandler \v!normal {0}
+\definepropertyhandler \v!inner {0}
+\definepropertyhandler \v!outer {1}
+\definepropertyhandler \v!both {2}
+\definepropertyhandler \v!hidden {3}
+
+\def\effectpropertydata#1%
+ {{\propertyhandler{#1}}%
+ {\propertyparameter{#1}\c!rulethickness}%
+ {\propertyparameter{#1}\c!stretch}}
+
+\def\starteffectproperty
+ {\expanded{\dostartfonteffect\effectpropertydata\currentproperty}%
+ \doeffectmark{\effectpropertydata\currentproperty}}
+
+\def\stopeffectproperty
+ {\dostopfonteffect
+ \ifcase\currentpropertylevel\or
+ \doeffectmark\empty
+ \else
+ \expanded{\dostartfonteffect\effectpropertydata\previousproperty}%
+ \doeffectmark{\effectpropertydata\previousproperty}%
+ \fi}
+
+\rawnewmark\effectmark
+
+\def\doeffectmark#1%
+ {\ifinpagebody \else \ifinframed \else
+ \expanded{\rawsetmark\noexpand\effectmark{#1}}% could be number
+ \fi \fi}
+
+\def\pusheffectproperty
+ {\doifsomething{\rawgetbotmark\effectmark}\dostopfonteffect}
+
+\def\popeffectproperty
+ {\doifsomething{\rawgetbotmark\effectmark}%
+ {\expanded{\dostartfonteffect\rawgetbotmark\effectmark}}}
+
+\def\popspliteffectproperty
+ {\getsplitmarks\effectmark
+ \doifsomething{\rawgetsplitbotmark\effectmark}%
+ {\expanded{\dostartfonteffect\rawgetsplitbotmark\effectmark}}}
+
+\appendtoks \pusheffectproperty \to \everypushproperties
+\appendtoks \popeffectproperty \to \everypopproperties
+\appendtoks \popspliteffectproperty \to \everypopsplitproperties
+
+\protect \endinput
diff --git a/tex/context/base/prop-mis.mkiv b/tex/context/base/prop-mis.mkiv
new file mode 100644
index 000000000..ee292155e
--- /dev/null
+++ b/tex/context/base/prop-mis.mkiv
@@ -0,0 +1,46 @@
+%D \module
+%D [ file=prop-mis,
+%D version=2004.05.29, % some code moved from private modules
+%D title=\CONTEXT\ Property Macros,
+%D subtitle=Miscelaneous,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D Overprint cum suis.
+
+\definepropertyhandler \v!overprint {\dotriggeroverprint\v!overprint}
+\definepropertyhandler \v!knockout {\dotriggeroverprint\v!knockout }
+
+\def\startoverprintproperty{\dotriggeroverprint\v!overprint}
+\def\stopoverprintproperty {\dotriggeroverprint\v!knockout }
+
+%D Negative cum suis.\def\dotriggeroverprint#1{\csname(os:#1)\endcsname}
+
+\definepropertyhandler \v!negative {\dotriggernegative\v!negative}
+\definepropertyhandler \v!positive {\dotriggernegative\v!positive}
+
+\def\startnegativeproperty{\dotriggernegative\v!negative}
+\def\stopnegativeproperty {\dotriggernegative\v!positive}
+
+%D Effects.
+
+\def\mktriggereffect#1%
+ {\dotriggereffect{#1}{\propertyparameter{#1}\c!stretch}{\propertyparameter{#1}\c!rulethickness}}
+
+\definepropertyhandler \v!normal {\mktriggereffect\v!normal}
+\definepropertyhandler \v!inner {\mktriggereffect\v!inner }
+\definepropertyhandler \v!outer {\mktriggereffect\v!outer }
+\definepropertyhandler \v!both {\mktriggereffect\v!both }
+\definepropertyhandler \v!hidden {\mktriggereffect\v!hidden}
+
+\def\starteffectproperty{\mktriggereffect\currentproperty}
+\def\stopeffectproperty {\mktriggereffect\v!normal }
+
+\protect \endinput
diff --git a/tex/context/base/prop-mis.tex b/tex/context/base/prop-mis.tex
index 769fc33f4..ed287d044 100644
--- a/tex/context/base/prop-mis.tex
+++ b/tex/context/base/prop-mis.tex
@@ -26,97 +26,11 @@
\defineproperty[\v!overprint][\s!overprint] [\c!method=\v!command]
\defineproperty[\v!knockout] [\s!overprint] [\c!method=\v!command]
-\definepropertyhandler \v!overprint {\dostartoverprint}
-\definepropertyhandler \v!knockout {\dostopoverprint }
-
-\def\startoverprintproperty
- {\ifincolor
- \propertyhandler\currentproperty
- \dooverprintmark\currentproperty
- \fi}
-
-\def\stopoverprintproperty
- {\ifincolor
- \ifcase\currentpropertylevel\or
- \dostopoverprint
- \dooverprintmark\empty
- \else
- \propertyhandler\previousproperty
- \dooverprintmark\previousproperty
- \fi
- \fi}
-
-\rawnewmark\overprintmark
-
-\def\dooverprintmark#1%
- {\ifinpagebody \else \ifinframed \else
- \expanded{\rawsetmark\noexpand\overprintmark{#1}}%
- \fi \fi}
-
-\def\pushoverprintproperty
- {\doifsomething{\rawgetbotmark\overprintmark}\dostopoverprint}
-
-\def\popoverprintproperty
- {\doifsomething{\rawgetbotmark\overprintmark}%
- {\propertyhandler{\rawgetbotmark\overprintmark}}}
-
-\def\popsplitoverprintproperty
- {\getsplitmarks\overprintmark % hier wel
- \doifsomething{\rawgetsplitbotmark\overprintmark}%
- {\propertyhandler{\rawgetsplitbotmark\overprintmark}}}
-
-\appendtoks \pushoverprintproperty \to \everypushproperties
-\appendtoks \popoverprintproperty \to \everypopproperties
-\appendtoks \popsplitoverprintproperty \to \everypopsplitproperties
-
%D Negation.
\defineproperty [\v!negative] [\s!negative] [\c!method=\v!command]
\defineproperty [\v!positive] [\s!negative] [\c!method=\v!command]
-\definepropertyhandler \v!negative {\dostartnegative}
-\definepropertyhandler \v!positive {\dostopnegative }
-
-\def\startnegativeproperty
- {\ifincolor
- \propertyhandler\currentproperty
- \donegativemark\currentproperty
- \fi}
-
-\def\stopnegativeproperty
- {\ifincolor
- \ifcase\currentpropertylevel\or
- \dostopnegative
- \donegativemark\empty
- \else
- \propertyhandler\previousproperty
- \donegativemark\previousproperty
- \fi
- \fi}
-
-\rawnewmark\negativemark
-
-\def\donegativemark#1%
- {\ifinpagebody \else \ifinframed \else
- \expanded{\rawsetmark\noexpand\negativemark{#1}}%
- \fi \fi}
-
-\def\pushnegativeproperty
- {\doifsomething{\rawgetbotmark\negativemark}\dostopnegative}
-
-\def\popnegativeproperty
- {\doifsomething{\rawgetbotmark\overprintmark}%
- {\propertyhandler{\rawgetbotmark\negativemark}}}
-
-\def\popsplitnegativeproperty
- {\getsplitmarks\negativemark % hier wel
- \doifsomething{\rawgetsplitbotmark\negativemark}%
- {\propertyhandler{\rawgetsplitbotmark\negativemark}}}
-
-\appendtoks \pushnegativeproperty \to \everypushproperties
-\appendtoks \popnegativeproperty \to \everypopproperties
-\appendtoks \popsplitnegativeproperty \to \everypopsplitproperties
-
%D Special font effects.
\setupproperty
@@ -130,95 +44,8 @@
\defineproperty [\v!normal] [\s!effect]
\defineproperty [\v!hidden] [\s!effect]
-\definepropertyhandler \v!normal {0}
-\definepropertyhandler \v!inner {0}
-\definepropertyhandler \v!outer {1}
-\definepropertyhandler \v!both {2}
-\definepropertyhandler \v!hidden {3}
-
-% \def\handleeffectproperty#1%
-% {\expanded{\dostartfonteffect
-% {\propertyhandler{#1}}%
-% {\propertyparameter{#1}\c!lijndikte}%
-% {\propertyparameter{#1}\c!rek}}}
-
-% \def\starteffectproperty
-% {\handleeffectproperty\currentproperty
-% \doeffectmark\currentproperty}
-
-% \def\stopeffectproperty
-% {\dostopfonteffect
-% \ifcase\currentpropertylevel\or
-% \doeffectmark\empty
-% \else
-% \handleeffectproperty\previousproperty
-% \doeffectmark\previousproperty
-% \fi}
-
-% \rawnewmark\effectmark
-
-% \def\doeffectmark#1%
-% {\ifinpagebody \else \ifinframed \else
-% \expanded{\rawsetmark\noexpand\effectmark{#1}}% could be number
-% \fi \fi}
-
-% \def\pusheffectproperty
-% {\doifsomething{\rawgetbotmark\effectmark}\dostopfonteffect}
-
-% \def\popeffectproperty
-% {\doifsomething{\rawgetbotmark\effectmark}%
-% {\handleeffectproperty{\rawgetbotmark\effectmark}}}
-
-% \def\popspliteffectproperty
-% {\getsplitmarks\effectmark
-% \doifsomething{\rawgetsplitbotmark\effectmark}%
-% {\handleeffectproperty{\rawgetsplitbotmark\effectmark}}}
-
-% \appendtoks \pusheffectproperty \to \everypushproperties
-% \appendtoks \popeffectproperty \to \everypopproperties
-% \appendtoks \popspliteffectproperty \to \everypopsplitproperties
-
-% %
-
-\def\effectpropertydata#1%
- {{\propertyhandler{#1}}%
- {\propertyparameter{#1}\c!rulethickness}%
- {\propertyparameter{#1}\c!stretch}}
-
-\def\starteffectproperty
- {\expanded{\dostartfonteffect\effectpropertydata\currentproperty}%
- \doeffectmark{\effectpropertydata\currentproperty}}
-
-\def\stopeffectproperty
- {\dostopfonteffect
- \ifcase\currentpropertylevel\or
- \doeffectmark\empty
- \else
- \expanded{\dostartfonteffect\effectpropertydata\previousproperty}%
- \doeffectmark{\effectpropertydata\previousproperty}%
- \fi}
-
-\rawnewmark\effectmark
-
-\def\doeffectmark#1%
- {\ifinpagebody \else \ifinframed \else
- \expanded{\rawsetmark\noexpand\effectmark{#1}}% could be number
- \fi \fi}
-
-\def\pusheffectproperty
- {\doifsomething{\rawgetbotmark\effectmark}\dostopfonteffect}
-
-\def\popeffectproperty
- {\doifsomething{\rawgetbotmark\effectmark}%
- {\expanded{\dostartfonteffect\rawgetbotmark\effectmark}}}
-
-\def\popspliteffectproperty
- {\getsplitmarks\effectmark
- \doifsomething{\rawgetsplitbotmark\effectmark}%
- {\expanded{\dostartfonteffect\rawgetsplitbotmark\effectmark}}}
+%D Plugin:
-\appendtoks \pusheffectproperty \to \everypushproperties
-\appendtoks \popeffectproperty \to \everypopproperties
-\appendtoks \popspliteffectproperty \to \everypopsplitproperties
+\loadmarkfile{prop-mis}
\protect \endinput
diff --git a/tex/context/base/s-abr-01.tex b/tex/context/base/s-abr-01.tex
index 98e36e2f1..3933b0a63 100644
--- a/tex/context/base/s-abr-01.tex
+++ b/tex/context/base/s-abr-01.tex
@@ -46,6 +46,7 @@
\logo [CD] {cd}
\logo [CDROM] {cdrom}
\logo [CID] {cid}
+\logo [CJK] {cjk}
\logo [CMR] {cmr}
\logo [CMYK] {cmyk}
\logo [CODHOST] {CodHost}
diff --git a/tex/context/base/spec-dpx.tex b/tex/context/base/spec-dpx.tex
index 44bbe10b6..d8ec1e518 100644
--- a/tex/context/base/spec-dpx.tex
+++ b/tex/context/base/spec-dpx.tex
@@ -393,6 +393,7 @@
\global\let\currentPDFresources\empty
\fi
\special{pdf:exobj}}%
+ \finalizeobjectbox\nextbox
\smashbox\nextbox
\flushatshipout{\box\nextbox}%
\egroup}%
@@ -749,6 +750,7 @@
{\scratchdimen\wd#2\scratchdimen.5\scratchdimen\hskip-\the\scratchdimen
\special{pdf:uxobj @MPPDF::\MPPDFobjectcounter}}}}%
\expanded{\doDVIPDFMXstartobject\zerocount{MPPDF}\MPPDFobjectcounter{\the\wd#2}{\the\ht#2}{\the\dp#2}}%
+ \finalizeobjectbox#2%
\box#2%
\doDVIPDFMXstopobject}
diff --git a/tex/context/base/spec-fdf.tex b/tex/context/base/spec-fdf.tex
index 7b99dfcc9..3531ca0d9 100644
--- a/tex/context/base/spec-fdf.tex
+++ b/tex/context/base/spec-fdf.tex
@@ -329,12 +329,9 @@
\def\doPDFsetupwhateverbox#1#2#3#4#5#6% watch the extra arguments
{\bgroup
- \!!widtha#5%
- \advance\!!widtha#3%
- \!!heighta-#6%
- \!!heightb#2% extra argument
- \advance\!!heightb -#4%
- \advance\!!heighta \!!heightb
+ \!!widtha \dimexpr#5+#3\relax
+ \!!heightb\dimexpr#2-#4\relax
+ \!!heighta\dimexpr\!!heightb-#6\relax
% sometimes whole values give better results
% \PointsToWholeBigPoints{#3}\left
% \PointsToWholeBigPoints\!!heighta\bottom
@@ -2972,12 +2969,6 @@
{\doPDFregistersomeindexcolor{#1}{#2}{#3}{#4}{Gray}{0.0 1.0}%
{pop}}
-% \def\doPDFregisterfigurecolor#1%
-% {\dogetobjectreference
-% {PDF\ifcase\internalspotcolorsize{#1} CS\or CS\else IX\fi}
-% {\internalspotcolorname{#1}}
-% \PDFimagecolorreference}
-
\let\checkpredefinedcolor\predefineindexcolor % we need an index in order to negate bitmaps
\def\doPDFregisterfigurecolor#1% always an index color
diff --git a/tex/context/base/spec-tpd.tex b/tex/context/base/spec-tpd.tex
index 428eb2750..37926efb5 100644
--- a/tex/context/base/spec-tpd.tex
+++ b/tex/context/base/spec-tpd.tex
@@ -906,6 +906,7 @@
% won't work in xforms; some day I will optimize
% this.
\the\everyPDFxform
+ \finalizeobjectbox\nextbox
\immediate\pdfxform
resources {\currentPDFresources\the\pdfpageresources}%
\nextbox
@@ -1360,6 +1361,7 @@
\def\setMPPDFobject#1#2% resources boxnumber
{\the\everyPDFxform
+ \finalizeobjectbox{#2}%
\immediate\pdfxform resources{#1}#2%
\edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}}
diff --git a/tex/context/base/syst-con.lua b/tex/context/base/syst-con.lua
index 273bc5b5c..9f35d68b6 100644
--- a/tex/context/base/syst-con.lua
+++ b/tex/context/base/syst-con.lua
@@ -1,30 +1,28 @@
--- filename : syst-con.lua
--- comment : companion to syst-con.tex (in ConTeXt)
--- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
--- copyright: PRAGMA ADE / ConTeXt Development Team
--- license : see context related readme files
+if not modules then modules = { } end modules ['syst-con'] = {
+ version = 1.001,
+ comment = "companion to syst-con.tex",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
--- remark : compact version
+converters = converters or { }
-if not versions then versions = { } end versions['syst-con'] = 1.001
-if not convert then convert = { } end
-
--- For raw 8 bit characters, the offset is 0x110000 (bottom of plane 18)
--- at the top of luatex's char range but outside the unicode range.
-
-function convert.lchexnumber (n) tex.sprint(string.format("%x" ,n)) end
-function convert.uchexnumber (n) tex.sprint(string.format("%X" ,n)) end
-function convert.lchexnumbers (n) tex.sprint(string.format("%02x",n)) end
-function convert.uchexnumbers (n) tex.sprint(string.format("%02X",n)) end
-function convert.octnumber (n) tex.sprint(string.format("%03o",n)) end
-function convert.hexstringtonumber(n) tex.sprint(tonumber(n,16)) end
-function convert.octstringtonumber(n) tex.sprint(tonumber(n, 8)) end
-function convert.rawcharacter (n) tex.sprint(unicode.utf8.char(0x110000+n)) end
+--[[ldx--
+<p>For raw 8 bit characters, the offset is 0x110000 (bottom of plane 18) at
+the top of <l n='luatex'/>'s char range but outside the unicode range.</p>
+--ldx]]--
do
- local char = unicode.utf8.char
- local flush = tex.sprint
+ local char, flush, format = unicode.utf8.char, tex.sprint, string.format
- function convert.rawcharacter(n) flush(char(0x110000+n)) end
+ function converters.lchexnumber (n) flush(format("%x" ,n)) end
+ function converters.uchexnumber (n) flush(format("%X" ,n)) end
+ function converters.lchexnumbers (n) flush(format("%02x",n)) end
+ function converters.uchexnumbers (n) flush(format("%02X",n)) end
+ function converters.octnumber (n) flush(format("%03o",n)) end
+ function converters.hexstringtonumber(n) flush(tonumber(n,16)) end
+ function converters.octstringtonumber(n) flush(tonumber(n, 8)) end
+ function converters.rawcharacter (n) flush(char(0x110000+n)) end
end
diff --git a/tex/context/base/syst-con.mkiv b/tex/context/base/syst-con.mkiv
index ddc9fe564..2f84395f0 100644
--- a/tex/context/base/syst-con.mkiv
+++ b/tex/context/base/syst-con.mkiv
@@ -15,13 +15,13 @@
\unprotect
-\def\lchexnumber #1{\ctxlua{convert.lchexnumber(\number#1)}}
-\def\uchexnumber #1{\ctxlua{convert.uchexnumber(\number#1)}}
-\def\lchexnumbers #1{\ctxlua{convert.lchexnumbers(\number#1)}}
-\def\uchexnumbers #1{\ctxlua{convert.uchexnumbers(\number#1)}}
-\def\octnumber #1{\ctxlua{convert.octnumber(\number#1)}}
-\def\hexstringtonumber#1{\ctxlua{convert.hexstringtonumber("#1")}}
-\def\octstringtonumber#1{\ctxlua{convert.octstringtonumber("#1")}}
-\def\rawcharacter #1{\ctxlua{convert.rawcharacter(\number#1)}}
+\def\lchexnumber #1{\ctxlua{converters.lchexnumber(\number#1)}}
+\def\uchexnumber #1{\ctxlua{converters.uchexnumber(\number#1)}}
+\def\lchexnumbers #1{\ctxlua{converters.lchexnumbers(\number#1)}}
+\def\uchexnumbers #1{\ctxlua{converters.uchexnumbers(\number#1)}}
+\def\octnumber #1{\ctxlua{converters.octnumber(\number#1)}}
+\def\hexstringtonumber#1{\ctxlua{converters.hexstringtonumber("#1")}}
+\def\octstringtonumber#1{\ctxlua{converters.octstringtonumber("#1")}}
+\def\rawcharacter #1{\ctxlua{converters.rawcharacter(\number#1)}}
\protect \endinput
diff --git a/tex/context/base/toks-ini.lua b/tex/context/base/toks-ini.lua
index ad046be50..cf313ceb3 100644
--- a/tex/context/base/toks-ini.lua
+++ b/tex/context/base/toks-ini.lua
@@ -48,8 +48,8 @@ tokens.letters = function(str)
return t
end
-collector = collector or { }
-collector.data = collector.data or { }
+collectors = collectors or { }
+collectors.data = collectors.data or { }
function tex.printlist(data)
callbacks.push('token_filter', function ()
@@ -58,27 +58,27 @@ function tex.printlist(data)
end)
end
-function collector.flush(tag)
- tex.printlist(collector.data[tag])
+function collectors.flush(tag)
+ tex.printlist(collectors.data[tag])
end
-function collector.test(tag)
- tex.printlist(collector.data[tag])
+function collectors.test(tag)
+ tex.printlist(collectors.data[tag])
end
-collector.registered = { }
+collectors.registered = { }
-function collector.register(name)
- collector.registered[token.csname_id(name)] = name
+function collectors.register(name)
+ collectors.registered[token.csname_id(name)] = name
end
-function collector.install(tag,end_cs)
- collector.data[tag] = { }
- local data = collector.data[tag]
+function collectors.install(tag,end_cs)
+ collectors.data[tag] = { }
+ local data = collectors.data[tag]
local call = token.command_id("call")
local relax = token.command_id("relax")
local endcs = token.csname_id(end_cs)
- local expand = collector.registered
+ local expand = collectors.registered
local get = token.get_next -- so no callback!
while true do
local t = get()
@@ -93,13 +93,13 @@ function collector.install(tag,end_cs)
end
end
-collector.show_methods = { }
+collectors.show_methods = { }
-function collector.show(tag, method)
+function collectors.show(tag, method)
if type(tag) == "table" then
- collector.show_methods[method or 'a'](tag)
+ collectors.show_methods[method or 'a'](tag)
else
- collector.show_methods[method or 'a'](collector.data[tag])
+ collectors.show_methods[method or 'a'](collectors.data[tag])
end
end
@@ -108,7 +108,7 @@ commands = commands or { }
commands.letter = token.command_id("letter")
commands.other = token.command_id("other_char")
-function collector.default_words(t,str)
+function collectors.default_words(t,str)
t[#t+1] = tokens.bgroup
t[#t+1] = token.create("red")
for k,v in ipairs(str) do
@@ -117,10 +117,10 @@ function collector.default_words(t,str)
t[#t+1] = tokens.egroup
end
-function collector.with_words(tag,handle)
+function collectors.with_words(tag,handle)
local t, w = { }, { }
- handle = handle or collector.default_words
- for _,v in ipairs(collector.data[tag]) do
+ handle = handle or collectors.default_words
+ for _,v in ipairs(collectors.data[tag]) do
if v[1] == commands.letter then
w[#w+1] = v[2]
else
@@ -134,10 +134,10 @@ function collector.with_words(tag,handle)
if #w > 0 then
handle(t,w)
end
- collector.data[tag] = t
+ collectors.data[tag] = t
end
-function collector.show_token(t)
+function collectors.show_token(t)
if t then
local cmd, chr, id, cs, name = t[1], t[2], t[3], nil, token.command_name(t) or ""
if cmd == commands.letter or cmd == commands.other then
@@ -159,13 +159,13 @@ function collector.show_token(t)
end
end
-function collector.trace()
+function collectors.trace()
local t = token.get_next()
- texio.write_nl(collector.show_token(t))
+ texio.write_nl(collectors.show_token(t))
return t
end
-collector.show_methods.a = function(data) -- no need to store the table, just pass directly
+collectors.show_methods.a = function(data) -- no need to store the table, just pass directly
local flush, ct = tex.sprint, tex.ctxcatcodes
local template = "\\NC %s\\NC %s\\NC %s\\NC %s\\NC %s\\NC\\NR "
flush(ct, "\\starttabulate[|T|Tr|cT|Tr|T|]")
@@ -192,7 +192,7 @@ collector.show_methods.a = function(data) -- no need to store the table, just pa
flush(ct, "\\stoptabulate")
end
-collector.show_methods.b_c = function(data,swap) -- no need to store the table, just pass directly
+collectors.show_methods.b_c = function(data,swap) -- no need to store the table, just pass directly
local flush, ct = tex.sprint, tex.ctxcatcodes
local template = "\\NC %s\\NC %s\\NC %s\\NC\\NR"
if swap then
@@ -228,5 +228,5 @@ collector.show_methods.b_c = function(data,swap) -- no need to store the table,
flush(ct, "\\stoptabulate")
end
-collector.show_methods.b = function(tag) collector.show_methods.b_c(tag,false) end
-collector.show_methods.c = function(tag) collector.show_methods.b_c(tag,true ) end
+collectors.show_methods.b = function(tag) collectors.show_methods.b_c(tag,false) end
+collectors.show_methods.c = function(tag) collectors.show_methods.b_c(tag,true ) end
diff --git a/tex/context/base/toks-ini.tex b/tex/context/base/toks-ini.tex
index 873cfa4d5..d3aa9cb5d 100644
--- a/tex/context/base/toks-ini.tex
+++ b/tex/context/base/toks-ini.tex
@@ -15,11 +15,11 @@
\registerctxluafile{toks-ini}{1.001}
-\def\starttokens [#1]{\ctxlua{collector.install("#1", "stoptokens")}}
+\def\starttokens [#1]{\ctxlua{collectors.install("#1", "stoptokens")}}
\let\stoptokens \relax
-\def\flushtokens [#1]{\ctxlua{collector.flush("#1")}}
-\def\showtokens [#1]{\ctxlua{collector.show("#1")}}
-\def\testtokens [#1]{\ctxlua{collector.with_words("#1")}}
-\def\registertoken #1{\ctxlua{collector.register("#1")}}
+\def\flushtokens [#1]{\ctxlua{collectors.flush("#1")}}
+\def\showtokens [#1]{\ctxlua{collectors.show("#1")}}
+\def\testtokens [#1]{\ctxlua{collectors.with_words("#1")}}
+\def\registertoken #1{\ctxlua{collectors.register("#1")}}
\endinput
diff --git a/tex/context/interface/keys-cz.xml b/tex/context/interface/keys-cz.xml
index 05766e2c8..8a5946ba9 100644
--- a/tex/context/interface/keys-cz.xml
+++ b/tex/context/interface/keys-cz.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="cz" version="2007.08.09 13:04">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="cz" version="2007.08.20 10:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
@@ -182,6 +182,7 @@
<cd:constant name="auto" value="auto"/>
<cd:constant name="autofile" value="autofile"/>
<cd:constant name="balance" value="rovnovaha"/>
+ <cd:constant name="bookmark" value="zalozka"/>
<cd:constant name="wfactor" value="sfaktor"/>
<cd:constant name="inner" value="vnitrni"/>
<cd:constant name="blank" value="prazdny"/>
@@ -287,6 +288,8 @@
<cd:constant name="leftcolor" value="barvavlevo"/>
<cd:constant name="leftstyle" value="stylvlevo"/>
<cd:constant name="leftmargin" value="levyokraj"/>
+ <cd:constant name="innermargin" value="innermargin"/>
+ <cd:constant name="outermargin" value="outermargin"/>
<cd:constant name="leftmargindistance" value="vzdalenostlevehookraje"/>
<cd:constant name="leftoffset" value="levyoffset"/>
<cd:constant name="leftedge" value="levahrana"/>
diff --git a/tex/context/interface/keys-de.xml b/tex/context/interface/keys-de.xml
index 3461fc0fa..7fd1c0971 100644
--- a/tex/context/interface/keys-de.xml
+++ b/tex/context/interface/keys-de.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="de" version="2007.08.09 13:04">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="de" version="2007.08.20 10:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
@@ -182,6 +182,7 @@
<cd:constant name="auto" value="auto"/>
<cd:constant name="autofile" value="autofile"/>
<cd:constant name="balance" value="ausgleichen"/>
+ <cd:constant name="bookmark" value="bookmark"/>
<cd:constant name="wfactor" value="bfaktor"/>
<cd:constant name="inner" value="innen"/>
<cd:constant name="blank" value="blanko"/>
@@ -287,6 +288,8 @@
<cd:constant name="leftcolor" value="linkerfarbe"/>
<cd:constant name="leftstyle" value="linkerstil"/>
<cd:constant name="leftmargin" value="linkerrand"/>
+ <cd:constant name="innermargin" value="innermargin"/>
+ <cd:constant name="outermargin" value="outermargin"/>
<cd:constant name="leftmargindistance" value="linkerrandabstand"/>
<cd:constant name="leftoffset" value="linkeroffset"/>
<cd:constant name="leftedge" value="linkekante"/>
diff --git a/tex/context/interface/keys-en.xml b/tex/context/interface/keys-en.xml
index 3867cf38f..530e61e66 100644
--- a/tex/context/interface/keys-en.xml
+++ b/tex/context/interface/keys-en.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="en" version="2007.08.09 13:04">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="en" version="2007.08.20 10:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
@@ -182,6 +182,7 @@
<cd:constant name="auto" value="auto"/>
<cd:constant name="autofile" value="autofile"/>
<cd:constant name="balance" value="balance"/>
+ <cd:constant name="bookmark" value="bookmark"/>
<cd:constant name="wfactor" value="wfactor"/>
<cd:constant name="inner" value="inner"/>
<cd:constant name="blank" value="blank"/>
@@ -287,6 +288,8 @@
<cd:constant name="leftcolor" value="leftcolor"/>
<cd:constant name="leftstyle" value="leftstyle"/>
<cd:constant name="leftmargin" value="leftmargin"/>
+ <cd:constant name="innermargin" value="innermargin"/>
+ <cd:constant name="outermargin" value="outermargin"/>
<cd:constant name="leftmargindistance" value="leftmargindistance"/>
<cd:constant name="leftoffset" value="leftoffset"/>
<cd:constant name="leftedge" value="leftedge"/>
diff --git a/tex/context/interface/keys-fr.xml b/tex/context/interface/keys-fr.xml
index 5680b44a7..2ba33594d 100644
--- a/tex/context/interface/keys-fr.xml
+++ b/tex/context/interface/keys-fr.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="fr" version="2007.08.09 13:04">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="fr" version="2007.08.20 10:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
@@ -182,6 +182,7 @@
<cd:constant name="auto" value="auto"/>
<cd:constant name="autofile" value="autofile"/>
<cd:constant name="balance" value="equilibre"/>
+ <cd:constant name="bookmark" value="marquepage"/>
<cd:constant name="wfactor" value="facteurlargeur"/>
<cd:constant name="inner" value="interieur"/>
<cd:constant name="blank" value="vide"/>
@@ -287,6 +288,8 @@
<cd:constant name="leftcolor" value="couleurgauche"/>
<cd:constant name="leftstyle" value="leftstyle"/>
<cd:constant name="leftmargin" value="margegauche"/>
+ <cd:constant name="innermargin" value="margeinterieure"/>
+ <cd:constant name="outermargin" value="margeexterieure"/>
<cd:constant name="leftmargindistance" value="distancemargegauche"/>
<cd:constant name="leftoffset" value="decalagegauche"/>
<cd:constant name="leftedge" value="bordgauche"/>
diff --git a/tex/context/interface/keys-it.xml b/tex/context/interface/keys-it.xml
index c9de9c5e9..088c25d10 100644
--- a/tex/context/interface/keys-it.xml
+++ b/tex/context/interface/keys-it.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="it" version="2007.08.09 13:04">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="it" version="2007.08.20 10:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
@@ -182,6 +182,7 @@
<cd:constant name="auto" value="auto"/>
<cd:constant name="autofile" value="autofile"/>
<cd:constant name="balance" value="bilanciamento"/>
+ <cd:constant name="bookmark" value="segnalibro"/>
<cd:constant name="wfactor" value="wfactor"/>
<cd:constant name="inner" value="interno"/>
<cd:constant name="blank" value="rigovuoto"/>
@@ -287,6 +288,8 @@
<cd:constant name="leftcolor" value="coloresinistra"/>
<cd:constant name="leftstyle" value="stilesinistra"/>
<cd:constant name="leftmargin" value="marginesinistro"/>
+ <cd:constant name="innermargin" value="margineinterno"/>
+ <cd:constant name="outermargin" value="margineesterno"/>
<cd:constant name="leftmargindistance" value="distanzamarginesinistro"/>
<cd:constant name="leftoffset" value="offsetsinistro"/>
<cd:constant name="leftedge" value="bordosinistro"/>
diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml
index 08c82396f..63fff53f1 100644
--- a/tex/context/interface/keys-nl.xml
+++ b/tex/context/interface/keys-nl.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="nl" version="2007.08.09 13:04">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="nl" version="2007.08.20 10:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
@@ -182,6 +182,7 @@
<cd:constant name="auto" value="auto"/>
<cd:constant name="autofile" value="autofile"/>
<cd:constant name="balance" value="balanceren"/>
+ <cd:constant name="bookmark" value="bookmark"/>
<cd:constant name="wfactor" value="bfactor"/>
<cd:constant name="inner" value="binnen"/>
<cd:constant name="blank" value="blanko"/>
@@ -287,6 +288,8 @@
<cd:constant name="leftcolor" value="linkerkleur"/>
<cd:constant name="leftstyle" value="linkerletter"/>
<cd:constant name="leftmargin" value="linkermarge"/>
+ <cd:constant name="innermargin" value="binnenmarge"/>
+ <cd:constant name="outermargin" value="buitenmarge"/>
<cd:constant name="leftmargindistance" value="linkermargeafstand"/>
<cd:constant name="leftoffset" value="linkeroffset"/>
<cd:constant name="leftedge" value="linkerrand"/>
diff --git a/tex/context/interface/keys-ro.xml b/tex/context/interface/keys-ro.xml
index 9a0c50c08..7d3b33673 100644
--- a/tex/context/interface/keys-ro.xml
+++ b/tex/context/interface/keys-ro.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="ro" version="2007.08.09 13:04">
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands" name="context" language="ro" version="2007.08.20 10:21">
<cd:variables>
<cd:variable name="lesshyphenation" value="lesshyphenation"/>
@@ -182,6 +182,7 @@
<cd:constant name="auto" value="auto"/>
<cd:constant name="autofile" value="autofile"/>
<cd:constant name="balance" value="balanta"/>
+ <cd:constant name="bookmark" value="semncarte"/>
<cd:constant name="wfactor" value="factorw"/>
<cd:constant name="inner" value="intern"/>
<cd:constant name="blank" value="blanc"/>
@@ -287,6 +288,8 @@
<cd:constant name="leftcolor" value="culoarestanga"/>
<cd:constant name="leftstyle" value="stilstanga"/>
<cd:constant name="leftmargin" value="marginestanga"/>
+ <cd:constant name="innermargin" value="innermargin"/>
+ <cd:constant name="outermargin" value="outermargin"/>
<cd:constant name="leftmargindistance" value="distantamarginestanga"/>
<cd:constant name="leftoffset" value="offsetstanga"/>
<cd:constant name="leftedge" value="bordurastanga"/>