diff options
author | Mojca Miklavec <mojca.miklavec@gmail.com> | 2012-05-14 17:38:55 +0000 |
---|---|---|
committer | Mojca Miklavec <mojca.miklavec@gmail.com> | 2012-05-14 17:38:55 +0000 |
commit | 15995e10bfc68edf79970c4ea4fbb6678566c46e (patch) | |
tree | 2de7ca2a83f2d37ef043ad7429a5cb945bb79ddb /Master/texmf-dist/tex/context/base/lxml-xml.lua | |
parent | c9a39f716f1e5ec820ed3aab2c9aef25c5a9d730 (diff) |
ConTeXt 2012.05.14 16:00
git-svn-id: svn://tug.org/texlive/trunk@26371 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/lxml-xml.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/lxml-xml.lua | 287 |
1 files changed, 180 insertions, 107 deletions
diff --git a/Master/texmf-dist/tex/context/base/lxml-xml.lua b/Master/texmf-dist/tex/context/base/lxml-xml.lua index 89fcba871bd..7e7922cfb25 100644 --- a/Master/texmf-dist/tex/context/base/lxml-xml.lua +++ b/Master/texmf-dist/tex/context/base/lxml-xml.lua @@ -6,15 +6,17 @@ if not modules then modules = { } end modules ['lxml-xml'] = { license = "see context related readme files" } -local concat = string.concat +local concat = table.concat +local find = string.find local xml = xml -local finalizers = xml.finalizers.xml -local xmlfilter = xml.filter -- we could inline this one for speed -local xmltostring = xml.tostring -local xmlserialize = xml.serialize -local xmlcollected = xml.collected +local finalizers = xml.finalizers.xml +local xmlfilter = xml.filter -- we could inline this one for speed +local xmltostring = xml.tostring +local xmlserialize = xml.serialize +local xmlcollected = xml.collected +local xmlnewhandlers = xml.newhandlers local function first(collected) -- wrong ? return collected and collected[1] @@ -28,16 +30,21 @@ local function all(collected) return collected end ---~ local function reverse(collected) ---~ if collected then ---~ local reversed, r = { }, 0 ---~ for c=#collected,1,-1 do ---~ r = r + 1 ---~ reversed[r] = collected[c] ---~ end ---~ return reversed ---~ end ---~ end +-- local function reverse(collected) +-- if collected then +-- local nc = #collected +-- if nc > 0 then +-- local reversed, r = { }, 0 +-- for c=nc,1,-1 do +-- r = r + 1 +-- reversed[r] = collected[c] +-- end +-- return reversed +-- else +-- return collected +-- end +-- end +-- end local reverse = table.reversed @@ -54,34 +61,37 @@ local function att(id,name) end local function count(collected) - return (collected and #collected) or 0 + return collected and #collected or 0 end local function position(collected,n) - if collected then - n = tonumber(n) or 0 - if n < 0 then - return collected[#collected + n + 1] - elseif n > 0 then - return collected[n] - else - return collected[1].mi or 0 - end + if not collected then + return 0 + end + local nc = #collected + if nc == 0 then + return 0 + end + n = tonumber(n) or 0 + if n < 0 then + return collected[nc + n + 1] + elseif n > 0 then + return collected[n] + else + return collected[1].mi or 0 end end local function match(collected) - return (collected and collected[1].mi) or 0 -- match + return collected and #collected > 0 and collected[1].mi or 0 -- match end local function index(collected) - if collected then - return collected[1].ni - end + return collected and #collected > 0 and collected[1].ni or 0 -- 0 is new end local function attributes(collected,arguments) - if collected then + if collected and #collected > 0 then local at = collected[1].at if arguments then return at[arguments] @@ -92,7 +102,7 @@ local function attributes(collected,arguments) end local function chainattribute(collected,arguments) -- todo: optional levels - if collected then + if collected and #collected > 0 then local e = collected[1] while e do local at = e.at @@ -110,108 +120,169 @@ local function chainattribute(collected,arguments) -- todo: optional levels return "" end -local function raw(collected) -- hybrid - if collected then +local function raw(collected) -- hybrid (not much different from text so it might go) + if collected and #collected > 0 then local e = collected[1] or collected - return (e and xmlserialize(e)) or "" -- only first as we cannot concat function + return e and xmltostring(e) or "" -- only first as we cannot concat function else return "" end end +-- + +local xmltexthandler = xmlnewhandlers { + name = "string", + initialize = function() + result = { } + return result + end, + finalize = function() + return concat(result) + end, + handle = function(...) + result[#result+1] = concat { ... } + end, + escape = false, +} + +local function xmltotext(root) + local dt = root.dt + if not dt then + return "" + end + local nt = #dt -- string or table + if nt == 0 then + return "" + elseif nt == 1 and type(dt[1]) == "string" then + return dt[1] -- no escaping of " ' < > & + else + return xmlserialize(root,xmltexthandler) or "" + end +end + +-- + local function text(collected) -- hybrid - if collected then - local e = collected[1] or collected - return (e and xmltostring(e.dt)) or "" + if collected then -- no # test here ! + local e = collected[1] or collected -- why fallback to element, how about cdata + return e and xmltotext(e) or "" else return "" end end local function texts(collected) - if collected then - local t, n = { }, 0 - for c=1,#collected do - local e = collected[c] - if e and e.dt then - n = n + 1 - t[n] = e.dt - end + if not collected then + return { } -- why no nil + end + local nc = #collected + if nc == 0 then + return { } -- why no nil + end + local t, n = { }, 0 + for c=1,nc do + local e = collected[c] + if e and e.dt then + n = n + 1 + t[n] = e.dt end - return t end + return t end local function tag(collected,n) - if collected then - local c - if n == 0 or not n then - c = collected[1] - elseif n > 1 then - c = collected[n] - else - c = collected[#collected-n+1] - end - return c and c.tg + if not collected then + return + end + local nc = #collected + if nc == 0 then + return + end + local c + if n == 0 or not n then + c = collected[1] + elseif n > 1 then + c = collected[n] + else + c = collected[nc-n+1] end + return c and c.tg end local function name(collected,n) - if collected then - local c - if n == 0 or not n then - c = collected[1] - elseif n > 1 then - c = collected[n] - else - c = collected[#collected-n+1] - end - if c then - if c.ns == "" then - return c.tg - else - return c.ns .. ":" .. c.tg - end - end + if not collected then + return + end + local nc = #collected + if nc == 0 then + return + end + local c + if n == 0 or not n then + c = collected[1] + elseif n > 1 then + c = collected[n] + else + c = collected[nc-n+1] + end + if not c then + -- sorry + elseif c.ns == "" then + return c.tg + else + return c.ns .. ":" .. c.tg end end local function tags(collected,nonamespace) - if collected then - local t, n = { }, 0 - for c=1,#collected do - local e = collected[c] - local ns, tg = e.ns, e.tg - n = n + 1 - if nonamespace or ns == "" then - t[n] = tg - else - t[n] = ns .. ":" .. tg - end + if not collected then + return + end + local nc = #collected + if nc == 0 then + return + end + local t, n = { }, 0 + for c=1,nc do + local e = collected[c] + local ns, tg = e.ns, e.tg + n = n + 1 + if nonamespace or ns == "" then + t[n] = tg + else + t[n] = ns .. ":" .. tg end - return t end + return t end -local function empty(collected) - if collected then - for c=1,#collected do - local e = collected[c] - if e then - local edt = e.dt - if edt then - local n = #edt - if n == 1 then - local edk = edt[1] - local typ = type(edk) - if typ == "table" then - return false - elseif edk ~= "" then -- maybe an extra tester for spacing only - return false - end - elseif n > 1 then +local function empty(collected,spacesonly) + if not collected then + return true + end + local nc = #collected + if nc == 0 then + return true + end + for c=1,nc do + local e = collected[c] + if e then + local edt = e.dt + if edt then + local n = #edt + if n == 1 then + local edk = edt[1] + local typ = type(edk) + if typ == "table" then + return false + elseif edk ~= "" then + return false + elseif spacesonly and not find(edk,"%S") then return false end + elseif n > 1 then + return false end end end @@ -266,14 +337,14 @@ function xml.raw(id,pattern) end end -function xml.text(id,pattern) +function xml.text(id,pattern) -- brrr either content or element (when cdata) if pattern then -- return text(xmlfilter(id,pattern)) local collected = xmlfilter(id,pattern) - return (collected and xmltostring(collected[1].dt)) or "" + return collected and #collected > 0 and xmltotext(collected[1]) or "" elseif id then -- return text(id) - return xmltostring(id.dt) or "" + return xmltotext(id) or "" else return "" end @@ -281,6 +352,8 @@ end xml.content = text +-- + function xml.position(id,pattern,n) -- element return position(xmlfilter(id,pattern),n) end @@ -289,8 +362,8 @@ function xml.match(id,pattern) -- number return match(xmlfilter(id,pattern)) end -function xml.empty(id,pattern) - return empty(xmlfilter(id,pattern)) +function xml.empty(id,pattern,spacesonly) + return empty(xmlfilter(id,pattern),spacesonly) end xml.all = xml.filter |