summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2007-05-29 14:28:53 +0000
committerpixel <pixel>2007-05-29 14:28:53 +0000
commitbcc024ab0bdc16e44d53d4a321bed4e6d561e199 (patch)
treef016323e6165b7b2b67b94684e0b3e5eaeec8118
parent40a2c21bd463914eec1e9bb44f67b8d4665aaef7 (diff)
Improving/Debugging XmlMarkup engine - now we are using a real tree in memory before rendering the object.
-rw-r--r--lib/xmllib.lua135
1 files changed, 112 insertions, 23 deletions
diff --git a/lib/xmllib.lua b/lib/xmllib.lua
index 1ef0f33..f2b452c 100644
--- a/lib/xmllib.lua
+++ b/lib/xmllib.lua
@@ -1,4 +1,4 @@
-local xml_remplacements = {
+local xml_replacements = {
{ "&", "&amp;" },
{ "<", "&lt;" },
{ ">", "&gt;" },
@@ -8,58 +8,144 @@ local attribute_replacements = {
{ '"', '\\"' },
}
-local function generic_escape(str, remplacements)
+local function generic_escape(str, replacements)
local _, r
- for _, r in pairs(xml_replacements) do
+ for _, r in pairs(replacements) do
str = string.gsub(str, r[1], r[2])
end
+
+ return str
end
local function xml_escape(str)
return generic_escape(str, xml_replacements)
end
-local function attribute_replacements(str)
+local function attribute_escape(str)
return generic_escape(str, attribute_replacements)
end
local function process_comment(xm, a)
- return "<!-- " .. a .. " -->"
+ return {
+ istop = true,
+ nodes = {
+ a
+ },
+ type = "comment",
+ }
end
-local function process_tag(xm, key, a)
- local middle, attrs, attrs_str, k, v, b
+local function process_lf(xm)
+ return {
+ istop = true,
+ type = "lf",
+ }
+end
+
+local function burrow(t)
+ local k, v
- middle = ""
- attrs = {}
+ if type(t) ~= "table" then return end
+ if type(t.istop) ~= "boolean" then return end
+
+ t.istop = nil
+end
+
+local function clean_tops(t)
+ local k, v
+
+ for k, v in pairs(t) do
+ if not v.istop then
+ t[k] = nil
+ end
+ end
+end
+
+local function process_tag(xm, key, a)
+ local ret, attrs, nodes, has_nodes, has_attrs, k, v, b = { istop = true, key = key }, {}, {}, false, false
if type(a) == "table" then
for k, v in ipairs(a) do
- middle = middle .. v
+ if type(v) == "table" then
+ burrow(v)
+ has_nodes = true
+ table.insert(nodes, v)
+ elseif type(v) == "string" then
+ has_nodes = true
+ table.insert(nodes, xml_escape(v))
+ else
+ error "Unsupported argument type."
+ end
end
for k, v in pairs(a) do
if (type(k) == "string") then
- attrs[k] = attribute_replacements(xml_replacements(v))
+ has_attrs = true
+ attrs[k] = attribute_escape(xml_escape(v))
end
end
elseif type(a) == "string" then
- middle = xml_escape(a)
+ has_nodes = true
+ table.insert(nodes, xml_escape(a))
end
+
+ if (has_nodes) then ret.nodes = nodes end
+ if (has_attrs) then ret.attrs = attrs end
+
+ table.insert(xm.tops, ret)
- if middle ~= "" then
- attrs_str = ""
- for k, v in pairs(attrs) do
- if (v == "") then
- attrs_str = " " .. attrs_str .. k
- else
- attrs_str = " " .. attrs_str .. k .. '="' .. v .. '"'
+ clean_tops(xm.tops)
+
+ return ret
+end
+
+local function render_attrs(t)
+ local r, k, v
+
+ if type(t) ~= "table" then return "" end
+
+ for k, v in pairs(t) do
+ r = r .. " " .. k .. '="' .. v .. '"'
+ end
+
+ return r
+end
+
+local function do_render_r(v)
+ local middle, i, n = ""
+
+ if v.type == "comment" then
+ return "<!-- " .. v.nodes[1] .. " -->"
+ elseif v.type == "lf" then
+ return "\n"
+ elseif type(v.key) == "string" then
+ if type(v.nodes) == "table" then
+ for i, n in ipairs(v.nodes) do
+ if type(n) == "string" then
+ middle = middle .. n
+ elseif type(n) == "table" then
+ middle = middle .. do_render_r(n)
+ end
end
+ return "<" .. v.key .. render_attrs(v.attrs) .. ">" .. middle .. "</" .. v.key .. ">"
+ else
+ return "<" .. v.key .. render_attrs(v.attrs) .. " />"
end
- return "<" .. key .. attrs_str .. ">" .. middle .. "</" .. key .. ">"
else
- return "<" .. key .. " />"
+ error "Inconsistancy in the XML structure."
end
+
+ return ""
+end
+
+local function do_render(xm)
+ local r, i, n = ""
+
+ for i, n in pairs(xm.tops) do
+ r = r .. do_render_r(n)
+ end
+
+ return xm.doctype .. "\n" .. r
end
local xmlmarkup_metatable = {
@@ -72,6 +158,10 @@ local xmlmarkup_metatable = {
function NewXmlMarkup()
local r = {
comment = process_comment,
+ lf = process_lf,
+ tops = {},
+ render = do_render,
+ doctype = '<?xml version="1.0" encoding="UTF-8"?>',
}
setmetatable(r, xmlmarkup_metatable)
@@ -88,7 +178,6 @@ end
xm = NewXmlMarkup()
-s =
xm:html {
xm:head {
xm:title "Test"
@@ -103,6 +192,6 @@ xm:html {
}
}
-print(s)
+print(xm:render())
]]--