diff options
Diffstat (limited to 'tex')
25 files changed, 1005 insertions, 298 deletions
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex 50c1120d2..2fb1cdae6 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf 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 Binary files differindex 05b5087c8..e70a4a726 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 1d0b0b16e..e35880659 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 0e4fe395e..8fd39d51a 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf 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 Binary files differindex acb862767..2abc86db5 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf 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 |