save the modifier list in ClassModelItem
[lqt.git] / generator / xml.lua
blob4a41d3a91d7ea36b810bd0e1c13728b7cc8f5c11
1 #!/usr/bin/lua
3 --[[
5 Copyright (c) 2007-2008 Mauro Iazzi
7 Permission is hereby granted, free of charge, to any person
8 obtaining a copy of this software and associated documentation
9 files (the "Software"), to deal in the Software without
10 restriction, including without limitation the rights to use,
11 copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the
13 Software is furnished to do so, subject to the following
14 conditions:
16 The above copyright notice and this permission notice shall be
17 included in all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 OTHER DEALINGS IN THE SOFTWARE.
28 --]]
31 local parseargs, collect
33 local escapes = {
34 gt = '>',
35 lt = '<',
38 local strip_escapes = function (s)
39 s = string.gsub(s, '&(%a+);', escapes)
40 s = string.gsub(s, '&amp;', '&')
41 return s
42 end
45 function parseargs(s)
46 local arg = {}
47 string.gsub(s, "([%w_]+)=([\"'])(.-)%2", function (w, _, a)
48 arg[strip_escapes(w)] = strip_escapes(a)
49 end)
50 return arg
51 end
53 function collect(s)
54 local stack = {}
55 local index = {}
56 local top = {}
57 table.insert(stack, top)
58 local ni,c,label,xarg, empty
59 local i, j = 1, 1
60 while true do
61 ni,j,c,label,xarg, empty = string.find(s, "<(%/?)(%w+)(.-)(%/?)>", j)
62 if not ni then break end
63 local text = string.sub(s, i, ni-1)
64 if not string.find(text, "^%s*$") then
65 table.insert(top, strip_escapes(text))
66 end
67 if empty == "/" then -- empty element tag
68 table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
69 elseif c == "" then -- start tag
70 top = {label=label, xarg=parseargs(xarg)}
71 table.insert(stack, top) -- new level
72 else -- end tag
73 local toclose = table.remove(stack) -- remove top
74 top = stack[#stack]
75 if #stack < 1 then
76 error("nothing to close with "..label)
77 end
78 if toclose.label ~= label then
79 error("trying to close "..toclose.label.." with "..label)
80 end
81 table.insert(top, toclose)
82 toclose.parent = top
83 toclose.index = #top
84 index[toclose] = true
85 end
86 i = j+1
87 end
88 local text = string.sub(s, i)
89 if not string.find(text, "^%s*$") then
90 table.insert(stack[#stack], text)
91 end
92 if #stack > 1 then
93 error("unclosed "..stack[stack.n].label)
94 end
95 return stack[1], index
96 end
98 return collect