papagaio 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +131 -211
- package/bin/cli.qjs +57 -0
- package/index.html +278 -380
- package/package.json +1 -1
- package/src/papagaio.js +279 -443
- package/tests/test.js +1 -1
- package/tests/tests.json +100 -604
package/tests/tests.json
CHANGED
|
@@ -2,717 +2,213 @@
|
|
|
2
2
|
"tests": [
|
|
3
3
|
{
|
|
4
4
|
"id": 1,
|
|
5
|
-
"name": "Basic
|
|
6
|
-
"code": "pattern {$x $y
|
|
7
|
-
"expected": "
|
|
5
|
+
"name": "Basic variable substitution",
|
|
6
|
+
"code": "pattern {$x $y} {$y, $x}\nhello world",
|
|
7
|
+
"expected": "world, hello"
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
"id": 2,
|
|
11
|
-
"name": "Flexible whitespace
|
|
11
|
+
"name": "Flexible whitespace with $$",
|
|
12
12
|
"code": "pattern {$$x and $$y} {$x & $y}\nhello and world",
|
|
13
13
|
"expected": "hello & world"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"id": 3,
|
|
17
|
-
"name": "Block with delimiters
|
|
17
|
+
"name": "Block with custom delimiters",
|
|
18
18
|
"code": "pattern {$block content {(}{)}} {[$content]}\ndata (hello world)",
|
|
19
|
-
"expected": "[hello world]"
|
|
19
|
+
"expected": "data [hello world]"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"id": 4,
|
|
23
|
-
"name": "
|
|
24
|
-
"code": "pattern {$
|
|
25
|
-
"expected": "
|
|
23
|
+
"name": "Block with multi-char delimiters",
|
|
24
|
+
"code": "pattern {$block code {<<}{>>}} {CODE[$code]}\n<<console.log()>>",
|
|
25
|
+
"expected": "CODE[console.log()]"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"id": 5,
|
|
29
|
-
"name": "
|
|
30
|
-
"code": "pattern {
|
|
31
|
-
"expected": "
|
|
29
|
+
"name": "Block with nested delimiters",
|
|
30
|
+
"code": "pattern {$block txt {<}{>}} {[$txt]}\nouter <middle <inner> content>",
|
|
31
|
+
"expected": "outer [middle <inner> content]"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"id": 6,
|
|
35
|
-
"name": "
|
|
36
|
-
"code": "pattern {$
|
|
37
|
-
"expected": "
|
|
35
|
+
"name": "Eval expression with arithmetic",
|
|
36
|
+
"code": "pattern {sum $a $b} {$eval{return parseInt($a) + parseInt($b)}}\nsum 5 3",
|
|
37
|
+
"expected": "8"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"id": 7,
|
|
41
|
-
"name": "
|
|
42
|
-
"code": "pattern {
|
|
43
|
-
"expected": "
|
|
41
|
+
"name": "Eval with arithmetic and variable",
|
|
42
|
+
"code": "pattern {multiply $n} {Result: $eval{return $n * 3}}\nmultiply 5",
|
|
43
|
+
"expected": "Result: 15"
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
"id": 8,
|
|
47
|
-
"name": "
|
|
48
|
-
"code": "pattern {
|
|
49
|
-
"expected": "
|
|
47
|
+
"name": "Multiple patterns cascade",
|
|
48
|
+
"code": "pattern {a} {b}\npattern {b} {c}\na",
|
|
49
|
+
"expected": "c"
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"id": 9,
|
|
53
|
-
"name": "
|
|
53
|
+
"name": "Global pattern matching",
|
|
54
54
|
"code": "pattern {x} {X}\nx y x z x",
|
|
55
55
|
"expected": "X y X z X"
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"id": 10,
|
|
59
|
-
"name": "
|
|
60
|
-
"code": "pattern {
|
|
61
|
-
"expected": "
|
|
59
|
+
"name": "Pattern with special regex characters",
|
|
60
|
+
"code": "pattern {a.*b} {MATCHED}\na.*b",
|
|
61
|
+
"expected": "MATCHED"
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"id": 11,
|
|
65
|
-
"name": "
|
|
66
|
-
"code": "pattern {
|
|
67
|
-
"expected": "
|
|
65
|
+
"name": "Multiple blocks in one pattern",
|
|
66
|
+
"code": "pattern {$block a {(}{)} and $block b {[}{]}} {$a|$b}\n(first) and [second]",
|
|
67
|
+
"expected": "first|second"
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"id": 12,
|
|
71
|
-
"name": "
|
|
72
|
-
"code": "pattern {$
|
|
73
|
-
"expected": "
|
|
71
|
+
"name": "Variable reuse in replacement",
|
|
72
|
+
"code": "pattern {$x} {$x:$x}\ndata",
|
|
73
|
+
"expected": "data:data"
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
"id": 13,
|
|
77
|
-
"name": "
|
|
78
|
-
"code": "pattern {
|
|
79
|
-
"expected": "
|
|
77
|
+
"name": "Literal dollar sign in replacement",
|
|
78
|
+
"code": "pattern {price} {$50}\nprice",
|
|
79
|
+
"expected": "$50"
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"id": 14,
|
|
83
|
-
"name": "
|
|
84
|
-
"code": "pattern {
|
|
85
|
-
"expected": "
|
|
83
|
+
"name": "Optional whitespace with $$ optional",
|
|
84
|
+
"code": "pattern {hello$$world} {HI}\nhello\n\nworld",
|
|
85
|
+
"expected": "HI"
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
"id": 15,
|
|
89
|
-
"name": "Block with
|
|
90
|
-
"code": "pattern {$block
|
|
91
|
-
"expected": "
|
|
89
|
+
"name": "Block with angle brackets",
|
|
90
|
+
"code": "pattern {$block inner {<}{>}} {WRAPPED[$inner]}\n<content>",
|
|
91
|
+
"expected": "WRAPPED[content]"
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
"id": 16,
|
|
95
|
-
"name": "Pattern with
|
|
96
|
-
"code": "pattern {
|
|
97
|
-
"expected": "
|
|
95
|
+
"name": "Pattern with literal characters",
|
|
96
|
+
"code": "pattern {Mr. $name} {Hello $name}\nMr. Smith",
|
|
97
|
+
"expected": "Hello Smith"
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
"id": 17,
|
|
101
|
-
"name": "
|
|
102
|
-
"code": "pattern {
|
|
103
|
-
"expected": "
|
|
101
|
+
"name": "Eval with division and decimals",
|
|
102
|
+
"code": "pattern {div $a $b} {$eval{return $a / $b}}\ndiv 7 2",
|
|
103
|
+
"expected": "3.5"
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
"id": 18,
|
|
107
|
-
"name": "
|
|
108
|
-
"code": "pattern {$
|
|
109
|
-
"expected": "
|
|
107
|
+
"name": "Block capturing with square brackets",
|
|
108
|
+
"code": "pattern {$block arr {[}{]}} {ARRAY[$arr]}\n[1, 2, 3]",
|
|
109
|
+
"expected": "ARRAY[1, 2, 3]"
|
|
110
110
|
},
|
|
111
111
|
{
|
|
112
112
|
"id": 19,
|
|
113
|
-
"name": "
|
|
114
|
-
"code": "pattern {
|
|
115
|
-
"expected": "
|
|
113
|
+
"name": "Pattern without whitespace matching",
|
|
114
|
+
"code": "pattern {$$a,$b} {$b,$a} one,two",
|
|
115
|
+
"expected": "two,one"
|
|
116
116
|
},
|
|
117
117
|
{
|
|
118
118
|
"id": 20,
|
|
119
|
-
"name": "
|
|
120
|
-
"code": "pattern {
|
|
121
|
-
"expected": "
|
|
119
|
+
"name": "Nested pattern in replacement",
|
|
120
|
+
"code": "pattern {$x} {->$x<-}\ntext",
|
|
121
|
+
"expected": "->text<-"
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
"id": 21,
|
|
125
|
-
"name": "
|
|
126
|
-
"code": "pattern {
|
|
127
|
-
"expected": "
|
|
125
|
+
"name": "First pattern applies, second doesn't match",
|
|
126
|
+
"code": "pattern {hello} {goodbye}\npattern {goodbye} {hi}\nhello",
|
|
127
|
+
"expected": "hi"
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"id": 22,
|
|
131
|
-
"name": "
|
|
132
|
-
"code": "pattern {
|
|
133
|
-
"expected": "
|
|
131
|
+
"name": "Block delimiter balancing - parentheses",
|
|
132
|
+
"code": "pattern {$block code {(}{)}} {RESULT[$code]}\n(a (b (c) d) e)",
|
|
133
|
+
"expected": "RESULT[a (b (c) d) e]"
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
"id": 23,
|
|
137
|
-
"name": "
|
|
138
|
-
"code": "
|
|
139
|
-
"expected": "<
|
|
137
|
+
"name": "Block delimiter balancing - angle brackets",
|
|
138
|
+
"code": "pattern {$block inner {<}{>}} {X[$inner]}\n<outer <middle <deep>> more>",
|
|
139
|
+
"expected": "X[outer <middle <deep>> more]"
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
142
|
"id": 24,
|
|
143
|
-
"name": "
|
|
144
|
-
"code": "pattern {
|
|
145
|
-
"expected": "
|
|
143
|
+
"name": "Block delimiter balancing - square brackets",
|
|
144
|
+
"code": "pattern {$block data {[}{]}} {DATA[$data]}\n[outer [inner [deep]] more]",
|
|
145
|
+
"expected": "DATA[outer [inner [deep]] more]"
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
148
|
"id": 25,
|
|
149
|
-
"name": "
|
|
150
|
-
"code": "pattern {
|
|
151
|
-
"expected": "
|
|
149
|
+
"name": "Block delimiter balancing - curly braces",
|
|
150
|
+
"code": "pattern {$block obj {}{}} {OBJ[$obj]}\n{key: {nested: {value}}}",
|
|
151
|
+
"expected": "OBJ[key: {nested: {value}}]"
|
|
152
152
|
},
|
|
153
153
|
{
|
|
154
154
|
"id": 26,
|
|
155
|
-
"name": "
|
|
156
|
-
"code": "pattern {$
|
|
157
|
-
"expected": "
|
|
155
|
+
"name": "Multiple nested delimiters in same pattern",
|
|
156
|
+
"code": "pattern {$block a {(}{)} $block b {[}{]}} {[$a|$b]}\n(test1) [test2]",
|
|
157
|
+
"expected": "[test1|test2]"
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
160
|
"id": 27,
|
|
161
|
-
"name": "
|
|
162
|
-
"code": "pattern {$
|
|
163
|
-
"expected": "
|
|
161
|
+
"name": "Simple pattern cascade",
|
|
162
|
+
"code": "pattern {START $x END} {RESULT[$x]}\nSTART data END",
|
|
163
|
+
"expected": "RESULT[data]"
|
|
164
164
|
},
|
|
165
165
|
{
|
|
166
166
|
"id": 28,
|
|
167
|
-
"name": "
|
|
168
|
-
"code": "pattern {$
|
|
169
|
-
"expected": "
|
|
167
|
+
"name": "Block with quotes as delimiters",
|
|
168
|
+
"code": "pattern {$block str {\"}{\"}} {STRING[$str]}\n\"hello world\"",
|
|
169
|
+
"expected": "STRING[hello world]"
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
172
|
"id": 29,
|
|
173
|
-
"name": "
|
|
174
|
-
"code": "pattern {$
|
|
175
|
-
"expected": "
|
|
173
|
+
"name": "Block with pipe delimiters",
|
|
174
|
+
"code": "pattern {$block val {|}{|}} {PIPE[$val]}\n|content here|",
|
|
175
|
+
"expected": "PIPE[content here]"
|
|
176
176
|
},
|
|
177
177
|
{
|
|
178
178
|
"id": 30,
|
|
179
|
-
"name": "
|
|
180
|
-
"code": "pattern {
|
|
181
|
-
"expected": "d"
|
|
179
|
+
"name": "Deeply nested block delimiters",
|
|
180
|
+
"code": "pattern {$block deep {<}{>}} {[$deep]}\n<a <b <c <d> c> b> a>",
|
|
181
|
+
"expected": "[a <b <c <d> c> b> a]"
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
"id": 31,
|
|
185
|
-
"name": "
|
|
186
|
-
"code": "pattern {$block
|
|
187
|
-
"expected": "
|
|
185
|
+
"name": "Two sequential patterns",
|
|
186
|
+
"code": "pattern {$block content {(}{)}} {BLOCK [$content]}\npattern {BLOCK $x} {RESULT: $x}\n(inner data)",
|
|
187
|
+
"expected": "RESULT: [inner data]"
|
|
188
188
|
},
|
|
189
189
|
{
|
|
190
190
|
"id": 32,
|
|
191
|
-
"name": "
|
|
192
|
-
"code": "pattern {$x
|
|
193
|
-
"expected": "
|
|
191
|
+
"name": "Multiple eval operations in sequence",
|
|
192
|
+
"code": "pattern {calc $x} {$eval{return parseInt($x) * 2}}\ncalc 3",
|
|
193
|
+
"expected": "6"
|
|
194
194
|
},
|
|
195
195
|
{
|
|
196
196
|
"id": 33,
|
|
197
|
-
"name": "Block
|
|
198
|
-
"code": "pattern {$block
|
|
199
|
-
"expected": "
|
|
197
|
+
"name": "Block delimiter edge case - empty content",
|
|
198
|
+
"code": "pattern {$block empty {(}{)}} {EMPTY[$empty]}\n()",
|
|
199
|
+
"expected": "EMPTY[]"
|
|
200
200
|
},
|
|
201
201
|
{
|
|
202
202
|
"id": 34,
|
|
203
|
-
"name": "
|
|
204
|
-
"code": "pattern {$
|
|
205
|
-
"expected": "
|
|
203
|
+
"name": "Multi-char delimiters with nesting",
|
|
204
|
+
"code": "pattern {$block code {<<}{>>}} {CODE[$code]}\n<<outer <<inner>> more>>",
|
|
205
|
+
"expected": "CODE[outer <<inner>> more]"
|
|
206
206
|
},
|
|
207
207
|
{
|
|
208
208
|
"id": 35,
|
|
209
|
-
"name": "
|
|
210
|
-
"code": "
|
|
211
|
-
"expected": "
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
"id": 36,
|
|
215
|
-
"name": "Pattern HTML generator function",
|
|
216
|
-
"code": "pattern {$tag $content} {<$tag>$content</$tag>}\ndiv HelloWorld",
|
|
217
|
-
"expected": "<div>HelloWorld</div>"
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
"id": 37,
|
|
221
|
-
"name": "Block with multi-char delimiter",
|
|
222
|
-
"code": "pattern {$block code {<<}{>>}} {CODE[$code]}\n<<console.log('test')>>",
|
|
223
|
-
"expected": "CODE[console.log('test')]"
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
"id": 38,
|
|
227
|
-
"name": "Markdown list to HTML",
|
|
228
|
-
"code": "pattern {- $item} {<li>$item</li>}\n- Apple\n- Banana",
|
|
229
|
-
"expected": "<li>Apple</li>"
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
"id": 39,
|
|
233
|
-
"name": "Pattern with literal $ ($)",
|
|
234
|
-
"code": "pattern {price} {Price: $50}\nprice",
|
|
235
|
-
"expected": "Price: $50"
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
"id": 40,
|
|
239
|
-
"name": "Markdown heading h1",
|
|
240
|
-
"code": "pattern {# $title} {<h1>$title</h1>}\n# Welcome",
|
|
241
|
-
"expected": "<h1>Welcome</h1>"
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
"id": 41,
|
|
245
|
-
"name": "Markdown heading h2",
|
|
246
|
-
"code": "pattern {## $title} {<h2>$title</h2>}\n## Section",
|
|
247
|
-
"expected": "<h2>Section</h2>"
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
"id": 42,
|
|
251
|
-
"name": "Variables with underscore names",
|
|
252
|
-
"code": "pattern {$var_name $other_var} {$other_var:$var_name}\nfirst second",
|
|
253
|
-
"expected": "second:first"
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
"id": 43,
|
|
257
|
-
"name": "Pattern with variable reuse",
|
|
258
|
-
"code": "pattern {$x} {$x-$x-$x}\ndata",
|
|
259
|
-
"expected": "data-data-data"
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
"id": 44,
|
|
263
|
-
"name": "Block with double quotes",
|
|
264
|
-
"code": "pattern {$block str {\"}{\"}} {STR[$str]}\n\"hello\"",
|
|
265
|
-
"expected": "STR[hello]"
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"id": 45,
|
|
269
|
-
"name": "Pattern with flexible space before and after",
|
|
270
|
-
"code": "pattern {$$ hello$$ } {FOUND}\n hello ",
|
|
271
|
-
"expected": "FOUND"
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
"id": 46,
|
|
275
|
-
"name": "Multiple blocks in one pattern",
|
|
276
|
-
"code": "pattern {$block a {(}{)}, $block b {[}{]}} {PAIR: $a and $b}\n(first), [second]",
|
|
277
|
-
"expected": "PAIR: first and second"
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
"id": 47,
|
|
281
|
-
"name": "Pattern with math symbols",
|
|
282
|
-
"code": "pattern {$x * $y} {multiplication: $x * $y}\n5 * 3",
|
|
283
|
-
"expected": "multiplication: 5 * 3"
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
"id": 48,
|
|
287
|
-
"name": "Eval with division and decimals",
|
|
288
|
-
"code": "pattern {div $a $b} {quotient: $eval{return $a / $b}}\ndiv 7 2",
|
|
289
|
-
"expected": "quotient: 3.5"
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
"id": 49,
|
|
293
|
-
"name": "Negative numbers in $eval",
|
|
294
|
-
"code": "pattern {calc $a $b} {result: $eval{return $a - $b}}\ncalc -5 -10",
|
|
295
|
-
"expected": "result: 5"
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
"id": 50,
|
|
299
|
-
"name": "Tabs as flexible whitespace",
|
|
300
|
-
"code": "pattern {from$$to} {path: from -> to}\nfrom\tto",
|
|
301
|
-
"expected": "path: from -> to"
|
|
302
|
-
},
|
|
303
|
-
{
|
|
304
|
-
"id": 51,
|
|
305
|
-
"name": "Unicode characters in variables",
|
|
306
|
-
"code": "pattern {greet $name} {Olá $name}\ngreet 世界",
|
|
307
|
-
"expected": "Olá 世界"
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
"id": 52,
|
|
311
|
-
"name": "Emoji support",
|
|
312
|
-
"code": "pattern {say $emoji} {You said: $emoji}\nsay 😊",
|
|
313
|
-
"expected": "You said: 😊"
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
"id": 53,
|
|
317
|
-
"name": "Trim multiple surrounding spaces",
|
|
318
|
-
"code": "pattern {$ $word$ } {FOUND: $word}\n word ",
|
|
319
|
-
"expected": "FOUND: word"
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
"id": 54,
|
|
323
|
-
"name": "No match leaves input intact",
|
|
324
|
-
"code": "pattern {nomatch $x} {X}\nnothing matches here",
|
|
325
|
-
"expected": "nothing matches here"
|
|
326
|
-
},
|
|
327
|
-
{
|
|
328
|
-
"id": 55,
|
|
329
|
-
"name": "Block captures first simple angle block",
|
|
330
|
-
"code": "pattern {$block txt {<}{>}} {CAP[$txt]}\nstart <one> middle <two> end",
|
|
331
|
-
"expected": "CAP[one]"
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
"id": 56,
|
|
335
|
-
"name": "Overlapping patterns cascade",
|
|
336
|
-
"code": "pattern {a} {A}\npattern {A} {B}\na",
|
|
337
|
-
"expected": "B"
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
"id": 57,
|
|
341
|
-
"name": "Literal dollar in replacement",
|
|
342
|
-
"code": "pattern {price} {Price: $50}\nprice",
|
|
343
|
-
"expected": "Price: $50"
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
"id": 58,
|
|
347
|
-
"name": "Simple Test",
|
|
348
|
-
"code": "pattern {$file.$ext} {file: $file}\nphoto.png",
|
|
349
|
-
"expected": "file: photo"
|
|
350
|
-
},
|
|
351
|
-
{
|
|
352
|
-
"id": 59,
|
|
353
|
-
"name": "Repeated global replacements",
|
|
354
|
-
"code": "pattern {x} {X}\nxxxxx",
|
|
355
|
-
"expected": "XXXXX"
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
"id": 60,
|
|
359
|
-
"name": "Context preserves inner pattern output",
|
|
360
|
-
"code": "context {\npattern {$x} {<$x>}\ninner\n}\ninner\nouter",
|
|
361
|
-
"expected": "<inner>"
|
|
362
|
-
},
|
|
363
|
-
{
|
|
364
|
-
"id": 61,
|
|
365
|
-
"name": "Block with pipe delimiters",
|
|
366
|
-
"code": "pattern {$block mid {|}{|}} {PIPE[$mid]}\n|a| and |b|",
|
|
367
|
-
"expected": "PIPE[a]"
|
|
368
|
-
},
|
|
369
|
-
{
|
|
370
|
-
"id": 62,
|
|
371
|
-
"name": "Trailing comma punctuation handling",
|
|
372
|
-
"code": "pattern {$w,} {$w!}\nhello,",
|
|
373
|
-
"expected": "hello!"
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
"id": 63,
|
|
377
|
-
"name": "Comma-separated two variables",
|
|
378
|
-
"code": "pattern {$a,$b} {[$a][$b]}\none,two",
|
|
379
|
-
"expected": "[one][two]"
|
|
380
|
-
},
|
|
381
|
-
{
|
|
382
|
-
"id": 64,
|
|
383
|
-
"name": "Apostrophe in pattern literal",
|
|
384
|
-
"code": "pattern {It's $name} {Hello $name}\nIt's John",
|
|
385
|
-
"expected": "Hello John"
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
"id": 65,
|
|
389
|
-
"name": "Arithmetic increment with large number",
|
|
390
|
-
"code": "pattern {num $a} {$eval{return parseInt($a) + 1}}\nnum 999",
|
|
391
|
-
"expected": "1000"
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
"id": 66,
|
|
395
|
-
"name": "Parentheses block capture with nesting",
|
|
396
|
-
"code": "pattern {$block txt {(}{)}} {B[$txt]}\n(a(b)c)",
|
|
397
|
-
"expected": "B[a(b)c]"
|
|
398
|
-
},
|
|
399
|
-
{
|
|
400
|
-
"id": 67,
|
|
401
|
-
"name": "Literal special regex characters in pattern",
|
|
402
|
-
"code": "pattern {a.*b} {PAT}\na.*b",
|
|
403
|
-
"expected": "PAT"
|
|
404
|
-
},
|
|
405
|
-
{
|
|
406
|
-
"id": 68,
|
|
407
|
-
"name": "(known issue) Block with multi-character delimiters containing double quotes",
|
|
408
|
-
"code": "pattern {$block str {\"k}{\"k}} {STR[$str]}\n\"khello\"k",
|
|
409
|
-
"expected": "STR[hello]"
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
"id": 69,
|
|
413
|
-
"name": "Block with multi-character delimiters",
|
|
414
|
-
"code": "pattern {$block str {open}{close}} {$str World!}\nopenHelloclose",
|
|
415
|
-
"expected": "Hello World!"
|
|
416
|
-
},
|
|
417
|
-
{
|
|
418
|
-
"id": 70,
|
|
419
|
-
"name": "Clear and keep",
|
|
420
|
-
"code": "pattern {SKIP $x} {$clear KEEP: $x} IGNORE_THIS SKIP keep_this",
|
|
421
|
-
"expected": "KEEP: keep_this"
|
|
422
|
-
},
|
|
423
|
-
{
|
|
424
|
-
"id": 71,
|
|
425
|
-
"name": "Simple Variables",
|
|
426
|
-
"code": "pattern {$x} {$x}\nhello",
|
|
427
|
-
"expected": "hello"
|
|
428
|
-
},
|
|
429
|
-
{
|
|
430
|
-
"id": 72,
|
|
431
|
-
"name": "Multiple Variables",
|
|
432
|
-
"code": "pattern {$x $y $z} {$z, $y, $x}\napple banana cherry",
|
|
433
|
-
"expected": "cherry, banana, apple"
|
|
434
|
-
},
|
|
435
|
-
{
|
|
436
|
-
"id": 73,
|
|
437
|
-
"name": "Flexible Whitespace",
|
|
438
|
-
"code": "pattern {$x$$and$$$y} {$x & $y}\nhello and world",
|
|
439
|
-
"expected": "hello & world"
|
|
440
|
-
},
|
|
441
|
-
{
|
|
442
|
-
"id": 74,
|
|
443
|
-
"name": "Flexible Whitespace (compact)",
|
|
444
|
-
"code": "pattern {$x$$and$$$y} {$x & $y}\nhello and world",
|
|
445
|
-
"expected": "hello & world"
|
|
446
|
-
},
|
|
447
|
-
{
|
|
448
|
-
"id": 75,
|
|
449
|
-
"name": "Block with parentheses",
|
|
450
|
-
"code": "pattern {$name $block content {(}{)}} {[$content]}\ndata (hello world)",
|
|
451
|
-
"expected": "[hello world]"
|
|
452
|
-
},
|
|
453
|
-
{
|
|
454
|
-
"id": 76,
|
|
455
|
-
"name": "Block with custom delimiters <<>>",
|
|
456
|
-
"code": "pattern {$block data {<<}{>>}} {DATA: $data}\n<<json stuff>>",
|
|
457
|
-
"expected": "DATA: json stuff"
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
"id": 77,
|
|
461
|
-
"name": "Multiple Blocks in pattern",
|
|
462
|
-
"code": "pattern {$block a {(}{)}, $block b {[}{]}} {$a|$b}\n(first), [second]",
|
|
463
|
-
"expected": "first|second"
|
|
464
|
-
},
|
|
465
|
-
{
|
|
466
|
-
"id": 78,
|
|
467
|
-
"name": "Basic pattern with literals",
|
|
468
|
-
"code": "pattern {match} {replace}\nmatch",
|
|
469
|
-
"expected": "replace"
|
|
470
|
-
},
|
|
471
|
-
{
|
|
472
|
-
"id": 79,
|
|
473
|
-
"name": "Markdown heading example",
|
|
474
|
-
"code": "pattern {# $title} {<h1>$title</h1>}\n# Welcome",
|
|
475
|
-
"expected": "<h1>Welcome</h1>"
|
|
476
|
-
},
|
|
477
|
-
{
|
|
478
|
-
"id": 80,
|
|
479
|
-
"name": "Multiple patterns cascade",
|
|
480
|
-
"code": "pattern {a} {b}\npattern {b} {c}\npattern {c} {d}\na",
|
|
481
|
-
"expected": "d"
|
|
482
|
-
},
|
|
483
|
-
{
|
|
484
|
-
"id": 81,
|
|
485
|
-
"name": "Context basic",
|
|
486
|
-
"code": "context {\n pattern {$x} {<$x>}\n \n apple\n banana\n}",
|
|
487
|
-
"expected": "<apple>\n <banana>"
|
|
488
|
-
},
|
|
489
|
-
{
|
|
490
|
-
"id": 82,
|
|
491
|
-
"name": "$unique incremental",
|
|
492
|
-
"code": "pattern {item} {[$unique]item_$unique}\nitem\nitem\nitem",
|
|
493
|
-
"expected": "[0]item_0\n[1]item_1\n[2]item_2"
|
|
494
|
-
},
|
|
495
|
-
{
|
|
496
|
-
"id": 83,
|
|
497
|
-
"name": "$unique same ID in replacement",
|
|
498
|
-
"code": "pattern {a} {$unique $unique}\na",
|
|
499
|
-
"expected": "0 0"
|
|
500
|
-
},
|
|
501
|
-
{
|
|
502
|
-
"id": 84,
|
|
503
|
-
"name": "$match full match",
|
|
504
|
-
"code": "pattern {[$x]} {FOUND: $match}\n[data]",
|
|
505
|
-
"expected": "FOUND: [data]"
|
|
506
|
-
},
|
|
507
|
-
{
|
|
508
|
-
"id": 85,
|
|
509
|
-
"name": "$prefix e $suffix",
|
|
510
|
-
"code": "pattern {world} {$prefix$suffix}hello world test",
|
|
511
|
-
"expected": "hello hello test test"
|
|
512
|
-
},
|
|
513
|
-
{
|
|
514
|
-
"id": 86,
|
|
515
|
-
"name": "$clear remove before match",
|
|
516
|
-
"code": "pattern {SKIP $x} {$clear KEEP: $x}\nIGNORE_THIS SKIP keep_this",
|
|
517
|
-
"expected": "KEEP: keep_this"
|
|
518
|
-
},
|
|
519
|
-
{
|
|
520
|
-
"id": 87,
|
|
521
|
-
"name": "$eval arithmetic multiplication",
|
|
522
|
-
"code": "pattern {$x} {$eval{return parseInt($x) * 2;}}\n5",
|
|
523
|
-
"expected": "10"
|
|
524
|
-
},
|
|
525
|
-
{
|
|
526
|
-
"id": 88,
|
|
527
|
-
"name": "Markdown h1 and h2",
|
|
528
|
-
"code": "pattern {## $t} {<h2>$t</h2>}\npattern {# $t} {<h1>$t</h1>}\n# Title\n## Subtitle",
|
|
529
|
-
"expected": "<h1>Title</h1>\n<h2>Subtitle</h2>"
|
|
530
|
-
},
|
|
531
|
-
{
|
|
532
|
-
"id": 89,
|
|
533
|
-
"name": "Markdown bold and italic",
|
|
534
|
-
"code": "pattern {**$t**} {<strong>$t</strong>}\npattern {*$t*} {<em>$t</em>}\n**bold** and *italic*",
|
|
535
|
-
"expected": "<strong>bold</strong> and <em>italic</em>"
|
|
536
|
-
},
|
|
537
|
-
{
|
|
538
|
-
"id": 90,
|
|
539
|
-
"name": "Markdown list",
|
|
540
|
-
"code": "pattern {- $i} {<li>$i</li>}\n- item1\n- item2",
|
|
541
|
-
"expected": "<li>item1</li>\n<li>item2</li>"
|
|
542
|
-
},
|
|
543
|
-
{
|
|
544
|
-
"id": 91,
|
|
545
|
-
"name": "CSV to JSON",
|
|
546
|
-
"code": "pattern {$a,$$b,$$c} {{ id: '$a', name: '$b', role: '$c' }}\n1,Alice,Engineer\n2,Bob,Designer",
|
|
547
|
-
"expected": "{ id: '1', name: 'Alice', role: 'Engineer' }\n{ id: '2', name: 'Bob', role: 'Designer' }"
|
|
548
|
-
},
|
|
549
|
-
{
|
|
550
|
-
"id": 92,
|
|
551
|
-
"name": "Config parser",
|
|
552
|
-
"code": "pattern {$key = $value} {const $key = '$value';}\nhost = localhost\nport = 3000",
|
|
553
|
-
"expected": "const host = 'localhost';\nconst port = '3000';"
|
|
554
|
-
},
|
|
555
|
-
{
|
|
556
|
-
"id": 93,
|
|
557
|
-
"name": "HTML generator",
|
|
558
|
-
"code": "pattern {$tag $content} {<$tag>$content</$tag>}\ndiv HelloWorld\nspan Test",
|
|
559
|
-
"expected": "<div>HelloWorld</div>\n<span>Test</span>"
|
|
560
|
-
},
|
|
561
|
-
{
|
|
562
|
-
"id": 94,
|
|
563
|
-
"name": "Variable reuse in replacement",
|
|
564
|
-
"code": "pattern {$x} {$x:$x:$x}\ndata",
|
|
565
|
-
"expected": "data:data:data"
|
|
566
|
-
},
|
|
567
|
-
{
|
|
568
|
-
"id": 95,
|
|
569
|
-
"name": "Literal dollar sign in replacement",
|
|
570
|
-
"code": "pattern {price} {Price: $50}\nprice",
|
|
571
|
-
"expected": "Price: $50"
|
|
572
|
-
},
|
|
573
|
-
{
|
|
574
|
-
"id": 96,
|
|
575
|
-
"name": "Block with angle brackets nesting",
|
|
576
|
-
"code": "pattern {$block content {<}{>}} {CONTENT:$content}\nouter <inner <deep> more>",
|
|
577
|
-
"expected": "CONTENT:inner <deep> more"
|
|
578
|
-
},
|
|
579
|
-
{
|
|
580
|
-
"id": 97,
|
|
581
|
-
"name": "Pattern with special regex characters",
|
|
582
|
-
"code": "pattern {a.*b} {MATCHED}\na.*b",
|
|
583
|
-
"expected": "MATCHED"
|
|
584
|
-
},
|
|
585
|
-
{
|
|
586
|
-
"id": 98,
|
|
587
|
-
"name": "Multiple $eval operations",
|
|
588
|
-
"code": "pattern {add $a $b} {$eval{return parseInt($a) + parseInt($b)}}\nadd 15 25",
|
|
589
|
-
"expected": "40"
|
|
590
|
-
},
|
|
591
|
-
{
|
|
592
|
-
"id": 99,
|
|
593
|
-
"name": "$eval with division and decimals",
|
|
594
|
-
"code": "pattern {div $a $b} {$eval{return $a / $b}}\ndiv 7 2",
|
|
595
|
-
"expected": "3.5"
|
|
596
|
-
},
|
|
597
|
-
{
|
|
598
|
-
"id": 100,
|
|
599
|
-
"name": "Unicode characters support",
|
|
600
|
-
"code": "pattern {oi $name} {Olá $name!}\noi Mundo",
|
|
601
|
-
"expected": "Olá Mundo!"
|
|
602
|
-
},
|
|
603
|
-
{
|
|
604
|
-
"id": 101,
|
|
605
|
-
"name": "Emoji support",
|
|
606
|
-
"code": "pattern {react $emoji} {Você reagiu: $emoji}\nreact 😊",
|
|
607
|
-
"expected": "Você reagiu: 😊"
|
|
608
|
-
},
|
|
609
|
-
{
|
|
610
|
-
"id": 102,
|
|
611
|
-
"name": "Tab as flexible whitespace",
|
|
612
|
-
"code": "pattern {from$$to} {path: from -> to}\nfrom\tto",
|
|
613
|
-
"expected": "path: from -> to"
|
|
614
|
-
},
|
|
615
|
-
{
|
|
616
|
-
"id": 103,
|
|
617
|
-
"name": "No match leaves input intact",
|
|
618
|
-
"code": "pattern {nomatch $x} {REPLACED}\nnothing matches here",
|
|
619
|
-
"expected": "nothing matches here"
|
|
620
|
-
},
|
|
621
|
-
{
|
|
622
|
-
"id": 104,
|
|
623
|
-
"name": "Empty context is removed",
|
|
624
|
-
"code": "Start\ncontext {}End",
|
|
625
|
-
"expected": "Start\nEnd"
|
|
626
|
-
},
|
|
627
|
-
{
|
|
628
|
-
"id": 105,
|
|
629
|
-
"name": "Block with pipe delimiters",
|
|
630
|
-
"code": "pattern {$block content {|}{|}} {PIPE[$content]}\n|value|",
|
|
631
|
-
"expected": "PIPE[value]"
|
|
632
|
-
},
|
|
633
|
-
{
|
|
634
|
-
"id": 106,
|
|
635
|
-
"name": "Block with double quotes delimiter",
|
|
636
|
-
"code": "pattern {$block str {\"}{\"}} {STR[$str]}\n\"hello world\"",
|
|
637
|
-
"expected": "STR[hello world]"
|
|
638
|
-
},
|
|
639
|
-
{
|
|
640
|
-
"id": 107,
|
|
641
|
-
"name": "Comma-separated pattern matching",
|
|
642
|
-
"code": "pattern {$$a,$$b,$$c} {[$a] [$b] [$c]}\none,two,three",
|
|
643
|
-
"expected": "[one] [two] [three]"
|
|
644
|
-
},
|
|
645
|
-
{
|
|
646
|
-
"id": 108,
|
|
647
|
-
"name": "Apostrophe in pattern literal",
|
|
648
|
-
"code": "pattern {It's $name} {Hello $name}\nIt's John",
|
|
649
|
-
"expected": "Hello John"
|
|
650
|
-
},
|
|
651
|
-
{
|
|
652
|
-
"id": 109,
|
|
653
|
-
"name": "Math operation with $eval",
|
|
654
|
-
"code": "pattern {num $a} {$eval{return parseInt($a) + 1}}\nnum 999",
|
|
655
|
-
"expected": "1000"
|
|
656
|
-
},
|
|
657
|
-
{
|
|
658
|
-
"id": 110,
|
|
659
|
-
"name": "Multi-character block delimiters",
|
|
660
|
-
"code": "pattern {$block code {open}{close}} {CODE[$code]}\nopenFunction()close",
|
|
661
|
-
"expected": "CODE[Function()]"
|
|
662
|
-
},
|
|
663
|
-
{
|
|
664
|
-
"id": 111,
|
|
665
|
-
"name": "Pattern with dot literal",
|
|
666
|
-
"code": "pattern {$$file.txt} {File: $file.txt}\ndocument.txt",
|
|
667
|
-
"expected": "File: document"
|
|
668
|
-
},
|
|
669
|
-
{
|
|
670
|
-
"id": 112,
|
|
671
|
-
"name": "Repeated global pattern matching",
|
|
672
|
-
"code": "pattern {x} {X}\nxxxxx",
|
|
673
|
-
"expected": "XXXXX"
|
|
674
|
-
},
|
|
675
|
-
{
|
|
676
|
-
"id": 113,
|
|
677
|
-
"name": "Overlapping patterns cascade",
|
|
678
|
-
"code": "pattern {a} {A}\npattern {A} {B}\npattern {B} {C}\na",
|
|
679
|
-
"expected": "C"
|
|
680
|
-
},
|
|
681
|
-
{
|
|
682
|
-
"id": 114,
|
|
683
|
-
"name": "Context with nested patterns",
|
|
684
|
-
"code": "context {\n pattern {$x} {\n<$x>}\napple\nbanana\ncherry\n}",
|
|
685
|
-
"expected": "<apple>\n<banana>\n<cherry>"
|
|
686
|
-
},
|
|
687
|
-
{
|
|
688
|
-
"id": 115,
|
|
689
|
-
"name": "$eval with subtraction (negatives)",
|
|
690
|
-
"code": "pattern {calc $a $b} {$eval{return $a - $b}}\ncalc -5 -10",
|
|
691
|
-
"expected": "5"
|
|
692
|
-
},
|
|
693
|
-
{
|
|
694
|
-
"id": 116,
|
|
695
|
-
"name": "Multiple spaces trim with flexible whitespace",
|
|
696
|
-
"code": "pattern {$ $word$ } {FOUND: $word}\n word ",
|
|
697
|
-
"expected": "FOUND: word"
|
|
698
|
-
},
|
|
699
|
-
{
|
|
700
|
-
"id": 117,
|
|
701
|
-
"name": "Block captures parentheses with nesting",
|
|
702
|
-
"code": "pattern {$block content {(}{)}} {B[$content]}\n(a(b)c)",
|
|
703
|
-
"expected": "B[a(b)c]"
|
|
704
|
-
},
|
|
705
|
-
{
|
|
706
|
-
"id": 118,
|
|
707
|
-
"name": "Arithmetic in config pattern",
|
|
708
|
-
"code": "pattern {$x + $y = $z} {$z is sum of $x and $y}\n5 + 3 = 8",
|
|
709
|
-
"expected": "8 is sum of 5 and 3"
|
|
710
|
-
},
|
|
711
|
-
{
|
|
712
|
-
"id": 119,
|
|
713
|
-
"name": "Trailing punctuation in pattern",
|
|
714
|
-
"code": "pattern {$$w,} {$$w!}\nhello,",
|
|
715
|
-
"expected": "hello!"
|
|
209
|
+
"name": "Cascading pattern transformations",
|
|
210
|
+
"code": "pattern {START $x END} {STEP1[$x]}\npattern {STEP1 $y} {STEP2[$y]}\npattern {STEP2 $z} {FINAL[$z]}\nSTART test END",
|
|
211
|
+
"expected": "FINAL[[[test]]]"
|
|
716
212
|
}
|
|
717
213
|
]
|
|
718
214
|
}
|