Software / code / prosody
Annotate
util/xtemplate.lua @ 13494:4c3d6ed9c823
Merge 0.12->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Wed, 12 Jun 2024 23:20:48 +0200 |
| parent | 13394:6debd8dd12ab |
| child | 13499:1f93e4f78c53 |
| 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 |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
42 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
|
43 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
|
44 local ns, name = s_match(args, "^(%b{})(.*)$"); |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
45 if ns then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
46 ns = s_sub(ns, 2, -2); |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
47 else |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
48 name, ns = args, nil; |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
49 end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
50 if ns == "" then ns = nil; end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
51 if name == "" then name = nil; end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
52 local out, i = {}, 1; |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
53 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
|
54 value = t_concat(out); |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
55 is_escaped = true; |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
56 elseif func == "and" and tmpl then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
57 local condition = value; |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
58 if args then condition = root:find(args); end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
59 if condition then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
60 value = render(tmpl, root, escape, filters); |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
61 is_escaped = true; |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
62 end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
63 elseif func == "or" and tmpl then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
64 local condition = value; |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
65 if args then condition = root:find(args); end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
66 if not condition then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
67 value = render(tmpl, root, escape, filters); |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
68 is_escaped = true; |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
69 end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
70 elseif filters and filters[func] then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
71 local f = filters[func]; |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
72 if args == nil then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
73 value, is_escaped = f(value, tmpl); |
|
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 value, is_escaped = f(args, value, tmpl); |
|
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 else |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
78 error("No such filter function: " .. func); |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
79 end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
80 pipe, pos = s_match(inner, "^(|?)()", p); |
|
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 |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
83 if type(value) == "string" then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
84 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
|
85 return pre_blank .. value .. post_blank |
|
12213
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
86 elseif st.is_stanza(value) then |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
87 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
|
88 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
|
89 end |
|
13394
6debd8dd12ab
util.xtemplate: Adopt {-path-} syntax to strip preceding and/or trailing whitespace
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
90 return pre_blank .. post_blank |
|
12213
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
91 end)) |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
92 end |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
93 |
|
dc9d63166488
util.xtemplate: Yet another string template library
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
94 return { render = render } |