From 08a4681010e0cb1e092218b0308f301a8f008231 Mon Sep 17 00:00:00 2001 From: Marius Date: Fri, 15 Mar 2013 00:20:15 +0200 Subject: beta 2013.03.14 23:02 --- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4145 -> 4133 bytes tex/context/base/context-version.png | Bin 40458 -> 39995 bytes tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/font-con.lua | 6 +- tex/context/base/font-ctx.lua | 224 ++++++++++++++------- tex/context/base/font-fea.mkvi | 40 ++-- tex/context/base/lang-def.lua | 45 ++++- tex/context/base/lang-ini.mkiv | 23 ++- tex/context/base/status-files.pdf | Bin 24809 -> 24773 bytes tex/context/base/status-lua.pdf | Bin 210044 -> 210153 bytes tex/generic/context/luatex/luatex-fonts-merged.lua | 6 +- 14 files changed, 233 insertions(+), 119 deletions(-) (limited to 'tex') diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index f9f4ae112..3c10a596a 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.14 17:31} +\newcontextversion{2013.03.14 23:02} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 7b5d767a0..be2b5e2c5 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2013.03.14 17:31} +\newcontextversion{2013.03.14 23:02} %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/context-version.pdf b/tex/context/base/context-version.pdf index c7c0da748..b99817f88 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png index 4c2103f5f..4890e14d2 100644 Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index 2585d5711..07119341d 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.14 17:31} +\edef\contextversion{2013.03.14 23:02} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index d893a457b..4caf863ce 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2013.03.14 17:31} +\edef\contextversion{2013.03.14 23:02} %D For those who want to use this: diff --git a/tex/context/base/font-con.lua b/tex/context/base/font-con.lua index 912935c9c..fc687ea58 100644 --- a/tex/context/base/font-con.lua +++ b/tex/context/base/font-con.lua @@ -966,7 +966,11 @@ hashmethods.normal = function(list) local s = { } local n = 0 for k, v in next, list do - if k ~= "number" and k ~= "features" then -- I need to figure this out, features + 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 diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 39fee86f1..bf39ca025 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -35,6 +35,7 @@ local trace_mapfiles = false trackers.register("fonts.mapfiles", functio local trace_automode = false trackers.register("fonts.automode", function(v) trace_automode = v end) local report_features = logs.reporter("fonts","features") +local report_cummulative = logs.reporter("fonts","cummulative") local report_defining = logs.reporter("fonts","defining") local report_status = logs.reporter("fonts","status") local report_mapfiles = logs.reporter("fonts","mapfiles") @@ -82,6 +83,16 @@ storage.register("fonts/numbers", numbers, "fonts.specifiers.contextnumbers") storage.register("fonts/merged", merged, "fonts.specifiers.contextmerged") storage.register("fonts/synonyms", synonyms, "fonts.specifiers.synonyms") +utilities.strings.formatters.add(string.formatters, + "font:name", + [["'"..file.basename(%s.properties.name).."'"]] +) + +utilities.strings.formatters.add(string.formatters, + "font:features", + [["'"..table.sequenced(%s," ",true).."'"]] +) + constructors.resolvevirtualtoo = true -- context specific (due to resolver) local allocate, mark = utilities.storage.allocate, utilities.storage.mark @@ -304,7 +315,8 @@ local function checkedscript(tfmdata,resources,features) script = latn and "latn" or "dflt" end if trace_automode then - report_defining("auto script mode, using script %a in font %a",script,file.basename(tfmdata.properties.name)) +-- report_defining("auto script mode, using script %a in font %a",script,file.basename(tfmdata.properties.name)) + report_defining("auto script mode, using script %a in font %!font:name!",script,tfmdata) end features.script = script return script @@ -329,15 +341,19 @@ local function checkedmode(tfmdata,resources,features) if found then -- more than one lookup if trace_automode then - report_defining("forcing mode %a, font %a, feature %a, script %a, language %a, %s", - "node",file.basename(tfmdata.properties.name),feature,script,language,"multiple lookups") +-- report_defining("forcing mode %a, font %a, feature %a, script %a, language %a, %s", +-- "node",file.basename(tfmdata.properties.name),feature,script,language,"multiple lookups") + report_defining("forcing mode %a, font %!font:name!, feature %a, script %a, language %a, %s", + "node",tfmdata,feature,script,language,"multiple lookups") end features.mode = "node" return "node" elseif needsnodemode[sequence.type] then if trace_automode then - report_defining("forcing mode %a, font %a, feature %a, script %a, language %a, %s", - "node",file.basename(tfmdata.properties.name),feature,script,language,"no base support") +-- report_defining("forcing mode %a, font %a, feature %a, script %a, language %a, %s", +-- "node",file.basename(tfmdata.properties.name),feature,script,language,"no base support") + report_defining("forcing mode %a, font %!font:name!, feature %a, script %a, language %a, %s", + "node",tfmdata,feature,script,language,"no base support") end features.mode = "node" return "node" @@ -361,7 +377,8 @@ definers.checkedmode = checkedmode local function modechecker(tfmdata,features,mode) -- we cannot adapt features as they are shared! if trace_features then - report_features(serialize(features,"used")) +-- report_features("fontname %a, features % a",file.basename(tfmdata.properties.name),features) + report_features("fontname %!font:name!, features %!font:features!",tfmdata,features) end local rawdata = tfmdata.shared.rawdata local resources = rawdata and rawdata.resources @@ -374,7 +391,8 @@ local function modechecker(tfmdata,features,mode) -- we cannot adapt features as mode = checkedmode(tfmdata,resources,features) end else - report_features("missing resources for font %a",file.basename(tfmdata.properties.name)) +-- report_features("missing resources for font %a",file.basename(tfmdata.properties.name)) + report_features("missing resources for font %!font:name!",tfmdata) end return mode end @@ -487,6 +505,17 @@ definers.registersplit("@", predefined,"virtual") local normalize_features = otffeatures.normalize -- should be general +local function definecontext(name,t) -- can be shared + local number = setups[name] and setups[name].number or 0 -- hm, numbers[name] + if number == 0 then + number = #numbers + 1 + numbers[number] = name + end + t.number = number + setups[name] = t + return number, t +end + local function presetcontext(name,parent,features) -- will go to con and shared if features == "" and find(parent,"=") then features = parent @@ -515,12 +544,14 @@ local function presetcontext(name,parent,features) -- will go to con and shared -- these are auto set so in order to prevent redundant definitions -- we need to preset them (we hash the features and adding a default -- setting during initialization may result in a different hash) ---~ for k,v in next, triggers do ---~ if features[v] == nil then -- not false ! ---~ local vv = default_features[v] ---~ if vv then features[v] = vv end ---~ end ---~ end + -- + -- for k,v in next, triggers do + -- if features[v] == nil then -- not false ! + -- local vv = default_features[v] + -- if vv then features[v] = vv end + -- end + -- end + -- for feature,value in next, features do if value == nil then -- not false ! local default = default_features[feature] @@ -533,11 +564,12 @@ local function presetcontext(name,parent,features) -- will go to con and shared -- optimization) local t = { } -- can we avoid t ? for k,v in next, features do - if v then t[k] = v end +-- if v then t[k] = v end + t[k] = v end -- needed for dynamic features -- maybe number should always be renewed as we can redefine features - local number = (setups[name] and setups[name].number) or 0 -- hm, numbers[name] + local number = setups[name] and setups[name].number or 0 -- hm, numbers[name] if number == 0 then number = #numbers + 1 numbers[number] = name @@ -578,10 +610,10 @@ local function contextnumber(name) -- will be replaced end end -local function mergecontext(currentnumber,extraname,option) - local current = setups[numbers[currentnumber]] +local function mergecontext(currentnumber,extraname,option) -- number string number local extra = setups[extraname] if extra then + local current = setups[numbers[currentnumber]] local mergedfeatures, mergedname = { }, nil if option < 0 then if current then @@ -608,13 +640,37 @@ local function mergecontext(currentnumber,extraname,option) numbers[number] = mergedname merged[number] = option setups[mergedname] = mergedfeatures --- inspect(mergedfeatures) return number -- contextnumber(mergedname) else return currentnumber end end +local function mergecontextfeatures(currentname,extraname) -- string string + local extra = setups[extraname] + if extra then + local current = setups[currentname] + local mergedfeatures, mergedname = { }, nil + if current then + for k, v in next, current do + mergedfeatures[k] = v + end + end + for k, v in next, extra do + mergedfeatures[k] = v + end + mergedname = currentname .. "+" .. extraname + local number = #numbers + 1 + mergedfeatures.number = number + numbers[number] = mergedname + merged[number] = option + setups[mergedname] = mergedfeatures + return number + else + return numbers[currentname] or 0 + end +end + local function registercontext(fontnumber,extraname,option) local extra = setups[extraname] if extra then @@ -642,6 +698,7 @@ specifiers.presetcontext = presetcontext specifiers.contextnumber = contextnumber specifiers.mergecontext = mergecontext specifiers.registercontext = registercontext +specifiers.definecontext = definecontext -- we extend the hasher: @@ -650,7 +707,7 @@ constructors.hashmethods.virtual = function(list) local n = 0 for k, v in next, list do n = n + 1 - s[n] = k + s[n] = k -- no checking on k end if n > 0 then sort(s) @@ -701,46 +758,46 @@ local function splitcontext(features) -- presetcontext creates dummy here return fastcopy(setups[features] or (presetcontext(features,"","") and setups[features])) end ---~ local splitter = lpeg.splitat("=") - ---~ local function splitcontext(features) ---~ local setup = setups[features] ---~ if setup then ---~ return setup ---~ elseif find(features,",") then ---~ -- This is not that efficient but handy anyway for quick and dirty tests ---~ -- beware, due to the way of caching setups you can get the wrong results ---~ -- when components change. A safeguard is to nil the cache. ---~ local merge = nil ---~ for feature in gmatch(features,"[^, ]+") do ---~ if find(feature,"=") then ---~ local k, v = lpegmatch(splitter,feature) ---~ if k and v then ---~ if not merge then ---~ merge = { k = v } ---~ else ---~ merge[k] = v ---~ end ---~ end ---~ else ---~ local s = setups[feature] ---~ if not s then ---~ -- skip ---~ elseif not merge then ---~ merge = s ---~ else ---~ for k, v in next, s do ---~ merge[k] = v ---~ end ---~ end ---~ end ---~ end ---~ setup = merge and presetcontext(features,"",merge) and setups[features] ---~ -- actually we have to nil setups[features] in order to permit redefinitions ---~ setups[features] = nil ---~ end ---~ return setup or (presetcontext(features,"","") and setups[features]) -- creates dummy ---~ end +-- local splitter = lpeg.splitat("=") +-- +-- local function splitcontext(features) +-- local setup = setups[features] +-- if setup then +-- return setup +-- elseif find(features,",") then +-- -- This is not that efficient but handy anyway for quick and dirty tests +-- -- beware, due to the way of caching setups you can get the wrong results +-- -- when components change. A safeguard is to nil the cache. +-- local merge = nil +-- for feature in gmatch(features,"[^, ]+") do +-- if find(feature,"=") then +-- local k, v = lpegmatch(splitter,feature) +-- if k and v then +-- if not merge then +-- merge = { k = v } +-- else +-- merge[k] = v +-- end +-- end +-- else +-- local s = setups[feature] +-- if not s then +-- -- skip +-- elseif not merge then +-- merge = s +-- else +-- for k, v in next, s do +-- merge[k] = v +-- end +-- end +-- end +-- end +-- setup = merge and presetcontext(features,"",merge) and setups[features] +-- -- actually we have to nil setups[features] in order to permit redefinitions +-- setups[features] = nil +-- end +-- return setup or (presetcontext(features,"","") and setups[features]) -- creates dummy +-- end specifiers.splitcontext = splitcontext @@ -1210,10 +1267,6 @@ mappings.reset() -- resets the default file local function nametoslot(name) local t = type(name) if t == "string" then --- local tfmdata = fontdata[currentfont()] --- local shared = tfmdata and tfmdata.shared --- local fntdata = shared and shared.rawdata --- return fntdata and fntdata.resources.unicodes[name] -- could also be in hashes return resources[true].unicodes[name] elseif t == "number" then return n @@ -1609,25 +1662,25 @@ end commands.definefontfeature = presetcontext -local namecache = { } - -function commands.feature(name,parent,font) +function commands.feature(parent,name,font) local font = font or currentfont() - local hash = font .. "*" .. name .. "*" .. 2 -- what + local full = parent .. "+" .. name + local hash = font .. "*" .. full .. "*" .. 2 -- what local done = withcache[hash] - if not done then - if namecache[name] then + if done then + else + local n = setups[full] + if n then else - presetcontext(name,parent) - namecache[name] = true + n = mergecontextfeatures(parent,name) -- registers parent .. "+" .. name end + done = registercontext(font,full,2) -- what + withcache[hash] = done if trace_features then - report_features("cummulative %a, font %a, number %a, set % a",name,font,n,f) + report_cummulative("font %!font:name!, number %a, set %a : %!font:features!", + fontdata[font],done,full,setups[numbers[done]]) end - done = registercontext(font,name,2) -- what - withcache[hash] = done end --- context(done) texattribute[0] = done end @@ -1635,6 +1688,27 @@ function commands.featurelist(...) context(fonts.specifiers.contexttostring(...)) end +function commands.registerlanguagefeatures() + local specifications = languages.data.specifications + for i=1,#specifications do + local specification = specifications[i] + local language = specification.opentype + if language then + local script = specification.opentypescript or specification.script + if script then + local context = specification.context + if type(context) == "table" then + for i=1,#context do + definecontext(context[i], { language = language, script = script}) + end + elseif type(context) == "string" then + definecontext(context, { language = language, script = script}) + end + end + end + end +end + -- a fontkern plug: local copy_node = node.copy diff --git a/tex/context/base/font-fea.mkvi b/tex/context/base/font-fea.mkvi index 208b1b8db..7b3319392 100644 --- a/tex/context/base/font-fea.mkvi +++ b/tex/context/base/font-fea.mkvi @@ -168,33 +168,19 @@ % beware: these are global features on top of existing font features -\let\currentfeature\s!current +\let\currentfeature \s!current +\let\m_font_feature_list\s!current -% \installcorenamespace{fontfeature} -% -% \setvalue{\??fontfeature\currentfeature}{} -% -% \unexpanded\def\feature#1% -% {\ifcsname\??fontfeature\fontid\font+\currentfeature+#1\endcsname \else -% \font_feature{#1}% -% \fi -% \attribute\zerocount\csname\??fontfeature\fontid\font+\currentfeature+#1\endcsname\relax -% \edef\currentfeature{\currentfeature+#1}} -% -% \unexpanded\def\font_feature#1% -% {\expandafter\xdef\csname\??fontfeature\fontid\font+\currentfeature+#1\endcsname{\ctxcommand{feature("\currentfeature+#1","#1",\number\fontid\font)}}} -% -% faster: -% -% \unexpanded\def\feature#1% -% {\attribute\zerocount\ctxcommand{feature("\currentfeature+#1","#1")}\relax -% \edef\currentfeature{\currentfeature+#1}} -% -% similar, less code: +\unexpanded\def\feature#1% hashing at this end is slower + {\edef\m_font_feature_asked{#1}% + \ifx\m_font_feature_asked\currentfeature \else + \font_feature_accumulate + \fi} -\unexpanded\def\feature#1% - {\ctxcommand{feature("\currentfeature+#1","#1")}% - \edef\currentfeature{\currentfeature+#1}} +\def\font_feature_accumulate + {\ctxcommand{feature("\m_font_feature_list","\m_font_feature_asked")}% + \edef\m_font_feature_list{\m_font_feature_list+\m_font_feature_asked}% also + at the lua end + \let\currentfeature\m_font_feature_asked} %D \macros %D {os} @@ -216,4 +202,8 @@ \def\doifelsecurrentfonthasfeature#feature% {\ctxcommand{doifelsecurrentfonthasfeature("#feature")}} +% new: + +\ctxcommand{registerlanguagefeatures()} + \protect \endinput diff --git a/tex/context/base/lang-def.lua b/tex/context/base/lang-def.lua index c6bbcf3ae..6656d8ed9 100644 --- a/tex/context/base/lang-def.lua +++ b/tex/context/base/lang-def.lua @@ -362,7 +362,7 @@ local specifications = allocate { { ["description"] = "Chinese, simplified", ["script"] = "hans", - ["opentype-script"] = "hani", + ["opentypescript"] = "hani", ["bibliographical"] = "chi", ["terminological"] = "zho", ["context"] = "cn", @@ -373,10 +373,12 @@ local specifications = allocate { data.specifications = specifications -local variants = { } data.variants = variants -local opentypes = { } data.opentypes = opentypes -local contexts = { } data.contexts = contexts -local records = { } data.records = records +local variants = { } data.variants = variants +local contexts = { } data.contexts = contexts +local records = { } data.records = records +local scripts = { } data.scripts = scripts +local opentypes = { } data.opentypes = opentypes +local opentypescripts = { } data.opentypescripts = opentypescripts for k=1,#specifications do local specification = specifications[k] @@ -388,6 +390,14 @@ for k=1,#specifications do if opentype then opentypes[lower(opentype)] = specification end + local script = specification.script + if script then + scripts[lower(script)] = specification + end + local opentypescript = specification.opentypescript + if opentypescript then + opentypescripts[lower(opentypescript)] = specification + end local context = context if context then if type(context) == "table" then @@ -402,31 +412,46 @@ end local defaultvariant = variants["en-us"] +local function get(k,key) + local v = rawget(variants,k) or rawget(opentypes,k) or rawget(contexts,k) + return v and v[key] +end + setmetatableindex(variants, function(t,k) k = lower(k) - local v = (rawget(variants,k) or rawget(opentypes,k) or rawget(contexts,k) or defaultvariant).language + local v = get(k,"language") or defaultvariant.language t[k] = v return v end) setmetatableindex(opentypes, function(t,k) k = lower(k) - local v = (rawget(variants,k) or rawget(opentypes,k) or rawget(contexts,k) or defaultvariant).opentype + local v = get(k,"opentype") or "dflt" + t[k] = v + return v +end) + +setmetatableindex(opentypescripts, function(t,k) + k = lower(k) + local v = get(k,"opentypescript") or get(k,"script") or defaultvariant.opentypescript or defaultvariant.script t[k] = v return v end) setmetatableindex(contexts, function(t,k) k = lower(str) - local v = (rawget(variants,k) or rawget(opentypes,k) or rawget(contexts,k) or defaultvariant).context - v = (type(v) == "table" and v[1]) or v + local v = get(k,"context") or defaultvariant.context + v = type(v) == "table" and v[1] or v t[k] = v return v end) setmetatableindex(records, function(t,k) -- how useful is this one? k = lower(k) - local v = rawget(variants,k) or rawget(opentypes,k) or rawget(contexts,k) or defaultvariant + local v = get(k) or defaultvariant t[k] = v return v end) + +-- print(opentypes.nl,opentypescripts.nl) +-- print(opentypes.de,opentypescripts.de) diff --git a/tex/context/base/lang-ini.mkiv b/tex/context/base/lang-ini.mkiv index 3bd7072e6..c6e9af394 100644 --- a/tex/context/base/lang-ini.mkiv +++ b/tex/context/base/lang-ini.mkiv @@ -215,7 +215,7 @@ \unexpanded\def\doifpatternselse#1% {\begingroup % will change - \language[#1]% + \lang_basics_set_current[#1]% \ifnum\normallanguage>\zerocount \endgroup\expandafter\firstoftwoarguments \else @@ -286,7 +286,8 @@ \c!rightspeech=\languageparameter\c!rightquotation, \c!limittext=\unknown, \c!date={\v!year,\ ,\v!month,\ ,\v!day}, - \c!text=Ag] + \c!text=Ag, + \s!font=] % \v!auto : experimental ! % to be tested: % @@ -421,6 +422,24 @@ % \dorecurse{100}{dit is toch wel een heel\normalhyphendiscretionary lang\normalhyphendiscretionary woord \recurselevel\ } % \dorecurse{100}{dit is toch wel een heellangwoord \recurselevel\ } +% new experimental feature + +\unexpanded\def\setuplanguages + {\setuplanguage[\s!default]} + +% \setuplanguages[\s!font=\v!auto] +% \setuplanguage[\s!default][\s!font=\v!auto] +% \setuplanguage[nl][\s!font=\v!auto] + +\ifdefined\feature \else \let\feature\gobbleoneargument \fi + +\appendtoks + \edef\p_language_font{\languageparameter\s!font}% + \ifx\p_language_font\v!auto + \feature\currentlanguage + \fi +\to \everylanguage + % The following may be a solution for the fact that one cannot % change catcodes of characters like : and ; inside an environment. diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 49b5f9c23..3914e74be 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 604bbe77c..8c8020263 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 969d564f4..dd5587d62 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 : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 03/14/13 17:31:10 +-- merge date : 03/14/13 23:02:19 do -- begin closure to overcome local limits and interference @@ -4220,7 +4220,9 @@ hashmethods.normal=function(list) local s={} local n=0 for k,v in next,list do - if k~="number" and k~="features" then + if not k then + elseif k=="number" or k=="features" then + else n=n+1 s[n]=k end -- cgit v1.2.3