diff options
Diffstat (limited to 'tex/context/base')
29 files changed, 1018 insertions, 151 deletions
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index 012a9c552..4798e31bc 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2009.10.16 16:13} +\newcontextversion{2009.10.18 15:20} %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/context.mkiv b/tex/context/base/context.mkiv index bd2bbe504..1a060d04f 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -241,6 +241,7 @@ \loadmarkfile{font-tra} \loadmarkfile{font-uni} \loadmarkfile{font-col} +\loadmarkfile{font-gds} \loadmarkfile{typo-spa} \loadmarkfile{typo-krn} diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 3f87e7a12..da8ad455b 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2009.10.16 16:13} +\edef\contextversion{2009.10.18 15:20} %D For those who want to use this: diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index de1422454..f3b7879fb 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['font-ctx'] = { local texsprint, count = tex.sprint, tex.count local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower -local tostring, next = tostring, next +local tostring, next, type = tostring, next, type local ctxcatcodes = tex.ctxcatcodes @@ -68,22 +68,25 @@ local settings_to_hash = aux.settings_to_hash local default_features = fonts.otf.features.default local function preset_context(name,parent,features) -- currently otf only + if features == "" and find(parent,"=") then + features = parent + parent = "" + end if features == "" then - if find(parent,"=") then - features = parent - parent = "" - end + features = { } + elseif type(features) == "string" then + features = normalize_meanings(settings_to_hash(features)) + else + features = normalize_meanings(features) end - local number = (setups[name] and setups[name].number) or 0 - local t = (features == "" and { }) or normalize_meanings(settings_to_hash(features)) -- todo: synonyms, and not otf bound if parent ~= "" then for p in gmatch(parent,"[^, ]+") do local s = setups[p] if s then for k,v in next, s do - if t[k] == nil then - t[k] = v + if features[k] == nil then + features[k] = v end end end @@ -93,25 +96,26 @@ local function preset_context(name,parent,features) -- currently otf only -- 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 type(t[v]) == "nil" then + if features[v] == nil then -- not false ! local vv = default_features[v] - if vv then t[v] = vv end + if vv then features[v] = vv end end end -- sparse 'm so that we get a better hash and less test (experimental -- optimization) - local tt = { } -- maybe avoid tt - for k,v in next, t do - if v then tt[k] = v end + local t = { } -- can we avoid t ? + for k,v in next, features do + if v then t[k] = v end end -- needed for dynamic features + local number = (setups[name] and setups[name].number) or 0 if number == 0 then number = #numbers + 1 numbers[number] = name end - tt.number = number - setups[name] = tt - return number + t.number = number + setups[name] = t + return number, t end local function context_number(name) -- will be replaced diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua index 9c9a67178..bc09d0f2e 100644 --- a/tex/context/base/font-def.lua +++ b/tex/context/base/font-def.lua @@ -9,7 +9,8 @@ if not modules then modules = { } end modules ['font-def'] = { local format, concat, gmatch, match, find, lower = string.format, table.concat, string.gmatch, string.match, string.find, string.lower local tostring, next = tostring, next -local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) +local trace_defining = false trackers .register("fonts.defining", function(v) trace_defining = v end) +local directive_embedall = false directives.register("fonts.embedall", function(v) directive_embedall = v end) trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading", "tfm.loading") trackers.register("fonts.all", "fonts.*", "otf.*", "afm.*", "tfm.*") @@ -283,7 +284,9 @@ function tfm.read(specification) end end if tfmtable then - if tfmtable.filename and fonts.dontembed[tfmtable.filename] then + if directive_embedall then + tfmtable.embedding = "full" + elseif tfmtable.filename and fonts.dontembed[tfmtable.filename] then tfmtable.embedding = "no" else tfmtable.embedding = "subset" diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua new file mode 100644 index 000000000..95623df1c --- /dev/null +++ b/tex/context/base/font-gds.lua @@ -0,0 +1,349 @@ +if not modules then modules = { } end modules ['font-gds'] = { + version = 1.000, + comment = "companion to font-gds.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local flattened= table.flattened +local type, next = type, next +local gmatch = string.gmatch + +-- goodies=name,colorscheme=,featureset= + +-- goodies + +fonts.goodies = fonts.goodies or { } +fonts.goodies.data = fonts.goodies.data or { } +fonts.goodies.list = fonts.goodies.list or { } + +local data = fonts.goodies.data +local list = fonts.goodies.list + +local function getgoodies(filename) -- maybe a merge is better + local goodies = data[filename] + if goodies ~= nil then + -- found or tagged unfound + elseif type(filename) == "string" then + local fullname = resolvers.find_file(file.addsuffix(filename,"lfg")) or "" -- prefered suffix + if fullname == "" then + fullname = resolvers.find_file(file.addsuffix(filename,"lua")) or "" -- fallback suffix + end + if fullname == "" then + logs.report("fonts", "goodie file '%s.lfg' is not found",filename) + data[filename] = false -- signal for not found + else + goodies = dofile(fullname) or false + data[filename] = goodies + end + end + return goodies +end + +function fonts.goodies.register(name,fnc) + list[name] = fnc +end + +fonts.goodies.get = getgoodies + +-- register goodies file + +local preset_context = fonts.define.specify.preset_context + +function fonts.initializers.common.goodies(tfmdata,value) + local goodies = { } + for filename in gmatch(value,"[^, ]+") do + local ok = getgoodies(filename) + if ok then + goodies[#goodies+1] = ok + if not ok.initialized then + for name, fnc in next, list do + fnc(ok,tfmdata) + end + ok.initialized = true + end + end + end + tfmdata.goodies = goodies -- shared ? +end + +-- featuresets + +local function initialize(goodies,tfmdata) + local featuresets = goodies.featuresets + local goodiesname = goodies.name + if featuresets then + for name,set in next, featuresets do + local ff = flattened(set) + local n, s = preset_context(goodiesname .. "::" .. name,"",ff) + featuresets[name] = s -- set + end + end +end + +fonts.goodies.register("featureset",initialize) + +function fonts.initializers.common.featureset(tfmdata,set) + local goodies = tfmdata.goodies -- shared ? + if goodies then + local features = tfmdata.shared.features + local what + for i=1,#goodies do + -- last one counts + local g = goodies[i] + what = (g.featuresets and g.featuresets[set]) or what + end + if what then + for feature, value in next, what do + if features[feature] == nil then + features[feature] = value + end + end + tfmdata.mode = features.mode or tfmdata.mode + end + end +end + +-- colorschemes + +fonts.goodies.colorschemes = fonts.goodies.colorschemes or { } +fonts.goodies.colorschemes.data = fonts.goodies.colorschemes.data or { } + +local colorschemes = fonts.goodies.colorschemes + +function fonts.initializers.common.colorscheme(tfmdata,scheme) + if type(scheme) == "string" then + local goodies = tfmdata.goodies + -- todo : check for already defined in shared + if goodies then + local what + for i=1,#goodies do + -- last one counts + local g = goodies[i] + what = (g.colorschemes and g.colorschemes[scheme]) or what + end + if what then + -- this is font bound but we can share them if needed + -- just as we could hash the conversions (per font) + local hash, reverse = tfmdata.luatex.unicodes, { } + for i=1,#what do + local w = what[i] + for j=1,#w do + local name = w[j] + local unicode = hash[name] + if unicode then + reverse[unicode] = i + end + end + end + tfmdata.colorscheme = reverse + return + end + end + end + tfmdata.colorscheme = false +end + +local fontdata = fonts.ids +local fcs = fonts.color.set +local has_attribute = node.has_attribute +local traverse_id = node.traverse_id +local a_colorscheme = attributes.private('colorscheme') +local glyph = node.id("glyph") + +function fonts.goodies.colorschemes.coloring(head) + local lastfont, lastscheme + for n in traverse_id(glyph,head) do + local a = has_attribute(n,a_colorscheme) + if a then + local f = n.font + if f ~= lastfont then + lastscheme, lastfont = fontdata[f].colorscheme, f + end + if lastscheme then + local sc = lastscheme[n.char] + if sc then + fcs(n,"colorscheme:"..a..":"..sc) -- slow + end + end + end + end +end + +function fonts.goodies.colorschemes.enable() + tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring") + function fonts.goodies.colorschemes.enable() end +end + +-- installation (collected to keep the overview) + +fonts.otf.tables.features['goodies'] = 'Goodies on top of built in features' +fonts.otf.tables.features['featurset'] = 'Goodie Feature Set' +fonts.otf.tables.features['colorscheme'] = 'Goodie Color Scheme' + +fonts.otf.features.register('goodies') +fonts.otf.features.register('featureset') +fonts.otf.features.register('colorscheme') + +table.insert(fonts.triggers, 1, "goodies") +table.insert(fonts.triggers, 2, "featureset") -- insert after +table.insert(fonts.triggers, "colorscheme") + +fonts.initializers.base.otf.goodies = fonts.initializers.common.goodies +fonts.initializers.node.otf.goodies = fonts.initializers.common.goodies + +fonts.initializers.base.otf.featureset = fonts.initializers.common.featureset +fonts.initializers.node.otf.featureset = fonts.initializers.common.featureset + +fonts.initializers.base.otf.colorscheme = fonts.initializers.common.colorscheme +fonts.initializers.node.otf.colorscheme = fonts.initializers.common.colorscheme + +-- The following file (husayni.lfg) is the experimental setup that we used +-- for Idris font. For the moment we don't store this in the cache and quite +-- probably these files sit in one of the paths: +-- +-- tex/context/fonts/goodies +-- tex/fonts/goodies/context +-- tex/fonts/data/foundry/collection + +--~ local yes = "yes", "node" + +--~ local basics = { +--~ analyze = yes, +--~ mode = "node", +--~ language = "dflt", +--~ script = "arab", +--~ } + +--~ local analysis = { +--~ ccmp = yes, +--~ init = yes, medi = yes, fina = yes, +--~ } + +--~ local regular = { +--~ rlig = yes, calt = yes, salt = yes, anum = yes, +--~ ss01 = yes, ss03 = yes, ss07 = yes, ss10 = yes, ss12 = yes, ss15 = yes, ss16 = yes, +--~ ss19 = yes, ss24 = yes, ss25 = yes, ss26 = yes, ss27 = yes, ss31 = yes, ss34 = yes, +--~ ss35 = yes, ss36 = yes, ss37 = yes, ss38 = yes, ss41 = yes, ss42 = yes, ss43 = yes, +--~ js16 = yes, +--~ } + +--~ local positioning = { +--~ kern = yes, curs = yes, mark = yes, mkmk = yes, +--~ } + +--~ return { +--~ name = "husayni", +--~ version = "1.00", +--~ comment = "Goodies that complement the Husayni font by Idris Samawi Hamid.", +--~ author = "Idris Samawi Hamid and Hans Hagen", +--~ featuresets = { +--~ default = { +--~ basics, analysis, regular, positioning, -- xxxx = yes, yyyy = 2, +--~ }, +--~ }, +--~ stylistics = { +--~ ss01 = "Allah, Muhammad", +--~ ss02 = "ss01 + Allah_final", +--~ ss03 = "level-1 stack over Jiim, initial entry only", +--~ ss04 = "level-1 stack over Jiim, initial/medial entry", +--~ ss05 = "multi-level Jiim stacking, initial/medial entry", +--~ ss06 = "aesthetic Faa/Qaaf for FJ_mm, FJ_mf connection", +--~ ss07 = "initial-entry stacking over Haa", +--~ ss08 = "initial/medial stacking over Haa, minus HM_mf strings", +--~ ss09 = "initial/medial Haa stacking plus HM_mf strings", +--~ ss10 = "basic dipped Miim, initial-entry B_S-stack over Miim", +--~ ss11 = "full dipped Miim, initial-entry B_S-stack over Miim", +--~ ss12 = "XBM_im initial-medial entry B_S-stack over Miim", +--~ ss13 = "full initial-medial entry B_S-stacked Miim", +--~ ss14 = "initial entry, stacked Laam on Miim", +--~ ss15 = "full stacked Laam-on-Miim", +--~ ss16 = "initial entry, stacked Ayn-on-Miim", +--~ ss17 = "full stacked Ayn-on-Miim", +--~ ss18 = "LMJ_im already contained in ss03--05, may remove", +--~ ss19 = "LM_im", +--~ ss20 = "KLM_m, sloped Miim", +--~ ss21 = "KLM_i_mm/LM_mm, sloped Miim", +--~ ss22 = "filled sloped Miim", +--~ ss23 = "LM_mm, non-sloped Miim", +--~ ss24 = "BR_i_mf, BN_i_mf", +--~ ss25 = "basic LH_im might merge with ss24", +--~ ss26 = "full Yaa.final special strings: BY_if, BY_mf, LY_mf", +--~ ss27 = "basic thin Miim.final", +--~ ss28 = "full thin Miim.final to be moved to jsnn", +--~ ss29 = "basic short Miim.final", +--~ ss30 = "full short Miim.final to be moved to jsnn", +--~ ss31 = "basic Raa.final strings: JR and SR", +--~ ss32 = "basic Raa.final strings: JR, SR, and BR", +--~ ss33 = "TtR to be moved to jsnn", +--~ ss34 = "AyR style also available in jsnn", +--~ ss35 = "full Kaaf contexts", +--~ ss36 = "full Laam contexts", +--~ ss37 = "Miim-Miim contexts", +--~ ss38 = "basic dipped Haa, B_SH_mm", +--~ ss39 = "full dipped Haa, B_S_LH_i_mm_Mf", +--~ ss40 = "aesthetic dipped medial Haa", +--~ ss41 = "high and low Baa strings", +--~ ss42 = "diagonal entry", +--~ ss43 = "initial alternates", +--~ ss44 = "hooked final alif", +--~ ss45 = "BMA_f", +--~ ss46 = "BM_mm_alt, for JBM combinations", +--~ ss47 = "Shaddah-<kasrah> combo", +--~ ss48 = "Auto-sukuun", +--~ ss49 = "No vowels", +--~ ss50 = "Shaddah/MaaddahHamzah only", +--~ ss51 = "No Skuun", +--~ ss52 = "No Waslah", +--~ ss53 = "No Waslah", +--~ ss54 = "chopped finals", +--~ ss55 = "idgham-tanwin", +--~ js01 = "Raawide", +--~ js02 = "Yaawide", +--~ js03 = "Kaafwide", +--~ js04 = "Nuunwide", +--~ js05 = "Kaafwide Nuunwide Siinwide Baawide", +--~ js06 = "final Haa wide", +--~ js07 = "thin Miim", +--~ js08 = "short Miim", +--~ js09 = "wide Siin", +--~ js10 = "thuluth-style initial Haa, final Miim, MRw_mf", +--~ js11 = "level-1 stretching", +--~ js12 = "level-2 stretching", +--~ js13 = "level-3 stretching", +--~ js14 = "final Alif", +--~ js15 = "hooked final Alif", +--~ js16 = "aesthetic medial Faa/Qaaf", +--~ js17 = "fancy isol Haa after Daal, Raa, and Waaw", +--~ js18 = "Laamwide, alternate substitution", +--~ js19 = "level-4 stretching, only siin and Hhaa for basmalah", +--~ js20 = "level-5 stretching, only siin and Hhaa for basmalah", +--~ js21 = "Haa.final_alt2", +--~ }, +--~ colorschemes = { +--~ default = { +--~ [1] = { +--~ "Onedotabove", "Onedotbelow", "Twodotsabove", "Twodotsbelow", "Threedotsabove", "Twodotsabove.vrt", "Twodotsbelow.vrt", "Twodotsabove.KBA", "Threedotsabove.KBA", "Threedotsbelowinv", +--~ }, +--~ [2] = { +--~ "Fathah", "Dammah", "Kasrah", "FathahVertical", "DammahInverted", "KasrahVertical", "FathahVertical.alt1", "KasrahVertical.alt1", "FathahTanwiin", "DammahTanwiin", "KasrahTanwiin", "Shaddah", "Sukuun", "MaaddahHamzah", "Jazm", "Maaddah", "DammahTanwiin_alt2", "DammahTanwiin_alt1", "FathahTanwiin_alt1", "KasrahTanwiin_alt1", "Fathah.mkmk", "Dammah.mkmk", "Kasrah.mkmk", "FathahVertical.mkmk", "DammahInverted.mkmk", "KasrahVertical.mkmk", "FathahTanwiin.mkmk", "DammahTanwiin.mkmk", "KasrahTanwiin.mkmk", "DammahTanwiin_alt1.mkmk", +--~ }, +--~ [3] = { +--~ "Ttaa.waqf", "SsLY.waqf", "QLY.waqf", "Miim.waqf", "LA.waqf", "Jiim.waqf", "Threedotsabove.waqf", "Siin.waqf", "Ssaad.waqf", "Qaaf.waqf", "SsL.waqf", "QF.waqf", "SKTH.waqf", "WQFH.waqf", "Kaaf.waqf", "Ayn.ruku", +--~ }, +--~ [4] = { +--~ "Hamzah","Hamzahabove", "Hamzahbelow", "MaaddahHamzah.identity", "Waslah", +--~ }, +--~ [5] = { +--~ "Waawsmall", "Yaasmall", "FathahVertical.alt2", "Waawsmall.isol", "Yaasmall.isol", "FathahVertical.isol", +--~ }, +--~ [6] = { +--~ "Miim.nuun_high", "Siin.Ssaad", "Nuunsmall", "emptydot_low", "emptydot_high", "Sifr.fill", "Miim.nuun_low", "Nuun.tanwiin", +--~ }, +--~ [7] = { +--~ "Ayah", "Yaasmall", "Ayah.alt1", "Ayah.alt2", "Ayah.alt3", "Ayah2", +--~ } +--~ } +--~ } +--~ } diff --git a/tex/context/base/font-gds.mkiv b/tex/context/base/font-gds.mkiv new file mode 100644 index 000000000..afdede721 --- /dev/null +++ b/tex/context/base/font-gds.mkiv @@ -0,0 +1,79 @@ +%D \module +%D [ file=font-gds, +%D version=2009.10.14, +%D title=\CONTEXT\ Font Support, +%D subtitle=Colorschemes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Font Support / Colorschemes} + +\registerctxluafile{font-gds}{1.001} + +\unprotect + +% this will become colorgroups + +\definecolor[colorscheme:1:1][s=.75] +\definecolor[colorscheme:1:2][r=.75] +\definecolor[colorscheme:1:3][g=.75] +\definecolor[colorscheme:1:4][b=.75] +\definecolor[colorscheme:1:5][c=.75] +\definecolor[colorscheme:1:6][m=.75] +\definecolor[colorscheme:1:7][y=.75] + +\definecolor[colorscheme:2:7][s=.75] +\definecolor[colorscheme:2:6][r=.75] +\definecolor[colorscheme:2:5][g=.75] +\definecolor[colorscheme:2:4][b=.75] +\definecolor[colorscheme:2:3][c=.75] +\definecolor[colorscheme:2:2][m=.75] +\definecolor[colorscheme:2:1][y=.75] + +\definesystemattribute[colorscheme] + +\def\setfontcolorscheme + {\ctxlua{fonts.goodies.colorschemes.enable()}% + \xdef\setfontcolorscheme[##1]{\dosetattribute{colorscheme}{##1}}% + \setfontcolorscheme} + +\edef\resetfontcolorscheme{\doresetattribute{colorscheme}} + +\protect \endinput + +% \definefontfeature[husayni-colored][goodies=husayni,colorscheme=default,featureset=default] +% +% \definedfont[husayni*husayni-colored at 36pt] +% +% \starttext \pardir TRT \textdir TRT +% +% \setfontcolorscheme[1] +% +% اَلْحَمْدُ لِلّٰهِ حَمْدَ مُعْتَرِفٍ بِحَمْدِهٖ، مُغْتَرِفٌ مِنْ بِحَارِ +% مَجْدِهٖ، بِلِسَانِ ٱلثَّنَاۤءِ شَاكِرًا، وَلِحُسْنِ اٰلاۤئِهٖ نَاشِرًا؛ +% اَلَّذِيْ خَلَقَ ٱلْمَوْتَ وَٱلْحَيٰوةَ، وَٱلْخَيْرَ وَٱلشَّرَّ، +% وَٱلنَّفْعَ وَٱلضَّرَّ، وَٱلسُّكُوْنَ وَٱلْحَرَكَةَ، وَٱلْأَرْوَاحَ +% وَٱلْأَجْسَامَ، وَٱلذِّكْرَ وَٱلنِّسْيَانَ. +% +% \setfontcolorscheme[2] +% +% اَلْحَمْدُ لِلّٰهِ حَمْدَ مُعْتَرِفٍ بِحَمْدِهٖ، مُغْتَرِفٌ مِنْ بِحَارِ +% مَجْدِهٖ، بِلِسَانِ ٱلثَّنَاۤءِ شَاكِرًا، وَلِحُسْنِ اٰلاۤئِهٖ نَاشِرًا؛ +% اَلَّذِيْ خَلَقَ ٱلْمَوْتَ وَٱلْحَيٰوةَ، وَٱلْخَيْرَ وَٱلشَّرَّ، +% وَٱلنَّفْعَ وَٱلضَّرَّ، وَٱلسُّكُوْنَ وَٱلْحَرَكَةَ، وَٱلْأَرْوَاحَ +% وَٱلْأَجْسَامَ، وَٱلذِّكْرَ وَٱلنِّسْيَانَ. +% +% \resetfontcolorscheme +% +% اَلْحَمْدُ لِلّٰهِ حَمْدَ مُعْتَرِفٍ بِحَمْدِهٖ، مُغْتَرِفٌ مِنْ بِحَارِ +% مَجْدِهٖ، بِلِسَانِ ٱلثَّنَاۤءِ شَاكِرًا، وَلِحُسْنِ اٰلاۤئِهٖ نَاشِرًا؛ +% اَلَّذِيْ خَلَقَ ٱلْمَوْتَ وَٱلْحَيٰوةَ، وَٱلْخَيْرَ وَٱلشَّرَّ، +% وَٱلنَّفْعَ وَٱلضَّرَّ، وَٱلسُّكُوْنَ وَٱلْحَرَكَةَ، وَٱلْأَرْوَاحَ +% وَٱلْأَجْسَامَ، وَٱلذِّكْرَ وَٱلنِّسْيَانَ. +% +% \stoptext diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv index 16ca08160..2b4dbdaf7 100644 --- a/tex/context/base/font-ini.mkiv +++ b/tex/context/base/font-ini.mkiv @@ -2719,8 +2719,8 @@ {\dotripleargument\dodefinefontfeature} \def\dodefinefontfeature[#1][#2][#3]% - {\global\expandafter\chardef\csname\??fq=#1\endcsname - \ctxlua{tex.write(fonts.define.specify.preset_context("#1","#2","#3"))}\relax} + {\global\expandafter\chardef\csname\??fq=#1\endcsname % beware () needed as we get two values returned + \ctxlua{tex.write((fonts.define.specify.preset_context("#1","#2","#3")))}\relax} \definefontfeature [default] diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua index a1b717217..6cdb076ac 100644 --- a/tex/context/base/font-mis.lua +++ b/tex/context/base/font-mis.lua @@ -11,7 +11,7 @@ local lower, strip = string.lower, string.strip fonts.otf = fonts.otf or { } -fonts.otf.version = fonts.otf.version or 2.631 +fonts.otf.version = fonts.otf.version or 2.633 fonts.otf.pack = true fonts.otf.cache = containers.define("fonts", "otf", fonts.otf.version, true) diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua index 59aff301b..653d3e95a 100644 --- a/tex/context/base/font-otf.lua +++ b/tex/context/base/font-otf.lua @@ -82,7 +82,7 @@ otf.features.default = otf.features.default or { } otf.enhancers = otf.enhancers or { } otf.glists = { "gsub", "gpos" } -otf.version = 2.631 -- beware: also sync font-mis.lua +otf.version = 2.633 -- beware: also sync font-mis.lua otf.pack = true -- beware: also sync font-mis.lua otf.syncspace = true otf.notdef = false @@ -202,7 +202,7 @@ local enhancers = { "patch bugs", "merge cid fonts", "prepare unicode", "cleanup ttf tables", "compact glyphs", "reverse coverage", "cleanup aat", "enrich with features", "add some missing characters", ---~ "reorganize mark classes", + "reorganize mark classes", "reorganize kerns", -- moved here "flatten glyph lookups", "flatten anchor tables", "flatten feature tables", "prepare luatex tables", @@ -674,21 +674,15 @@ otf.enhancers["analyse subtables"] = function(data,filename) end local flags = gk.flags if flags then ---~ gk.flags = { -- forcing false packs nicer ---~ (flags.ignorecombiningmarks and "mark") or false, ---~ (flags.ignoreligatures and "ligature") or false, ---~ (flags.ignorebaseglyphs and "base") or false, ---~ flags.r2l or false, ---~ } gk.flags = { -- forcing false packs nicer - ((flags.ignorecombiningmarks or flags.mark_class) and "mark") or false, - ( flags.ignoreligatures and "ligature") or false, - ( flags.ignorebaseglyphs and "base") or false, - flags.r2l or false, + (flags.ignorecombiningmarks and "mark") or false, + (flags.ignoreligatures and "ligature") or false, + (flags.ignorebaseglyphs and "base") or false, + flags.r2l or false, } ---~ if flags.mark_class then ---~ gk.markclass = luatex.markclasses[flags.mark_class] ---~ end + if flags.mark_class then + gk.markclass = luatex.markclasses[flags.mark_class] + end end end end diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index 14837d2e1..880b52a49 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -1443,12 +1443,11 @@ function chainprocs.gpos_pair(start,stop,kind,chainname,currentcontext,cache,cur local factor = tfmdata.factor while snext and snext.id == glyph and snext.subtype<256 and snext.font == currentfont do local nextchar = snext.char -local krn = kerns[nextchar] + local krn = kerns[nextchar] if not krn and marks[nextchar] then prev = snext snext = snext.next else ---~ local krn = kerns[nextchar] if not krn then -- skip elseif type(krn) == "table" then @@ -1520,7 +1519,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local flags, done = sequence.flags, false local skipmark, skipligature, skipbase = flags[1], flags[2], flags[3] local someskip = skipmark or skipligature or skipbase -- could be stored in flags for a fast test (hm, flags could be false !) - local markclass = sequence.markclass + local markclass = sequence.markclass -- todo, first we need a proper test for k=1,#contexts do local match, current, last = true, start, start local ck = contexts[k] @@ -1554,10 +1553,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local ccd = descriptions[char] if ccd then local class = ccd.class ---~ if class == skipmark or class == skipligature or class == skipbase or (markclass and not markclass[char]) then - if class == skipmark or class == skipligature or class == skipbase then ---~ if someskip and (class == skipmark or class == skipligature or class == skipbase) then - -- skip 'm + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then if trace_skips then show_skip(kind,chainname,char,ck,class) end @@ -1601,10 +1597,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local ccd = descriptions[char] if ccd then local class = ccd.class ---~ if class == skipmark or class == skipligature or class == skipbase or (markclass and not markclass[char]) then - if class == skipmark or class == skipligature or class == skipbase then ---~ if someskip and class == skipmark or class == skipligature or class == skipbase then - -- skip 'm + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then if trace_skips then show_skip(kind,chainname,char,ck,class) end @@ -1658,10 +1651,7 @@ local function normal_handle_contextchain(start,kind,chainname,contexts,sequence local ccd = descriptions[char] if ccd then local class = ccd.class ---~ if class == skipmark or class == skipligature or class == skipbase or (markclass and not markclass[char]) then - if class == skipmark or class == skipligature or class == skipbase then ---~ if someskip and class == skipmark or class == skipligature or class == skipbase then - -- skip 'm + if class == skipmark or class == skipligature or class == skipbase or (markclass and class == "mark" and not markclass[char]) then if trace_skips then show_skip(kind,chainname,char,ck,class) end diff --git a/tex/context/base/font-pat.lua b/tex/context/base/font-pat.lua index 4a97248c4..f2b86a48a 100644 --- a/tex/context/base/font-pat.lua +++ b/tex/context/base/font-pat.lua @@ -10,6 +10,8 @@ local match, lower = string.match, string.lower local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) +-- this will become a per font patch file +-- -- older versions of latin modern didn't have the designsize set -- so for them we get it from the name @@ -92,3 +94,18 @@ local function patch(data,filename) end patches["palatino.*arabic"] = patch + +local function patch(data,filename) + local m = data.math + if m then + local d = m.DisplayOperatorMinHeight or 0 + if d < 2800 then + if trace_loading then + logs.report("load otf","patching DisplayOperatorMinHeight(%s -> 2800)",d) + end + m.DisplayOperatorMinHeight = 2800 + end + end +end + +patches["cambria"] = patch diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua index 905da59ce..73412f821 100644 --- a/tex/context/base/font-tfm.lua +++ b/tex/context/base/font-tfm.lua @@ -258,7 +258,9 @@ function tfm.do_scale(tfmtable, scaledpoints) t.unicodes = tfmtable.unicodes t.indices = tfmtable.indices t.marks = tfmtable.marks +t.goodies = tfmtable.goodies t.colorscheme = tfmtable.colorscheme +--~ t.embedding = tfmtable.embedding t.descriptions = descriptions if tfmtable.fonts then t.fonts = table.fastcopy(tfmtable.fonts) -- hm also at the end diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua index 9e0b12f7c..d7c2b0250 100644 --- a/tex/context/base/l-table.lua +++ b/tex/context/base/l-table.lua @@ -614,7 +614,7 @@ function table.tofile(filename,root,name,reduce,noquotes,hexify) end end -local function flatten(t,f,complete) +local function flatten(t,f,complete) -- is this used? meybe a variant with next, ... for i=1,#t do local v = t[i] if type(v) == "table" then @@ -643,6 +643,24 @@ end table.flatten_one_level = table.unnest +-- a better one: + +local function flattened(t,f) + if not f then + f = { } + end + for k, v in next, t do + if type(v) == "table" then + flattened(v,f) + else + f[k] = v + end + end + return f +end + +table.flattened = flattened + -- the next three may disappear function table.remove_value(t,value) -- todo: n diff --git a/tex/context/base/luat-dum.lua b/tex/context/base/luat-dum.lua index 699a0feef..dd5ade7a9 100644 --- a/tex/context/base/luat-dum.lua +++ b/tex/context/base/luat-dum.lua @@ -13,6 +13,11 @@ statistics = { starttiming = dummyfunction, stoptiming = dummyfunction, } +directives = { + register = dummyfunction, + enable = dummyfunction, + disable = dummyfunction, +} trackers = { register = dummyfunction, enable = dummyfunction, diff --git a/tex/context/base/lxml-aux.lua b/tex/context/base/lxml-aux.lua index ccff8e90d..eb2f3bb85 100644 --- a/tex/context/base/lxml-aux.lua +++ b/tex/context/base/lxml-aux.lua @@ -111,7 +111,7 @@ function xml.collect_texts(root, pattern, flatten) -- todo: variant with handle if collected and flatten then local xmltostring = xml.tostring for c=1,#collected do - collected[c] = xmltostring(collected[c]) + collected[c] = xmltostring(collected[c].dt) end end return collected or { } diff --git a/tex/context/base/lxml-ctx.lua b/tex/context/base/lxml-ctx.lua new file mode 100644 index 000000000..0ac12ab3c --- /dev/null +++ b/tex/context/base/lxml-ctx.lua @@ -0,0 +1,127 @@ +if not modules then modules = { } end modules ['lxml-ctx'] = { + version = 1.001, + comment = "companion to lxml-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- is this still used? + +xml.ctx = { } +xml.ctx.enhancers = { } + + +-- hashen + +function xml.ctx.enhancers.compound(root,lpath,before,tokens,after) -- todo lpeg + local before = before or "[%a%d][%a%d][%a%d]" + local tokens = tokens or "[%/%-]" + local after = after or "[%a%d][%a%d][%a%d]" + local pattern = "(" .. before .. ")(" .. tokens .. ")(" .. after .. ")" + local action = function(a,b,c) + return a .. "<compound token=" .. string.format("%q",b) .. "/>" .. c + end + xml.enhance(root,lpath,pattern,action) -- still present? +end + +local loaded = { } + +local nodesettostring = xml.nodesettostring + +-- maybe use detokenize instead of \type + +function xml.ctx.tshow(specification) + local pattern = specification.pattern + local xmlroot = specification.xmlroot + local attribute = specification.attribute + if context then + local xmlpattern = pattern + if not string.find(xmlpattern,"^[%a]+://") then + xmlpattern = "xml://" .. pattern + end + parsed = xml.parse_pattern(xmlpattern) + titlecommand = specification.title or "type" + if parsed.state then + context[titlecommand]("pattern: " .. pattern .. " (".. parsed.state .. ")") + else + context[titlecommand]("pattern: " .. pattern) + end + context.starttabulate({ "|Tr|Tl|Tp|" } ) + if specification.warning and parsed.comment then + context.NC() + context("!") + context.NC() + context.rlap(parsed.comment) + context.NR() + context.TB() + end + for p=1,#parsed do + local pp = parsed[p] + local kind = pp.kind + context.NC() + context(p) + context.NC() + context(kind) + context.NC() + if kind == "axis" then + context(pp.axis) + elseif kind == "nodes" then + context(nodesettostring(pp.nodes,pp.nodetest)) + elseif kind == "expression" then +--~ context("%s => %s",pp.expression,pp.converted) + context(pp.expression) + elseif kind == "finalizer" then + context("%s(%s)",pp.name,pp.arguments) + elseif kind == "error" and pp.comment then + context(pp.comment) + end + context.NC() + context.NR() + end + context.stoptabulate() + if xmlroot and xmlroot ~= "" then + if not loaded[xmlroot] then + loaded[xmlroot] = { xml.convert(buffers.content(xmlroot) or "") } + end + local collected = xml.parse_apply(loaded[xmlroot],xmlpattern) + if collected then + local tc = type(collected) + if not tc then + -- skip + else + context.blank() + context.type("result : ") + if tc == "string" then + context.type(collected) + elseif tc == "table" then + if collected.tg then + collected = { collected } + end + for c=1,#collected do + local cc = collected[c] + if attribute and attribute ~= "" then + local ccat = cc.at + local a = ccat and ccat[attribute] + if a and a ~= "" then + context.type(a) + context.type(">") + end + end + local ccns = cc.ns + if ccns == "" then + context.type(cc.tg) + else + context.type(ccns .. ":" .. cc.tg) + end + context.space() + end + else + context.type(tostring(tc)) + end + context.blank() + end + end + end + end +end diff --git a/tex/context/base/lxml-ctx.mkiv b/tex/context/base/lxml-ctx.mkiv new file mode 100644 index 000000000..44d95ba96 --- /dev/null +++ b/tex/context/base/lxml-ctx.mkiv @@ -0,0 +1,64 @@ +%D \module +%D [ file=lxml-ini, +%D version=2007.08.17, +%D title=\CONTEXT\ \XML\ Support, +%D subtitle=Initialization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Experimental. This might change! Also, it might become a module +%D instead if core code. + +\writestatus{loading}{ConTeXt XML Support / Goodies} + +\registerctxluafile{lxml-ctx}{1.001} + +\unprotect + +% the letterbar is a messy hack and is needed for the tabulate + +\settrue \xmllshowbuffer +\setfalse\xmllshowtitle +\settrue \xmllshowwarning + +\definehead[lshowtitle][subsubsubsubsubject] +\setuphead[lshowtitle][style=\tta] + +% \def\setuplxmlshow[#1]% +% {\dodoubleargument\getparameters[\??xl]} + +\def\xmllshow#1% + {\begingroup + \let|=\letterbar + \ctxlua{xml.ctx.tshow { + pattern = \!!bs#1\!!es, + \ifconditional\xmllshowtitle + title = "lshowtitle", + \fi + \ifconditional\xmllshowwarning + warning = true, + \fi + } }% + \endgroup} + +\def\xmllshowbuffer#1#2#3% + {\begingroup + \let|=\letterbar + \ctxlua{xml.ctx.tshow { + pattern = \!!bs#2\!!es, + \ifconditional\xmllshowbuffer + xmlroot = "#1", + attribute = "#3", + \fi + \ifconditional\xmllshowwarning + warning = true, + \fi + } }% + \endgroup} + +\protect diff --git a/tex/context/base/lxml-ent.lua b/tex/context/base/lxml-ent.lua index 69c37e8f9..9003c9d83 100644 --- a/tex/context/base/lxml-ent.lua +++ b/tex/context/base/lxml-ent.lua @@ -8,6 +8,7 @@ if not modules then modules = { } end modules ['lxml-ent'] = { local type, next = type, next local texsprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes +local utf = unicode.utf8 local utfupper = utf.upper --[[ldx-- diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua index 184d2f1ae..0f5407bda 100644 --- a/tex/context/base/lxml-lpt.lua +++ b/tex/context/base/lxml-lpt.lua @@ -35,8 +35,9 @@ a/b/c/text() a/b/c/text(1) a/b/c/text(-1) a/b/c/text(n) </typing> --ldx]]-- -local trace_lpath = false if trackers then trackers.register("xml.lpath", function(v) trace_lpath = v end) end -local trace_lparse = false if trackers then trackers.register("xml.lparse", function(v) trace_lparse = v end) end +local trace_lpath = false if trackers then trackers.register("xml.path", function(v) trace_lpath = v end) end +local trace_lparse = false if trackers then trackers.register("xml.parse", function(v) trace_lparse = v end) end +local trace_lprofile = false if trackers then trackers.register("xml.profile", function(v) trace_lpath = v trace_lparse = v trace_lprofile = v end) end --[[ldx-- <p>We've now arrived at an interesting part: accessing the tree using a subset @@ -694,7 +695,7 @@ local function parse_pattern(pattern) -- the gain of caching is rather minimal parsed = { pattern = pattern } end cache[pattern] = parsed - if trace_lparse then + if trace_lparse and not trace_lprofile then lshow(parsed) end end @@ -714,6 +715,73 @@ end -- caching found lookups saves not that much (max .1 sec on a 8 sec run) -- and it also messes up finalizers +local profiled = { } xml.profiled = profiled + +local function profiled_apply(list,parsed,nofparsed) + local p = profiled[parsed.pattern] + if p then + p.tested = p.tested + 1 + else + p = { tested = 1, matched = 0, finalized = 0 } + profiled[parsed.pattern] = p + end + local collected = list + for i=1,nofparsed do + local pi = parsed[i] + local kind = pi.kind + if kind == "axis" then + collected = apply_axis[pi.axis](collected) + elseif kind == "nodes" then + collected = apply_nodes(collected,pi.nodetest,pi.nodes) + elseif kind == "expression" then + collected = apply_expression(collected,pi.evaluator,i) + elseif kind == "finalizer" then + collected = pi.finalizer(collected) + p.matched = p.matched + 1 + p.finalized = p.finalized + 1 + return collected + end + if not collected or #collected == 0 then + return nil + end + end + if collected then + p.matched = p.matched + 1 + end + return collected +end + +local function traced_apply(list,parsed,nofparsed) + if trace_lparse then + lshow(parsed) + end + logs.report("lpath", "collecting : %s",parsed.pattern) + logs.report("lpath", " root tags : %s",tagstostring(list)) + local collected = list + for i=1,nofparsed do + local pi = parsed[i] + local kind = pi.kind + if kind == "axis" then + collected = apply_axis[pi.axis](collected) + logs.report("lpath", "% 10i : ax : %s",(collected and #collected) or 0,pi.axis) + elseif kind == "nodes" then + collected = apply_nodes(collected,pi.nodetest,pi.nodes) + logs.report("lpath", "% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest)) + elseif kind == "expression" then + collected = apply_expression(collected,pi.evaluator,i) + logs.report("lpath", "% 10i : ex : %s",(collected and #collected) or 0,pi.expression) + elseif kind == "finalizer" then + collected = pi.finalizer(collected) + logs.report("lpath", "% 10i : fi : %s : %s(%s)",(collected and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") + return collected + end + if not collected or #collected == 0 then + return nil + end + end + return collected +end + local function parse_apply(list,pattern) -- we avoid an extra call local parsed = cache[pattern] @@ -730,60 +798,35 @@ local function parse_apply(list,pattern) return end local nofparsed = #parsed - if nofparsed > 0 then - if trace_lpath then - if trace_lparse then - lshow(parsed) - end - logs.report("lpath", "collecting : %s",pattern) - logs.report("lpath", " root tags : %s",tagstostring(list)) - local collected = list - for i=1,nofparsed do - local pi = parsed[i] - local kind = pi.kind - if kind == "axis" then - collected = apply_axis[pi.axis](collected) - -- collected = pi.apply(collected) - logs.report("lpath", "% 10i : ax : %s",(collected and #collected) or 0,pi.axis) - elseif kind == "nodes" then - collected = apply_nodes(collected,pi.nodetest,pi.nodes) - logs.report("lpath", "% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest)) - elseif kind == "expression" then - collected = apply_expression(collected,pi.evaluator,i) - logs.report("lpath", "% 10i : ex : %s",(collected and #collected) or 0,pi.expression) - elseif kind == "finalizer" then - collected = pi.finalizer(collected) - logs.report("lpath", "% 10i : fi : %s : %s(%s)",(collected and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") - return collected - end - if not collected or #collected == 0 then - return nil + if nofparsed == 0 then + -- something is wrong + elseif not trace_lpath then + -- normal apply, inline, no self + local collected = list + for i=1,nofparsed do + local pi = parsed[i] + local kind = pi.kind + if kind == "axis" then + local axis = pi.axis + if axis ~= "self" then + collected = apply_axis[axis](collected) end + elseif kind == "nodes" then + collected = apply_nodes(collected,pi.nodetest,pi.nodes) + elseif kind == "expression" then + collected = apply_expression(collected,pi.evaluator,i) + elseif kind == "finalizer" then + return pi.finalizer(collected) end - return collected - else - local collected = list - for i=1,nofparsed do - local pi = parsed[i] - local kind = pi.kind - if kind == "axis" then - local axis = pi.axis - if axis ~= "self" then - collected = apply_axis[axis](collected) - end - elseif kind == "nodes" then - collected = apply_nodes(collected,pi.nodetest,pi.nodes) - elseif kind == "expression" then - collected = apply_expression(collected,pi.evaluator,i) - elseif kind == "finalizer" then - return pi.finalizer(collected) - end - if not collected or #collected == 0 then - return nil - end + if not collected or #collected == 0 then + return nil end - return collected end + return collected + elseif trace_lprofile then + return profiled_apply(list,parsed,nofparsed) + else -- trace_lpath + return traced_apply(list,parsed,nofparsed) end end diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua index 69f5b5116..0759a7277 100644 --- a/tex/context/base/lxml-tex.lua +++ b/tex/context/base/lxml-tex.lua @@ -1289,6 +1289,28 @@ statistics.register("lxml preparation time", function() end end) +statistics.register("lxml lpath profile", function() + local p = xml.profiled + if p and next(p) then + local s = table.sortedkeys(p) + local tested, matched, finalized = 0, 0, 0 + texio.write_nl("log","\nbegin of lxml profile\n") + texio.write_nl("log","\n tested matched finalized pattern\n\n") + for i=1,#s do + local pattern = s[i] + local pp = p[pattern] + local t, m, f = pp.tested, pp.matched, pp.finalized + tested, matched, finalized = tested + t, matched + m, finalized + f + texio.write_nl("log",format("%9i %9i %9i %s",t,m,f,pattern)) + end + texio.write_nl("log","\nend of lxml profile\n") + return format("%s patterns, %s tested, %s matched, %s finalized (see log for details)",#s,tested,matched,finalized) + else + return nil + end +end) + + -- misc function lxml.nonspace(id,pattern) -- slow, todo loop diff --git a/tex/context/base/lxml-xml.lua b/tex/context/base/lxml-xml.lua index 7ff3f5955..215635e78 100644 --- a/tex/context/base/lxml-xml.lua +++ b/tex/context/base/lxml-xml.lua @@ -173,7 +173,15 @@ local function empty(collected) local edt = e.dt if edt then local n = #edt - if (n > 2) or (n > 0 and edt[1] == "") then + if n == 1 then + local edk = edt[1] + local typ = type(edk) + if typ == "table" then + return false + elseif edk ~= "" then -- maybe an extra tester for spacing only + return false + end + elseif n > 1 then return false end end diff --git a/tex/context/base/m-directives.tex b/tex/context/base/m-directives.tex new file mode 100644 index 000000000..c958f6cad --- /dev/null +++ b/tex/context/base/m-directives.tex @@ -0,0 +1,5 @@ +\doifnotmode{mkiv} {\endinput} + +\starttext + \showdirectives +\stoptext diff --git a/tex/context/base/m-track.tex b/tex/context/base/m-trackers.tex index cfcbbabff..cfcbbabff 100644 --- a/tex/context/base/m-track.tex +++ b/tex/context/base/m-trackers.tex diff --git a/tex/context/base/node-inj.lua b/tex/context/base/node-inj.lua index 2befb0167..5829513d3 100644 --- a/tex/context/base/node-inj.lua +++ b/tex/context/base/node-inj.lua @@ -312,6 +312,7 @@ function nodes.inject_kerns(head,where,keep) local k = wx[p] if k then n.xoffset = p.xoffset - d[1] - k[2] +--~ n.xoffset = p.xoffset - k[2] else n.xoffset = p.xoffset - d[1] end diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua index cd006e68b..4cd324922 100644 --- a/tex/context/base/trac-deb.lua +++ b/tex/context/base/trac-deb.lua @@ -194,13 +194,3 @@ function tracers.register_dump_hash(delta) end main.register_stop_actions(1,function() tracers.dump_hash(nil,true) end) -- at front end - --- trackers (maybe group the show by class) - -function trackers.show() - commands.writestatus("","") - for k,v in ipairs(trackers.list()) do - commands.writestatus("tracker",v) - end - commands.writestatus("","") -end diff --git a/tex/context/base/trac-deb.mkiv b/tex/context/base/trac-deb.mkiv index 870c452ad..24e17f486 100644 --- a/tex/context/base/trac-deb.mkiv +++ b/tex/context/base/trac-deb.mkiv @@ -41,3 +41,8 @@ \def\resettrackers {\ctxlua{trackers.reset()}} \def\enabletrackers [#1]{\ctxlua{trackers.enable("#1")}} \def\disabletrackers[#1]{\ctxlua{trackers.disable("#1")}} + +\def\showdirectives {\ctxlua{directives.show()}} +%def\resetdirectives {\ctxlua{directives.reset()}} % would be weird to use +\def\enabledirectives [#1]{\ctxlua{directives.enable("#1")}} +\def\disabledirectives[#1]{\ctxlua{directives.disable("#1")}} diff --git a/tex/context/base/trac-inf.lua b/tex/context/base/trac-inf.lua index 4386c0c96..1a1977f3f 100644 --- a/tex/context/base/trac-inf.lua +++ b/tex/context/base/trac-inf.lua @@ -161,3 +161,4 @@ function statistics.timed(action,report) statistics.stoptiming(timer) report("total runtime: %s",statistics.elapsedtime(timer)) end + diff --git a/tex/context/base/trac-tra.lua b/tex/context/base/trac-tra.lua index 56ca02dfb..3a8f14074 100644 --- a/tex/context/base/trac-tra.lua +++ b/tex/context/base/trac-tra.lua @@ -10,12 +10,15 @@ if not modules then modules = { } end modules ['trac-tra'] = { -- bound to a variable, like node.new, node.copy etc (contrary to for instance -- node.has_attribute which is bound to a has_attribute local variable in mkiv) +local getinfo = debug.getinfo +local type, next = type, next +local concat = table.concat +local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub + debugger = debugger or { } local counters = { } local names = { } -local getinfo = debug.getinfo -local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub -- one @@ -143,11 +146,11 @@ end --~ print("") --~ debugger.showstats(print,3) -trackers = trackers or { } - -local data, done = { }, { } +setters = setters or { } +setters.data = setters.data or { } -local function set(what,value) +local function set(t,what,value) + local data, done = t.data, t.done if type(what) == "string" then what = aux.settings_to_array(what) -- inefficient but ok end @@ -166,28 +169,30 @@ local function set(what,value) end end -local function reset() - for d, f in next, data do +local function reset(t) + for d, f in next, t.data do for i=1,#f do f[i](false) end end end -local function enable(what) - set(what,true) +local function enable(t,what) + set(t,what,true) end -local function disable(what) +local function disable(t,what) + local data = t.data if not what or what == "" then - done = { } - reset() + t.done = { } + reset(t) else - set(what,false) + set(t,what,false) end end -function trackers.register(what,...) +function setters.register(t,what,...) + local data = t.data what = lower(what) local w = data[what] if not w then @@ -199,32 +204,32 @@ function trackers.register(what,...) if typ == "function" then w[#w+1] = fnc elseif typ == "string" then - w[#w+1] = function(value) set(fnc,value,nesting) end + w[#w+1] = function(value) set(t,fnc,value,nesting) end end end end -function trackers.enable(what) - local e = trackers.enable - trackers.enable, done = enable, { } - enable(string.simpleesc(what)) - trackers.enable, done = e, { } +function setters.enable(t,what) + local e = t.enable + t.enable, t.done = enable, { } + enable(t,string.simpleesc(what)) + t.enable, t.done = e, { } end -function trackers.disable(what) - local e = trackers.disable - trackers.disable, done = disable, { } - disable(string.simpleesc(what)) - trackers.disable, done = e, { } +function setters.disable(t,what) + local e = t.disable + t.disable, t.done = disable, { } + disable(t,string.simpleesc(what)) + t.disable, t.done = e, { } end -function trackers.reset() - done = { } - reset() +function setters.reset(t) + t.done = { } + reset(t) end -function trackers.list() -- pattern - local list = table.sortedkeys(data) +function setters.list(t) -- pattern + local list = table.sortedkeys(t.data) local user, system = { }, { } for l=1,#list do local what = list[l] @@ -236,3 +241,136 @@ function trackers.list() -- pattern end return user, system end + +function setters.show(t) + commands.writestatus("","") + for k,v in ipairs(setters.list(t)) do + commands.writestatus(t.name,v) + end + commands.writestatus("","") +end + +-- we could have used a bit of oo and the trackers:enable syntax but +-- there is already a lot of code around using the singluar tracker + +function setters.new(name) + local t + t = { + data = { }, + name = name, + enable = function(...) setters.enable (t,...) end, + disable = function(...) setters.disable (t,...) end, + register = function(...) setters.register(t,...) end, + list = function(...) setters.list (t,...) end, + show = function(...) setters.show (t,...) end, + } + setters.data[name] = t + return t +end + +trackers = setters.new("trackers") +directives = setters.new("directives") + +-- nice trick: we overload two of the directives related functions with variants that +-- do tracing (itself using a tracker) .. proof of concept + +local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end) + +local e = directives.enable +local d = directives.disable + +function directives.enable(...) + commands.writestatus("directives","enabling: %s",concat({...}," ")) + e(...) +end + +function directives.disable(...) + commands.writestatus("directives","disabling: %s",concat({...}," ")) + d(...) +end + +--~ -- old code: +-- +--~ trackers = trackers or { } +--~ local data, done = { }, { } +--~ local function set(what,value) +--~ if type(what) == "string" then +--~ what = aux.settings_to_array(what) -- inefficient but ok +--~ end +--~ for i=1,#what do +--~ local w = what[i] +--~ for d, f in next, data do +--~ if done[d] then +--~ -- prevent recursion due to wildcards +--~ elseif find(d,w) then +--~ done[d] = true +--~ for i=1,#f do +--~ f[i](value) +--~ end +--~ end +--~ end +--~ end +--~ end +--~ local function reset() +--~ for d, f in next, data do +--~ for i=1,#f do +--~ f[i](false) +--~ end +--~ end +--~ end +--~ local function enable(what) +--~ set(what,true) +--~ end +--~ local function disable(what) +--~ if not what or what == "" then +--~ done = { } +--~ reset() +--~ else +--~ set(what,false) +--~ end +--~ end +--~ function trackers.register(what,...) +--~ what = lower(what) +--~ local w = data[what] +--~ if not w then +--~ w = { } +--~ data[what] = w +--~ end +--~ for _, fnc in next, { ... } do +--~ local typ = type(fnc) +--~ if typ == "function" then +--~ w[#w+1] = fnc +--~ elseif typ == "string" then +--~ w[#w+1] = function(value) set(fnc,value,nesting) end +--~ end +--~ end +--~ end +--~ function trackers.enable(what) +--~ local e = trackers.enable +--~ trackers.enable, done = enable, { } +--~ enable(string.simpleesc(what)) +--~ trackers.enable, done = e, { } +--~ end +--~ function trackers.disable(what) +--~ local e = trackers.disable +--~ trackers.disable, done = disable, { } +--~ disable(string.simpleesc(what)) +--~ trackers.disable, done = e, { } +--~ end +--~ function trackers.reset() +--~ done = { } +--~ reset() +--~ end +--~ function trackers.list() -- pattern +--~ local list = table.sortedkeys(data) +--~ local user, system = { }, { } +--~ for l=1,#list do +--~ local what = list[l] +--~ if find(what,"^%*") then +--~ system[#system+1] = what +--~ else +--~ user[#user+1] = what +--~ end +--~ end +--~ return user, system +--~ end |