-
Notifications
You must be signed in to change notification settings - Fork 0
/
init.go
313 lines (301 loc) · 16.1 KB
/
init.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
package dyntpl
import (
"github.com/koykov/clock"
"github.com/koykov/inspector/testobj_ins"
)
func init() {
// Register simple builtin modifiers.
RegisterModFn("default", "def", modDefault).
WithDescription("Modifier `default` returns the passed `arg` if the preceding value is undefined or empty, otherwise the value of the variable.").
WithParam("arg any", "").
WithExample(`{%= notExistingOrEmptyVar|default("N/D") %}`)
RegisterModFn("ifThen", "if", modIfThen).
WithDescription("Modifier `ifThen` passes `arg` only if preceding condition is true.").
WithParam("arg any", "").
WithExample(`{%= obj.Active|ifThen("<button>Buy</button>") %}`)
RegisterModFn("ifThenElse", "ifel", modIfThenElse).
WithDescription("Modifier `ifTheElse` passes `arg0` if preceding condition is true or `arg1` otherwise.").
WithParam("arg0 any", "").
WithParam("arg1 any", "").
WithExample(`{%= user.AllowSell|ifThenElse("<button>Sell</button>", "not available!") %}`)
// Register builtin escape/quote modifiers.
RegisterModFn("jsonEscape", "je", modJSONEscape).
WithDescription("Applies JSON escaping to printing value. May work together with `{% jsonquote %}...{% endjsonquote %}`.").
WithExample(`{"name":"{%= user.name|jsonEscape %}"} // {"name":"Foo\"bar"}`)
RegisterModFn("jsonQuote", "jq", modJSONQuote).
WithDescription("Applies JSON quotation to printing value.").
WithExample(`{"name":{%= user.name|jsonQuote %}} // {"name":"Foo\"bar"}`)
RegisterModFn("htmlEscape", "he", modHTMLEscape).
WithDescription("Applies HTML escaping to printing value.").
WithExample(`<span data-title="{%= title|htmlEscape %}">{%= text|he %}</span> // <span data-title="<h1>Go is an open source programming language that makes it easy to build <strong>simple<strong>, <strong>reliable</strong>, and <strong>efficient</strong> software.</h1>">Show more ></span>`)
RegisterModFn("linkEscape", "le", modLinkEscape).
WithDescription("Applies Link escaping to printing value.").
WithExample(`<a href="{%l= link %}"> // <a href="https://x.com/link-with-\"-and+space-symbol">`)
RegisterModFn("urlEncode", "ue", modURLEncode).
WithDescription("Applies URL encoding to printing value.").
WithExample(`<a href="https://redir.com/{%u= url %}">go to >>></a> // <a href="https://redir.com/https%3A%2F%2Fgolang.org%2Fsrc%2Fnet%2Furl%2Furl.go%23L100">go to >>></a>`)
RegisterModFn("attrEscape", "ae", modAttrEscape).
WithDescription("Applies Attribute escaping to printing value.").
WithExample(`<span font='{%a= var1 %}'> // <span font='foo&<>"'`!@$%()=+{}[]#;bar'>`)
RegisterModFn("cssEscape", "ce", modCSSEscape).
WithDescription("Applies CSS escaping to printing value.").
WithExample(`background-image:url({%c= var1|escape('css') %}); // background-image:url(\3c \3e \27 \22 \26 \100 \2c \2e \5f aAzZ09\20 \21 \1f600 );`)
RegisterModFn("jsEscape", "jse", modJSEscape).
WithDescription("Applies Javascript escaping to printing value.").
WithExample(`<script>{%J= var1 %}</script> // <script>\u003c\u003e\u0027\u0022\u0026\/,._aAzZ09\u0020\u0100\ud83d\ude00</script>`)
RegisterModFn("raw", "noesc", func(_ *Ctx, _ *any, _ any, _ []any) error { return nil }).
WithDescription("Disable value escaping/quoting inside bound tags (`{% jsonescape %}...{% endjsonescape %}`, ...)")
// Register builtin round modifiers.
RegisterModFn("round", "", modRound).
WithDescription("Modifier `round` returns the nearest integer, rounding half away from zero.")
RegisterModFn("roundPrec", "roundp", modRoundPrec).
WithDescription("Modifier `roundPrec` rounds value to given precision.").
WithExample(`// f = 3.1415
{%= f|roundPrec(3) %} // 3.141`)
RegisterModFn("ceil", "", modCeil).
WithDescription("Modifier `ceil` returns the least integer value greater than or equal to x.")
RegisterModFn("ceilPrec", "ceilp", modCeilPrec).
WithDescription("Modifier `ceilPrec` rounds value to ceil value with given precision").
WithExample(`// f = 56.68734
{% = f|ceilPrec(3) %} // 56.688`)
RegisterModFn("floor", "", modFloor).
WithDescription("Modifier `floor` returns the greatest integer value less than or equal to x.")
RegisterModFn("floorPrec", "floorp", modFloorPrec).
WithDescription("Modifier `floorPrec` rounds value to floor value with given precision").
WithExample(`// f = 20.214999
{% = f|floorPrec(3) %} // 20.214`)
// Register time modifiers.
RegisterModFnNS("time", "now", "", modNow).
WithDescription("Returns the current local time.")
RegisterModFnNS("time", "format", "date", modDate).
WithParam("layout string", "See https://github.com/koykov/clock#format for possible patterns").
WithDescription("Modifier `time::format` returns a textual representation of the time value formatted according given layout.").
WithExample(`{%= date|time::date("%d %b %y %H:%M %z") %} // 05 Feb 09 07:00 +0200
{%= date|time::date("%b %e %H:%M:%S.%N") %} // Feb 5 07:00:57.012345600`)
RegisterModFnNS("time", "add", "date_modify", modDateAdd).
WithParam("duration string", "Textual representation of duration you want to add to the datetime. Possible units:\n"+
" * `nsec`, `ns`\n"+
" * `usec`, `us`, `µs`\n"+
" * `msec`, `ms`\n"+
" * `seconds`, `second`, `sec`, `s`\n"+
" * `minutes`, `minute`, `min`, `m`\n"+
" * `hours`, `hour`, `hr`, `h`\n"+
" * `days`, `day`, `d`\n"+
" * `weeks`, `week`, `w`\n"+
" * `months`, `month`, `M`\n"+
" * `years`, `year`, `y`\n"+
" * `century`, `cen`, `c`\n"+
" * `millennium`, `mil`\n").
WithDescription("Modifier `time::add` returns time+duration.").
WithExample(`{%= date|time::add("+1 m")|time::date(time::StampNano) %}{% endl %} // Jan 21 20:05:26.000000555
{%= date|time::add("+1 min")|time::date(time::StampNano) %}{% endl %} // Jan 21 20:05:26.000000555
{%= date|time::add("+1 minute")|time::date(time::StampNano) %}{% endl %} // Jan 21 20:05:26.000000555
{%= date|time::add("+1 minutes")|time::date(time::StampNano) %} // Jan 21 20:05:26.000000555
`)
// Register math modifiers.
RegisterModFnNS("math", "abs", "", modAbs).
WithParam("val float", "Not mandatory").
WithDescription("Returns absolute value.").
WithExample(`num = -123456
{%= num|math::abs() %} // 123456
{%= math::abs(num) %} // 123456`)
RegisterModFnNS("math", "inc", "", modInc).
WithParam("val float", "Not mandatory").
WithDescription("Increments the value.").
WithExample(`num = 10
{%= num|math::inc() %} // 11
{%= math::inc(num) %} // 11`)
RegisterModFnNS("math", "dec", "", modDec).
WithParam("val float", "Not mandatory").
WithDescription("Decrements the value.").
WithExample(`num = 10
{%= num|math::dec() %} // 9
{%= math::dec(num) %} // 9`)
RegisterModFnNS("math", "add", "", modMathAdd).
WithParam("val float", "Not mandatory").
WithParam("arg float", "Value to add").
WithDescription("Adds `arg` to value.").
WithExample(`num = 555
{%= num|math::add(5.345) %} // 560.345
{%= math::add(num, 5.345) %} // 560.345`)
RegisterModFnNS("math", "sub", "", modMathSub).
WithParam("val float", "Not mandatory").
WithParam("arg float", "Value to subtract").
WithDescription("Subtracts `arg` from value.").
WithExample(`num = 555
{%= num|math::sub(5.345) %} // 549.655
{%= math::sub(num, 5.345) %} // 549.655`)
RegisterModFnNS("math", "mul", "", modMathMul).
WithParam("val float", "Not mandatory").
WithParam("arg float", "Value to multiply").
WithDescription("Multiplies value with `arg`.").
WithExample(`num = 10
{%= num|math::mul(5.345) %} // 100
{%= math::mul(num, 5.345) %} // 100`)
RegisterModFnNS("math", "div", "", modMathDiv).
WithParam("val float", "Not mandatory").
WithParam("arg float", "Value to divide").
WithDescription("Divides value to `arg`.").
WithExample(`num = 10
{%= num|math::div(5) %} // 2
{%= math::div(num, 5) %} // 2`)
RegisterModFnNS("math", "mod", "", modMathMod).
WithParam("val float", "Not mandatory").
WithParam("arg float", "Value to divide").
WithDescription("Modifier 'mod' implement modulus operator. Returns the remainder or signed remainder of a division, after value is divided by `arg`.").
WithExample(`num = 10
{%= num|math::mod(3) %} // 1
{%= math::mod(num, 3) %} // 1`)
RegisterModFnNS("math", "sqrt", "", modMathSqrt).
WithParam("val float", "Not mandatory").
WithDescription("Modifier 'sqrt' returns square root of value (`√val`).").
WithExample(`num = 100
{%= num|math::sqrt() %} // 10
{%= math::sqrt(num) %} // 10`)
RegisterModFnNS("math", "cbrt", "", modMathCbrt).
WithParam("val float", "Not mandatory").
WithDescription("Modifier 'sqrt' computes the cube root of value (∛val).").
WithExample(`num = 1000
{%= num|math::cqrt() %} // 10
{%= math::cqrt(num) %} // 10`)
RegisterModFnNS("math", "radical", "rad", modMathRadical).
WithParam("val float", "Not mandatory").
WithParam("root float", "Root of value required").
WithDescription("Modifier 'radical' computes the radical (`root`-order root) of value.").
WithExample(`num = 16
{%f.6= num|math::rad(4) %} // 2
{%f.6= math::rad(num, 4) %} // 2`)
RegisterModFnNS("math", "exp", "", modMathExp).
WithParam("val float", "Not mandatory").
WithDescription("Modifier 'exp' computes e**value, the base-e exponential of value.").
WithExample(`num = 5
{%f.6= num|math::exp() %} // 148.4131591025766
{%f.6= math::exp(num) %} // 148.4131591025766`)
RegisterModFnNS("math", "log", "", modMathLog).
WithParam("val float", "Not mandatory").
WithDescription("Modifier 'log' computes the natural logarithm of value.").
WithExample(`num = 6
{%f.6= num|math::log() %} // 1.791759469228055
{%f.6= math::log(num) %} // 1.791759469228055`)
RegisterModFnNS("math", "factorial", "fact", modMathFact).
WithParam("val float", "Not mandatory").
WithParam("root float", "Root of value required").
WithDescription("Modifier 'radical' computes the radical (`root`-order root) of value.").
WithExample(`num = 16
{%f.6= num|math::rad(4) %} // 2
{%f.6= math::rad(num, 4) %} // 2`)
RegisterModFnNS("math", "max", "", modMathMax).
WithParam("arg0 float", "").
WithParam("arg1 float", "").
WithDescription("Modifier 'max' returns maximum value of `arg0` or `arg1`.")
RegisterModFnNS("math", "min", "", modMathMin).
WithParam("arg0 float", "").
WithParam("arg1 float", "").
WithDescription("Modifier 'max' returns minimum value of `arg0` or `arg1`.")
RegisterModFnNS("math", "pow", "", modMathPow).
WithParam("val float", "Not mandatory").
WithParam("exp float", "Exponent").
WithDescription("Modifier 'radical' computes `val**exp`, the base-`val` exponential of `exp`.").
WithExample(`num = 2
{%= num|math::pow(4) %} // 16
{%= math::pow(num, 4) %} // 16`)
// Register builtin condition helpers.
RegisterCondFn("lenEq0", condLenEq0).
WithParam("arg bytes", "Possible types: `string`, `[]byte`, `[]string`, `[][]byte`.").
WithDescription("Checks if length of `arg` equal to zero.").
WithNote("DEPRECATED! Use native expression like `{% if len(arg) == 0 %}...{% endif %}`.")
RegisterCondFn("lenGt0", condLenGt0).
WithParam("arg bytes", "Possible types: `string`, `[]byte`, `[]string`, `[][]byte`.").
WithDescription("Checks if length of `arg` greater or equal to zero.").
WithNote("DEPRECATED! Use native expression like `{% if len(arg) >= 0 %}...{% endif %}`.")
RegisterCondFn("lenGtq0", condLenGtq0).
WithParam("arg bytes", "Possible types: `string`, `[]byte`, `[]string`, `[][]byte`.").
WithDescription("Checks if length of `arg` less or equal to zero.").
WithNote("DEPRECATED! Use native expression like `{% if len(arg) <= 0 %}...{% endif %}`.")
// Register builtin empty check helpers.
RegisterEmptyCheckFn("int", EmptyCheckInt).
WithDescription("Checks if value is integer and contains zero value.")
RegisterEmptyCheckFn("uint", EmptyCheckUint).
WithDescription("Checks if value is unsigned integer and contains zero value.")
RegisterEmptyCheckFn("float", EmptyCheckFloat).
WithDescription("Checks if value is float and contains zero value.")
RegisterEmptyCheckFn("bytes", EmptyCheckBytes).
WithDescription("Checks if value is byte slice (`[]byte`) and its length equals to zero.")
RegisterEmptyCheckFn("bytes_slice", EmptyCheckBytesSlice).
WithDescription("Checks if value is bytes matrix (`[][]byte`) and contains no rows.")
RegisterEmptyCheckFn("str", EmptyCheckStr).
WithDescription("Checks if value is string and its length equals to zero.")
RegisterEmptyCheckFn("str_slice", EmptyCheckStrSlice).
WithDescription("Checks if value is slice of strings and its contains n string.")
RegisterEmptyCheckFn("bool", EmptyCheckBool).
WithDescription("Checks if value is boolean and equals to false.")
// Register datetime layouts.
RegisterGlobalNS("time", "Layout", "", clock.Layout).
WithType("string").
WithDescription("time.Layout presentation in strtotime format.")
RegisterGlobalNS("time", "ANSIC", "", clock.ANSIC).
WithType("string").
WithDescription("time.ANSIC presentation in strtotime format.")
RegisterGlobalNS("time", "UnixDate", "", clock.UnixDate).
WithType("string").
WithDescription("time.UnixDate presentation in strtotime format.")
RegisterGlobalNS("time", "RubyDate", "", clock.RubyDate).
WithType("string").
WithDescription("time.RubyDate presentation in strtotime format.")
RegisterGlobalNS("time", "RFC822", "", clock.RFC822).
WithType("string").
WithDescription("time.RFC822 presentation in strtotime format.")
RegisterGlobalNS("time", "RFC822Z", "", clock.RFC822Z).
WithType("string").
WithDescription("time.RFC822Z presentation in strtotime format.")
RegisterGlobalNS("time", "RFC850", "", clock.RFC850).
WithType("string").
WithDescription("time.RFC850 presentation in strtotime format.")
RegisterGlobalNS("time", "RFC1123", "", clock.RFC1123).
WithType("string").
WithDescription("time.RFC1123 presentation in strtotime format.")
RegisterGlobalNS("time", "RFC1123Z", "", clock.RFC1123Z).
WithType("string").
WithDescription("time.RFC1123Z presentation in strtotime format.")
RegisterGlobalNS("time", "RFC3339", "", clock.RFC3339).
WithType("string").
WithDescription("time.RFC3339 presentation in strtotime format.")
RegisterGlobalNS("time", "RFC3339Nano", "", clock.RFC3339Nano).
WithType("string").
WithDescription("time.RFC3339Nano presentation in strtotime format.")
RegisterGlobalNS("time", "Kitchen", "", clock.Kitchen).
WithType("string").
WithDescription("time.Kitchen presentation in strtotime format.")
RegisterGlobalNS("time", "Stamp", "", clock.Stamp).
WithType("string").
WithDescription("time.Stamp presentation in strtotime format.")
RegisterGlobalNS("time", "StampMilli", "", clock.StampMilli).
WithType("string").
WithDescription("time.StampMilli presentation in strtotime format.")
RegisterGlobalNS("time", "StampMicro", "", clock.StampMicro).
WithType("string").
WithDescription("time.StampMicro presentation in strtotime format.")
RegisterGlobalNS("time", "StampNano", "", clock.StampNano).
WithType("string").
WithDescription("time.StampNano presentation in strtotime format.")
// Register test modifiers.
RegisterModFn("testNameOf", "", modTestNameOf).
WithDescription("Testing stuff: don't use in production.")
RegisterModFnNS("testns", "pack", "", func(_ *Ctx, _ *any, _ any, _ []any) error { return nil }).
WithDescription("Testing namespace stuff: don't use in production.")
RegisterModFnNS("testns", "extract", "", func(_ *Ctx, _ *any, _ any, _ []any) error { return nil }).
WithDescription("Testing namespace stuff: don't use in production.")
RegisterModFnNS("testns", "marshal", "", func(_ *Ctx, _ *any, _ any, _ []any) error { return nil }).
WithDescription("Testing namespace stuff: don't use in production.")
RegisterModFnNS("testns", "modCB", "", func(ctx *Ctx, _ *any, _ any, args []any) error {
ctx.SetStatic("testVar", args[0])
return nil
}).
WithDescription("Testing namespace stuff: don't use in production.")
// Register test condition-ok helpers.
RegisterCondOKFn("__testUserNextHistory999", testCondOK).
WithDescription("Testing namespace stuff: don't use in production.")
// Register test variable-inspector pairs.
RegisterVarInsPair("__testFin999", &testobj_ins.TestFinanceInspector{}).
WithDescription("Testing stuff: don't use in production.")
}