3 local parseargs
, collect
, strip_escapes
5 strip_escapes
= function (s
)
6 s
= string.gsub(s
, '>', '>')
7 s
= string.gsub(s
, '<', '<')
14 string.gsub(s
, "([%w_]+)=([\"'])(.-)%2", function (w
, _
, a
)
15 arg
[strip_escapes(w
)] = strip_escapes(a
)
24 table.insert(stack
, top
)
25 local ni
,c
,label
,xarg
, empty
28 ni
,j
,c
,label
,xarg
, empty
= string.find(s
, "<(%/?)(%w+)(.-)(%/?)>", j
)
29 if not ni
then break end
30 local text
= string.sub(s
, i
, ni
-1)
31 if not string.find(text
, "^%s*$") then
32 table.insert(top
, text
)
34 if empty
== "/" then -- empty element tag
35 table.insert(top
, {label
=label
, xarg
=parseargs(xarg
), empty
=1})
36 elseif c
== "" then -- start tag
37 top
= {label
=label
, xarg
=parseargs(xarg
)}
38 table.insert(stack
, top
) -- new level
40 local toclose
= table.remove(stack
) -- remove top
43 error("nothing to close with "..label
)
45 if toclose
.label
~= label
then
46 error("trying to close "..toclose
.label
.." with "..label
)
48 table.insert(top
, toclose
)
50 if toclose
.xarg
.id
then
51 idindex
[toclose
.xarg
.id
] = toclose
56 local text
= string.sub(s
, i
)
57 if not string.find(text
, "^%s*$") then
58 table.insert(stack
[#stack
], text
)
61 error("unclosed "..stack
[stack
.n
].label
)
63 return stack
[1], idindex