Annotate

util/template.lua @ 3545:c85f9a4ae1c4

util.template: Initial commit. A template library for XML stanzas.
author Waqas Hussain <waqas20@gmail.com>
date Sun, 24 Oct 2010 15:06:13 +0500
child 3546:cb1600dea3ad
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3545
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
1
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
2 local t_insert = table.insert;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
3 local st = require "util.stanza";
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
4 local lxp = require "lxp";
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
5 local setmetatable = setmetatable;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
6 local pairs = pairs;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
7 local error = error;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
8 local s_gsub = string.gsub;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
9
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
10 local print = print;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
11
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
12 module("template")
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
13
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
14 local function process_stanza(stanza, ops)
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
15 -- process attrs
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
16 for key, val in pairs(stanza.attr) do
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
17 if val:match("{[^}]*}") then
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
18 t_insert(ops, {stanza.attr, key, val});
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
19 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
20 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
21 -- process children
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
22 local i = 1;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
23 while i <= #stanza do
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
24 local child = stanza[i];
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
25 if child.name then
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
26 process_stanza(child, ops);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
27 elseif child:match("{[^}]*}") then -- text
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
28 t_insert(ops, {stanza, i, child});
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
29 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
30 i = i + 1;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
31 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
32 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
33
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
34 local parse_xml = (function()
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
35 local ns_prefixes = {
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
36 ["http://www.w3.org/XML/1998/namespace"] = "xml";
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
37 };
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
38 local ns_separator = "\1";
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
39 local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$";
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
40 return function(xml)
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
41 local handler = {};
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
42 local stanza = st.stanza("root");
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
43 function handler:StartElement(tagname, attr)
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
44 local curr_ns,name = tagname:match(ns_pattern);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
45 if name == "" then
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
46 curr_ns, name = "", curr_ns;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
47 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
48 if curr_ns ~= "" then
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
49 attr.xmlns = curr_ns;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
50 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
51 for i=1,#attr do
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
52 local k = attr[i];
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
53 attr[i] = nil;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
54 local ns, nm = k:match(ns_pattern);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
55 if nm ~= "" then
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
56 ns = ns_prefixes[ns];
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
57 if ns then
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
58 attr[ns..":"..nm] = attr[k];
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
59 attr[k] = nil;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
60 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
61 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
62 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
63 stanza:tag(name, attr);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
64 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
65 function handler:CharacterData(data)
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
66 data = data:gsub("^%s*", ""):gsub("%s*$", "");
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
67 stanza:text(data);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
68 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
69 function handler:EndElement(tagname)
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
70 stanza:up();
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
71 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
72 local parser = lxp.new(handler, "\1");
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
73 local ok, err, line, col = parser:parse(xml);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
74 if ok then ok, err, line, col = parser:parse(); end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
75 --parser:close();
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
76 if ok then
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
77 return stanza.tags[1];
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
78 else
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
79 return ok, err.." (line "..line..", col "..col..")";
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
80 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
81 end;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
82 end)();
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
83
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
84 local function create_template(text)
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
85 local stanza, err = parse_xml(text);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
86 if not stanza then error(err); end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
87 local ops = {};
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
88 process_stanza(stanza, ops);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
89 ops.stanza = stanza;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
90
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
91 local template = {};
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
92 function template.apply(data)
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
93 local newops = st.clone(ops);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
94 for i=1,#newops do
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
95 local op = newops[i];
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
96 local t, k, v = op[1], op[2], op[3];
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
97 t[k] = s_gsub(v, "{([^}]*)}", data);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
98 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
99 return newops.stanza;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
100 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
101 return template;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
102 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
103
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
104 local templates = setmetatable({}, { __mode = 'k' });
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
105 return function(text)
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
106 local template = templates[text];
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
107 if not template then
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
108 template = create_template(text);
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
109 templates[text] = template;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
110 end
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
111 return template;
c85f9a4ae1c4 util.template: Initial commit. A template library for XML stanzas.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
112 end;