3 local parseargs
, collect
10 local strip_escapes
= function (s
)
11 s
= string.gsub(s
, '&(%a+);', escapes
)
18 string.gsub(s
, "([%w_]+)=([\"'])(.-)%2", function (w
, _
, a
)
19 arg
[strip_escapes(w
)] = strip_escapes(a
)
28 table.insert(stack
, top
)
29 local ni
,c
,label
,xarg
, empty
32 ni
,j
,c
,label
,xarg
, empty
= string.find(s
, "<(%/?)(%w+)(.-)(%/?)>", j
)
33 if not ni
then break end
34 local text
= string.sub(s
, i
, ni
-1)
35 if not string.find(text
, "^%s*$") then
36 table.insert(top
, strip_escapes(text
))
38 if empty
== "/" then -- empty element tag
39 table.insert(top
, {label
=label
, xarg
=parseargs(xarg
), empty
=1})
40 elseif c
== "" then -- start tag
41 top
= {label
=label
, xarg
=parseargs(xarg
)}
42 table.insert(stack
, top
) -- new level
44 local toclose
= table.remove(stack
) -- remove top
47 error("nothing to close with "..label
)
49 if toclose
.label
~= label
then
50 error("trying to close "..toclose
.label
.." with "..label
)
52 table.insert(top
, toclose
)
59 local text
= string.sub(s
, i
)
60 if not string.find(text
, "^%s*$") then
61 table.insert(stack
[#stack
], text
)
64 error("unclosed "..stack
[stack
.n
].label
)
66 return stack
[1], index