5 strip_escapes
= function (self
, s
)
6 s
= string.gsub(s
, '>', '>')
7 s
= string.gsub(s
, '<', '<')
11 parseargs
= function (self
, s
)
13 string.gsub(s
, "([%w_]+)=([\"'])(.-)%2", function (w
, _
, a
)
14 arg
[self
:strip_escapes(w
)] = self
:strip_escapes(a
)
19 collect
= function (self
, s
)
22 table.insert(stack
, top
)
23 local ni
,c
,label
,xarg
, empty
26 ni
,j
,c
,label
,xarg
, empty
= string.find(s
, "<(%/?)(%w+)(.-)(%/?)>", j
)
27 if not ni
then break end
28 local text
= string.sub(s
, i
, ni
-1)
29 if not string.find(text
, "^%s*$") then
30 table.insert(top
, text
)
32 if empty
== "/" then -- empty element tag
33 table.insert(top
, {tag=label
, attr
=self
:parseargs(xarg
), empty
=1})
34 elseif c
== "" then -- start tag
35 top
= {tag=label
, attr
=self
:parseargs(xarg
)}
36 table.insert(stack
, top
) -- new level
38 local toclose
= table.remove(stack
) -- remove top
41 error("nothing to close with "..label
)
43 if toclose
.tag ~= label
then
44 error("trying to close "..toclose
.label
.." with "..label
)
46 table.insert(top
, toclose
)
50 local text
= string.sub(s
, i
)
51 if not string.find(text
, "^%s*$") then
52 table.insert(stack
[stack
.n
], text
)
55 error("unclosed "..stack
[stack
.n
].label
)