Annotate

util/xtemplate.lua @ 13533:c885594f7f9a

mod_pubsub: Allow passing additional error context Sometimes it is useful to pass additional information along.
author Kim Alvefur <zash@zash.se>
date Sun, 27 Oct 2024 15:23:45 +0100
parent 13525:0f7e7311eebf
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
12975
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12213
diff changeset
6 local st = require("prosody.util.stanza");
12213
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
13394
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
11 return (s_gsub(template, "(%s*)(%b{})(%s*)", function(pre_blank, block, post_blank)
12213
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 local inner = s_sub(block, 2, -2);
13394
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
13 if inner:sub(1, 1) == "-" then
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
14 pre_blank = "";
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
15 inner = inner:sub(2);
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
16 end
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
17 if inner:sub(-1, -1) == "-" then
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
18 post_blank = "";
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
19 inner = inner:sub(1, -2);
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
20 end
12213
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21 local path, pipe, pos = s_match(inner, "^([^|]+)(|?)()");
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 if not (type(path) == "string") then return end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 local value
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 if path == "." then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 value = root;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 elseif path == "#" then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 value = root:get_text();
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 else
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 value = root:find(path);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 local is_escaped = false;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 while pipe == "|" do
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 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
35 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
36 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
37 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
38 if not func then break end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
39 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
40 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
41
13500
997d9ad12477 util.xtemplate: Fix error on applying each() to zero stanzas
Kim Alvefur <zash@zash.se>
parents: 12213
diff changeset
42 if func == "each" and tmpl then
13499
1f93e4f78c53 util.xtemplate: Fix error on applying each() to zero stanzas
Kim Alvefur <zash@zash.se>
parents: 13394
diff changeset
43 if not st.is_stanza(value) then return pre_blank .. post_blank end
12213
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 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
45 local ns, name = s_match(args, "^(%b{})(.*)$");
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 if ns then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
47 ns = s_sub(ns, 2, -2);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
48 else
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 name, ns = args, nil;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51 if ns == "" then ns = nil; end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
52 if name == "" then name = nil; end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
53 local out, i = {}, 1;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
54 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
55 value = t_concat(out);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
56 is_escaped = true;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
57 elseif func == "and" and tmpl then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
58 local condition = value;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
59 if args then condition = root:find(args); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
60 if condition then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
61 value = render(tmpl, root, escape, filters);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
62 is_escaped = true;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
63 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
64 elseif func == "or" and tmpl then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
65 local condition = value;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
66 if args then condition = root:find(args); end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
67 if not condition then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
68 value = render(tmpl, root, escape, filters);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
69 is_escaped = true;
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
70 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
71 elseif filters and filters[func] then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
72 local f = filters[func];
13525
0f7e7311eebf util.xtemplate: Use same argument order in filters even without 'args'
Kim Alvefur <zash@zash.se>
parents: 13501
diff changeset
73 value, is_escaped = f(value, args, tmpl);
12213
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
74 else
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
75 error("No such filter function: " .. func);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
76 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
77 pipe, pos = s_match(inner, "^(|?)()", p);
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
78 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 if type(value) == "string" then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 if not is_escaped then value = escape(value); end
13394
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
82 return pre_blank .. value .. post_blank
12213
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83 elseif st.is_stanza(value) then
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 value = value:get_text();
13394
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
85 if value then return pre_blank .. escape(value) .. post_blank end
12213
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 end
13394
6debd8dd12ab util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 12975
diff changeset
87 return pre_blank .. post_blank
12213
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
88 end))
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
89 end
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90
dc9d63166488 util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff changeset
91 return { render = render }