1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # Test suites for module `markdown`
16 module test_markdown
is test_suite
19 intrude import markdown
21 class TestMarkdownProcessor
24 fun test_process_empty
do
27 var res
= test
.md_to_html
.write_to_string
31 fun test_process_tabs
do
35 var exp
= """<pre><code>some code
38 var res
= test
.md_to_html
.write_to_string
43 fun test_process_par1
do
45 var exp
= "<p>test</p>\n"
46 var res
= test
.md_to_html
.write_to_string
50 fun test_process_par2
do
64 var res
= test
.md_to_html
.write_to_string
68 fun test_process_par3
do
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.
74 Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
75 id sem consectetuer libero luctus adipiscing.
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>
84 var res
= test
.md_to_html
.write_to_string
88 fun test_process_headings_1
do
97 <h1 id="This_is_a_H1">This is a H1</h1>
98 <h2 id="This_is_a_H2">This is a H2</h2>
100 var res
= test
.md_to_html
.write_to_string
104 fun test_process_headings_2
do
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>
116 var res
= test
.md_to_html
.write_to_string
120 fun test_process_headings_3
do
126 ### This is a H3 ######
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>
133 var res
= test
.md_to_html
.write_to_string
137 fun test_process_hr
do
147 ---------------------------------------
149 var exp
= "<hr/>\n<hr/>\n<hr/>\n<hr/>\n<hr/>\n"
150 var res
= test
.md_to_html
.write_to_string
154 fun test_process_bquote1
do
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.
160 > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
161 > id sem consectetuer libero luctus adipiscing.
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>
171 var res
= test
.md_to_html
.write_to_string
175 fun test_process_bquote2
do
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.
181 > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
182 id sem consectetuer libero luctus adipiscing.
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>
192 var res
= test
.md_to_html
.write_to_string
196 fun test_process_bquote3
do
198 > This is the first level of quoting.
200 > > This is nested blockquote.
202 > Back to the first level.
204 var exp
= """<blockquote>
205 <p>This is the first level of quoting.</p>
207 <p>This is nested blockquote.</p>
209 <p>Back to the first level.</p>
212 var res
= test
.md_to_html
.write_to_string
216 fun test_process_list1
do
228 var res
= test
.md_to_html
.write_to_string
232 fun test_process_list2
do
244 var res
= test
.md_to_html
.write_to_string
248 fun test_process_list3
do
260 var res
= test
.md_to_html
.write_to_string
264 fun test_process_list4
do
276 var res
= test
.md_to_html
.write_to_string
280 fun test_process_list5
do
292 var res
= test
.md_to_html
.write_to_string
296 fun test_process_list6
do
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.
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>
313 var res
= test
.md_to_html
.write_to_string
317 fun test_process_list7
do
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.
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>
334 var res
= test
.md_to_html
.write_to_string
338 fun test_process_list8
do
352 var res
= test
.md_to_html
.write_to_string
356 fun test_process_list9
do
358 1. This is a list item with two paragraphs. Lorem ipsum dolor
359 sit amet, consectetuer adipiscing elit. Aliquam hendrerit
362 Vestibulum enim wisi, viverra nec, fringilla in, laoreet
363 vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
366 2. Suspendisse id sem consectetuer libero luctus adipiscing.
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
377 <li><p>Suspendisse id sem consectetuer libero luctus adipiscing.</p>
381 var res
= test
.md_to_html
.write_to_string
385 fun test_process_list10
do
387 * This is a list item with two paragraphs.
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.
393 * Another item in the same list.
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>
402 <li><p>Another item in the same list.</p>
406 var res
= test
.md_to_html
.write_to_string
410 fun test_process_list11
do
413 * and this is not a list
416 <p>This is a paragraph
417 * and this is not a list</p>
419 var proc
= new MarkdownProcessor
420 proc
.ext_mode
= false
421 var res
= proc
.process
(test
).write_to_string
425 fun test_process_list_ext
do
428 * and this is not a list
431 <p>This is a paragraph</p>
433 <li>and this is not a list</li>
436 var res
= test
.md_to_html
.write_to_string
440 fun test_process_code1
do
442 This is a normal paragraph:
444 This is a code block.
446 var exp
= """<p>This is a normal paragraph:</p>
447 <pre><code>This is a code block.
450 var res
= test
.md_to_html
.write_to_string
454 fun test_process_code2
do
456 Here is an example of AppleScript:
458 tell application "Foo"
463 © 2004 Foo Corporation
467 <p>Here is an example of AppleScript:</p>
468 <pre><code>tell application "Foo"
472 <div class="footer">
473 &copy; 2004 Foo Corporation
477 var res
= test
.md_to_html
.write_to_string
481 fun test_process_code_ext1
do
483 Here is an example of AppleScript:
485 tell application "Foo"
490 © 2004 Foo Corporation
495 <p>Here is an example of AppleScript:</p>
496 <pre><code>tell application "Foo"
500 <div class="footer">
501 &copy; 2004 Foo Corporation
505 var res
= test
.md_to_html
.write_to_string
509 fun test_process_code_ext2
do
511 Here is an example of AppleScript:
513 tell application "Foo"
518 © 2004 Foo Corporation
523 <p>Here is an example of AppleScript:</p>
524 <pre><code>tell application "Foo"
528 <div class="footer">
529 &copy; 2004 Foo Corporation
533 var res
= test
.md_to_html
.write_to_string
537 fun test_process_code_ext3
do
538 var proc
= new MarkdownProcessor
539 proc
.ext_mode
= false
542 Here is an example of AppleScript:
546 <p>Here is an example of AppleScript:
549 var res
= proc
.process
(test
).write_to_string
553 fun test_process_code_ext4
do
555 Here is an example of AppleScript:
559 <p>Here is an example of AppleScript:</p>
563 var res
= test
.md_to_html
.write_to_string
567 fun test_process_code_ext5
do
574 <pre class="nit"><code>print "Hello World!"
577 var res
= test
.md_to_html
.write_to_string
581 fun test_process_nesting1
do
583 > ## This is a header.
585 > 1. This is the first list item.
586 > 2. This is the second list item.
588 > Here's some example code:
590 > return shell_exec("echo $input | $markdown_script");
594 <h2 id="This_is_a_header.">This is a header.</h2>
596 <li>This is the first list item.</li>
597 <li>This is the second list item.</li>
599 <p>Here's some example code:</p>
600 <pre><code>return shell_exec("echo $input | $markdown_script");
604 var res
= test
.md_to_html
.write_to_string
608 fun test_process_nesting2
do
610 * A list item with a blockquote:
612 > This is a blockquote
613 > inside a list item.
617 <li><p>A list item with a blockquote:</p>
619 <p>This is a blockquote
620 inside a list item.</p>
625 var res
= test
.md_to_html
.write_to_string
629 fun test_process_nesting3
do
631 * A list item with a code block:
637 <li><p>A list item with a code block:</p>
638 <pre><code><code goes here>
643 var res
= test
.md_to_html
.write_to_string
647 fun test_process_nesting4
do
664 var res
= test
.md_to_html
.write_to_string
669 # fun test_process_nesting5 do
687 # var res = test.md_to_html.write_to_string
691 fun test_process_emph1
do
699 __double underscores__
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>
706 var res
= test
.md_to_html
.write_to_string
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
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
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
733 fun test_process_xml1
do
735 This is a regular paragraph.
743 This is another regular paragraph.
746 <p>This is a regular paragraph.</p>
752 <p>This is another regular paragraph.</p>
754 var res
= test
.md_to_html
.write_to_string
758 fun test_process_xml2
do
760 This is an image <img src="foo/bar" alt="baz"/> in a regular paragraph.
762 var exp
= """<p>This is an image <img src="foo/bar" alt="baz" /> in a regular paragraph.</p>
764 var res
= test
.md_to_html
.write_to_string
768 fun test_process_xml3
do
775 var res
= test
.md_to_html
.write_to_string
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
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
793 fun test_process_span_code3
do
795 A single backtick in a code span: `` ` ``
797 A backtick-delimited string in a code span: `` `foo` ``
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>
803 var res
= test
.md_to_html
.write_to_string
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><blink></code> tags.</p>\n"
810 var res
= test
.md_to_html
.write_to_string
814 fun test_process_span_code5
do
815 var test
= "`—` is the decimal-encoded equivalent of `—`."
816 var exp
= "<p><code>&#8212;</code> is the decimal-encoded equivalent of <code>&mdash;</code>.</p>\n"
817 var res
= test
.md_to_html
.write_to_string
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
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
835 fun test_process_escape3
do
836 var test
= "Ben & Lux"
837 var exp
= "<p>Ben & Lux</p>\n"
838 var res
= test
.md_to_html
.write_to_string
842 fun test_process_link1
do
844 This is [an example](http://example.com/ "Title") inline link.
846 [This link](http://example.net/) has no title attribute.
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>
851 var res
= test
.md_to_html
.write_to_string
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
862 fun test_process_link3
do
864 This is [an example][id] reference-style link.
866 This is [an example] [id] reference-style link.
870 [id]: http://example.com/ "Optional Title Here"
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>
880 var res
= test
.md_to_html
.write_to_string
884 fun test_process_link4
do
886 This is multiple examples: [foo][1], [bar][2], [baz][3].
888 [1]: http://example.com/ "Optional Title Here"
889 [2]: http://example.com/ 'Optional Title Here'
890 [3]: http://example.com/ (Optional Title Here)
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>
895 var res
= test
.md_to_html
.write_to_string
899 fun test_process_link5
do
901 This is multiple examples: [foo][a], [bar][A], [a].
903 [a]: http://example.com/ "Optional Title Here"
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>
907 var res
= test
.md_to_html
.write_to_string
911 fun test_process_link6
do
913 I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][].
915 [Google]: http://google.com/ "Google"
916 [Yahoo]: http://search.yahoo.com/ "Yahoo Search"
917 [MSN]: http://search.msn.com/ "MSN Search"
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>
921 var res
= test
.md_to_html
.write_to_string
925 fun test_process_link7
do
927 Visit [Daring Fireball][] for more information.
929 [Daring Fireball]: http://daringfireball.net/
931 var exp
= """<p>Visit <a href="http://daringfireball.net/">Daring Fireball</a> for more information.</p>
933 var res
= test
.md_to_html
.write_to_string
937 fun test_process_link8
do
943 break] with a line-ending space.
948 <p>This one has a <a href="/foo">line
950 <p>This one has a <a href="/foo">line
951 break</a> with a line-ending space.</p>
953 var res
= test
.md_to_html
.write_to_string
957 # FIXME unignore test once escape strings fixed
958 # fun test_process_link9 do
962 # Foo [bar](/url/ "Title with \"quotes\" inside").
965 # [bar]: /url/ "Title with \"quotes\" inside"
968 # <p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p>
969 # <p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p>
971 # var res = test.md_to_html.write_to_string
975 fun test_process_img1
do
977 ![Alt text](/path/to/img.jpg)
979 ![Alt text](/path/to/img.jpg "Optional title")
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>
984 var res
= test
.md_to_html
.write_to_string
988 fun test_process_img2
do
992 [id]: url/to/image "Optional title attribute"
994 var exp
= """<p><img src="url/to/image" alt="Alt text" title="Optional title attribute"/></p>
996 var res
= test
.md_to_html
.write_to_string
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
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
1017 fun test_daring_encoding
do
1019 AT&T has an ampersand in their name.
1021 AT&T is another way to write it.
1029 Here's a [link] [1] with an ampersand in the URL.
1031 Here's a link with an amersand in the link text: [AT&T] [2].
1033 Here's an inline [link](/script?foo=1&bar=2).
1035 Here's an inline [link](</script?foo=1&bar=2>).
1038 [1]: http://example.com/?foo=1&bar=2
1039 [2]: http://att.com/ "AT&T"
1043 <p>AT&T has an ampersand in their name.</p>
1044 <p>AT&T is another way to write it.</p>
1045 <p>This & that.</p>
1048 <p>Here's a <a href="http://example.com/?foo=1&bar=2">link</a> with an ampersand in the URL.</p>
1049 <p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p>
1050 <p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p>
1051 <p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p>
1053 var res
= test
.md_to_html
.write_to_string
1058 fun test_daring_autolinks
do
1060 Link: <http://example.com/>.
1062 With an ampersand: <http://example.com/?foo=1&bar=2>
1065 * <http://example.com/>
1068 > Blockquoted: <http://example.com/>
1070 Auto-links should not occur here: `<http://example.com/>`
1072 or here: <http://example.com/>
1076 <p>Link: <a href="http://example.com/">http://example.com/</a>.</p>
1077 <p>With an ampersand: <a href="http://example.com/?foo=1&bar=2">http://example.com/?foo=1&bar=2</a></p>
1080 <li><a href="http://example.com/">http://example.com/</a></li>
1084 <p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>
1086 <p>Auto-links should not occur here: <code><http://example.com/></code></p>
1087 <pre><code>or here: <http://example.com/>
1090 var res
= test
.md_to_html
.write_to_string
1094 fun test_daring_escape
do
1096 These should all get escaped:
1131 These should not, because they occur within a code block:
1165 Nor should these, which occur in code spans:
1199 These should get escaped, even though they're matching pairs for
1200 other Markdown constructs:
1208 This is a code span with a literal backslash-backtick sequence: `` \` ``
1210 This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.
1212 This is a tag with backslashes <span attr='\\\\backslashes\\\\'>bar</span>.
1215 <p>These should all get escaped:</p>
1216 <p>Backslash: \\</p>
1219 <p>Underscore: \_</p>
1220 <p>Left brace: \{</p>
1221 <p>Right brace: \}</p>
1222 <p>Left bracket: \[</p>
1223 <p>Right bracket: \]</p>
1224 <p>Left paren: \(</p>
1225 <p>Right paren: \)</p>
1226 <p>Greater-than: \></p>
1232 <p>These should not, because they occur within a code block:</p>
1233 <pre><code>Backslash: \\
1265 <p>Nor should these, which occur in code spans:</p>
1266 <p>Backslash: <code>\\</code></p>
1267 <p>Backtick: <code>\`</code></p>
1268 <p>Asterisk: <code>\*</code></p>
1269 <p>Underscore: <code>\_</code></p>
1270 <p>Left brace: <code>\{</code></p>
1271 <p>Right brace: <code>\}</code></p>
1272 <p>Left bracket: <code>\[</code></p>
1273 <p>Right bracket: <code>\]</code></p>
1274 <p>Left paren: <code>\(</code></p>
1275 <p>Right paren: <code>\)</code></p>
1276 <p>Greater-than: <code>\></code></p>
1277 <p>Hash: <code>\#</code></p>
1278 <p>Period: <code>\.</code></p>
1279 <p>Bang: <code>\!</code></p>
1280 <p>Plus: <code>\+</code></p>
1281 <p>Minus: <code>\-</code></p>
1282 <p>These should get escaped, even though they're matching pairs for
1283 other Markdown constructs:</p>
1285 <p>_underscores_</p>
1287 <p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p>
1288 <p>This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.</p>
1289 <p>This is a tag with backslashes <span attr='\\\\backslashes\\\\'>bar</span>.</p>
1292 var res
= test
.md_to_html
.write_to_string
1296 fun test_daring_blockquotes
do
1314 <pre><code>sub status {
1319 <pre><code>sub status {
1325 var res
= test
.md_to_html
.write_to_string
1329 fun test_daring_code_blocks
do
1331 code block on the first line
1335 code block indented by spaces
1339 the lines in this block
1340 all contain trailing spaces
1344 code block on the last line
1348 <pre><code>code block on the first line
1350 <p>Regular text.</p>
1351 <pre><code>code block indented by spaces
1353 <p>Regular text.</p>
1354 <pre><code>the lines in this block
1355 all contain trailing spaces
1357 <p>Regular Text.</p>
1358 <pre><code>code block on the last line
1361 var res
= test
.md_to_html
.write_to_string
1365 fun test_daring_code_spans
do
1367 `<test a="` content of attribute `">`
1369 Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>
1371 Here's how you put `` `backticks` `` in a code span.
1375 <p><code><test a="</code> content of attribute <code>"></code></p>
1376 <p>Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span></p>
1377 <p>Here's how you put <code>`backticks`</code> in a code span.</p>
1379 var res
= test
.md_to_html
.write_to_string
1383 fun test_daring_pars
do
1384 var proc
= new MarkdownProcessor
1385 proc
.ext_mode
= false
1388 In Markdown 1.0.0 and earlier. Version
1389 8. This line turns into a list item.
1390 Because a hard-wrapped line in the
1391 middle of a paragraph looked like a
1394 Here's one with a bullet.
1399 <p>In Markdown 1.0.0 and earlier. Version
1400 8. This line turns into a list item.
1401 Because a hard-wrapped line in the
1402 middle of a paragraph looked like a
1404 <p>Here's one with a bullet.
1407 var res
= proc
.process
(test
).write_to_string
1411 fun test_daring_rules
do
1523 var res
= test
.md_to_html
.write_to_string
1527 fun test_daring_images
do
1529 ![Alt text](/path/to/img.jpg)
1531 ![Alt text](/path/to/img.jpg "Optional title")
1533 Inline within a paragraph: [alt text](/url/).
1535 ![alt text](/url/ "title preceded by two spaces")
1537 ![alt text](/url/ "title has spaces afterward" )
1539 ![alt text](</url/>)
1541 ![alt text](</url/> "with a title").
1545 ![this is a stupid URL](http://example.com/(parens).jpg)
1554 [bar]: /url/ "Title here"
1558 <p><img src="/path/to/img.jpg" alt="Alt text"/></p>
1559 <p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title"/></p>
1560 <p>Inline within a paragraph: <a href="/url/">alt text</a>.</p>
1561 <p><img src="/url/" alt="alt text" title="title preceded by two spaces"/></p>
1562 <p><img src="/url/" alt="alt text" title="title has spaces afterward"/></p>
1563 <p><img src="/url/" alt="alt text"/></p>
1564 <p><img src="/url/" alt="alt text" title="with a title"/>.</p>
1565 <p><img src="" alt="Empty"/></p>
1566 <p><img src="http://example.com/(parens).jpg" alt="this is a stupid URL"/></p>
1567 <p><img src="/url/" alt="alt text"/></p>
1568 <p><img src="/url/" alt="alt text" title="Title here"/></p>
1570 var res
= test
.md_to_html
.write_to_string
1574 fun test_daring_inline_html1
do
1576 Here's a simple block:
1582 This should be a code block, though:
1602 This should just be an HTML comment:
1617 Just plain comment, with trailing spaces on the line:
1639 <hr class="foo" id="bar" />
1641 <hr class="foo" id="bar"/>
1643 <hr class="foo" id="bar" >
1647 <p>Here's a simple block:</p>
1651 <p>This should be a code block, though:</p>
1652 <pre><code><div>
1656 <p>As should this:</p>
1657 <pre><code><div>foo</div>
1667 <p>This should just be an HTML comment:</p>
1675 <pre><code><!-- Comment -->
1677 <p>Just plain comment, with trailing spaces on the line:</p>
1680 <pre><code><hr />
1689 <hr class="foo" id="bar" />
1690 <hr class="foo" id="bar"/>
1691 <hr class="foo" id="bar" >
1693 var res
= test
.md_to_html
.write_to_string
1697 fun test_daring_inline_html2
do
1699 Simple block on one line:
1703 And nested without indentation:
1715 And with attributes:
1722 This was broken in 1.0.2b7:
1724 <div class="inlinepage">
1725 <div class="toggleableend">
1732 <p>Simple block on one line:</p>
1734 <p>And nested without indentation:</p>
1744 <p>And with attributes:</p>
1749 <p>This was broken in 1.0.2b7:</p>
1750 <div class="inlinepage">
1751 <div class="toggleableend">
1756 var res
= test
.md_to_html
.write_to_string
1760 fun test_daring_inline_html3
do
1764 <!-- This is a simple comment -->
1767 This is another comment.
1772 <!-- one comment block -- -- with two comments -->
1778 <p>Paragraph one.</p>
1779 <!-- This is a simple comment -->
1781 This is another comment.
1783 <p>Paragraph two.</p>
1784 <!-- one comment block -- -- with two comments -->
1787 var res
= test
.md_to_html
.write_to_string
1791 fun test_daring_links1
do
1793 Just a [URL](/url/).
1795 [URL and title](/url/ "title").
1797 [URL and title](/url/ "title preceded by two spaces").
1799 [URL and title](/url/ "title preceded by a tab").
1801 [URL and title](/url/ "title has spaces afterward" ).
1803 [URL wrapped in angle brackets](</url/>).
1805 [URL w/ angle brackets + title](</url/> "Here's the title").
1809 [With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing))
1811 (With outer parens and [parens in url](/foo(bar)))
1814 [With parens in the URL](/foo(bar) "and a title")
1816 (With outer parens and [parens in url](/foo(bar) "and a title"))
1820 <p>Just a <a href="/url/">URL</a>.</p>
1821 <p><a href="/url/" title="title">URL and title</a>.</p>
1822 <p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>
1823 <p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>
1824 <p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>
1825 <p><a href="/url/">URL wrapped in angle brackets</a>.</p>
1826 <p><a href="/url/" title="Here's the title">URL w/ angle brackets + title</a>.</p>
1827 <p><a href="">Empty</a>.</p>
1828 <p><a href="http://en.wikipedia.org/wiki/WIMP_(computing)">With parens in the URL</a></p>
1829 <p>(With outer parens and <a href="/foo(bar)">parens in url</a>)</p>
1830 <p><a href="/foo(bar)" title="and a title">With parens in the URL</a></p>
1831 <p>(With outer parens and <a href="/foo(bar)" title="and a title">parens in url</a>)</p>
1833 var res
= test
.md_to_html
.write_to_string
1837 fun test_daring_links2
do
1849 With [embedded [brackets]] [b].
1856 Indented [thrice][].
1858 Indented [four][] times.
1873 [this] [this] should work
1875 So should [this][this].
1889 [Something in brackets like [this][] should work]
1893 In this case, [this](/somethingelse/) points to something else.
1895 Backslashing should suppress \\\[this] and [this\\\].
1902 Here's one where the [link
1903 breaks] across lines.
1905 Here's another where the [link
1906 breaks] across lines, but with a line-ending space.
1909 [link breaks]: /url/
1913 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1914 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1915 <p>Foo <a href="/url/" title="Title">bar</a>.</p>
1916 <p>With <a href="/url/">embedded [brackets]</a>.</p>
1917 <p>Indented <a href="/url">once</a>.</p>
1918 <p>Indented <a href="/url">twice</a>.</p>
1919 <p>Indented <a href="/url">thrice</a>.</p>
1920 <p>Indented [four][] times.</p>
1921 <pre><code>[four]: /url
1924 <p><a href="foo">this</a> should work</p>
1925 <p>So should <a href="foo">this</a>.</p>
1926 <p>And <a href="foo">this</a>.</p>
1927 <p>And <a href="foo">this</a>.</p>
1928 <p>And <a href="foo">this</a>.</p>
1929 <p>But not [that] [].</p>
1930 <p>Nor [that][].</p>
1932 <p>[Something in brackets like <a href="foo">this</a> should work]</p>
1933 <p>[Same with <a href="foo">this</a>.]</p>
1934 <p>In this case, <a href="/somethingelse/">this</a> points to something else.</p>
1935 <p>Backslashing should suppress [this] and [this].</p>
1937 <p>Here's one where the <a href="/url/">link
1938 breaks</a> across lines.</p>
1939 <p>Here's another where the <a href="/url/">link
1940 breaks</a> across lines, but with a line-ending space.</p>
1942 var res
= test
.md_to_html
.write_to_string
1946 fun test_daring_links3
do
1948 This is the [simple case].
1950 [simple case]: /simple
1954 This one has a [line
1957 This one has a [line
1958 break] with a line-ending space.
1963 [this] [that] and the [other]
1971 <p>This is the <a href="/simple">simple case</a>.</p>
1972 <p>This one has a <a href="/foo">line
1974 <p>This one has a <a href="/foo">line
1975 break</a> with a line-ending space.</p>
1976 <p><a href="/that">this</a> and the <a href="/other">other</a></p>
1978 var res
= test
.md_to_html
.write_to_string
1982 fun test_daring_nested
do
2000 var res
= test
.md_to_html
.write_to_string
2004 fun test_daring_list
do
2090 Multiple paragraphs:
2092 1. Item 1, graf one.
2094 Item 2. graf two. The quick brown fox jumped over the lazy dog's
2118 Same thing but with paragraphs:
2131 <h2 id="Unordered">Unordered</h2>
2132 <p>Asterisks tight:</p>
2138 <p>Asterisks loose:</p>
2140 <li><p>asterisk 1</p>
2142 <li><p>asterisk 2</p>
2144 <li><p>asterisk 3</p>
2148 <p>Pluses tight:</p>
2154 <p>Pluses loose:</p>
2164 <p>Minuses tight:</p>
2170 <p>Minuses loose:</p>
2179 <h2 id="Ordered">Ordered</h2>
2192 <p>Loose using tabs:</p>
2201 <p>and using spaces:</p>
2210 <p>Multiple paragraphs:</p>
2212 <li><p>Item 1, graf one.</p>
2213 <p>Item 2. graf two. The quick brown fox jumped over the lazy dog's
2221 <h2 id="Nested">Nested</h2>
2231 <p>Here's another:</p>
2242 <p>Same thing but with paragraphs:</p>
2257 var res
= test
.md_to_html
.write_to_string
2261 fun test_daring_strong_em
do
2263 ***This is strong and em.***
2265 So is ***this*** word.
2267 ___This is strong and em.___
2269 So is ___this___ word.
2273 <p><strong><em>This is strong and em.</em></strong></p>
2274 <p>So is <strong><em>this</em></strong> word.</p>
2275 <p><strong><em>This is strong and em.</em></strong></p>
2276 <p>So is <strong><em>this</em></strong> word.</p>
2278 var res
= test
.md_to_html
.write_to_string
2282 fun test_daring_tabs
do
2284 + this is a list item
2287 + this is a list item
2288 indented with spaces
2292 this code block is indented by one tab
2296 this code block is indented by two tabs
2300 + this is an example list item
2303 + this is an example list item
2304 indented with spaces
2309 <li><p>this is a list item
2310 indented with tabs</p>
2312 <li><p>this is a list item
2313 indented with spaces</p>
2317 <pre><code>this code block is indented by one tab
2320 <pre><code> this code block is indented by two tabs
2323 <pre><code>+ this is an example list item
2326 + this is an example list item
2327 indented with spaces
2330 var res
= test
.md_to_html
.write_to_string
2334 fun test_daring_tidyness
do
2336 > A list within a blockquote:
2345 <p>A list within a blockquote:</p>
2353 var res
= test
.md_to_html
.write_to_string
2363 fun test_has_blocks
do
2364 var subject
= new MDBlock
2365 assert not subject
.has_blocks
2366 subject
.first_block
= new MDBlock
2367 assert subject
.has_blocks
2370 fun test_count_blocks
do
2371 var subject
= new MDBlock
2372 assert subject
.count_blocks
== 0
2373 subject
.first_block
= new MDBlock
2374 assert subject
.count_blocks
== 1
2375 subject
.first_block
.next
= new MDBlock
2376 assert subject
.count_blocks
== 2
2379 fun test_has_lines
do
2380 var subject
= new MDBlock
2381 assert not subject
.has_lines
2382 subject
.first_line
= new MDLine("")
2383 assert subject
.has_lines
2386 fun test_count_lines
do
2387 var subject
= new MDBlock
2388 assert subject
.count_lines
== 0
2389 subject
.first_line
= new MDLine("")
2390 assert subject
.count_lines
== 1
2391 subject
.first_line
.next
= new MDLine("")
2392 assert subject
.count_lines
== 2
2396 var line1
= new MDLine("line1")
2397 var line2
= new MDLine("line2")
2398 var line3
= new MDLine("line3")
2399 var subject
= new MDBlock
2400 subject
.add_line line1
2401 subject
.add_line line2
2402 subject
.add_line line3
2403 var block
= subject
.split
(line2
)
2404 assert subject
.count_blocks
== 1
2405 assert subject
.count_lines
== 1
2406 assert subject
.first_line
== line3
2407 assert block
.count_blocks
== 0
2408 assert block
.count_lines
== 2
2409 assert block
.first_line
== line1
2410 assert block
.last_line
== line2
2413 fun test_add_line
do
2414 var subject
= new MDBlock
2415 assert subject
.count_lines
== 0
2416 subject
.add_line
new MDLine("")
2417 assert subject
.count_lines
== 1
2418 subject
.add_line
new MDLine("")
2419 assert subject
.count_lines
== 2
2422 fun test_remove_line
do
2423 var line1
= new MDLine("line1")
2424 var line2
= new MDLine("line2")
2425 var line3
= new MDLine("line3")
2426 var subject
= new MDBlock
2427 subject
.add_line line1
2428 subject
.add_line line2
2429 subject
.add_line line3
2430 subject
.remove_line
(line2
)
2431 assert subject
.count_lines
== 2
2432 subject
.remove_line
(line1
)
2433 assert subject
.count_lines
== 1
2434 assert subject
.first_line
== line3
2435 assert subject
.last_line
== line3
2438 fun test_transform_headline1
do
2439 var subject
= new MDBlock
2440 var kind
= new BlockHeadline(subject
)
2441 subject
.add_line
new MDLine(" # Title 1 ")
2442 kind
.transform_headline
(subject
)
2443 assert kind
.depth
== 1
2444 assert subject
.first_line
.value
== "Title 1"
2447 fun test_transform_headline2
do
2448 var subject
= new MDBlock
2449 var kind
= new BlockHeadline(subject
)
2450 subject
.add_line
new MDLine(" #####Title 5 ")
2451 kind
.transform_headline
(subject
)
2452 assert kind
.depth
== 5
2453 assert subject
.first_line
.value
== "Title 5"
2456 fun test_remove_quote_prefix
do
2457 var subject
= new MDBlock
2458 var kind
= new BlockQuote(subject
)
2459 subject
.add_line
new MDLine(" > line 1")
2460 subject
.add_line
new MDLine(" > line 2")
2461 subject
.add_line
new MDLine(" > line 3")
2462 kind
.remove_block_quote_prefix
(subject
)
2463 assert subject
.first_line
.value
== "line 1"
2464 assert subject
.first_line
.next
.value
== "line 2"
2465 assert subject
.first_line
.next
.next
.value
== "line 3"
2468 fun test_remove_leading_empty_lines_1
do
2469 var block
= new MDBlock
2470 block
.add_line
new MDLine("")
2471 block
.add_line
new MDLine("")
2472 block
.add_line
new MDLine("")
2473 block
.add_line
new MDLine("")
2474 block
.add_line
new MDLine(" text")
2475 block
.add_line
new MDLine("")
2476 assert block
.remove_leading_empty_lines
2477 assert block
.first_line
.value
== " text"
2480 fun test_remove_leading_empty_lines_2
do
2481 var block
= new MDBlock
2482 block
.add_line
new MDLine(" text")
2483 block
.remove_leading_empty_lines
2484 assert block
.first_line
.value
== " text"
2487 fun test_remove_trailing_empty_lines_1
do
2488 var block
= new MDBlock
2489 block
.add_line
new MDLine("")
2490 block
.add_line
new MDLine("text")
2491 block
.add_line
new MDLine("")
2492 block
.add_line
new MDLine("")
2493 block
.add_line
new MDLine("")
2494 block
.add_line
new MDLine("")
2495 assert block
.remove_trailing_empty_lines
2496 assert block
.last_line
.value
== "text"
2499 fun test_remove_trailing_empty_lines_2
do
2500 var block
= new MDBlock
2501 block
.add_line
new MDLine("text ")
2502 assert not block
.remove_trailing_empty_lines
2503 assert block
.last_line
.value
== "text "
2506 fun test_remove_surrounding_empty_lines
do
2507 var block
= new MDBlock
2508 block
.add_line
new MDLine("")
2509 block
.add_line
new MDLine("text")
2510 block
.add_line
new MDLine("")
2511 block
.add_line
new MDLine("")
2512 block
.add_line
new MDLine("")
2513 block
.add_line
new MDLine("")
2514 assert block
.remove_surrounding_empty_lines
2515 assert block
.first_line
.value
== "text"
2516 assert block
.last_line
.value
== "text"
2527 fun test_is_empty
do
2528 subject
= new MDLine("")
2529 assert subject
.is_empty
2530 subject
= new MDLine(" ")
2531 assert subject
.is_empty
2532 subject
= new MDLine("test")
2533 assert not subject
.is_empty
2534 subject
= new MDLine(" test")
2535 assert not subject
.is_empty
2539 subject
= new MDLine("")
2540 assert subject
.leading
== 0
2541 subject
= new MDLine(" ")
2542 assert subject
.leading
== 4
2543 subject
= new MDLine("test")
2544 assert subject
.leading
== 0
2545 subject
= new MDLine(" test")
2546 assert subject
.leading
== 4
2549 fun test_trailing
do
2550 subject
= new MDLine("")
2551 assert subject
.trailing
== 0
2552 subject
= new MDLine(" ")
2553 assert subject
.trailing
== 0
2554 subject
= new MDLine("test ")
2555 assert subject
.trailing
== 3
2556 subject
= new MDLine(" test ")
2557 assert subject
.trailing
== 1
2560 fun test_line_type
do
2561 var v
= new MarkdownProcessor
2562 subject
= new MDLine("")
2563 assert v
.line_kind
(subject
) isa LineEmpty
2564 subject
= new MDLine(" ")
2565 assert v
.line_kind
(subject
) isa LineEmpty
2566 subject
= new MDLine("text ")
2567 assert v
.line_kind
(subject
) isa LineOther
2568 subject
= new MDLine(" # Title")
2569 assert v
.line_kind
(subject
) isa LineHeadline
2570 subject
= new MDLine(" ### Title")
2571 assert v
.line_kind
(subject
) isa LineHeadline
2572 subject
= new MDLine(" code")
2573 assert v
.line_kind
(subject
) isa LineCode
2574 subject
= new MDLine(" Title ")
2575 subject
.next
= new MDLine("== ")
2576 assert v
.line_kind
(subject
) isa LineHeadline1
2577 subject
= new MDLine(" Title ")
2578 subject
.next
= new MDLine("-- ")
2579 assert v
.line_kind
(subject
) isa LineHeadline2
2580 subject
= new MDLine(" * * * ")
2581 assert v
.line_kind
(subject
) isa LineHR
2582 subject
= new MDLine(" *** ")
2583 assert v
.line_kind
(subject
) isa LineHR
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 LineBlockquote
2590 subject
= new MDLine("<p></p>")
2591 assert v
.line_kind
(subject
) isa LineXML
2592 subject
= new MDLine("<p>")
2593 assert v
.line_kind
(subject
) isa LineOther
2594 subject
= new MDLine(" * foo")
2595 assert v
.line_kind
(subject
) isa LineUList
2596 subject
= new MDLine("- foo")
2597 assert v
.line_kind
(subject
) isa LineUList
2598 subject
= new MDLine("+ foo")
2599 assert v
.line_kind
(subject
) isa LineUList
2600 subject
= new MDLine("1. foo")
2601 assert v
.line_kind
(subject
) isa LineOList
2602 subject
= new MDLine(" 11111. foo")
2603 assert v
.line_kind
(subject
) isa LineOList
2606 fun test_line_type_ext
do
2607 var v
= new MarkdownProcessor
2608 subject
= new MDLine(" ~~~")
2609 assert v
.line_kind
(subject
) isa LineFence
2610 subject
= new MDLine(" ```")
2611 assert v
.line_kind
(subject
) isa LineFence
2614 fun test_count_chars
do
2615 subject
= new MDLine("")
2616 assert subject
.count_chars
('*') == 0
2617 subject
= new MDLine("* ")
2618 assert subject
.count_chars
('*') == 1
2619 subject
= new MDLine(" * text")
2620 assert subject
.count_chars
('*') == 0
2621 subject
= new MDLine(" * * *")
2622 assert subject
.count_chars
('*') == 3
2623 subject
= new MDLine("text ** ")
2624 assert subject
.count_chars
('*') == 0
2627 fun test_count_chars_start
do
2628 subject
= new MDLine("")
2629 assert subject
.count_chars_start
('*') == 0
2630 subject
= new MDLine("* ")
2631 assert subject
.count_chars_start
('*') == 1
2632 subject
= new MDLine(" * text")
2633 assert subject
.count_chars_start
('*') == 1
2634 subject
= new MDLine(" * * * text")
2635 assert subject
.count_chars_start
('*') == 3
2636 subject
= new MDLine("text ** ")
2637 assert subject
.count_chars_start
('*') == 0
2641 class TestHTMLDecorator
2644 fun test_headlines
do
2658 var proc
= new MarkdownProcessor
2659 var decorator
= proc
.emitter
.decorator
.as(HTMLDecorator)
2662 for id
, headline
in decorator
.headlines
do
2663 res
+= "{headline.title}:{id}\n"