discard """ outputsub: "" """ # tests for rstgen module. import ../../lib/packages/docutils/rstgen import ../../lib/packages/docutils/rst import unittest, strutils, strtabs import std/private/miscdollars proc toHtml(input: string, rstOptions: RstParseOptions = {roSupportMarkdown}, error: ref string = nil, warnings: ref seq[string] = nil): string = ## If `error` is nil then no errors should be generated. ## The same goes for `warnings`. proc testMsgHandler(filename: string, line, col: int, msgkind: MsgKind, arg: string) = let mc = msgkind.whichMsgClass let a = $msgkind % arg var message: string toLocation(message, filename, line, col + ColRstOffset) message.add " $1: $2" % [$mc, a] if mc == mcError: doAssert error != nil, "unexpected RST error '" & message & "'" error[] = message # we check only first error because subsequent ones may be meaningless raise newException(EParseError, message) else: doAssert warnings != nil, "unexpected RST warning '" & message & "'" warnings[].add message try: result = rstToHtml(input, rstOptions, defaultConfig(), msgHandler=testMsgHandler) except EParseError: discard suite "YAML syntax highlighting": test "Basics": let input = """.. code-block:: yaml %YAML 1.2 --- a string: string a list: - item 1 - item 2 a map: ? key : value ...""" let output = input.toHtml({}) doAssert output == """
%YAML 1.2 --- a string: string a list: - item 1 - item 2 a map: ? key : value ...""" test "Block scalars": let input = """.. code-block:: yaml a literal block scalar: | some text # not a comment # a comment, since less indented # another comment a folded block scalar: >2 some text # not a comment since indented as specified # a comment another literal block scalar: |+ # comment after header allowed, since more indented than parent""" let output = input.toHtml({}) doAssert output == """
a literal block scalar: | some text # not a comment # a comment, since less indented # another comment a folded block scalar: >2 some text # not a comment since indented as specified # a comment another literal block scalar: |+ # comment after header allowed, since more indented than parent""" test "Directives": let input = """.. code-block:: yaml %YAML 1.2 --- %not a directive ... %a directive ... a string % not a directive ... %TAG ! !foo:""" let output = input.toHtml({}) doAssert output == """
%YAML 1.2 --- %not a directive ... %a directive ... a string % not a directive ... %TAG ! !foo:""" test "Flow Style and Numbers": let input = """.. code-block:: yaml { "quoted string": 42, 'single quoted string': false, [ list, "with", 'entries' ]: 73.32e-73, more numbers: [-783, 11e78], not numbers: [ 42e, 0023, +32.37, 8 ball] }""" let output = input.toHtml({}) doAssert output == """
{ "quoted string": 42, 'single quoted string': false, [ list, "with", 'entries' ]: 73.32e-73, more numbers: [-783, 11e78], not numbers: [ 42e, 0023, +32.37, 8 ball] }""" test "Anchors, Aliases, Tags": let input = """.. code-block:: yaml --- !!map !!str string: !
--- !!map !!str string: !<tag:yaml.org,2002:int> 42 ? &anchor !!seq []: : !localtag foo alias: *anchor""" test "Edge cases": let input = """.. code-block:: yaml ... %a string: a:string:not:a:map ... not a list: -2 -3 -4 example.com/not/a#comment: ?not a map key """ let output = input.toHtml({}) doAssert output == """
... %a string: a:string:not:a:map ... not a list: -2 -3 -4 example.com/not/a#comment: ?not a map key""" suite "RST/Markdown general": test "RST emphasis": doAssert rstToHtml("*Hello* **world**!", {}, newStringTable(modeStyleInsensitive)) == "Hello world!" test "Markdown links": check("(( [Nim](https://nim-lang.org/) ))".toHtml == """(( Nim ))""") check("(([Nim](https://nim-lang.org/)))".toHtml == """((Nim))""") check("[[Nim](https://nim-lang.org/)]".toHtml == """[Nim]""") test "Markdown tables": let input1 = """ | A1 header | A2 \| not fooled | :--- | ----: | | C1 | C2 **bold** | ignored | | D1 `code \|` | D2 | also ignored | E1 \| text | | | F2 without pipe not in table""" let output1 = input1.toHtml doAssert output1 == """
A1 header | A2 | not fooled |
---|---|
C1 | C2 bold |
D1 code | | D2 |
E1 | text | |
F2 without pipe |
not in table
""" let input2 = """ | A1 header | A2 | | --- | --- |""" let output2 = input2.toHtml doAssert output2 == """A1 header | A2 |
---|
line block
other line
" let output1l = rstToLatex(input1, {}) doAssert "line block\n\n" in output1l doAssert "other line\n\n" in output1l doAssert output1l.count("\\vspace") == 2 + 2 # +2 surrounding paddings let input2 = dedent""" Paragraph1 | Paragraph2""" let output2 = input2.toHtml doAssert "Paragraph1
Paragraph2
\n" == output2 let input3 = dedent""" | xxx | yyy | zzz""" let output3 = input3.toHtml doAssert "xxx
" in output3 doAssert "yyy
" in output3 doAssert "zzz
" in output3 # check that '| ' with a few spaces is still parsed as new line let input4 = dedent""" | xxx | | zzz""" let output4 = input4.toHtml doAssert "xxx
" in output4 doAssert "zzz
" in output4 test "RST enumerated lists": let input1 = dedent """ 1. line1 1 2. line2 2 3. line3 3 4. line4 4 5. line5 5 """ let output1 = input1.toHtml for i in 1..5: doAssert ($i & ". line" & $i) notin output1 doAssert ("
C. string1 string2
\n" test "Markdown enumerated lists": let input1 = dedent """ Below are 2 enumerated lists: Markdown-style (5 items) and RST (1 item) 1. line1 1. line2 1. line3 1. line4 1. line5 #. lineA """ let output1 = input1.toHtml for i in 1..5: doAssert ($i & ". line" & $i) notin output1 doAssert ("Paragraph1
" in output0 test "RST admonitions": # check that all admonitions are implemented let input0 = dedent """ .. admonition:: endOf admonition .. attention:: endOf attention .. caution:: endOf caution .. danger:: endOf danger .. error:: endOf error .. hint:: endOf hint .. important:: endOf important .. note:: endOf note .. tip:: endOf tip .. warning:: endOf warning """ let output0 = input0.toHtml for a in ["admonition", "attention", "caution", "danger", "error", "hint", "important", "note", "tip", "warning" ]: doAssert "endOf " & a & "Test paragraph.
" in output1 doAssert "class=\"admonition admonition-error\"" in output1 # Test that second line is parsed as continuation of the first line. let input2 = dedent """ .. error:: endOfError Test2p. Test paragraph. """ let output2 = input2.toHtml doAssert "endOfError Test2p.Test paragraph.
" in output2 doAssert "class=\"admonition admonition-error\"" in output2 let input3 = dedent """ .. note:: endOfNote """ let output3 = input3.toHtml doAssert "endOfNotetarget300" in output2 doAssert "href=\"#subsectiona\">target301" in output2 doAssert "href=\"#citation-cit2020\">target103" in output2 let output2l = rstToLatex(input2, {}) doAssert "\\label{section-xyz}\\hypertarget{section-xyz}{}" in output2l doAssert "\\hyperlink{section-xyz}{target300}" in output2l doAssert "\\hyperlink{subsectiona}{target301}" in output2l test "RST internal links (inline)": let input1 = dedent """ Paragraph with _`some definition`. Ref. `some definition`_. """ let output1 = input1.toHtml doAssert "some definition" in output1 doAssert "Ref. some definition" in output1 test "RST references (additional symbols)": # check that ., _, -, +, : are allowed symbols in references without ` ` let input1 = dedent """ sec.1 ----- 2-other:sec+c_2 ^^^^^^^^^^^^^^^ .. _link.1_2021: Paragraph Ref. sec.1_! and 2-other:sec+c_2_;and link.1_2021_. """ let output1 = input1.toHtml doAssert "id=\"secdot1\"" in output1 doAssert "id=\"Z2minusothercolonsecplusc-2\"" in output1 doAssert "id=\"linkdot1-2021\"" in output1 let ref1 = "sec.1" let ref2 = "2-other:sec+c_2" let ref3 = "link.1_2021" let refline = "Ref. " & ref1 & "! and " & ref2 & ";and " & ref3 & "." doAssert refline in output1 suite "RST/Code highlight": test "Basic Python code highlight": let pythonCode = """ .. code-block:: python def f_name(arg=42): print(f"{arg}") """ let expected = """
""" check strip(rstToHtml(pythonCode, {}, newStringTable(modeCaseSensitive))) == strip(expected)def f_name(arg=42): print(f"{arg}")