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>
This commit is contained in:
parent
56f5010fa4
commit
35bd39a9d0
9 changed files with 656 additions and 36 deletions
|
|
@ -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&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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue