summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/lxml-lpt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/lxml-lpt.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/lxml-lpt.lua329
1 files changed, 204 insertions, 125 deletions
diff --git a/Master/texmf-dist/tex/context/base/lxml-lpt.lua b/Master/texmf-dist/tex/context/base/lxml-lpt.lua
index bddbe48685c..aa0b0a22ecc 100644
--- a/Master/texmf-dist/tex/context/base/lxml-lpt.lua
+++ b/Master/texmf-dist/tex/context/base/lxml-lpt.lua
@@ -7,11 +7,14 @@ if not modules then modules = { } end modules ['lxml-pth'] = {
}
-- e.ni is only valid after a filter run
+-- todo: B/C/[get first match]
local concat, remove, insert = table.concat, table.remove, table.insert
local type, next, tonumber, tostring, setmetatable, loadstring = type, next, tonumber, tostring, setmetatable, loadstring
local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep
-local lpegmatch = lpeg.match
+local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+
+local setmetatableindex = table.setmetatableindex
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
@@ -43,23 +46,33 @@ local trace_lpath = false if trackers then trackers.register("xml.path",
local trace_lparse = false if trackers then trackers.register("xml.parse", function(v) trace_lparse = v end) end
local trace_lprofile = false if trackers then trackers.register("xml.profile", function(v) trace_lpath = v trace_lparse = v trace_lprofile = v end) end
+local report_lpath = logs.reporter("xml","lpath")
+
--[[ldx--
<p>We've now arrived at an interesting part: accessing the tree using a subset
of <l n='xpath'/> and since we're not compatible we call it <l n='lpath'/>. We
will explain more about its usage in other documents.</p>
--ldx]]--
+local xml = xml
+
local lpathcalls = 0 function xml.lpathcalls () return lpathcalls end
local lpathcached = 0 function xml.lpathcached() return lpathcached end
-xml.functions = xml.functions or { } -- internal
-xml.expressions = xml.expressions or { } -- in expressions
-xml.finalizers = xml.finalizers or { } -- fast do-with ... (with return value other than collection)
-xml.specialhandler = xml.specialhandler or { }
+xml.functions = xml.functions or { } -- internal
+local functions = xml.functions
+
+xml.expressions = xml.expressions or { } -- in expressions
+local expressions = xml.expressions
-local functions = xml.functions
-local expressions = xml.expressions
-local finalizers = xml.finalizers
+xml.finalizers = xml.finalizers or { } -- fast do-with ... (with return value other than collection)
+local finalizers = xml.finalizers
+
+xml.specialhandler = xml.specialhandler or { }
+local specialhandler = xml.specialhandler
+
+lpegpatterns.xml = lpegpatterns.xml or { }
+local xmlpatterns = lpegpatterns.xml
finalizers.xml = finalizers.xml or { }
finalizers.tex = finalizers.tex or { }
@@ -69,14 +82,14 @@ local function fallback (t, name)
if fn then
t[name] = fn
else
- logs.report("xml","unknown sub finalizer '%s'",tostring(name))
+ report_lpath("unknown sub finalizer '%s'",tostring(name))
fn = function() end
end
return fn
end
-setmetatable(finalizers.xml, { __index = fallback })
-setmetatable(finalizers.tex, { __index = fallback })
+setmetatableindex(finalizers.xml, fallback)
+setmetatableindex(finalizers.tex, fallback)
xml.defaultprotocol = "xml"
@@ -124,7 +137,7 @@ apply_axis['root'] = function(list)
rt = ll
end
end
- collected[#collected+1] = rt
+ collected[l] = rt
end
return collected
end
@@ -132,94 +145,103 @@ end
apply_axis['self'] = function(list)
--~ local collected = { }
--~ for l=1,#list do
---~ collected[#collected+1] = list[l]
+--~ collected[l] = list[l]
--~ end
--~ return collected
return list
end
apply_axis['child'] = function(list)
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
local ll = list[l]
local dt = ll.dt
- local en = 0
- for k=1,#dt do
- local dk = dt[k]
- if dk.tg then
- collected[#collected+1] = dk
- dk.ni = k -- refresh
- en = en + 1
- dk.ei = en
+ if dt then -- weird that this is needed
+ local en = 0
+ for k=1,#dt do
+ local dk = dt[k]
+ if dk.tg then
+ c = c + 1
+ collected[c] = dk
+ dk.ni = k -- refresh
+ en = en + 1
+ dk.ei = en
+ end
end
+ ll.en = en
end
- ll.en = en
end
return collected
end
-local function collect(list,collected)
+local function collect(list,collected,c)
local dt = list.dt
if dt then
local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
- collected[#collected+1] = dk
+ c = c + 1
+ collected[c] = dk
dk.ni = k -- refresh
en = en + 1
dk.ei = en
- collect(dk,collected)
+ c = collect(dk,collected,c)
end
end
list.en = en
end
+ return c
end
apply_axis['descendant'] = function(list)
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
- collect(list[l],collected)
+ c = collect(list[l],collected,c)
end
return collected
end
-local function collect(list,collected)
+local function collect(list,collected,c)
local dt = list.dt
if dt then
local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
- collected[#collected+1] = dk
+ c = c + 1
+ collected[c] = dk
dk.ni = k -- refresh
en = en + 1
dk.ei = en
- collect(dk,collected)
+ c = collect(dk,collected,c)
end
end
list.en = en
end
+ return c
end
apply_axis['descendant-or-self'] = function(list)
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
local ll = list[l]
if ll.special ~= true then -- catch double root
- collected[#collected+1] = ll
+ c = c + 1
+ collected[c] = ll
end
- collect(ll,collected)
+ c = collect(ll,collected,c)
end
return collected
end
apply_axis['ancestor'] = function(list)
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
local ll = list[l]
while ll do
ll = ll.__p__
if ll then
- collected[#collected+1] = ll
+ c = c + 1
+ collected[c] = ll
end
end
end
@@ -227,14 +249,16 @@ apply_axis['ancestor'] = function(list)
end
apply_axis['ancestor-or-self'] = function(list)
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
local ll = list[l]
- collected[#collected+1] = ll
+ c = c + 1
+ collected[c] = ll
while ll do
ll = ll.__p__
if ll then
- collected[#collected+1] = ll
+ c = c + 1
+ collected[c] = ll
end
end
end
@@ -242,11 +266,12 @@ apply_axis['ancestor-or-self'] = function(list)
end
apply_axis['parent'] = function(list)
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
local pl = list[l].__p__
if pl then
- collected[#collected+1] = pl
+ c = c + 1
+ collected[c] = pl
end
end
return collected
@@ -261,7 +286,7 @@ apply_axis['namespace'] = function(list)
end
apply_axis['following'] = function(list) -- incomplete
---~ local collected = { }
+--~ local collected, c = { }, 0
--~ for l=1,#list do
--~ local ll = list[l]
--~ local p = ll.__p__
@@ -269,7 +294,8 @@ apply_axis['following'] = function(list) -- incomplete
--~ for i=ll.ni+1,#d do
--~ local di = d[i]
--~ if type(di) == "table" then
---~ collected[#collected+1] = di
+--~ c = c + 1
+--~ collected[c] = di
--~ break
--~ end
--~ end
@@ -279,7 +305,7 @@ apply_axis['following'] = function(list) -- incomplete
end
apply_axis['preceding'] = function(list) -- incomplete
---~ local collected = { }
+--~ local collected, c = { }, 0
--~ for l=1,#list do
--~ local ll = list[l]
--~ local p = ll.__p__
@@ -287,7 +313,8 @@ apply_axis['preceding'] = function(list) -- incomplete
--~ for i=ll.ni-1,1,-1 do
--~ local di = d[i]
--~ if type(di) == "table" then
---~ collected[#collected+1] = di
+--~ c = c + 1
+--~ collected[c] = di
--~ break
--~ end
--~ end
@@ -297,7 +324,7 @@ apply_axis['preceding'] = function(list) -- incomplete
end
apply_axis['following-sibling'] = function(list)
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
local ll = list[l]
local p = ll.__p__
@@ -305,7 +332,8 @@ apply_axis['following-sibling'] = function(list)
for i=ll.ni+1,#d do
local di = d[i]
if type(di) == "table" then
- collected[#collected+1] = di
+ c = c + 1
+ collected[c] = di
end
end
end
@@ -313,7 +341,7 @@ apply_axis['following-sibling'] = function(list)
end
apply_axis['preceding-sibling'] = function(list)
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
local ll = list[l]
local p = ll.__p__
@@ -321,7 +349,8 @@ apply_axis['preceding-sibling'] = function(list)
for i=1,ll.ni-1 do
local di = d[i]
if type(di) == "table" then
- collected[#collected+1] = di
+ c = c + 1
+ collected[c] = di
end
end
end
@@ -329,7 +358,7 @@ apply_axis['preceding-sibling'] = function(list)
end
apply_axis['reverse-sibling'] = function(list) -- reverse preceding
- local collected = { }
+ local collected, c = { }, 0
for l=1,#list do
local ll = list[l]
local p = ll.__p__
@@ -337,7 +366,8 @@ apply_axis['reverse-sibling'] = function(list) -- reverse preceding
for i=ll.ni-1,1,-1 do
local di = d[i]
if type(di) == "table" then
- collected[#collected+1] = di
+ c = c + 1
+ collected[c] = di
end
end
end
@@ -363,7 +393,7 @@ local function apply_nodes(list,directive,nodes)
return { }
end
else
- local collected, m, p = { }, 0, nil
+ local collected, c, m, p = { }, 0, 0, nil
if not nns then -- only check tag
for l=1,#list do
local ll = list[l]
@@ -372,11 +402,13 @@ local function apply_nodes(list,directive,nodes)
if directive then
if ntg == ltg then
local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
- collected[#collected+1], ll.mi = ll, m
+ c = c + 1
+ collected[c], ll.mi = ll, m
end
elseif ntg ~= ltg then
local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
- collected[#collected+1], ll.mi = ll, m
+ c = c + 1
+ collected[c], ll.mi = ll, m
end
end
end
@@ -388,11 +420,13 @@ local function apply_nodes(list,directive,nodes)
if directive then
if lns == nns then
local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
- collected[#collected+1], ll.mi = ll, m
+ c = c + 1
+ collected[c], ll.mi = ll, m
end
elseif lns ~= nns then
local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
- collected[#collected+1], ll.mi = ll, m
+ c = c + 1
+ collected[c], ll.mi = ll, m
end
end
end
@@ -406,11 +440,13 @@ local function apply_nodes(list,directive,nodes)
if directive then
if ok then
local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
- collected[#collected+1], ll.mi = ll, m
+ c = c + 1
+ collected[c], ll.mi = ll, m
end
elseif not ok then
local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
- collected[#collected+1], ll.mi = ll, m
+ c = c + 1
+ collected[c], ll.mi = ll, m
end
end
end
@@ -418,7 +454,7 @@ local function apply_nodes(list,directive,nodes)
return collected
end
else
- local collected, m, p = { }, 0, nil
+ local collected, c, m, p = { }, 0, 0, nil
for l=1,#list do
local ll = list[l]
local ltg = ll.tg
@@ -435,11 +471,13 @@ local function apply_nodes(list,directive,nodes)
if directive then
if ok then
local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
- collected[#collected+1], ll.mi = ll, m
+ c = c + 1
+ collected[c], ll.mi = ll, m
end
elseif not ok then
local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end
- collected[#collected+1], ll.mi = ll, m
+ c = c + 1
+ collected[c], ll.mi = ll, m
end
end
end
@@ -450,12 +488,13 @@ end
local quit_expression = false
local function apply_expression(list,expression,order)
- local collected = { }
+ local collected, c = { }, 0
quit_expression = false
for l=1,#list do
local ll = list[l]
if expression(list,ll,l,order) then -- nasty, order alleen valid als n=1
- collected[#collected+1] = ll
+ c = c + 1
+ collected[c] = ll
end
if quit_expression then
break
@@ -494,7 +533,9 @@ local lp_builtin = P (
P("ns") / "ll.ns"
) * ((spaces * P("(") * spaces * P(")"))/"")
-local lp_attribute = (P("@") + P("attribute::")) / "" * Cc("(ll.at and ll.at['") * R("az","AZ","--","__")^1 * Cc("'])")
+-- for the moment we keep namespaces with attributes
+
+local lp_attribute = (P("@") + P("attribute::")) / "" * Cc("(ll.at and ll.at['") * ((R("az","AZ") + S("-_:"))^1) * Cc("'])")
local lp_fastpos_p = ((P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end)
local lp_fastpos_n = ((P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end)
local lp_fastpos = lp_fastpos_n + lp_fastpos_p
@@ -613,13 +654,13 @@ local skip = { }
local function errorrunner_e(str,cnv)
if not skip[str] then
- logs.report("lpath","error in expression: %s => %s",str,cnv)
+ report_lpath("error in expression: %s => %s",str,cnv)
skip[str] = cnv or str
end
return false
end
local function errorrunner_f(str,arg)
- logs.report("lpath","error in finalizer: %s(%s)",str,arg or "")
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
return false
end
@@ -670,7 +711,7 @@ local special_1 = P("*") * Cc(register_auto_descendant) * Cc(register_all_nodes
local special_2 = P("/") * Cc(register_auto_self)
local special_3 = P("") * Cc(register_auto_self)
-local parser = Ct { "patterns", -- can be made a bit faster by moving pattern outside
+local pathparser = Ct { "patterns", -- can be made a bit faster by moving pattern outside
patterns = spaces * V("protocol") * spaces * (
( V("special") * spaces * P(-1) ) +
@@ -742,6 +783,8 @@ local parser = Ct { "patterns", -- can be made a bit faster by moving pattern ou
}
+xmlpatterns.pathparser = pathparser
+
local cache = { }
local function nodesettostring(set,nodetest)
@@ -751,7 +794,7 @@ local function nodesettostring(set,nodetest)
if not ns or ns == "" then ns = "*" end
if not tg or tg == "" then tg = "*" end
tg = (tg == "@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1] = (directive and tg) or format("not(%s)",tg)
+ t[i] = (directive and tg) or format("not(%s)",tg)
end
if nodetest == false then
return format("not(%s)",concat(t,"|"))
@@ -770,7 +813,7 @@ local function tagstostring(list)
local ns, tg = li.ns, li.tg
if not ns or ns == "" then ns = "*" end
if not tg or tg == "" then tg = "*" end
- t[#t+1] = (tg == "@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[i] = (tg == "@rt@" and "[root]") or format("%s:%s",ns,tg)
end
return concat(t," ")
end
@@ -778,16 +821,16 @@ end
xml.nodesettostring = nodesettostring
-local parse_pattern -- we have a harmless kind of circular reference
+local lpath -- we have a harmless kind of circular reference
+
+local lshowoptions = { functions = false }
local function lshow(parsed)
if type(parsed) == "string" then
- parsed = parse_pattern(parsed)
+ parsed = lpath(parsed)
end
- local s = table.serialize_functions -- ugly
- table.serialize_functions = false -- ugly
- logs.report("lpath","%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,table.serialize(parsed,false))
- table.serialize_functions = s -- ugly
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false,lshowoptions))
end
xml.lshow = lshow
@@ -801,7 +844,7 @@ local function add_comment(p,str)
end
end
-parse_pattern = function (pattern) -- the gain of caching is rather minimal
+lpath = function (pattern) -- the gain of caching is rather minimal
lpathcalls = lpathcalls + 1
if type(pattern) == "table" then
return pattern
@@ -810,13 +853,13 @@ parse_pattern = function (pattern) -- the gain of caching is rather minimal
if parsed then
lpathcached = lpathcached + 1
else
- parsed = lpegmatch(parser,pattern)
+ parsed = lpegmatch(pathparser,pattern)
if parsed then
parsed.pattern = pattern
local np = #parsed
if np == 0 then
parsed = { pattern = pattern, register_self, state = "parsing error" }
- logs.report("lpath","parsing error in '%s'",pattern)
+ report_lpath("parsing error in '%s'",pattern)
lshow(parsed)
else
-- we could have done this with a more complex parser but this
@@ -858,6 +901,8 @@ parse_pattern = function (pattern) -- the gain of caching is rather minimal
end
end
+xml.lpath = lpath
+
-- we can move all calls inline and then merge the trace back
-- technically we can combine axis and the next nodes which is
-- what we did before but this a bit cleaner (but slower too)
@@ -920,32 +965,32 @@ local function traced_apply(list,parsed,nofparsed,order)
if trace_lparse then
lshow(parsed)
end
- logs.report("lpath", "collecting : %s",parsed.pattern)
- logs.report("lpath", " root tags : %s",tagstostring(list))
- logs.report("lpath", " order : %s",order or "unset")
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
local collected = list
for i=1,nofparsed do
local pi = parsed[i]
local kind = pi.kind
if kind == "axis" then
collected = apply_axis[pi.axis](collected)
- logs.report("lpath", "% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
elseif kind == "nodes" then
collected = apply_nodes(collected,pi.nodetest,pi.nodes)
- logs.report("lpath", "% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
elseif kind == "expression" then
collected = apply_expression(collected,pi.evaluator,order)
- logs.report("lpath", "% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
elseif kind == "finalizer" then
collected = pi.finalizer(collected)
- logs.report("lpath", "% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
end
if not collected or #collected == 0 then
local pn = i < nofparsed and parsed[nofparsed]
if pn and pn.kind == "finalizer" then
collected = pn.finalizer(collected)
- logs.report("lpath", "% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected) == "table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
return collected
end
return nil
@@ -982,8 +1027,41 @@ local function normal_apply(list,parsed,nofparsed,order)
return collected
end
-local function parse_apply(list,pattern)
- -- we avoid an extra call
+--~ local function applylpath(list,pattern)
+--~ -- we avoid an extra call
+--~ local parsed = cache[pattern]
+--~ if parsed then
+--~ lpathcalls = lpathcalls + 1
+--~ lpathcached = lpathcached + 1
+--~ elseif type(pattern) == "table" then
+--~ lpathcalls = lpathcalls + 1
+--~ parsed = pattern
+--~ else
+--~ parsed = lpath(pattern) or pattern
+--~ end
+--~ if not parsed then
+--~ return
+--~ end
+--~ local nofparsed = #parsed
+--~ if nofparsed == 0 then
+--~ return -- something is wrong
+--~ end
+--~ local one = list[1] -- we could have a third argument: isroot and list or list[1] or whatever we like ... todo
+--~ if not one then
+--~ return -- something is wrong
+--~ elseif not trace_lpath then
+--~ return normal_apply(list,parsed,nofparsed,one.mi)
+--~ elseif trace_lprofile then
+--~ return profiled_apply(list,parsed,nofparsed,one.mi)
+--~ else
+--~ return traced_apply(list,parsed,nofparsed,one.mi)
+--~ end
+--~ end
+
+local function applylpath(list,pattern)
+ if not list then
+ return
+ end
local parsed = cache[pattern]
if parsed then
lpathcalls = lpathcalls + 1
@@ -992,7 +1070,7 @@ local function parse_apply(list,pattern)
lpathcalls = lpathcalls + 1
parsed = pattern
else
- parsed = parse_pattern(pattern) or pattern
+ parsed = lpath(pattern) or pattern
end
if not parsed then
return
@@ -1001,25 +1079,32 @@ local function parse_apply(list,pattern)
if nofparsed == 0 then
return -- something is wrong
end
- local one = list[1]
- if not one then
- return -- something is wrong
- elseif not trace_lpath then
- return normal_apply(list,parsed,nofparsed,one.mi)
+ if not trace_lpath then
+ return normal_apply ({ list },parsed,nofparsed,list.mi)
elseif trace_lprofile then
- return profiled_apply(list,parsed,nofparsed,one.mi)
+ return profiled_apply({ list },parsed,nofparsed,list.mi)
else
- return traced_apply(list,parsed,nofparsed,one.mi)
+ return traced_apply ({ list },parsed,nofparsed,list.mi)
end
end
+xml.applylpath = applylpath -- takes a table as first argment, which is what xml.filter will do
+
+--[[ldx--
+<p>This is the main filter function. It returns whatever is asked for.</p>
+--ldx]]--
+
+function xml.filter(root,pattern) -- no longer funny attribute handling here
+ return applylpath(root,pattern)
+end
+
-- internal (parsed)
expressions.child = function(e,pattern)
- return parse_apply({ e },pattern) -- todo: cache
+ return applylpath(e,pattern) -- todo: cache
end
expressions.count = function(e,pattern)
- local collected = parse_apply({ e },pattern) -- todo: cache
+ local collected = applylpath(e,pattern) -- todo: cache
return (collected and #collected) or 0
end
@@ -1029,7 +1114,7 @@ expressions.oneof = function(s,...) -- slow
local t = {...} for i=1,#t do if s == t[i] then return true end end return false
end
expressions.error = function(str)
- xml.error_handler("unknown function in lpath expression",tostring(str or "?"))
+ xml.errorhandler("unknown function in lpath expression",tostring(str or "?"))
return false
end
expressions.undefined = function(s)
@@ -1058,8 +1143,8 @@ expressions.boolean = toboolean
-- user interface
local function traverse(root,pattern,handle)
- logs.report("xml","use 'xml.selection' instead for '%s'",pattern)
- local collected = parse_apply({ root },pattern)
+ report_lpath("use 'xml.selection' instead for '%s'",pattern)
+ local collected = applylpath(root,pattern)
if collected then
for c=1,#collected do
local e = collected[c]
@@ -1070,7 +1155,7 @@ local function traverse(root,pattern,handle)
end
local function selection(root,pattern,handle)
- local collected = parse_apply({ root },pattern)
+ local collected = applylpath(root,pattern)
if collected then
if handle then
for c=1,#collected do
@@ -1082,19 +1167,12 @@ local function selection(root,pattern,handle)
end
end
-xml.parse_parser = parser
-xml.parse_pattern = parse_pattern
-xml.parse_apply = parse_apply
xml.traverse = traverse -- old method, r, d, k
xml.selection = selection -- new method, simple handle
-local lpath = parse_pattern
-
-xml.lpath = lpath
-
-function xml.cached_patterns()
- return cache
-end
+--~ function xml.cachedpatterns()
+--~ return cache
+--~ end
-- generic function finalizer (independant namespace)
@@ -1106,13 +1184,13 @@ local function dofunction(collected,fnc)
f(collected[c])
end
else
- logs.report("xml","unknown function '%s'",fnc)
+ report_lpath("unknown function '%s'",fnc)
end
end
end
-xml.finalizers.xml["function"] = dofunction
-xml.finalizers.tex["function"] = dofunction
+finalizers.xml["function"] = dofunction
+finalizers.tex["function"] = dofunction
-- functions
@@ -1205,14 +1283,6 @@ expressions.tag = function(e,n) -- only tg
end
--[[ldx--
-<p>This is the main filter function. It returns whatever is asked for.</p>
---ldx]]--
-
-function xml.filter(root,pattern) -- no longer funny attribute handling here
- return parse_apply({ root },pattern)
-end
-
---[[ldx--
<p>Often using an iterators looks nicer in the code than passing handler
functions. The <l n='lua'/> book describes how to use coroutines for that
purpose (<url href='http://www.lua.org/pil/9.3.html'/>). This permits
@@ -1231,7 +1301,7 @@ end
local wrap, yield = coroutine.wrap, coroutine.yield
function xml.elements(root,pattern,reverse) -- r, d, k
- local collected = parse_apply({ root },pattern)
+ local collected = applylpath(root,pattern)
if collected then
if reverse then
return wrap(function() for c=#collected,1,-1 do
@@ -1247,7 +1317,7 @@ function xml.elements(root,pattern,reverse) -- r, d, k
end
function xml.collected(root,pattern,reverse) -- e
- local collected = parse_apply({ root },pattern)
+ local collected = applylpath(root,pattern)
if collected then
if reverse then
return wrap(function() for c=#collected,1,-1 do yield(collected[c]) end end)
@@ -1257,3 +1327,12 @@ function xml.collected(root,pattern,reverse) -- e
end
return wrap(function() end)
end
+
+-- handy
+
+function xml.inspect(collection,pattern)
+ pattern = pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern %q\n\n%s\n",pattern,xml.tostring(e))
+ end
+end