trstgen.nim 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. discard """
  2. outputsub: ""
  3. """
  4. # tests for rstgen module.
  5. import ../../lib/packages/docutils/rstgen
  6. import ../../lib/packages/docutils/rst
  7. import unittest, strutils, strtabs
  8. suite "YAML syntax highlighting":
  9. test "Basics":
  10. let input = """.. code-block:: yaml
  11. %YAML 1.2
  12. ---
  13. a string: string
  14. a list:
  15. - item 1
  16. - item 2
  17. a map:
  18. ? key
  19. : value
  20. ..."""
  21. let output = rstTohtml(input, {}, defaultConfig())
  22. assert output == """<pre class = "listing"><span class="Directive">%YAML 1.2</span>
  23. <span class="Keyword">---</span>
  24. <span class="StringLit">a string</span><span class="Punctuation">:</span> <span class="StringLit">string</span>
  25. <span class="StringLit">a list</span><span class="Punctuation">:</span>
  26. <span class="Punctuation">-</span> <span class="StringLit">item 1</span>
  27. <span class="Punctuation">-</span> <span class="StringLit">item 2</span>
  28. <span class="StringLit">a map</span><span class="Punctuation">:</span>
  29. <span class="Punctuation">?</span> <span class="StringLit">key</span>
  30. <span class="Punctuation">:</span> <span class="StringLit">value</span>
  31. <span class="Keyword">...</span></pre>"""
  32. test "Block scalars":
  33. let input = """.. code-block:: yaml
  34. a literal block scalar: |
  35. some text
  36. # not a comment
  37. # a comment, since less indented
  38. # another comment
  39. a folded block scalar: >2
  40. some text
  41. # not a comment since indented as specified
  42. # a comment
  43. another literal block scalar:
  44. |+ # comment after header
  45. allowed, since more indented than parent"""
  46. let output = rstToHtml(input, {}, defaultConfig())
  47. assert output == """<pre class = "listing"><span class="StringLit">a literal block scalar</span><span class="Punctuation">:</span> <span class="Command">|</span><span class="Command"></span><span class="LongStringLit">
  48. some text
  49. # not a comment
  50. </span><span class="Comment"># a comment, since less indented</span>
  51. <span class="Comment"># another comment</span>
  52. <span class="StringLit">a folded block scalar</span><span class="Punctuation">:</span> <span class="Command">&gt;2</span><span class="Command"></span><span class="LongStringLit">
  53. some text
  54. # not a comment since indented as specified
  55. </span><span class="Comment"># a comment</span>
  56. <span class="StringLit">another literal block scalar</span><span class="Punctuation">:</span>
  57. <span class="Command">|+</span> <span class="Comment"># comment after header</span><span class="LongStringLit">
  58. allowed, since more indented than parent</span></pre>"""
  59. test "Directives":
  60. let input = """.. code-block:: yaml
  61. %YAML 1.2
  62. ---
  63. %not a directive
  64. ...
  65. %a directive
  66. ...
  67. a string
  68. % not a directive
  69. ...
  70. %TAG ! !foo:"""
  71. let output = rstToHtml(input, {}, defaultConfig())
  72. assert output == """<pre class = "listing"><span class="Directive">%YAML 1.2</span>
  73. <span class="Keyword">---</span>
  74. <span class="StringLit">%not a directive</span>
  75. <span class="Keyword">...</span>
  76. <span class="Directive">%a directive</span>
  77. <span class="Keyword">...</span>
  78. <span class="StringLit">a string</span>
  79. <span class="StringLit">% not a directive</span>
  80. <span class="Keyword">...</span>
  81. <span class="Directive">%TAG ! !foo:</span></pre>"""
  82. test "Flow Style and Numbers":
  83. let input = """.. code-block:: yaml
  84. {
  85. "quoted string": 42,
  86. 'single quoted string': false,
  87. [ list, "with", 'entries' ]: 73.32e-73,
  88. more numbers: [-783, 11e78],
  89. not numbers: [ 42e, 0023, +32.37, 8 ball]
  90. }"""
  91. let output = rstToHtml(input, {}, defaultConfig())
  92. assert output == """<pre class = "listing"><span class="Punctuation">{</span>
  93. <span class="StringLit">&quot;</span><span class="StringLit">quoted string&quot;</span><span class="Punctuation">:</span> <span class="DecNumber">42</span><span class="Punctuation">,</span>
  94. <span class="StringLit">'single quoted string'</span><span class="Punctuation">:</span> <span class="StringLit">false</span><span class="Punctuation">,</span>
  95. <span class="Punctuation">[</span> <span class="StringLit">list</span><span class="Punctuation">,</span> <span class="StringLit">&quot;</span><span class="StringLit">with&quot;</span><span class="Punctuation">,</span> <span class="StringLit">'entries'</span> <span class="Punctuation">]</span><span class="Punctuation">:</span> <span class="FloatNumber">73.32e-73</span><span class="Punctuation">,</span>
  96. <span class="StringLit">more numbers</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="DecNumber">-783</span><span class="Punctuation">,</span> <span class="FloatNumber">11e78</span><span class="Punctuation">]</span><span class="Punctuation">,</span>
  97. <span class="StringLit">not numbers</span><span class="Punctuation">:</span> <span class="Punctuation">[</span> <span class="StringLit">42e</span><span class="Punctuation">,</span> <span class="StringLit">0023</span><span class="Punctuation">,</span> <span class="StringLit">+32.37</span><span class="Punctuation">,</span> <span class="StringLit">8 ball</span><span class="Punctuation">]</span>
  98. <span class="Punctuation">}</span></pre>"""
  99. test "Anchors, Aliases, Tags":
  100. let input = """.. code-block:: yaml
  101. --- !!map
  102. !!str string: !<tag:yaml.org,2002:int> 42
  103. ? &anchor !!seq []:
  104. : !localtag foo
  105. alias: *anchor
  106. """
  107. let output = rstToHtml(input, {}, defaultConfig())
  108. assert output == """<pre class = "listing"><span class="Keyword">---</span> <span class="TagStart">!!map</span>
  109. <span class="TagStart">!!str</span> <span class="StringLit">string</span><span class="Punctuation">:</span> <span class="TagStart">!&lt;tag:yaml.org,2002:int&gt;</span> <span class="DecNumber">42</span>
  110. <span class="Punctuation">?</span> <span class="Label">&amp;anchor</span> <span class="TagStart">!!seq</span> <span class="Punctuation">[</span><span class="Punctuation">]</span><span class="Punctuation">:</span>
  111. <span class="Punctuation">:</span> <span class="TagStart">!localtag</span> <span class="StringLit">foo</span>
  112. <span class="StringLit">alias</span><span class="Punctuation">:</span> <span class="Reference">*anchor</span></pre>"""
  113. test "Edge cases":
  114. let input = """.. code-block:: yaml
  115. ...
  116. %a string:
  117. a:string:not:a:map
  118. ...
  119. not a list:
  120. -2
  121. -3
  122. -4
  123. example.com/not/a#comment:
  124. ?not a map key
  125. """
  126. let output = rstToHtml(input, {}, defaultConfig())
  127. assert output == """<pre class = "listing"><span class="Keyword">...</span>
  128. <span class="StringLit">%a string</span><span class="Punctuation">:</span>
  129. <span class="StringLit">a:string:not:a:map</span>
  130. <span class="Keyword">...</span>
  131. <span class="StringLit">not a list</span><span class="Punctuation">:</span>
  132. <span class="DecNumber">-2</span>
  133. <span class="DecNumber">-3</span>
  134. <span class="DecNumber">-4</span>
  135. <span class="StringLit">example.com/not/a#comment</span><span class="Punctuation">:</span>
  136. <span class="StringLit">?not a map key</span></pre>"""
  137. suite "RST/Markdown general":
  138. test "RST emphasis":
  139. assert rstToHtml("*Hello* **world**!", {},
  140. newStringTable(modeStyleInsensitive)) ==
  141. "<em>Hello</em> <strong>world</strong>!"
  142. test "Markdown links":
  143. let
  144. a = rstToHtml("(( [Nim](https://nim-lang.org/) ))", {roSupportMarkdown}, defaultConfig())
  145. b = rstToHtml("(([Nim](https://nim-lang.org/)))", {roSupportMarkdown}, defaultConfig())
  146. c = rstToHtml("[[Nim](https://nim-lang.org/)]", {roSupportMarkdown}, defaultConfig())
  147. assert a == """(( <a class="reference external" href="https://nim-lang.org/">Nim</a> ))"""
  148. assert b == """((<a class="reference external" href="https://nim-lang.org/">Nim</a>))"""
  149. assert c == """[<a class="reference external" href="https://nim-lang.org/">Nim</a>]"""
  150. test "Markdown tables":
  151. let input1 = """
  152. | A1 header | A2 \| not fooled
  153. | :--- | ----: |
  154. | C1 | C2 **bold** | ignored |
  155. | D1 `code \|` | D2 | also ignored
  156. | E1 \| text |
  157. | | F2 without pipe
  158. not in table"""
  159. let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
  160. assert output1 == """<table border="1" class="docutils"><tr><th>A1 header</th><th>A2 | not fooled</th></tr>
  161. <tr><td>C1</td><td>C2 <strong>bold</strong></td></tr>
  162. <tr><td>D1 <tt class="docutils literal"><span class="pre">code |</span></tt></td><td>D2</td></tr>
  163. <tr><td>E1 | text</td><td></td></tr>
  164. <tr><td></td><td>F2 without pipe</td></tr>
  165. </table><p>not in table</p>
  166. """
  167. let input2 = """
  168. | A1 header | A2 |
  169. | --- | --- |"""
  170. let output2 = rstToHtml(input2, {roSupportMarkdown}, defaultConfig())
  171. assert output2 == """<table border="1" class="docutils"><tr><th>A1 header</th><th>A2</th></tr>
  172. </table>"""
  173. test "RST tables":
  174. let input1 = """
  175. Test 2 column/4 rows table:
  176. ==== ===
  177. H0 H1
  178. ==== ===
  179. A0 A1
  180. ==== ===
  181. A2 A3
  182. ==== ===
  183. A4 A5
  184. ==== === """
  185. let output1 = rstToLatex(input1, {})
  186. assert "{|X|X|}" in output1 # 2 columns
  187. assert count(output1, "\\\\") == 4 # 4 rows
  188. for cell in ["H0", "H1", "A0", "A1", "A2", "A3", "A4", "A5"]:
  189. assert cell in output1
  190. let input2 = """
  191. Now test 3 columns / 2 rows, and also borders containing 4 =, 3 =, 1 = signs:
  192. ==== === =
  193. H0 H1 H
  194. ==== === =
  195. A0 A1 X
  196. Ax Y
  197. ==== === = """
  198. let output2 = rstToLatex(input2, {})
  199. assert "{|X|X|X|}" in output2 # 3 columns
  200. assert count(output2, "\\\\") == 2 # 2 rows
  201. for cell in ["H0", "H1", "H", "A0", "A1", "X", "Ax", "Y"]:
  202. assert cell in output2
  203. test "RST adornments":
  204. let input1 = """
  205. Check that a few punctuation symbols are not parsed as adornments:
  206. :word1: word2 .... word3 """
  207. let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
  208. discard output1
  209. test "RST sections":
  210. let input1 = """
  211. Long chapter name
  212. '''''''''''''''''''
  213. """
  214. let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
  215. assert "Long chapter name" in output1 and "<h1" in output1
  216. let input2 = """
  217. Short chapter name:
  218. ChA
  219. ===
  220. """
  221. let output2 = rstToHtml(input2, {roSupportMarkdown}, defaultConfig())
  222. assert "ChA" in output2 and "<h1" in output2
  223. let input3 = """
  224. Very short chapter name:
  225. X
  226. ~
  227. """
  228. let output3 = rstToHtml(input3, {roSupportMarkdown}, defaultConfig())
  229. assert "X" in output3 and "<h1" in output3
  230. let input4 = """
  231. Check that short underline is not enough to make section:
  232. Wrong chapter
  233. ------------
  234. """
  235. let output4 = rstToHtml(input4, {roSupportMarkdown}, defaultConfig())
  236. assert "Wrong chapter" in output4 and "<h1" notin output4
  237. let input5 = """
  238. Check that punctuation after adornment and indent are not detected as adornment.
  239. Some chapter
  240. --------------
  241. "punctuation symbols" """
  242. let output5 = rstToHtml(input5, {roSupportMarkdown}, defaultConfig())
  243. assert "&quot;punctuation symbols&quot;" in output5 and "<h1" in output5
  244. test "RST links":
  245. let input1 = """
  246. Want to learn about `my favorite programming language`_?
  247. .. _my favorite programming language: https://nim-lang.org"""
  248. let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
  249. assert "<a" in output1 and "href=\"https://nim-lang.org\"" in output1
  250. test "RST transitions":
  251. let input1 = """
  252. context1
  253. ~~~~
  254. context2
  255. """
  256. let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
  257. assert "<hr" in output1
  258. let input2 = """
  259. This is too short to be a transition:
  260. ---
  261. context2
  262. """
  263. let output2 = rstToHtml(input2, {roSupportMarkdown}, defaultConfig())
  264. assert "<hr" notin output2
  265. test "RST literal block":
  266. let input1 = """
  267. Test literal block
  268. ::
  269. check """
  270. let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
  271. assert "<pre>" in output1
  272. test "Markdown code block":
  273. let input1 = """
  274. ```
  275. let x = 1
  276. ``` """
  277. let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
  278. assert "<pre" in output1 and "class=\"Keyword\"" notin output1
  279. let input2 = """
  280. Parse the block with language specifier:
  281. ```Nim
  282. let x = 1
  283. ``` """
  284. let output2 = rstToHtml(input2, {roSupportMarkdown}, defaultConfig())
  285. assert "<pre" in output2 and "class=\"Keyword\"" in output2
  286. test "RST comments":
  287. let input1 = """
  288. Check that comment disappears:
  289. ..
  290. some comment """
  291. let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
  292. assert output1 == "Check that comment disappears:"
  293. test "RST line blocks":
  294. let input1 = """
  295. =====
  296. Test1
  297. =====
  298. |
  299. |
  300. | line block
  301. | other line
  302. """
  303. var option: bool
  304. var rstGenera: RstGenerator
  305. var output1: string
  306. rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", {})
  307. rstGenera.renderRstToOut(rstParse(input1, "", 1, 1, option, {}), output1)
  308. assert rstGenera.meta[metaTitle] == "Test1"
  309. # check that title was not overwritten to '|'
  310. assert "line block<br />" in output1
  311. assert "other line<br />" in output1
  312. let output1l = rstToLatex(input1, {})
  313. assert "line block\\\\" in output1l
  314. assert "other line\\\\" in output1l