mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-27 09:43:58 +00:00
rst: add missing line/column info for some warnings (#18383)
* rst: add missing line/column info for some warnings * add workaround * use TLineInfo/FileIndex for storing file names * fix blank lines in include file (rm harmful strip) * don't use ref TLineInfo * return `hasToc` as output parameter for uniformity * Update compiler/docgen.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * Update compiler/docgen.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * Update lib/packages/docutils/rst.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * address review - stylistic things * Update compiler/docgen.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * unify RST warnings/errors names * doAssert + minor name change * fix a bug caught by doAssert * apply strbasics.strip to final HTML/Latex * rm redundant filename * fix test after rebase * delete `order` from rnFootnoteRef, also display errors/warnings properly when footnote references are from different files * Update compiler/lineinfos.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * Update lib/packages/docutils/rstast.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * Update lib/packages/docutils/rstast.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * Update lib/packages/docutils/rstast.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * revert because of error: Error: cannot prove that it's safe to initialize 'info' with the runtime value for the discriminator 'kind' * Update lib/packages/docutils/rstgen.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * apply suggestion * Update lib/packages/docutils/rst.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * add Table for string->file name mapping * do not import compiler/lineinfos * fix ambiguous calls Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> Co-authored-by: narimiran <narimiran@disroot.org>
This commit is contained in:
@@ -5,6 +5,8 @@ discard """
|
||||
|
||||
[Suite] RST indentation
|
||||
|
||||
[Suite] Warnings
|
||||
|
||||
[Suite] RST include directive
|
||||
|
||||
[Suite] RST escaping
|
||||
@@ -51,9 +53,8 @@ proc toAst(input: string,
|
||||
# we don't find any files in online mode:
|
||||
result = ""
|
||||
|
||||
var dummyHasToc = false
|
||||
var rst = rstParse(input, filen, line=LineRstInit, column=ColRstInit,
|
||||
dummyHasToc, rstOptions, myFindFile, testMsgHandler)
|
||||
var (rst, _, _) = rstParse(input, filen, line=LineRstInit, column=ColRstInit,
|
||||
rstOptions, myFindFile, testMsgHandler)
|
||||
result = renderRstToStr(rst)
|
||||
except EParseError as e:
|
||||
if e.msg != "":
|
||||
@@ -356,6 +357,53 @@ suite "RST indentation":
|
||||
# "template..." should be parsed as a definition list attached to ":test:":
|
||||
check inputWrong.toAst != ast
|
||||
|
||||
suite "Warnings":
|
||||
test "warnings for broken footnotes/links/substitutions":
|
||||
let input = dedent"""
|
||||
firstParagraph
|
||||
|
||||
footnoteRef [som]_
|
||||
|
||||
link `a broken Link`_
|
||||
|
||||
substitution |undefined subst|
|
||||
|
||||
link short.link_
|
||||
|
||||
lastParagraph
|
||||
"""
|
||||
var warnings = new seq[string]
|
||||
let output = input.toAst(warnings=warnings)
|
||||
check(warnings[] == @[
|
||||
"input(3, 14) Warning: broken link 'citation-som'",
|
||||
"input(5, 7) Warning: broken link 'a-broken-link'",
|
||||
"input(7, 15) Warning: unknown substitution 'undefined subst'",
|
||||
"input(9, 6) Warning: broken link 'shortdotlink'"
|
||||
])
|
||||
|
||||
test "With include directive and blank lines at the beginning":
|
||||
"other.rst".writeFile(dedent"""
|
||||
|
||||
|
||||
firstParagraph
|
||||
|
||||
here brokenLink_""")
|
||||
let input = ".. include:: other.rst"
|
||||
var warnings = new seq[string]
|
||||
let output = input.toAst(warnings=warnings)
|
||||
check warnings[] == @["other.rst(5, 6) Warning: broken link 'brokenlink'"]
|
||||
check(output == dedent"""
|
||||
rnInner
|
||||
rnParagraph
|
||||
rnLeaf 'firstParagraph'
|
||||
rnParagraph
|
||||
rnLeaf 'here'
|
||||
rnLeaf ' '
|
||||
rnRef
|
||||
rnLeaf 'brokenLink'
|
||||
""")
|
||||
removeFile("other.rst")
|
||||
|
||||
suite "RST include directive":
|
||||
test "Include whole":
|
||||
"other.rst".writeFile("**test1**")
|
||||
@@ -374,7 +422,7 @@ OtherStart
|
||||
.. include:: other.rst
|
||||
:start-after: OtherStart
|
||||
"""
|
||||
doAssert "<em>Visible</em>" == rstTohtml(input, {}, defaultConfig())
|
||||
check "<em>Visible</em>" == rstTohtml(input, {}, defaultConfig())
|
||||
removeFile("other.rst")
|
||||
|
||||
test "Include everything before":
|
||||
@@ -406,7 +454,7 @@ And this should **NOT** be visible in `docs.html`
|
||||
:start-after: OtherStart
|
||||
:end-before: OtherEnd
|
||||
"""
|
||||
doAssert "<em>Visible</em>" == rstTohtml(input, {}, defaultConfig())
|
||||
check "<em>Visible</em>" == rstTohtml(input, {}, defaultConfig())
|
||||
removeFile("other.rst")
|
||||
|
||||
|
||||
|
||||
@@ -237,8 +237,7 @@ not in table"""
|
||||
<tr><td>D1 <tt class="docutils literal"><span class="pre">""" & id"code" & " " & op"\|" & """</span></tt></td><td>D2</td></tr>
|
||||
<tr><td>E1 | text</td><td></td></tr>
|
||||
<tr><td></td><td>F2 without pipe</td></tr>
|
||||
</table><p>not in table</p>
|
||||
""")
|
||||
</table><p>not in table</p>""")
|
||||
let input2 = """
|
||||
| A1 header | A2 |
|
||||
| --- | --- |"""
|
||||
@@ -420,9 +419,10 @@ Some chapter
|
||||
"the following intermediate section level(s) are missing on " &
|
||||
"lines 12..15: underline -----)")
|
||||
|
||||
test "RST sections overline":
|
||||
# the same as input9good but with overline headings
|
||||
# first overline heading has a special meaning: document title
|
||||
let input10 = dedent """
|
||||
let input = dedent """
|
||||
======
|
||||
Title0
|
||||
======
|
||||
@@ -454,22 +454,23 @@ Some chapter
|
||||
~~~~~
|
||||
|
||||
"""
|
||||
var option: bool
|
||||
var rstGenera: RstGenerator
|
||||
var output10: string
|
||||
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", {})
|
||||
rstGenera.renderRstToOut(rstParse(input10, "", 1, 1, option, {}), output10)
|
||||
var output: string
|
||||
let (rst, files, _) = rstParse(input, "", 1, 1, {})
|
||||
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", filenames = files)
|
||||
rstGenera.renderRstToOut(rst, output)
|
||||
doAssert rstGenera.meta[metaTitle] == "Title0"
|
||||
doAssert rstGenera.meta[metaSubTitle] == "SubTitle0"
|
||||
doAssert "<h1 id=\"level1\"><center>Level1</center></h1>" in output10
|
||||
doAssert "<h2 id=\"level2\">Level2</h2>" in output10
|
||||
doAssert "<h3 id=\"level3\"><center>Level3</center></h3>" in output10
|
||||
doAssert "<h1 id=\"l1\"><center>L1</center></h1>" in output10
|
||||
doAssert "<h2 id=\"another2\">Another2</h2>" in output10
|
||||
doAssert "<h3 id=\"more3\"><center>More3</center></h3>" in output10
|
||||
doAssert "<h1 id=\"level1\"><center>Level1</center></h1>" in output
|
||||
doAssert "<h2 id=\"level2\">Level2</h2>" in output
|
||||
doAssert "<h3 id=\"level3\"><center>Level3</center></h3>" in output
|
||||
doAssert "<h1 id=\"l1\"><center>L1</center></h1>" in output
|
||||
doAssert "<h2 id=\"another2\">Another2</h2>" in output
|
||||
doAssert "<h3 id=\"more3\"><center>More3</center></h3>" in output
|
||||
|
||||
test "RST sections overline 2":
|
||||
# check that a paragraph prevents interpreting overlines as document titles
|
||||
let input11 = dedent """
|
||||
let input = dedent """
|
||||
Paragraph
|
||||
|
||||
======
|
||||
@@ -480,18 +481,19 @@ Some chapter
|
||||
SubTitle0
|
||||
+++++++++
|
||||
"""
|
||||
var option11: bool
|
||||
var rstGenera11: RstGenerator
|
||||
var output11: string
|
||||
rstGenera11.initRstGenerator(outHtml, defaultConfig(), "input", {})
|
||||
rstGenera11.renderRstToOut(rstParse(input11, "", 1, 1, option11, {}), output11)
|
||||
doAssert rstGenera11.meta[metaTitle] == ""
|
||||
doAssert rstGenera11.meta[metaSubTitle] == ""
|
||||
doAssert "<h1 id=\"title0\"><center>Title0</center></h1>" in output11
|
||||
doAssert "<h2 id=\"subtitle0\"><center>SubTitle0</center></h2>" in output11
|
||||
var rstGenera: RstGenerator
|
||||
var output: string
|
||||
let (rst, files, _) = rstParse(input, "", 1, 1, {})
|
||||
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", filenames=files)
|
||||
rstGenera.renderRstToOut(rst, output)
|
||||
doAssert rstGenera.meta[metaTitle] == ""
|
||||
doAssert rstGenera.meta[metaSubTitle] == ""
|
||||
doAssert "<h1 id=\"title0\"><center>Title0</center></h1>" in output
|
||||
doAssert "<h2 id=\"subtitle0\"><center>SubTitle0</center></h2>" in output
|
||||
|
||||
test "RST+Markdown sections":
|
||||
# check that RST and Markdown headings don't interfere
|
||||
let input12 = dedent """
|
||||
let input = dedent """
|
||||
======
|
||||
Title0
|
||||
======
|
||||
@@ -509,14 +511,14 @@ Some chapter
|
||||
MySection2a
|
||||
-----------
|
||||
"""
|
||||
var option12: bool
|
||||
var rstGenera12: RstGenerator
|
||||
var output12: string
|
||||
rstGenera12.initRstGenerator(outHtml, defaultConfig(), "input", {})
|
||||
rstGenera12.renderRstToOut(rstParse(input12, "", 1, 1, option12, {roSupportMarkdown}), output12)
|
||||
doAssert rstGenera12.meta[metaTitle] == "Title0"
|
||||
doAssert rstGenera12.meta[metaSubTitle] == ""
|
||||
doAssert output12 ==
|
||||
var rstGenera: RstGenerator
|
||||
var output: string
|
||||
let (rst, files, _) = rstParse(input, "", 1, 1, {roSupportMarkdown})
|
||||
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", filenames=files)
|
||||
rstGenera.renderRstToOut(rst, output)
|
||||
doAssert rstGenera.meta[metaTitle] == "Title0"
|
||||
doAssert rstGenera.meta[metaSubTitle] == ""
|
||||
doAssert output ==
|
||||
"\n<h1 id=\"mysection1a\">MySection1a</h1>" & # RST
|
||||
"\n<h1 id=\"mysection1b\">MySection1b</h1>" & # Markdown
|
||||
"\n<h1 id=\"mysection1c\">MySection1c</h1>" & # RST
|
||||
@@ -628,7 +630,7 @@ let x = 1
|
||||
let p2 = """<p>Par2 <tt class="docutils literal"><span class="pre">value2</span></tt>.</p>"""
|
||||
let p3 = """<p>Par3 <tt class="docutils literal"><span class="pre">""" & id"value3" & "</span></tt>.</p>"
|
||||
let p4 = """<p>Par4 <tt class="docutils literal"><span class="pre">value4</span></tt>.</p>"""
|
||||
let expected = p1 & p2 & "\n" & p3 & "\n" & p4 & "\n"
|
||||
let expected = p1 & p2 & "\n" & p3 & "\n" & p4
|
||||
check(input.toHtml == expected)
|
||||
|
||||
test "role directive":
|
||||
@@ -653,8 +655,8 @@ Check that comment disappears:
|
||||
let output1 = input1.toHtml
|
||||
doAssert output1 == "Check that comment disappears:"
|
||||
|
||||
test "RST line blocks":
|
||||
let input1 = """
|
||||
test "RST line blocks + headings":
|
||||
let input = """
|
||||
=====
|
||||
Test1
|
||||
=====
|
||||
@@ -665,19 +667,20 @@ Test1
|
||||
| other line
|
||||
|
||||
"""
|
||||
var option: bool
|
||||
var rstGenera: RstGenerator
|
||||
var output1: string
|
||||
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", {})
|
||||
rstGenera.renderRstToOut(rstParse(input1, "", 1, 1, option, {}), output1)
|
||||
var output: string
|
||||
let (rst, files, _) = rstParse(input, "", 1, 1, {})
|
||||
rstGenera.initRstGenerator(outHtml, defaultConfig(), "input", filenames=files)
|
||||
rstGenera.renderRstToOut(rst, output)
|
||||
doAssert rstGenera.meta[metaTitle] == "Test1"
|
||||
# check that title was not overwritten to '|'
|
||||
doAssert output1 == "<p><br/><br/>line block<br/>other line<br/></p>"
|
||||
let output1l = rstToLatex(input1, {})
|
||||
doAssert output == "<p><br/><br/>line block<br/>other line<br/></p>"
|
||||
let output1l = rstToLatex(input, {})
|
||||
doAssert "line block\n\n" in output1l
|
||||
doAssert "other line\n\n" in output1l
|
||||
doAssert output1l.count("\\vspace") == 2 + 2 # +2 surrounding paddings
|
||||
|
||||
test "RST line blocks":
|
||||
let input2 = dedent"""
|
||||
Paragraph1
|
||||
|
||||
@@ -686,7 +689,7 @@ Test1
|
||||
Paragraph2"""
|
||||
|
||||
let output2 = input2.toHtml
|
||||
doAssert "Paragraph1<p><br/></p> <p>Paragraph2</p>\n" == output2
|
||||
doAssert "Paragraph1<p><br/></p> <p>Paragraph2</p>" == output2
|
||||
|
||||
let input3 = dedent"""
|
||||
| xxx
|
||||
@@ -853,7 +856,7 @@ Test1
|
||||
check("input(6, 1) Warning: RST style: \n" &
|
||||
"not enough indentation on line 6" in warnings8[0])
|
||||
doAssert output8 == "Paragraph.<ol class=\"upperalpha simple\">" &
|
||||
"<li>stringA</li>\n<li>stringB</li>\n</ol>\n<p>C. string1 string2 </p>\n"
|
||||
"<li>stringA</li>\n<li>stringB</li>\n</ol>\n<p>C. string1 string2 </p>"
|
||||
|
||||
test "Markdown enumerated lists":
|
||||
let input1 = dedent """
|
||||
@@ -926,7 +929,7 @@ Test1
|
||||
Not references[#note]_[1 #]_ [wrong citation]_ and [not&allowed]_.
|
||||
"""
|
||||
let output2 = input2.toHtml
|
||||
doAssert output2 == "Not references[#note]_[1 #]_ [wrong citation]_ and [not&allowed]_. "
|
||||
doAssert output2 == "Not references[#note]_[1 #]_ [wrong citation]_ and [not&allowed]_."
|
||||
|
||||
# check that auto-symbol footnotes work:
|
||||
let input3 = dedent """
|
||||
@@ -1034,9 +1037,7 @@ Test1
|
||||
"""
|
||||
var warnings8 = new seq[string]
|
||||
let output8 = input8.toHtml(warnings=warnings8)
|
||||
# TODO: the line 1 is arbitrary because reference lines are not preserved
|
||||
check(warnings8[] == @["input(1, 1) Warning: unknown substitution " &
|
||||
"\'citation-som\'"])
|
||||
check(warnings8[] == @["input(3, 7) Warning: broken link 'citation-som'"])
|
||||
|
||||
# check that footnote group does not break parsing of other directives:
|
||||
let input9 = dedent """
|
||||
@@ -1144,10 +1145,33 @@ Test1
|
||||
"""
|
||||
var error = new string
|
||||
let output = input.toHtml(error=error)
|
||||
check(error[] == "input(1, 1) Error: invalid field: " &
|
||||
check(error[] == "input(2, 3) Error: invalid field: " &
|
||||
"extra arguments were given to number-lines: ' let a = 1'")
|
||||
check "" == output
|
||||
|
||||
test "code-block warning":
|
||||
let input = dedent """
|
||||
.. code:: Nim
|
||||
:unsupportedField: anything
|
||||
|
||||
.. code:: unsupportedLang
|
||||
|
||||
anything
|
||||
|
||||
```anotherLang
|
||||
someCode
|
||||
```
|
||||
"""
|
||||
let warnings = new seq[string]
|
||||
let output = input.toHtml(warnings=warnings)
|
||||
check(warnings[] == @[
|
||||
"input(2, 4) Warning: field 'unsupportedField' not supported",
|
||||
"input(4, 11) Warning: language 'unsupportedLang' not supported",
|
||||
"input(8, 4) Warning: language 'anotherLang' not supported"
|
||||
])
|
||||
check(output == "<pre class = \"listing\">anything</pre>" &
|
||||
"<p><pre class = \"listing\">\nsomeCode\n</pre> </p>")
|
||||
|
||||
test "RST admonitions":
|
||||
# check that all admonitions are implemented
|
||||
let input0 = dedent """
|
||||
@@ -1477,7 +1501,7 @@ Test1
|
||||
check "(3, 15) Warning: " in warnings[1]
|
||||
check "language 'py:class' not supported" in warnings[1]
|
||||
check("""<p>See function <span class="py:func">spam</span>.</p>""" & "\n" &
|
||||
"""<p>See also <span class="py:class">egg</span>. </p>""" & "\n" ==
|
||||
"""<p>See also <span class="py:class">egg</span>. </p>""" ==
|
||||
output)
|
||||
|
||||
test "(not) Roles: check escaping 1":
|
||||
|
||||
Reference in New Issue
Block a user