From 001a15c01dd2201598cfea529fcf244c3a9aac06 Mon Sep 17 00:00:00 2001 From: Marius Date: Tue, 19 Mar 2013 15:40:14 +0200 Subject: beta 2013.03.19 14:27 --- tex/context/base/buff-ver.lua | 13 +- tex/context/base/char-utf.lua | 208 ++-- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4135 -> 4137 bytes tex/context/base/context-version.png | Bin 40510 -> 40464 bytes tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/core-env.lua | 25 +- tex/context/base/font-hsh.lua | 2 +- tex/context/base/font-otd.lua | 21 +- tex/context/base/font-otn.lua | 51 +- tex/context/base/l-number.lua | 4 +- tex/context/base/math-noa.lua | 4 +- tex/context/base/node-fin.lua | 1047 ++++++++++++++------ tex/context/base/node-fnt.lua | 17 +- tex/context/base/node-inj.lua | 4 +- tex/context/base/node-ref.lua | 126 +-- tex/context/base/spac-chr.lua | 6 +- tex/context/base/spac-ver.lua | 20 +- tex/context/base/status-files.pdf | Bin 24768 -> 24761 bytes tex/context/base/status-lua.pdf | Bin 211224 -> 211332 bytes tex/context/base/strc-ref.lua | 5 + tex/context/base/strc-ref.mkvi | 10 +- tex/context/base/task-ini.lua | 18 +- tex/context/base/trac-vis.lua | 106 +- tex/context/base/trac-vis.mkiv | 37 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 35 +- 28 files changed, 1131 insertions(+), 636 deletions(-) (limited to 'tex') diff --git a/tex/context/base/buff-ver.lua b/tex/context/base/buff-ver.lua index a5dd808fd..e327a59dd 100644 --- a/tex/context/base/buff-ver.lua +++ b/tex/context/base/buff-ver.lua @@ -508,9 +508,12 @@ end visualizers.visualize = visualize visualizers.getvisualizer = getvisualizer +local fallbacks = { } table.setmetatableindex(fallbacks,function(t,k) local v = { nature = k } t[k] = v return v end) + local function checkedsettings(settings,nature) if not settings then - return { nature = nature } + -- let's avoid dummy tables as much as possible + return fallbacks[nature] else if not settings.nature then settings.nature = nature @@ -695,14 +698,14 @@ end commands.loadvisualizer = visualizers.load ---~ local decodecomment = resolvers.macros.decodecomment -- experiment +-- local decodecomment = resolvers.macros.decodecomment -- experiment function commands.typebuffer(settings) local lines = getlines(settings.name) if lines then local content, m = filter(lines,settings) if content and content ~= "" then ---~ content = decodecomment(content) + -- content = decodecomment(content) content = dotabs(content,settings) visualize(content,checkedsettings(settings,"display")) end @@ -734,7 +737,7 @@ local strip = Cs((P("\\") * ((1-S("\\ "))^1) * (P(" ")/"") + 1)^0) -- function commands.typestring(settings) local content = settings.data if content and content ~= "" then - content = lpegmatch(strip,content) -- can be an option, btu needed in e.g. tabulate + content = #content > 1 and lpegmatch(strip,content) or content -- can be an option, but needed in e.g. tabulate -- content = decodecomment(content) -- content = dotabs(content,settings) visualize(content,checkedsettings(settings,"inline")) @@ -752,7 +755,7 @@ function commands.typefile(settings) str = regimes.translate(str,regime) end if str and str~= "" then ---~ content = decodecomment(content) + -- content = decodecomment(content) local lines = splitlines(str) local content, m = filter(lines,settings) if content and content ~= "" then diff --git a/tex/context/base/char-utf.lua b/tex/context/base/char-utf.lua index 154213ea8..d0e40e664 100644 --- a/tex/context/base/char-utf.lua +++ b/tex/context/base/char-utf.lua @@ -258,113 +258,115 @@ not collecting tokens is not only faster but also saves garbage collecting. -- I might use the combined loop at some point for the filter -- some day. ---~ function utffilters.collapse(str) -- not really tested (we could preallocate a table) ---~ if str and str ~= "" then ---~ local nstr = #str ---~ if nstr > 1 then ---~ if initialize then -- saves a call ---~ initialize() ---~ end ---~ local tokens, t, first, done, n = { }, 0, false, false, 0 ---~ for second in utfcharacters(str) do ---~ local dec = decomposed[second] ---~ if dec then ---~ if not done then ---~ if n > 0 then ---~ for s in utfcharacters(str) do ---~ if n == 1 then ---~ break ---~ else ---~ t = t + 1 ---~ tokens[t] = s ---~ n = n - 1 ---~ end ---~ end ---~ end ---~ done = true ---~ elseif first then ---~ t = t + 1 ---~ tokens[t] = first ---~ end ---~ t = t + 1 ---~ tokens[t] = dec ---~ first = false ---~ elseif done then ---~ local crs = high[second] ---~ if crs then ---~ if first then ---~ t = t + 1 ---~ tokens[t] = first ---~ end ---~ first = crs ---~ else ---~ local cgf = graphemes[first] ---~ if cgf and cgf[second] then ---~ first = cgf[second] ---~ elseif first then ---~ t = t + 1 ---~ tokens[t] = first ---~ first = second ---~ else ---~ first = second ---~ end ---~ end ---~ else ---~ local crs = high[second] ---~ if crs then ---~ for s in utfcharacters(str) do ---~ if n == 1 then ---~ break ---~ else ---~ t = t + 1 ---~ tokens[t] = s ---~ n = n - 1 ---~ end ---~ end ---~ if first then ---~ t = t + 1 ---~ tokens[t] = first ---~ end ---~ first = crs ---~ done = true ---~ else ---~ local cgf = graphemes[first] ---~ if cgf and cgf[second] then ---~ for s in utfcharacters(str) do ---~ if n == 1 then ---~ break ---~ else ---~ t = t + 1 ---~ tokens[t] = s ---~ n = n - 1 ---~ end ---~ end ---~ first = cgf[second] ---~ done = true ---~ else ---~ first = second ---~ n = n + 1 ---~ end ---~ end ---~ end ---~ end ---~ if done then ---~ if first then ---~ t = t + 1 ---~ tokens[t] = first ---~ end ---~ return concat(tokens) -- seldom called ---~ end ---~ elseif nstr > 0 then ---~ return high[str] or str ---~ end ---~ end ---~ return str ---~ end +-- function utffilters.collapse(str) -- not really tested (we could preallocate a table) +-- if str and str ~= "" then +-- local nstr = #str +-- if nstr > 1 then +-- if initialize then -- saves a call +-- initialize() +-- end +-- local tokens, t, first, done, n = { }, 0, false, false, 0 +-- for second in utfcharacters(str) do +-- local dec = decomposed[second] +-- if dec then +-- if not done then +-- if n > 0 then +-- for s in utfcharacters(str) do +-- if n == 1 then +-- break +-- else +-- t = t + 1 +-- tokens[t] = s +-- n = n - 1 +-- end +-- end +-- end +-- done = true +-- elseif first then +-- t = t + 1 +-- tokens[t] = first +-- end +-- t = t + 1 +-- tokens[t] = dec +-- first = false +-- elseif done then +-- local crs = high[second] +-- if crs then +-- if first then +-- t = t + 1 +-- tokens[t] = first +-- end +-- first = crs +-- else +-- local cgf = graphemes[first] +-- if cgf and cgf[second] then +-- first = cgf[second] +-- elseif first then +-- t = t + 1 +-- tokens[t] = first +-- first = second +-- else +-- first = second +-- end +-- end +-- else +-- local crs = high[second] +-- if crs then +-- for s in utfcharacters(str) do +-- if n == 1 then +-- break +-- else +-- t = t + 1 +-- tokens[t] = s +-- n = n - 1 +-- end +-- end +-- if first then +-- t = t + 1 +-- tokens[t] = first +-- end +-- first = crs +-- done = true +-- else +-- local cgf = graphemes[first] +-- if cgf and cgf[second] then +-- for s in utfcharacters(str) do +-- if n == 1 then +-- break +-- else +-- t = t + 1 +-- tokens[t] = s +-- n = n - 1 +-- end +-- end +-- first = cgf[second] +-- done = true +-- else +-- first = second +-- n = n + 1 +-- end +-- end +-- end +-- end +-- if done then +-- if first then +-- t = t + 1 +-- tokens[t] = first +-- end +-- return concat(tokens) -- seldom called +-- end +-- elseif nstr > 0 then +-- return high[str] or str +-- end +-- end +-- return str +-- end local skippable = table.tohash { "mkiv", "mkvi" } local filesuffix = file.suffix +-- we could reuse tokens but it's seldom populated anyway + function utffilters.collapse(str,filename) -- not really tested (we could preallocate a table) if skippable[filesuffix(filename)] then return str diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 8e2ab2a89..ed69cb76c 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.18 18:49} +\newcontextversion{2013.03.19 14:27} %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 fe01546f0..973c1ab68 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.18 18:49} +\newcontextversion{2013.03.19 14:27} %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 bf250e02e..af99b8369 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 094275eeb..5cfb728c5 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 18c21ca01..87bb0f8cb 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.18 18:49} +\edef\contextversion{2013.03.19 14:27} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 681bbaf99..fd01490f5 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.18 18:49} +\edef\contextversion{2013.03.19 14:27} %D For those who want to use this: diff --git a/tex/context/base/core-env.lua b/tex/context/base/core-env.lua index 8b9ae172b..025192d4b 100644 --- a/tex/context/base/core-env.lua +++ b/tex/context/base/core-env.lua @@ -16,6 +16,7 @@ local P, C, S, Cc, lpegmatch, patterns = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc, lpeg.m local csname_id = token.csname_id local create = token.create local texcount = tex.count +local texsetcount = tex.setcount local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex @@ -77,13 +78,23 @@ end) -- todo : global -function tex.settrue(name) - texcount[name] = 0 -end - -function tex.setfalse(name) - texcount[name] = 1 -end +-- not possible as we let at the tex end to zerocount and plusone +-- +-- function tex.settrue(name,glob) +-- if glob then +-- texsetcount("global",name,0) +-- else +-- texcount[name] = 0 +-- end +-- end +-- +-- function tex.setfalse(name,glob) +-- if glob then +-- texsetcount("global",name,1) +-- else +-- texcount[name] = 1 +-- end +-- end ---- arg = P("{") * C(patterns.nested) * P("}") + Cc("") diff --git a/tex/context/base/font-hsh.lua b/tex/context/base/font-hsh.lua index dc38b87cf..42c4be950 100644 --- a/tex/context/base/font-hsh.lua +++ b/tex/context/base/font-hsh.lua @@ -157,7 +157,7 @@ setmetatableindex(italics, function(t,k) -- is test ! local properties = identifiers[k].properties local hasitalics = properties and properties.hasitalics if hasitalics then - hasitalics = chardata[k] -- convenient return + hasitalics = characters[k] -- convenient return else hasitalics = false end diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua index 8a41ebcdb..a9d093d6d 100644 --- a/tex/context/base/font-otd.lua +++ b/tex/context/base/font-otd.lua @@ -242,15 +242,20 @@ function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in specia } rl[attr] = ra local sequences = tfmdata.resources.sequences - setmetatableindex(ra, function(t,k) - if type(k) == "number" then - local v = initialize(sequences[k],script,language,s_enabled,a_enabled,font,attr,dynamic) - t[k] = v or false - return v - end - end) +-- setmetatableindex(ra, function(t,k) +-- if type(k) == "number" then +-- local v = initialize(sequences[k],script,language,s_enabled,a_enabled,font,attr,dynamic) +-- t[k] = v or false +-- return v +-- end +-- end) +for s=1,#sequences do + local v = initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic) + if v then + ra[#ra+1] = v + end +end end - return ra end diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index 90f053bcc..6eed30c94 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -2033,13 +2033,19 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context } rs[language] = rl local sequences = tfmdata.resources.sequences - setmetatableindex(rl, function(t,k) - if type(k) == "number" then - local v = enabled and initialize(sequences[k],script,language,enabled) - t[k] = v - return v - end - end) +-- setmetatableindex(rl, function(t,k) +-- if type(k) == "number" then +-- local v = enabled and initialize(sequences[k],script,language,enabled) +-- t[k] = v +-- return v +-- end +-- end) +for s=1,#sequences do + local v = enabled and initialize(sequences[s],script,language,enabled) + if v then + rl[#rl+1] = v + end +end end return rl end @@ -2101,12 +2107,17 @@ local function featuresprocessor(head,font,attr) -- Keeping track of the headnode is needed for devanagari (I generalized it a bit -- so that multiple cases are also covered.) - for s=1,#sequences do - local dataset = datasets[s] - if dataset then - featurevalue = dataset[1] -- todo: pass to function instead of using a global - if featurevalue then - local sequence = sequences[s] -- also dataset[5] +-- for s=1,#sequences do +-- local dataset = datasets[s] +-- if dataset then +-- featurevalue = dataset[1] -- todo: pass to function instead of using a global +-- if featurevalue then -- never false + +for s=1,#datasets do + local dataset = datasets[s] + featurevalue = dataset[1] -- todo: pass to function instead of using a global + + local sequence = dataset[5] -- sequences[s] -- also dataset[5] local rlparmode = 0 local topstack = 0 local success = false @@ -2191,8 +2202,8 @@ local function featuresprocessor(head,font,attr) else start = start.next end -elseif id == math_code then - start = endofmath(start).next + elseif id == math_code then + start = endofmath(start).next else start = start.next end @@ -2326,8 +2337,12 @@ elseif id == math_code then if trace_steps then -- ? registerstep(head) end - end - end + +-- end +-- else +-- -- report_process("warning, no dataset %a",s) +-- end + end return head, done end @@ -2510,7 +2525,7 @@ local function prepare_contextchains(tfmdata) local replacements = rule.replacements local sequence = { } local nofsequences = 0 - -- Wventually we can store start, stop and sequence in the cached file + -- Eventually we can store start, stop and sequence in the cached file -- but then less sharing takes place so best not do that without a lot -- of profiling so let's forget about it. if before then diff --git a/tex/context/base/l-number.lua b/tex/context/base/l-number.lua index e26eb729d..001ca31f7 100644 --- a/tex/context/base/l-number.lua +++ b/tex/context/base/l-number.lua @@ -17,7 +17,7 @@ local lpegmatch = lpeg.match number = number or { } local number = number -if bit32 then +if bit32 then -- I wonder if this is faster local btest, bor = bit32.btest, bit32.bor @@ -28,7 +28,7 @@ if bit32 then number.hasbit = btest number.setbit = bor - function number.setbit(x,p) + function number.setbit(x,p) -- why not bor? return btest(x,p) and x or x + p end diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua index 2f2f73ea2..92d417524 100644 --- a/tex/context/base/math-noa.lua +++ b/tex/context/base/math-noa.lua @@ -148,8 +148,6 @@ local function process(start,what,n,parent) end elseif id == math_char or id == math_textchar or id == math_delim then break - elseif id == math_style then - -- has a next elseif id == math_noad then local noad = start.nucleus if noad then process(noad,what,n,start) end -- list noad = start.sup if noad then process(noad,what,n,start) end -- list @@ -181,6 +179,8 @@ local function process(start,what,n,parent) noad = start.sub if noad then process(noad,what,n,start) end -- list noad = start.accent if noad then process(noad,what,n,start) end -- list noad = start.bot_accent if noad then process(noad,what,n,start) end -- list + elseif id == math_style then + -- has a next else -- glue, penalty, etc end diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua index 9367badd3..2e62ebcb5 100644 --- a/tex/context/base/node-fin.lua +++ b/tex/context/base/node-fin.lua @@ -29,15 +29,15 @@ local vlist_code = nodecodes.vlist local pdfliteral_code = whatcodes.pdfliteral -local states = attributes.states -local numbers = attributes.numbers -local a_trigger = attributes.private('trigger') -local triggering = false +local states = attributes.states +local numbers = attributes.numbers +local a_trigger = attributes.private('trigger') +local triggering = false -local starttiming = statistics.starttiming -local stoptiming = statistics.stoptiming - -local unsetvalue = attributes.unsetvalue +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming +local loadstripped = utilities.lua.loadstripped +local unsetvalue = attributes.unsetvalue -- these two will be like trackers @@ -80,97 +80,105 @@ end -- so that we moved looping to the processor itself; this may lead to a bit of -- duplicate code once that we have more state handlers -local function process_attribute(head,plugin) -- head,attribute,enabled,initializer,resolver,processor,finalizer - local namespace = plugin.namespace - if namespace.enabled ~= false then -- this test will go away - starttiming(attributes) -- in principle we could delegate this to the main caller +-- local function process_attribute(head,plugin) -- head,attribute,enabled,initializer,resolver,processor,finalizer +-- local namespace = plugin.namespace +-- if namespace.enabled ~= false then -- this test will go away +-- starttiming(attributes) -- in principle we could delegate this to the main caller +-- local done, used, ok = false, nil, false +-- local attribute = namespace.attribute or numbers[plugin.name] -- todo: plugin.attribute +-- local processor = plugin.processor +-- if processor then +-- local initializer = plugin.initializer +-- local resolver = plugin.resolver +-- local inheritance = (resolver and resolver()) or nil -- -0x7FFFFFFF -- we can best use nil and skip ! +-- if initializer then +-- initializer(namespace,attribute,head) +-- end +-- head, ok = processor(namespace,attribute,head,inheritance) +-- if ok then +-- local finalizer = plugin.finalizer +-- if finalizer then +-- head, ok, used = finalizer(namespace,attribute,head) +-- if used then +-- local flusher = plugin.flusher +-- if flusher then +-- head = flusher(namespace,attribute,head,used) +-- end +-- end +-- end +-- done = true +-- end +-- end +-- stoptiming(attributes) +-- return head, done +-- else +-- return head, false +-- end +-- end +-- +-- function nodes.installattributehandler(plugin) -- we need to avoid this nested function +-- return function(head) +-- return process_attribute(head,plugin) +-- end +-- end + +-- An experiment: lean and mean functions. It is not really faster but +-- with upcoming functionality it might make a difference, e.g. features +-- like 'casing' and 'italics' can be called a lot so there it makes sense. + +nodes.plugindata = nil + +local template = [[ +local plugin = nodes.plugindata +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming +local namespace = plugin.namespace +local attribute = namespace.attribute or attributes.numbers[plugin.name] +local processor = plugin.processor +local initializer = plugin.initializer +local resolver = plugin.resolver +local finalizer = plugin.finalizer +local flusher = plugin.flusher +if not processor then + return function(head) + return head, false + end +elseif initializer or finalizer or resolver then + return function(head) + starttiming(attributes) local done, used, ok = false, nil, false - local attribute = namespace.attribute or numbers[plugin.name] -- todo: plugin.attribute - local processor = plugin.processor - if processor then - local initializer = plugin.initializer - local resolver = plugin.resolver - local inheritance = (resolver and resolver()) or nil -- -0x7FFFFFFF -- we can best use nil and skip ! - if initializer then - initializer(namespace,attribute,head) - end - head, ok = processor(namespace,attribute,head,inheritance) - if ok then - local finalizer = plugin.finalizer - if finalizer then - head, ok, used = finalizer(namespace,attribute,head) - if used then - local flusher = plugin.flusher - if flusher then - head = flusher(namespace,attribute,head,used) - end - end + local inheritance = (resolver and resolver()) or nil -- -0x7FFFFFFF -- we can best use nil and skip ! + if initializer then + initializer(namespace,attribute,head) + end + head, ok = processor(namespace,attribute,head,inheritance) + if ok then + if finalizer then + head, ok, used = finalizer(namespace,attribute,head) + if used and flusher then + head = flusher(namespace,attribute,head,used) end - done = true end + done = true end stoptiming(attributes) return head, done - else - return head, false end -end - --- nodes.process_attribute = process_attribute - -function nodes.installattributehandler(plugin) -- we need to avoid this nested function +else return function(head) - return process_attribute(head,plugin) + starttiming(attributes) + local head, done = processor(namespace,attribute,head) + stoptiming(attributes) + return head, done end end +nodes.plugindata = nil +]] ---~ experiment (maybe local to function makes more sense) ---~ ---~ plugindata = { } ---~ ---~ local template = [[ ---~ local plugin = plugindata["%s"] ---~ local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming ---~ local namespace = plugin.namespace ---~ local attribute = namespace.attribute ---~ local processor = plugin.processor ---~ local initializer = plugin.initializer ---~ local resolver = plugin.resolver ---~ local finalizer = plugin.finalizer ---~ local flusher = plugin.flusher ---~ return function (head) ---~ if namespace.enabled then ---~ starttiming(attributes) ---~ local done, used, ok = false, nil, false ---~ if procesxsor then ---~ local inheritance = (resolver and resolver()) or nil -- -0x7FFFFFFF -- we can best use nil and skip ! ---~ if initializer then ---~ initializer(namespace,attribute,head) ---~ end ---~ head, ok = processor(namespace,attribute,head,inheritance) ---~ if ok then ---~ if finalizer then ---~ head, ok, used = finalizer(namespace,attribute,head) ---~ if used and flusher then ---~ head = flusher(namespace,attribute,head,used) ---~ end ---~ end ---~ done = true ---~ end ---~ end ---~ stoptiming(attributes) ---~ return head, done ---~ else ---~ return head, false ---~ end ---~ end ---~ ]] ---~ ---~ function nodes.installattributehandler(plugin) -- we need to avoid this nested function ---~ plugindata[plugin.name] = plugin ---~ local str = format(template,plugin.name) ---~ return loadstring(str)() ---~ end +function nodes.installattributehandler(plugin) + nodes.plugindata = plugin + return loadstripped(template)() +end -- the injectors @@ -299,85 +307,318 @@ end -- return head, done -- end -local function process(namespace,attribute,head,inheritance,default) -- one attribute - local stack, done = head, false +-- local function process(namespace,attribute,head,inheritance,default) -- one attribute +-- local stack, done = head, false - local function check() - local c = stack[attribute] - if c then - if default and c == inheritance then - if current ~= default then - head = insert_node_before(head,stack,copy_node(nsdata[default])) - current = default - done = true - end - elseif current ~= c then - head = insert_node_before(head,stack,copy_node(nsdata[c])) - current = c - done = true - end - elseif default and inheritance then - if current ~= default then - head = insert_node_before(head,stack,copy_node(nsdata[default])) - current = default - done = true - end - elseif current > 0 then - head = insert_node_before(head,stack,copy_node(nsnone)) - current = 0 - done = true - end - return c - end +-- local function check() +-- local c = stack[attribute] +-- if c then +-- if default and c == inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- done = true +-- end +-- elseif current ~= c then +-- head = insert_node_before(head,stack,copy_node(nsdata[c])) +-- current = c +-- done = true +-- end +-- elseif default and inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- done = true +-- end +-- elseif current > 0 then +-- head = insert_node_before(head,stack,copy_node(nsnone)) +-- current = 0 +-- done = true +-- end +-- return c +-- end - local function nested(content) - if nstrigger and stack[nstrigger] then - local outer = stack[attribute] - if outer ~= inheritance then - return process(namespace,attribute,content,inheritance,outer) - else - return process(namespace,attribute,content,inheritance,default) - end - else - return process(namespace,attribute,content,inheritance,default) - end - end +-- local function nested(content) +-- if nstrigger and stack[nstrigger] then +-- local outer = stack[attribute] +-- if outer ~= inheritance then +-- return process(namespace,attribute,content,inheritance,outer) +-- else +-- return process(namespace,attribute,content,inheritance,default) +-- end +-- else +-- return process(namespace,attribute,content,inheritance,default) +-- end +-- end + +-- while stack do +-- local id = stack.id +-- if id == glyph_code then +-- check() +-- elseif id == glue_code then +-- local content = stack.leader +-- if content and check() then +-- local savedcurrent = current +-- local ci = content.id +-- if ci == hlist_code or ci == vlist_code then +-- -- else we reset inside a box unneeded, okay, the downside is +-- -- that we trigger color in each repeated box, so there is room +-- -- for improvement here +-- current = 0 +-- end + +-- local ok = false +-- stack.leader, ok = nested(content) +-- done = done or ok + +-- current = savedcurrent +-- end +-- elseif id == hlist_code or id == vlist_code then +-- local content = stack.list +-- if content then + +-- local ok = false +-- stack.list, ok = nested(content) +-- done = done or ok + +-- end +-- elseif id == rule_code then +-- if stack.width ~= 0 then +-- check() +-- end +-- end +-- stack = stack.next +-- end +-- return head, done +-- end + +-- local function process(namespace,attribute,head,inheritance,default) -- one attribute +-- local stack, done = head, false +-- while stack do +-- local id = stack.id +-- if id == glyph_code then +-- -- begin of check +-- local c = stack[attribute] +-- if c then +-- if default and c == inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- done = true +-- end +-- elseif current ~= c then +-- head = insert_node_before(head,stack,copy_node(nsdata[c])) +-- current = c +-- done = true +-- end +-- elseif default and inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- done = true +-- end +-- elseif current > 0 then +-- head = insert_node_before(head,stack,copy_node(nsnone)) +-- current = 0 +-- done = true +-- end +-- -- end of check +-- elseif id == glue_code then +-- local content = stack.leader +-- if content then +-- -- begin of check +-- local c = stack[attribute] +-- if c then +-- if default and c == inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- done = true +-- end +-- elseif current ~= c then +-- head = insert_node_before(head,stack,copy_node(nsdata[c])) +-- current = c +-- done = true +-- end +-- -- begin special to this check +-- local savedcurrent = current +-- local ci = content.id +-- if ci == hlist_code or ci == vlist_code then +-- -- else we reset inside a box unneeded, okay, the downside is +-- -- that we trigger color in each repeated box, so there is room +-- -- for improvement here +-- current = 0 +-- end +-- -- begin nested -- +-- local ok = false +-- if nstrigger and stack[nstrigger] then +-- local outer = stack[attribute] +-- if outer ~= inheritance then +-- stack.leader, ok = process(namespace,attribute,content,inheritance,outer) +-- else +-- stack.leader, ok = process(namespace,attribute,content,inheritance,default) +-- end +-- else +-- stack.leader, ok = process(namespace,attribute,content,inheritance,default) +-- end +-- -- end nested -- +-- done = done or ok +-- current = savedcurrent +-- -- end special to this check +-- elseif default and inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- done = true +-- end +-- elseif current > 0 then +-- head = insert_node_before(head,stack,copy_node(nsnone)) +-- current = 0 +-- done = true +-- end +-- -- end of check +-- end +-- elseif id == hlist_code or id == vlist_code then +-- local content = stack.list +-- if content then +-- -- begin nested -- +-- local ok +-- if nstrigger and stack[nstrigger] then +-- local outer = stack[attribute] +-- if outer ~= inheritance then +-- stack.list, ok = process(namespace,attribute,content,inheritance,outer) +-- else +-- stack.list, ok = process(namespace,attribute,content,inheritance,default) +-- end +-- else +-- stack.list, ok = process(namespace,attribute,content,inheritance,default) +-- end +-- -- end nested -- +-- done = done or ok +-- end +-- elseif id == rule_code then +-- if stack.width ~= 0 then +-- -- begin of check +-- local c = stack[attribute] +-- if c then +-- if default and c == inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- done = true +-- end +-- elseif current ~= c then +-- head = insert_node_before(head,stack,copy_node(nsdata[c])) +-- current = c +-- done = true +-- end +-- elseif default and inheritance then +-- if current ~= default then +-- head = insert_node_before(head,stack,copy_node(nsdata[default])) +-- current = default +-- done = true +-- end +-- elseif current > 0 then +-- head = insert_node_before(head,stack,copy_node(nsnone)) +-- current = 0 +-- done = true +-- end +-- -- end of check +-- end +-- end +-- stack = stack.next +-- end +-- return head, done +-- end +local function process(namespace,attribute,head,inheritance,default) -- one attribute + local stack = head + local done = false + local check = false + local leader = nil while stack do local id = stack.id if id == glyph_code then - check() + check = true elseif id == glue_code then - local content = stack.leader - if content and check() then - local savedcurrent = current - local ci = content.id - if ci == hlist_code or ci == vlist_code then - -- else we reset inside a box unneeded, okay, the downside is - -- that we trigger color in each repeated box, so there is room - -- for improvement here - current = 0 - end - - local ok = false - stack.leader, ok = nested(content) - done = done or ok - - current = savedcurrent + leader = stack.leader + if leader then + check = true end elseif id == hlist_code or id == vlist_code then local content = stack.list if content then - - local ok = false - stack.list, ok = nested(content) + -- begin nested -- + local ok + if nstrigger and stack[nstrigger] then + local outer = stack[attribute] + if outer ~= inheritance then + stack.list, ok = process(namespace,attribute,content,inheritance,outer) + else + stack.list, ok = process(namespace,attribute,content,inheritance,default) + end + else + stack.list, ok = process(namespace,attribute,content,inheritance,default) + end + -- end nested -- done = done or ok - end elseif id == rule_code then - if stack.width ~= 0 then - check() + check = stack.width ~= 0 + end + -- much faster this way than using a check() and nested() function + if check then + local c = stack[attribute] + if c then + if default and c == inheritance then + if current ~= default then + head = insert_node_before(head,stack,copy_node(nsdata[default])) + current = default + done = true + end + elseif current ~= c then + head = insert_node_before(head,stack,copy_node(nsdata[c])) + current = c + done = true + end + if leader then + local savedcurrent = current + local ci = leader.id + if ci == hlist_code or ci == vlist_code then + -- else we reset inside a box unneeded, okay, the downside is + -- that we trigger color in each repeated box, so there is room + -- for improvement here + current = 0 + end + -- begin nested -- + local ok = false + if nstrigger and stack[nstrigger] then + local outer = stack[attribute] + if outer ~= inheritance then + stack.leader, ok = process(namespace,attribute,leader,inheritance,outer) + else + stack.leader, ok = process(namespace,attribute,leader,inheritance,default) + end + else + stack.leader, ok = process(namespace,attribute,leader,inheritance,default) + end + -- end nested -- + done = done or ok + current = savedcurrent + leader = false + end + elseif default and inheritance then + if current ~= default then + head = insert_node_before(head,stack,copy_node(nsdata[default])) + current = default + done = true + end + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + current = 0 + done = true end + check = false end stack = stack.next end @@ -479,100 +720,184 @@ states.process = process -- return head, done -- end -local function selective(namespace,attribute,head,inheritance,default) -- two attributes - local stack, done = head, false +-- local function selective(namespace,attribute,head,inheritance,default) -- two attributes +-- local stack, done = head, false - local function check() - local c = stack[attribute] - if c then - if default and c == inheritance then - if current ~= default then - local data = nsdata[default] - head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) - current = default - done = true - end - else - local s = stack[nsselector] - if current ~= c or current_selector ~= s then - local data = nsdata[c] - head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) - current = c - current_selector = s - done = true - end - end - elseif default and inheritance then - if current ~= default then - local data = nsdata[default] - head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) - current = default - done = true - end - elseif current > 0 then - head = insert_node_before(head,stack,copy_node(nsnone)) - current, current_selector, done = 0, 0, true - end - return c - end +-- local function check() +-- local c = stack[attribute] +-- if c then +-- if default and c == inheritance then +-- if current ~= default then +-- local data = nsdata[default] +-- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) +-- current = default +-- done = true +-- end +-- else +-- local s = stack[nsselector] +-- if current ~= c or current_selector ~= s then +-- local data = nsdata[c] +-- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) +-- current = c +-- current_selector = s +-- done = true +-- end +-- end +-- elseif default and inheritance then +-- if current ~= default then +-- local data = nsdata[default] +-- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) +-- current = default +-- done = true +-- end +-- elseif current > 0 then +-- head = insert_node_before(head,stack,copy_node(nsnone)) +-- current, current_selector, done = 0, 0, true +-- end +-- return c +-- end - local function nested(content) - if nstrigger and stack[nstrigger] then - local outer = stack[attribute] - if outer ~= inheritance then - return selective(namespace,attribute,content,inheritance,outer) - else - return selective(namespace,attribute,content,inheritance,default) - end - else - return selective(namespace,attribute,content,inheritance,default) - end - end +-- local function nested(content) +-- if nstrigger and stack[nstrigger] then +-- local outer = stack[attribute] +-- if outer ~= inheritance then +-- return selective(namespace,attribute,content,inheritance,outer) +-- else +-- return selective(namespace,attribute,content,inheritance,default) +-- end +-- else +-- return selective(namespace,attribute,content,inheritance,default) +-- end +-- end +-- while stack do +-- local id = stack.id +-- if id == glyph_code then +-- check() +-- elseif id == glue_code then +-- local content = stack.leader +-- if content and check() then +-- -- local savedcurrent = current +-- -- local ci = content.id +-- -- if ci == hlist_code or ci == vlist_code then +-- -- -- else we reset inside a box unneeded, okay, the downside is +-- -- -- that we trigger color in each repeated box, so there is room +-- -- -- for improvement here +-- -- current = 0 +-- -- end + +-- local ok = false +-- stack.leader, ok = nested(content) +-- done = done or ok + +-- -- current = savedcurrent +-- end +-- elseif id == hlist_code or id == vlist_code then +-- local content = stack.list +-- if content then + +-- local ok = false +-- stack.list, ok = nested(content) +-- done = done or ok + +-- end +-- elseif id == rule_code then +-- if stack.width ~= 0 then +-- check() +-- end +-- end +-- stack = stack.next +-- end +-- return head, done +-- end + +local function selective(namespace,attribute,head,inheritance,default) -- two attributes + local stack = head + local done = false + local check = false + local leader = nil while stack do local id = stack.id if id == glyph_code then - check() + check = true elseif id == glue_code then - local content = stack.leader - if content and check() then - local savedcurrent = current - local ci = content.id - if ci == hlist_code or ci == vlist_code then - -- else we reset inside a box unneeded, okay, the downside is - -- that we trigger color in each repeated box, so there is room - -- for improvement here - current = 0 - end - - local ok = false - stack.leader, ok = nested(content) - done = done or ok - - current = savedcurrent + leader = stack.leader + if leader then + check = true end elseif id == hlist_code or id == vlist_code then local content = stack.list if content then - local ok = false - stack.list, ok = nested(content) + -- begin nested + if nstrigger and stack[nstrigger] then + local outer = stack[attribute] + if outer ~= inheritance then + stack.list, ok = selective(namespace,attribute,content,inheritance,outer) + else + stack.list, ok = selective(namespace,attribute,content,inheritance,default) + end + else + stack.list, ok = selective(namespace,attribute,content,inheritance,default) + end + -- end nested done = done or ok - - -- nicer: - -- - -- local content, ok = nested(content) - -- if ok then - -- stack.leader = content - -- done = true - -- end - end elseif id == rule_code then - if stack.width ~= 0 then - check() + check = stack.width ~= 0 + end + + if check then + local c = stack[attribute] + if c then + if default and c == inheritance then + if current ~= default then + local data = nsdata[default] + head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) + current = default + done = true + end + else + local s = stack[nsselector] + if current ~= c or current_selector ~= s then + local data = nsdata[c] + head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) + current = c + current_selector = s + done = true + end + end + if leader then + local ok = false + -- begin nested + if nstrigger and stack[nstrigger] then + local outer = stack[attribute] + if outer ~= inheritance then + stack.leader, ok = selective(namespace,attribute,leader,inheritance,outer) + else + stack.leader, ok = selective(namespace,attribute,leader,inheritance,default) + end + else + stack.leader, ok = selective(namespace,attribute,leader,inheritance,default) + end + -- end nested + done = done or ok + leader = false + end + elseif default and inheritance then + if current ~= default then + local data = nsdata[default] + head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector])) + current = default + done = true + end + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + current, current_selector, done = 0, 0, true end + check = false end + stack = stack.next end return head, done @@ -589,38 +914,92 @@ states.selective = selective -- Todo: make a better stacker. Keep track (in attribute) about nesting level. Not -- entirely trivial and a generic solution is nicer (compares to the exporter). -local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise - local stack, done = head, false - local current, depth = default or 0, 0 - - local function check() - local a = stack[attribute] - if a then - if current ~= a then - head = insert_node_before(head,stack,copy_node(nsdata[a])) - depth = depth + 1 - current, done = a, true - end - elseif default > 0 then - -- - elseif current > 0 then - head = insert_node_before(head,stack,copy_node(nsnone)) - depth = depth - 1 - current, done = 0, true - end - return a - end +-- local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise +-- local stack, done = head, false +-- local current, depth = default or 0, 0 +-- +-- local function check() +-- local a = stack[attribute] +-- if a then +-- if current ~= a then +-- head = insert_node_before(head,stack,copy_node(nsdata[a])) +-- depth = depth + 1 +-- current, done = a, true +-- end +-- elseif default > 0 then +-- -- +-- elseif current > 0 then +-- head = insert_node_before(head,stack,copy_node(nsnone)) +-- depth = depth - 1 +-- current, done = 0, true +-- end +-- return a +-- end +-- +-- while stack do +-- local id = stack.id +-- if id == glyph_code then +-- check() +-- elseif id == glue_code then +-- local content = stack.leader +-- if content and check() then +-- local ok = false +-- stack.leader, ok = stacked(namespace,attribute,content,current) +-- done = done or ok +-- end +-- elseif id == hlist_code or id == vlist_code then +-- local content = stack.list +-- if content then +-- -- the problem is that broken lines gets the attribute which can be a later one +-- if nslistwise then +-- local a = stack[attribute] +-- if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below +-- local p = current +-- current, done = a, true +-- head = insert_node_before(head,stack,copy_node(nsdata[a])) +-- stack.list = stacked(namespace,attribute,content,current) +-- head, stack = insert_node_after(head,stack,copy_node(nsnone)) +-- current = p +-- else +-- local ok = false +-- stack.list, ok = stacked(namespace,attribute,content,current) +-- done = done or ok +-- end +-- else +-- local ok = false +-- stack.list, ok = stacked(namespace,attribute,content,current) +-- done = done or ok +-- end +-- end +-- elseif id == rule_code then +-- if stack.width ~= 0 then +-- check() +-- end +-- end +-- stack = stack.next +-- end +-- while depth > 0 do +-- head = insert_node_after(head,stack,copy_node(nsnone)) +-- depth = depth - 1 +-- end +-- return head, done +-- end +local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise + local stack = head + local done = false + local current = default or 0 + local depth = 0 + local check = false + local leader = false while stack do local id = stack.id if id == glyph_code then - check() + check = true elseif id == glue_code then - local content = stack.leader - if content and check() then - local ok = false - stack.leader, ok = stacked(namespace,attribute,content,current) - done = done or ok + leader = stack.leader + if leader then + check = true end elseif id == hlist_code or id == vlist_code then local content = stack.list @@ -647,10 +1026,33 @@ local function stacked(namespace,attribute,head,default) -- no triggering, no in end end elseif id == rule_code then - if stack.width ~= 0 then - check() + check = stack.width ~= 0 + end + + if check then + local a = stack[attribute] + if a then + if current ~= a then + head = insert_node_before(head,stack,copy_node(nsdata[a])) + depth = depth + 1 + current, done = a, true + end + if leader then + local ok = false + stack.leader, ok = stacked(namespace,attribute,content,current) + done = done or ok + leader = false + end + elseif default > 0 then + -- + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + depth = depth - 1 + current, done = 0, true end + check = false end + stack = stack.next end while depth > 0 do @@ -664,35 +1066,93 @@ states.stacked = stacked -- experimental +-- local function stacker(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise +-- nsbegin() +-- local current, previous, done, okay = head, head, false, false +-- local attrib = default or unsetvalue +-- +-- local function check() +-- local a = current[attribute] or unsetvalue +-- if a ~= attrib then +-- local n = nsstep(a) +-- if n then +-- -- !!!! TEST CODE !!!! +-- -- head = insert_node_before(head,current,copy_node(nsdata[tonumber(n)])) -- a +-- head = insert_node_before(head,current,n) -- a +-- end +-- attrib, done, okay = a, true, true +-- end +-- return a +-- end +-- +-- while current do +-- local id = current.id +-- if id == glyph_code then +-- check() +-- elseif id == glue_code then +-- local content = current.leader +-- if content and check() then +-- -- tricky as a leader has to be a list so we cannot inject before +-- local _, ok = stacker(namespace,attribute,content,attrib) +-- done = done or ok +-- end +-- elseif id == hlist_code or id == vlist_code then +-- local content = current.list +-- if not content then +-- -- skip +-- elseif nslistwise then +-- local a = current[attribute] +-- if a and attrib ~= a and nslistwise[a] then -- viewerlayer +-- done = true +-- head = insert_node_before(head,current,copy_node(nsdata[a])) +-- current.list = stacker(namespace,attribute,content,a) +-- head, current = insert_node_after(head,current,copy_node(nsnone)) +-- else +-- local ok = false +-- current.list, ok = stacker(namespace,attribute,content,attrib) +-- done = done or ok +-- end +-- else +-- local ok = false +-- current.list, ok = stacker(namespace,attribute,content,default) +-- done = done or ok +-- end +-- elseif id == rule_code then +-- if current.width ~= 0 then +-- check() +-- end +-- end +-- previous = current +-- current = current.next +-- end +-- if okay then +-- local n = nsend() +-- if n then +-- -- !!!! TEST CODE !!!! +-- -- head = insert_node_after(head,previous,copy_node(nsdata[tostring(n)])) +-- head = insert_node_after(head,previous,n) +-- end +-- end +-- return head, done +-- end + local function stacker(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise nsbegin() - local current, previous, done, okay = head, head, false, false - local attrib = default or unsetvalue - - local function check() - local a = current[attribute] or unsetvalue - if a ~= attrib then - local n = nsstep(a) - if n then - -- !!!! TEST CODE !!!! --- head = insert_node_before(head,current,copy_node(nsdata[tonumber(n)])) -- a - head = insert_node_before(head,current,n) -- a - end - attrib, done, okay = a, true, true - end - return a - end - + local current = head + local previous = head + local done = false + local okay = false + local attrib = default or unsetvalue + local check = false + local leader = false while current do local id = current.id if id == glyph_code then - check() + check = true elseif id == glue_code then - local content = current.leader - if content and check() then - -- tricky as a leader has to be a list so we cannot inject before - local _, ok = stacker(namespace,attribute,content,attrib) - done = done or ok + leader = current.leader + if leader then + check = true end elseif id == hlist_code or id == vlist_code then local content = current.list @@ -716,10 +1176,29 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in done = done or ok end elseif id == rule_code then - if current.width ~= 0 then - check() + check = current.width ~= 0 + end + + if check then + local a = current[attribute] or unsetvalue + if a ~= attrib then + local n = nsstep(a) + if n then + -- !!!! TEST CODE !!!! + -- head = insert_node_before(head,current,copy_node(nsdata[tonumber(n)])) -- a + head = insert_node_before(head,current,n) -- a + end + attrib, done, okay = a, true, true + if leader then + -- tricky as a leader has to be a list so we cannot inject before + local _, ok = stacker(namespace,attribute,leader,attrib) + done = done or ok + leader = false + end end + check = false end + previous = current current = current.next end @@ -727,7 +1206,7 @@ local function stacker(namespace,attribute,head,default) -- no triggering, no in local n = nsend() if n then -- !!!! TEST CODE !!!! --- head = insert_node_after(head,previous,copy_node(nsdata[tostring(n)])) + -- head = insert_node_after(head,previous,copy_node(nsdata[tostring(n)])) head = insert_node_after(head,previous,n) end end diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua index 530659eaa..946b07ee5 100644 --- a/tex/context/base/node-fnt.lua +++ b/tex/context/base/node-fnt.lua @@ -97,7 +97,7 @@ function handlers.characters(head) end -- todo: time a while and skip over or make a special traverse_id that skips over math for n in traverse_id(glyph_code,head) do --- if n.subtype<256 then -- all are 1 + -- if n.subtype<256 then -- all are 1 local font = n.font local attr = n[0] or 0 -- zero attribute is reserved for fonts in context if font ~= prevfont or attr ~= prevattr then @@ -134,7 +134,7 @@ function handlers.characters(head) prevfont = font prevattr = attr end --- end + -- end end if trace_fontrun then report_fonts() @@ -142,8 +142,9 @@ function handlers.characters(head) report_fonts("dynamics: %s",(a > 0 and concat(keys(attrfonts)," ")) or "none") report_fonts() end - -- we could combine these and just make the attribute nil - if u == 1 then + if u == 0 then + -- skip + elseif u == 1 then local font, processors = next(usedfonts) local n = #processors if n > 0 then @@ -158,7 +159,7 @@ function handlers.characters(head) end end end - elseif u > 0 then + else for font, processors in next, usedfonts do local n = #processors local h, d = processors[1](head,font,0) @@ -173,7 +174,9 @@ function handlers.characters(head) end end end - if a == 1 then + if a == 0 then + -- skip + elseif a == 1 then local font, dynamics = next(attrfonts) for attribute, processors in next, dynamics do -- attr can switch in between local n = #processors @@ -192,7 +195,7 @@ function handlers.characters(head) end end end - elseif a > 0 then + else for font, dynamics in next, attrfonts do for attribute, processors in next, dynamics do -- attr can switch in between local n = #processors diff --git a/tex/context/base/node-inj.lua b/tex/context/base/node-inj.lua index acaf9407a..3e1687426 100644 --- a/tex/context/base/node-inj.lua +++ b/tex/context/base/node-inj.lua @@ -108,12 +108,12 @@ end function injections.setmark(start,base,factor,rlmode,ba,ma,index) -- ba=baseanchor, ma=markanchor local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) -- the index argument is no longer used but when this local bound = base[a_markbase] -- fails again we should pass it -local index = 1 + local index = 1 if bound then local mb = marks[bound] if mb then -- if not index then index = #mb + 1 end -index = #mb + 1 + index = #mb + 1 mb[index] = { dx, dy, rlmode } start[a_markmark] = bound start[a_markdone] = index diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua index 05e365979..09e066434 100644 --- a/tex/context/base/node-ref.lua +++ b/tex/context/base/node-ref.lua @@ -72,24 +72,24 @@ local traverse = node.traverse local find_node_tail = node.tail or node.slide local tosequence = nodes.tosequence -local function dimensions(parent,start,stop) - stop = stop and stop.next - if parent then - if stop then - return list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,start,stop) - else - return list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,start) - end - else - if stop then - return list_dimensions(start,stop) - else - return list_dimensions(start) - end - end -end - ---~ more compact +-- local function dimensions(parent,start,stop) +-- stop = stop and stop.next +-- if parent then +-- if stop then +-- return list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,start,stop) +-- else +-- return list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,start) +-- end +-- else +-- if stop then +-- return list_dimensions(start,stop) +-- else +-- return list_dimensions(start) +-- end +-- end +-- end +-- +-- -- more compact local function dimensions(parent,start,stop) if parent then @@ -204,65 +204,6 @@ end -- skip is somewhat messy --- local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main --- if head then --- local current, first, last, firstdir, reference = head, nil, nil, nil, nil --- pardir = pardir or "===" --- txtdir = txtdir or "===" --- while current do --- local id = current.id --- local r = current[attribute] --- if id == hlist_code or id == vlist_code then --- -- somehow reference is true so the following fails (second one not done) in --- -- test \goto{test}[page(2)] test \gotobox{test}[page(2)] --- -- so let's wait till this fails again --- -- if not reference and r and (not skip or r > skip) then -- > or ~= --- if r and (not skip or r > skip) then -- > or ~= --- inject_list(id,current,r,make,stack,pardir,txtdir) --- end --- if r then --- done[r] = (done[r] or 0) + 1 --- end --- local list = current.list --- if list then --- local _ --- current.list, _, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir) --- end --- if r then --- done[r] = done[r] - 1 --- end --- elseif id == whatsit_code then --- local subtype = current.subtype --- if subtype == localpar_code then --- pardir = current.dir --- elseif subtype == dir_code then --- txtdir = current.dir --- end --- elseif id == glue_code and current.subtype == leftskip_code then -- any glue at the left? --- -- --- elseif not r then --- -- just go on, can be kerns --- elseif not reference then --- reference, first, last, firstdir = r, current, current, txtdir --- elseif r == reference then --- last = current --- elseif (done[reference] or 0) == 0 then -- or id == glue_code and current.subtype == right_skip_code --- if not skip or r > skip then -- maybe no > test --- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) --- reference, first, last, firstdir = nil, nil, nil, nil --- end --- else --- reference, first, last, firstdir = r, current, current, txtdir --- end --- current = current.next --- end --- if reference and (done[reference] or 0) == 0 then --- head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) --- end --- end --- return head, true, pardir, txtdir --- end - local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main if head then local current, first, last, firstdir, reference = head, nil, nil, nil, nil @@ -325,37 +266,6 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx return head, true, pardir, txtdir end --- local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) -- singular ! --- if head then --- pardir = pardir or "===" --- txtdir = txtdir or "===" --- local current = head --- while current do --- local id = current.id --- local r = current[attribute] --- if id == hlist_code or id == vlist_code then --- if r and not done[r] then --- done[r] = true --- inject_list(id,current,r,make,stack,pardir,txtdir) --- end --- current.list = inject_area(current.list,attribute,make,stack,done,current,pardir,txtdir) --- elseif id == whatsit_code then --- local subtype = current.subtype --- if subtype == localpar_code then --- pardir = current.dir --- elseif subtype == dir_code then --- txtdir = current.dir --- end --- elseif r and not done[r] then --- done[r] = true --- head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir) --- end --- current = current.next --- end --- end --- return head, true --- end - local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) -- singular ! if head then pardir = pardir or "===" diff --git a/tex/context/base/spac-chr.lua b/tex/context/base/spac-chr.lua index f7a4e32ec..2502b1992 100644 --- a/tex/context/base/spac-chr.lua +++ b/tex/context/base/spac-chr.lua @@ -178,9 +178,9 @@ function characters.handler(head) local current = head local done = false while current do - local next = current.next local id = current.id if id == glyph_code then + local next = current.next local char = current.char local method = methods[char] if method then @@ -191,8 +191,10 @@ function characters.handler(head) head = remove_node(head,current,true) done = true end + current = next + else + current = current.next end - current = next end return head, done end diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index cb38a4d66..7d030ab1a 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -177,16 +177,16 @@ function vspacing.definesnapmethod(name,method) context(n) end ---~ local rule_id = nodecodes.rule ---~ local vlist_id = nodecodes.vlist ---~ function nodes.makevtop(n) ---~ if n.id == vlist_id then ---~ local list = n.list ---~ local height = (list and list.id <= rule_id and list.height) or 0 ---~ n.depth = n.depth - height + n.height ---~ n.height = height ---~ end ---~ end +-- local rule_id = nodecodes.rule +-- local vlist_id = nodecodes.vlist +-- function nodes.makevtop(n) +-- if n.id == vlist_id then +-- local list = n.list +-- local height = (list and list.id <= rule_id and list.height) or 0 +-- n.depth = n.depth - height + n.height +-- n.height = height +-- end +-- end local reference = nodes.reference diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 4c889c2da..2ba67a882 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 2c2d5e0ed..c94f04130 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index b38608966..284418c48 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -1768,6 +1768,11 @@ function references.filterdefault() return references.filter("default",getcurrentprefixspec(v_default)) end +function commands.currentreferencedefault(tag) + if not tag then tag = "default" end + references.filter(tag,context.delayed(getcurrentprefixspec(tag))) +end + filters.generic = { } function filters.generic.title(data) diff --git a/tex/context/base/strc-ref.mkvi b/tex/context/base/strc-ref.mkvi index 3a357f342..26f389294 100644 --- a/tex/context/base/strc-ref.mkvi +++ b/tex/context/base/strc-ref.mkvi @@ -1805,8 +1805,16 @@ \csname \??referencingprefix:#category#parameter\endcsname \fi\fi\fi} +% \def\currentreferencedefault +% {\ctxcommand{filterdefaultreference()}} + \def\currentreferencedefault - {\ctxcommand{filterdefaultreference()}} + {\ctxcommand{filterreference("\s!default",\ctxcommand{getcurrentprefixspec("\s!default")})}} + +% needs testing +% +% \def\currentreferencedefault +% {\ctxcommand{currentreferencedefault()}} %D Not all support is visible by looking at the \TEX\ code; here is one of those:^ %D diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index 292db8a08..7f5603353 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -37,17 +37,15 @@ appendaction("processors", "fonts", "builders.paragraphs.solutions.split appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo appendaction("processors", "fonts", "nodes.injections.handler") -- maybe todo appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nohead") -- maybe todo -appendaction("processors", "fonts", "builders.kernel.ligaturing") -- always on -appendaction("processors", "fonts", "builders.kernel.kerning") -- always on +appendaction("processors", "fonts", "builders.kernel.ligaturing") -- always on (could be selective: if only node mode) +appendaction("processors", "fonts", "builders.kernel.kerning") -- always on (could be selective: if only node mode) appendaction("processors", "fonts", "nodes.handlers.stripping") -- disabled (might move) +------------("processors", "fonts", "typesetters.italics.handler") -- disabled (after otf/kern handling) appendaction("processors", "lists", "typesetters.spacings.handler") -- disabled appendaction("processors", "lists", "typesetters.kerns.handler") -- disabled appendaction("processors", "lists", "typesetters.digits.handler") -- disabled (after otf handling) appendaction("processors", "lists", "typesetters.italics.handler") -- disabled (after otf/kern handling) - --- appendaction("processors", "fonts", "typesetters.italics.handler") -- disabled (after otf/kern handling) - appendaction("processors", "lists", "typesetters.paragraphs.handler") -- disabled appendaction("shipouts", "normalizers", "nodes.handlers.cleanuppage") -- disabled @@ -59,12 +57,10 @@ appendaction("shipouts", "normalizers", "nodes.shifts.handler") appendaction("shipouts", "normalizers", "structures.tags.handler") -- disabled appendaction("shipouts", "normalizers", "nodes.handlers.accessibility") -- disabled appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds") -- disabled -appendaction("shipouts", "normalizers", "nodes.handlers.alignbackgrounds") -- disabled - --- appendaction("shipouts", "normalizers", "nodes.handlers.export") -- disabled +appendaction("shipouts", "normalizers", "nodes.handlers.alignbackgrounds") -- disabled +------------("shipouts", "normalizers", "nodes.handlers.export") -- disabled appendaction("shipouts", "finishers", "nodes.visualizers.handler") -- disabled - appendaction("shipouts", "finishers", "attributes.colors.handler") -- disabled appendaction("shipouts", "finishers", "attributes.transparencies.handler") -- disabled appendaction("shipouts", "finishers", "attributes.colorintents.handler") -- disabled @@ -182,8 +178,8 @@ freezegroup("shipouts", "finishers") freezegroup("mvlbuilders", "normalizers") freezegroup("vboxbuilders", "normalizers") ---~ freezegroup("parbuilders", "lists") ---~ freezegroup("pagebuilders", "lists") +-----------("parbuilders", "lists") +-----------("pagebuilders", "lists") freezegroup("math", "normalizers") freezegroup("math", "builders") diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua index 39dc2b34d..1727bddca 100644 --- a/tex/context/base/trac-vis.lua +++ b/tex/context/base/trac-vis.lua @@ -150,30 +150,85 @@ local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_ local enabled = false local layers = { } +local preset_boxes = modes.hbox + modes.vbox +local preset_makeup = preset_boxes + modes.kern + modes.glue + modes.penalty +local preset_all = preset_makeup + modes.fontkern + modes.whatsit + modes.glyph + modes.user + function visualizers.setfont(id) usedfont = id or current_font() exheight = exheights[usedfont] emwidth = emwidths[usedfont] end +-- we can preset a bunch of bits + +local function enable() + if not usedfont then + -- we use a narrow monospaced font + visualizers.setfont(fonts.definers.define { name = "lmmonoltcond10regular", size = tex.sp("4pt") }) + end + for mode, value in next, modes do + local tag = formatters["v_%s"](mode) + attributes.viewerlayers.define { + tag = tag, + title = formatters["visualizer %s"](mode), + visible = "start", + editable = "yes", + printable = "yes" + } + layers[mode] = attributes.viewerlayers.register(tag,true) + end + l_hbox = layers.hbox + l_vbox = layers.vbox + l_vtop = layers.vtop + l_glue = layers.glue + l_kern = layers.kern + l_penalty = layers.penalty + l_fontkern = layers.fontkern + l_strut = layers.strut + l_whatsit = layers.whatsit + l_glyph = layers.glyph + l_user = layers.user + nodes.tasks.enableaction("shipouts","nodes.visualizers.handler") + report_visualize("enabled") + enabled = true + tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end +end + local function setvisual(n,a,what) -- this will become more efficient when we have the bit lib linked in + if not a then + a = 0 + end if not n or n == "reset" then return unsetvalue elseif n == "makeup" then - for i=1,#modes_makeup do - a = setvisual(modes_makeup[i],a) + if a == 0 then + a = preset_makeup + else + a = setbit(a,preset_makeup) + -- for i=1,#modes_makeup do + -- a = setvisual(modes_makeup[i],a) + -- end end elseif n == "boxes" then - for i=1,#modes_boxes do - a = setvisual(modes_boxes[i],a) + if a == 0 then + a = preset_boxes + else + a = setbit(a,preset_boxes) + -- for i=1,#modes_boxes do + -- a = setvisual(modes_boxes[i],a) + -- end end elseif n == "all" then if what == false then return unsetvalue + elseif a == 0 then + a = preset_all else - for i=1,#modes_all do - a = setvisual(modes_all[i],a) - end + a = setbit(a,preset_all) + -- for i=1,#modes_all do + -- a = setvisual(modes_all[i],a) + -- end end else local m = modes[n] @@ -182,10 +237,13 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha if what == false then return unsetvalue else - a = setbit(0,m) + -- a = setbit(0,m) + a = m end elseif what == false then a = clearbit(a,m) + elseif a == 0 then + a = m else a = setbit(a,m) end @@ -196,35 +254,7 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha if a == unsetvalue or a == 0 then return unsetvalue elseif not enabled then -- must happen at runtime (as we don't store layers yet) - if not usedfont then - -- we use a narrow monospaced font - visualizers.setfont(fonts.definers.define { name = "lmmonoltcond10regular", size = tex.sp("4pt") }) - end - for mode, value in next, modes do - local tag = formatters["v_%s"](mode) - attributes.viewerlayers.define { - tag = tag, - title = formatters["visualizer %s"](mode), - visible = "start", - editable = "yes", - printable = "yes" - } - layers[mode] = attributes.viewerlayers.register(tag,true) - end - l_hbox = layers.hbox - l_vbox = layers.vbox - l_vtop = layers.vtop - l_glue = layers.glue - l_kern = layers.kern - l_penalty = layers.penalty - l_fontkern = layers.fontkern - l_strut = layers.strut - l_whatsit = layers.whatsit - l_glyph = layers.glyph - l_user = layers.user - nodes.tasks.enableaction("shipouts","nodes.visualizers.handler") - report_visualize("enabled") - enabled = true + enable() end return a end @@ -241,7 +271,7 @@ commands.setvisual = visualizers.setvisual commands.setlayer = visualizers.setlayer function commands.visual(n) - context(setvisual(n,0)) + context(setvisual(n)) end local function set(mode,v) diff --git a/tex/context/base/trac-vis.mkiv b/tex/context/base/trac-vis.mkiv index f7559932c..4990913d7 100644 --- a/tex/context/base/trac-vis.mkiv +++ b/tex/context/base/trac-vis.mkiv @@ -36,6 +36,9 @@ \unprotect +\newconstant\c_syst_visualizers_state +\newtoks \t_syst_visualizers_optimize + \definesystemattribute[visual][public,global] %D We only provide box visualizers as they can come in handy for testing @@ -50,6 +53,27 @@ \unexpanded\def\ruledvtop{\syst_visualizers_vtop attr \visualattribute \ctxcommand{visual("simplevtop")} } % special case \unexpanded\def\ruledtopv{\syst_visualizers_vtop attr \visualattribute \ctxcommand{visual("vtop")} } +\appendtoks + \ifcase\c_syst_visualizers_state\else + \syst_visualizers_speedup + \fi +\to \everyshipout + +\appendtoks + \global\let\syst_visualizers_speedup\relax +\to \t_syst_visualizers_optimize + +\def\syst_visualizers_speedup{\the\t_syst_visualizers_optimize} + +\appendtoks + \normalexpanded {% + \unexpanded\xdef\ruledhbox\expandafter{\ruledhbox}% + \unexpanded\xdef\ruledvbox\expandafter{\ruledvbox}% + \unexpanded\xdef\ruledvtop\expandafter{\ruledvtop}% + \unexpanded\xdef\ruledtopv\expandafter{\ruledtopv}% + }% +\to \t_syst_visualizers_optimize + \unexpanded\def\showmakeup {\ctxcommand{setvisual("makeup")}% \let\normalvtop\ruledtopv @@ -110,10 +134,17 @@ % \def\spac_struts_vide_hbox % {\hbox attr \visualattribute \ctxcommand{visual("strut")} } +% +% \def\spac_struts_vide_hbox +% {\xdef\spac_struts_vide_hbox{\hbox attr \visualattribute \ctxcommand{visual("strut")} }% +% \spac_struts_vide_hbox} + +\unexpanded\def\spac_struts_vide_hbox + {\hbox attr \visualattribute \ctxcommand{visual("strut")} } -\def\spac_struts_vide_hbox - {\edef\spac_struts_vide_hbox{\hbox attr \visualattribute \ctxcommand{visual("strut")} }% - \spac_struts_vide_hbox} +\appendtoks + \normalexpanded{\unexpanded\xdef\spac_struts_vide_hbox\expandafter{\spac_struts_vide_hbox}}% +\to \t_syst_visualizers_optimize %D For manuals: diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 007e762f0..8d0a51e5f 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/18/13 18:49:25 +-- merge date : 03/19/13 14:27:10 do -- begin closure to overcome local limits and interference @@ -7581,11 +7581,11 @@ end function injections.setmark(start,base,factor,rlmode,ba,ma,index) local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) local bound=base[a_markbase] -local index=1 + local index=1 if bound then local mb=marks[bound] if mb then -index=#mb+1 + index=#mb+1 mb[index]={ dx,dy,rlmode } start[a_markmark]=bound start[a_markdone]=index @@ -9905,13 +9905,12 @@ function otf.dataset(tfmdata,font) } rs[language]=rl local sequences=tfmdata.resources.sequences - setmetatableindex(rl,function(t,k) - if type(k)=="number" then - local v=enabled and initialize(sequences[k],script,language,enabled) - t[k]=v - return v - end - end) +for s=1,#sequences do + local v=enabled and initialize(sequences[s],script,language,enabled) + if v then + rl[#rl+1]=v + end +end end return rl end @@ -9937,12 +9936,10 @@ local function featuresprocessor(head,font,attr) local done=false local datasets=otf.dataset(tfmdata,font,attr) local dirstack={} - for s=1,#sequences do - local dataset=datasets[s] - if dataset then - featurevalue=dataset[1] - if featurevalue then - local sequence=sequences[s] +for s=1,#datasets do + local dataset=datasets[s] + featurevalue=dataset[1] + local sequence=dataset[5] local rlparmode=0 local topstack=0 local success=false @@ -10024,8 +10021,8 @@ local function featuresprocessor(head,font,attr) else start=start.next end -elseif id==math_code then - start=endofmath(start).next + elseif id==math_code then + start=endofmath(start).next else start=start.next end @@ -10158,8 +10155,6 @@ elseif id==math_code then if trace_steps then registerstep(head) end - end - end end return head,done end -- cgit v1.2.3