summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/context-version.pdfbin4245 -> 4245 bytes
-rw-r--r--tex/context/base/mkiv/char-utf.lua76
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/font-con.lua29
-rw-r--r--tex/context/base/mkiv/font-ctx.lua128
-rw-r--r--tex/context/base/mkiv/font-fea.mkvi32
-rw-r--r--tex/context/base/mkiv/font-ini.mkvi44
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-otc.lua178
-rw-r--r--tex/context/base/mkiv/font-otd.lua48
-rw-r--r--tex/context/base/mkiv/font-otl.lua2
-rw-r--r--tex/context/base/mkiv/font-ots.lua13
-rw-r--r--tex/context/base/mkiv/lang-dis.lua12
-rw-r--r--tex/context/base/mkiv/lang-hyp.lua32
-rw-r--r--tex/context/base/mkiv/lang-ini.lua4
-rw-r--r--tex/context/base/mkiv/node-fnt.lua6
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin9080 -> 9192 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin268642 -> 268684 bytes
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin820812 -> 793238 bytes
-rw-r--r--tex/context/interface/mkiv/i-fonts.xml52
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60787 -> 60787 bytes
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua628
-rw-r--r--tex/generic/context/luatex/luatex-fonts.lua1
-rw-r--r--tex/generic/context/luatex/luatex-math.tex12
25 files changed, 1005 insertions, 298 deletions
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index 50c1120d2..2fb1cdae6 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/char-utf.lua b/tex/context/base/mkiv/char-utf.lua
index 327529c32..ece9d7a76 100644
--- a/tex/context/base/mkiv/char-utf.lua
+++ b/tex/context/base/mkiv/char-utf.lua
@@ -48,8 +48,8 @@ characters.graphemes = graphemes
local collapsed = allocate()
characters.collapsed = collapsed
-local combined = allocate()
-characters.combined = combined
+-- local combined = allocate()
+-- characters.combined = combined
local decomposed = allocate()
characters.decomposed = decomposed
@@ -65,8 +65,6 @@ characters.filters.utf = utffilters
local data = characters.data
--- is characters.combined cached?
-
--[[ldx--
<p>It only makes sense to collapse at runtime, since we don't expect source code
to depend on collapsing.</p>
@@ -96,76 +94,6 @@ local decomposed = allocate {
characters.decomposed = decomposed
--- local function initialize() -- maybe only 'mn'
--- local data = characters.data
--- for unicode, v in next, data do
--- -- using vs and first testing for length is faster (.02->.01 s)
--- local vs = v.specials
--- if vs and #vs == 3 then
--- local vc = vs[1]
--- if vc == "char" then
--- local one, two = vs[2], vs[3]
--- if data[two].category == "mn" then
--- local cgf = combined[one]
--- if not cgf then
--- cgf = { [two] = unicode }
--- combined[one] = cgf
--- else
--- cgf[two] = unicode
--- end
--- end
--- local first, second, combination = utfchar(one), utfchar(two), utfchar(unicode)
--- local cgf = graphemes[first]
--- if not cgf then
--- cgf = { [second] = combination }
--- graphemes[first] = cgf
--- else
--- cgf[second] = combination
--- end
--- if v.mathclass or v.mathspec then
--- local mps = mathpairs[two]
--- if not mps then
--- mps = { [one] = unicode }
--- mathpairs[two] = mps
--- else
--- mps[one] = unicode -- here unicode
--- end
--- local mps = mathpairs[second]
--- if not mps then
--- mps = { [first] = combination }
--- mathpairs[second] = mps
--- else
--- mps[first] = combination
--- end
--- end
--- -- elseif vc == "compat" then
--- -- else
--- -- local description = v.description
--- -- if find(description,"LIGATURE") then
--- -- if vs then
--- -- local t = { }
--- -- for i=2,#vs do
--- -- t[#t+1] = utfchar(vs[i])
--- -- end
--- -- decomposed[utfchar(unicode)] = concat(t)
--- -- else
--- -- local vs = v.shcode
--- -- if vs then
--- -- local t = { }
--- -- for i=1,#vs do
--- -- t[i] = utfchar(vs[i])
--- -- end
--- -- decomposed[utfchar(unicode)] = concat(t)
--- -- end
--- -- end
--- -- end
--- end
--- end
--- end
--- initialize = false
--- characters.initialize = function() end -- when used outside tex
--- end
-
local function initialize() -- maybe in tex mode store in format !
local data = characters.data
local function backtrack(v,last,target)
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 6e7b66a5b..943b7d050 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.06.02 21:28}
+\newcontextversion{2016.06.05 16:26}
%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.mkiv b/tex/context/base/mkiv/context.mkiv
index 06455ca91..0548d0023 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.06.02 21:28}
+\edef\contextversion{2016.06.05 16:26}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index 367f8078e..3af286203 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -1049,6 +1049,29 @@ function constructors.hashfeatures(specification) -- will be overloaded
return "unknown"
end
+-- hashmethods.normal = function(list)
+-- local s = { }
+-- local n = 0
+-- for k, v in next, list do
+-- if not k then
+-- -- no need to add to hash
+-- elseif k == "number" or k == "features" then
+-- -- no need to add to hash (maybe we need a skip list)
+-- else
+-- n = n + 1
+-- s[n] = k
+-- end
+-- end
+-- if n > 0 then
+-- sort(s)
+-- for i=1,n do
+-- local k = s[i]
+-- s[i] = k .. '=' .. tostring(list[k])
+-- end
+-- return concat(s,"+")
+-- end
+-- end
+
hashmethods.normal = function(list)
local s = { }
local n = 0
@@ -1059,15 +1082,11 @@ hashmethods.normal = function(list)
-- no need to add to hash (maybe we need a skip list)
else
n = n + 1
- s[n] = k
+ s[n] = k .. '=' .. tostring(v)
end
end
if n > 0 then
sort(s)
- for i=1,n do
- local k = s[i]
- s[i] = k .. '=' .. tostring(list[k])
- end
return concat(s,"+")
end
end
diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua
index d0cff32f8..82c70164c 100644
--- a/tex/context/base/mkiv/font-ctx.lua
+++ b/tex/context/base/mkiv/font-ctx.lua
@@ -174,8 +174,8 @@ constructors.nofsharedhashes = 0
constructors.nofsharedvectors = 0
constructors.noffontsloaded = 0
-local shares = { }
-local hashes = { }
+local shares = { }
+local hashes = { }
function constructors.trytosharefont(target,tfmdata)
constructors.noffontsloaded = constructors.noffontsloaded + 1
@@ -292,7 +292,7 @@ otftables.scripts.auto = "automatic fallback to latn when no dflt present"
-- setmetatableindex(otffeatures.descriptions,otftables.features)
-local privatefeatures = {
+local privatefeatures = { -- this can go away
tlig = true,
trep = true,
anum = true,
@@ -583,42 +583,48 @@ local function presetcontext(name,parent,features) -- will go to con and shared
return number, t
end
+-- local function contextnumber(name) -- will be replaced
+-- local t = setups[name]
+-- if not t then
+-- return 0
+-- elseif t.auto then -- check where used, autolanguage / autoscript?
+-- local lng = tonumber(tex.language)
+-- local tag = name .. ":" .. lng
+-- local s = setups[tag]
+-- if s then
+-- return s.number or 0
+-- else
+-- local script, language = languages.association(lng)
+-- if t.script ~= script or t.language ~= language then
+-- local s = fastcopy(t)
+-- local n = #numbers + 1
+-- setups[tag] = s
+-- numbers[n] = tag
+-- s.number = n
+-- s.script = script
+-- s.language = language
+-- return n
+-- else
+-- setups[tag] = t
+-- return t.number or 0
+-- end
+-- end
+-- else
+-- return t.number or 0
+-- end
+-- end
+
local function contextnumber(name) -- will be replaced
local t = setups[name]
- if not t then
- return 0
- elseif t.auto then
- local lng = tonumber(tex.language)
- local tag = name .. ":" .. lng
- local s = setups[tag]
- if s then
- return s.number or 0
- else
- local script, language = languages.association(lng)
- if t.script ~= script or t.language ~= language then
- local s = fastcopy(t)
- local n = #numbers + 1
- setups[tag] = s
- numbers[n] = tag
- s.number = n
- s.script = script
- s.language = language
- return n
- else
- setups[tag] = t
- return t.number or 0
- end
- end
- else
- return t.number or 0
- end
+ return t and t.number or 0
end
local function mergecontext(currentnumber,extraname,option) -- number string number (used in scrp-ini
local extra = setups[extraname]
if extra then
local current = setups[numbers[currentnumber]]
- local mergedfeatures, mergedname = { }, nil
+ local mergedfeatures = { }
+ local mergedname = nil
if option < 0 then
if current then
for k, v in next, current do
@@ -1435,7 +1441,7 @@ function definers.resolve(specification) -- overload function in font-con.lua
else
specification.forced = specification.forced
end
- -- goodies are a context specific thing and not always defined
+ -- goodies are a context specific thing and are not always defined
-- as feature, so we need to make sure we add them here before
-- hashing because otherwise we get funny goodies applied
local goodies = specification.goodies
@@ -1454,14 +1460,21 @@ function definers.resolve(specification) -- overload function in font-con.lua
end
end
-- so far for goodie hacks
- specification.hash = lower(specification.name .. ' @ ' .. hashfeatures(specification))
- if specification.sub and specification.sub ~= "" then
- specification.hash = specification.sub .. ' @ ' .. specification.hash
+ local hash = hashfeatures(specification)
+ local name = specification.name
+ local sub = specification.sub
+ if sub and sub ~= "" then
+ specification.hash = lower(name .. " @ " .. sub .. ' @ ' .. hash)
+ else
+ specification.hash = lower(name .. " @ " .. ' @ ' .. hash)
end
+ --
return specification
end
+
+
-- soon to be obsolete:
local mappings = fonts.mappings
@@ -2021,15 +2034,7 @@ end
do
- -- local scanners = tokens.scanners
- -- local scanstring = scanners.string
- -- local scaninteger = scanners.integer
- -- local scandimen = scanners.dimen
- -- local scanboolean = scanners.boolean
-
- -- local scanners = interfaces.scanners
-
- local setmacro = tokens.setters.macro
+ local setmacro = tokens.setters.macro
function constructors.currentfonthasfeature(n)
local f = fontdata[currentfont()]
@@ -2046,25 +2051,9 @@ do
arguments = "string"
}
- -- local p, f = 1, formatters["%0.1fpt"] -- normally this value is changed only once
- --
- -- local stripper = lpeg.patterns.stripzeros
- --
- -- function commands.nbfs(amount,precision)
- -- if precision ~= p then
- -- p = precision
- -- f = formatters["%0." .. p .. "fpt"]
- -- end
- -- context(lpegmatch(stripper,f(amount/65536)))
- -- end
-
local f_strip = formatters["%0.2fpt"] -- normally this value is changed only once
local stripper = lpeg.patterns.stripzeros
- -- scanners.nbfs = function()
- -- context(lpegmatch(stripper,f_strip(scandimen()/65536)))
- -- end
-
implement {
name = "nbfs",
arguments = "dimen",
@@ -2073,18 +2062,6 @@ do
end
}
- -- commands.featureattribute = function(tag) context(contextnumber(tag)) end
- -- commands.setfontfeature = function(tag) texsetattribute(0,contextnumber(tag)) end
- -- commands.resetfontfeature = function() texsetattribute(0,0) end
- -- commands.setfontofid = function(id) context_getvalue(csnames[id]) end
- -- commands.definefontfeature = presetcontext
-
- -- scanners.featureattribute = function() context(contextnumber(scanstring())) end
- -- scanners.setfontfeature = function() texsetattribute(0,contextnumber(scanstring())) end
- -- scanners.resetfontfeature = function() texsetattribute(0,0) end
- -- scanners.setfontofid = function() context_getvalue(csnames[scaninteger()]) end
- -- scanners.definefontfeature = function() presetcontext(scanstring(),scanstring(),scanstring()) end
-
implement {
name = "featureattribute",
arguments = "string",
@@ -2187,6 +2164,9 @@ do
end
end
+ constructors.setfeature = setfeature
+ constructors.resetfeature = resetfeature
+
implement { name = "resetfeature", actions = resetfeature }
implement { name = "addfeature", actions = setfeature, arguments = { "'+'", "string", "string" } }
implement { name = "subtractfeature", actions = setfeature, arguments = { "'-'", "string", "string" } }
@@ -2200,8 +2180,8 @@ do
}
implement {
- name = "registerlanguagefeatures",
- actions = registerlanguagefeatures,
+ name = "registerlanguagefeatures",
+ actions = registerlanguagefeatures,
}
end
diff --git a/tex/context/base/mkiv/font-fea.mkvi b/tex/context/base/mkiv/font-fea.mkvi
index dade70494..4a4034225 100644
--- a/tex/context/base/mkiv/font-fea.mkvi
+++ b/tex/context/base/mkiv/font-fea.mkvi
@@ -284,6 +284,38 @@
\letvalue{\??featureyes\s!unknown}\empty
\letvalue{\??featurenop\s!unknown}\empty
+% experimental bonus:
+
+% \unexpanded\def\addfflanguage
+% {\ifnum\c_font_feature_state=\plusone
+% \ifx\currentlanguage\currentfeature\else
+% \font_feature_add_language_indeed
+% \fi
+% \else
+% \font_feature_add_language_indeed
+% \fi}
+%
+% \unexpanded\def\font_feature_add_language_indeed
+% {\clf_addfeature{\m_font_feature_list}{\currentlanguage}%
+% \edef\m_font_feature_list{\m_font_feature_list+\currentlanguage}% also + at the lua end
+% \c_font_feature_state\plusone
+% \let\currentfeature\currentlanguage}
+%
+% some 3% slower:
+
+% \unexpanded\def\addfflanguage
+% {\let\m_font_feature_asked\currentlanguage
+% \font_feature_add}
+
+\let\m_font_feature_language\currentlanguage
+
+\unexpanded\def\addfflanguage
+ {\ifx\currentlanguage\m_font_feature_language\else
+ \let\m_font_feature_language\currentlanguage
+ \let\m_font_feature_asked \currentlanguage
+ \font_feature_add
+ \fi}
+
% just for old times sake:
\unexpanded\def\featureattribute#feature%
diff --git a/tex/context/base/mkiv/font-ini.mkvi b/tex/context/base/mkiv/font-ini.mkvi
index edf9e688e..73df62677 100644
--- a/tex/context/base/mkiv/font-ini.mkvi
+++ b/tex/context/base/mkiv/font-ini.mkvi
@@ -879,6 +879,40 @@
\let\fontfile\s!unknown
+%D Relatively new:
+
+\installcorenamespace{fonts}
+\installcorenamespace{fontslanguage}
+
+\installsetuponlycommandhandler \??fonts {fonts}
+
+\newconstant\c_fonts_auto_language
+
+\letvalue{\??fontslanguage\v!auto}\plusone % experimental
+%letvalue{\??fontslanguage\v!yes }\plustwo % less efficient, for experiments
+
+\appendtoks
+ \c_fonts_auto_language
+ \ifcsname\??fontslanguage\fontsparameter\c!language\endcsname
+ \lastnamedcs
+ \else
+ \zerocount
+ \fi
+\to \everysetupfonts
+
+\appendtoks
+ \ifcase\c_fonts_auto_language
+ % nothing
+ \or
+ \addfflanguage
+ % \or
+ % font
+ \fi
+\to \everylanguage
+
+% \setupfonts
+% [\c!language=\v!auto]
+
%D \macros
%D {everyfont,everyfontswitch}
@@ -887,6 +921,16 @@
\def\setfontcharacteristics{\the\everyfont}
+% \appendtoks
+% \ifcase\c_fonts_auto_language
+% % nothing
+% \or
+% % auto
+% \or
+% \addfflanguage
+% \fi
+% \to \everyfont
+
%D \macros
%D {definefont}
%D
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index 5d0d5af7a..6cf305309 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers = otf.readers
if readers then
- otf.version = otf.version or 3.021
+ otf.version = otf.version or 3.022
otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true)
function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua
index a91dac5cf..d50b1ec14 100644
--- a/tex/context/base/mkiv/font-otc.lua
+++ b/tex/context/base/mkiv/font-otc.lua
@@ -51,6 +51,42 @@ local noflags = { false, false, false, false }
-- beware: shared, maybe we should copy the sequence
+local function validspecification(specification,name)
+ local dataset = specification.dataset
+ if dataset then
+ -- okay
+ elseif specification[1] then
+ dataset = specification
+ specification = { dataset = dataset }
+ else
+ dataset = { { data = specification.data } }
+ specification.data = nil
+ specification.dataset = dataset
+ end
+ local first = dataset[1]
+ if first then
+ first = first.data
+ end
+ if not first then
+ report_otf("invalid feature specification, no dataset")
+ return
+ end
+ if type(name) ~= "string" then
+ name = specification.name or first.name
+ end
+ if type(name) ~= "string" then
+ report_otf("invalid feature specification, no name")
+ return
+ end
+ local n = #dataset
+ if n > 0 then
+ for i=1,n do
+ setmetatableindex(dataset[i],specification)
+ end
+ return specification, name
+ end
+end
+
local function addfeature(data,feature,specifications)
-- todo: add some validator / check code so that we're more tolerant to
@@ -63,6 +99,18 @@ local function addfeature(data,feature,specifications)
if not features or not sequences then
return
end
+
+local alreadydone = resources.alreadydone
+if not alreadydone then
+ alreadydone = { }
+ resources.alreadydone = alreadydone
+end
+if alreadydone[specifications] then
+ return
+else
+ alreadydone[specifications] = true
+end
+
-- feature has to be unique but the name entry wins eventually
local fontfeatures = resources.features or everywhere
@@ -72,9 +120,9 @@ local function addfeature(data,feature,specifications)
local skip = 0
local aglunicodes = false
- if not specifications[1] then
- -- so we accept a one entry specification
- specifications = { specifications }
+ local specifications = validspecification(specifications,name)
+ if not specifications then
+ return
end
local function tounicode(code)
@@ -376,11 +424,15 @@ local function addfeature(data,feature,specifications)
return coverage
end
- for s=1,#specifications do
- local specification = specifications[s]
- local valid = specification.valid
- local feature = specification.name or feature
- if not valid or valid(data,specification,feature) then
+ local dataset = specifications.dataset
+
+ for s=1,#dataset do
+ local specification = dataset[s]
+ local valid = specification.valid -- nowhere used
+ local feature = specification.name or feature
+ if not feature or feature == "" then
+ report_otf("no valid name given for extra feature")
+ elseif not valid or valid(data,specification,feature) then -- anum uses this
local initialize = specification.initialize
if initialize then
-- when false is returned we initialize only once
@@ -497,10 +549,37 @@ local function addfeature(data,feature,specifications)
type = types[featuretype],
}
-- todo : before|after|index
- if specification.prepend then
- insert(sequences,1,sequence)
- else
+ local prepend = specification.prepend
+ if prepend == true then
+ prepend = 1
+ end
+ if type(prepend) == "number" then
+ -- okay
+ elseif type(prepend) == "string" then
+ local index = false
+ for i=1,#sequences do
+ local s = sequences[i]
+ local f = s.features
+ if f then
+ for k in next, f do
+ if k == prepend then
+ index = i
+ break
+ end
+ end
+ if index then
+ break
+ end
+ end
+ end
+ prepend = index
+ elseif prepend == true then
+ prepend = 1
+ end
+ if not prepend or prepend <= 0 or prepend > #sequences then
insert(sequences,sequence)
+ else
+ insert(sequences,prepend,sequence)
end
-- register in metadata (merge as there can be a few)
local features = fontfeatures[category]
@@ -540,18 +619,23 @@ local knownfeatures = { }
function otf.addfeature(name,specification)
if type(name) == "table" then
specification = name
- name = specification.name
end
- if type(name) == "string" then
+ if type(specification) ~= "table" then
+ report_otf("invalid feature specification, no valid table")
+ return
+ end
+ specification, name = validspecification(specification,name)
+ if name and specification then
local slot = knownfeatures[name]
if slot then
- -- we overload one
+ -- we overload one .. should be option
else
slot = #extrafeatures + 1
knownfeatures[name] = slot
end
specification.name = name -- to be sure
extrafeatures[slot] = specification
+ -- report_otf("adding feature %a @ %i",name,slot)
end
end
@@ -626,39 +710,39 @@ registerotffeature {
description = 'tex replacements',
}
--- tcom
-
-if characters.combined then
-
- local tcom = { }
-
- local function initialize()
- characters.initialize()
- for first, seconds in next, characters.combined do
- for second, combination in next, seconds do
- tcom[combination] = { first, second }
- end
- end
- -- return false
- end
-
- local tcom_specification = {
- type = "ligature",
- features = everywhere,
- data = tcom,
- order = { "tcom" },
- flags = noflags,
- initialize = initialize,
- }
-
- otf.addfeature("tcom",tcom_specification)
-
- registerotffeature {
- name = 'tcom',
- description = 'tex combinations',
- }
-
-end
+-- -- tcom (obsolete, was already not set for a while)
+
+-- if characters.combined then
+--
+-- local tcom = { }
+--
+-- local function initialize()
+-- characters.initialize()
+-- for first, seconds in next, characters.combined do
+-- for second, combination in next, seconds do
+-- tcom[combination] = { first, second }
+-- end
+-- end
+-- -- return false
+-- end
+--
+-- local tcom_specification = {
+-- type = "ligature",
+-- features = everywhere,
+-- data = tcom,
+-- order = { "tcom" },
+-- flags = noflags,
+-- initialize = initialize,
+-- }
+--
+-- otf.addfeature("tcom",tcom_specification)
+--
+-- registerotffeature {
+-- name = 'tcom',
+-- description = 'tex combinations',
+-- }
+--
+-- end
-- anum
diff --git a/tex/context/base/mkiv/font-otd.lua b/tex/context/base/mkiv/font-otd.lua
index fc5ba64c9..64cb1bcb4 100644
--- a/tex/context/base/mkiv/font-otd.lua
+++ b/tex/context/base/mkiv/font-otd.lua
@@ -132,6 +132,10 @@ local wildcard = "*"
-- needs checking: some added features can pass twice
+local P, C, Cc, lpegmatch = lpeg.P, lpeg.C, lpeg.Cc, lpeg.match
+
+local pattern = P("always") * (P(-1) * Cc(true) + P(":") * C((1-P(-1))^1))
+
local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr,dynamic,ra,autoscript,autolanguage)
local features = sequence.features
if features then
@@ -148,21 +152,34 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr
e_e = s_enabled and s_enabled[kind] -- the value (font)
end
if e_e then
- local scripts = features[kind] --
- local languages = scripts[script] or scripts[wildcard]
- if not languages and autoscript then
- langages = defaultscript(featuretype,autoscript,scripts)
- end
- if languages then
- -- we need detailed control over default becase we want to trace
- -- only first attribute match check, so we assume simple fina's
- local valid = false
- if languages[language] then
- valid = e_e
- elseif languages[wildcard] then
- valid = e_e
- elseif autolanguage and defaultlanguage(featuretype,autolanguage,languages) then
- valid = e_e
+ local valid = type(e_e) == "string" and lpegmatch(pattern,e_e)
+ if valid then
+ -- we have hit always
+ local attribute = autofeatures[kind] or false
+ if trace_applied then
+ report_process(
+ "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a",
+ font,attr or 0,dynamic,kind,"*","*",sequence.name,valid)
+ end
+ ra[#ra+1] = { valid, attribute, sequence, kind }
+ else
+ -- we already checked for e_e
+ local scripts = features[kind] --
+ local languages = scripts[script] or scripts[wildcard]
+ if not languages and autoscript then
+ langages = defaultscript(featuretype,autoscript,scripts)
+ end
+ if languages then
+ -- we need detailed control over default becase we want to trace
+ -- only first attribute match check, so we assume simple fina's
+ -- local valid = false
+ if languages[language] then
+ valid = e_e
+ elseif languages[wildcard] then
+ valid = e_e
+ elseif autolanguage and defaultlanguage(featuretype,autolanguage,languages) then
+ valid = e_e
+ end
end
if valid then
local attribute = autofeatures[kind] or false
@@ -241,6 +258,7 @@ function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in specia
local autoscript = (s_enabled and s_enabled.autoscript ) or (a_enabled and a_enabled.autoscript )
local autolanguage = (s_enabled and s_enabled.autolanguage) or (a_enabled and a_enabled.autolanguage)
for s=1,#sequences do
+ -- just return nil or ra step
initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic,ra,autoscript,autolanguage)
end
end
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index 73e3df9c0..394689b82 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -53,7 +53,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.021 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.022 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
local otfreaders = otf.readers
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 669668eb8..544af9003 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -124,7 +124,7 @@ local trace_cursive = false registertracker("otf.cursive", function(v
local trace_preparing = false registertracker("otf.preparing", function(v) trace_preparing = v end)
local trace_bugs = false registertracker("otf.bugs", function(v) trace_bugs = v end)
local trace_details = false registertracker("otf.details", function(v) trace_details = v end)
-local trace_applied = false registertracker("otf.applied", function(v) trace_applied = v end)
+----- trace_applied = false registertracker("otf.applied", function(v) trace_applied = v end)
local trace_steps = false registertracker("otf.steps", function(v) trace_steps = v end)
local trace_skips = false registertracker("otf.skips", function(v) trace_skips = v end)
local trace_directions = false registertracker("otf.directions", function(v) trace_directions = v end)
@@ -3389,9 +3389,13 @@ local function featuresprocessor(head,font,attr)
end
- if attr == 0 then
- attr = false -- some 10% faster when no dynamics but hardly measureable on real runs
- end
+ -- some 10% faster when no dynamics but hardly measureable on real runs .. but: it only
+ -- works when we have no other dynamics as otherwise the zero run will be applied to the
+ -- whole stream for which we then need to pass another variable which we won't
+
+ -- if attr == 0 then
+ -- attr = false
+ -- end
head = tonut(head)
@@ -3484,7 +3488,6 @@ local function featuresprocessor(head,font,attr)
local start = head -- local ?
rlmode = 0 -- to be checked ?
if nofsteps == 1 then -- happens often
-
local step = steps[1]
local lookupcache = step.coverage
if not lookupcache then
diff --git a/tex/context/base/mkiv/lang-dis.lua b/tex/context/base/mkiv/lang-dis.lua
index 749e2e35d..7fd5a6afb 100644
--- a/tex/context/base/mkiv/lang-dis.lua
+++ b/tex/context/base/mkiv/lang-dis.lua
@@ -26,6 +26,7 @@ local getattr = nuts.getattr
local getsubtype = nuts.getsubtype
local setsubtype = nuts.setsubtype
local getchar = nuts.getchar
+local setchar = nuts.setchar
local getdisc = nuts.getdisc
local setdisc = nuts.setdisc
local isglyph = nuts.isglyph
@@ -33,12 +34,14 @@ local isglyph = nuts.isglyph
local copy_node = nuts.copy
local remove_node = nuts.remove
local traverse_id = nuts.traverse_id
+local flush_list = nuts.flush_list
local nodecodes = nodes.nodecodes
local disccodes = nodes.disccodes
local disc_code = nodecodes.disc
local glyph_code = nodecodes.glyph
+
local discretionary_code = disccodes.discretionary
local a_visualize = attributes.private("visualizediscretionary")
@@ -49,7 +52,7 @@ local getlanguagedata = languages.getdata
local check_regular = true
local expanders = {
- [disccodes.discretionary] = function(d,template)
+ [discretionary_code] = function(d,template)
-- \discretionary
return template
end,
@@ -61,18 +64,23 @@ local expanders = {
local char = isglyph(pre)
if char and char <= 0 then
done = true
- pre = nil
+ flush_list(pre)
+ pre = nil
end
end
if post then
local char = isglyph(post)
if char and char <= 0 then
done = true
+ flush_list(post)
post = nil
end
end
if done then
+ -- todo: take existing penalty
setdisc(d,pre,post,replace,discretionary_code,tex.exhyphenpenalty)
+ else
+ setfield(d,"subtype",discretionary_code)
end
return template
end,
diff --git a/tex/context/base/mkiv/lang-hyp.lua b/tex/context/base/mkiv/lang-hyp.lua
index 7864220e3..b797f85e1 100644
--- a/tex/context/base/mkiv/lang-hyp.lua
+++ b/tex/context/base/mkiv/lang-hyp.lua
@@ -605,8 +605,8 @@ if context then
local discretionary_code = disccodes.discretionary
local explicit_code = disccodes.explicit
+ local automatic_code = disccodes.automatic
----- regular_code = disccodes.regular
- ----- automatic_code = disccodes.automatic
local nuts = nodes.nuts
local tonut = nodes.tonut
@@ -658,6 +658,9 @@ if context then
local a_hyphenation = attributes.private("hyphenation")
+ local expand_explicit = languages.expanders[explicit_code]
+ local expand_automatic = languages.expanders[automatic_code]
+
local interwordpenalty = 5000
function traditional.loadpatterns(language)
@@ -1281,20 +1284,15 @@ if context then
setcolor(glyph,"darkred") -- these get checked
setcolor(disc,"darkgreen") -- in the colorizer
end
- local pre = mil
+ local pre = nil
local post = nil
local replace = glyph
- if not leftchar then
- leftchar = code
- end
- if rightchar then
- pre = copy_node(glyph)
- setchar(pre,rightchar)
- end
- if leftchar then
+ if leftchar and leftchar > 0 then
post = copy_node(glyph)
setchar(post,leftchar)
end
+ pre = copy_node(glyph)
+ setchar(pre,rightchar and rightchar > 0 and rightchar or code)
setdisc(disc,pre,post,replace,discretionary_code,hyphenpenalty)
if attributes then
setfield(disc,"attr",attributes)
@@ -1425,16 +1423,12 @@ if context then
current = getnext(current)
elseif subtype == explicit_code then -- \- => only here
size = 0
+ expand_explicit(current)
+ current = getnext(current)
+ elseif subtype == automatic_code then -- - => only here
+ size = 0
+ expand_automatic(current)
current = getnext(current)
- while current do
- local id = getid(current)
- if id == glyph_code or id == disc_code then
- current = getnext(current)
- else
- break
- end
- end
- -- todo: change to discretionary_code
else
-- automatic (-) : the hyphenator turns an exhyphen into glyph+disc
-- first : done by the hyphenator
diff --git a/tex/context/base/mkiv/lang-ini.lua b/tex/context/base/mkiv/lang-ini.lua
index 00fdb3f09..0677cb003 100644
--- a/tex/context/base/mkiv/lang-ini.lua
+++ b/tex/context/base/mkiv/lang-ini.lua
@@ -259,7 +259,9 @@ function languages.associate(tag,script,language) -- not yet used
end
function languages.association(tag) -- not yet used
- if type(tag) == "number" then
+ if not tag then
+ tag = numbers[tex.language]
+ elseif type(tag) == "number" then
tag = numbers[tag]
end
local lat = tag and associated[tag]
diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua
index f1e8b33ed..c130f86ca 100644
--- a/tex/context/base/mkiv/node-fnt.lua
+++ b/tex/context/base/mkiv/node-fnt.lua
@@ -402,17 +402,19 @@ function handlers.characters(head)
-- skip
elseif u == 1 then
local font, processors = next(usedfonts)
+ local attr = a == 0 and false or 0 -- 0 is the savest way
for i=1,#processors do
- local h, d = processors[i](head,font,0)
+ local h, d = processors[i](head,font,attr)
if d then
head = h or head
done = true
end
end
else
+ local attr = a == 0 and false or 0 -- 0 is the savest way
for font, processors in next, usedfonts do
for i=1,#processors do
- local h, d = processors[i](head,font,0)
+ local h, d = processors[i](head,font,attr)
if d then
head = h or head
done = true
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 05b5087c8..e70a4a726 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 1d0b0b16e..e35880659 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/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 0e4fe395e..8fd39d51a 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-fonts.xml b/tex/context/interface/mkiv/i-fonts.xml
index 112b93c6e..1c62ba1ff 100644
--- a/tex/context/interface/mkiv/i-fonts.xml
+++ b/tex/context/interface/mkiv/i-fonts.xml
@@ -65,31 +65,31 @@
<cd:resolve name="argument-text"/>
</cd:arguments>
</cd:command>
-
+
<cd:command name="emphit" file="font-emp.mkvi">
<cd:arguments>
<cd:resolve name="argument-text"/>
</cd:arguments>
</cd:command>
-
+
<cd:command name="emphsl" file="font-emp.mkvi">
<cd:arguments>
<cd:resolve name="argument-text"/>
</cd:arguments>
</cd:command>
-
+
<cd:command name="emphtf" file="font-emp.mkvi">
<cd:arguments>
<cd:resolve name="argument-text"/>
</cd:arguments>
</cd:command>
-
+
<cd:command name="emph" file="font-emp.mkvi">
<cd:arguments>
<cd:resolve name="argument-text"/>
</cd:arguments>
</cd:command>
-
+
<cd:command name="emphasized" file="font-emp.mkvi">
<cd:arguments>
<cd:resolve name="argument-text"/>
@@ -798,39 +798,25 @@
</cd:arguments>
</cd:command>
- <cd:command name="setupbodyfont" file="font-ini.mkiv">
+ <cd:command name="setupfonts" file="font-ini.mkiv">
<cd:arguments>
- <cd:keywords list="yes" optional="yes">
+ <cd:parameters>
<cd:constant type="cd:dimension"/>
- <cd:constant type="cd:name"/>
- <cd:constant type="global"/>
- <cd:constant type="reset"/>
- <cd:constant type="x"/>
- <cd:constant type="xx"/>
- <cd:constant type="small"/>
- <cd:constant type="big"/>
- <cd:constant type="script"/>
- <cd:constant type="scriptscript"/>
- <cd:constant type="rm"/>
- <cd:constant type="ss"/>
- <cd:constant type="tt"/>
- <cd:constant type="hw"/>
- <cd:constant type="cg"/>
- <cd:constant type="roman"/>
- <cd:constant type="serif"/>
- <cd:constant type="regular"/>
- <cd:constant type="sans"/>
- <cd:constant type="sansserif"/>
- <cd:constant type="support"/>
- <cd:constant type="type"/>
- <cd:constant type="teletype"/>
- <cd:constant type="mono"/>
- <cd:constant type="handwritten"/>
- <cd:constant type="calligraphic"/>
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command name="setupbodyfont" file="font-ini.mkiv">
+ <cd:arguments>
+ <cd:assignments list="yes">
+ <cd:parameter name="language">
+ <cd:constant type="no" default="yes"/>
+ <cd:constant type="auto"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="switchtobodyfont" file="font-ini.mkvi">
<cd:arguments>
<cd:keywords list="yes">
@@ -1624,4 +1610,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index acb862767..2abc86db5 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 19fb2482c..ea4f6e8d6 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 : 06/02/16 21:28:16
+-- merge date : 06/05/16 16:26:23
do -- begin closure to overcome local limits and interference
@@ -2785,6 +2785,620 @@ end -- closure
do -- begin closure to overcome local limits and interference
+if not modules then modules={} end modules ['l-unicode']={
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
+}
+utf=utf or (unicode and unicode.utf8) or {}
+utf.characters=utf.characters or string.utfcharacters
+utf.values=utf.values or string.utfvalues
+local type=type
+local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
+local concat=table.concat
+local P,C,R,Cs,Ct,Cmt,Cc,Carg,Cp=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Ct,lpeg.Cmt,lpeg.Cc,lpeg.Carg,lpeg.Cp
+local lpegmatch=lpeg.match
+local patterns=lpeg.patterns
+local tabletopattern=lpeg.utfchartabletopattern
+local bytepairs=string.bytepairs
+local finder=lpeg.finder
+local replacer=lpeg.replacer
+local utfvalues=utf.values
+local utfgmatch=utf.gmatch
+local p_utftype=patterns.utftype
+local p_utfstricttype=patterns.utfstricttype
+local p_utfoffset=patterns.utfoffset
+local p_utf8char=patterns.utf8character
+local p_utf8byte=patterns.utf8byte
+local p_utfbom=patterns.utfbom
+local p_newline=patterns.newline
+local p_whitespace=patterns.whitespace
+if not unicode then
+ unicode={ utf=utf }
+end
+if not utf.char then
+ local floor,char=math.floor,string.char
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+floor(n/0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+floor(n/0x1000),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+floor(n/0x40000),
+ 0x80+(floor(n/0x1000)%0x40),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ else
+ return ""
+ end
+ end
+end
+if not utf.byte then
+ local utf8byte=patterns.utf8byte
+ function utf.byte(c)
+ return lpegmatch(utf8byte,c)
+ end
+end
+local utfchar,utfbyte=utf.char,utf.byte
+function utf.filetype(data)
+ return data and lpegmatch(p_utftype,data) or "unknown"
+end
+local toentities=Cs (
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
+)
+patterns.toentities=toentities
+function utf.toentities(str)
+ return lpegmatch(toentities,str)
+end
+local one=P(1)
+local two=C(1)*C(1)
+local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
+local pattern=P("\254\255")*Cs((
+ four/function(a,b,c,d)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(a,b)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )+P("\255\254")*Cs((
+ four/function(b,a,d,c)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(b,a)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )
+function string.toutf(s)
+ return lpegmatch(pattern,s) or s
+end
+local validatedutf=Cs (
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
+)
+patterns.validatedutf=validatedutf
+function utf.is_valid(str)
+ return type(str)=="string" and lpegmatch(validatedutf,str) or false
+end
+if not utf.len then
+ local n,f=0,1
+ local utfcharcounter=patterns.utfbom^-1*Cmt (
+ Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
+ function(_,t,d)
+ n=n+(t-f)/d
+ f=t
+ return true
+ end
+ )^0
+ function utf.len(str)
+ n,f=0,1
+ lpegmatch(utfcharcounter,str or "")
+ return n
+ end
+end
+utf.length=utf.len
+if not utf.sub then
+ local utflength=utf.length
+ local b,e,n,first,last=0,0,0,0,0
+ local function slide_zero(s,p)
+ n=n+1
+ if n>=last then
+ e=p-1
+ else
+ return p
+ end
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
+ end
+ if n>=last then
+ e=p-1
+ else
+ return p
+ end
+ end
+ local function slide_two(s,p)
+ n=n+1
+ if n==first then
+ b=p
+ else
+ return true
+ end
+ end
+ local pattern_zero=Cmt(p_utf8char,slide_zero)^0
+ local pattern_one=Cmt(p_utf8char,slide_one )^0
+ local pattern_two=Cmt(p_utf8char,slide_two )^0
+ local pattern_first=C(patterns.utf8character)
+ function utf.sub(str,start,stop)
+ if not start then
+ return str
+ end
+ if start==0 then
+ start=1
+ end
+ if not stop then
+ if start<0 then
+ local l=utflength(str)
+ start=l+start
+ else
+ start=start-1
+ end
+ b,n,first=0,0,start
+ lpegmatch(pattern_two,str)
+ if n>=first then
+ return sub(str,b)
+ else
+ return ""
+ end
+ end
+ if start<0 or stop<0 then
+ local l=utf.length(str)
+ if start<0 then
+ start=l+start
+ if start<=0 then
+ start=1
+ else
+ start=start+1
+ end
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
+ else
+ stop=stop+1
+ end
+ end
+ end
+ if start==1 and stop==1 then
+ return lpegmatch(pattern_first,str) or ""
+ elseif start>stop then
+ return ""
+ elseif start>1 then
+ b,e,n,first,last=0,0,0,start-1,stop
+ lpegmatch(pattern_one,str)
+ if n>=first and e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ else
+ b,e,n,last=1,0,0,stop
+ lpegmatch(pattern_zero,str)
+ if e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ end
+ end
+end
+function utf.remapper(mapping,option,action)
+ local variant=type(mapping)
+ if variant=="table" then
+ action=action or mapping
+ if option=="dynamic" then
+ local pattern=false
+ table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8char)^0)
+ end
+ return lpegmatch(pattern,str)
+ end
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8char)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8char)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8char/mapping+p_utf8char)^0)
+ else
+ local pattern=Cs((p_utf8char/mapping+p_utf8char)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
+ end
+ end,pattern
+ end
+ else
+ return function(str)
+ return str or ""
+ end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
+end
+function utf.subtituter(t)
+ local f=finder (t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ local i=lpegmatch(f,str)
+ if not i then
+ return str
+ elseif i>#str then
+ return str
+ else
+ return lpegmatch(r,str)
+ end
+ end
+end
+local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
+local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8char)^0)
+local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8char))^0)
+local utfcharsplitter_raw=Ct(C(p_utf8char)^0)
+patterns.utflinesplitter=utflinesplitter
+function utf.splitlines(str)
+ return lpegmatch(utflinesplitter,str or "")
+end
+function utf.split(str,ignorewhitespace)
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
+end
+function utf.totable(str)
+ return lpegmatch(utfcharsplitter_raw,str)
+end
+function utf.magic(f)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
+end
+local utf16_to_utf8_be,utf16_to_utf8_le
+local utf32_to_utf8_be,utf32_to_utf8_le
+local utf_16_be_getbom=patterns.utfbom_16_be^-1
+local utf_16_le_getbom=patterns.utfbom_16_le^-1
+local utf_32_be_getbom=patterns.utfbom_32_be^-1
+local utf_32_le_getbom=patterns.utfbom_32_le^-1
+local utf_16_be_linesplitter=utf_16_be_getbom*lpeg.tsplitat(patterns.utf_16_be_nl)
+local utf_16_le_linesplitter=utf_16_le_getbom*lpeg.tsplitat(patterns.utf_16_le_nl)
+local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_nl)
+local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
+local more=0
+local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
+end
+local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
+end
+local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
+end
+local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
+end
+p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
+p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
+p_utf32_to_utf8_be=P(true)/function() more=0 end*utf_32_be_getbom*Cs(p_utf32_to_utf8_be^0)
+p_utf32_to_utf8_le=P(true)/function() more=0 end*utf_32_le_getbom*Cs(p_utf32_to_utf8_le^0)
+patterns.utf16_to_utf8_be=p_utf16_to_utf8_be
+patterns.utf16_to_utf8_le=p_utf16_to_utf8_le
+patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
+patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
+utf16_to_utf8_be=function(s)
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
+end
+local utf16_to_utf8_be_t=function(t)
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_be,s)
+ end
+ end
+ return t
+end
+utf16_to_utf8_le=function(s)
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ end
+end
+local utf16_to_utf8_le_t=function(t)
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_le,s)
+ end
+ end
+ return t
+end
+utf32_to_utf8_be=function(s)
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
+end
+local utf32_to_utf8_be_t=function(t)
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_be,s)
+ end
+ end
+ return t
+end
+utf32_to_utf8_le=function(s)
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
+end
+local utf32_to_utf8_le_t=function(t)
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_le,s)
+ end
+ end
+ return t
+end
+utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
+utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
+utf.utf32_to_utf8_le_t=utf32_to_utf8_le_t
+utf.utf32_to_utf8_be_t=utf32_to_utf8_be_t
+utf.utf16_to_utf8_le=utf16_to_utf8_le
+utf.utf16_to_utf8_be=utf16_to_utf8_be
+utf.utf32_to_utf8_le=utf32_to_utf8_le
+utf.utf32_to_utf8_be=utf32_to_utf8_be
+function utf.utf8_to_utf8_t(t)
+ return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
+end
+function utf.utf16_to_utf8_t(t,endian)
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+end
+function utf.utf32_to_utf8_t(t,endian)
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+end
+local function little(b)
+ if b<0x10000 then
+ return char(b%256,b/256)
+ else
+ b=b-0x10000
+ local b1,b2=b/1024+0xD800,b%1024+0xDC00
+ return char(b1%256,b1/256,b2%256,b2/256)
+ end
+end
+local function big(b)
+ if b<0x10000 then
+ return char(b/256,b%256)
+ else
+ b=b-0x10000
+ local b1,b2=b/1024+0xD800,b%1024+0xDC00
+ return char(b1/256,b1%256,b2/256,b2%256)
+ end
+end
+local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
+local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
+local function utf8_to_utf16_be(str,nobom)
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
+end
+local function utf8_to_utf16_le(str,nobom)
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
+end
+utf.utf8_to_utf16_be=utf8_to_utf16_be
+utf.utf8_to_utf16_le=utf8_to_utf16_le
+function utf.utf8_to_utf16(str,littleendian,nobom)
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
+end
+local pattern=Cs (
+ (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+)
+function utf.tocodes(str,separator)
+ return lpegmatch(pattern,str,1,separator or " ")
+end
+function utf.ustring(s)
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+end
+function utf.xstring(s)
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+end
+function utf.toeight(str)
+ if not str or str=="" then
+ return nil
+ end
+ local utftype=lpegmatch(p_utfstricttype,str)
+ if utftype=="utf-8" then
+ return sub(str,4)
+ elseif utftype=="utf-16-be" then
+ return utf16_to_utf8_be(str)
+ elseif utftype=="utf-16-le" then
+ return utf16_to_utf8_le(str)
+ else
+ return str
+ end
+end
+local p_nany=p_utf8char/""
+if utfgmatch then
+ function utf.count(str,what)
+ if type(what)=="string" then
+ local n=0
+ for _ in utfgmatch(str,what) do
+ n=n+1
+ end
+ return n
+ else
+ return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
+ end
+ end
+else
+ local cache={}
+ function utf.count(str,what)
+ if type(what)=="string" then
+ local p=cache[what]
+ if not p then
+ p=Cs((P(what)/" "+p_nany)^0)
+ cache[p]=p
+ end
+ return #lpegmatch(p,str)
+ else
+ return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
+ end
+ end
+end
+if not utf.characters then
+ function utf.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
+ string.utfcharacters=utf.characters
+end
+if not utf.values then
+ local find=string.find
+ local dummy=function()
+ end
+ function utf.values(str)
+ local n=#str
+ if n==0 then
+ return dummy
+ elseif n==1 then
+ return function() return utfbyte(str) end
+ else
+ local p=1
+ return function()
+ local b,e=find(str,".[\128-\191]*",p)
+ if b then
+ p=e+1
+ return utfbyte(sub(str,b,e))
+ end
+ end
+ end
+ end
+ string.utfvalues=utf.values
+end
+function utf.chrlen(u)
+ return
+ (u<0x80 and 1) or
+ (u<0xE0 and 2) or
+ (u<0xF0 and 3) or
+ (u<0xF8 and 4) or
+ (u<0xFC and 5) or
+ (u<0xFE and 6) or 0
+end
+
+end -- closure
+
+do -- begin closure to overcome local limits and interference
+
if not modules then modules={} end modules ['util-str']={
version=1.001,
comment="companion to luat-lib.mkiv",
@@ -5890,15 +6504,11 @@ hashmethods.normal=function(list)
elseif k=="number" or k=="features" then
else
n=n+1
- s[n]=k
+ s[n]=k..'='..tostring(v)
end
end
if n>0 then
sort(s)
- for i=1,n do
- local k=s[i]
- s[i]=k..'='..tostring(list[k])
- end
return concat(s,"+")
end
end
@@ -14532,7 +15142,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_de
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.021
+otf.version=3.022
otf.cache=containers.define("fonts","otl",otf.version,true)
local otfreaders=otf.readers
local hashes=fonts.hashes
@@ -17258,7 +17868,6 @@ local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursiv
local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end)
local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end)
local trace_details=false registertracker("otf.details",function(v) trace_details=v end)
-local trace_applied=false registertracker("otf.applied",function(v) trace_applied=v end)
local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end)
local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end)
local trace_directions=false registertracker("otf.directions",function(v) trace_directions=v end)
@@ -19960,9 +20569,6 @@ local function featuresprocessor(head,font,attr)
nesting=nesting-1
return head,false
end
- if attr==0 then
- attr=false
- end
head=tonut(head)
if trace_steps then
checkstep(head)
diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua
index c493844c8..07d9343a7 100644
--- a/tex/generic/context/luatex/luatex-fonts.lua
+++ b/tex/generic/context/luatex/luatex-fonts.lua
@@ -186,6 +186,7 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
loadmodule("l-file.lua")
loadmodule("l-boolean.lua")
loadmodule("l-math.lua")
+ loadmodule("l-unicode.lua")
-- A few slightly higher level support modules:
diff --git a/tex/generic/context/luatex/luatex-math.tex b/tex/generic/context/luatex/luatex-math.tex
index 604b4a1f8..b24902100 100644
--- a/tex/generic/context/luatex/luatex-math.tex
+++ b/tex/generic/context/luatex/luatex-math.tex
@@ -40,9 +40,9 @@
\font\tenbf = file:lmroman10-bold.otf:+liga;+kern;+tlig;+trep at 10pt
\font\tenbi = file:lmroman10-bolditalic.otf:+liga;+kern;+tlig;+trep at 10pt
%
- \font\mathfonttextupright = file:latinmodern-math.otf:ssty=0;fixmath=yes at 10pt
- \font\mathfontscriptupright = file:latinmodern-math.otf:ssty=1;fixmath=yes at 7pt
- \font\mathfontscriptscriptupright = file:latinmodern-math.otf:ssty=2;fixmath=yes at 5pt
+ \font\mathfonttextupright = file:latinmodern-math.otf:script=math;ssty=0;mathsize=yes at 10pt
+ \font\mathfontscriptupright = file:latinmodern-math.otf:script=math;ssty=1;mathsize=yes at 7pt
+ \font\mathfontscriptscriptupright = file:latinmodern-math.otf:script=math;ssty=2;mathsize=yes at 5pt
%
\textfont 0 = \mathfonttextupright
\scriptfont 0 = \mathfontscriptupright
@@ -61,9 +61,9 @@
\font\tenbf = file:lucidabrightot-demi.otf:+liga;+kern;+tlig;+trep at 10pt
\font\tenbi = file:lucidabrightot-demiitalic.otf:+liga;+kern;+tlig;+trep at 10pt
%
- \font\mathfonttextupright = file:lucidabrightmathot.otf:ssty=0;fixmath=yes at 10pt
- \font\mathfontscriptupright = file:lucidabrightmathot.otf:ssty=1;fixmath=yes at 7pt
- \font\mathfontscriptscriptupright = file:lucidabrightmathot.otf:ssty=2;fixmath=yes at 5pt
+ \font\mathfonttextupright = file:lucidabrightmathot.otf:script=math;ssty=0;mathsize=yes at 10pt
+ \font\mathfontscriptupright = file:lucidabrightmathot.otf:script=math;ssty=1;mathsize=yes at 7pt
+ \font\mathfontscriptscriptupright = file:lucidabrightmathot.otf:script=math;ssty=2;mathsize=yes at 5pt
%
\textfont 0 = \mathfonttextupright
\scriptfont 0 = \mathfontscriptupright