# HG changeset patch # User Matthew Wild # Date 1294073226 0 # Node ID 783004a1222460e9c98db5cd5adde1c79ec185c6 # Parent 692d221ef9bd26887987f5449498e59adbf16641 util.xmllex: Add diff -r 692d221ef9bd -r 783004a12224 util/xmllex.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/xmllex.lua Mon Jan 03 16:47:06 2011 +0000 @@ -0,0 +1,157 @@ +a=[[ + + + + + +]] +b=[[ + + Wow, I'm green with envy! + + +

+ Wow, I'm green + with envy! +

+ + +
+]] + +local ipairs , pairs , setmetatable = ipairs , pairs , setmetatable +local strsub = string.sub +local tblconcat = table.concat + +local function getstring ( stringindex , startmsg , startpos , finishmsg , finishpos ) + if startmsg == finishmsg then --All originated in same string + return strsub ( stringindex [ startmsg ] , startpos , finishpos ) + else -- Over multiple source strings + return strsub ( stringindex [ startmsg ] , startpos , -1 ) + .. tblconcat ( stringindex , "" , startmsg + 1 , finishmsg - 1 ) + .. strsub ( stringindex [ finishmsg ] , 1 , finishpos ) + end +end + +local m_mt = { + __tostring = function ( v ) + return getstring ( v.stringindex , v.startmsg , v.starte + 1 , v.finishmsg , v.finishs - 1 ) + end +} + +local function index ( str , r ) + local stringindex + local curstr , nexti + if r then + stringindex = r.stringindex or { } + curstr = #stringindex + 1 + stringindex [ curstr ] = str + + nexti = #r + else + stringindex = { str } + curstr = 1 + + r = { stringindex = stringindex } + + nexti = 0 + end + + local m + do + local t = r [ nexti ] + if t and not t.finish then + m = t + else + m = setmetatable ( { stringindex = stringindex } , m_mt ) + nexti = nexti + 1 + end + end + + local d = 0 + while true do + local a , b , c , close , selfclosing + + if not m.start then + a , b , close = str:find ( "<(/?)" , d ) + + if not a then break end + m.startmsg = curstr + m.start = a + m.starte = b + if close == "/" then + m.closed = true + else + m.closed = false + end + end + + r [ nexti ] = m + nexti = nexti + 1 + + c , d , selfclosing = str:find ( "(/?)>" , b ) + if not c then + return false , r + end + m.finishmsg = curstr + m.finish = d + m.finishs = c + m.selfclosed = selfclosing == "/" + + m = setmetatable ( { stringindex = stringindex } , m_mt ) + end + return r +end + +local function tagindex_to_tree(indices) + local root = {} + local leaf = root + local stringindex = indices.stringindex + for k ,v in ipairs ( indices ) do + if v.selfclosed then + print("selfclosed",v) + leaf [ #leaf + 1 ] = { + parent = leaf ; + selfclosing = v ; + } + elseif v.closed then + print("close",v) + leaf.endtag = v + leaf = leaf.parent + else + print("open",v) + + local newleaf = { + parent = leaf ; + starttag = v ; + } + leaf [ #leaf + 1 ] = newleaf + leaf = newleaf + end + end + assert ( leaf == root , "Mismatched opening/closing tags" ) + return root; +end + +local function getattributes ( starttag ) + local str = tostring ( starttag ) + + local attr = { } + local elem = str:match ( "[^%s=>