Differences From
Artifact [7216746946]:
34 34 str = str:gsub('%s+[\n$]','')
35 35 str = str:gsub('\n','')
36 36 str = str:gsub('</a><a ','</a> <a ') -- keep nav links from getting smooshed
37 37 str = str:gsub(tplchar .. '%?([-%w]+)', function(file)
38 38 if not docs[file] then docs[file] = data.doc[file] end
39 39 return string.format('<a href="#help-%s" class="help">?</a>', file)
40 40 end)
41 - for start, mode, key, stop in string.gmatch(str,'()'..tplchar..'([:!]?)([-a-zA-Z0-9_]+)()') do
41 + for start, mode, key, stop in string.gmatch(str,'()'..tplchar..'([:!$]?)([-a-zA-Z0-9_]+)()') do
42 42 if string.sub(str,start-1,start-1) ~= '\\' then
43 43 segs[#segs+1] = string.sub(str,last,start-1)
44 44 fields[#segs] = { key = key:gsub('-','_'), mode = (mode ~= '' and mode or nil) }
45 45 last = stop
46 46 end
47 47 end
48 48 segs[#segs+1] = string.sub(str,last)
................................................................................
73 73 if not kfac[fld.key] then
74 74 rec.entries[#rec.entries + 1] = {
75 75 field = fld.key;
76 76 type = lib.mem.ptr(int8);
77 77 }
78 78 end
79 79 kfac[fld.key] = (kfac[fld.key] or 0) + 1
80 - sanmode[fld.key] = fld.mode == ':' and 6 or fld.mode == '!' and 5 or 1
80 + sanmode[fld.key] = fld.mode == ':' and 6
81 + or fld.mode == '!' and 5
82 + or fld.mode == '$' and 2 or 1
81 83 end
82 84 for key, fac in pairs(kfac) do
83 85 local sanfac = sanmode[key]
84 86
85 87 tallyup[#tallyup + 1] = quote
86 88 [runningtally] = [runningtally] + ([symself].[key].ct)*fac*sanfac
87 89 end
................................................................................
99 101 for idx, seg in ipairs(segs) do
100 102 copiers[#copiers+1] = quote [cpypos] = lib.mem.cpy([cpypos], [&opaque]([seg]), [#seg]) end
101 103 senders[#senders+1] = quote lib.net.mg_send([destcon], [seg], [#seg]) end
102 104 appenders[#appenders+1] = quote [accumulator]:push([seg], [#seg]) end
103 105 if fields[idx] and fields[idx].mode then
104 106 local f = fields[idx]
105 107 local fp = `symself.[f.key]
108 + local sanexp
109 + if f.mode == '$' then
110 + sanexp = `lib.str.qesc(pool, fp)
111 + else
112 + sanexp = `lib.html.sanitize(pool, fp, [f.mode == ':'])
113 + end
106 114 copiers[#copiers+1] = quote
107 115 if fp.ct > 0 then
108 - var san = lib.html.sanitize(pool, fp, [f.mode == ':'])
116 + var san = sanexp
109 117 [cpypos] = lib.mem.cpy([cpypos], [&opaque](san.ptr), san.ct)
110 118 --san:free()
111 119 end
112 120 end
113 121 senders[#senders+1] = quote
114 122 if fp.ct > 0 then
115 - var san = lib.html.sanitize(pool, fp, [f.mode == ':'])
123 + var san = sanexp
116 124 lib.net.mg_send([destcon], san.ptr, san.ct)
117 125 --san:free()
118 126 end
119 127 end
120 128 appenders[#appenders+1] = quote
121 129 if fp.ct > 0 then
122 - var san = lib.html.sanitize(pool, fp, [f.mode == ':'])
130 + var san = sanexp
123 131 [accumulator]:ppush(san)
124 132 --san:free()
125 133 end
126 134 end
127 135 elseif fields[idx] then
128 136 local f = fields[idx]
129 137 local fp = `symself.[f.key]