summary refs log tree commit diff stats
path: root/tests/stdlib/trstgen.nim
diff options
context:
space:
mode:
authorAndrey Makarov <ph.makarov@gmail.com>2021-02-15 16:12:40 +0300
committerGitHub <noreply@github.com>2021-02-15 14:12:40 +0100
commit35bd39a9d0eef1396b2f6a562430ec63e36b7921 (patch)
treecf83fd97d39b7ae11663d965d6652603f2778247 /tests/stdlib/trstgen.nim
parent56f5010fa405018d40c4416ffe86bd3aaa1cb75a (diff)
downloadNim-35bd39a9d0eef1396b2f6a562430ec63e36b7921.tar.gz
RST: implement footnotes and citations (#16960)
* RST: implement footnotes and citations
* manual fixup of nimdoc.out.css
* remove unused code
* shorter printing code
* Update lib/packages/docutils/rst.nim

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
Diffstat (limited to 'tests/stdlib/trstgen.nim')
-rw-r--r--tests/stdlib/trstgen.nim208
1 files changed, 208 insertions, 0 deletions
diff --git a/tests/stdlib/trstgen.nim b/tests/stdlib/trstgen.nim
index 0f28fb4cc..03911f6d1 100644
--- a/tests/stdlib/trstgen.nim
+++ b/tests/stdlib/trstgen.nim
@@ -8,6 +8,9 @@ import ../../lib/packages/docutils/rstgen
 import ../../lib/packages/docutils/rst
 import unittest, strutils, strtabs
 
+proc toHtml(input: string): string =
+  rstToHtml(input, {roSupportMarkdown}, defaultConfig())
+
 suite "YAML syntax highlighting":
   test "Basics":
     let input = """.. code-block:: yaml
@@ -572,6 +575,203 @@ Test1
     doAssert count(output1, "<ul ") == 1
     doAssert count(output1, "</ul>") == 1
 
+  test "Nim RST footnotes and citations":
+    # check that auto-label footnote enumerated properly after a manual one
+    let input1 = dedent """
+      .. [1] Body1.
+      .. [#note] Body2
+
+      Ref. [#note]_
+      """
+    let output1 = input1.toHtml
+    doAssert output1.count(">[1]</a>") == 1
+    doAssert output1.count(">[2]</a>") == 2
+    doAssert "href=\"#footnote-note\"" in output1
+    doAssert ">[-1]" notin output1
+    doAssert "Body1." in output1
+    doAssert "Body2" in output1
+
+    # check that there are NO footnotes/citations, only comments:
+    let input2 = dedent """
+      .. [1 #] Body1.
+      .. [# note] Body2.
+      .. [wrong citation] That gives you a comment.
+
+      .. [not&allowed] That gives you a comment.
+
+      Not references[#note]_[1 #]_ [wrong citation]_ and [not&allowed]_.
+      """
+    let output2 = input2.toHtml
+    doAssert output2 == "Not references[#note]_[1 #]_ [wrong citation]_ and [not&amp;allowed]_. "
+
+    # check that auto-symbol footnotes work:
+    let input3 = dedent """
+      Ref. [*]_ and [*]_ and [*]_.
+
+      .. [*] Body1
+      .. [*] Body2.
+
+
+      .. [*] Body3.
+      .. [*] Body4
+
+      And [*]_.
+      """
+    let output3 = input3.toHtml
+    # both references and footnotes. Footnotes have link to themselves.
+    doAssert output3.count("href=\"#footnotesym-1\">[*]</a>") == 2
+    doAssert output3.count("href=\"#footnotesym-2\">[**]</a>") == 2
+    doAssert output3.count("href=\"#footnotesym-3\">[***]</a>") == 2
+    doAssert output3.count("href=\"#footnotesym-4\">[^]</a>") == 2
+    # footnote group
+    doAssert output3.count("<hr class=\"footnote\">" &
+                           "<div class=\"footnote-group\">") == 1
+    # footnotes
+    doAssert output3.count("<div class=\"footnote-label\"><sup><strong>" &
+               "<a href=\"#footnotesym-1\">[*]</a></strong></sup></div>") == 1
+    doAssert output3.count("<div class=\"footnote-label\"><sup><strong>" &
+               "<a href=\"#footnotesym-2\">[**]</a></strong></sup></div>") == 1
+    doAssert output3.count("<div class=\"footnote-label\"><sup><strong>" &
+               "<a href=\"#footnotesym-3\">[***]</a></strong></sup></div>") == 1
+    doAssert output3.count("<div class=\"footnote-label\"><sup><strong>" &
+               "<a href=\"#footnotesym-4\">[^]</a></strong></sup></div>") == 1
+    for i in 1 .. 4: doAssert ("Body" & $i) in output3
+
+    # check manual, auto-number and auto-label footnote enumeration
+    let input4 = dedent """
+      .. [3] Manual1.
+      .. [#] Auto-number1.
+      .. [#mylabel] Auto-label1.
+      .. [#note] Auto-label2.
+      .. [#] Auto-number2.
+
+      Ref. [#note]_ and [#]_ and [#]_.
+      """
+    let output4 = input4.toHtml
+    doAssert ">[-1]" notin output1
+    let order = @[
+        "footnote-3", "[3]", "Manual1.",
+        "footnoteauto-1", "[1]", "Auto-number1",
+        "footnote-mylabel", "[2]", "Auto-label1",
+        "footnote-note", "[4]", "Auto-label2",
+        "footnoteauto-2", "[5]", "Auto-number2",
+        ]
+    for i in 0 .. order.len-2:
+      let pos1 = output4.find(order[i])
+      let pos2 = output4.find(order[i+1])
+      doAssert pos1 >= 0
+      doAssert pos2 >= 0
+      doAssert pos1 < pos2
+
+    # forgot [#]_
+    let input5 = dedent """
+      .. [3] Manual1.
+      .. [#] Auto-number1.
+      .. [#note] Auto-label2.
+
+      Ref. [#note]_
+      """
+    # TODO: find out hot to configure proper exception instead of defect
+    expect(AssertionDefect):
+      let output5 = input5.toHtml
+
+    # extra [*]_
+    let input6 = dedent """
+      Ref. [*]_
+
+      .. [*] Auto-Symbol.
+
+      Ref. [*]_
+      """
+    expect(AssertionDefect):
+      let output6 = input6.toHtml
+
+    let input7 = dedent """
+      .. [Some:CITATION-2020] Citation.
+
+      Ref. [some:citation-2020]_.
+      """
+    let output7 = input7.toHtml
+    doAssert output7.count("href=\"#citation-somecoloncitationminus2020\"") == 2
+    doAssert output7.count("[Some:CITATION-2020]") == 1
+    doAssert output7.count("[some:citation-2020]") == 1
+    doAssert output3.count("<hr class=\"footnote\">" &
+                           "<div class=\"footnote-group\">") == 1
+
+    let input8 = dedent """
+      .. [Some] Citation.
+
+      Ref. [som]_.
+      """
+    expect(AssertionDefect):
+      let output8 = input8.toHtml
+
+    # check that footnote group does not break parsing of other directives:
+    let input9 = dedent """
+      .. [Some] Citation.
+
+      .. _`internal anchor`:
+
+      .. [Another] Citation.
+      .. just comment.
+      .. [Third] Citation.
+
+      Paragraph1.
+
+      Paragraph2 ref `internal anchor`_.
+      """
+    let output9 = input9.toHtml
+    #doAssert "id=\"internal-anchor\"" in output9
+    #doAssert "internal anchor" notin output9
+    doAssert output9.count("<hr class=\"footnote\">" &
+                           "<div class=\"footnote-group\">") == 1
+    doAssert output9.count("<div class=\"footnote-label\">") == 3
+    doAssert "just comment" notin output9
+
+    # check that nested citations/footnotes work
+    let input10 = dedent """
+      Paragraph1 [#]_.
+
+      .. [First] Citation.
+
+         .. [#] Footnote.
+
+            .. [Third] Citation.
+      """
+    let output10 = input10.toHtml
+    doAssert output10.count("<hr class=\"footnote\">" &
+                            "<div class=\"footnote-group\">") == 3
+    doAssert output10.count("<div class=\"footnote-label\">") == 3
+    doAssert "<a href=\"#citation-first\">[First]</a>" in output10
+    doAssert "<a href=\"#footnoteauto-1\">[1]</a>" in output10
+    doAssert "<a href=\"#citation-third\">[Third]</a>" in output10
+
+    let input11 = ".. [note]\n"  # should not crash
+    let output11 = input11.toHtml
+    doAssert "<a href=\"#citation-note\">[note]</a>" in output11
+
+    # check that references to auto-numbered footnotes work
+    let input12 = dedent """
+      Ref. [#]_ and [#]_ STOP.
+
+      .. [#] Body1.
+      .. [#] Body3
+      .. [2] Body2.
+      """
+    let output12 = input12.toHtml
+    let orderAuto = @[
+        "#footnoteauto-1", "[1]",
+        "#footnoteauto-2", "[3]",
+        "STOP.",
+        "Body1.", "Body3", "Body2."
+        ]
+    for i in 0 .. orderAuto.len-2:
+      let pos1 = output12.find(orderAuto[i])
+      let pos2 = output12.find(orderAuto[i+1])
+      doAssert pos1 >= 0
+      doAssert pos2 >= 0
+      doAssert pos1 < pos2
+
   test "Nim (RST extension) code-block":
     # check that presence of fields doesn't consume the following text as
     # its code (which is a literal block)
@@ -760,6 +960,13 @@ Test1
       -----------
 
       Ref. target300_ and target301_.
+
+      .. _target103:
+
+      .. [cit2020] note.
+
+      Ref. target103_.
+
     """
     let output2 = rstToHtml(input2, {roSupportMarkdown}, defaultConfig())
     # "target101" should be erased and changed to "section-xyz":
@@ -772,6 +979,7 @@ Test1
     # links should preserve their original names but point to section labels:
     doAssert "href=\"#section-xyz\">target300" 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