summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/lxml-tex.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/lxml-tex.lua')
-rw-r--r--tex/context/base/mkiv/lxml-tex.lua426
1 files changed, 296 insertions, 130 deletions
diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua
index b8280ba9c..ae3edba56 100644
--- a/tex/context/base/mkiv/lxml-tex.lua
+++ b/tex/context/base/mkiv/lxml-tex.lua
@@ -92,6 +92,8 @@ local forceraw = false
local p_texescape = patterns.texescape
+local tokenizedcs = context.tokenizedcs
+
directives.enable("xml.path.keeplastmatch")
-- tex entities
@@ -499,13 +501,29 @@ function lxml.checkindex(name)
return root and root.index or 0
end
-function lxml.withindex(name,n,command) -- will change as name is always there now
- local i, p = lpegmatch(splitter,n)
- if p then
- contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",n,"}")
- else
- contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",name,"::",n,"}")
+if tokenizedcs then
+
+ function lxml.withindex(name,n,command) -- will change as name is always there now
+ local i, p = lpegmatch(splitter,n)
+ local w = tokenizedcs.xmlw
+ if p then
+ contextsprint(ctxcatcodes,w,"{",command,"}{",n,"}")
+ else
+ contextsprint(ctxcatcodes,w,"{",command,"}{",name,"::",n,"}")
+ end
+ end
+
+else
+
+ function lxml.withindex(name,n,command) -- will change as name is always there now
+ local i, p = lpegmatch(splitter,n)
+ if p then
+ contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",n,"}")
+ else
+ contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",name,"::",n,"}")
+ end
end
+
end
function lxml.getindex(name,n) -- will change as name is always there now
@@ -728,21 +746,6 @@ end
local default_element_handler = xml.gethandlers("verbose").functions["@el@"]
--- local xmlw = setmetatableindex(function(t,k)
--- local v = setmetatableindex(function(t,kk)
--- local v
--- if kk == false then
--- v = "\\xmlw{" .. k .. "}{"
--- else
--- v = "\\xmlw{" .. k .. "}{" .. kk .. "::"
--- end
--- t[kk] = v
--- return v
--- end)
--- t[k]= v
--- return v
--- end)
-
local setfilename = false
local trace_name = false
local report_name = logs.reporter("lxml")
@@ -765,39 +768,80 @@ trackers.register("system.synctex.xml",function(v)
trace_name = v
end)
-local function tex_element(e,handlers)
- if setfilename then
- syncfilename(e,"element")
- end
- local command = e.command
- if command == nil then
- default_element_handler(e,handlers)
- elseif command == true then
- -- text (no <self></self>) / so, no mkii fallback then
- handlers.serialize(e.dt,handlers)
- elseif command == false then
- -- ignore
- else
- local tc = type(command)
- if tc == "string" then
- local rootname, ix = e.name, e.ix
- if rootname then
- if not ix then
- addindex(rootname,false,true)
- ix = e.ix
+local tex_element
+
+if tokenizedcs then
+
+ tex_element = function(e,handlers)
+ if setfilename then
+ syncfilename(e,"element")
+ end
+ local command = e.command
+ if command == nil then
+ default_element_handler(e,handlers)
+ elseif command == true then
+ -- text (no <self></self>) / so, no mkii fallback then
+ handlers.serialize(e.dt,handlers)
+ elseif command == false then
+ -- ignore
+ else
+ local tc = type(command)
+ if tc == "string" then
+ local rootname, ix = e.name, e.ix
+ local w = tokenizedcs.xmlw
+ if rootname then
+ if not ix then
+ addindex(rootname,false,true)
+ ix = e.ix
+ end
+ contextsprint(ctxcatcodes,w,"{",command,"}{",rootname,"::",ix,"}")
+ else
+ report_lxml("fatal error: no index for %a",command)
+ contextsprint(ctxcatcodes,w,"{",command,"}{",ix or 0,"}")
end
- -- faster than context.xmlw
- contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",rootname,"::",ix,"}")
- -- contextsprint(ctxcatcodes,xmlw[command][rootname],ix,"}")
- else
- report_lxml("fatal error: no index for %a",command)
- contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",ix or 0,"}")
- -- contextsprint(ctxcatcodes,xmlw[command][false],ix or 0,"}")
+ elseif tc == "function" then
+ command(e)
+ end
+ end
+ end
+
+else
+
+ tex_element = function(e,handlers)
+ if setfilename then
+ syncfilename(e,"element")
+ end
+ local command = e.command
+ if command == nil then
+ default_element_handler(e,handlers)
+ elseif command == true then
+ -- text (no <self></self>) / so, no mkii fallback then
+ handlers.serialize(e.dt,handlers)
+ elseif command == false then
+ -- ignore
+ else
+ local tc = type(command)
+ if tc == "string" then
+ local rootname, ix = e.name, e.ix
+ if rootname then
+ if not ix then
+ addindex(rootname,false,true)
+ ix = e.ix
+ end
+ -- faster than context.xmlw
+ contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",rootname,"::",ix,"}")
+ -- contextsprint(ctxcatcodes,xmlw[command][rootname],ix,"}")
+ else
+ report_lxml("fatal error: no index for %a",command)
+ contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",ix or 0,"}")
+ -- contextsprint(ctxcatcodes,xmlw[command][false],ix or 0,"}")
+ end
+ elseif tc == "function" then
+ command(e)
end
- elseif tc == "function" then
- command(e)
end
end
+
end
-- <?context-directive foo ... ?>
@@ -1180,7 +1224,7 @@ function lxml.flushsetups(id,...)
local sd = setups[document]
if sd then
for k=1,#sd do
- local v= sd[k]
+ local v = sd[k]
if not done[v] then
if trace_loading then
report_lxml("applying setup %02i : %a to %a",k,v,document)
@@ -1442,29 +1486,63 @@ end
-- the number of commands is often relative small but there can be many calls
-- to this finalizer
-local function command(collected,cmd,otherwise)
- local n = collected and #collected
- if n and n > 0 then
- local wildcard = find(cmd,"*",1,true)
- for c=1,n do -- maybe optimize for n=1
- local e = collected[c]
- local ix = e.ix
- local name = e.name
- if name and not ix then
- addindex(name,false,true)
- ix = e.ix
- end
- if not ix or not name then
- report_lxml("no valid node index for element %a using command %s",name or "?",cmd)
- elseif wildcard then
- contextsprint(ctxcatcodes,"\\xmlw{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}")
- else
- contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",name,"::",ix,"}")
+local command
+
+if tokenizedcs then
+
+ command = function(collected,cmd,otherwise)
+ local n = collected and #collected
+ local w = tokenizedcs.xmlw
+ if n and n > 0 then
+ local wildcard = find(cmd,"*",1,true)
+ for c=1,n do -- maybe optimize for n=1
+ local e = collected[c]
+ local ix = e.ix
+ local name = e.name
+ if name and not ix then
+ addindex(name,false,true)
+ ix = e.ix
+ end
+ if not ix or not name then
+ report_lxml("no valid node index for element %a using command %s",name or "?",cmd)
+ elseif wildcard then
+ contextsprint(ctxcatcodes,w,"{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}")
+ else
+ contextsprint(ctxcatcodes,w,"{",cmd,"}{",name,"::",ix,"}")
+ end
+ end
+ elseif otherwise then
+ contextsprint(ctxcatcodes,w,"{",otherwise,"}{#1}")
+ end
+ end
+
+else
+
+ command = function(collected,cmd,otherwise)
+ local n = collected and #collected
+ if n and n > 0 then
+ local wildcard = find(cmd,"*",1,true)
+ for c=1,n do -- maybe optimize for n=1
+ local e = collected[c]
+ local ix = e.ix
+ local name = e.name
+ if name and not ix then
+ addindex(name,false,true)
+ ix = e.ix
+ end
+ if not ix or not name then
+ report_lxml("no valid node index for element %a using command %s",name or "?",cmd)
+ elseif wildcard then
+ contextsprint(ctxcatcodes,"\\xmlw{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}")
+ else
+ contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",name,"::",ix,"}")
+ end
end
+ elseif otherwise then
+ contextsprint(ctxcatcodes,"\\xmlw{",otherwise,"}{#1}")
end
- elseif otherwise then
- contextsprint(ctxcatcodes,"\\xmlw{",otherwise,"}{#1}")
end
+
end
-- local wildcards = setmetatableindex(function(t,k)
@@ -1675,7 +1753,7 @@ local function concatrange(collected,start,stop,separator,lastseparator,textonly
end
end
-local function concat(collected,separator,lastseparator,textonly) -- test this on mml
+local function concatlist(collected,separator,lastseparator,textonly) -- test this on mml
concatrange(collected,false,false,separator,lastseparator,textonly)
end
@@ -1697,14 +1775,12 @@ texfinalizers.context = ctxtext
texfinalizers.position = position
texfinalizers.match = match
texfinalizers.index = index
-texfinalizers.concat = concat
+texfinalizers.concat = concatlist
texfinalizers.concatrange = concatrange
texfinalizers.chainattribute = chainattribute
texfinalizers.chainpath = chainpath
texfinalizers.default = all -- !!
-local concat = table.concat
-
function texfinalizers.tag(collected,n)
if collected then
local nc = #collected
@@ -1997,7 +2073,7 @@ do
implement {
name = "xmldoifatt",
arguments = "3 strings",
- actions = function(id,l,v)
+ actions = function(id,k,v)
local e = getid(id)
ctx_doif(e and e.at[k] == v or false)
end
@@ -2006,7 +2082,7 @@ do
implement {
name = "xmldoifnotatt",
arguments = "3 strings",
- actions = function(id,l,v)
+ actions = function(id,k,v)
local e = getid(id)
ctx_doifnot(e and e.at[k] == v or false)
end
@@ -2015,7 +2091,7 @@ do
implement {
name = "xmldoifelseatt",
arguments = "3 strings",
- actions = function(id,l,v)
+ actions = function(id,k,v)
local e = getid(id)
ctx_doifelse(e and e.at[k] == v or false)
end
@@ -2139,24 +2215,51 @@ function lxml.direct(id)
end
end
-function lxml.command(id,pattern,cmd)
- local i, p = getid(id,true)
- local collected = xmlapplylpath(getid(i),pattern)
- if collected then
- local nc = #collected
- if nc > 0 then
- local rootname = p or i.name
- for c=1,nc do
- local e = collected[c]
- local ix = e.ix
- if not ix then
- addindex(rootname,false,true)
- ix = e.ix
+if tokenizedcs then
+
+ function lxml.command(id,pattern,cmd)
+ local i, p = getid(id,true)
+ local collected = xmlapplylpath(getid(i),pattern)
+ if collected then
+ local nc = #collected
+ if nc > 0 then
+ local rootname = p or i.name
+ local w = tokenizedcs.xmlw
+ for c=1,nc do
+ local e = collected[c]
+ local ix = e.ix
+ if not ix then
+ addindex(rootname,false,true)
+ ix = e.ix
+ end
+ contextsprint(ctxcatcodes,w,"{",cmd,"}{",rootname,"::",ix,"}")
+ end
+ end
+ end
+ end
+
+else
+
+ function lxml.command(id,pattern,cmd)
+ local i, p = getid(id,true)
+ local collected = xmlapplylpath(getid(i),pattern)
+ if collected then
+ local nc = #collected
+ if nc > 0 then
+ local rootname = p or i.name
+ for c=1,nc do
+ local e = collected[c]
+ local ix = e.ix
+ if not ix then
+ addindex(rootname,false,true)
+ ix = e.ix
+ end
+ contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}")
end
- contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}")
end
end
end
+
end
-- loops
@@ -2292,13 +2395,13 @@ function texfinalizers.lettered(collected)
end
end
---~ function texfinalizers.apply(collected,what) -- to be tested
---~ if collected then
---~ for c=1,#collected do
---~ contextsprint(ctxcatcodes,what(collected[c].dt[1]))
---~ end
---~ end
---~ end
+-- function texfinalizers.apply(collected,what) -- to be tested
+-- if collected then
+-- for c=1,#collected do
+-- contextsprint(ctxcatcodes,what(collected[c].dt[1]))
+-- end
+-- end
+-- end
function lxml.toparameters(id)
local e = getid(id)
@@ -2357,49 +2460,56 @@ end
-- parameters
-function lxml.setatt(id,name,value)
- local e = getid(id)
- if e then
- local a = e.at
- if a then
- a[name] = value
- else
- e.at = { [name] = value }
+do
+
+ local function setatt(id,name,value)
+ local e = getid(id)
+ if e then
+ local a = e.at
+ if a then
+ a[name] = value
+ else
+ e.at = { [name] = value }
+ end
end
end
-end
-function lxml.setpar(id,name,value)
- local e = getid(id)
- if e then
- local p = e.pa
- if p then
- p[name] = value
- else
- e.pa = { [name] = value }
+ local function setpar(id,name,value)
+ local e = getid(id)
+ if e then
+ local p = e.pa
+ if p then
+ p[name] = value
+ else
+ e.pa = { [name] = value }
+ end
end
end
-end
-function lxml.setattribute(id,pattern,name,value)
- local collected = xmlapplylpath(getid(id),pattern)
- if collected then
- for i=1,#collected do
- setatt(collected[i],name,value)
+ lxml.setatt = setatt
+ lxml.setpar = setpar
+
+ function lxml.setattribute(id,pattern,name,value)
+ local collected = xmlapplylpath(getid(id),pattern)
+ if collected then
+ for i=1,#collected do
+ setatt(collected[i],name,value)
+ end
end
end
-end
-function lxml.setparameter(id,pattern,name,value)
- local collected = xmlapplylpath(getid(id),pattern)
- if collected then
- for i=1,#collected do
- setpar(collected[i],name,value)
+ function lxml.setparameter(id,pattern,name,value)
+ local collected = xmlapplylpath(getid(id),pattern)
+ if collected then
+ for i=1,#collected do
+ setpar(collected[i],name,value)
+ end
end
end
-end
-lxml.setparam = lxml.setparameter
+ lxml.setparam = lxml.setparameter
+
+end
-- relatively new:
@@ -2629,3 +2739,59 @@ function texfinalizers.xml(collected,name,setup)
buffers.assign(name,strip(xmltostring(root)))
context.xmlprocessbuffer(name,name,setup or (name..":setup"))
end
+
+-- experiment
+
+do
+
+ local xmltoelement = xml.toelement
+ local xmlreindex = xml.reindex
+
+ function lxml.replace(root,pattern,whatever)
+ if type(root) == "string" then
+ root = lxml.getid(root)
+ end
+ local collected = xmlapplylpath(root,pattern)
+ if collected then
+ local isstring = type(whatever) == "string"
+ for c=1,#collected do
+ local e = collected[c]
+ local p = e.__p__
+ if p then
+ local d = p.dt
+ local n = e.ni
+ local w = isstring and whatever or whatever(e)
+ if w then
+ local t = xmltoelement(w,root).dt
+ if t then
+ t.__p__ = p
+ if type(t) == "table" then
+ local t1 = t[1]
+ d[n] = t1
+ t1.at.type = e.at.type or t1.at.type
+ for i=2,#t do
+ n = n + 1
+ insert(d,n,t[i])
+ end
+ else
+ d[n] = t
+ end
+ xmlreindex(d) -- probably not needed
+ end
+ end
+ end
+ end
+ end
+ end
+
+ -- function document.mess_around(root)
+ -- lxml.replace(
+ -- root,
+ -- "p[@variant='foo']",
+ -- function(c)
+ -- return (string.gsub(tostring(c),"foo","<bar>%1</bar>"))
+ -- end
+ -- )
+ -- end
+
+end