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.lua189
1 files changed, 148 insertions, 41 deletions
diff --git a/Master/texmf-dist/tex/context/base/lxml-lpt.lua b/Master/texmf-dist/tex/context/base/lxml-lpt.lua
index 44dd971551a..51ab321b931 100644
--- a/Master/texmf-dist/tex/context/base/lxml-lpt.lua
+++ b/Master/texmf-dist/tex/context/base/lxml-lpt.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['lxml-pth'] = {
+if not modules then modules = { } end modules ['lxml-lpt'] = {
version = 1.001,
comment = "this module is the basis for the lxml-* ones",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -10,11 +10,12 @@ if not modules then modules = { } end modules ['lxml-pth'] = {
-- 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 type, next, tonumber, tostring, setmetatable, load, select = type, next, tonumber, tostring, setmetatable, load, select
local format, upper, lower, gmatch, gsub, find, rep = string.format, string.upper, string.lower, string.gmatch, string.gsub, string.find, string.rep
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local setmetatableindex = table.setmetatableindex
+local formatters = string.formatters -- no need (yet) as paths are cached anyway
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
@@ -82,7 +83,7 @@ local function fallback (t, name)
if fn then
t[name] = fn
else
- report_lpath("unknown sub finalizer '%s'",tostring(name))
+ report_lpath("unknown sub finalizer %a",name)
fn = function() end
end
return fn
@@ -539,14 +540,23 @@ local lp_builtin = P (
-- 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)
+
+-- lp_fastpos_p = (P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end
+-- lp_fastpos_n = (P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end
+
+lp_fastpos_p = P("+")^0 * R("09")^1 * P(-1) / "l==%0"
+lp_fastpos_n = P("-") * R("09")^1 * P(-1) / "(%0<0 and (#list+%0==l))"
+
local lp_fastpos = lp_fastpos_n + lp_fastpos_p
+
local lp_reserved = C("and") + C("or") + C("not") + C("div") + C("mod") + C("true") + C("false")
-local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / function(t) -- todo: better . handling
- return t .. "("
-end
+-- local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / function(t) -- todo: better . handling
+-- return t .. "("
+-- end
+
+-- local lp_lua_function = (R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / "%0("
+local lp_lua_function = Cs((R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(")) / "%0"
local lp_function = C(R("az","AZ","__")^1) * P("(") / function(t) -- todo: better . handling
if expressions[t] then
@@ -599,15 +609,12 @@ local converter = Cs (
)
cleaner = Cs ( (
---~ lp_fastpos +
+ -- lp_fastpos +
lp_reserved +
lp_number +
lp_string +
1 )^1 )
-
---~ expr
-
local template_e = [[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -662,6 +669,7 @@ local function errorrunner_e(str,cnv)
end
return false
end
+
local function errorrunner_f(str,arg)
report_lpath("error in finalizer: %s(%s)",str,arg or "")
return false
@@ -673,7 +681,7 @@ end
local function register_expression(expression)
local converted = lpegmatch(converter,expression)
- local runner = loadstring(format(template_e,converted))
+ local runner = load(format(template_e,converted))
runner = (runner and runner()) or function() errorrunner_e(expression,converted) end
return { kind = "expression", expression = expression, converted = converted, evaluator = runner }
end
@@ -681,9 +689,9 @@ end
local function register_finalizer(protocol,name,arguments)
local runner
if arguments and arguments ~= "" then
- runner = loadstring(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ runner = load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
else
- runner = loadstring(format(template_f_n,protocol or xml.defaultprotocol,name))
+ runner = load(format(template_f_n,protocol or xml.defaultprotocol,name))
end
runner = (runner and runner()) or function() errorrunner_f(name,arguments) end
return { kind = "finalizer", name = name, arguments = arguments, finalizer = runner }
@@ -863,7 +871,7 @@ lpath = function (pattern) -- the gain of caching is rather minimal
local np = #parsed
if np == 0 then
parsed = { pattern = pattern, register_self, state = "parsing error" }
- report_lpath("parsing error in '%s'",pattern)
+ report_lpath("parsing error in pattern: %s",pattern)
lshow(parsed)
else
-- we could have done this with a more complex parser but this
@@ -1107,6 +1115,7 @@ end
expressions.child = function(e,pattern)
return applylpath(e,pattern) -- todo: cache
end
+
expressions.count = function(e,pattern) -- what if pattern == empty or nil
local collected = applylpath(e,pattern) -- todo: cache
return pattern and (collected and #collected) or 0
@@ -1114,13 +1123,30 @@ end
-- external
-expressions.oneof = function(s,...) -- slow
- local t = {...} for i=1,#t do if s == t[i] then return true end end return false
+-- expressions.oneof = function(s,...)
+-- local t = {...}
+-- for i=1,#t do
+-- if s == t[i] then
+-- return true
+-- end
+-- end
+-- return false
+-- end
+
+expressions.oneof = function(s,...)
+ for i=1,select("#",...) do
+ if s == select(i,...) then
+ return true
+ end
+ end
+ return false
end
+
expressions.error = function(str)
xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
return false
end
+
expressions.undefined = function(s)
return s == nil
end
@@ -1164,7 +1190,7 @@ end
-- user interface
local function traverse(root,pattern,handle)
- report_lpath("use 'xml.selection' instead for '%s'",pattern)
+ -- report_lpath("use 'xml.selection' instead for pattern: %s",pattern)
local collected = applylpath(root,pattern)
if collected then
for c=1,#collected do
@@ -1197,15 +1223,15 @@ xml.selection = selection -- new method, simple handle
-- generic function finalizer (independant namespace)
-local function dofunction(collected,fnc)
+local function dofunction(collected,fnc,...)
if collected then
local f = functions[fnc]
if f then
for c=1,#collected do
- f(collected[c])
+ f(collected[c],...)
end
else
- report_lpath("unknown function '%s'",fnc)
+ report_lpath("unknown function %a",fnc)
end
end
end
@@ -1217,7 +1243,7 @@ finalizers.tex["function"] = dofunction
expressions.text = function(e,n)
local rdt = e.__p__.dt
- return (rdt and rdt[n]) or ""
+ return rdt and rdt[n] or ""
end
expressions.name = function(e,n) -- ns + tg
@@ -1319,34 +1345,89 @@ end
</typing>
--ldx]]--
-local wrap, yield = coroutine.wrap, coroutine.yield
+-- local wrap, yield = coroutine.wrap, coroutine.yield
+-- local dummy = function() end
+--
+-- function xml.elements(root,pattern,reverse) -- r, d, k
+-- local collected = applylpath(root,pattern)
+-- if collected then
+-- if reverse then
+-- return wrap(function() for c=#collected,1,-1 do
+-- local e = collected[c] local r = e.__p__ yield(r,r.dt,e.ni)
+-- end end)
+-- else
+-- return wrap(function() for c=1,#collected do
+-- local e = collected[c] local r = e.__p__ yield(r,r.dt,e.ni)
+-- end end)
+-- end
+-- end
+-- return wrap(dummy)
+-- end
+--
+-- function xml.collected(root,pattern,reverse) -- e
+-- 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)
+-- else
+-- return wrap(function() for c=1,#collected do yield(collected[c]) end end)
+-- end
+-- end
+-- return wrap(dummy)
+-- end
+
+-- faster:
+
+local dummy = function() end
function xml.elements(root,pattern,reverse) -- r, d, k
local collected = applylpath(root,pattern)
- if collected then
- if reverse then
- return wrap(function() for c=#collected,1,-1 do
- local e = collected[c] local r = e.__p__ yield(r,r.dt,e.ni)
- end end)
- else
- return wrap(function() for c=1,#collected do
- local e = collected[c] local r = e.__p__ yield(r,r.dt,e.ni)
- end end)
+ if not collected then
+ return dummy
+ elseif reverse then
+ local c = #collected + 1
+ return function()
+ if c > 1 then
+ c = c - 1
+ local e = collected[c]
+ local r = e.__p__
+ return r, r.dt, e.ni
+ end
+ end
+ else
+ local n, c = #collected, 0
+ return function()
+ if c < n then
+ c = c + 1
+ local e = collected[c]
+ local r = e.__p__
+ return r, r.dt, e.ni
+ end
end
end
- return wrap(function() end)
end
function xml.collected(root,pattern,reverse) -- e
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)
- else
- return wrap(function() for c=1,#collected do yield(collected[c]) end end)
+ if not collected then
+ return dummy
+ elseif reverse then
+ local c = #collected + 1
+ return function()
+ if c > 1 then
+ c = c - 1
+ return collected[c]
+ end
+ end
+ else
+ local n, c = #collected, 0
+ return function()
+ if c < n then
+ c = c + 1
+ return collected[c]
+ end
end
end
- return wrap(function() end)
end
-- handy
@@ -1354,6 +1435,32 @@ end
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))
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
+end
+
+-- texy (see xfdf):
+
+local function split(e)
+ local dt = e.dt
+ if dt then
+ for i=1,#dt do
+ local dti = dt[i]
+ if type(dti) == "string" then
+ dti = gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti = gsub(dti,"[\n\r]+","\n\n")
+ dt[i] = dti
+ else
+ split(dti)
+ end
+ end
end
+ return e
+end
+
+function xml.finalizers.paragraphs(c)
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end