summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2016-06-02 23:03:30 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2016-06-02 23:03:30 +0200
commit2bca80bc96d0182956e57c51b5d4977f714bed5c (patch)
treee0edb360bc5de3067487bcbb31eb040f696e2853 /tex
parenta274872832cdd1e71ce4b019858c61c5a77c6b98 (diff)
downloadcontext-2bca80bc96d0182956e57c51b5d4977f714bed5c.tar.gz
2016-06-02 21:33:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/context-version.pdfbin4250 -> 4245 bytes
-rw-r--r--tex/context/base/mkii/mult-de.mkii1
-rw-r--r--tex/context/base/mkii/mult-en.mkii1
-rw-r--r--tex/context/base/mkii/mult-fr.mkii1
-rw-r--r--tex/context/base/mkii/mult-it.mkii1
-rw-r--r--tex/context/base/mkii/mult-nl.mkii1
-rw-r--r--tex/context/base/mkii/mult-pe.mkii1
-rw-r--r--tex/context/base/mkii/mult-ro.mkii1
-rw-r--r--tex/context/base/mkiv/anch-pos.lua9
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context-todo.tex6
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/font-ext.lua23
-rw-r--r--tex/context/base/mkiv/font-gds.lua941
-rw-r--r--tex/context/base/mkiv/font-lib.mkvi6
-rw-r--r--tex/context/base/mkiv/font-otj.lua2
-rw-r--r--tex/context/base/mkiv/font-sel.lua4
-rw-r--r--tex/context/base/mkiv/good-ctx.lua275
-rw-r--r--tex/context/base/mkiv/good-gen.lua208
-rw-r--r--tex/context/base/mkiv/good-ini.lua349
-rw-r--r--tex/context/base/mkiv/good-mth.lua173
-rw-r--r--tex/context/base/mkiv/layo-ini.lua8
-rw-r--r--tex/context/base/mkiv/lxml-tab.lua6
-rw-r--r--tex/context/base/mkiv/lxml-tex.lua3
-rw-r--r--tex/context/base/mkiv/math-map.lua4
-rw-r--r--tex/context/base/mkiv/mult-def.lua4
-rw-r--r--tex/context/base/mkiv/page-mix.lua3
-rw-r--r--tex/context/base/mkiv/spac-ali.lua2
-rw-r--r--tex/context/base/mkiv/spac-ver.mkiv16
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin9274 -> 9080 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin268373 -> 268642 bytes
-rw-r--r--tex/context/base/mkiv/trac-vis.lua7
-rw-r--r--tex/context/base/mkiv/typo-mar.lua332
-rw-r--r--tex/context/base/mkiv/typo-mar.mkiv6
-rw-r--r--tex/context/interface/mkii/keys-cs.xml1
-rw-r--r--tex/context/interface/mkii/keys-de.xml1
-rw-r--r--tex/context/interface/mkii/keys-en.xml1
-rw-r--r--tex/context/interface/mkii/keys-fr.xml1
-rw-r--r--tex/context/interface/mkii/keys-it.xml1
-rw-r--r--tex/context/interface/mkii/keys-nl.xml1
-rw-r--r--tex/context/interface/mkii/keys-pe.xml1
-rw-r--r--tex/context/interface/mkii/keys-ro.xml1
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin820931 -> 820812 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60791 -> 60787 bytes
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
45 files changed, 1235 insertions, 1173 deletions
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index 11024640d..50c1120d2 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii
index 0762fadfc..dbadca7c5 100644
--- a/tex/context/base/mkii/mult-de.mkii
+++ b/tex/context/base/mkii/mult-de.mkii
@@ -1160,6 +1160,7 @@
\setinterfaceconstant{splitoffset}{splitoffset}
\setinterfaceconstant{spot}{spot}
\setinterfaceconstant{stack}{stack}
+\setinterfaceconstant{stackname}{stackname}
\setinterfaceconstant{start}{start}
\setinterfaceconstant{starter}{starter}
\setinterfaceconstant{state}{status}
diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii
index a16b87a48..751235942 100644
--- a/tex/context/base/mkii/mult-en.mkii
+++ b/tex/context/base/mkii/mult-en.mkii
@@ -1160,6 +1160,7 @@
\setinterfaceconstant{splitoffset}{splitoffset}
\setinterfaceconstant{spot}{spot}
\setinterfaceconstant{stack}{stack}
+\setinterfaceconstant{stackname}{stackname}
\setinterfaceconstant{start}{start}
\setinterfaceconstant{starter}{starter}
\setinterfaceconstant{state}{state}
diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii
index 6c71d4aad..aff330d76 100644
--- a/tex/context/base/mkii/mult-fr.mkii
+++ b/tex/context/base/mkii/mult-fr.mkii
@@ -1160,6 +1160,7 @@
\setinterfaceconstant{splitoffset}{splitoffset}
\setinterfaceconstant{spot}{spot}
\setinterfaceconstant{stack}{stack}
+\setinterfaceconstant{stackname}{stackname}
\setinterfaceconstant{start}{demarre}
\setinterfaceconstant{starter}{starter}
\setinterfaceconstant{state}{etat}
diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii
index a875555bd..2c7dd13e9 100644
--- a/tex/context/base/mkii/mult-it.mkii
+++ b/tex/context/base/mkii/mult-it.mkii
@@ -1160,6 +1160,7 @@
\setinterfaceconstant{splitoffset}{splitoffset}
\setinterfaceconstant{spot}{spot}
\setinterfaceconstant{stack}{stack}
+\setinterfaceconstant{stackname}{stackname}
\setinterfaceconstant{start}{inizia}
\setinterfaceconstant{starter}{starter}
\setinterfaceconstant{state}{stato}
diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii
index efc0d2be3..163628a2f 100644
--- a/tex/context/base/mkii/mult-nl.mkii
+++ b/tex/context/base/mkii/mult-nl.mkii
@@ -1160,6 +1160,7 @@
\setinterfaceconstant{splitoffset}{splitsoffset}
\setinterfaceconstant{spot}{spot}
\setinterfaceconstant{stack}{stapel}
+\setinterfaceconstant{stackname}{stapelnaam}
\setinterfaceconstant{start}{start}
\setinterfaceconstant{starter}{opener}
\setinterfaceconstant{state}{status}
diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii
index 7e5c53791..c2db11315 100644
--- a/tex/context/base/mkii/mult-pe.mkii
+++ b/tex/context/base/mkii/mult-pe.mkii
@@ -1160,6 +1160,7 @@
\setinterfaceconstant{splitoffset}{شکافتن‌آفست}
\setinterfaceconstant{spot}{لکه}
\setinterfaceconstant{stack}{توده}
+\setinterfaceconstant{stackname}{stackname}
\setinterfaceconstant{start}{شروع}
\setinterfaceconstant{starter}{starter}
\setinterfaceconstant{state}{وضعیت}
diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii
index f7121f703..9698bffa5 100644
--- a/tex/context/base/mkii/mult-ro.mkii
+++ b/tex/context/base/mkii/mult-ro.mkii
@@ -1160,6 +1160,7 @@
\setinterfaceconstant{splitoffset}{splitoffset}
\setinterfaceconstant{spot}{spot}
\setinterfaceconstant{stack}{stack}
+\setinterfaceconstant{stackname}{stackname}
\setinterfaceconstant{start}{start}
\setinterfaceconstant{starter}{starter}
\setinterfaceconstant{state}{stare}
diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua
index 77816111d..2cb2e70ee 100644
--- a/tex/context/base/mkiv/anch-pos.lua
+++ b/tex/context/base/mkiv/anch-pos.lua
@@ -468,6 +468,15 @@ function jobpositions.enhance(name)
enhance(tobesaved[name])
end
+function jobpositions.gettobesaved(name,tag)
+ local t = tobesaved[name]
+ if t and tag then
+ return t[tag]
+ else
+ return t
+ end
+end
+
-- scanners.pos = function(name,t) -- name t
-- local name = scanstring()
-- tobesaved[name] = scanstring()
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 4c62d968e..6e7b66a5b 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2016.05.31 09:02}
+\newcontextversion{2016.06.02 21:28}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context-todo.tex b/tex/context/base/mkiv/context-todo.tex
index 0e69b3df8..4df9dc816 100644
--- a/tex/context/base/mkiv/context-todo.tex
+++ b/tex/context/base/mkiv/context-todo.tex
@@ -10,9 +10,6 @@
\startitemize
\startitem
- head||tail cleanup in disc nodes (get rid of temp i.e.\ delay till linebreak)
- \stopitem
- \startitem
cleanup passive nodes
\stopitem
\startitem
@@ -47,6 +44,9 @@
play with par callback and properties
\stopitem
\startitem
+ add flag to font for math engine
+ \stopitem
+ \startitem
get rid of components
\stopitem
\startitem
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 66946af45..06455ca91 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -39,7 +39,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2016.05.31 09:02}
+\edef\contextversion{2016.06.02 21:28}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua
index 61e8c8179..7ab11ffb0 100644
--- a/tex/context/base/mkiv/font-ext.lua
+++ b/tex/context/base/mkiv/font-ext.lua
@@ -36,6 +36,7 @@ local fontdata = hashes.identifiers
local allocate = utilities.storage.allocate
local settings_to_array = utilities.parsers.settings_to_array
local getparameters = utilities.parsers.getparameters
+local gettexdimen = tex.getdimen
local setmetatableindex = table.setmetatableindex
@@ -625,12 +626,20 @@ local function manipulatedimensions(tfmdata,key,value)
if type(value) == "string" and value ~= "" then
local characters = tfmdata.characters
local parameters = tfmdata.parameters
- local emwidth = parameters.quad
- local exheight = parameters.xheight
- local spec = settings_to_array(value)
- local width = (spec[1] or 0) * emwidth
- local height = (spec[2] or 0) * exheight
- local depth = (spec[3] or 0) * exheight
+ local emwidth = parameters.quad
+ local exheight = parameters.xheight
+ local width = 0
+ local height = 0
+ local depth = 0
+ if value == "strut" then
+ height = gettexdimen("strutht")
+ depth = gettexdimen("strutdp")
+ else
+ local spec = settings_to_array(value)
+ width = (spec[1] or 0) * emwidth
+ height = (spec[2] or 0) * exheight
+ depth = (spec[3] or 0) * exheight
+ end
if width > 0 then
local resources = tfmdata.resources
local additions = { }
@@ -687,7 +696,7 @@ local function manipulatedimensions(tfmdata,key,value)
elseif height > 0 and depth > 0 then
for unicode, old_c in next, characters do
old_c.height = height
- old_c.depth = depth
+ old_c.depth = depth
end
elseif height > 0 then
for unicode, old_c in next, characters do
diff --git a/tex/context/base/mkiv/font-gds.lua b/tex/context/base/mkiv/font-gds.lua
deleted file mode 100644
index c24bef315..000000000
--- a/tex/context/base/mkiv/font-gds.lua
+++ /dev/null
@@ -1,941 +0,0 @@
-if not modules then modules = { } end modules ['font-gds'] = {
- version = 1.000,
- comment = "companion to font-gds.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- depends on ctx
-
-local type, next, tonumber = type, next, tonumber
-local gmatch, lower, find, splitup = string.gmatch, string.lower, string.find, string.splitup
-
-local fonts = fonts
-local nodes = nodes
-local attributes = attributes
-local node = node
-
-local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end)
-local report_goodies = logs.reporter("fonts","goodies")
-
-local allocate = utilities.storage.allocate
-local setmetatableindex = table.setmetatableindex
-
-local implement = interfaces.implement
-
-local texsp = tex.sp
-local formatters = string.formatters
-
-local otf = fonts.handlers.otf
-local afm = fonts.handlers.afm
-local tfm = fonts.handlers.tfm
-
-local registerotffeature = otf.features.register
-local registerafmfeature = afm.features.register
-local registertfmfeature = tfm.features.register
-
-local fontgoodies = fonts.goodies or { }
-fonts.goodies = fontgoodies
-
-local typefaces = fonts.typefaces or allocate()
-fonts.typefaces = typefaces
-
-local data = fontgoodies.data or allocate()
-fontgoodies.data = data
-
-local list = fontgoodies.list or { }
-fontgoodies.list = list -- no allocate as we want to see what is there
-
-local addotffeature = otf.enhancers.addfeature
-
-local findfile = resolvers.findfile
-
-local glyph_code = nodes.nodecodes.glyph
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-local getfont = nuts.getfont
-local getchar = nuts.getchar
-local getattr = nuts.getattr
-local traverse_id = nuts.traverse_id
-
-function fontgoodies.report(what,trace,goodies)
- if trace_goodies or trace then
- local whatever = goodies[what]
- if whatever then
- report_goodies("goodie %a found in %a",what,goodies.name)
- end
- end
-end
-
-local function loadgoodies(filename) -- maybe a merge is better
- local goodies = data[filename] -- we assume no suffix is given
- if goodies ~= nil then
- -- found or tagged unfound
- elseif type(filename) == "string" then
- local fullname = findfile(file.addsuffix(filename,"lfg")) or "" -- prefered suffix
- if fullname == "" then
- fullname = findfile(file.addsuffix(filename,"lua")) or "" -- fallback suffix
- end
- if fullname == "" then
- report_goodies("goodie file '%s.lfg' is not found",filename)
- data[filename] = false -- signal for not found
- else
- goodies = dofile(fullname) or false
- if not goodies then
- report_goodies("goodie file %a is invalid",fullname)
- return nil
- elseif trace_goodies then
- report_goodies("goodie file %a is loaded",fullname)
- end
- goodies.name = goodies.name or "no name"
- for name, fnc in next, list do
- if trace_goodies then
- report_goodies("handling goodie %a",name)
- end
- fnc(goodies)
- end
- goodies.initialized = true
- data[filename] = goodies
- end
- end
- return goodies
-end
-
-function fontgoodies.register(name,fnc) -- will be a proper sequencer
- list[name] = fnc
-end
-
-fontgoodies.load = loadgoodies
-
--- register goodies file
-
-local function setgoodies(tfmdata,value)
- local goodies = tfmdata.goodies
- if not goodies then -- actually an error
- goodies = { }
- tfmdata.goodies = goodies
- end
- for filename in gmatch(value,"[^, ]+") do
- -- we need to check for duplicates
- local ok = loadgoodies(filename)
- if ok then
- if trace_goodies then
- report_goodies("assigning goodie %a",filename)
- end
- goodies[#goodies+1] = ok
- end
- end
-end
-
--- this will be split into good-* files and this file might become good-ini.lua
-
--- featuresets
-
-local function flattenedfeatures(t,tt)
- -- first set value dominates
- local tt = tt or { }
- for i=1,#t do
- local ti = t[i]
- if type(ti) == "table" then
- flattenedfeatures(ti,tt)
- elseif tt[ti] == nil then
- tt[ti] = true
- end
- end
- for k, v in next, t do
- if type(k) ~= "number" then -- not tonumber(k)
- if type(v) == "table" then
- flattenedfeatures(v,tt)
- elseif tt[k] == nil then
- tt[k] = v
- end
- end
- end
- return tt
-end
-
--- fonts.features.flattened = flattenedfeatures
-
-local function prepare_features(goodies,name,set)
- if set then
- local ff = flattenedfeatures(set)
- local fullname = goodies.name .. "::" .. name
- local n, s = fonts.specifiers.presetcontext(fullname,"",ff)
- goodies.featuresets[name] = s -- set
- if trace_goodies then
- report_goodies("feature set %a gets number %a and name %a",name,n,fullname)
- end
- return n
- end
-end
-
-fontgoodies.prepare_features = prepare_features
-
-local function initialize(goodies)
- local featuresets = goodies.featuresets
- if featuresets then
- if trace_goodies then
- report_goodies("checking featuresets in %a",goodies.name)
- end
- for name, set in next, featuresets do
- prepare_features(goodies,name,set)
- end
- end
-end
-
-fontgoodies.register("featureset",initialize)
-
-local function setfeatureset(tfmdata,set,features)
- local goodies = tfmdata.goodies -- shared ?
- if goodies then
- local properties = tfmdata.properties
- local what
- for i=1,#goodies do
- -- last one wins
- local g = goodies[i]
- what = g.featuresets and g.featuresets[set] or what
- end
- if what then
- for feature, value in next, what do
- if features[feature] == nil then
- features[feature] = value
- end
- end
- properties.mode = what.mode or properties.mode
- end
- end
-end
-
--- postprocessors (we could hash processor and share code)
-
-function fontgoodies.registerpostprocessor(tfmdata,f,prepend)
- local postprocessors = tfmdata.postprocessors
- if not postprocessors then
- tfmdata.postprocessors = { f }
- elseif prepend then
- table.insert(postprocessors,f,1)
- else
- table.insert(postprocessors,f)
- end
-end
-
-local function setpostprocessor(tfmdata,processor)
- local goodies = tfmdata.goodies
- if goodies and type(processor) == "string" then
- local found = { }
- local asked = utilities.parsers.settings_to_array(processor)
- for i=1,#goodies do
- local g = goodies[i]
- local p = g.postprocessors
- if p then
- for i=1,#asked do
- local a = asked[i]
- local f = p[a]
- if type(f) == "function" then
- found[a] = f
- end
- end
- end
- end
- local postprocessors = tfmdata.postprocessors or { }
- for i=1,#asked do
- local a = asked[i]
- local f = found[a]
- if f then
- postprocessors[#postprocessors+1] = f
- end
- end
- if #postprocessors > 0 then
- tfmdata.postprocessors = postprocessors
- end
- end
-end
-
--- colorschemes
-
-local colorschemes = fontgoodies.colorschemes or allocate { }
-fontgoodies.colorschemes = colorschemes
-colorschemes.data = colorschemes.data or { }
-
-local function setcolorscheme(tfmdata,scheme)
- if type(scheme) == "string" then
- local goodies = tfmdata.goodies
- -- todo : check for already defined in shared
- if goodies then
- local what
- for i=1,#goodies do
- -- last one counts
- local g = goodies[i]
- what = g.colorschemes and g.colorschemes[scheme] or what
- end
- if type(what) == "table" then
- -- this is font bound but we can share them if needed
- -- just as we could hash the conversions (per font)
- local hash = tfmdata.resources.unicodes
- local reverse = { }
- local characters = tfmdata.characters
- for i=1,#what do
- local w = what[i]
- for j=1,#w do
- local name = w[j]
- if name == "*" then
- -- inefficient but only used for tracing anyway
- for _, unicode in next, hash do
- reverse[unicode] = i
- end
- elseif type(name) == "number" then
- reverse[name] = i
- elseif find(name,":",1,true) then
- local start, stop = splitup(name,":")
- start = tonumber(start)
- stop = tonumber(stop)
- if start and stop then
- -- limited usage: we only deal with non reassigned
- -- maybe some day I'll also support the ones with a
- -- tounicode in this range
- for unicode=start,stop do
- if characters[unicode] then
- reverse[unicode] = i
- end
- end
- end
- else
- local unicode = hash[name]
- if unicode then
- reverse[unicode] = i
- end
- end
- end
- end
- tfmdata.properties.colorscheme = reverse
- return
- end
- end
- end
- tfmdata.properties.colorscheme = false
-end
-
-local fontproperties = fonts.hashes.properties
-
-local a_colorscheme = attributes.private('colorscheme')
-local setnodecolor = nodes.tracers.colors.set
-
--- function colorschemes.coloring(head)
--- local lastfont, lastscheme
--- local done = false
--- for n in traverse_id(glyph_code,tonut(head)) do
--- local a = getattr(n,a_colorscheme)
--- if a then
--- local f = getfont(n)
--- if f ~= lastfont then
--- lastscheme = fontproperties[f].colorscheme
--- lastfont = f
--- end
--- if lastscheme then
--- local sc = lastscheme[getchar(n)]
--- if sc then
--- done = true
--- setnodecolor(n,"colorscheme:"..a..":"..sc) -- slow
--- end
--- end
--- end
--- end
--- return head, done
--- end
-
--- seldom used, mostly in manuals, so non critical .. anyhow, somewhat faster:
-
--- function colorschemes.coloring(head)
--- local lastfont = nil
--- local lastattr = nil
--- local lastscheme = nil
--- local lastprefix = nil
--- local done = nil
--- for n in traverse_id(glyph_code,tonut(head)) do
--- local a = getattr(n,a_colorscheme)
--- if a then
--- if a ~= lastattr then
--- lastattr = a
--- lastprefix = "colorscheme:" .. a .. ":"
--- end
--- local f = getfont(n)
--- if f ~= lastfont then
--- lastfont = f
--- lastscheme = fontproperties[f].colorscheme
--- end
--- if lastscheme then
--- local sc = lastscheme[getchar(n)]
--- if sc then
--- setnodecolor(n,lastprefix .. sc) -- slow
--- done = true
--- end
--- end
--- end
--- end
--- return head, done
--- end
-
--- ok, in case we have hundreds of pages colored:
-
-local cache = { } -- this could be a weak table
-
-setmetatableindex(cache,function(t,a)
- local v = { }
- setmetatableindex(v,function(t,c)
- local v = "colorscheme:" .. a .. ":" .. c
- t[c] = v
- return v
- end)
- t[a]= v
- return v
-end)
-
-function colorschemes.coloring(head)
- local lastfont = nil
- local lastattr = nil
- local lastcache = nil
- local lastscheme = nil
- local done = nil
- for n in traverse_id(glyph_code,tonut(head)) do
- local a = getattr(n,a_colorscheme)
- if a then
- local f = getfont(n)
- if f ~= lastfont then
- lastfont = f
- lastscheme = fontproperties[f].colorscheme
- end
- if a ~= lastattr then
- lastattr = a
- lastcache = cache[a]
- end
- if lastscheme then
- local sc = lastscheme[getchar(n)]
- if sc then
- setnodecolor(n,lastcache[sc]) -- we could inline this one
- done = true
- end
- end
- end
- end
- return head, done
-end
-
-function colorschemes.enable()
- nodes.tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring")
- function colorschemes.enable() end
-end
-
-local function setextrafeatures(tfmdata)
- local goodies = tfmdata.goodies
- if goodies then
- for i=1,#goodies do
- local g = goodies[i]
- local f = g.features
- if f then
- for feature, specification in next, f do
- addotffeature(tfmdata.shared.rawdata,feature,specification)
- registerotffeature {
- name = feature,
- description = formatters["extra: %s"](feature)
- }
- end
- end
- end
- end
-end
-
-local function setextensions(tfmdata)
- local goodies = tfmdata.goodies
- if goodies then
- for i=1,#goodies do
- local g = goodies[i]
- local e = g.extensions
- if e then
- local goodie = g.name or "unknown"
- for i=1,#e do
- local name = "extension-" .. i
- -- report_goodies("adding extension %s from %s",name,goodie)
- otf.enhancers.addfeature(tfmdata.shared.rawdata,name,e[i])
- end
- end
- end
- end
-end
-
--- installation
-
-local goodies_specification = {
- name = "goodies",
- description = "goodies on top of built in features",
- initializers = {
- position = 1,
- base = setgoodies,
- node = setgoodies,
- }
-}
-
-registerotffeature(goodies_specification)
-registerafmfeature(goodies_specification)
-registertfmfeature(goodies_specification)
-
--- maybe more of the following could be for type one too
-
-registerotffeature {
- name = "extrafeatures",
- description = "extra features",
- default = true,
- initializers = {
- position = 2,
- base = setextrafeatures,
- node = setextrafeatures,
- }
-}
-
-registerotffeature {
- name = "extensions",
- description = "extensions to features",
- default = true,
- initializers = {
- position = 2,
- base = setextensions,
- node = setextensions,
- }
-}
-
-registerotffeature {
- name = "featureset",
- description = "goodie feature set",
- initializers = {
- position = 3,
- base = setfeatureset,
- node = setfeatureset,
- }
-}
-
-registerotffeature {
- name = "colorscheme",
- description = "goodie color scheme",
- initializers = {
- base = setcolorscheme,
- node = setcolorscheme,
- }
-}
-
-registerotffeature {
- name = "postprocessor",
- description = "goodie postprocessor",
- initializers = {
- base = setpostprocessor,
- node = setpostprocessor,
- }
-}
-
--- experiment, we have to load the definitions immediately as they precede
--- the definition so they need to be initialized in the typescript
-
-local function initialize(goodies)
- local mathgoodies = goodies.mathematics
- if mathgoodies then
- local virtuals = mathgoodies.virtuals
- local mapfiles = mathgoodies.mapfiles
- local maplines = mathgoodies.maplines
- if virtuals then
- for name, specification in next, virtuals do
- -- beware, they are all constructed
- mathematics.makefont(name,specification,goodies)
- end
- end
- if mapfiles then
- for i=1,#mapfiles do
- fonts.mappings.loadfile(mapfiles[i]) -- todo: backend function
- end
- end
- if maplines then
- for i=1,#maplines do
- fonts.mappings.loadline(maplines[i]) -- todo: backend function
- end
- end
- end
-end
-
-fontgoodies.register("mathematics", initialize)
-
--- the following takes care of explicit file specifications
---
--- files = {
--- name = "antykwapoltawskiego",
--- list = {
--- ["AntPoltLtCond-Regular.otf"] = {
--- -- name = "antykwapoltawskiego",
--- style = "regular",
--- weight = "light",
--- width = "condensed",
--- },
--- },
--- }
-
--- math italics (not rteally needed)
---
--- it would be nice to have a \noitalics\font option
-
-local function initialize(tfmdata)
- local goodies = tfmdata.goodies
- if goodies then
- local shared = tfmdata.shared
- for i=1,#goodies do
- local mathgoodies = goodies[i].mathematics
- if mathgoodies then
- local mathitalics = mathgoodies.italics
- if mathitalics then
- local properties = tfmdata.properties
- if properties.setitalics then
- mathitalics = mathitalics[file.nameonly(properties.name)] or mathitalics
- if mathitalics then
- if trace_goodies then
- report_goodies("loading mathitalics for font %a",properties.name)
- end
- local corrections = mathitalics.corrections
- local defaultfactor = mathitalics.defaultfactor
- -- properties.mathitalic_defaultfactor = defaultfactor -- we inherit outer one anyway (name will change)
- if corrections then
- fontgoodies.registerpostprocessor(tfmdata, function(tfmdata) -- this is another tfmdata (a copy)
- -- better make a helper so that we have less code being defined
- local properties = tfmdata.properties
- local parameters = tfmdata.parameters
- local characters = tfmdata.characters
- properties.mathitalic_defaultfactor = defaultfactor
- properties.mathitalic_defaultvalue = defaultfactor * parameters.quad
- if trace_goodies then
- report_goodies("assigning mathitalics for font %a",properties.name)
- end
- local quad = parameters.quad
- local hfactor = parameters.hfactor
- for k, v in next, corrections do
- local c = characters[k]
- if c then
- if v > -1 and v < 1 then
- c.italic = v * quad
- else
- c.italic = v * hfactor
- end
- else
- report_goodies("invalid mathitalics entry %U for font %a",k,properties.name)
- end
- end
- end)
- end
- return -- maybe not as these can accumulate
- end
- end
- end
- end
- end
- end
-end
-
-registerotffeature {
- name = "mathitalics",
- description = "additional math italic corrections",
- -- default = true,
- initializers = {
- base = initialize,
- node = initialize,
- }
-}
-
--- fontgoodies.register("mathitalics", initialize)
-
--- files
-
-local function initialize(goodies)
- local files = goodies.files
- if files then
- fonts.names.register(files)
- end
-end
-
-fontgoodies.register("files", initialize)
-
--- some day we will have a define command and then we can also do some
--- proper tracing
---
--- fonts.typefaces["antykwapoltawskiego-condensed"] = {
--- shortcut = "rm",
--- shape = "serif",
--- fontname = "antykwapoltawskiego",
--- normalweight = "light",
--- boldweight = "medium",
--- width = "condensed",
--- size = "default",
--- features = "default",
--- }
-
-local function initialize(goodies)
- local typefaces = goodies.typefaces
- if typefaces then
- local ft = fonts.typefaces
- for k, v in next, typefaces do
- ft[k] = v
- end
- end
-end
-
-fontgoodies.register("typefaces", initialize)
-
-local compositions = { }
-
-function fontgoodies.getcompositions(tfmdata)
- return compositions[file.nameonly(tfmdata.properties.filename or "")]
-end
-
-local function initialize(goodies)
- local gc = goodies.compositions
- if gc then
- for k, v in next, gc do
- compositions[k] = v
- end
- end
-end
-
-fontgoodies.register("compositions", initialize)
-
--- extra treatments (on top of defaults): \loadfontgoodies[mytreatments]
-
-local treatmentdata = fonts.treatments.data
-
-local function initialize(goodies)
- local treatments = goodies.treatments
- if treatments then
- for name, data in next, treatments do
- treatmentdata[name] = data -- always wins
- end
- end
-end
-
-fontgoodies.register("treatments", initialize)
-
-local filenames = fontgoodies.filenames or allocate()
-fontgoodies.filenames = filenames
-
-local filedata = filenames.data or allocate()
-filenames.data = filedata
-
-local function initialize(goodies) -- design sizes are registered global
- local fn = goodies.filenames
- if fn then
- for usedname, alternativenames in next, fn do
- filedata[usedname] = alternativenames
- end
- end
-end
-
-fontgoodies.register("filenames", initialize)
-
-function fontgoodies.filenames.resolve(name)
- local fd = filedata[name]
- if fd and findfile(name) == "" then
- for i=1,#fd do
- local fn = fd[i]
- if findfile(fn) ~= "" then
- return fn
- end
- end
- else
- -- no lookup, just use the regular mechanism
- end
- return name
-end
-
-local designsizes = fontgoodies.designsizes or allocate()
-fontgoodies.designsizes = designsizes
-
-local designdata = designsizes.data or allocate()
-designsizes.data = designdata
-
-local function initialize(goodies) -- design sizes are registered global
- local gd = goodies.designsizes
- if gd then
- for name, data in next, gd do
- local ranges = { }
- for size, file in next, data do
- if size ~= "default" then
- ranges[#ranges+1] = { texsp(size), file } -- also lower(file)
- end
- end
- table.sort(ranges,function(a,b) return a[1] < b[1] end)
- designdata[lower(name)] = { -- overloads, doesn't merge!
- default = data.default,
- ranges = ranges,
- }
- end
- end
-end
-
-fontgoodies.register("designsizes", initialize)
-
-function fontgoodies.designsizes.register(name,size,specification)
- local d = designdata[name]
- if not d then
- d = {
- ranges = { },
- default = nil, -- so we have no default set
- }
- designdata[name] = d
- end
- if size == "default" then
- d.default = specification
- else
- if type(size) == "string" then
- size = texsp(size) -- hm
- end
- local ranges = d.ranges
- ranges[#ranges+1] = { size, specification }
- end
-end
-
-function fontgoodies.designsizes.filename(name,spec,size) -- returns nil of no match
- local data = designdata[lower(name)]
- if data then
- if not spec or spec == "" or spec == "default" then
- return data.default
- elseif spec == "auto" then
- local ranges = data.ranges
- if ranges then
- for i=1,#ranges do
- local r = ranges[i]
- if r[1] >= size then -- todo: rounding so maybe size - 100
- return r[2]
- end
- end
- end
- return data.default or (ranges and ranges[#ranges][2])
- end
- end
-end
-
--- The following file (husayni.lfg) is the experimental setup that we used
--- for Idris font. For the moment we don't store this in the cache and quite
--- probably these files sit in one of the paths:
---
--- tex/context/fonts/goodies
--- tex/fonts/goodies/context
--- tex/fonts/data/foundry/collection
---
--- see lfg files in distribution
-
--- interface
-
-implement {
- name = "loadfontgoodies",
- actions = fontgoodies.load,
- arguments = "string",
- overload = true, -- for now, permits new font loader
-}
-
-implement {
- name = "enablefontcolorschemes",
- onlyonce = true,
- actions = colorschemes.enable,
- overload = true, -- for now, permits new font loader
-}
-
--- weird place ... depends on math
-
-local function finalize(tfmdata,feature,value)
- mathematics.overloaddimensions(tfmdata,tfmdata,value)
-end
-
-registerotffeature {
- name = "mathdimensions",
- description = "manipulate math dimensions",
- -- default = true,
- manipulators = {
- base = finalize,
- node = finalize,
- }
-}
-
-local enabled = false directives.register("fontgoodies.mathkerning",function(v) enabled = v end)
-
-local function initialize(tfmdata)
- if enabled and tfmdata.mathparameters then -- funny, cambria text has this
- local goodies = tfmdata.goodies
- if goodies then
- local characters = tfmdata.characters
- if characters[0x1D44E] then -- 119886
- -- we have at least an italic a
- for i=1,#goodies do
- local mathgoodies = goodies[i].mathematics
- if mathgoodies then
- local kerns = mathgoodies.kerns
- if kerns then
- for unicode, specification in next, kerns do
- local chardata = characters[unicode]
- if chardata and (not chardata.mathkerns or specification.force) then
- chardata.mathkerns = specification
- end
- end
- return
- end
- end
- end
- else
- return -- no proper math font anyway
- end
- end
- end
-end
-
-registerotffeature {
- name = "mathkerns",
- description = "math kerns",
- default = true,
- initializers = {
- base = initialize,
- node = initialize,
- }
-}
-
--- kern hackery:
---
--- yes : use goodies table
--- auto : assume features to be set (often ccmp only)
-
-local function setkeepligatures(tfmdata)
- if not tfmdata.properties.keptligatures then
- local goodies = tfmdata.goodies
- if goodies then
- for i=1,#goodies do
- local g = goodies[i]
- local letterspacing = g.letterspacing
- if letterspacing then
- local keptligatures = letterspacing.keptligatures
- if keptligatures then
- local unicodes = tfmdata.resources.unicodes -- so we accept names
- local hash = { }
- for k, v in next, keptligatures do
- local u = unicodes[k]
- if u then
- hash[u] = true
- else
- -- error: unknown name
- end
- end
- tfmdata.properties.keptligatures = hash
- end
- end
- end
- end
- end
-end
-
-registerotffeature {
- name = "keepligatures",
- description = "keep ligatures in letterspacing",
- initializers = {
- base = setkeepligatures,
- node = setkeepligatures,
- }
-}
diff --git a/tex/context/base/mkiv/font-lib.mkvi b/tex/context/base/mkiv/font-lib.mkvi
index fd6f70d69..d13de4b3e 100644
--- a/tex/context/base/mkiv/font-lib.mkvi
+++ b/tex/context/base/mkiv/font-lib.mkvi
@@ -76,7 +76,11 @@
\registerctxluafile{font-vf} {1.001}
\registerctxluafile{font-enh}{1.001}
-\registerctxluafile{font-gds}{1.001}
+%registerctxluafile{font-gds}{1.001}
+\registerctxluafile{good-ini}{1.001}
+\registerctxluafile{good-gen}{1.001}
+\registerctxluafile{good-ctx}{1.001}
+\registerctxluafile{good-mth}{1.001}
\registerctxluafile{font-def}{1.001}
\registerctxluafile{font-ctx}{1.001} % after def as it overloads
diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua
index 0db30c646..d1408fd52 100644
--- a/tex/context/base/mkiv/font-otj.lua
+++ b/tex/context/base/mkiv/font-otj.lua
@@ -24,6 +24,8 @@ if not modules then modules = { } end modules ['font-otj'] = {
-- The use_advance code is just a test and is meant for testing and manuals. There is no
-- performance (or whatever) gain and using kerns is somewhat cleaner (at least for now).
+-- Maybe: subtype fontkern when pure kerns.
+
if not nodes.properties then return end
local next, rawget = next, rawget
diff --git a/tex/context/base/mkiv/font-sel.lua b/tex/context/base/mkiv/font-sel.lua
index 02dc9e686..4620319f5 100644
--- a/tex/context/base/mkiv/font-sel.lua
+++ b/tex/context/base/mkiv/font-sel.lua
@@ -70,7 +70,7 @@ local report_selectfont = logs.reporter("selectfont")
local report_files = logs.reporter("selectfont","files")
local report_features = logs.reporter("selectfont","features")
local report_goodies = logs.reporter("selectfont","goodies")
-local report_alternatives = logs.reporter("selectfont","alternatives")
+----- report_alternatives = logs.reporter("selectfont","alternatives")
local report_typescript = logs.reporter("selectfont","typescripts")
defaults["rm"] = { features = { ["sc"] = "*,f:smallcaps" } }
@@ -919,4 +919,4 @@ implement {
name = "definefontfamilypreset",
actions = selectfont.definefontfamilypreset,
arguments = { "string", "string" }
-} \ No newline at end of file
+}
diff --git a/tex/context/base/mkiv/good-ctx.lua b/tex/context/base/mkiv/good-ctx.lua
new file mode 100644
index 000000000..4c8b9fcff
--- /dev/null
+++ b/tex/context/base/mkiv/good-ctx.lua
@@ -0,0 +1,275 @@
+if not modules then modules = { } end modules ['good-ctx'] = {
+ version = 1.000,
+ comment = "companion to font-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- depends on ctx
+
+local type, next, tonumber = type, next, tonumber
+local find, splitup = string.find, string.splitup
+
+local fonts = fonts
+local nodes = nodes
+local attributes = attributes
+
+----- trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end)
+----- report_goodies = logs.reporter("fonts","goodies")
+
+local allocate = utilities.storage.allocate
+local setmetatableindex = table.setmetatableindex
+
+local implement = interfaces.implement
+
+local registerotffeature = fonts.handlers.otf.features.register
+----- registerafmfeature = fonts.handlers.afm.features.register
+----- registertfmfeature = fonts.handlers.tfm.features.register
+
+local fontgoodies = fonts.goodies or { }
+
+local glyph_code = nodes.nodecodes.glyph
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+local getfont = nuts.getfont
+local getchar = nuts.getchar
+local getattr = nuts.getattr
+local traverse_id = nuts.traverse_id
+
+-- colorschemes
+
+local colorschemes = fontgoodies.colorschemes or allocate { }
+fontgoodies.colorschemes = colorschemes
+colorschemes.data = colorschemes.data or { }
+
+local function setcolorscheme(tfmdata,scheme)
+ if type(scheme) == "string" then
+ local goodies = tfmdata.goodies
+ -- todo : check for already defined in shared
+ if goodies then
+ local what
+ for i=1,#goodies do
+ -- last one counts
+ local g = goodies[i]
+ what = g.colorschemes and g.colorschemes[scheme] or what
+ end
+ if type(what) == "table" then
+ -- this is font bound but we can share them if needed
+ -- just as we could hash the conversions (per font)
+ local hash = tfmdata.resources.unicodes
+ local reverse = { }
+ local characters = tfmdata.characters
+ for i=1,#what do
+ local w = what[i]
+ for j=1,#w do
+ local name = w[j]
+ if name == "*" then
+ -- inefficient but only used for tracing anyway
+ for _, unicode in next, hash do
+ reverse[unicode] = i
+ end
+ elseif type(name) == "number" then
+ reverse[name] = i
+ elseif find(name,":",1,true) then
+ local start, stop = splitup(name,":")
+ start = tonumber(start)
+ stop = tonumber(stop)
+ if start and stop then
+ -- limited usage: we only deal with non reassigned
+ -- maybe some day I'll also support the ones with a
+ -- tounicode in this range
+ for unicode=start,stop do
+ if characters[unicode] then
+ reverse[unicode] = i
+ end
+ end
+ end
+ else
+ local unicode = hash[name]
+ if unicode then
+ reverse[unicode] = i
+ end
+ end
+ end
+ end
+ tfmdata.properties.colorscheme = reverse
+ return
+ end
+ end
+ end
+ tfmdata.properties.colorscheme = false
+end
+
+local fontproperties = fonts.hashes.properties
+
+local a_colorscheme = attributes.private('colorscheme')
+local setnodecolor = nodes.tracers.colors.set
+
+-- function colorschemes.coloring(head)
+-- local lastfont, lastscheme
+-- local done = false
+-- for n in traverse_id(glyph_code,tonut(head)) do
+-- local a = getattr(n,a_colorscheme)
+-- if a then
+-- local f = getfont(n)
+-- if f ~= lastfont then
+-- lastscheme = fontproperties[f].colorscheme
+-- lastfont = f
+-- end
+-- if lastscheme then
+-- local sc = lastscheme[getchar(n)]
+-- if sc then
+-- done = true
+-- setnodecolor(n,"colorscheme:"..a..":"..sc) -- slow
+-- end
+-- end
+-- end
+-- end
+-- return head, done
+-- end
+
+-- seldom used, mostly in manuals, so non critical .. anyhow, somewhat faster:
+
+-- function colorschemes.coloring(head)
+-- local lastfont = nil
+-- local lastattr = nil
+-- local lastscheme = nil
+-- local lastprefix = nil
+-- local done = nil
+-- for n in traverse_id(glyph_code,tonut(head)) do
+-- local a = getattr(n,a_colorscheme)
+-- if a then
+-- if a ~= lastattr then
+-- lastattr = a
+-- lastprefix = "colorscheme:" .. a .. ":"
+-- end
+-- local f = getfont(n)
+-- if f ~= lastfont then
+-- lastfont = f
+-- lastscheme = fontproperties[f].colorscheme
+-- end
+-- if lastscheme then
+-- local sc = lastscheme[getchar(n)]
+-- if sc then
+-- setnodecolor(n,lastprefix .. sc) -- slow
+-- done = true
+-- end
+-- end
+-- end
+-- end
+-- return head, done
+-- end
+
+-- ok, in case we have hundreds of pages colored:
+
+local cache = { } -- this could be a weak table
+
+setmetatableindex(cache,function(t,a)
+ local v = { }
+ setmetatableindex(v,function(t,c)
+ local v = "colorscheme:" .. a .. ":" .. c
+ t[c] = v
+ return v
+ end)
+ t[a]= v
+ return v
+end)
+
+function colorschemes.coloring(head)
+ local lastfont = nil
+ local lastattr = nil
+ local lastcache = nil
+ local lastscheme = nil
+ local done = nil
+ for n in traverse_id(glyph_code,tonut(head)) do
+ local a = getattr(n,a_colorscheme)
+ if a then
+ local f = getfont(n)
+ if f ~= lastfont then
+ lastfont = f
+ lastscheme = fontproperties[f].colorscheme
+ end
+ if a ~= lastattr then
+ lastattr = a
+ lastcache = cache[a]
+ end
+ if lastscheme then
+ local sc = lastscheme[getchar(n)]
+ if sc then
+ setnodecolor(n,lastcache[sc]) -- we could inline this one
+ done = true
+ end
+ end
+ end
+ end
+ return head, done
+end
+
+function colorschemes.enable()
+ nodes.tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring")
+ function colorschemes.enable() end
+end
+
+registerotffeature {
+ name = "colorscheme",
+ description = "goodie color scheme",
+ initializers = {
+ base = setcolorscheme,
+ node = setcolorscheme,
+ }
+}
+
+-- kern hackery:
+--
+-- yes : use goodies table
+-- auto : assume features to be set (often ccmp only)
+
+local function setkeepligatures(tfmdata)
+ if not tfmdata.properties.keptligatures then
+ local goodies = tfmdata.goodies
+ if goodies then
+ for i=1,#goodies do
+ local g = goodies[i]
+ local letterspacing = g.letterspacing
+ if letterspacing then
+ local keptligatures = letterspacing.keptligatures
+ if keptligatures then
+ local unicodes = tfmdata.resources.unicodes -- so we accept names
+ local hash = { }
+ for k, v in next, keptligatures do
+ local u = unicodes[k]
+ if u then
+ hash[u] = true
+ else
+ -- error: unknown name
+ end
+ end
+ tfmdata.properties.keptligatures = hash
+ end
+ end
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "keepligatures",
+ description = "keep ligatures in letterspacing",
+ initializers = {
+ base = setkeepligatures,
+ node = setkeepligatures,
+ }
+}
+
+if implement then
+
+ implement {
+ name = "enablefontcolorschemes",
+ onlyonce = true,
+ actions = colorschemes.enable,
+ overload = true, -- for now, permits new font loader
+ }
+
+end
diff --git a/tex/context/base/mkiv/good-gen.lua b/tex/context/base/mkiv/good-gen.lua
new file mode 100644
index 000000000..cee6b3172
--- /dev/null
+++ b/tex/context/base/mkiv/good-gen.lua
@@ -0,0 +1,208 @@
+if not modules then modules = { } end modules ['good-gen'] = {
+ version = 1.000,
+ comment = "companion to font-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- depends on ctx
+
+local type, next = type, next
+local lower = string.lower
+
+local fonts = fonts
+
+----- trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end)
+----- report_goodies = logs.reporter("fonts","goodies")
+
+local allocate = utilities.storage.allocate
+local texsp = tex.sp
+local fontgoodies = fonts.goodies or { }
+local findfile = resolvers.findfile
+
+
+local typefaces = fonts.typefaces or { }
+fonts.typefaces = typefaces
+
+-- the following takes care of explicit file specifications
+--
+-- files = {
+-- name = "antykwapoltawskiego",
+-- list = {
+-- ["AntPoltLtCond-Regular.otf"] = {
+-- -- name = "antykwapoltawskiego",
+-- style = "regular",
+-- weight = "light",
+-- width = "condensed",
+-- },
+-- },
+-- }
+
+-- files
+
+local function initialize(goodies)
+ local files = goodies.files
+ if files then
+ fonts.names.register(files)
+ end
+end
+
+fontgoodies.register("files", initialize)
+
+-- some day we will have a define command and then we can also do some
+-- proper tracing
+--
+-- fonts.typefaces["antykwapoltawskiego-condensed"] = {
+-- shortcut = "rm",
+-- shape = "serif",
+-- fontname = "antykwapoltawskiego",
+-- normalweight = "light",
+-- boldweight = "medium",
+-- width = "condensed",
+-- size = "default",
+-- features = "default",
+-- }
+
+local function initialize(goodies)
+ local typefaces = goodies.typefaces
+ if typefaces then
+ local ft = fonts.typefaces
+ for k, v in next, typefaces do
+ ft[k] = v
+ end
+ end
+end
+
+fontgoodies.register("typefaces", initialize)
+
+local compositions = { }
+
+function fontgoodies.getcompositions(tfmdata)
+ return compositions[file.nameonly(tfmdata.properties.filename or "")]
+end
+
+local function initialize(goodies)
+ local gc = goodies.compositions
+ if gc then
+ for k, v in next, gc do
+ compositions[k] = v
+ end
+ end
+end
+
+fontgoodies.register("compositions", initialize)
+
+-- extra treatments (on top of defaults): \loadfontgoodies[mytreatments]
+
+local treatmentdata = fonts.treatments.data
+
+local function initialize(goodies)
+ local treatments = goodies.treatments
+ if treatments then
+ for name, data in next, treatments do
+ treatmentdata[name] = data -- always wins
+ end
+ end
+end
+
+fontgoodies.register("treatments", initialize)
+
+local filenames = fontgoodies.filenames or allocate()
+fontgoodies.filenames = filenames
+
+local filedata = filenames.data or allocate()
+filenames.data = filedata
+
+local function initialize(goodies) -- design sizes are registered global
+ local fn = goodies.filenames
+ if fn then
+ for usedname, alternativenames in next, fn do
+ filedata[usedname] = alternativenames
+ end
+ end
+end
+
+fontgoodies.register("filenames", initialize)
+
+function fontgoodies.filenames.resolve(name)
+ local fd = filedata[name]
+ if fd and findfile(name) == "" then
+ for i=1,#fd do
+ local fn = fd[i]
+ if findfile(fn) ~= "" then
+ return fn
+ end
+ end
+ else
+ -- no lookup, just use the regular mechanism
+ end
+ return name
+end
+
+local designsizes = fontgoodies.designsizes or allocate()
+fontgoodies.designsizes = designsizes
+
+local designdata = designsizes.data or allocate()
+designsizes.data = designdata
+
+local function initialize(goodies) -- design sizes are registered global
+ local gd = goodies.designsizes
+ if gd then
+ for name, data in next, gd do
+ local ranges = { }
+ for size, file in next, data do
+ if size ~= "default" then
+ ranges[#ranges+1] = { texsp(size), file } -- also lower(file)
+ end
+ end
+ table.sort(ranges,function(a,b) return a[1] < b[1] end)
+ designdata[lower(name)] = { -- overloads, doesn't merge!
+ default = data.default,
+ ranges = ranges,
+ }
+ end
+ end
+end
+
+fontgoodies.register("designsizes", initialize)
+
+function fontgoodies.designsizes.register(name,size,specification)
+ local d = designdata[name]
+ if not d then
+ d = {
+ ranges = { },
+ default = nil, -- so we have no default set
+ }
+ designdata[name] = d
+ end
+ if size == "default" then
+ d.default = specification
+ else
+ if type(size) == "string" then
+ size = texsp(size) -- hm
+ end
+ local ranges = d.ranges
+ ranges[#ranges+1] = { size, specification }
+ end
+end
+
+function fontgoodies.designsizes.filename(name,spec,size) -- returns nil of no match
+ local data = designdata[lower(name)]
+ if data then
+ if not spec or spec == "" or spec == "default" then
+ return data.default
+ elseif spec == "auto" then
+ local ranges = data.ranges
+ if ranges then
+ for i=1,#ranges do
+ local r = ranges[i]
+ if r[1] >= size then -- todo: rounding so maybe size - 100
+ return r[2]
+ end
+ end
+ end
+ return data.default or (ranges and ranges[#ranges][2])
+ end
+ end
+end
diff --git a/tex/context/base/mkiv/good-ini.lua b/tex/context/base/mkiv/good-ini.lua
new file mode 100644
index 000000000..f11b0f004
--- /dev/null
+++ b/tex/context/base/mkiv/good-ini.lua
@@ -0,0 +1,349 @@
+if not modules then modules = { } end modules ['good-ini'] = {
+ version = 1.000,
+ comment = "companion to font-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- depends on ctx
+
+local type, next = type, next
+local gmatch = string.gmatch
+
+local fonts = fonts
+
+local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end)
+local report_goodies = logs.reporter("fonts","goodies")
+
+local allocate = utilities.storage.allocate
+local implement = interfaces.implement
+local findfile = resolvers.findfile
+local formatters = string.formatters
+
+local otf = fonts.handlers.otf
+local afm = fonts.handlers.afm
+local tfm = fonts.handlers.tfm
+
+local registerotffeature = otf.features.register
+local registerafmfeature = afm.features.register
+local registertfmfeature = tfm.features.register
+
+local addotffeature = otf.enhancers.addfeature
+
+local fontgoodies = fonts.goodies or { }
+fonts.goodies = fontgoodies
+
+local data = fontgoodies.data or { }
+fontgoodies.data = data -- no allocate as we want to see what is there
+
+local list = fontgoodies.list or { }
+fontgoodies.list = list -- no allocate as we want to see what is there
+
+fontgoodies.suffixes = { "lfg", "lua" } -- lfg is context specific and should not be used elsewhere
+
+function fontgoodies.report(what,trace,goodies)
+ if trace_goodies or trace then
+ local whatever = goodies[what]
+ if whatever then
+ report_goodies("goodie %a found in %a",what,goodies.name)
+ end
+ end
+end
+
+local function locate(filename)
+ local suffixes = fontgoodies.suffixes
+ for i=1,#suffixes do
+ local suffix = suffixes[i]
+ local fullname = findfile(file.addsuffix(filename,suffix))
+ if fullname and fullname ~= "" then
+ return fullname
+ end
+ end
+end
+
+local function loadgoodies(filename) -- maybe a merge is better
+ local goodies = data[filename] -- we assume no suffix is given
+ if goodies ~= nil then
+ -- found or tagged unfound
+ elseif type(filename) == "string" then
+ local fullname = locate(filename)
+ if not fullname or fullname == "" then
+ report_goodies("goodie file %a is not found (suffixes: % t)",filename,fontgoodies.suffixes)
+ data[filename] = false -- signal for not found
+ else
+ goodies = dofile(fullname) or false
+ if not goodies then
+ report_goodies("goodie file %a is invalid",fullname)
+ return nil
+ elseif trace_goodies then
+ report_goodies("goodie file %a is loaded",fullname)
+ end
+ goodies.name = goodies.name or "no name"
+ for name, fnc in next, list do
+ if trace_goodies then
+ report_goodies("handling goodie %a",name)
+ end
+ fnc(goodies)
+ end
+ goodies.initialized = true
+ data[filename] = goodies
+ end
+ end
+ return goodies
+end
+
+function fontgoodies.register(name,fnc) -- will be a proper sequencer
+ list[name] = fnc
+end
+
+fontgoodies.load = loadgoodies
+
+if implement then
+
+ implement {
+ name = "loadfontgoodies",
+ actions = loadgoodies,
+ arguments = "string",
+ overload = true, -- for now, permits new font loader
+ }
+
+end
+
+-- register goodies file
+
+local function setgoodies(tfmdata,value)
+ local goodies = tfmdata.goodies
+ if not goodies then -- actually an error
+ goodies = { }
+ tfmdata.goodies = goodies
+ end
+ for filename in gmatch(value,"[^, ]+") do
+ -- we need to check for duplicates
+ local ok = loadgoodies(filename)
+ if ok then
+ if trace_goodies then
+ report_goodies("assigning goodie %a",filename)
+ end
+ goodies[#goodies+1] = ok
+ end
+ end
+end
+
+-- featuresets
+
+local function flattenedfeatures(t,tt)
+ -- first set value dominates
+ local tt = tt or { }
+ for i=1,#t do
+ local ti = t[i]
+ if type(ti) == "table" then
+ flattenedfeatures(ti,tt)
+ elseif tt[ti] == nil then
+ tt[ti] = true
+ end
+ end
+ for k, v in next, t do
+ if type(k) ~= "number" then -- not tonumber(k)
+ if type(v) == "table" then
+ flattenedfeatures(v,tt)
+ elseif tt[k] == nil then
+ tt[k] = v
+ end
+ end
+ end
+ return tt
+end
+
+-- fonts.features.flattened = flattenedfeatures
+
+local function prepare_features(goodies,name,set)
+ if set then
+ local ff = flattenedfeatures(set)
+ local fullname = goodies.name .. "::" .. name
+ local n, s = fonts.specifiers.presetcontext(fullname,"",ff)
+ goodies.featuresets[name] = s -- set
+ if trace_goodies then
+ report_goodies("feature set %a gets number %a and name %a",name,n,fullname)
+ end
+ return n
+ end
+end
+
+fontgoodies.prepare_features = prepare_features
+
+local function initialize(goodies)
+ local featuresets = goodies.featuresets
+ if featuresets then
+ if trace_goodies then
+ report_goodies("checking featuresets in %a",goodies.name)
+ end
+ for name, set in next, featuresets do
+ prepare_features(goodies,name,set)
+ end
+ end
+end
+
+fontgoodies.register("featureset",initialize)
+
+local function setfeatureset(tfmdata,set,features)
+ local goodies = tfmdata.goodies -- shared ?
+ if goodies then
+ local properties = tfmdata.properties
+ local what
+ for i=1,#goodies do
+ -- last one wins
+ local g = goodies[i]
+ what = g.featuresets and g.featuresets[set] or what
+ end
+ if what then
+ for feature, value in next, what do
+ if features[feature] == nil then
+ features[feature] = value
+ end
+ end
+ properties.mode = what.mode or properties.mode
+ end
+ end
+end
+
+-- postprocessors (we could hash processor and share code)
+
+function fontgoodies.registerpostprocessor(tfmdata,f,prepend)
+ local postprocessors = tfmdata.postprocessors
+ if not postprocessors then
+ tfmdata.postprocessors = { f }
+ elseif prepend then
+ table.insert(postprocessors,f,1)
+ else
+ table.insert(postprocessors,f)
+ end
+end
+
+local function setpostprocessor(tfmdata,processor)
+ local goodies = tfmdata.goodies
+ if goodies and type(processor) == "string" then
+ local found = { }
+ local asked = utilities.parsers.settings_to_array(processor)
+ for i=1,#goodies do
+ local g = goodies[i]
+ local p = g.postprocessors
+ if p then
+ for i=1,#asked do
+ local a = asked[i]
+ local f = p[a]
+ if type(f) == "function" then
+ found[a] = f
+ end
+ end
+ end
+ end
+ local postprocessors = tfmdata.postprocessors or { }
+ for i=1,#asked do
+ local a = asked[i]
+ local f = found[a]
+ if f then
+ postprocessors[#postprocessors+1] = f
+ end
+ end
+ if #postprocessors > 0 then
+ tfmdata.postprocessors = postprocessors
+ end
+ end
+end
+
+local function setextrafeatures(tfmdata)
+ local goodies = tfmdata.goodies
+ if goodies then
+ for i=1,#goodies do
+ local g = goodies[i]
+ local f = g.features
+ if f then
+ for feature, specification in next, f do
+ addotffeature(tfmdata.shared.rawdata,feature,specification)
+ registerotffeature {
+ name = feature,
+ description = formatters["extra: %s"](feature)
+ }
+ end
+ end
+ end
+ end
+end
+
+local function setextensions(tfmdata)
+ local goodies = tfmdata.goodies
+ if goodies then
+ for i=1,#goodies do
+ local g = goodies[i]
+ local e = g.extensions
+ if e then
+ local goodie = g.name or "unknown"
+ for i=1,#e do
+ local name = "extension-" .. i
+ -- report_goodies("adding extension %s from %s",name,goodie)
+ otf.enhancers.addfeature(tfmdata.shared.rawdata,name,e[i])
+ end
+ end
+ end
+ end
+end
+
+-- installation
+
+local goodies_specification = {
+ name = "goodies",
+ description = "goodies on top of built in features",
+ initializers = {
+ position = 1,
+ base = setgoodies,
+ node = setgoodies,
+ }
+}
+
+registerotffeature(goodies_specification)
+registerafmfeature(goodies_specification)
+registertfmfeature(goodies_specification)
+
+-- maybe more of the following could be for type one too
+
+registerotffeature {
+ name = "extrafeatures",
+ description = "extra features",
+ default = true,
+ initializers = {
+ position = 2,
+ base = setextrafeatures,
+ node = setextrafeatures,
+ }
+}
+
+registerotffeature {
+ name = "extensions",
+ description = "extensions to features",
+ default = true,
+ initializers = {
+ position = 2,
+ base = setextensions,
+ node = setextensions,
+ }
+}
+
+registerotffeature {
+ name = "featureset",
+ description = "goodie feature set",
+ initializers = {
+ position = 3,
+ base = setfeatureset,
+ node = setfeatureset,
+ }
+}
+
+registerotffeature {
+ name = "postprocessor",
+ description = "goodie postprocessor",
+ initializers = {
+ base = setpostprocessor,
+ node = setpostprocessor,
+ }
+}
diff --git a/tex/context/base/mkiv/good-mth.lua b/tex/context/base/mkiv/good-mth.lua
new file mode 100644
index 000000000..7533a17c3
--- /dev/null
+++ b/tex/context/base/mkiv/good-mth.lua
@@ -0,0 +1,173 @@
+if not modules then modules = { } end modules ['good-mth'] = {
+ version = 1.000,
+ comment = "companion to font-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type, next = type, next
+
+local fonts = fonts
+
+local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end)
+local report_goodies = logs.reporter("fonts","goodies")
+
+local registerotffeature = fonts.handlers.otf.features.register
+local fontgoodies = fonts.goodies or { }
+
+-- experiment, we have to load the definitions immediately as they precede
+-- the definition so they need to be initialized in the typescript
+
+local function finalize(tfmdata,feature,value)
+ mathematics.overloaddimensions(tfmdata,tfmdata,value)
+end
+
+registerotffeature {
+ name = "mathdimensions",
+ description = "manipulate math dimensions",
+ -- default = true,
+ manipulators = {
+ base = finalize,
+ node = finalize,
+ }
+}
+
+local function initialize(goodies)
+ local mathgoodies = goodies.mathematics
+ if mathgoodies then
+ local virtuals = mathgoodies.virtuals
+ local mapfiles = mathgoodies.mapfiles
+ local maplines = mathgoodies.maplines
+ if virtuals then
+ for name, specification in next, virtuals do
+ -- beware, they are all constructed
+ mathematics.makefont(name,specification,goodies)
+ end
+ end
+ if mapfiles then
+ for i=1,#mapfiles do
+ fonts.mappings.loadfile(mapfiles[i]) -- todo: backend function
+ end
+ end
+ if maplines then
+ for i=1,#maplines do
+ fonts.mappings.loadline(maplines[i]) -- todo: backend function
+ end
+ end
+ end
+end
+
+fontgoodies.register("mathematics", initialize)
+
+local enabled = false directives.register("fontgoodies.mathkerning",function(v) enabled = v end)
+
+local function initialize(tfmdata)
+ if enabled and tfmdata.mathparameters then -- funny, cambria text has this
+ local goodies = tfmdata.goodies
+ if goodies then
+ local characters = tfmdata.characters
+ if characters[0x1D44E] then -- 119886
+ -- we have at least an italic a
+ for i=1,#goodies do
+ local mathgoodies = goodies[i].mathematics
+ if mathgoodies then
+ local kerns = mathgoodies.kerns
+ if kerns then
+ for unicode, specification in next, kerns do
+ local chardata = characters[unicode]
+ if chardata and (not chardata.mathkerns or specification.force) then
+ chardata.mathkerns = specification
+ end
+ end
+ return
+ end
+ end
+ end
+ else
+ return -- no proper math font anyway
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "mathkerns",
+ description = "math kerns",
+ default = true,
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+-- math italics (not really needed)
+--
+-- it would be nice to have a \noitalics\font option
+
+local function initialize(tfmdata)
+ local goodies = tfmdata.goodies
+ if goodies then
+ local shared = tfmdata.shared
+ for i=1,#goodies do
+ local mathgoodies = goodies[i].mathematics
+ if mathgoodies then
+ local mathitalics = mathgoodies.italics
+ if mathitalics then
+ local properties = tfmdata.properties
+ if properties.setitalics then
+ mathitalics = mathitalics[file.nameonly(properties.name)] or mathitalics
+ if mathitalics then
+ if trace_goodies then
+ report_goodies("loading mathitalics for font %a",properties.name)
+ end
+ local corrections = mathitalics.corrections
+ local defaultfactor = mathitalics.defaultfactor
+ -- properties.mathitalic_defaultfactor = defaultfactor -- we inherit outer one anyway (name will change)
+ if corrections then
+ fontgoodies.registerpostprocessor(tfmdata, function(tfmdata) -- this is another tfmdata (a copy)
+ -- better make a helper so that we have less code being defined
+ local properties = tfmdata.properties
+ local parameters = tfmdata.parameters
+ local characters = tfmdata.characters
+ properties.mathitalic_defaultfactor = defaultfactor
+ properties.mathitalic_defaultvalue = defaultfactor * parameters.quad
+ if trace_goodies then
+ report_goodies("assigning mathitalics for font %a",properties.name)
+ end
+ local quad = parameters.quad
+ local hfactor = parameters.hfactor
+ for k, v in next, corrections do
+ local c = characters[k]
+ if c then
+ if v > -1 and v < 1 then
+ c.italic = v * quad
+ else
+ c.italic = v * hfactor
+ end
+ else
+ report_goodies("invalid mathitalics entry %U for font %a",k,properties.name)
+ end
+ end
+ end)
+ end
+ return -- maybe not as these can accumulate
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "mathitalics",
+ description = "additional math italic corrections",
+ -- default = true,
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
+-- fontgoodies.register("mathitalics", initialize)
diff --git a/tex/context/base/mkiv/layo-ini.lua b/tex/context/base/mkiv/layo-ini.lua
index d35d7ef69..bfe33595d 100644
--- a/tex/context/base/mkiv/layo-ini.lua
+++ b/tex/context/base/mkiv/layo-ini.lua
@@ -18,7 +18,7 @@ layouts = {
local status = layouts.status
-function status.leftorrightpagection(left,right)
+function status.leftorrightpageaction(left,right)
if left == nil then
left, right = false, true
end
@@ -41,14 +41,14 @@ function status.leftorrightpagection(left,right)
end
end
-function status.isleftpage()
+function status.isleftpage(r)
if not conditionals.layoutisdoublesided then
return false
elseif conditionals.layoutissinglesided then
return false
elseif texgetcount("pagenoshift") % 2 == 0 then
- return texgetcount("realpageno") % 2 == 0
+ return (r or texgetcount("realpageno")) % 2 == 0
else
- return not texgetcount("realpageno") % 2 == 0
+ return not (r or texgetcount("realpageno")) % 2 == 0
end
end
diff --git a/tex/context/base/mkiv/lxml-tab.lua b/tex/context/base/mkiv/lxml-tab.lua
index 2925af5f9..3c386b7a3 100644
--- a/tex/context/base/mkiv/lxml-tab.lua
+++ b/tex/context/base/mkiv/lxml-tab.lua
@@ -1049,9 +1049,13 @@ local grammar_unparsed_text = P { "preamble",
-- maybe we will add settings to result as well
-local function _xmlconvert_(data, settings)
+local function _xmlconvert_(data,settings)
settings = settings or { } -- no_root strip_cm_and_dt given_entities parent_root error_handler
preparexmlstate(settings)
+ local preprocessor = settings.preprocessor
+ if data and data ~= "" and type(preprocessor) == "function" then
+ data = preprocessor(data,settings) or data -- settings.currentresource
+ end
if settings.parent_root then
mt = getmetatable(settings.parent_root)
else
diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua
index 836286073..026cf520d 100644
--- a/tex/context/base/mkiv/lxml-tex.lua
+++ b/tex/context/base/mkiv/lxml-tex.lua
@@ -523,6 +523,8 @@ local function entityconverter(id,str,ent) -- todo: disable tex entities when ra
return xmlprivatetoken(str)
end
+lxml.preprocessor = nil
+
local function lxmlconvert(id,data,compress,currentresource)
local settings = { -- we're now roundtrip anyway
unify_predefined_entities = false, -- is also default
@@ -530,6 +532,7 @@ local function lxmlconvert(id,data,compress,currentresource)
resolve_predefined_entities = true, -- is also default
resolve_entities = function(str,ent) return entityconverter(id,str,ent) end,
currentresource = tostring(currentresource or id),
+ preprocessor = lxml.preprocessor,
}
if compress and compress == variables.yes then
settings.strip_cm_and_dt = true
diff --git a/tex/context/base/mkiv/math-map.lua b/tex/context/base/mkiv/math-map.lua
index 94dde4110..f3726cf72 100644
--- a/tex/context/base/mkiv/math-map.lua
+++ b/tex/context/base/mkiv/math-map.lua
@@ -164,6 +164,10 @@ local function toupper (n) local t = { } for i=0,25 do t[0x00041+i] = n+i end re
local function tolower (n) local t = { } for i=0,25 do t[0x00061+i] = n+i end return t end
local function tovector(t) return t end
+-- how about 0x2A (ast) cq. 0x2217
+-- 0x2D (hyphen) cq. 0x2212
+-- 0x3A (colon) cq. 0x2236
+
local regular_tf = {
digits = todigit(0x00030),
ucletters = toupper(0x00041),
diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua
index 681144816..b74ced203 100644
--- a/tex/context/base/mkiv/mult-def.lua
+++ b/tex/context/base/mkiv/mult-def.lua
@@ -10565,6 +10565,10 @@ return {
["pe"]="توده",
["ro"]="stack",
},
+ ["stackname"]={
+ ["en"]="stackname",
+ ["nl"]="stapelnaam",
+ },
["start"]={
["cs"]="start",
["de"]="start",
diff --git a/tex/context/base/mkiv/page-mix.lua b/tex/context/base/mkiv/page-mix.lua
index 5ff1abf09..1154a24f5 100644
--- a/tex/context/base/mkiv/page-mix.lua
+++ b/tex/context/base/mkiv/page-mix.lua
@@ -44,7 +44,6 @@ local vpack = nuts.vpack
local freenode = nuts.free
local concatnodes = nuts.concat
local slidenodes = nuts.slide -- ok here as we mess with prev links intermediately
-local findtail = nuts.tail
local getfield = nuts.getfield
local setfield = nuts.setfield
@@ -63,8 +62,6 @@ local getbox = nuts.getbox
local getskip = nuts.getskip
local getattribute = nuts.getattribute
-local texgetskip = tex.getskip
-
local theprop = nuts.theprop
local nodepool = nuts.pool
diff --git a/tex/context/base/mkiv/spac-ali.lua b/tex/context/base/mkiv/spac-ali.lua
index a67a30133..dc206a2a2 100644
--- a/tex/context/base/mkiv/spac-ali.lua
+++ b/tex/context/base/mkiv/spac-ali.lua
@@ -115,7 +115,7 @@ local function handler(head,leftpage,realpageno)
end
function alignments.handler(head)
- local leftpage = isleftpage(true,false)
+ local leftpage = isleftpage()
local realpageno = texgetcount("realpageno")
local head, done = handler(tonut(head),leftpage,realpageno)
return tonode(head), done
diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv
index 250e4e396..7fe41c6de 100644
--- a/tex/context/base/mkiv/spac-ver.mkiv
+++ b/tex/context/base/mkiv/spac-ver.mkiv
@@ -1256,14 +1256,14 @@
%D Keyword based strutting:
-\letvalue{\??struts\v!yes }\setstrut % \setvalue{\??struts\v!yes }{\setstrut}
-\letvalue{\??struts\v!auto }\setautostrut % \setvalue{\??struts\v!auto }{\setautostrut}
-\letvalue{\??struts\v!no }\setnostrut % \setvalue{\??struts\v!no }{\setnostrut}
-\letvalue{\??struts\v!cap }\setcapstrut % \setvalue{\??struts\v!cap }{\setcapstrut}
-\letvalue{\??struts\v!fit }\setfontstrut % \setvalue{\??struts\v!fit }{\setfontstrut}
-\letvalue{\??struts\v!line }\setstrut % \setvalue{\??struts\v!line }{\setstrut}
-\letvalue{\??struts\s!default}\setstrut % \setvalue{\??struts\s!default}{\setstrut}
-\letvalue{\??struts\empty }\setstrut % \setvalue{\??struts\empty }{\setstrut}
+\letvalue{\??struts\v!yes }\setstrut
+\letvalue{\??struts\v!auto }\setautostrut
+\letvalue{\??struts\v!no }\setnostrut
+\letvalue{\??struts\v!cap }\setcapstrut
+\letvalue{\??struts\v!fit }\setfontstrut
+\letvalue{\??struts\v!line }\setstrut
+\letvalue{\??struts\s!default}\setstrut
+\letvalue{\??struts\empty }\setstrut
%D Handy:
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index d80b8b645..05b5087c8 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index e5c33fd93..1d0b0b16e 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua
index 080b72673..e37a31902 100644
--- a/tex/context/base/mkiv/trac-vis.lua
+++ b/tex/context/base/mkiv/trac-vis.lua
@@ -374,8 +374,11 @@ end
local f_cache = { }
local function fontkern(head,current)
- local kern = getfield(current,"kern") + getfield(current,"expansion_factor")
- local info = f_cache[kern]
+ local width = getfield(current,"kern")
+ local extra = getfield(current,"expansion_factor")
+ local kern = width + extra
+ local info = f_cache[kern]
+ -- report_visualize("fontkern: %p ex %p",width,extra)
if info then
-- print("hit fontkern")
else
diff --git a/tex/context/base/mkiv/typo-mar.lua b/tex/context/base/mkiv/typo-mar.lua
index 2886c7887..fb03b23ea 100644
--- a/tex/context/base/mkiv/typo-mar.lua
+++ b/tex/context/base/mkiv/typo-mar.lua
@@ -9,70 +9,8 @@ if not modules then modules = { } end modules ['typo-mar'] = {
-- todo:
--
-- * autoleft/right depending on available space (or distance to margin)
--- * stack across paragraphs, but that is messy and one should reconsider
--- using margin data then as also vertical spacing kicks in
-- * floating margin data, with close-to-call anchoring
--- -- experiment (does not work, too much interference)
---
--- local pdfprint = pdf.print
--- local format = string.format
---
--- anchors = anchors or { }
---
--- local whatever = { }
--- local factor = (7200/7227)/65536
---
--- function anchors.set(tag)
--- whatever[tag] = { pdf.h, pdf.v }
--- end
---
--- function anchors.reset(tag)
--- whatever[tag] = nil
--- end
---
--- function anchors.startmove(tag,how) -- save/restore nodes but they don't support moves
--- local w = whatever[tag]
--- if not w then
--- -- error
--- elseif how == "horizontal" or how == "h" then
--- pdfprint("page",format(" q 1 0 0 1 %f 0 cm ", (w[1] - pdf.h) * factor))
--- elseif how == "vertical" or how == "v" then
--- pdfprint("page",format(" q 1 0 0 1 0 %f cm ", (w[2] - pdf.v) * factor))
--- else
--- pdfprint("page",format(" q 1 0 0 1 %f %f cm ", (w[1] - pdf.h) * factor, (w[2] - pdf.v) * factor))
--- end
--- end
---
--- function anchors.stopmove(tag)
--- local w = whatever[tag]
--- if not w then
--- -- error
--- else
--- pdfprint("page"," Q ")
--- end
--- end
---
--- local latelua = nodes.pool.latelua
---
--- function anchors.node_set(tag)
--- return latelua(formatters["anchors.set(%q)"](tag))
--- end
---
--- function anchors.node_reset(tag)
--- return latelua(formatters["anchors.reset(%q)"](tag))
--- end
---
--- function anchors.node_start_move(tag,how)
--- return latelua(formatters["anchors.startmove(%q,%q)](tag,how))
--- end
---
--- function anchors.node_stop_move(tag)
--- return latelua(formatters["anchors.stopmove(%q)"](tag))
--- end
-
--- so far
-
local format, validstring = string.format, string.valid
local insert, remove, sortedkeys, fastcopy = table.insert, table.remove, table.sortedkeys, table.fastcopy
local setmetatable, next = setmetatable, next
@@ -138,6 +76,7 @@ local setattr = nuts.setattr
local getsubtype = nuts.getsubtype
local getlist = nuts.getlist
local setlist = nuts.setlist
+local setlink = nuts.setlink
local getbox = nuts.getbox
local takebox = nuts.takebox
@@ -158,11 +97,12 @@ local userdefined_code = whatsitcodes.userdefined
local nodepool = nuts.pool
local new_usernumber = nodepool.usernumber
+local new_hlist = nodepool.hlist
local lateluafunction = nodepool.lateluafunction
local texgetdimen = tex.getdimen
------ texgetcount = tex.getcount
+local texgetcount = tex.getcount
local texget = tex.get
local isleftpage = layouts.status.isleftpage
@@ -173,7 +113,6 @@ local addtoline = paragraphs.addtoline
local moveinline = paragraphs.moveinline
local calculatedelta = paragraphs.calculatedelta
------ a_specialcontent = attributes.private("specialcontent")
local a_linenumber = attributes.private('linenumber')
local inline_mark = nodepool.userids["margins.inline"]
@@ -194,6 +133,7 @@ local nofsaved = 0
local nofstored = 0
local nofinlined = 0
local nofdelayed = 0
+local nofinjected = 0
local h_anchors = 0
local v_anchors = 0
@@ -257,7 +197,6 @@ end
function margins.save(t)
setmetatable(t,defaults)
local content = takebox(t.number)
- -- setattr(content,a_specialcontent,1)
setprop(content,"specialcontent","margindata")
local location = t.location
local category = t.category
@@ -392,7 +331,7 @@ local function realign(current,candidate)
local atleft = true
local hmove = 0
local delta = 0
- local leftpage = isleftpage(false,true)
+ local leftpage = isleftpage()
local leftdelta = 0
local rightdelta = 0
local leftdistance = distance
@@ -426,6 +365,8 @@ local function realign(current,candidate)
if not leftpage then
atleft = false
end
+ else
+ -- v_left
end
local islocal = scope == v_local
@@ -477,20 +418,23 @@ end
-- table gets saved when the v_continue case is active. We use a special variant
-- of position tracking, after all we only need the page number and vertical position.
-local stacked = { } -- left/right keys depending on location
+local validstacknames = {
+ [v_left ] = v_left ,
+ [v_right] = v_right,
+ [v_inner] = v_inner,
+ [v_outer] = v_outer,
+}
+
local cache = { }
-local anchors = { }
-
-local function resetstacked(location)
- if location then
- local s = { }
- stacked[location] = s
- anchors[location] = false
- return s
- else
- stacked = { }
- anchors = { }
- return stacked
+local stacked = { [v_yes] = { }, [v_continue] = { } }
+local anchors = { [v_yes] = { }, [v_continue] = { } }
+
+local function resetstacked(all)
+ stacked[v_yes] = { }
+ anchors[v_yes] = { }
+ if all then
+ stacked[v_continue] = { }
+ anchors[v_continue] = { }
end
end
@@ -498,24 +442,45 @@ end
local function sa(tag) -- maybe l/r keys ipv left/right keys
local p = cache[tag]
- if trace_marginstack then
- report_margindata("updating anchor %a",tag)
+ if p then
+ if trace_marginstack then
+ report_margindata("updating anchor %a",tag)
+ end
+ p.p = true
+ p.y = true
+ setposition('md:v',tag,p)
+ cache[tag] = nil -- do this later, per page a cleanup
end
- p.p = true
- p.y = true
--- p.a = tag
- setposition('md:v',tag,p)
- cache[tag] = nil
end
local function setanchor(v_anchor) -- freezes the global here
return lateluafunction(function() sa(v_anchor) end)
end
+local function aa(tag,n) -- maybe l/r keys ipv left/right keys
+ local p = jobpositions.gettobesaved('md:v',tag)
+ if p then
+ if trace_marginstack then
+ report_margindata("updating injected %a",tag)
+ end
+ local pages = p.pages
+ if not pages then
+ pages = { }
+ p.pages = pages
+ end
+ pages[n] = texgetcount("realpageno")
+ elseif trace_marginstack then
+ report_margindata("not updating injected %a",tag)
+ end
+end
+
+local function addtoanchor(v_anchor,n) -- freezes the global here
+ return lateluafunction(function() aa(v_anchor,n) end)
+end
+
local function markovershoot(current) -- todo: alleen als offset > line
v_anchors = v_anchors + 1
cache[v_anchors] = fastcopy(stacked)
--- cache[v_anchors] = stacked -- so we adapt the previous too
local anchor = setanchor(v_anchors)
-- local list = hpack_nodes(linked_nodes(anchor,getlist(current))) -- not ok, we need to retain width
local list = hpack_nodes(linked_nodes(anchor,getlist(current)),getfield(current,"width"),"exactly")--
@@ -527,64 +492,6 @@ local function markovershoot(current) -- todo: alleen als offset > line
setlist(current,list)
end
--- local function getovershoot(location)
--- local p = getposition("md:v",v_anchors)
--- local c = getposition("md:v",v_anchors+1)
--- if p and c and p.p and p.p == c.p then
--- local distance = p.y - c.y
--- local offset = p[location] or 0
--- local overshoot = offset - distance
--- if trace_marginstack then
--- report_margindata("location %a, anchor %a, distance %p, offset %p, overshoot %p",location,v_anchors,distance,offset,overshoot)
--- end
--- if overshoot > 0 then
--- return overshoot, offset, distance
--- else
--- return 0, offset, distance
--- end
--- elseif trace_marginstack then
--- report_margindata("location %a, anchor %a, nothing to correct",location,v_anchors)
--- end
--- return 0, 0, 0
--- end
-
-local function getovershoot(location)
- local c = getposition("md:v",v_anchors+1)
- if c then
- local p = false
- local cp = c.p
- for i=v_anchors,1,-1 do
- local pi = getposition("md:v",i)
- if pi.p == cp then
- p = pi
- else
- break
- end
- end
- if p then
- local distance = p.y - c.y
- local offset = p[location] or 0
- local overshoot = offset - distance
- if trace_marginstack then
- report_margindata("location %a, anchor %a, distance %p, offset %p, overshoot %p",location,v_anchors,distance,offset,overshoot)
- end
- if overshoot > 0 then
- return overshoot, offset, distance
- else
- return 0, offset, distance
- end
- end
- end
- if trace_marginstack then
- report_margindata("location %a, anchor %a, nothing to correct",location,v_anchors)
- end
- return 0, 0, 0
-end
-
-local function getanchor(location,anchor)
- return getposition("md:v",anchor)
-end
-
local function inject(parent,head,candidate)
local box = candidate.box
if not box then
@@ -595,6 +502,7 @@ local function inject(parent,head,candidate)
local depth = getfield(box,"depth")
local shift = getfield(box,"shift")
local stack = candidate.stack
+ local stackname = candidate.stackname
local location = candidate.location
local method = candidate.method
local voffset = candidate.voffset
@@ -604,8 +512,18 @@ local function inject(parent,head,candidate)
local strutdepth = candidate.strutdepth
local inline = candidate.inline
local psubtype = getsubtype(parent)
- local offset = stacked[location]
+ -- This stackname is experimental and therefore undocumented and basically
+ -- unsupported. It was introduced when we needed to support overlapping
+ -- of different anchors.
+ if not stackname or stackname == "" then
+ stackname = location
+ else
+ stackname = validstacknames[stackname] or location
+ end
+ local isstacked = stack == v_continue or stack == v_yes
+ local offset = stack and stack ~= "" and stacked[stack][stackname]
local firstonstack = offset == false or offset == nil
+ nofinjected = nofinjected + 1
nofdelayed = nofdelayed + 1
-- yet untested
baseline = tonumber(baseline)
@@ -622,61 +540,79 @@ local function inject(parent,head,candidate)
baseline = false -- strutheight -- actually a hack
end
end
- candidate.width = width
- candidate.hsize = getfield(parent,"width") -- we can also pass textwidth
- candidate.psubtype = psubtype
+ candidate.width = width
+ candidate.hsize = getfield(parent,"width") -- we can also pass textwidth
+ candidate.psubtype = psubtype
+ candidate.stackname = stackname
if trace_margindata then
report_margindata("processing, index %s, height %p, depth %p, parent %a, method %a",candidate.n,height,depth,listcodes[psubtype],method)
end
- -- The next section handles the inline notes that are checked for overlap which
- -- is somewhat tricky as that mechanism is mostly for paragraph boundnotes.
- local stackedinline = inline and (stack == v_yes or stack == v_continue)
- if stackedinline then
+ -- Overlap detection is somewhat complex because we have display and inline
+ -- notes mixed as well as inner and outer positioning. We do need to
+ -- handle it in the stream because we also keep lines together so we keep
+ -- track of page numbers of notes.
+
+ if isstacked then
firstonstack = true
- if anchors[location] then
- local a1 = getanchor(location,anchors[location])
- local a2 = getanchor(location,v_anchors+1)
- if a1 and a2 and a1.p == a2.p then
- local distance = a1.y - a2.y
- if distance > offset then
- -- report_margindata("location %s, no overlap, case 1",location)
- elseif offset > 0 then
- offset = offset - distance
- firstonstack = false
- -- report_margindata("location %s, overlap %a",location,offset)
- -- else
- -- report_margindata("location %s, no overlap, case 2",location)
+ local anchor = getposition("md:v")
+ if anchor and (location == v_inner or location == v_outer) then
+ local pages = anchor.pages
+ if pages then
+ local page = pages[nofinjected]
+ if page then
+ if isleftpage(page) then
+ stackname = location == v_inner and v_right or v_left
+ else
+ stackname = location == v_inner and v_left or v_right
+ end
+ candidate.stackname = stackname
+ offset = stack and stack ~= "" and stacked[stack][stackname]
end
- -- else
- -- report_margindata("location %s, no overlap, case 3",location)
end
- -- else
- -- report_margindata("location %s, no overlap, case 4",location)
end
- anchors[location] = v_anchors + 1
- end
- -- end of special section
- if firstonstack then
- offset = 0
- else
- -- offset = offset + height
- end
- if stack == v_yes then
+ local current = v_anchors + 1
+ local previous = anchors[stack][stackname]
+ if trace_margindata then
+ report_margindata("anchor %i, offset so far %p",current,offset or 0)
+ end
+ local ap = anchor and anchor[previous]
+ local ac = anchor and anchor[current]
+ if not previous then
+ elseif previous == current then
+ firstonstack = false
+ elseif ap and ac and ap.p == ac.p then
+ local distance = ap.y - ac.y
+ if trace_margindata then
+ report_margindata("distance %p",distance)
+ end
+ if offset > distance then
+ -- we already overflow
+ offset = offset - distance
+ firstonstack = false
+ else
+ offset = 0
+ end
+ else
+ -- what to do
+ end
+ anchors[v_yes] [stackname] = current
+ anchors[v_continue][stackname] = current
+ if firstonstack then
+ offset = 0
+ end
offset = offset + candidate.dy -- always
shift = shift + offset
- elseif stack == v_continue then
- offset = offset + candidate.dy -- always
+ else
if firstonstack then
- offset = offset + getovershoot(location)
+ offset = 0
end
- shift = shift + offset
+ offset = offset + candidate.dy -- always
+ shift = shift + offset
end
- -- -- --
-- Maybe we also need to patch offset when we apply methods, but how ...
-- This needs a bit of playing as it depends on the stack setting of the
-- following which we don't know yet ... so, consider stacking partially
-- experimental.
- -- -- --
if method == v_top then
local delta = height - getfield(parent,"height")
if trace_margindata then
@@ -732,13 +668,19 @@ local function inject(parent,head,candidate)
offset = offset + delta
end
setfield(box,"shift",shift)
- setfield(box,"width",0)
+ setfield(box,"width",0) -- not needed when wrapped
+ --
+ if isstacked then
+ setlink(box,addtoanchor(v_anchor,nofinjected))
+ box = new_hlist(box)
+ -- set height / depth ?
+ end
--
candidate.hook, candidate.node = addtoline(parent,box)
--
setprop(box,"margindata",candidate)
if trace_margindata then
- report_margindata("injected, location %a, shift %p",location,shift)
+ report_margindata("injected, location %a, stack %a, shift %p",location,stackname,shift)
end
-- we need to add line etc to offset as well
offset = offset + depth
@@ -747,16 +689,17 @@ local function inject(parent,head,candidate)
depth = offset,
slack = candidate.bottomspace, -- todo: 'depth' => strutdepth
lineheight = candidate.lineheight, -- only for tracing
- stacked = stackedinline,
+ stacked = inline and isstacked,
}
offset = offset + height
-- we need a restart ... when there is no overlap at all
- stacked[location] = offset
+ stacked[v_yes] [stackname] = offset
+ stacked[v_continue][stackname] = offset
-- todo: if no real depth then zero
if trace_margindata then
report_margindata("status, offset %s",offset)
end
- return getlist(parent), room, stackedinline or (stack == v_continue)
+ return getlist(parent), room, inline and isstacked or (stack == v_continue)
end
local function flushinline(parent,head)
@@ -850,7 +793,6 @@ local function flushed(scope,parent) -- current is hlist
setattr(parent,a_linenumber,a)
end
end
- -- resetstacked()
end
return done, continue
end
@@ -890,9 +832,7 @@ local function handler(scope,head,group)
report_margindata("flushing stage one, nothing done, %s left",nofstored)
end
end
- -- if done then
- resetstacked() -- why doesn't done work ok here?
- -- end
+resetstacked()
return tonode(head), done
else
return head, false
@@ -964,7 +904,6 @@ local function finalhandler(head)
local id = getid(current)
if id == hlist_code then -- only lines?
local a = getprop(current,"margindata")
--- if not a or a == 0 then
if not a then
finalhandler(getlist(current))
elseif realigned(current,a) then
@@ -991,9 +930,11 @@ function margins.finalhandler(head)
end
head = tonut(head)
local head, done = finalhandler(head)
+ resetstacked(true)
head = tonode(head)
return head, done
else
+ resetstacked()
return head, false
end
end
@@ -1055,6 +996,7 @@ interfaces.implement {
{ "align" },
{ "option" },
{ "line", "integer" },
+ { "stackname" },
{ "stack" },
}
}
diff --git a/tex/context/base/mkiv/typo-mar.mkiv b/tex/context/base/mkiv/typo-mar.mkiv
index 4c634a2d3..013974086 100644
--- a/tex/context/base/mkiv/typo-mar.mkiv
+++ b/tex/context/base/mkiv/typo-mar.mkiv
@@ -122,6 +122,7 @@
\c!scope=\v!global,
\c!width=,
% \c!stack=,
+ % \c!stackname=,
% \c!option=, % \v!paragraph (follow shape)
\c!line=0,
\c!anchor=\v!text,
@@ -131,8 +132,8 @@
\c!hoffset=\zeropoint,
\c!voffset=\zeropoint]
-\setupmarginframed % so, align should be set with the data command
- [\c!strut=\v!yes,
+\setupmarginframed % so, align should be set with the data command
+ [\c!strut=\v!yes, % so by default we scale the strut to the font !
\c!offset=\v!overlay,
\c!fr!analyze=\v!yes,
\c!frame=\v!off,
@@ -303,6 +304,7 @@
% \fi
align {\margindataparameter\c!align}%
line \numexpr\margindataparameter\c!line\relax
+ stackname {\margindataparameter\c!stackname}%
stack {\margindataparameter\c!stack}%
\relax
\else
diff --git a/tex/context/interface/mkii/keys-cs.xml b/tex/context/interface/mkii/keys-cs.xml
index ce8e41016..94f41a5a8 100644
--- a/tex/context/interface/mkii/keys-cs.xml
+++ b/tex/context/interface/mkii/keys-cs.xml
@@ -1166,6 +1166,7 @@
<cd:constant name='splitoffset' value='splitoffset'/>
<cd:constant name='spot' value='spot'/>
<cd:constant name='stack' value='stack'/>
+ <cd:constant name='stackname' value='stackname'/>
<cd:constant name='start' value='start'/>
<cd:constant name='starter' value='starter'/>
<cd:constant name='state' value='status'/>
diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml
index 5c7ecc651..edbba27c9 100644
--- a/tex/context/interface/mkii/keys-de.xml
+++ b/tex/context/interface/mkii/keys-de.xml
@@ -1166,6 +1166,7 @@
<cd:constant name='splitoffset' value='splitoffset'/>
<cd:constant name='spot' value='spot'/>
<cd:constant name='stack' value='stack'/>
+ <cd:constant name='stackname' value='stackname'/>
<cd:constant name='start' value='start'/>
<cd:constant name='starter' value='starter'/>
<cd:constant name='state' value='status'/>
diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml
index 621cbd763..9b0a7727a 100644
--- a/tex/context/interface/mkii/keys-en.xml
+++ b/tex/context/interface/mkii/keys-en.xml
@@ -1166,6 +1166,7 @@
<cd:constant name='splitoffset' value='splitoffset'/>
<cd:constant name='spot' value='spot'/>
<cd:constant name='stack' value='stack'/>
+ <cd:constant name='stackname' value='stackname'/>
<cd:constant name='start' value='start'/>
<cd:constant name='starter' value='starter'/>
<cd:constant name='state' value='state'/>
diff --git a/tex/context/interface/mkii/keys-fr.xml b/tex/context/interface/mkii/keys-fr.xml
index 301f94628..dbc2955f5 100644
--- a/tex/context/interface/mkii/keys-fr.xml
+++ b/tex/context/interface/mkii/keys-fr.xml
@@ -1166,6 +1166,7 @@
<cd:constant name='splitoffset' value='splitoffset'/>
<cd:constant name='spot' value='spot'/>
<cd:constant name='stack' value='stack'/>
+ <cd:constant name='stackname' value='stackname'/>
<cd:constant name='start' value='demarre'/>
<cd:constant name='starter' value='starter'/>
<cd:constant name='state' value='etat'/>
diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml
index 458acd5c1..dcd6e4502 100644
--- a/tex/context/interface/mkii/keys-it.xml
+++ b/tex/context/interface/mkii/keys-it.xml
@@ -1166,6 +1166,7 @@
<cd:constant name='splitoffset' value='splitoffset'/>
<cd:constant name='spot' value='spot'/>
<cd:constant name='stack' value='stack'/>
+ <cd:constant name='stackname' value='stackname'/>
<cd:constant name='start' value='inizia'/>
<cd:constant name='starter' value='starter'/>
<cd:constant name='state' value='stato'/>
diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml
index 5e214c8bb..f2ce3629b 100644
--- a/tex/context/interface/mkii/keys-nl.xml
+++ b/tex/context/interface/mkii/keys-nl.xml
@@ -1166,6 +1166,7 @@
<cd:constant name='splitoffset' value='splitsoffset'/>
<cd:constant name='spot' value='spot'/>
<cd:constant name='stack' value='stapel'/>
+ <cd:constant name='stackname' value='stapelnaam'/>
<cd:constant name='start' value='start'/>
<cd:constant name='starter' value='opener'/>
<cd:constant name='state' value='status'/>
diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml
index 1afb96c9a..e66ad4f09 100644
--- a/tex/context/interface/mkii/keys-pe.xml
+++ b/tex/context/interface/mkii/keys-pe.xml
@@ -1166,6 +1166,7 @@
<cd:constant name='splitoffset' value='شکافتن‌آفست'/>
<cd:constant name='spot' value='لکه'/>
<cd:constant name='stack' value='توده'/>
+ <cd:constant name='stackname' value='stackname'/>
<cd:constant name='start' value='شروع'/>
<cd:constant name='starter' value='starter'/>
<cd:constant name='state' value='وضعیت'/>
diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml
index 8a7707a2d..2fe560325 100644
--- a/tex/context/interface/mkii/keys-ro.xml
+++ b/tex/context/interface/mkii/keys-ro.xml
@@ -1166,6 +1166,7 @@
<cd:constant name='splitoffset' value='splitoffset'/>
<cd:constant name='spot' value='spot'/>
<cd:constant name='stack' value='stack'/>
+ <cd:constant name='stackname' value='stackname'/>
<cd:constant name='start' value='start'/>
<cd:constant name='starter' value='starter'/>
<cd:constant name='state' value='stare'/>
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 39a841a19..0e4fe395e 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 1e326ed67..acb862767 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 4d1ef8322..19fb2482c 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 05/31/16 09:02:55
+-- merge date : 06/02/16 21:28:16
do -- begin closure to overcome local limits and interference