wptemplates 0.0.3

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.
@@ -0,0 +1,38 @@
1
+ module Wptemplates
2
+ module Utils
3
+ module_function
4
+
5
+ def normalize_link string, anchor = false
6
+ normalized = string.clone
7
+ normalized.tr!('_',' ')
8
+ normalized.strip!
9
+ normalized.squeeze!(' ')
10
+ normalized[0] = normalized[0,1].upcase unless anchor
11
+ normalized
12
+ end
13
+
14
+ def normalize_linklabel string
15
+ normalized = string.clone
16
+ normalized.strip!
17
+ normalized.squeeze!(' ')
18
+ normalized
19
+ end
20
+
21
+ def symbolize string
22
+ symbolized = normalize_link(string)
23
+ symbolized.tr!(' ','_')
24
+ symbolized.downcase.to_sym
25
+ end
26
+
27
+ def fixpoint options = {}
28
+ clone = options[:clone] || false
29
+ cur = options[:start]
30
+ begin
31
+ pre = clone && !cur.nil? ? cur.clone : cur
32
+ cur = yield(cur)
33
+ end while cur != pre
34
+ cur
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module Wptemplates
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,458 @@
1
+ require 'spec_helper'
2
+ require 'strscan'
3
+
4
+ def ScanShortcutFor(regex)
5
+ Module.new do
6
+ define_method :scan do |text|
7
+ StringScanner.new(text).scan(Wptemplates::Regexes.send(regex))
8
+ end
9
+ define_method :scanner_after do |text|
10
+ s = StringScanner.new(text)
11
+ s.scan(Wptemplates::Regexes.send(regex))
12
+ s
13
+ end
14
+ end
15
+ end
16
+
17
+ describe Wptemplates::Regexes do
18
+
19
+ describe '.till_doublebrace_doubleopenbrackets_or_pipe' do
20
+ include ScanShortcutFor(:till_doublebrace_doubleopenbrackets_or_pipe)
21
+
22
+ it 'consumes a string with no doublebraces or doubleopenbrackets or pipes at all' do
23
+ expect(scan "abc").to eq("abc")
24
+ end
25
+ it 'consumes until doublebraces or doubleopenbrackets or pipe' do
26
+ expect(scan "abc{{d").to eq("abc")
27
+ expect(scan "abc|d").to eq("abc")
28
+ expect(scan "abc}}d").to eq("abc")
29
+ expect(scan "abc[[d").to eq("abc")
30
+ end
31
+ it 'ignores starting doubleopenbrackets' do
32
+ expect(scan "[[abc").to eq("[[abc")
33
+ expect(scan "[[abc{{d").to eq("[[abc")
34
+ expect(scan "[[abc|d").to eq("[[abc")
35
+ expect(scan "[[abc}}d").to eq("[[abc")
36
+ expect(scan "[[abc[[d").to eq("[[abc")
37
+ end
38
+ it 'does not accept an empty string (epsilon transition)' do
39
+ expect(scan "{{d").to be_false
40
+ expect(scan "|d").to be_false
41
+ expect(scan "}}d").to be_false
42
+ end
43
+ it 'consumes until doublebraces or doubleopenbrackets or pipe even if other braces and pipes show up (not greedy)' do
44
+ expect(scan "ab|c{{d}}e").to eq("ab")
45
+ expect(scan "ab|c|d|e").to eq("ab")
46
+ expect(scan "ab{{c|d}}e").to eq("ab")
47
+ expect(scan "ab}}c|d{{e").to eq("ab")
48
+ expect(scan "ab[[c|d}}e").to eq("ab")
49
+ expect(scan "ab[[c|d{{e").to eq("ab")
50
+ end
51
+ it 'ignores lone braces' do
52
+ expect(scan "ab{c|d}}e").to eq("ab{c")
53
+ expect(scan "ab}c|d{{e").to eq("ab}c")
54
+ end
55
+ it 'ignores lone openbrackets' do
56
+ expect(scan "ab[c|d}}e").to eq("ab[c")
57
+ end
58
+ it 'ignores closebrackets' do
59
+ expect(scan "ab]]c|d}}e").to eq("ab]]c")
60
+ end
61
+ end
62
+
63
+ describe '.till_doubleopenbrace_or_doubleopenbrackets' do
64
+ include ScanShortcutFor(:till_doubleopenbrace_or_doubleopenbrackets)
65
+
66
+ it 'consumes a string with no doubleopenbraces or doubleopenbrackets at all' do
67
+ expect(scan "abc").to eq("abc")
68
+ expect(scan "ab}}c").to eq("ab}}c")
69
+ expect(scan "ab|c").to eq("ab|c")
70
+ expect(scan "ab]]c").to eq("ab]]c")
71
+ end
72
+ it 'consumes until doubleopenbraces' do
73
+ expect(scan "abc{{d").to eq("abc")
74
+ expect(scan "abc|d{{").to eq("abc|d")
75
+ expect(scan "abc}}d{{").to eq("abc}}d")
76
+ end
77
+ it 'ignores starting doubleopenbrackets' do
78
+ expect(scan "[[abc").to eq("[[abc")
79
+ expect(scan "[[abc{{d").to eq("[[abc")
80
+ expect(scan "[[abc|d{{").to eq("[[abc|d")
81
+ expect(scan "[[abc}}d{{").to eq("[[abc}}d")
82
+ end
83
+ it 'consumes until doubleopenbrackets' do
84
+ expect(scan "abc[[d").to eq("abc")
85
+ expect(scan "abc|d[[").to eq("abc|d")
86
+ expect(scan "abc]]d[[").to eq("abc]]d")
87
+ end
88
+ it 'does not accept an empty string (epsilon transition)' do
89
+ expect(scan "{{d").to be_false
90
+ end
91
+ it 'consumes until doubleopenbraces/brackets if other doubleopenbraces/brackets show up (not greedy)' do
92
+ expect(scan "ab{{d{{e").to eq("ab")
93
+ expect(scan "ab[[d{{e").to eq("ab")
94
+ expect(scan "ab[[d[[e").to eq("ab")
95
+ expect(scan "ab{{d[[e").to eq("ab")
96
+ end
97
+ it 'ignores lone braces and brackets' do
98
+ expect(scan "ab[{c{{e").to eq("ab[{c")
99
+ expect(scan "ab[{c[[e").to eq("ab[{c")
100
+ end
101
+ end
102
+
103
+ describe '.till_doubleclosebrace_or_pipe' do
104
+ include ScanShortcutFor(:till_doubleclosebrace_or_pipe)
105
+
106
+ it 'consumes a string with no doubleclosebraces or pipes at all' do
107
+ expect(scan "abc").to eq("abc")
108
+ expect(scan "ab{{c").to eq("ab{{c")
109
+ end
110
+ it 'consumes until doubleclosebraces' do
111
+ expect(scan "abc}}d").to eq("abc")
112
+ expect(scan "a{{bc}}d").to eq("a{{bc")
113
+ end
114
+ it 'consumes until a pipe' do
115
+ expect(scan "abc|d").to eq("abc")
116
+ expect(scan "a{{bc|d").to eq("a{{bc")
117
+ end
118
+ it 'does not accept an empty string (epsilon transition)' do
119
+ expect(scan "}}d").to be_false
120
+ expect(scan "|d").to be_false
121
+ end
122
+ it 'consumes until doubleclosebracees even if other doubleclosebrace show up (not greedy)' do
123
+ expect(scan "ab}}d}}e").to eq("ab")
124
+ end
125
+ it 'consumes until a pipe even if other pipes show up (not greedy)' do
126
+ expect(scan "ab|d|e").to eq("ab")
127
+ end
128
+ it 'ignores lone braces' do
129
+ expect(scan "ab}c}}e").to eq("ab}c")
130
+ end
131
+ end
132
+
133
+ describe '.from_pipe_till_equals_no_doubleclosebrace_or_pipe' do
134
+ include ScanShortcutFor(:from_pipe_till_equals_no_doubleclosebrace_or_pipe)
135
+
136
+ context 'when there is an equals sign and a pipe' do
137
+ it 'consumes a string including equals with no doubleclosebraces or pipes at all' do
138
+ expect(scan "|abc=").to eq("|abc=")
139
+ expect(scan "|abc=d").to eq("|abc=")
140
+ expect(scan "|ab{{c=d").to eq("|ab{{c=")
141
+ end
142
+ it 'fails when doubleclosebraces occur before equals' do
143
+ expect(scan "|abc}}d=e").to be_false
144
+ expect(scan "|a{{bc}}d=e").to be_false
145
+ end
146
+ it 'ignores single closebraces' do
147
+ expect(scan "|abc}d=e").to eq("|abc}d=")
148
+ expect(scan "|a{{bc}d=e").to eq("|a{{bc}d=")
149
+ end
150
+ it 'fails when a pipe occurs before equals' do
151
+ expect(scan "|abc|d=e").to be_false
152
+ expect(scan "|a{{bc|d=e").to be_false
153
+ end
154
+ it 'does actually accept an empty string (epsilon transition)' do
155
+ expect(scan "|=d").to eq("|=")
156
+ expect(scan "|=").to eq("|=")
157
+ end
158
+ it 'consumes until equals even if other equals show up (not greedy)' do
159
+ expect(scan "|ab=d=e").to eq("|ab=")
160
+ end
161
+ it 'provides us with the stuff between pipe and equals in the first index' do
162
+ expect(scanner_after("|ab=c")[1]).to eq("ab")
163
+ expect(scanner_after("|=c")[1]).to eq("")
164
+ end
165
+ end
166
+
167
+ context 'when there is no equals sign' do
168
+ it 'fails on plain string' do
169
+ expect(scan "|abc").to be_false
170
+ end
171
+ it 'fails when there is a pipe' do
172
+ expect(scan "abc|d").to be_false
173
+ expect(scan "abcd|").to be_false
174
+ expect(scan "|abcd").to be_false
175
+ end
176
+ it 'fails when there are doubleclosebraces' do
177
+ expect(scan "abc}}d").to be_false
178
+ expect(scan "abcd}}").to be_false
179
+ expect(scan "}}abcd").to be_false
180
+ end
181
+ end
182
+ context 'when the pipe is not a the beginning or there is no pipe' do
183
+ it 'fails' do
184
+ expect(scan "abc").to be_false
185
+ expect(scan "abc=").to be_false
186
+ expect(scan "a|bc=d").to be_false
187
+ expect(scan " |bc=d").to be_false
188
+ end
189
+ end
190
+
191
+ end
192
+
193
+ describe '.a_pipe' do
194
+ include ScanShortcutFor(:a_pipe)
195
+
196
+ it 'consumes a pipe' do
197
+ expect(scan "|").to eq("|")
198
+ expect(scan "|a").to eq("|")
199
+ end
200
+ it 'consumes only one pipe even if there are others around (not greedy)' do
201
+ expect(scan "|||").to eq("|")
202
+ expect(scan "|a|").to eq("|")
203
+ expect(scan "|a|a").to eq("|")
204
+ end
205
+ it 'fails when there is stuff before the pipe' do
206
+ expect(scan "a|").to be_false
207
+ expect(scan "a|b").to be_false
208
+ end
209
+ end
210
+
211
+ describe '.a_doubleopenbrace' do
212
+ include ScanShortcutFor(:a_doubleopenbrace)
213
+
214
+ it 'consumes a doubleopenbrace' do
215
+ expect(scan "{{").to eq("{{")
216
+ expect(scan "{{a").to eq("{{")
217
+ end
218
+ it 'consumes only one doubleopenbrace even if there are others around (not greedy)' do
219
+ expect(scan "{{a{{").to eq("{{")
220
+ expect(scan "{{a{{a").to eq("{{")
221
+ end
222
+ it 'fails when there is stuff before the doubleopenbrace' do
223
+ expect(scan "a{{").to be_false
224
+ expect(scan "a{{b").to be_false
225
+ end
226
+ it 'ignores singleopenbrace' do
227
+ expect(scan "a{").to be_false
228
+ expect(scan "a{b").to be_false
229
+ end
230
+ it 'deals with extra braces' do
231
+ expect(scan "{{{").to eq("{{")
232
+ expect(scan "{{{{").to eq("{{")
233
+ expect(scan "{{{{{").to eq("{{")
234
+ expect(scan "{{{{{{").to eq("{{")
235
+ end
236
+ it 'ignores pipes and doubleclosingbrace' do
237
+ expect(scan "|").to be_false
238
+ expect(scan "}}").to be_false
239
+ end
240
+ end
241
+
242
+ describe '.a_doubleclosingbrace' do
243
+ include ScanShortcutFor(:a_doubleclosingbrace)
244
+
245
+ it 'consumes a doubleclosingbrace' do
246
+ expect(scan "}}").to eq("}}")
247
+ expect(scan "}}a").to eq("}}")
248
+ end
249
+ it 'consumes only one doubleclosingbrace even if there are others around (not greedy)' do
250
+ expect(scan "}}a}}").to eq("}}")
251
+ expect(scan "}}a}}a").to eq("}}")
252
+ end
253
+ it 'fails when there is stuff before the doubleclosingbrace' do
254
+ expect(scan "a}}").to be_false
255
+ expect(scan "a}}b").to be_false
256
+ end
257
+ it 'ignores singleclosebrace' do
258
+ expect(scan "a}").to be_false
259
+ expect(scan "a}b").to be_false
260
+ end
261
+ it 'deals with extra braces' do
262
+ expect(scan "}}}").to eq("}}")
263
+ expect(scan "}}}}").to eq("}}")
264
+ expect(scan "}}}}}").to eq("}}")
265
+ expect(scan "}}}}}}").to eq("}}")
266
+ end
267
+ it 'ignores pipes and doubleopenbrace' do
268
+ expect(scan "|").to be_false
269
+ expect(scan "{{").to be_false
270
+ end
271
+ end
272
+
273
+ describe '.a_link' do
274
+ include ScanShortcutFor(:a_link)
275
+
276
+ it 'consumes a normal link' do
277
+ s = scanner_after("[[foo]]")
278
+ expect(s.matched).to eq("[[foo]]")
279
+ expect(s[1]).to eq("foo")
280
+ expect(s[2]).to be_nil
281
+ expect(s[3]).to eq("")
282
+ end
283
+ it 'consumes only the normal link' do
284
+ s = scanner_after("[[foo]].")
285
+ expect(s.matched).to eq("[[foo]]")
286
+ expect(s[1]).to eq("foo")
287
+ expect(s[2]).to be_nil
288
+ expect(s[3]).to eq("")
289
+ end
290
+ it 'consumes some extra letters after closing brackets' do
291
+ s = scanner_after("[[foo]]nx.")
292
+ expect(s.matched).to eq("[[foo]]nx")
293
+ expect(s[1]).to eq("foo")
294
+ expect(s[2]).to be_nil
295
+ expect(s[3]).to eq("nx")
296
+ end
297
+ it 'consumes a link label' do
298
+ s = scanner_after("[[foo|bar]].")
299
+ expect(s.matched).to eq("[[foo|bar]]")
300
+ expect(s[1]).to eq("foo")
301
+ expect(s[2]).to eq("bar")
302
+ expect(s[3]).to eq("")
303
+ end
304
+ it 'consumes a link label and extra letters' do
305
+ s = scanner_after("[[foo|bar]]ny.")
306
+ expect(s.matched).to eq("[[foo|bar]]ny")
307
+ expect(s[1]).to eq("foo")
308
+ expect(s[2]).to eq("bar")
309
+ expect(s[3]).to eq("ny")
310
+ end
311
+ it 'consumes an empty link label' do
312
+ s = scanner_after("[[foo|]].")
313
+ expect(s.matched).to eq("[[foo|]]")
314
+ expect(s[1]).to eq("foo")
315
+ expect(s[2]).to eq("")
316
+ expect(s[3]).to eq("")
317
+ end
318
+ it 'consumes a link with an anchor' do
319
+ s = scanner_after("[[foo#ro|bar]]ny.")
320
+ expect(s.matched).to eq("[[foo#ro|bar]]ny")
321
+ expect(s[1]).to eq("foo#ro")
322
+ expect(s[2]).to eq("bar")
323
+ expect(s[3]).to eq("ny")
324
+ end
325
+ it 'does not consume unclosed links' do
326
+ expect(scan "[[a").to be_false
327
+ end
328
+ it 'does not consume unclosed links with newlines' do
329
+ expect(scan "[[a\nb]]").to be_false
330
+ end
331
+ it 'consume only to the first pair of brackets even if there are others around' do
332
+ s = scanner_after("[[a]]b]]c,x")
333
+ expect(s.matched).to eq("[[a]]b")
334
+ expect(s[1]).to eq("a")
335
+ expect(s[2]).to be_nil
336
+ expect(s[3]).to eq("b")
337
+ end
338
+ it 'consumes pipes in the label' do
339
+ s = scanner_after("[[a|b|c]]d,x")
340
+ expect(s.matched).to eq("[[a|b|c]]d")
341
+ expect(s[1]).to eq("a")
342
+ expect(s[2]).to eq("b|c")
343
+ expect(s[3]).to eq("d")
344
+ end
345
+ it 'consumes single brackets in the label' do
346
+ s = scanner_after("[[a|b]c]]d,x")
347
+ expect(s.matched).to eq("[[a|b]c]]d")
348
+ expect(s[1]).to eq("a")
349
+ expect(s[2]).to eq("b]c")
350
+ expect(s[3]).to eq("d")
351
+ end
352
+ it 'consumes parens in urls' do
353
+ s = scanner_after("[[a(b)|c]]d.")
354
+ expect(s.matched).to eq("[[a(b)|c]]d")
355
+ expect(s[1]).to eq("a(b)")
356
+ expect(s[2]).to eq("c")
357
+ expect(s[3]).to eq("d")
358
+ end
359
+ it 'consumes commas in urls' do
360
+ s = scanner_after("[[a,b|c]]d.")
361
+ expect(s.matched).to eq("[[a,b|c]]d")
362
+ expect(s[1]).to eq("a,b")
363
+ expect(s[2]).to eq("c")
364
+ expect(s[3]).to eq("d")
365
+ end
366
+ it 'consumes spaces in urls' do
367
+ s = scanner_after("[[ ]]")
368
+ expect(s.matched).to eq("[[ ]]")
369
+ expect(s[1]).to eq(" ")
370
+ expect(s[2]).to be_nil
371
+ expect(s[3]).to eq("")
372
+ end
373
+ end
374
+
375
+ describe '.until_hash' do
376
+ it 'prints the part to the first hash, excluding' do
377
+ expect("abc#def"[subject.until_hash]).to eq("abc")
378
+ expect("abc#d#ef"[subject.until_hash]).to eq("abc")
379
+ expect("abc#def#"[subject.until_hash]).to eq("abc")
380
+ expect("abc#"[subject.until_hash]).to eq("abc")
381
+ end
382
+ it 'prints everything if there is no hash' do
383
+ expect("abc"[subject.until_hash]).to eq("abc")
384
+ end
385
+ end
386
+
387
+ describe '.after_hash' do
388
+ it 'prints the part after the first hash, excluding' do
389
+ expect("abc#def"[subject.after_hash]).to eq("def")
390
+ expect("abc#d#ef"[subject.after_hash]).to eq("d#ef")
391
+ expect("abc#def#"[subject.after_hash]).to eq("def#")
392
+ expect("abc#"[subject.after_hash]).to eq("")
393
+ end
394
+ it 'returns nil if there is no hash' do
395
+ expect("abc"[subject.after_hash]).to be_nil
396
+ end
397
+ end
398
+
399
+ describe '.has_parens' do
400
+ it 'detects if there are matching parens at the end' do
401
+ expect("abc(def)"[subject.has_parens]).to be_true
402
+ expect("abc (def)"[subject.has_parens]).to be_true
403
+ expect("abc (def) "[subject.has_parens]).to be_true
404
+ expect("abc(def) "[subject.has_parens]).to be_true
405
+ expect("abc(d(ef)"[subject.has_parens]).to be_true
406
+ expect("abc(d(e)f)"[subject.has_parens]).to be_true
407
+ expect("abc(d(ef)"[subject.has_parens]).to be_true
408
+ expect("abc(d)e(f)"[subject.has_parens]).to be_true
409
+ expect("abc(def"[subject.has_parens]).to be_false
410
+ expect("abc)def"[subject.has_parens]).to be_false
411
+ expect("abc"[subject.has_parens]).to be_false
412
+ end
413
+ it 'returns the part without parens as :no_parens' do
414
+ expect("abc(def)"[subject.has_parens, :no_parens]).to eq("abc")
415
+ expect("abc (def)"[subject.has_parens, :no_parens]).to eq("abc")
416
+ expect("abc (def) "[subject.has_parens, :no_parens]).to eq("abc")
417
+ expect("abc(def) "[subject.has_parens, :no_parens]).to eq("abc")
418
+ expect("abc(d(ef)"[subject.has_parens, :no_parens]).to eq("abc")
419
+ expect("abc(d(e)f)"[subject.has_parens, :no_parens]).to eq("abc")
420
+ expect("abc(d(ef)"[subject.has_parens, :no_parens]).to eq("abc")
421
+ expect("abc(d)e(f)"[subject.has_parens, :no_parens]).to eq("abc")
422
+ expect("abc(def"[subject.has_parens, :no_parens]).to be_nil
423
+ expect("abc)def"[subject.has_parens, :no_parens]).to be_nil
424
+ expect("abc"[subject.has_parens, :no_parens]).to be_nil
425
+ end
426
+ end
427
+
428
+ describe '.first_comma' do
429
+ it 'returns the part before the first comma and space, excluding, as :before' do
430
+ expect("abc, def"[subject.first_comma, :before]).to eq("abc")
431
+ expect("abc, def, ghi"[subject.first_comma, :before]).to eq("abc")
432
+ expect("abc def"[subject.first_comma, :before]).to eq("abc def")
433
+ expect("abc,def"[subject.first_comma, :before]).to eq("abc,def")
434
+ expect("abc,"[subject.first_comma, :before]).to eq("abc,")
435
+ expect(",abc"[subject.first_comma, :before]).to eq(",abc")
436
+ expect(", abc"[subject.first_comma, :before]).to eq("")
437
+ expect("a, , b"[subject.first_comma, :before]).to eq("a")
438
+ end
439
+ end
440
+
441
+ describe '.first_comma' do
442
+ it 'returns the part before the matching parens at the end as :before' do
443
+ expect("abc(def)"[subject.parens, :before]).to eq("abc")
444
+ # different whitespace behaviour not to loose any valid ", "
445
+ expect("abc (def)"[subject.parens, :before]).to eq("abc ")
446
+ expect("abc (def) "[subject.parens, :before]).to eq("abc ")
447
+ expect("abc(def) "[subject.parens, :before]).to eq("abc")
448
+ expect("abc(d(ef)"[subject.parens, :before]).to eq("abc")
449
+ expect("abc(d(e)f)"[subject.parens, :before]).to eq("abc")
450
+ expect("abc(d(ef)"[subject.parens, :before]).to eq("abc")
451
+ expect("abc(d)e(f)"[subject.parens, :before]).to eq("abc")
452
+ expect("abc(def"[subject.parens, :before]).to eq("abc(def")
453
+ expect("abc)def"[subject.parens, :before]).to eq("abc)def")
454
+ expect("abc"[subject.parens, :before]).to eq("abc")
455
+ end
456
+ end
457
+
458
+ end