-- xml.lua -- (c) Dirk Laurie 2012 Licence: zlib/pnglib -- That means you can do anything except claim I didn't write it. -- Some code borrowed from `strict.lua` --[[ Usage: interactive: lua -l "xml" -i or filter: lua -l xml -e 'print(load("return "..io.read"*a")())' or programming: require "xml" After that, you can write XMLinLua, e.g. the expression macro {name="author-short", names{variable="author",'name form="short"'} } represents the following string: How it works: When an unknown name is encountered, an immediately available function is created that can be called in two ways: name(body) name{param=val,param=val...,body} where `body` evaluates to a string. If `body` does not match the pattern "<.*>", it will be formatted by "<%s/>". These will respectively be rendered in XML as body body Of course, the sequence of `param="val"` terms does not follow the original, since the argument is a table. If you have already defined the name, assign `nil` to it before trying to use it in this way. --]] local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget local mt = getmetatable(_G) if mt == nil then mt = {} setmetatable(_G, mt) end local function what () local d = getinfo(3, "S") return d and d.what or "C" end local concat=table.concat local format, match, gsub =string.format, string.match, string.gsub mt.__index = function (t, n) if what() ~= "C" then local f = function(arg) local body, restore if type(arg)=="table" then body=arg[1]; restore=body; arg[1]=nil elseif type(arg)=="string" then body=arg; arg={} else error("bad argument #1 to n: expected table or string, got ".. type(arg)) end if type(body)=="string" then if not match(body,"<.*>") then body=format("<%s/>",body) end else arg[1]=restore error("bad argument to "..n..": expected string, got "..type(body)) end local args={} for k,v in pairs(arg) do args[#args+1]=format(' %s="%s"',k,v) end return format("<%s%s>\n %s\n",n,concat(args), gsub(body,"\n","\n "),n) end rawset(t, n, f) return f end end