Annotate

util/xtemplate.lua @ 13134:638f627e707f

util.datamanager: Add O(1) list indexing with on-disk index Index file contains offsets and lengths of each item() which allows seeking directly to each item and reading it without parsing the entire file. Also allows tricks like binary search, assuming items have some defined order. We take advantage of the 1-based indexing in tables to store a magic header in the 0 position, so that table index 1 ends up at file index 1.
author Kim Alvefur <zash@zash.se>
date Tue, 11 May 2021 02:09:56 +0200
parent 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
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
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 }