summaryrefslogtreecommitdiff
path: root/xml.lua
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-09-03 12:52:17 +0100
committerubq323 <ubq323@ubq323.website>2024-09-03 12:52:17 +0100
commitb3de433cfd4e39c8fe6d776e258db3b44a3ddd39 (patch)
tree1467b88252052836f6344793eee2fe51b7dc5947 /xml.lua
parent643e4202f4c5a5ee7a87779ffb69928e685db451 (diff)
more thing
Diffstat (limited to 'xml.lua')
-rw-r--r--xml.lua80
1 files changed, 79 insertions, 1 deletions
diff --git a/xml.lua b/xml.lua
index 7153831..35d2804 100644
--- a/xml.lua
+++ b/xml.lua
@@ -1,6 +1,7 @@
-- originally from http://lua-users.org/wiki/LuaXml
-- modified by me a bit
+
local function parseargs(s)
local arg = {}
string.gsub(s, "([%-%w]+)=([\"'])(.-)%2", function (w, _, a)
@@ -69,6 +70,7 @@ do
local _, cqa = pcall(require, 'cqueues.auxlib')
wrap = cqa and cqa.wrap or coroutine.wrap
end
+
local function stanzae(getmore)
return wrap(function()
local buf = ''
@@ -85,5 +87,81 @@ local function stanzae(getmore)
end)
end
+local entity_escapes = {
+ ["<"]="&lt;",
+ [">"]="&gt;",
+ ["&"]="&amp;",
+ ['"']="&quot;",
+ ["'"]="&apos;"
+}
+
+local function escape(s)
+ return s:gsub("[<>&'\"]",entity_escapes)
+end
+
+local safestr_mt = {name='SAFESTR', __tostring=function(x) return x.s end}
+local function safestr(s) return setmetatable({s=s}, safestr_mt) end
+
+local function _xmlify(x)
+ if getmetatable(x) == safestr_mt then
+ return x
+ elseif type(x) == 'string' then
+ return safestr(escape(x))
+ elseif type(x) == 'table' then -- must be a tag
+ local function argstr(t)
+ local argstring = ''
+ for k,v in pairs(t) do
+ argstring = argstring .. (" %s='%s'"):format(k, _xmlify(v))
+ end
+ return argstring
+ end
+ if x.empty then
+ return safestr(("<%s%s/>"):format(x.label, argstr(x.xarg)))
+ else
+ local open = ("<%s%s>"):format(x.label, argstr(x.xarg))
+ local close = ("</%s>"):format(x.label)
+ local children = {}
+ for _,child in ipairs(x) do
+ table.insert(children, tostring(_xmlify(child)))
+ end
+ return safestr(open .. table.concat(children, '') .. close)
+ end
+ end
+end
+
+local function xmlify(...)
+ local n = select('#',...)
+ if n <= 1 then return _xmlify(...) end
+
+ local out = {}
+ for i = 1, n do
+ out[i] = tostring(_xmlify(select(i, ...)))
+ end
+ return table.concat(out, '\n')
+end
+
+-- dsl for input to xmlify. doesn't do escaping or anything.
+-- THERE IS NO ESCAPE
+local X = setmetatable({}, {__index=function(_,label)
+ return function(tab)
+ local out = {}
+ local xarg = {}
+ local empty = true
+
+ for k, v in pairs(tab) do
+ if type(k) == 'number' then -- child
+ empty = nil
+ out[k] = v
+ elseif type(k) == 'string' then -- attrib
+ xarg[k] = v
+ end
+ end
+
+ out.label = label
+ out.xarg = xarg
+ out.empty = empty
+ return out
+ end
+end})
-return { psingle = psingle, stanzae = stanzae, wrap=wrap }
+return { psingle = psingle, stanzae = stanzae, wrap=wrap, xmlify=xmlify, X=X }