Annotate

util/xtemplate.lua @ 13247:1bb4aa803b32 0.12

util.array: Fix new() library function Backport of ffe4adbd2af9 since new was added in the 0.12 branch
author Kim Alvefur <zash@zash.se>
date Sat, 22 Jul 2023 16:31:05 +0200
parent 12213:dc9d63166488
child 12975:d10957394a3c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12213
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 local s_gsub = string.gsub;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 local s_match = string.match;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 local s_sub = string.sub;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4 local t_concat = table.concat;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6 local st = require("util.stanza");
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8 local function render(template, root, escape, filters)
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 escape = escape or st.xml_escape;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
10
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 return (s_gsub(template, "%b{}", function(block)
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 local inner = s_sub(block, 2, -2);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13 local path, pipe, pos = s_match(inner, "^([^|]+)(|?)()");
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 if not (type(path) == "string") then return end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
15 local value
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16 if path == "." then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 value = root;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18 elseif path == "#" then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19 value = root:get_text();
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 else
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21 value = root:find(path);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 local is_escaped = false;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 while pipe == "|" do
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 local func, args, tmpl, p = s_match(inner, "^(%w+)(%b())(%b{})()", pos);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 if not func then func, args, p = s_match(inner, "^(%w+)(%b())()", pos); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 if not func then func, tmpl, p = s_match(inner, "^(%w+)(%b{})()", pos); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 if not func then func, p = s_match(inner, "^(%w+)()", pos); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 if not func then break end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 if tmpl then tmpl = s_sub(tmpl, 2, -2); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 if args then args = s_sub(args, 2, -2); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 if func == "each" and tmpl and st.is_stanza(value) then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35 if not args then value, args = root, path; end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 local ns, name = s_match(args, "^(%b{})(.*)$");
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37 if ns then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
38 ns = s_sub(ns, 2, -2);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39 else
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
40 name, ns = args, nil;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
41 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
42 if ns == "" then ns = nil; end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
43 if name == "" then name = nil; end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 local out, i = {}, 1;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45 for c in (value):childtags(name, ns) do out[i], i = render(tmpl, c, escape, filters), i + 1; end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 value = t_concat(out);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
47 is_escaped = true;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
48 elseif func == "and" and tmpl then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 local condition = value;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50 if args then condition = root:find(args); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51 if condition then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52 value = render(tmpl, root, escape, filters);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
53 is_escaped = true;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
55 elseif func == "or" and tmpl then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56 local condition = value;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 if args then condition = root:find(args); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58 if not condition then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 value = render(tmpl, root, escape, filters);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 is_escaped = true;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
62 elseif filters and filters[func] then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 local f = filters[func];
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64 if args == nil then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65 value, is_escaped = f(value, tmpl);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
66 else
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
67 value, is_escaped = f(args, value, tmpl);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
68 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69 else
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70 error("No such filter function: " .. func);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
71 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
72 pipe, pos = s_match(inner, "^(|?)()", p);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
73 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75 if type(value) == "string" then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
76 if not is_escaped then value = escape(value); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
77 return value
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
78 elseif st.is_stanza(value) then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79 value = value:get_text();
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 if value then return escape(value) end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 return ""
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83 end))
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 return { render = render }