2021-04-18 15:19:52 +02:00
|
|
|
-- FIXME: Not sure yet if this will be needed
|
|
|
|
local function escape_name(name)
|
|
|
|
return name
|
|
|
|
end
|
|
|
|
|
|
|
|
local escapes = {
|
|
|
|
['"'] = """,
|
|
|
|
['<'] = "<",
|
|
|
|
['>'] = ">",
|
|
|
|
['&'] = "&",
|
|
|
|
}
|
|
|
|
local function escape_text(text)
|
2023-12-20 19:22:21 +01:00
|
|
|
return string.gsub(string.gsub(tostring(text), '["<>&]', escapes), '[\x00-\x08\x0B\x0C\x0E-\x1F]', function(x)
|
2023-12-19 23:27:31 +01:00
|
|
|
return string.format('^^%02x', string.byte(x))
|
|
|
|
end)
|
2021-04-18 15:19:52 +02:00
|
|
|
end
|
2023-12-19 23:27:31 +01:00
|
|
|
print("<node>", escape_text"<node>")
|
2021-04-18 15:19:52 +02:00
|
|
|
|
2021-04-26 16:01:57 +02:00
|
|
|
local attrs = {}
|
2021-04-19 13:30:54 +02:00
|
|
|
local function write_elem(tree, indent)
|
2021-04-18 15:19:52 +02:00
|
|
|
if not tree[0] then print('ERR', require'inspect'(tree)) end
|
|
|
|
local escaped_name = escape_name(assert(tree[0]))
|
2021-04-26 16:01:57 +02:00
|
|
|
local i = 0
|
2021-05-12 07:43:57 +02:00
|
|
|
for attr, val in next, tree do if type(attr) == 'string' and string.byte(attr) ~= 0x3A then
|
2021-04-26 16:01:57 +02:00
|
|
|
i = i + 1
|
|
|
|
attrs[i] = string.format(' %s="%s"', escape_name(attr), escape_text(val))
|
2021-04-18 15:19:52 +02:00
|
|
|
end end
|
2021-04-26 16:01:57 +02:00
|
|
|
table.sort(attrs)
|
|
|
|
local out = string.format('%s<%s%s', indent or '', escaped_name, table.concat(attrs))
|
|
|
|
for j = 1, i do attrs[j] = nil end
|
2021-04-18 15:19:52 +02:00
|
|
|
if not tree[1] then
|
|
|
|
return out .. '/>'
|
|
|
|
end
|
|
|
|
out = out .. '>'
|
2021-04-19 13:30:54 +02:00
|
|
|
local inner_indent = indent and indent .. ' '
|
2021-06-23 18:48:30 +02:00
|
|
|
local is_string
|
2021-04-18 15:19:52 +02:00
|
|
|
for _, elem in ipairs(tree) do
|
|
|
|
if type(elem) == 'string' then
|
2021-06-23 18:48:30 +02:00
|
|
|
if inner_indent and not is_string then
|
2021-04-19 13:30:54 +02:00
|
|
|
out = out .. inner_indent
|
|
|
|
end
|
2021-04-18 15:19:52 +02:00
|
|
|
out = out .. escape_text(elem)
|
2021-06-23 18:48:30 +02:00
|
|
|
is_string = true
|
2021-04-18 15:19:52 +02:00
|
|
|
else
|
2021-04-19 13:30:54 +02:00
|
|
|
out = out .. write_elem(elem, inner_indent)
|
2021-06-23 18:48:30 +02:00
|
|
|
is_string = nil
|
2021-04-18 15:19:52 +02:00
|
|
|
end
|
|
|
|
end
|
2021-04-19 13:30:54 +02:00
|
|
|
if indent then out = out .. indent end
|
2021-04-18 15:19:52 +02:00
|
|
|
return out .. '</' .. escaped_name .. '>'
|
|
|
|
end
|
|
|
|
|
2021-04-23 02:58:07 +02:00
|
|
|
return function(element, indent, version)
|
|
|
|
return (version == '11' and '<?xml version="1.1"?>' or '') ..
|
2021-05-18 21:01:48 +02:00
|
|
|
write_elem(element, indent and '\n' or nil)
|
2021-04-23 02:58:07 +02:00
|
|
|
end
|