diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/lxml-lpt.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/lxml-lpt.lua | 329 |
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 |