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.lua63
1 files changed, 42 insertions, 21 deletions
diff --git a/Master/texmf-dist/tex/context/base/lxml-lpt.lua b/Master/texmf-dist/tex/context/base/lxml-lpt.lua
index aa0b0a22ecc..44dd971551a 100644
--- a/Master/texmf-dist/tex/context/base/lxml-lpt.lua
+++ b/Master/texmf-dist/tex/context/base/lxml-lpt.lua
@@ -164,8 +164,8 @@ apply_axis['child'] = function(list)
c = c + 1
collected[c] = dk
dk.ni = k -- refresh
- en = en + 1
- dk.ei = en
+ en = en + 1
+ dk.ei = en
end
end
ll.en = en
@@ -193,6 +193,7 @@ local function collect(list,collected,c)
end
return c
end
+
apply_axis['descendant'] = function(list)
local collected, c = { }, 0
for l=1,#list do
@@ -514,6 +515,12 @@ local lp_or = P("|") / " or "
local lp_and = P("&") / " and "
local lp_builtin = P (
+ P("text") / "(ll.dt[1] or '')" + -- fragile
+ P("content") / "ll.dt" +
+ -- P("name") / "(ll.ns~='' and ll.ns..':'..ll.tg)" +
+ P("name") / "((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)" +
+ P("tag") / "ll.tg" +
+ P("position") / "l" + -- is element in finalizer
P("firstindex") / "1" +
P("lastindex") / "(#ll.__p__.dt or 1)" +
P("firstelement") / "1" +
@@ -521,15 +528,11 @@ local lp_builtin = P (
P("first") / "1" +
P("last") / "#list" +
P("rootposition") / "order" +
- P("position") / "l" + -- is element in finalizer
P("order") / "order" +
P("element") / "(ll.ei or 1)" +
P("index") / "(ll.ni or 1)" +
P("match") / "(ll.mi or 1)" +
- P("text") / "(ll.dt[1] or '')" +
- -- P("name") / "(ll.ns~='' and ll.ns..':'..ll.tg)" +
- P("name") / "((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)" +
- P("tag") / "ll.tg" +
+ -- P("namespace") / "ll.ns" +
P("ns") / "ll.ns"
) * ((spaces * P("(") * spaces * P(")"))/"")
@@ -553,11 +556,11 @@ local lp_function = C(R("az","AZ","__")^1) * P("(") / function(t) -- todo: bett
end
end
-local lparent = lpeg.P("(")
-local rparent = lpeg.P(")")
+local lparent = P("(")
+local rparent = P(")")
local noparent = 1 - (lparent+rparent)
-local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}
-local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"}
+local nested = P{lparent * (noparent + V(1))^0 * rparent}
+local value = P(lparent * C((noparent + nested)^0) * rparent) -- P{"("*C(((1-S("()"))+V(1))^0)*")"}
local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')")
local lp_number = S("+-") * R("09")^1
@@ -711,7 +714,10 @@ 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 pathparser = Ct { "patterns", -- can be made a bit faster by moving pattern outside
+local no_nextcolon = P(-1) + #(1-P(":")) -- newer lpeg needs the P(-1)
+local no_nextlparent = P(-1) + #(1-P("(")) -- newer lpeg needs the P(-1)
+
+local pathparser = Ct { "patterns", -- can be made a bit faster by moving some patterns outside
patterns = spaces * V("protocol") * spaces * (
( V("special") * spaces * P(-1) ) +
@@ -740,10 +746,8 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving patter
shortcuts = V("shortcuts_a") * (spaces * "/" * spaces * V("shortcuts_a"))^0,
s_descendant_or_self = (P("***/") + P("/")) * Cc(register_descendant_or_self), --- *** is a bonus
- -- s_descendant_or_self = P("/") * Cc(register_descendant_or_self),
s_descendant = P("**") * Cc(register_descendant),
- s_child = P("*") * #(1-P(":")) * Cc(register_child ),
--- s_child = P("*") * #(P("/")+P(-1)) * Cc(register_child ),
+ s_child = P("*") * no_nextcolon * Cc(register_child ),
s_parent = P("..") * Cc(register_parent ),
s_self = P("." ) * Cc(register_self ),
s_root = P("^^") * Cc(register_root ),
@@ -770,13 +774,13 @@ local pathparser = Ct { "patterns", -- can be made a bit faster by moving patter
expressions = expression / register_expression,
letters = R("az")^1,
- name = (1-lpeg.S("/[]()|:*!"))^1,
+ name = (1-S("/[]()|:*!"))^1, -- make inline
negate = P("!") * Cc(false),
nodefunction = V("negate") + P("not") * Cc(false) + Cc(true),
nodetest = V("negate") + Cc(true),
nodename = (V("negate") + Cc(true)) * spaces * ((V("wildnodename") * P(":") * V("wildnodename")) + (Cc(false) * V("wildnodename"))),
- wildnodename = (C(V("name")) + P("*") * Cc(false)) * #(1-P("(")),
+ wildnodename = (C(V("name")) + P("*") * Cc(false)) * no_nextlparent,
nodeset = spaces * Ct(V("nodename") * (spaces * P("|") * spaces * V("nodename"))^0) * spaces,
finalizer = (Cb("protocol") * P("/")^-1 * C(V("name")) * arguments * P(-1)) / register_finalizer,
@@ -940,7 +944,7 @@ local function profiled_apply(list,parsed,nofparsed,order)
elseif kind == "expression" then
collected = apply_expression(collected,pi.evaluator,order)
elseif kind == "finalizer" then
- collected = pi.finalizer(collected)
+ collected = pi.finalizer(collected) -- no check on # here
p.matched = p.matched + 1
p.finalized = p.finalized + 1
return collected
@@ -1103,9 +1107,9 @@ end
expressions.child = function(e,pattern)
return applylpath(e,pattern) -- todo: cache
end
-expressions.count = function(e,pattern)
+expressions.count = function(e,pattern) -- what if pattern == empty or nil
local collected = applylpath(e,pattern) -- todo: cache
- return (collected and #collected) or 0
+ return pattern and (collected and #collected) or 0
end
-- external
@@ -1114,7 +1118,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.errorhandler("unknown function in lpath expression",tostring(str or "?"))
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
return false
end
expressions.undefined = function(s)
@@ -1140,6 +1144,23 @@ expressions.lower = lower
expressions.number = tonumber
expressions.boolean = toboolean
+function expressions.contains(str,pattern)
+ local t = type(str)
+ if t == "string" then
+ if find(str,pattern) then
+ return true
+ end
+ elseif t == "table" then
+ for i=1,#str do
+ local d = str[i]
+ if type(d) == "string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
+end
+
-- user interface
local function traverse(root,pattern,handle)