From 72d161c0a522fd92f32edd3588fa126c453f4a3d Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Wed, 28 Dec 2016 18:36:04 +0100 Subject: 2016-12-28 18:01:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkiv/cont-new.mkiv | 2 +- tex/context/base/mkiv/context.mkiv | 2 +- tex/context/base/mkiv/lxml-css.lua | 721 ++++++++++++++++++++- tex/context/base/mkiv/lxml-lpt.lua | 30 +- tex/context/base/mkiv/lxml-tab.lua | 13 +- tex/context/base/mkiv/publ-dat.lua | 45 +- tex/context/base/mkiv/status-files.pdf | Bin 25587 -> 25595 bytes tex/context/base/mkiv/status-lua.pdf | Bin 369201 -> 369266 bytes tex/context/interface/mkiv/i-context.pdf | Bin 803602 -> 803598 bytes tex/context/interface/mkiv/i-readme.pdf | Bin 60766 -> 60767 bytes tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 13 files changed, 791 insertions(+), 28 deletions(-) (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 53fe67bc2..353d27e9f 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.12.21 18:51} +\newcontextversion{2016.12.28 17:55} %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/mkii/context.mkii b/tex/context/base/mkii/context.mkii index d022b1626..5e069a54d 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2016.12.21 18:51} +\edef\contextversion{2016.12.28 17:55} %D For those who want to use this: diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index d31d880f7..9057defc3 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.12.21 18:51} +\newcontextversion{2016.12.28 17:55} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 86722cf34..1cab20d40 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.12.21 18:51} +\edef\contextversion{2016.12.28 17:55} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/lxml-css.lua b/tex/context/base/mkiv/lxml-css.lua index fa921b24f..b2198f341 100644 --- a/tex/context/base/mkiv/lxml-css.lua +++ b/tex/context/base/mkiv/lxml-css.lua @@ -6,10 +6,12 @@ if not modules then modules = { } end modules ['lxml-css'] = { license = "see context related readme files" } -local tonumber, rawset = tonumber, rawset -local lower, format = string.lower, string.format -local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf +local tonumber, rawset, type = tonumber, rawset, type +local lower, format, find, gmatch = string.lower, string.format, string.find, string.gmatch +local topattern, is_empty = string.topattern, string.is_empty +local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf, lpeg.Cs local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns +local sort = table.sort xml.css = xml.css or { } local css = xml.css @@ -169,3 +171,716 @@ function css.colorspecification(str) local c = str and attributes.colors.values[tonumber(str)] return c and format("rgb(%s%%,%s%%,%s%%)",c[3]*100,c[4]*100,c[5]*100) end + +-- The following might be handy. It hooks into the normal parser as +-- and should work ok with the rest. It's sometimes even a bit faster but that might +-- change. It's somewhat optimized but not too aggressively. + +-- element-1 > element-2 : element-2 with parent element-1 + +local function s_element_a(list,collected,c,negate,str,dummy,dummy,n) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local ok = all or ll.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + if (not n or n > 1) and dt then + c = s_element_a(dt,collected,c,negate,str,dummy,dummy,n and n+1 or 1) + end + end + end + return c +end + +-- element-1 + element-2 : element-2 preceded by element-1 + +local function s_element_b(list,collected,c,negate,str) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local pp = ll.__p__ + if pp then + local dd = pp.dt + if dd then + local ni = ll.ni + local d = dd[ni+1] + local dt = d and d.dt + if not dt then + d = dd[ni+2] + dt = d and d.dt + end + if dt then + local ok = all or d.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = d + end + end + end + end + end + return c +end + +-- element-1 ~ element-2 : element-2 preceded by element-1 -- ? + +local function s_element_c(list,collected,c,negate,str) + local all = str == "*" + for l=1,#list do + local ll = list[l] + local pp = ll.__p__ + if pp then + local dt = pp.dt + if dt then + local ni = ll.ni + for i=ni+1,#dt do + local d = dt[i] + local dt = d.dt + if dt then + local ok = all or d.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = d + end + end + end + end + end + end + return c +end + +-- element +-- element-1 element-2 : element-2 inside element-1 + +local function s_element_d(list,collected,c,negate,str) + if str == "*" then + if not negate then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + if not ll.special then + c = c + 1 + collected[c] = ll + end + c = s_element_d(dt,collected,c,negate,str) + end + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + if not ll.special then + local ok = ll.tg == str + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + end + c = s_element_d(dt,collected,c,negate,str) + end + end + end + return c +end + +-- [attribute] +-- [attribute=value] equals +-- [attribute~=value] contains word +-- [attribute^="value"] starts with +-- [attribute$="value"] ends with +-- [attribute*="value"] contains + +-- .class (no need to optimize) +-- #id (no need to optimize) + +local function s_attribute(list,collected,c,negate,str,what,value) + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local at = ll.at + if at then + local v = at[str] + local ok = negate + if v then + if not what then + ok = not negate + elseif what == 1 then + if v == value then + ok = not negate + end + elseif what == 2 then + -- todo: lpeg + if find(v,value) then + ok = not negate + end + elseif what == 3 then + -- todo: lpeg + if find(v," ") then + for s in gmatch(v,"[^ ]+") do + if s == value then + ok = not negate + break + end + end + elseif v == value then + ok = not negate + end + end + end + if ok then + c = c + 1 + collected[c] = ll + end + end + c = s_attribute(dt,collected,c,negate,str,what,value) + end + end + return c +end + +-- :nth-child(n) +-- :nth-last-child(n) +-- :first-child +-- :last-child + +local function filter_down(collected,c,negate,dt,a,b) + local t = { } + local n = 0 + for i=1,#dt do + local d = dt[i] + if type(d) == "table" then + n = n + 1 + t[n] = i + end + end + if n == 0 then + return 0 + end + local m = a + while true do + if m > n then + break + end + if m > 0 then + t[m] = -t[m] -- sign signals match + end + m = m + b + end + if negate then + for i=n,1-1 do + local ti = t[i] + if ti > 0 then + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + else + for i=n,1,-1 do + local ti = t[i] + if ti < 0 then + ti = - ti + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + end + return c +end + +local function filter_up(collected,c,negate,dt,a,b) + local t = { } + local n = 0 + for i=1,#dt do + local d = dt[i] + if type(d) == "table" then + n = n + 1 + t[n] = i + end + end + if n == 0 then + return 0 + end + if not b then + b = 0 + end + local m = n - a + while true do + if m < 1 then + break + end + if m < n then + t[m] = -t[m] -- sign signals match + end + m = m - b + end + if negate then + for i=1,n do + local ti = t[i] + if ti > 0 then + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + else + for i=1,n do + local ti = t[i] + if ti < 0 then + ti = - ti + local di = dt[ti] + c = c + 1 + collected[c] = di + end + end + end + return c +end + +local function just(collected,c,negate,dt,a,start,stop,step) + local m = 0 + for i=start,stop,step do + local d = dt[i] + if type(d) == "table" then + m = m + 1 + if negate then + if a ~= m then + c = c + 1 + collected[c] = d + end + else + if a == m then + c = c + 1 + collected[c] = d + break + end + end + end + end + return c +end + +local function s_nth_child(list,collected,c,negate,a,n,b) + if n == "n" then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = filter_up(collected,c,negate,dt,a,b) + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = just(collected,c,negate,dt,a,1,#dt,1) + end + end + end + return c +end + +local function s_nth_last_child(list,collected,c,negate,a,n,b) + if n == "n" then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = filter_down(collected,c,negate,dt,a,b) + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + c = just(collected,c,negate,dt,a,#dt,1,-1) + end + end + end + return c +end + +-- :nth-of-type(n) +-- :nth-last-of-type(n) +-- :first-of-type +-- :last-of-type + +local function s_nth_of_type(list,collected,c,negate,a,n,b) + if n == "n" then + return filter_up(collected,c,negate,list,a,b) + else + return just(collected,c,negate,list,a,1,#list,1) + end +end + +local function s_nth_last_of_type(list,collected,c,negate,a,n,b) + if n == "n" then + return filter_down(collected,c,negate,list,a,b) + else + return just(collected,c,negate,list,a,#list,1,-1) + end +end + +-- :only-of-type + +local function s_only_of_type(list,collected,c,negate) + if negate then + for i=1,#list do + c = c + 1 + collected[c] = list[i] + end + else + if #list == 1 then + c = c + 1 + collected[c] = list[1] + end + end + return c +end + +-- :only-child + +local function s_only_child(list,collected,c,negate) + if negate then + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + for i=1,#dt do + local di = dt[i] + if type(di) == "table" then + c = c + 1 + collected[c] = di + end + end + end + end + else + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt and #dt == 1 then + local di = dt[1] + if type(di) == "table" then + c = c + 1 + collected[c] = di + end + end + end + end + return c +end + +-- :empty + +local function s_empty(list,collected,c,negate) + for l=1,#list do + local ll = list[l] + local dt = ll.dt + if dt then + local dn = #dt + local ok = dn == 0 + if not ok and dn == 1 then + local d = dt[1] + if type(d) == "string" and is_empty(d) then + ok = true + end + end + if negate then + ok = not ok + end + if ok then + c = c + 1 + collected[c] = ll + end + end + end + return c +end + +-- :root + +local function s_root(list,collected,c,negate) + for l=1,#list do + local ll = list[l] + if type(ll) == "table" then + local r = xml.root(ll) + if r then + if r.special and r.tg == "@rt@" then + r = r.dt[r.ri] + end + c = c + 1 + collected[c] = r + break + end + end + end + return c +end + +local P, R, S, C, Cs, Ct, Cc, Carg, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.Carg, lpeg.match + +local whitespace = lpegpatterns.whitespace +local p_number = lpegpatterns.integer / tonumber +local p_space = whitespace^0 + +local p_key = C((R("az","AZ","09") + S("_-"))^1) +local p_left = S("#.[],:()") +local p_right = S("#.[],:() ") +local p_tag = C((1-p_left) * (1-p_right)^0) +local p_value = C((1-P("]"))^0) +local p_unquoted = (P('"')/"") * C((1-P('"'))^0) * (P('"')/"") + + (1-P("]"))^1 +local p_element = Ct( ( + P(">") * p_space * Cc(s_element_a) + + P("+") * p_space * Cc(s_element_b) + + P("~") * p_space * Cc(s_element_c) + + Cc(s_element_d) + ) * p_tag ) +local p_attribute = P("[") * Ct(Cc(s_attribute) * p_key * ( + P("=" ) * Cc(1) * Cs( p_unquoted) + + P("^=") * Cc(2) * Cs(Cc("^") * (p_unquoted / topattern)) + + P("$=") * Cc(2) * Cs( p_unquoted / topattern * Cc("$")) + + P("*=") * Cc(2) * Cs( p_unquoted / topattern) + + P("~=") * Cc(3) * Cs( p_unquoted) + )^0 * P("]")) + +local p_separator = p_space * P(",") * p_space + +local p_formula = p_space * P("(") + * p_space + * ( + p_number * p_space * (C("n") * p_space * (p_number + Cc(0)))^-1 + + P("even") * Cc(0) * Cc("n") * Cc(2) + + P("odd") * Cc(-1) * Cc("n") * Cc(2) + ) + * p_space + * P(")") + +local p_step = P(".") * Ct(Cc(s_attribute) * Cc("class") * Cc(3) * p_tag) + + P("#") * Ct(Cc(s_attribute) * Cc("id") * Cc(1) * p_tag) + + p_attribute + + p_element + + P(":nth-child") * Ct(Cc(s_nth_child) * p_formula) + + P(":nth-last-child") * Ct(Cc(s_nth_last_child) * p_formula) + + P(":first-child") * Ct(Cc(s_nth_child) * Cc(1)) + + P(":last-child") * Ct(Cc(s_nth_last_child) * Cc(1)) + + P(":only-child") * Ct(Cc(s_only_child) ) + + P(":nth-of-type") * Ct(Cc(s_nth_of_type) * p_formula) + + P(":nth-last-of-type") * Ct(Cc(s_nth_last_of_type) * p_formula) + + P(":first-of-type") * Ct(Cc(s_nth_of_type) * Cc(1)) + + P(":last-of-type") * Ct(Cc(s_nth_last_of_type) * Cc(1)) + + P(":only-of-type") * Ct(Cc(s_only_of_type) ) + + P(":empty") * Ct(Cc(s_empty) ) + + P(":root") * Ct(Cc(s_root) ) + +local p_not = P(":not") * Cc(true) * p_space * P("(") * p_space * p_step * p_space * P(")") +local p_yes = Cc(false) * p_space * p_step + +local p_stepper = Ct((p_space * (p_not+p_yes))^1) +local p_steps = Ct((p_stepper * p_separator^0)^1) * p_space * (P(-1) + function() print("error") end) + +local cache = table.setmetatableindex(function(t,k) + local v = lpegmatch(p_steps,k) or false + t[k] = v + return v +end) + +local function selector(root,s) + -- local steps = lpegmatch(p_steps,s) + local steps = cache[s] + if steps then + local done = { } + local collected = { } + local nofcollected = 0 + local nofsteps = #steps + for i=1,nofsteps do + local step = steps[i] + local n = #step + if n > 0 then + local r = root + local m = 0 + local c = { } + for i=1,n,2 do + local s = step[i+1] -- function + data + m = s[1](r,c,0,step[i],s[2],s[3],s[4]) + if m == 0 then + break + else + r = c + c = { } + end + end + if m > 0 then + if nofsteps > 1 then + for i=1,m do + local ri = r[i] + if done[ri] then + -- print("duplicate",i) + -- elseif ri.special then + -- done[ri] = true + else + nofcollected = nofcollected + 1 + collected[nofcollected] = ri + done[ri] = true + end + end + else + return r + end + end + end + end + if nofcollected > 1 then + -- local n = 0 + -- local function traverse(e) + -- if done[e] then + -- n = n + 1 + -- done[e] = n + -- end + -- local dt = e.dt + -- if dt then + -- for i=1,#dt do + -- local e = dt[i] + -- if type(e) == "table" then + -- traverse(e) + -- end + -- end + -- end + -- end + -- traverse(root[1]) + -- + local n = 0 + local function traverse(dt) + for i=1,#dt do + local e = dt[i] + if done[e] then + n = n + 1 + done[e] = n + if n == nofcollected then + return + end + end + local d = e.dt + if d then + traverse(d) + if n == nofcollected then + return + end + end + end + end + local r = root[1] + if done[r] then + n = n + 1 + done[r] = n + end + traverse(r.dt) + -- + sort(collected,function(a,b) return done[a] < done[b] end) + end + return collected + else + return { } + end +end + +xml.applyselector= selector + +-- local t = [[ +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- d e +-- d e +-- d e e +-- d f +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- g gg f +-- +-- g gg f +-- g gg f +-- g f +-- g f +-- +-- +-- ]] +-- +-- local s = [[ .one ]] +-- local s = [[ .one, .two ]] +-- local s = [[ .one, .two, #first ]] +-- local s = [[ .one, .two, #first, c, e, [foo], [bar=foo] ]] +-- local s = [[ .one, .two, #first, c, e, [foo], [bar=foo], [bar~=foo] [bar^="foo"] ]] +-- local s = [[ [bar^="foo"] ]] +-- local s = [[ g f .one, g f .three ]] +-- local s = [[ g > f .one, g > f .three ]] +-- local s = [[ * ]] +-- local s = [[ d + e ]] +-- local s = [[ d ~ e ]] +-- local s = [[ d ~ e, g f .one, g f .three ]] +-- local s = [[ :not(d) ]] +-- local s = [[ [whatever~="five"] ]] +-- local s = [[ :not([whatever~="five"]) ]] +-- local s = [[ e ]] +-- local s = [[ :not ( e ) ]] +-- local s = [[ a:nth-child(3) ]] +-- local s = [[ a:nth-child(3n+1) ]] +-- local s = [[ a:nth-child(2n+8) ]] +-- local s = [[ g:nth-of-type(3) ]] +-- local s = [[ a:first-child ]] +-- local s = [[ a:last-child ]] +-- local s = [[ e:first-of-type ]] +-- local s = [[gg d:only-of-type ]] +-- local s = [[ a:nth-child(even) ]] +-- local s = [[ a:nth-child(odd) ]] +-- local s = [[ g:empty ]] +-- local s = [[ g:root ]] + +function css.applyselector(x,str) + -- the wrapping needs checking so this is a placeholder + return applyselector({ x },str) +end + +-- local c = css.applyselector(xml.convert(t),s) for i=1,#c do print(xml.tostring(c[i])) end + diff --git a/tex/context/base/mkiv/lxml-lpt.lua b/tex/context/base/mkiv/lxml-lpt.lua index 7ee1db1d8..19d69076a 100644 --- a/tex/context/base/mkiv/lxml-lpt.lua +++ b/tex/context/base/mkiv/lxml-lpt.lua @@ -177,7 +177,7 @@ apply_axis['child'] = function(list) if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh +-- dk.ni = k -- refresh en = en + 1 dk.ei = en end @@ -197,7 +197,7 @@ local function collect(list,collected,c) if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh +-- dk.ni = k -- refresh en = en + 1 dk.ei = en c = collect(dk,collected,c) @@ -225,7 +225,7 @@ local function collect(list,collected,c) if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh +-- dk.ni = k -- refresh en = en + 1 dk.ei = en c = collect(dk,collected,c) @@ -518,6 +518,15 @@ local function apply_expression(list,expression,order) return collected end +local function apply_selector(list,specification) + if xml.applyselector then + apply_selector = xml.applyselector + return apply_selector(list,specification) + else + return list + end +end + -- this one can be made faster but there are not that many conversions so it doesn't -- really pay of @@ -717,6 +726,10 @@ local function register_nodes(nodetest,nodes) return { kind = "nodes", nodetest = nodetest, nodes = nodes } end +local function register_selector(specification) + return { kind = "selector", specification = specification } +end + local function register_expression(expression) local converted = lpegmatch(converter,expression) local runner = load(format(template_e,converted)) @@ -775,7 +788,7 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving some p -- the / is needed for // as descendant or self is somewhat special -- -- step = (V("shortcuts") + V("axis") * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, - step = ((V("shortcuts") + P("/") + V("axis")) * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, + step = ((V("shortcuts") + V("selector") + P("/") + V("axis")) * spaces * V("nodes")^0 + V("error")) * spaces * V("expressions")^0 * spaces * V("finalizer")^0, axis = V("last_match") + V("descendant") @@ -838,6 +851,8 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving some p reverse_sibling = P('reverse-sibling::') * Cc(register_reverse_sibling ), last_match = P('last-match::') * Cc(register_last_match ), + selector = P("{") * C((1-P("}"))^1) * P("}") / register_selector, + nodes = (V("nodefunction") * spaces * P("(") * V("nodeset") * P(")") + V("nodetest") * V("nodeset")) / register_nodes, expressions = expression / register_expression, @@ -1026,6 +1041,8 @@ do collected = apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) elseif kind == "finalizer" then collected = pi.finalizer(collected) -- no check on # here p.matched = p.matched + 1 @@ -1068,6 +1085,9 @@ do elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) + report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification) elseif kind == "finalizer" then collected = pi.finalizer(collected) report_lpath("% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "") @@ -1100,6 +1120,8 @@ do collected = apply_nodes(collected,pi.nodetest,pi.nodes) elseif kind == "expression" then collected = apply_expression(collected,pi.evaluator,order) + elseif kind == "selector" then + collected = apply_selector(collected,pi.specification) elseif kind == "finalizer" then return pi.finalizer(collected) end diff --git a/tex/context/base/mkiv/lxml-tab.lua b/tex/context/base/mkiv/lxml-tab.lua index 209dec7f9..64322e4d0 100644 --- a/tex/context/base/mkiv/lxml-tab.lua +++ b/tex/context/base/mkiv/lxml-tab.lua @@ -264,6 +264,7 @@ local function add_empty(spacing, namespace, tag) tg = tag, at = at, dt = { }, + ni = nt, __p__ = top } dt[nt] = t @@ -285,7 +286,8 @@ local function add_begin(spacing, namespace, tag) rn = resolved, tg = tag, at = at, - dt = {}, + dt = { }, + ni = nt, -- preset slot __p__ = stack[level] } setmetatable(top, mt) @@ -313,6 +315,7 @@ local function add_end(spacing, namespace, tag) end dt = top.dt nt = #dt + 1 + toclose.ni = nt dt[nt] = toclose -- dt[0] = top -- nasty circular reference when serializing table if toclose.at.xmlns then @@ -370,7 +373,13 @@ local function add_special(what, spacing, text) -- forget it else nt = nt + 1 - dt[nt] = { special=true, ns="", tg=what, dt={ text } } + dt[nt] = { + special = true, + ns = "", + tg = what, + ni = nt, + dt = { text }, + } end end diff --git a/tex/context/base/mkiv/publ-dat.lua b/tex/context/base/mkiv/publ-dat.lua index f6650dd4d..f57efa9a1 100644 --- a/tex/context/base/mkiv/publ-dat.lua +++ b/tex/context/base/mkiv/publ-dat.lua @@ -43,9 +43,11 @@ local p_utf8character = lpegpatterns.utf8character local trace = false trackers.register("publications", function(v) trace = v end) local trace_duplicates = true trackers.register("publications.duplicates", function(v) trace = v end) +local trace_strings = false trackers.register("publications.strings", function(v) trace = v end) local report = logs.reporter("publications") local report_duplicates = logs.reporter("publications","duplicates") +local report_strings = logs.reporter("publications","strings") local allocate = utilities.storage.allocate @@ -537,8 +539,28 @@ do luadata[hashtag] = entries end + local f_invalid = formatters[""] + local function resolve(s,dataset) - return dataset.shortcuts[s] or defaultshortcuts[s] or s -- can be number + local e = dataset.shortcuts[s] + if e then + if trace_strings then + report_strings("%a resolves to %a",s,e) + end + return e + end + e = defaultshortcuts[s] + if e then + if trace_strings then + report_strings("%a resolves to default %a",s,e) + end + return e + end + if tonumber(s) then + return s + end + report("error in database, invalid value %a",s) + return f_invalid(s) end local pattern = p_whitespace^0 @@ -600,28 +622,23 @@ do local unbalanced = (left/"") * balanced * (right/"") * P(-1) - local reference = P("@") * C((R("az","AZ","09") + S("_:-"))^1) + local reference = C((R("az","AZ","09") + S("_:-"))^1) local b_value = p_left * balanced * p_right - -- local u_value = p_left * unbalanced * p_right -- get rid of outer { } - -- local s_value = (single/"") * (u_value + s_quoted) * (single/"") - -- local d_value = (double/"") * (u_value + d_quoted) * (double/"") local s_value = (single/"") * (unbalanced + s_quoted) * (single/"") local d_value = (double/"") * (unbalanced + d_quoted) * (double/"") - local r_value = reference * Carg(1) / resolve + local r_value = P("@") * reference * Carg(1) / resolve + + reference * Carg(1) / resolve + local n_value = C(R("09")^1) --- local e_value = (1-S(",}"))^0 / function(s) - local e_value = Cs((left * balanced * right + (1 - S(",}")))^0) / function(s) - report("error in database, invalid value %a",s) - return "[invalid: " .. s .. "]" + local e_value = Cs((left * balanced * right + (1 - S(",}")))^0) * Carg(1) / function(s,dataset) + return resolve(s,dataset) end - local somevalue = d_value + b_value + s_value + r_value + e_value + local somevalue = d_value + b_value + s_value + r_value + n_value + e_value local value = Cs((somevalue * ((spacing * hash * spacing)/"" * somevalue)^0)) local stripper = lpegpatterns.stripper - value = value / function(s) - return lpegmatch(stripper,s) - end + value = value / function(s) return lpegmatch(stripper,s) end local forget = percent^1 * (1-lineending)^0 local spacing = spacing * forget^0 * spacing diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 0a9d95fef..d5f616baf 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index b7090d2a8..419d34320 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index 0f76a4ac2..4fac278b4 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index 5a55f45de..b284c4966 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index c503add27..f5339a3b7 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 12/21/16 18:51:59 +-- merge date : 12/28/16 17:55:48 do -- begin closure to overcome local limits and interference -- cgit v1.2.3