diff options
Diffstat (limited to 'tex/context/base/mkiv/lxml-tex.lua')
-rw-r--r-- | tex/context/base/mkiv/lxml-tex.lua | 426 |
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 |