update NOTICE
[nit.git] / lib / markdown / test_markdown.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Test suites for module `markdown`
16 module test_markdown is test_suite
17
18 import test_suite
19 intrude import markdown
20
21 class TestMarkdownProcessor
22 super TestSuite
23
24 fun test_process_empty do
25 var test = ""
26 var exp = ""
27 var res = test.md_to_html.write_to_string
28 assert res == exp
29 end
30
31 fun test_process_tabs do
32 var test = """
33 some code
34 """
35 var exp = """<pre><code>some code
36 </code></pre>
37 """
38 var res = test.md_to_html.write_to_string
39 assert res == exp
40 end
41
42
43 fun test_process_par1 do
44 var test = "test"
45 var exp = "<p>test</p>\n"
46 var res = test.md_to_html.write_to_string
47 assert res == exp
48 end
49
50 fun test_process_par2 do
51 var test = """
52 line1
53 line2
54
55 line3 line4
56
57 line5"""
58 var exp = """
59 <p>line1
60 line2</p>
61 <p>line3 line4</p>
62 <p>line5</p>
63 """
64 var res = test.md_to_html.write_to_string
65 assert res == exp
66 end
67
68 fun test_process_par3 do
69 var test = """
70 Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
71 Aliquam hendrerit mi posuere lectus.
72 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
73
74 Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
75 id sem consectetuer libero luctus adipiscing.
76 """
77 var exp = """
78 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
79 Aliquam hendrerit mi posuere lectus.
80 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
81 <p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
82 id sem consectetuer libero luctus adipiscing.</p>
83 """
84 var res = test.md_to_html.write_to_string
85 assert res == exp
86 end
87
88 fun test_process_headings_1 do
89 var test = """
90 This is a H1
91 =============
92
93 This is a H2
94 -------------
95 """
96 var exp = """
97 <h1 id="This_is_a_H1">This is a H1</h1>
98 <h2 id="This_is_a_H2">This is a H2</h2>
99 """
100 var res = test.md_to_html.write_to_string
101 assert res == exp
102 end
103
104 fun test_process_headings_2 do
105 var test = """
106 # This is a H1
107
108 ## This is a H2
109 ###### This is a H6
110 """
111 var exp = """
112 <h1 id="This_is_a_H1">This is a H1</h1>
113 <h2 id="This_is_a_H2">This is a H2</h2>
114 <h6 id="This_is_a_H6">This is a H6</h6>
115 """
116 var res = test.md_to_html.write_to_string
117 assert res == exp
118 end
119
120 fun test_process_headings_3 do
121 var test = """
122 # This is a H1 #
123
124 ## This is a H2 ##
125
126 ### This is a H3 ######
127 """
128 var exp = """
129 <h1 id="This_is_a_H1">This is a H1</h1>
130 <h2 id="This_is_a_H2">This is a H2</h2>
131 <h3 id="This_is_a_H3">This is a H3</h3>
132 """
133 var res = test.md_to_html.write_to_string
134 assert res == exp
135 end
136
137 fun test_process_hr do
138 var test = """
139 * * *
140
141 ***
142
143 *****
144
145 - - -
146
147 ---------------------------------------
148 """
149 var exp = "<hr/>\n<hr/>\n<hr/>\n<hr/>\n<hr/>\n"
150 var res = test.md_to_html.write_to_string
151 assert res == exp
152 end
153
154 fun test_process_bquote1 do
155 var test = """
156 > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
157 > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
158 > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
159 >
160 > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
161 > id sem consectetuer libero luctus adipiscing.
162 """
163 var exp = """<blockquote>
164 <p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
165 consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
166 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
167 <p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
168 id sem consectetuer libero luctus adipiscing.</p>
169 </blockquote>
170 """
171 var res = test.md_to_html.write_to_string
172 assert res == exp
173 end
174
175 fun test_process_bquote2 do
176 var test = """
177 > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
178 consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
179 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
180
181 > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
182 id sem consectetuer libero luctus adipiscing.
183 """
184 var exp = """<blockquote>
185 <p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
186 consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
187 Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
188 <p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
189 id sem consectetuer libero luctus adipiscing.</p>
190 </blockquote>
191 """
192 var res = test.md_to_html.write_to_string
193 assert res == exp
194 end
195
196 fun test_process_bquote3 do
197 var test = """
198 > This is the first level of quoting.
199 >
200 > > This is nested blockquote.
201 >
202 > Back to the first level.
203 """
204 var exp = """<blockquote>
205 <p>This is the first level of quoting.</p>
206 <blockquote>
207 <p>This is nested blockquote.</p>
208 </blockquote>
209 <p>Back to the first level.</p>
210 </blockquote>
211 """
212 var res = test.md_to_html.write_to_string
213 assert res == exp
214 end
215
216 fun test_process_list1 do
217 var test = """
218 * Red
219 * Green
220 * Blue
221 """
222 var exp = """<ul>
223 <li>Red</li>
224 <li>Green</li>
225 <li>Blue</li>
226 </ul>
227 """
228 var res = test.md_to_html.write_to_string
229 assert res == exp
230 end
231
232 fun test_process_list2 do
233 var test = """
234 + Red
235 + Green
236 + Blue
237 """
238 var exp = """<ul>
239 <li>Red</li>
240 <li>Green</li>
241 <li>Blue</li>
242 </ul>
243 """
244 var res = test.md_to_html.write_to_string
245 assert res == exp
246 end
247
248 fun test_process_list3 do
249 var test = """
250 - Red
251 - Green
252 - Blue
253 """
254 var exp = """<ul>
255 <li>Red</li>
256 <li>Green</li>
257 <li>Blue</li>
258 </ul>
259 """
260 var res = test.md_to_html.write_to_string
261 assert res == exp
262 end
263
264 fun test_process_list4 do
265 var test = """
266 1. Bird
267 2. McHale
268 3. Parish
269 """
270 var exp = """<ol>
271 <li>Bird</li>
272 <li>McHale</li>
273 <li>Parish</li>
274 </ol>
275 """
276 var res = test.md_to_html.write_to_string
277 assert res == exp
278 end
279
280 fun test_process_list5 do
281 var test = """
282 3. Bird
283 1. McHale
284 8. Parish
285 """
286 var exp = """<ol>
287 <li>Bird</li>
288 <li>McHale</li>
289 <li>Parish</li>
290 </ol>
291 """
292 var res = test.md_to_html.write_to_string
293 assert res == exp
294 end
295
296 fun test_process_list6 do
297 var test = """
298 * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
299 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
300 viverra nec, fringilla in, laoreet vitae, risus.
301 * Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
302 Suspendisse id sem consectetuer libero luctus adipiscing.
303 """
304 var exp = """
305 <ul>
306 <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
307 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
308 viverra nec, fringilla in, laoreet vitae, risus.</li>
309 <li>Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
310 Suspendisse id sem consectetuer libero luctus adipiscing.</li>
311 </ul>
312 """
313 var res = test.md_to_html.write_to_string
314 assert res == exp
315 end
316
317 fun test_process_list7 do
318 var test = """
319 * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
320 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
321 viverra nec, fringilla in, laoreet vitae, risus.
322 * Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
323 Suspendisse id sem consectetuer libero luctus adipiscing.
324 """
325 var exp = """
326 <ul>
327 <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
328 Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
329 viverra nec, fringilla in, laoreet vitae, risus.</li>
330 <li>Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
331 Suspendisse id sem consectetuer libero luctus adipiscing.</li>
332 </ul>
333 """
334 var res = test.md_to_html.write_to_string
335 assert res == exp
336 end
337
338 fun test_process_list8 do
339 var test = """
340 * Bird
341
342 * Magic
343 """
344 var exp = """
345 <ul>
346 <li><p>Bird</p>
347 </li>
348 <li><p>Magic</p>
349 </li>
350 </ul>
351 """
352 var res = test.md_to_html.write_to_string
353 assert res == exp
354 end
355
356 fun test_process_list9 do
357 var test = """
358 1. This is a list item with two paragraphs. Lorem ipsum dolor
359 sit amet, consectetuer adipiscing elit. Aliquam hendrerit
360 mi posuere lectus.
361
362 Vestibulum enim wisi, viverra nec, fringilla in, laoreet
363 vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
364 sit amet velit.
365
366 2. Suspendisse id sem consectetuer libero luctus adipiscing.
367 """
368 var exp = """
369 <ol>
370 <li><p>This is a list item with two paragraphs. Lorem ipsum dolor
371 sit amet, consectetuer adipiscing elit. Aliquam hendrerit
372 mi posuere lectus.</p>
373 <p>Vestibulum enim wisi, viverra nec, fringilla in, laoreet
374 vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
375 sit amet velit.</p>
376 </li>
377 <li><p>Suspendisse id sem consectetuer libero luctus adipiscing.</p>
378 </li>
379 </ol>
380 """
381 var res = test.md_to_html.write_to_string
382 assert res == exp
383 end
384
385 fun test_process_list10 do
386 var test = """
387 * This is a list item with two paragraphs.
388
389 This is the second paragraph in the list item. You're
390 only required to indent the first line. Lorem ipsum dolor
391 sit amet, consectetuer adipiscing elit.
392
393 * Another item in the same list.
394 """
395 var exp = """
396 <ul>
397 <li><p>This is a list item with two paragraphs.</p>
398 <p>This is the second paragraph in the list item. You're
399 only required to indent the first line. Lorem ipsum dolor
400 sit amet, consectetuer adipiscing elit.</p>
401 </li>
402 <li><p>Another item in the same list.</p>
403 </li>
404 </ul>
405 """
406 var res = test.md_to_html.write_to_string
407 assert res == exp
408 end
409
410 fun test_process_list11 do
411 var test = """
412 This is a paragraph
413 * and this is not a list
414 """
415 var exp = """
416 <p>This is a paragraph
417 * and this is not a list</p>
418 """
419 var proc = new MarkdownProcessor
420 proc.ext_mode = false
421 var res = proc.process(test).write_to_string
422 assert res == exp
423 end
424
425 fun test_process_list_ext do
426 var test = """
427 This is a paragraph
428 * and this is not a list
429 """
430 var exp = """
431 <p>This is a paragraph</p>
432 <ul>
433 <li>and this is not a list</li>
434 </ul>
435 """
436 var res = test.md_to_html.write_to_string
437 assert res == exp
438 end
439
440 fun test_process_code1 do
441 var test = """
442 This is a normal paragraph:
443
444 This is a code block.
445 """
446 var exp = """<p>This is a normal paragraph:</p>
447 <pre><code>This is a code block.
448 </code></pre>
449 """
450 var res = test.md_to_html.write_to_string
451 assert res == exp
452 end
453
454 fun test_process_code2 do
455 var test = """
456 Here is an example of AppleScript:
457
458 tell application "Foo"
459 beep
460 end tell
461
462 <div class="footer">
463 &copy; 2004 Foo Corporation
464 </div>
465 """
466 var exp = """
467 <p>Here is an example of AppleScript:</p>
468 <pre><code>tell application "Foo"
469 beep
470 end tell
471
472 &lt;div class="footer"&gt;
473 &amp;copy; 2004 Foo Corporation
474 &lt;/div&gt;
475 </code></pre>
476 """
477 var res = test.md_to_html.write_to_string
478 assert res == exp
479 end
480
481 fun test_process_code_ext1 do
482 var test = """
483 Here is an example of AppleScript:
484 ~~~
485 tell application "Foo"
486 beep
487 end tell
488
489 <div class="footer">
490 &copy; 2004 Foo Corporation
491 </div>
492 ~~~
493 """
494 var exp = """
495 <p>Here is an example of AppleScript:</p>
496 <pre><code>tell application "Foo"
497 beep
498 end tell
499
500 &lt;div class="footer"&gt;
501 &amp;copy; 2004 Foo Corporation
502 &lt;/div&gt;
503 </code></pre>
504 """
505 var res = test.md_to_html.write_to_string
506 assert res == exp
507 end
508
509 fun test_process_code_ext2 do
510 var test = """
511 Here is an example of AppleScript:
512 ```
513 tell application "Foo"
514 beep
515 end tell
516
517 <div class="footer">
518 &copy; 2004 Foo Corporation
519 </div>
520 ```
521 """
522 var exp = """
523 <p>Here is an example of AppleScript:</p>
524 <pre><code>tell application "Foo"
525 beep
526 end tell
527
528 &lt;div class="footer"&gt;
529 &amp;copy; 2004 Foo Corporation
530 &lt;/div&gt;
531 </code></pre>
532 """
533 var res = test.md_to_html.write_to_string
534 assert res == exp
535 end
536
537 fun test_process_code_ext3 do
538 var proc = new MarkdownProcessor
539 proc.ext_mode = false
540
541 var test = """
542 Here is an example of AppleScript:
543 beep
544 """
545 var exp = """
546 <p>Here is an example of AppleScript:
547 beep</p>
548 """
549 var res = proc.process(test).write_to_string
550 assert res == exp
551 end
552
553 fun test_process_code_ext4 do
554 var test = """
555 Here is an example of AppleScript:
556 beep
557 """
558 var exp = """
559 <p>Here is an example of AppleScript:</p>
560 <pre><code>beep
561 </code></pre>
562 """
563 var res = test.md_to_html.write_to_string
564 assert res == exp
565 end
566
567 fun test_process_code_ext5 do
568 var test = """
569 ```nit
570 print "Hello World!"
571 ```
572 """
573 var exp = """
574 <pre class="nit"><code>print "Hello World!"
575 </code></pre>
576 """
577 var res = test.md_to_html.write_to_string
578 assert res == exp
579 end
580
581 fun test_process_nesting1 do
582 var test = """
583 > ## This is a header.
584 >
585 > 1. This is the first list item.
586 > 2. This is the second list item.
587 >
588 > Here's some example code:
589 >
590 > return shell_exec("echo $input | $markdown_script");
591 """
592 var exp = """
593 <blockquote>
594 <h2 id="This_is_a_header.">This is a header.</h2>
595 <ol>
596 <li>This is the first list item.</li>
597 <li>This is the second list item.</li>
598 </ol>
599 <p>Here's some example code:</p>
600 <pre><code>return shell_exec("echo $input | $markdown_script");
601 </code></pre>
602 </blockquote>
603 """
604 var res = test.md_to_html.write_to_string
605 assert res == exp
606 end
607
608 fun test_process_nesting2 do
609 var test = """
610 * A list item with a blockquote:
611
612 > This is a blockquote
613 > inside a list item.
614 """
615 var exp = """
616 <ul>
617 <li><p>A list item with a blockquote:</p>
618 <blockquote>
619 <p>This is a blockquote
620 inside a list item.</p>
621 </blockquote>
622 </li>
623 </ul>
624 """
625 var res = test.md_to_html.write_to_string
626 assert res == exp
627 end
628
629 fun test_process_nesting3 do
630 var test = """
631 * A list item with a code block:
632
633 <code goes here>
634 """
635 var exp = """
636 <ul>
637 <li><p>A list item with a code block:</p>
638 <pre><code>&lt;code goes here&gt;
639 </code></pre>
640 </li>
641 </ul>
642 """
643 var res = test.md_to_html.write_to_string
644 assert res == exp
645 end
646
647 fun test_process_nesting4 do
648 var test = """
649 * Tab
650 * Tab
651 * Tab
652 """
653 var exp = """
654 <ul>
655 <li>Tab<ul>
656 <li>Tab<ul>
657 <li>Tab</li>
658 </ul>
659 </li>
660 </ul>
661 </li>
662 </ul>
663 """
664 var res = test.md_to_html.write_to_string
665 assert res == exp
666 end
667
668 # TODO
669 # fun test_process_nesting5 do
670 # var test = """
671 # * this
672 #
673 # * sub
674 #
675 # that
676 # """
677 # var exp = """
678 # <ul>
679 # <li><p>this</p>
680 # <ul>
681 # <li>sub</li>
682 # </ul>
683 # <p>that</p>
684 # </li>
685 # </ul>
686 # """
687 # var res = test.md_to_html.write_to_string
688 # assert res == exp
689 # end
690
691 fun test_process_emph1 do
692 var test = """
693 *single asterisks*
694
695 _single underscores_
696
697 **double asterisks**
698
699 __double underscores__
700 """
701 var exp = """<p><em>single asterisks</em></p>
702 <p><em>single underscores</em></p>
703 <p><strong>double asterisks</strong></p>
704 <p><strong>double underscores</strong></p>
705 """
706 var res = test.md_to_html.write_to_string
707 assert res == exp
708 end
709
710 fun test_process_emph2 do
711 var test = "un*frigging*believable"
712 var exp = "<p>un<em>frigging</em>believable</p>\n"
713 var res = test.md_to_html.write_to_string
714 assert res == exp
715 end
716
717 fun test_process_emph3 do
718 var proc = new MarkdownProcessor
719 proc.ext_mode = false
720 var test = "Con_cat_this"
721 var exp = "<p>Con<em>cat</em>this</p>\n"
722 var res = proc.process(test).write_to_string
723 assert res == exp
724 end
725
726 fun test_process_emph_ext do
727 var test = "Con_cat_this"
728 var exp = "<p>Con_cat_this</p>\n"
729 var res = test.md_to_html.write_to_string
730 assert res == exp
731 end
732
733 fun test_process_xml1 do
734 var test = """
735 This is a regular paragraph.
736
737 <table>
738 <tr>
739 <td>Foo</td>
740 </tr>
741 </table>
742
743 This is another regular paragraph.
744 """
745 var exp = """
746 <p>This is a regular paragraph.</p>
747 <table>
748 <tr>
749 <td>Foo</td>
750 </tr>
751 </table>
752 <p>This is another regular paragraph.</p>
753 """
754 var res = test.md_to_html.write_to_string
755 assert res == exp
756 end
757
758 fun test_process_xml2 do
759 var test = """
760 This is an image <img src="foo/bar" alt="baz"/> in a regular paragraph.
761 """
762 var exp = """<p>This is an image <img src="foo/bar" alt="baz" /> in a regular paragraph.</p>
763 """
764 var res = test.md_to_html.write_to_string
765 assert res == exp
766 end
767
768 fun test_process_xml3 do
769 var test = """
770 <div style=">"/>
771 """
772 var exp = """
773 <div style=">"/>
774 """
775 var res = test.md_to_html.write_to_string
776 assert res == exp
777 end
778
779 fun test_process_span_code1 do
780 var test = "Use the `printf()` function."
781 var exp = "<p>Use the <code>printf()</code> function.</p>\n"
782 var res = test.md_to_html.write_to_string
783 assert res == exp
784 end
785
786 fun test_process_span_code2 do
787 var test = "``There is a literal backtick (`) here.``"
788 var exp = "<p><code>There is a literal backtick (`) here.</code></p>\n"
789 var res = test.md_to_html.write_to_string
790 assert res == exp
791 end
792
793 fun test_process_span_code3 do
794 var test = """
795 A single backtick in a code span: `` ` ``
796
797 A backtick-delimited string in a code span: `` `foo` ``
798 """
799 var exp = """
800 <p>A single backtick in a code span: <code>`</code></p>
801 <p>A backtick-delimited string in a code span: <code>`foo`</code></p>
802 """
803 var res = test.md_to_html.write_to_string
804 assert res == exp
805 end
806
807 fun test_process_span_code4 do
808 var test = "Please don't use any `<blink>` tags."
809 var exp = "<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>\n"
810 var res = test.md_to_html.write_to_string
811 assert res == exp
812 end
813
814 fun test_process_span_code5 do
815 var test = "`&#8212;` is the decimal-encoded equivalent of `&mdash;`."
816 var exp = "<p><code>&amp;#8212;</code> is the decimal-encoded equivalent of <code>&amp;mdash;</code>.</p>\n"
817 var res = test.md_to_html.write_to_string
818 assert res == exp
819 end
820
821 fun test_process_escape1 do
822 var test = "\\*this text is surrounded by literal asterisks\\*"
823 var exp = "<p>*this text is surrounded by literal asterisks*</p>\n"
824 var res = test.md_to_html.write_to_string
825 assert res == exp
826 end
827
828 fun test_process_escape2 do
829 var test = "1986\\. What a great season."
830 var exp = "<p>1986. What a great season.</p>\n"
831 var res = test.md_to_html.write_to_string
832 assert res == exp
833 end
834
835 fun test_process_escape3 do
836 var test = "Ben & Lux"
837 var exp = "<p>Ben &amp; Lux</p>\n"
838 var res = test.md_to_html.write_to_string
839 assert res == exp
840 end
841
842 fun test_process_link1 do
843 var test = """
844 This is [an example](http://example.com/ "Title") inline link.
845
846 [This link](http://example.net/) has no title attribute.
847 """
848 var exp = """<p>This is <a href="http://example.com/" title="Title">an example</a> inline link.</p>
849 <p><a href="http://example.net/">This link</a> has no title attribute.</p>
850 """
851 var res = test.md_to_html.write_to_string
852 assert res == exp
853 end
854
855 fun test_process_link2 do
856 var test = "See my [About](/about/) page for details."
857 var exp = "<p>See my <a href=\"/about/\">About</a> page for details.</p>\n"
858 var res = test.md_to_html.write_to_string
859 assert res == exp
860 end
861
862 fun test_process_link3 do
863 var test = """
864 This is [an example][id] reference-style link.
865
866 This is [an example] [id] reference-style link.
867
868 Some lorem ipsum
869
870 [id]: http://example.com/ "Optional Title Here"
871
872 Some other lipsum
873 """
874 var exp = """
875 <p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
876 <p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
877 <p>Some lorem ipsum</p>
878 <p>Some other lipsum</p>
879 """
880 var res = test.md_to_html.write_to_string
881 assert res == exp
882 end
883
884 fun test_process_link4 do
885 var test = """
886 This is multiple examples: [foo][1], [bar][2], [baz][3].
887
888 [1]: http://example.com/ "Optional Title Here"
889 [2]: http://example.com/ 'Optional Title Here'
890 [3]: http://example.com/ (Optional Title Here)
891 """
892 var exp = """
893 <p>This is multiple examples: <a href="http://example.com/" title="Optional Title Here">foo</a>, <a href="http://example.com/" title="Optional Title Here">bar</a>, <a href="http://example.com/" title="Optional Title Here">baz</a>.</p>
894 """
895 var res = test.md_to_html.write_to_string
896 assert res == exp
897 end
898
899 fun test_process_link5 do
900 var test = """
901 This is multiple examples: [foo][a], [bar][A], [a].
902
903 [a]: http://example.com/ "Optional Title Here"
904 """
905 var exp = """<p>This is multiple examples: <a href="http://example.com/" title="Optional Title Here">foo</a>, <a href="http://example.com/" title="Optional Title Here">bar</a>, <a href="http://example.com/" title="Optional Title Here">a</a>.</p>
906 """
907 var res = test.md_to_html.write_to_string
908 assert res == exp
909 end
910
911 fun test_process_link6 do
912 var test = """
913 I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][].
914
915 [Google]: http://google.com/ "Google"
916 [Yahoo]: http://search.yahoo.com/ "Yahoo Search"
917 [MSN]: http://search.msn.com/ "MSN Search"
918 """
919 var exp = """<p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
920 """
921 var res = test.md_to_html.write_to_string
922 assert res == exp
923 end
924
925 fun test_process_link7 do
926 var test = """
927 Visit [Daring Fireball][] for more information.
928
929 [Daring Fireball]: http://daringfireball.net/
930 """
931 var exp = """<p>Visit <a href="http://daringfireball.net/">Daring Fireball</a> for more information.</p>
932 """
933 var res = test.md_to_html.write_to_string
934 assert res == exp
935 end
936
937 fun test_process_link8 do
938 var test = """
939 This one has a [line
940 break].
941
942 This one has a [line
943 break] with a line-ending space.
944
945 [line break]: /foo
946 """
947 var exp = """
948 <p>This one has a <a href="/foo">line
949 break</a>.</p>
950 <p>This one has a <a href="/foo">line
951 break</a> with a line-ending space.</p>
952 """
953 var res = test.md_to_html.write_to_string
954 assert res == exp
955 end
956
957 # FIXME unignore test once escape strings fixed
958 # fun test_process_link9 do
959 # var test = """
960 # Foo [bar][].
961 #
962 # Foo [bar](/url/ "Title with \"quotes\" inside").
963 #
964 #
965 # [bar]: /url/ "Title with \"quotes\" inside"
966 # """
967 # var exp = """
968 # <p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
969 # <p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
970 # """
971 # var res = test.md_to_html.write_to_string
972 # assert res == exp
973 # end
974
975 fun test_process_img1 do
976 var test = """
977 ![Alt text](/path/to/img.jpg)
978
979 ![Alt text](/path/to/img.jpg "Optional title")
980 """
981 var exp = """<p><img src="/path/to/img.jpg" alt="Alt text"/></p>
982 <p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title"/></p>
983 """
984 var res = test.md_to_html.write_to_string
985 assert res == exp
986 end
987
988 fun test_process_img2 do
989 var test = """
990 ![Alt text][id]
991
992 [id]: url/to/image "Optional title attribute"
993 """
994 var exp = """<p><img src="url/to/image" alt="Alt text" title="Optional title attribute"/></p>
995 """
996 var res = test.md_to_html.write_to_string
997 assert res == exp
998 end
999
1000 fun test_process_strike do
1001 var proc = new MarkdownProcessor
1002 proc.ext_mode = false
1003 var test = "This is how you ~~strike text~~"
1004 var exp = "<p>This is how you ~~strike text~~</p>\n"
1005 var res = proc.process(test).write_to_string
1006 assert exp == res
1007 end
1008
1009 fun test_process_strike_ext do
1010 var test = "This is how you ~~strike text~~"
1011 var exp = "<p>This is how you <del>strike text</del></p>\n"
1012 var res = test.md_to_html.write_to_string
1013 assert exp == res
1014 end
1015
1016 fun test_escape_bad_html do
1017 var test = "-1 if < , +1 if > and 0 otherwise"
1018 var exp = "<p>-1 if &lt; , +1 if > and 0 otherwise</p>\n"
1019 var res = test.md_to_html.write_to_string
1020 assert exp == res
1021 end
1022
1023 fun test_daring_encoding do
1024 var test = """
1025 AT&T has an ampersand in their name.
1026
1027 AT&amp;T is another way to write it.
1028
1029 This & that.
1030
1031 4 < 5.
1032
1033 6 > 5.
1034
1035 Here's a [link] [1] with an ampersand in the URL.
1036
1037 Here's a link with an amersand in the link text: [AT&T] [2].
1038
1039 Here's an inline [link](/script?foo=1&bar=2).
1040
1041 Here's an inline [link](</script?foo=1&bar=2>).
1042
1043
1044 [1]: http://example.com/?foo=1&bar=2
1045 [2]: http://att.com/ "AT&T"
1046 """
1047
1048 var exp = """
1049 <p>AT&amp;T has an ampersand in their name.</p>
1050 <p>AT&amp;T is another way to write it.</p>
1051 <p>This &amp; that.</p>
1052 <p>4 &lt; 5.</p>
1053 <p>6 > 5.</p>
1054 <p>Here's a <a href="http://example.com/?foo=1&amp;bar=2">link</a> with an ampersand in the URL.</p>
1055 <p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&amp;T">AT&amp;T</a>.</p>
1056 <p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
1057 <p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
1058 """
1059 var res = test.md_to_html.write_to_string
1060 assert res == exp
1061
1062 end
1063
1064 fun test_daring_autolinks do
1065 var test = """
1066 Link: <http://example.com/>.
1067
1068 With an ampersand: <http://example.com/?foo=1&bar=2>
1069
1070 * In a list?
1071 * <http://example.com/>
1072 * It should.
1073
1074 > Blockquoted: <http://example.com/>
1075
1076 Auto-links should not occur here: `<http://example.com/>`
1077
1078 or here: <http://example.com/>
1079 """
1080
1081 var exp = """
1082 <p>Link: <a href="http://example.com/">http://example.com/</a>.</p>
1083 <p>With an ampersand: <a href="http://example.com/?foo=1&amp;bar=2">http://example.com/?foo=1&amp;bar=2</a></p>
1084 <ul>
1085 <li>In a list?</li>
1086 <li><a href="http://example.com/">http://example.com/</a></li>
1087 <li>It should.</li>
1088 </ul>
1089 <blockquote>
1090 <p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>
1091 </blockquote>
1092 <p>Auto-links should not occur here: <code>&lt;http://example.com/&gt;</code></p>
1093 <pre><code>or here: &lt;http://example.com/&gt;
1094 </code></pre>
1095 """
1096 var res = test.md_to_html.write_to_string
1097 assert res == exp
1098 end
1099
1100 fun test_daring_escape do
1101 var test = """
1102 These should all get escaped:
1103
1104 Backslash: \\
1105
1106 Backtick: \`
1107
1108 Asterisk: \*
1109
1110 Underscore: \_
1111
1112 Left brace: \{
1113
1114 Right brace: \}
1115
1116 Left bracket: \[
1117
1118 Right bracket: \]
1119
1120 Left paren: \(
1121
1122 Right paren: \)
1123
1124 Greater-than: \>
1125
1126 Hash: \#
1127
1128 Period: \.
1129
1130 Bang: \!
1131
1132 Plus: \+
1133
1134 Minus: \-
1135
1136
1137 These should not, because they occur within a code block:
1138
1139 Backslash: \\
1140
1141 Backtick: \`
1142
1143 Asterisk: \*
1144
1145 Underscore: \_
1146
1147 Left brace: \{
1148
1149 Right brace: \}
1150
1151 Left bracket: \[
1152
1153 Right bracket: \]
1154
1155 Left paren: \(
1156
1157 Right paren: \)
1158
1159 Greater-than: \>
1160
1161 Hash: \#
1162
1163 Period: \.
1164
1165 Bang: \!
1166
1167 Plus: \+
1168
1169 Minus: \-
1170
1171 Nor should these, which occur in code spans:
1172
1173 Backslash: `\\`
1174
1175 Backtick: `` \` ``
1176
1177 Asterisk: `\*`
1178
1179 Underscore: `\_`
1180
1181 Left brace: `\{`
1182
1183 Right brace: `\}`
1184
1185 Left bracket: `\[`
1186
1187 Right bracket: `\]`
1188
1189 Left paren: `\(`
1190
1191 Right paren: `\)`
1192
1193 Greater-than: `\>`
1194
1195 Hash: `\#`
1196
1197 Period: `\.`
1198
1199 Bang: `\!`
1200
1201 Plus: `\+`
1202
1203 Minus: `\-`
1204
1205 These should get escaped, even though they're matching pairs for
1206 other Markdown constructs:
1207
1208 \\\*asterisks\\\*
1209
1210 \\\_underscores\\\_
1211
1212 \\\`backticks\\\`
1213
1214 This is a code span with a literal backslash-backtick sequence: `` \` ``
1215
1216 This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.
1217
1218 This is a tag with backslashes <span attr='\\\\backslashes\\\\'>bar</span>.
1219 """
1220 var exp = """
1221 <p>These should all get escaped:</p>
1222 <p>Backslash: \\</p>
1223 <p>Backtick: \`</p>
1224 <p>Asterisk: \*</p>
1225 <p>Underscore: \_</p>
1226 <p>Left brace: \{</p>
1227 <p>Right brace: \}</p>
1228 <p>Left bracket: \[</p>
1229 <p>Right bracket: \]</p>
1230 <p>Left paren: \(</p>
1231 <p>Right paren: \)</p>
1232 <p>Greater-than: \></p>
1233 <p>Hash: \#</p>
1234 <p>Period: \.</p>
1235 <p>Bang: \!</p>
1236 <p>Plus: \+</p>
1237 <p>Minus: \-</p>
1238 <p>These should not, because they occur within a code block:</p>
1239 <pre><code>Backslash: \\
1240
1241 Backtick: \`
1242
1243 Asterisk: \*
1244
1245 Underscore: \_
1246
1247 Left brace: \{
1248
1249 Right brace: \}
1250
1251 Left bracket: \[
1252
1253 Right bracket: \]
1254
1255 Left paren: \(
1256
1257 Right paren: \)
1258
1259 Greater-than: \&gt;
1260
1261 Hash: \#
1262
1263 Period: \.
1264
1265 Bang: \!
1266
1267 Plus: \+
1268
1269 Minus: \-
1270 </code></pre>
1271 <p>Nor should these, which occur in code spans:</p>
1272 <p>Backslash: <code>\\</code></p>
1273 <p>Backtick: <code>\`</code></p>
1274 <p>Asterisk: <code>\*</code></p>
1275 <p>Underscore: <code>\_</code></p>
1276 <p>Left brace: <code>\{</code></p>
1277 <p>Right brace: <code>\}</code></p>
1278 <p>Left bracket: <code>\[</code></p>
1279 <p>Right bracket: <code>\]</code></p>
1280 <p>Left paren: <code>\(</code></p>
1281 <p>Right paren: <code>\)</code></p>
1282 <p>Greater-than: <code>\&gt;</code></p>
1283 <p>Hash: <code>\#</code></p>
1284 <p>Period: <code>\.</code></p>
1285 <p>Bang: <code>\!</code></p>
1286 <p>Plus: <code>\+</code></p>
1287 <p>Minus: <code>\-</code></p>
1288 <p>These should get escaped, even though they're matching pairs for
1289 other Markdown constructs:</p>
1290 <p>*asterisks*</p>
1291 <p>_underscores_</p>
1292 <p>`backticks`</p>
1293 <p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p>
1294 <p>This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.</p>
1295 <p>This is a tag with backslashes <span attr='\\\\backslashes\\\\'>bar</span>.</p>
1296 """
1297
1298 var res = test.md_to_html.write_to_string
1299 assert res == exp
1300 end
1301
1302 fun test_daring_blockquotes do
1303 var test = """
1304 > Example:
1305 >
1306 > sub status {
1307 > print "working";
1308 > }
1309 >
1310 > Or:
1311 >
1312 > sub status {
1313 > return "working";
1314 > }
1315 """
1316
1317 var exp = """
1318 <blockquote>
1319 <p>Example:</p>
1320 <pre><code>sub status {
1321 print "working";
1322 }
1323 </code></pre>
1324 <p>Or:</p>
1325 <pre><code>sub status {
1326 return "working";
1327 }
1328 </code></pre>
1329 </blockquote>
1330 """
1331 var res = test.md_to_html.write_to_string
1332 assert res == exp
1333 end
1334
1335 fun test_daring_code_blocks do
1336 var test = """
1337 code block on the first line
1338
1339 Regular text.
1340
1341 code block indented by spaces
1342
1343 Regular text.
1344
1345 the lines in this block
1346 all contain trailing spaces
1347
1348 Regular Text.
1349
1350 code block on the last line
1351 """
1352
1353 var exp = """
1354 <pre><code>code block on the first line
1355 </code></pre>
1356 <p>Regular text.</p>
1357 <pre><code>code block indented by spaces
1358 </code></pre>
1359 <p>Regular text.</p>
1360 <pre><code>the lines in this block
1361 all contain trailing spaces
1362 </code></pre>
1363 <p>Regular Text.</p>
1364 <pre><code>code block on the last line
1365 </code></pre>
1366 """
1367 var res = test.md_to_html.write_to_string
1368 assert res == exp
1369 end
1370
1371 fun test_daring_code_spans do
1372 var test = """
1373 `<test a="` content of attribute `">`
1374
1375 Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>
1376
1377 Here's how you put `` `backticks` `` in a code span.
1378 """
1379
1380 var exp = """
1381 <p><code>&lt;test a="</code> content of attribute <code>"&gt;</code></p>
1382 <p>Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span></p>
1383 <p>Here's how you put <code>`backticks`</code> in a code span.</p>
1384 """
1385 var res = test.md_to_html.write_to_string
1386 assert res == exp
1387 end
1388
1389 fun test_daring_pars do
1390 var proc = new MarkdownProcessor
1391 proc.ext_mode = false
1392
1393 var test = """
1394 In Markdown 1.0.0 and earlier. Version
1395 8. This line turns into a list item.
1396 Because a hard-wrapped line in the
1397 middle of a paragraph looked like a
1398 list item.
1399
1400 Here's one with a bullet.
1401 * criminey.
1402 """
1403
1404 var exp = """
1405 <p>In Markdown 1.0.0 and earlier. Version
1406 8. This line turns into a list item.
1407 Because a hard-wrapped line in the
1408 middle of a paragraph looked like a
1409 list item.</p>
1410 <p>Here's one with a bullet.
1411 * criminey.</p>
1412 """
1413 var res = proc.process(test).write_to_string
1414 assert res == exp
1415 end
1416
1417 fun test_daring_rules do
1418 var test = """
1419 Dashes:
1420
1421 ---
1422
1423 ---
1424
1425 ---
1426
1427 ---
1428
1429 ---
1430
1431 - - -
1432
1433 - - -
1434
1435 - - -
1436
1437 - - -
1438
1439 - - -
1440
1441
1442 Asterisks:
1443
1444 ***
1445
1446 ***
1447
1448 ***
1449
1450 ***
1451
1452 ***
1453
1454 * * *
1455
1456 * * *
1457
1458 * * *
1459
1460 * * *
1461
1462 * * *
1463
1464
1465 Underscores:
1466
1467 ___
1468
1469 ___
1470
1471 ___
1472
1473 ___
1474
1475 ___
1476
1477 _ _ _
1478
1479 _ _ _
1480
1481 _ _ _
1482
1483 _ _ _
1484
1485 _ _ _
1486 """
1487
1488 var exp = """
1489 <p>Dashes:</p>
1490 <hr/>
1491 <hr/>
1492 <hr/>
1493 <hr/>
1494 <pre><code>---
1495 </code></pre>
1496 <hr/>
1497 <hr/>
1498 <hr/>
1499 <hr/>
1500 <pre><code>- - -
1501 </code></pre>
1502 <p>Asterisks:</p>
1503 <hr/>
1504 <hr/>
1505 <hr/>
1506 <hr/>
1507 <pre><code>***
1508 </code></pre>
1509 <hr/>
1510 <hr/>
1511 <hr/>
1512 <hr/>
1513 <pre><code>* * *
1514 </code></pre>
1515 <p>Underscores:</p>
1516 <hr/>
1517 <hr/>
1518 <hr/>
1519 <hr/>
1520 <pre><code>___
1521 </code></pre>
1522 <hr/>
1523 <hr/>
1524 <hr/>
1525 <hr/>
1526 <pre><code>_ _ _
1527 </code></pre>
1528 """
1529 var res = test.md_to_html.write_to_string
1530 assert res == exp
1531 end
1532
1533 fun test_daring_images do
1534 var test = """
1535 ![Alt text](/path/to/img.jpg)
1536
1537 ![Alt text](/path/to/img.jpg "Optional title")
1538
1539 Inline within a paragraph: [alt text](/url/).
1540
1541 ![alt text](/url/ "title preceded by two spaces")
1542
1543 ![alt text](/url/ "title has spaces afterward" )
1544
1545 ![alt text](</url/>)
1546
1547 ![alt text](</url/> "with a title").
1548
1549 ![Empty]()
1550
1551 ![this is a stupid URL](http://example.com/(parens).jpg)
1552
1553
1554 ![alt text][foo]
1555
1556 [foo]: /url/
1557
1558 ![alt text][bar]
1559
1560 [bar]: /url/ "Title here"
1561 """
1562
1563 var exp = """
1564 <p><img src="/path/to/img.jpg" alt="Alt text"/></p>
1565 <p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title"/></p>
1566 <p>Inline within a paragraph: <a href="/url/">alt text</a>.</p>
1567 <p><img src="/url/" alt="alt text" title="title preceded by two spaces"/></p>
1568 <p><img src="/url/" alt="alt text" title="title has spaces afterward"/></p>
1569 <p><img src="/url/" alt="alt text"/></p>
1570 <p><img src="/url/" alt="alt text" title="with a title"/>.</p>
1571 <p><img src="" alt="Empty"/></p>
1572 <p><img src="http://example.com/(parens).jpg" alt="this is a stupid URL"/></p>
1573 <p><img src="/url/" alt="alt text"/></p>
1574 <p><img src="/url/" alt="alt text" title="Title here"/></p>
1575 """
1576 var res = test.md_to_html.write_to_string
1577 assert res == exp
1578 end
1579
1580 fun test_daring_inline_html1 do
1581 var test = """
1582 Here's a simple block:
1583
1584 <div>
1585 foo
1586 </div>
1587
1588 This should be a code block, though:
1589
1590 <div>
1591 foo
1592 </div>
1593
1594 As should this:
1595
1596 <div>foo</div>
1597
1598 Now, nested:
1599
1600 <div>
1601 <div>
1602 <div>
1603 foo
1604 </div>
1605 </div>
1606 </div>
1607
1608 This should just be an HTML comment:
1609
1610 <!-- Comment -->
1611
1612 Multiline:
1613
1614 <!--
1615 Blah
1616 Blah
1617 -->
1618
1619 Code block:
1620
1621 <!-- Comment -->
1622
1623 Just plain comment, with trailing spaces on the line:
1624
1625 <!-- foo -->
1626
1627 Code:
1628
1629 <hr />
1630
1631 Hr's:
1632
1633 <hr>
1634
1635 <hr/>
1636
1637 <hr />
1638
1639 <hr>
1640
1641 <hr/>
1642
1643 <hr />
1644
1645 <hr class="foo" id="bar" />
1646
1647 <hr class="foo" id="bar"/>
1648
1649 <hr class="foo" id="bar" >
1650 """
1651
1652 var exp = """
1653 <p>Here's a simple block:</p>
1654 <div>
1655 foo
1656 </div>
1657 <p>This should be a code block, though:</p>
1658 <pre><code>&lt;div&gt;
1659 foo
1660 &lt;/div&gt;
1661 </code></pre>
1662 <p>As should this:</p>
1663 <pre><code>&lt;div&gt;foo&lt;/div&gt;
1664 </code></pre>
1665 <p>Now, nested:</p>
1666 <div>
1667 <div>
1668 <div>
1669 foo
1670 </div>
1671 </div>
1672 </div>
1673 <p>This should just be an HTML comment:</p>
1674 <!-- Comment -->
1675 <p>Multiline:</p>
1676 <!--
1677 Blah
1678 Blah
1679 -->
1680 <p>Code block:</p>
1681 <pre><code>&lt;!-- Comment --&gt;
1682 </code></pre>
1683 <p>Just plain comment, with trailing spaces on the line:</p>
1684 <!-- foo -->
1685 <p>Code:</p>
1686 <pre><code>&lt;hr /&gt;
1687 </code></pre>
1688 <p>Hr's:</p>
1689 <hr>
1690 <hr/>
1691 <hr />
1692 <hr>
1693 <hr/>
1694 <hr />
1695 <hr class="foo" id="bar" />
1696 <hr class="foo" id="bar"/>
1697 <hr class="foo" id="bar" >
1698 """
1699 var res = test.md_to_html.write_to_string
1700 assert res == exp
1701 end
1702
1703 fun test_daring_inline_html2 do
1704 var test = """
1705 Simple block on one line:
1706
1707 <div>foo</div>
1708
1709 And nested without indentation:
1710
1711 <div>
1712 <div>
1713 <div>
1714 foo
1715 </div>
1716 <div style=">"/>
1717 </div>
1718 <div>bar</div>
1719 </div>
1720
1721 And with attributes:
1722
1723 <div>
1724 <div id="foo">
1725 </div>
1726 </div>
1727
1728 This was broken in 1.0.2b7:
1729
1730 <div class="inlinepage">
1731 <div class="toggleableend">
1732 foo
1733 </div>
1734 </div>
1735 """
1736
1737 var exp = """
1738 <p>Simple block on one line:</p>
1739 <div>foo</div>
1740 <p>And nested without indentation:</p>
1741 <div>
1742 <div>
1743 <div>
1744 foo
1745 </div>
1746 <div style=">"/>
1747 </div>
1748 <div>bar</div>
1749 </div>
1750 <p>And with attributes:</p>
1751 <div>
1752 <div id="foo">
1753 </div>
1754 </div>
1755 <p>This was broken in 1.0.2b7:</p>
1756 <div class="inlinepage">
1757 <div class="toggleableend">
1758 foo
1759 </div>
1760 </div>
1761 """
1762 var res = test.md_to_html.write_to_string
1763 assert res == exp
1764 end
1765
1766 fun test_daring_inline_html3 do
1767 var test = """
1768 Paragraph one.
1769
1770 <!-- This is a simple comment -->
1771
1772 <!--
1773 This is another comment.
1774 -->
1775
1776 Paragraph two.
1777
1778 <!-- one comment block -- -- with two comments -->
1779
1780 The end.
1781 """
1782
1783 var exp = """
1784 <p>Paragraph one.</p>
1785 <!-- This is a simple comment -->
1786 <!--
1787 This is another comment.
1788 -->
1789 <p>Paragraph two.</p>
1790 <!-- one comment block -- -- with two comments -->
1791 <p>The end.</p>
1792 """
1793 var res = test.md_to_html.write_to_string
1794 assert res == exp
1795 end
1796
1797 fun test_daring_links1 do
1798 var test = """
1799 Just a [URL](/url/).
1800
1801 [URL and title](/url/ "title").
1802
1803 [URL and title](/url/ "title preceded by two spaces").
1804
1805 [URL and title](/url/ "title preceded by a tab").
1806
1807 [URL and title](/url/ "title has spaces afterward" ).
1808
1809 [URL wrapped in angle brackets](</url/>).
1810
1811 [URL w/ angle brackets + title](</url/> "Here's the title").
1812
1813 [Empty]().
1814
1815 [With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing))
1816
1817 (With outer parens and [parens in url](/foo(bar)))
1818
1819
1820 [With parens in the URL](/foo(bar) "and a title")
1821
1822 (With outer parens and [parens in url](/foo(bar) "and a title"))
1823 """
1824
1825 var exp = """
1826 <p>Just a <a href="/url/">URL</a>.</p>
1827 <p><a href="/url/" title="title">URL and title</a>.</p>
1828 <p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>
1829 <p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>
1830 <p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>
1831 <p><a href="/url/">URL wrapped in angle brackets</a>.</p>
1832 <p><a href="/url/" title="Here&apos;s the title">URL w/ angle brackets + title</a>.</p>
1833 <p><a href="">Empty</a>.</p>
1834 <p><a href="http://en.wikipedia.org/wiki/WIMP_(computing)">With parens in the URL</a></p>
1835 <p>(With outer parens and <a href="/foo(bar)">parens in url</a>)</p>
1836 <p><a href="/foo(bar)" title="and a title">With parens in the URL</a></p>
1837 <p>(With outer parens and <a href="/foo(bar)" title="and a title">parens in url</a>)</p>
1838 """
1839 var res = test.md_to_html.write_to_string
1840 assert res == exp
1841 end
1842
1843 fun test_daring_links2 do
1844 var test = """
1845 Foo [bar] [1].
1846
1847 Foo [bar][1].
1848
1849 Foo [bar]
1850 [1].
1851
1852 [1]: /url/ "Title"
1853
1854
1855 With [embedded [brackets]] [b].
1856
1857
1858 Indented [once][].
1859
1860 Indented [twice][].
1861
1862 Indented [thrice][].
1863
1864 Indented [four][] times.
1865
1866 [once]: /url
1867
1868 [twice]: /url
1869
1870 [thrice]: /url
1871
1872 [four]: /url
1873
1874
1875 [b]: /url/
1876
1877 * * *
1878
1879 [this] [this] should work
1880
1881 So should [this][this].
1882
1883 And [this] [].
1884
1885 And [this][].
1886
1887 And [this].
1888
1889 But not [that] [].
1890
1891 Nor [that][].
1892
1893 Nor [that].
1894
1895 [Something in brackets like [this][] should work]
1896
1897 [Same with [this].]
1898
1899 In this case, [this](/somethingelse/) points to something else.
1900
1901 Backslashing should suppress \\\[this] and [this\\\].
1902
1903 [this]: foo
1904
1905
1906 * * *
1907
1908 Here's one where the [link
1909 breaks] across lines.
1910
1911 Here's another where the [link
1912 breaks] across lines, but with a line-ending space.
1913
1914
1915 [link breaks]: /url/
1916 """
1917
1918 var exp = """
1919 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1920 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1921 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1922 <p>With <a href="/url/">embedded [brackets]</a>.</p>
1923 <p>Indented <a href="/url">once</a>.</p>
1924 <p>Indented <a href="/url">twice</a>.</p>
1925 <p>Indented <a href="/url">thrice</a>.</p>
1926 <p>Indented [four][] times.</p>
1927 <pre><code>[four]: /url
1928 </code></pre>
1929 <hr/>
1930 <p><a href="foo">this</a> should work</p>
1931 <p>So should <a href="foo">this</a>.</p>
1932 <p>And <a href="foo">this</a>.</p>
1933 <p>And <a href="foo">this</a>.</p>
1934 <p>And <a href="foo">this</a>.</p>
1935 <p>But not [that] [].</p>
1936 <p>Nor [that][].</p>
1937 <p>Nor [that].</p>
1938 <p>[Something in brackets like <a href="foo">this</a> should work]</p>
1939 <p>[Same with <a href="foo">this</a>.]</p>
1940 <p>In this case, <a href="/somethingelse/">this</a> points to something else.</p>
1941 <p>Backslashing should suppress [this] and [this].</p>
1942 <hr/>
1943 <p>Here's one where the <a href="/url/">link
1944 breaks</a> across lines.</p>
1945 <p>Here's another where the <a href="/url/">link
1946 breaks</a> across lines, but with a line-ending space.</p>
1947 """
1948 var res = test.md_to_html.write_to_string
1949 assert res == exp
1950 end
1951
1952 fun test_daring_links3 do
1953 var test = """
1954 This is the [simple case].
1955
1956 [simple case]: /simple
1957
1958
1959
1960 This one has a [line
1961 break].
1962
1963 This one has a [line
1964 break] with a line-ending space.
1965
1966 [line break]: /foo
1967
1968
1969 [this] [that] and the [other]
1970
1971 [this]: /this
1972 [that]: /that
1973 [other]: /other
1974 """
1975
1976 var exp = """
1977 <p>This is the <a href="/simple">simple case</a>.</p>
1978 <p>This one has a <a href="/foo">line
1979 break</a>.</p>
1980 <p>This one has a <a href="/foo">line
1981 break</a> with a line-ending space.</p>
1982 <p><a href="/that">this</a> and the <a href="/other">other</a></p>
1983 """
1984 var res = test.md_to_html.write_to_string
1985 assert res == exp
1986 end
1987
1988 fun test_daring_nested do
1989 var test = """
1990 > foo
1991 >
1992 > > bar
1993 >
1994 > foo
1995 """
1996
1997 var exp = """
1998 <blockquote>
1999 <p>foo</p>
2000 <blockquote>
2001 <p>bar</p>
2002 </blockquote>
2003 <p>foo</p>
2004 </blockquote>
2005 """
2006 var res = test.md_to_html.write_to_string
2007 assert res == exp
2008 end
2009
2010 fun test_daring_list do
2011 var test = """
2012 ## Unordered
2013
2014 Asterisks tight:
2015
2016 * asterisk 1
2017 * asterisk 2
2018 * asterisk 3
2019
2020
2021 Asterisks loose:
2022
2023 * asterisk 1
2024
2025 * asterisk 2
2026
2027 * asterisk 3
2028
2029 * * *
2030
2031 Pluses tight:
2032
2033 + Plus 1
2034 + Plus 2
2035 + Plus 3
2036
2037
2038 Pluses loose:
2039
2040 + Plus 1
2041
2042 + Plus 2
2043
2044 + Plus 3
2045
2046 * * *
2047
2048
2049 Minuses tight:
2050
2051 - Minus 1
2052 - Minus 2
2053 - Minus 3
2054
2055
2056 Minuses loose:
2057
2058 - Minus 1
2059
2060 - Minus 2
2061
2062 - Minus 3
2063
2064
2065 ## Ordered
2066
2067 Tight:
2068
2069 1. First
2070 2. Second
2071 3. Third
2072
2073 and:
2074
2075 1. One
2076 2. Two
2077 3. Three
2078
2079
2080 Loose using tabs:
2081
2082 1. First
2083
2084 2. Second
2085
2086 3. Third
2087
2088 and using spaces:
2089
2090 1. One
2091
2092 2. Two
2093
2094 3. Three
2095
2096 Multiple paragraphs:
2097
2098 1. Item 1, graf one.
2099
2100 Item 2. graf two. The quick brown fox jumped over the lazy dog's
2101 back.
2102
2103 2. Item 2.
2104
2105 3. Item 3.
2106
2107
2108
2109 ## Nested
2110
2111 * Tab
2112 * Tab
2113 * Tab
2114
2115 Here's another:
2116
2117 1. First
2118 2. Second:
2119 * Fee
2120 * Fie
2121 * Foe
2122 3. Third
2123
2124 Same thing but with paragraphs:
2125
2126 1. First
2127
2128 2. Second:
2129 * Fee
2130 * Fie
2131 * Foe
2132
2133 3. Third
2134 """
2135
2136 var exp = """
2137 <h2 id="Unordered">Unordered</h2>
2138 <p>Asterisks tight:</p>
2139 <ul>
2140 <li>asterisk 1</li>
2141 <li>asterisk 2</li>
2142 <li>asterisk 3</li>
2143 </ul>
2144 <p>Asterisks loose:</p>
2145 <ul>
2146 <li><p>asterisk 1</p>
2147 </li>
2148 <li><p>asterisk 2</p>
2149 </li>
2150 <li><p>asterisk 3</p>
2151 </li>
2152 </ul>
2153 <hr/>
2154 <p>Pluses tight:</p>
2155 <ul>
2156 <li>Plus 1</li>
2157 <li>Plus 2</li>
2158 <li>Plus 3</li>
2159 </ul>
2160 <p>Pluses loose:</p>
2161 <ul>
2162 <li><p>Plus 1</p>
2163 </li>
2164 <li><p>Plus 2</p>
2165 </li>
2166 <li><p>Plus 3</p>
2167 </li>
2168 </ul>
2169 <hr/>
2170 <p>Minuses tight:</p>
2171 <ul>
2172 <li>Minus 1</li>
2173 <li>Minus 2</li>
2174 <li>Minus 3</li>
2175 </ul>
2176 <p>Minuses loose:</p>
2177 <ul>
2178 <li><p>Minus 1</p>
2179 </li>
2180 <li><p>Minus 2</p>
2181 </li>
2182 <li><p>Minus 3</p>
2183 </li>
2184 </ul>
2185 <h2 id="Ordered">Ordered</h2>
2186 <p>Tight:</p>
2187 <ol>
2188 <li>First</li>
2189 <li>Second</li>
2190 <li>Third</li>
2191 </ol>
2192 <p>and:</p>
2193 <ol>
2194 <li>One</li>
2195 <li>Two</li>
2196 <li>Three</li>
2197 </ol>
2198 <p>Loose using tabs:</p>
2199 <ol>
2200 <li><p>First</p>
2201 </li>
2202 <li><p>Second</p>
2203 </li>
2204 <li><p>Third</p>
2205 </li>
2206 </ol>
2207 <p>and using spaces:</p>
2208 <ol>
2209 <li><p>One</p>
2210 </li>
2211 <li><p>Two</p>
2212 </li>
2213 <li><p>Three</p>
2214 </li>
2215 </ol>
2216 <p>Multiple paragraphs:</p>
2217 <ol>
2218 <li><p>Item 1, graf one.</p>
2219 <p>Item 2. graf two. The quick brown fox jumped over the lazy dog's
2220 back.</p>
2221 </li>
2222 <li><p>Item 2.</p>
2223 </li>
2224 <li><p>Item 3.</p>
2225 </li>
2226 </ol>
2227 <h2 id="Nested">Nested</h2>
2228 <ul>
2229 <li>Tab<ul>
2230 <li>Tab<ul>
2231 <li>Tab</li>
2232 </ul>
2233 </li>
2234 </ul>
2235 </li>
2236 </ul>
2237 <p>Here's another:</p>
2238 <ol>
2239 <li>First</li>
2240 <li>Second:<ul>
2241 <li>Fee</li>
2242 <li>Fie</li>
2243 <li>Foe</li>
2244 </ul>
2245 </li>
2246 <li>Third</li>
2247 </ol>
2248 <p>Same thing but with paragraphs:</p>
2249 <ol>
2250 <li><p>First</p>
2251 </li>
2252 <li><p>Second:</p>
2253 <ul>
2254 <li>Fee</li>
2255 <li>Fie</li>
2256 <li>Foe</li>
2257 </ul>
2258 </li>
2259 <li><p>Third</p>
2260 </li>
2261 </ol>
2262 """
2263 var res = test.md_to_html.write_to_string
2264 assert res == exp
2265 end
2266
2267 fun test_daring_strong_em do
2268 var test = """
2269 ***This is strong and em.***
2270
2271 So is ***this*** word.
2272
2273 ___This is strong and em.___
2274
2275 So is ___this___ word.
2276 """
2277
2278 var exp = """
2279 <p><strong><em>This is strong and em.</em></strong></p>
2280 <p>So is <strong><em>this</em></strong> word.</p>
2281 <p><strong><em>This is strong and em.</em></strong></p>
2282 <p>So is <strong><em>this</em></strong> word.</p>
2283 """
2284 var res = test.md_to_html.write_to_string
2285 assert res == exp
2286 end
2287
2288 fun test_daring_tabs do
2289 var test = """
2290 + this is a list item
2291 indented with tabs
2292
2293 + this is a list item
2294 indented with spaces
2295
2296 Code:
2297
2298 this code block is indented by one tab
2299
2300 And:
2301
2302 this code block is indented by two tabs
2303
2304 And:
2305
2306 + this is an example list item
2307 indented with tabs
2308
2309 + this is an example list item
2310 indented with spaces
2311 """
2312
2313 var exp = """
2314 <ul>
2315 <li><p>this is a list item
2316 indented with tabs</p>
2317 </li>
2318 <li><p>this is a list item
2319 indented with spaces</p>
2320 </li>
2321 </ul>
2322 <p>Code:</p>
2323 <pre><code>this code block is indented by one tab
2324 </code></pre>
2325 <p>And:</p>
2326 <pre><code> this code block is indented by two tabs
2327 </code></pre>
2328 <p>And:</p>
2329 <pre><code>+ this is an example list item
2330 indented with tabs
2331
2332 + this is an example list item
2333 indented with spaces
2334 </code></pre>
2335 """
2336 var res = test.md_to_html.write_to_string
2337 assert res == exp
2338 end
2339
2340 fun test_daring_tidyness do
2341 var test = """
2342 > A list within a blockquote:
2343 >
2344 > * asterisk 1
2345 > * asterisk 2
2346 > * asterisk 3
2347 """
2348
2349 var exp = """
2350 <blockquote>
2351 <p>A list within a blockquote:</p>
2352 <ul>
2353 <li>asterisk 1</li>
2354 <li>asterisk 2</li>
2355 <li>asterisk 3</li>
2356 </ul>
2357 </blockquote>
2358 """
2359 var res = test.md_to_html.write_to_string
2360 assert res == exp
2361 end
2362
2363
2364 end
2365
2366 class TestBlock
2367 super TestSuite
2368
2369 fun test_has_blocks do
2370 var subject = new MDBlock
2371 assert not subject.has_blocks
2372 subject.first_block = new MDBlock
2373 assert subject.has_blocks
2374 end
2375
2376 fun test_count_blocks do
2377 var subject = new MDBlock
2378 assert subject.count_blocks == 0
2379 subject.first_block = new MDBlock
2380 assert subject.count_blocks == 1
2381 subject.first_block.next = new MDBlock
2382 assert subject.count_blocks == 2
2383 end
2384
2385 fun test_has_lines do
2386 var subject = new MDBlock
2387 assert not subject.has_lines
2388 subject.first_line = new MDLine("")
2389 assert subject.has_lines
2390 end
2391
2392 fun test_count_lines do
2393 var subject = new MDBlock
2394 assert subject.count_lines == 0
2395 subject.first_line = new MDLine("")
2396 assert subject.count_lines == 1
2397 subject.first_line.next = new MDLine("")
2398 assert subject.count_lines == 2
2399 end
2400
2401 fun test_split do
2402 var line1 = new MDLine("line1")
2403 var line2 = new MDLine("line2")
2404 var line3 = new MDLine("line3")
2405 var subject = new MDBlock
2406 subject.add_line line1
2407 subject.add_line line2
2408 subject.add_line line3
2409 var block = subject.split(line2)
2410 assert subject.count_blocks == 1
2411 assert subject.count_lines == 1
2412 assert subject.first_line == line3
2413 assert block.count_blocks == 0
2414 assert block.count_lines == 2
2415 assert block.first_line == line1
2416 assert block.last_line == line2
2417 end
2418
2419 fun test_add_line do
2420 var subject = new MDBlock
2421 assert subject.count_lines == 0
2422 subject.add_line new MDLine("")
2423 assert subject.count_lines == 1
2424 subject.add_line new MDLine("")
2425 assert subject.count_lines == 2
2426 end
2427
2428 fun test_remove_line do
2429 var line1 = new MDLine("line1")
2430 var line2 = new MDLine("line2")
2431 var line3 = new MDLine("line3")
2432 var subject = new MDBlock
2433 subject.add_line line1
2434 subject.add_line line2
2435 subject.add_line line3
2436 subject.remove_line(line2)
2437 assert subject.count_lines == 2
2438 subject.remove_line(line1)
2439 assert subject.count_lines == 1
2440 assert subject.first_line == line3
2441 assert subject.last_line == line3
2442 end
2443
2444 fun test_transform_headline1 do
2445 var subject = new MDBlock
2446 var kind = new BlockHeadline(subject)
2447 subject.add_line new MDLine(" # Title 1 ")
2448 kind.transform_headline(subject)
2449 assert kind.depth == 1
2450 assert subject.first_line.value == "Title 1"
2451 end
2452
2453 fun test_transform_headline2 do
2454 var subject = new MDBlock
2455 var kind = new BlockHeadline(subject)
2456 subject.add_line new MDLine(" #####Title 5 ")
2457 kind.transform_headline(subject)
2458 assert kind.depth == 5
2459 assert subject.first_line.value == "Title 5"
2460 end
2461
2462 fun test_remove_quote_prefix do
2463 var subject = new MDBlock
2464 var kind = new BlockQuote(subject)
2465 subject.add_line new MDLine(" > line 1")
2466 subject.add_line new MDLine(" > line 2")
2467 subject.add_line new MDLine(" > line 3")
2468 kind.remove_block_quote_prefix(subject)
2469 assert subject.first_line.value == "line 1"
2470 assert subject.first_line.next.value == "line 2"
2471 assert subject.first_line.next.next.value == "line 3"
2472 end
2473
2474 fun test_remove_leading_empty_lines_1 do
2475 var block = new MDBlock
2476 block.add_line new MDLine("")
2477 block.add_line new MDLine("")
2478 block.add_line new MDLine("")
2479 block.add_line new MDLine("")
2480 block.add_line new MDLine(" text")
2481 block.add_line new MDLine("")
2482 assert block.remove_leading_empty_lines
2483 assert block.first_line.value == " text"
2484 end
2485
2486 fun test_remove_leading_empty_lines_2 do
2487 var block = new MDBlock
2488 block.add_line new MDLine(" text")
2489 block.remove_leading_empty_lines
2490 assert block.first_line.value == " text"
2491 end
2492
2493 fun test_remove_trailing_empty_lines_1 do
2494 var block = new MDBlock
2495 block.add_line new MDLine("")
2496 block.add_line new MDLine("text")
2497 block.add_line new MDLine("")
2498 block.add_line new MDLine("")
2499 block.add_line new MDLine("")
2500 block.add_line new MDLine("")
2501 assert block.remove_trailing_empty_lines
2502 assert block.last_line.value == "text"
2503 end
2504
2505 fun test_remove_trailing_empty_lines_2 do
2506 var block = new MDBlock
2507 block.add_line new MDLine("text ")
2508 assert not block.remove_trailing_empty_lines
2509 assert block.last_line.value == "text "
2510 end
2511
2512 fun test_remove_surrounding_empty_lines do
2513 var block = new MDBlock
2514 block.add_line new MDLine("")
2515 block.add_line new MDLine("text")
2516 block.add_line new MDLine("")
2517 block.add_line new MDLine("")
2518 block.add_line new MDLine("")
2519 block.add_line new MDLine("")
2520 assert block.remove_surrounding_empty_lines
2521 assert block.first_line.value == "text"
2522 assert block.last_line.value == "text"
2523 end
2524 end
2525
2526 class TestLine
2527 super TestSuite
2528
2529 var subject: MDLine
2530
2531 fun test_is_empty do
2532 subject = new MDLine("")
2533 assert subject.is_empty
2534 subject = new MDLine(" ")
2535 assert subject.is_empty
2536 subject = new MDLine("test")
2537 assert not subject.is_empty
2538 subject = new MDLine(" test")
2539 assert not subject.is_empty
2540 end
2541
2542 fun test_leading do
2543 subject = new MDLine("")
2544 assert subject.leading == 0
2545 subject = new MDLine(" ")
2546 assert subject.leading == 4
2547 subject = new MDLine("test")
2548 assert subject.leading == 0
2549 subject = new MDLine(" test")
2550 assert subject.leading == 4
2551 end
2552
2553 fun test_trailing do
2554 subject = new MDLine("")
2555 assert subject.trailing == 0
2556 subject = new MDLine(" ")
2557 assert subject.trailing == 0
2558 subject = new MDLine("test ")
2559 assert subject.trailing == 3
2560 subject = new MDLine(" test ")
2561 assert subject.trailing == 1
2562 end
2563
2564 fun test_line_type do
2565 var v = new MarkdownProcessor
2566 subject = new MDLine("")
2567 assert v.line_kind(subject) isa LineEmpty
2568 subject = new MDLine(" ")
2569 assert v.line_kind(subject) isa LineEmpty
2570 subject = new MDLine("text ")
2571 assert v.line_kind(subject) isa LineOther
2572 subject = new MDLine(" # Title")
2573 assert v.line_kind(subject) isa LineHeadline
2574 subject = new MDLine(" ### Title")
2575 assert v.line_kind(subject) isa LineHeadline
2576 subject = new MDLine(" code")
2577 assert v.line_kind(subject) isa LineCode
2578 subject = new MDLine(" Title ")
2579 subject.next = new MDLine("== ")
2580 assert v.line_kind(subject) isa LineHeadline1
2581 subject = new MDLine(" Title ")
2582 subject.next = new MDLine("-- ")
2583 assert v.line_kind(subject) isa LineHeadline2
2584 subject = new MDLine(" * * * ")
2585 assert v.line_kind(subject) isa LineHR
2586 subject = new MDLine(" *** ")
2587 assert v.line_kind(subject) isa LineHR
2588 subject = new MDLine("- -- ")
2589 assert v.line_kind(subject) isa LineHR
2590 subject = new MDLine("--------- ")
2591 assert v.line_kind(subject) isa LineHR
2592 subject = new MDLine(" >")
2593 assert v.line_kind(subject) isa LineBlockquote
2594 subject = new MDLine("<p></p>")
2595 assert v.line_kind(subject) isa LineXML
2596 subject = new MDLine("<p>")
2597 assert v.line_kind(subject) isa LineOther
2598 subject = new MDLine(" * foo")
2599 assert v.line_kind(subject) isa LineUList
2600 subject = new MDLine("- foo")
2601 assert v.line_kind(subject) isa LineUList
2602 subject = new MDLine("+ foo")
2603 assert v.line_kind(subject) isa LineUList
2604 subject = new MDLine("1. foo")
2605 assert v.line_kind(subject) isa LineOList
2606 subject = new MDLine(" 11111. foo")
2607 assert v.line_kind(subject) isa LineOList
2608 end
2609
2610 fun test_line_type_ext do
2611 var v = new MarkdownProcessor
2612 subject = new MDLine(" ~~~")
2613 assert v.line_kind(subject) isa LineFence
2614 subject = new MDLine(" ```")
2615 assert v.line_kind(subject) isa LineFence
2616 end
2617
2618 fun test_count_chars do
2619 subject = new MDLine("")
2620 assert subject.count_chars('*') == 0
2621 subject = new MDLine("* ")
2622 assert subject.count_chars('*') == 1
2623 subject = new MDLine(" * text")
2624 assert subject.count_chars('*') == 0
2625 subject = new MDLine(" * * *")
2626 assert subject.count_chars('*') == 3
2627 subject = new MDLine("text ** ")
2628 assert subject.count_chars('*') == 0
2629 end
2630
2631 fun test_count_chars_start do
2632 subject = new MDLine("")
2633 assert subject.count_chars_start('*') == 0
2634 subject = new MDLine("* ")
2635 assert subject.count_chars_start('*') == 1
2636 subject = new MDLine(" * text")
2637 assert subject.count_chars_start('*') == 1
2638 subject = new MDLine(" * * * text")
2639 assert subject.count_chars_start('*') == 3
2640 subject = new MDLine("text ** ")
2641 assert subject.count_chars_start('*') == 0
2642 end
2643 end
2644
2645 class TestHTMLDecorator
2646 super TestSuite
2647
2648 fun test_headlines do
2649 var test = """
2650 # **a**
2651 ## a.a
2652 ### a.a.b
2653 ### a.a.b
2654 ## a.b
2655 # [b](test)
2656 ## b.a
2657 ### b.a.c
2658 ## b.b
2659 ## b.c
2660 # c
2661 """
2662 var proc = new MarkdownProcessor
2663 var decorator = proc.emitter.decorator.as(HTMLDecorator)
2664 proc.process(test)
2665 var res = ""
2666 for id, headline in decorator.headlines do
2667 res += "{headline.title}:{id}\n"
2668 end
2669 var exp = """
2670 **a**:a
2671 a.a:a.a
2672 a.a.b:a.a.b
2673 a.a.b:a.a.b_1
2674 a.b:a.b
2675 [b](test):btest
2676 b.a:b.a
2677 b.a.c:b.a.c
2678 b.b:b.b
2679 b.c:b.c
2680 c:c
2681 """
2682 assert res == exp
2683 end
2684 end