wikiwah 0.0.1

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.
data/lib/wikiwah.rb~ ADDED
@@ -0,0 +1,99 @@
1
+ require 'wikiwah/flow'
2
+ require 'wikiwah/subst'
3
+ require 'wikiwah/version'
4
+
5
+ # A formatter for turning Wiki-esque text into HTML.
6
+ #
7
+ # = Block-level markup
8
+ #
9
+ # - A line prefixed by "=" is a heading. The heading-level is implied by
10
+ # the number of "=" characters.
11
+ #
12
+ # - A line beginning with "*" or "-" is an unordered list item.
13
+ #
14
+ # - A line beginning with "1.", "(1)" or "#" is an ordered list item.
15
+ #
16
+ # - A paragraph prefixed by "|" is preformatted text (e.g. code)
17
+ #
18
+ # - A paragraph prefixed by ">" is a blockquote (ie. a citation)
19
+ #
20
+ # = Text markup
21
+ #
22
+ # - HTML tags are rendered verbatim.
23
+ #
24
+ # - Text may by marked *bold*, /italic/, _underlined_, +monospace+
25
+ #
26
+ # - Text may be quoted with '{{{' and '}}}'
27
+ #
28
+ # - URLs turn into links.
29
+ #
30
+ # - "{LOCATION}" creates a link to LOCATION.
31
+ #
32
+ # - "{LABEL}@LOCATION" creates a link to LOCATION, with the specified
33
+ # LABEL.
34
+ #
35
+ class WikiWah
36
+
37
+ attr_writer :link_translator
38
+
39
+ def initialize
40
+ @link_translator = proc do |link| link end
41
+ init_transformer
42
+ end
43
+
44
+ # Convert WikiWah text to HTML.
45
+ def to_html(text)
46
+ Flow.convert(text) do |paragraph|
47
+ @transformer.transform(paragraph)
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def translate_link(link)
54
+ @link_translator.call(link)
55
+ end
56
+
57
+ def init_transformer
58
+ @transformer = WikiWah::Subst.new
59
+ @transformer.add_transformation(/""(.+)""/) do |match|
60
+ # Double-double-quoted
61
+ CGI.escapeHTML(match[1])
62
+ end
63
+ @transformer.add_transformation(/\\(.)/) do |match|
64
+ # Backslash-quoted
65
+ match[1]
66
+ end
67
+ @transformer.add_transformation(/\<(.+?)\>/m) do |match|
68
+ # In-line HTML
69
+ match[0]
70
+ end
71
+ @transformer.add_transformation(/\{(.+?)\}(@(\S*[\w\/]))?/m) do |match|
72
+ # Distinuished link
73
+ label = @transformer.transform(match[1])
74
+ location = translate_link(match[3] || match[1])
75
+ if location
76
+ "<a href='#{location}'>#{label}</a>"
77
+ else
78
+ "{#{label}}"
79
+ end
80
+ end
81
+ @transformer.add_transformation(/\b[a-z]+:[\w\/]\S*[\w\/]/) do |match|
82
+ # URL
83
+ "<a href='#{match[0]}'>#{match[0]}</a>"
84
+ end
85
+ @transformer.add_transformation(%r[(^|\W)([*+_/])([*+_/]*\w.*?\w[*+_/]*)\2(?!\w)]) do |match|
86
+ # Bold/italic/etc.
87
+ tag = case match[2]
88
+ when '*'; 'strong'
89
+ when '+'; 'tt'
90
+ when '/'; 'em'
91
+ when '_'; 'u'
92
+ end
93
+ content = @transformer.transform(match[3])
94
+ (match[1] + '<' + tag + '>' + content + '</' + tag + '>')
95
+ end
96
+ end
97
+
98
+ end
99
+
@@ -0,0 +1,422 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'wikiwah/flow'
4
+ require 'test/unit'
5
+
6
+ # Tests follow. The structure is
7
+ #
8
+ # ====
9
+ # #{input}
10
+ # ----
11
+ # #{expected_output}
12
+ #
13
+ # This script will complain if the actual output doesn't match.
14
+
15
+ TESTS = <<END_OF_TESTS
16
+
17
+ ==== # Paragraph
18
+ Simple paragraph
19
+ ----
20
+ <p>
21
+ Simple paragraph
22
+ </p>
23
+
24
+ ==== # Two paragraphs
25
+ P1
26
+
27
+ P2
28
+ ----
29
+ <p>
30
+ P1
31
+ </p>
32
+ <p>
33
+ P2
34
+ </p>
35
+
36
+ ==== # List: one item
37
+ * List
38
+ ----
39
+ <ul class="sparse">
40
+ <li>
41
+ List
42
+ </li>
43
+ </ul>
44
+
45
+ ==== # List: two items
46
+ * item 1
47
+ * item 2
48
+ ----
49
+ <ul class="sparse">
50
+ <li>
51
+ item 1
52
+ </li>
53
+ <li>
54
+ item 2
55
+ </li>
56
+ </ul>
57
+
58
+ ==== # Nested lists
59
+ * item 1
60
+ - item 1.1
61
+ * item 2
62
+ ----
63
+ <ul class="sparse">
64
+ <li>
65
+ item 1
66
+ </li>
67
+ <ul>
68
+ <li>
69
+ item 1.1
70
+ </li>
71
+ </ul>
72
+ <li>
73
+ item 2
74
+ </li>
75
+ </ul>
76
+
77
+ ==== # Numbered list
78
+ # item 1
79
+ # item 2
80
+ ----
81
+ <ol>
82
+ <li>
83
+ item 1
84
+ </li>
85
+ <li>
86
+ item 2
87
+ </li>
88
+ </ol>
89
+
90
+ ==== # Numbered list followed by un-numbered list
91
+ # item 1
92
+ * item 2
93
+ ----
94
+ <ol>
95
+ <li>
96
+ item 1
97
+ </li>
98
+ </ol>
99
+ <ul class="sparse">
100
+ <li>
101
+ item 2
102
+ </li>
103
+ </ul>
104
+
105
+ ==== # Paragraph/list
106
+ P1
107
+
108
+ - item 1
109
+ ----
110
+ <p>
111
+ P1
112
+ </p>
113
+ <ul>
114
+ <li>
115
+ item 1
116
+ </li>
117
+ </ul>
118
+
119
+ ==== # Paragraph/nested-list
120
+ P1
121
+
122
+ - item 1
123
+ ----
124
+ <p>
125
+ P1
126
+ <ul>
127
+ <li>
128
+ item 1
129
+ </li>
130
+ </ul>
131
+ </p>
132
+
133
+ ==== # List/paragraph
134
+ - item 1
135
+
136
+ P1
137
+ ----
138
+ <ul>
139
+ <li>
140
+ item 1
141
+ </li>
142
+ </ul>
143
+ <p>
144
+ P1
145
+ </p>
146
+
147
+ ==== # Paragraph/list/paragraph
148
+ P1
149
+
150
+ - item 1
151
+
152
+ P2
153
+ ----
154
+ <p>
155
+ P1
156
+ </p>
157
+ <ul>
158
+ <li>
159
+ item 1
160
+ </li>
161
+ </ul>
162
+ <p>
163
+ P2
164
+ </p>
165
+
166
+ ==== # Code
167
+ | code
168
+ |
169
+ | more code
170
+ ----
171
+ <pre>
172
+ code
173
+
174
+ more code
175
+ </pre>
176
+
177
+ ==== # Blockquote
178
+ > block
179
+ > quote
180
+ ----
181
+ <blockquote>
182
+ block
183
+ quote
184
+ </blockquote>
185
+
186
+ ==== # Blockquote with space
187
+ > block
188
+ >
189
+ > quote
190
+ ----
191
+ <blockquote>
192
+ block
193
+
194
+ quote
195
+ </blockquote>
196
+
197
+ ====
198
+ > q1
199
+
200
+ - item
201
+
202
+ > q2
203
+ ----
204
+ <blockquote>
205
+ q1
206
+ <ul>
207
+ <li>
208
+ item
209
+ </li>
210
+ </ul>
211
+ q2
212
+ </blockquote>
213
+
214
+ ====
215
+ - item
216
+
217
+ | code
218
+ ----
219
+ <ul>
220
+ <li>
221
+ item
222
+ </li>
223
+ </ul>
224
+ <pre>
225
+ code
226
+ </pre>
227
+
228
+ ====
229
+ * item
230
+
231
+ | code
232
+ ----
233
+ <ul class="sparse">
234
+ <li>
235
+ item
236
+ </li>
237
+ <pre>
238
+ code
239
+ </pre>
240
+ </ul>
241
+
242
+ ====
243
+ Text with <tags> in
244
+ ----
245
+ <p>
246
+ Text with <tags> in
247
+ </p>
248
+
249
+ ====
250
+ drink XXXX
251
+ ----
252
+ <p>
253
+ drink BEER
254
+ </p>
255
+
256
+ ====
257
+ = HEAD
258
+ - blah
259
+ ----
260
+ <h1>
261
+ HEAD
262
+ </h1>
263
+ <ul>
264
+ <li>
265
+ blah
266
+ </li>
267
+ </ul>
268
+
269
+ ====
270
+ P1
271
+
272
+ quote
273
+
274
+ P2
275
+ ----
276
+ <p>
277
+ P1
278
+ <blockquote>
279
+ quote
280
+ </blockquote>
281
+ </p>
282
+ <p>
283
+ P2
284
+ </p>
285
+
286
+ ====
287
+ P1
288
+
289
+ quote
290
+ - xxx
291
+ ----
292
+ <p>
293
+ P1
294
+ <blockquote>
295
+ quote
296
+ <ul>
297
+ <li>
298
+ xxx
299
+ </li>
300
+ </ul>
301
+ </blockquote>
302
+ </p>
303
+
304
+ ====
305
+ 1. juan
306
+ 2. two
307
+ ----
308
+ <ol>
309
+ <li>
310
+ juan
311
+ </li>
312
+ <li>
313
+ two
314
+ </li>
315
+ </ol>
316
+
317
+ ====
318
+ (1) juan
319
+ (2) two
320
+ ----
321
+ <ol>
322
+ <li>
323
+ juan
324
+ </li>
325
+ <li>
326
+ two
327
+ </li>
328
+ </ol>
329
+
330
+ ====
331
+ | x
332
+ | |y|
333
+ | z
334
+ ----
335
+ <pre>
336
+ x
337
+ |y|
338
+ z
339
+ </pre>
340
+
341
+ ====
342
+ - list item
343
+
344
+ == header
345
+ ----
346
+ <ul>
347
+ <li>
348
+ list item
349
+ </li>
350
+ </ul>
351
+ <h2>
352
+ header
353
+ </h2>
354
+
355
+ ====
356
+ % term1
357
+
358
+ definition1
359
+
360
+ % term2
361
+
362
+ definition2
363
+ ----
364
+ <dl>
365
+ <dt>
366
+ term1
367
+ </dt>
368
+ <dd>
369
+ definition1
370
+ </dd>
371
+ <dt>
372
+ term2
373
+ </dt>
374
+ <dd>
375
+ definition2
376
+ </dd>
377
+ </dl>
378
+
379
+ ====
380
+ b4
381
+
382
+ % term1
383
+
384
+ def1
385
+
386
+ after
387
+ ----
388
+ <p>
389
+ b4
390
+ </p>
391
+ <dl>
392
+ <dt>
393
+ term1
394
+ </dt>
395
+ <dd>
396
+ def1
397
+ </dd>
398
+ </dl>
399
+ <p>
400
+ after
401
+ </p>
402
+ END_OF_TESTS
403
+
404
+ class WikiWah
405
+ class FlowTests < Test::Unit::TestCase
406
+
407
+ TESTS.split(/\n====.*\n/).each_with_index do |test, i|
408
+ (input, expected) = test.split(/----\n/)
409
+ next unless expected
410
+ define_method("test_#{i}") do
411
+ actual = WikiWah::Flow.convert(input) do |s|
412
+ s.gsub(/XXXX/, "BEER")
413
+ end
414
+ expected[/\s*\z/] = ''
415
+ actual[/\s*\z/] = ''
416
+ assert_equal(expected, actual)
417
+ end
418
+ end
419
+
420
+ end
421
+ end
422
+