diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index ea0c079daa93d..d83d07cf88483 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -146,7 +146,7 @@
## .. _Sphinx directives: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html
import
- os, strutils, rstast, algorithm, lists, sequtils
+ os, strutils, rstast, std/enumutils, algorithm, lists, sequtils
type
RstParseOption* = enum ## options for the RST parser
@@ -487,7 +487,7 @@ template nextTok(p: RstParser): Token = p.tok[p.idx + 1]
proc whichMsgClass*(k: MsgKind): MsgClass =
## returns which message class `k` belongs to.
- case ($k)[1]
+ case k.symbolName[1]
of 'e', 'E': result = mcError
of 'w', 'W': result = mcWarning
of 'h', 'H': result = mcHint
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index f72ff9e8f0ba9..c52a0fdccd144 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -1476,7 +1476,8 @@ $content
# ---------- forum ---------------------------------------------------------
proc rstToHtml*(s: string, options: RstParseOptions,
- config: StringTableRef): string =
+ config: StringTableRef,
+ msgHandler: MsgHandler = rst.defaultMsgHandler): string =
## Converts an input rst string into embeddable HTML.
##
## This convenience proc parses any input string using rst markup (it doesn't
@@ -1503,11 +1504,10 @@ proc rstToHtml*(s: string, options: RstParseOptions,
const filen = "input"
var d: RstGenerator
- initRstGenerator(d, outHtml, config, filen, options, myFindFile,
- rst.defaultMsgHandler)
+ initRstGenerator(d, outHtml, config, filen, options, myFindFile, msgHandler)
var dummyHasToc = false
var rst = rstParse(s, filen, line=LineRstInit, column=ColRstInit,
- dummyHasToc, options)
+ dummyHasToc, options, myFindFile, msgHandler)
result = ""
renderRstToOut(d, rst, result)
diff --git a/tests/stdlib/trstgen.nim b/tests/stdlib/trstgen.nim
index 7d5c0e28f2c27..4d0f0678144ba 100644
--- a/tests/stdlib/trstgen.nim
+++ b/tests/stdlib/trstgen.nim
@@ -8,8 +8,37 @@ import ../../lib/packages/docutils/rstgen
import ../../lib/packages/docutils/rst
import unittest, strutils, strtabs
-proc toHtml(input: string): string =
- rstToHtml(input, {roSupportMarkdown}, defaultConfig())
+proc toHtml(input: string,
+ rstOptions: RstParseOptions = {roSupportMarkdown},
+ expectError: string = "",
+ expectWarnings: seq[string] = @[]): string =
+ var warnings: seq[string]
+ var error: string
+ proc testMsgHandler(filename: string, line, col: int, msgkind: MsgKind,
+ arg: string) =
+ let mc = msgkind.whichMsgClass
+ let a = $msgkind % arg
+ let message = "$1($2, $3) $4: $5" % [$filename, $line, $col, $mc, a]
+ if mc == mcError:
+ error = message
+ # we check only first error because subsequent ones may be meaningless
+ raise newException(EParseError, message)
+ else:
+ warnings.add message
+ try:
+ result = rstToHtml(input, rstOptions, defaultConfig(), testMsgHandler)
+ except EParseError:
+ discard
+ template assertEqual(s1, s2: untyped) =
+ let result = s1 == s2
+ if not result:
+ echo "assert failed, Expected:"
+ echo s1
+ echo "got:"
+ echo s2
+ doAssert result
+ assertEqual(expectError, error)
+ assertEqual(expectWarnings, warnings)
suite "YAML syntax highlighting":
test "Basics":
@@ -24,7 +53,7 @@ suite "YAML syntax highlighting":
? key
: value
..."""
- let output = rstTohtml(input, {}, defaultConfig())
+ let output = input.toHtml({})
doAssert output == """
%YAML 1.2
---
a string: string
@@ -50,7 +79,7 @@ suite "YAML syntax highlighting":
another literal block scalar:
|+ # comment after header
allowed, since more indented than parent"""
- let output = rstToHtml(input, {}, defaultConfig())
+ let output = input.toHtml({})
doAssert output == """a literal block scalar: |
some text
# not a comment
@@ -76,7 +105,7 @@ suite "YAML syntax highlighting":
% not a directive
...
%TAG ! !foo:"""
- let output = rstToHtml(input, {}, defaultConfig())
+ let output = input.toHtml({})
doAssert output == """%YAML 1.2
---
%not a directive
@@ -97,7 +126,7 @@ suite "YAML syntax highlighting":
more numbers: [-783, 11e78],
not numbers: [ 42e, 0023, +32.37, 8 ball]
}"""
- let output = rstToHtml(input, {}, defaultConfig())
+ let output = input.toHtml({})
doAssert output == """{
"quoted string": 42,
'single quoted string': false,
@@ -114,7 +143,7 @@ suite "YAML syntax highlighting":
: !localtag foo
alias: *anchor
"""
- let output = rstToHtml(input, {}, defaultConfig())
+ let output = input.toHtml({})
doAssert output == """--- !!map
!!str string: !<tag:yaml.org,2002:int> 42
? &anchor !!seq []:
@@ -134,7 +163,7 @@ suite "YAML syntax highlighting":
example.com/not/a#comment:
?not a map key
"""
- let output = rstToHtml(input, {}, defaultConfig())
+ let output = input.toHtml({})
doAssert output == """...
%a string:
a:string:not:a:map
@@ -155,9 +184,9 @@ suite "RST/Markdown general":
test "Markdown links":
let
- a = rstToHtml("(( [Nim](https://nim-lang.org/) ))", {roSupportMarkdown}, defaultConfig())
- b = rstToHtml("(([Nim](https://nim-lang.org/)))", {roSupportMarkdown}, defaultConfig())
- c = rstToHtml("[[Nim](https://nim-lang.org/)]", {roSupportMarkdown}, defaultConfig())
+ a = "(( [Nim](https://nim-lang.org/) ))".toHtml
+ b = "(([Nim](https://nim-lang.org/)))".toHtml
+ c = "[[Nim](https://nim-lang.org/)]".toHtml
doAssert a == """(( Nim ))"""
doAssert b == """((Nim))"""
@@ -172,7 +201,7 @@ suite "RST/Markdown general":
| E1 \| text |
| | F2 without pipe
not in table"""
- let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
+ let output1 = input1.toHtml
doAssert output1 == """
A1 header | A2 | not fooled |
C1 | C2 bold |
D1 code | | D2 |
@@ -183,7 +212,7 @@ not in table"""
let input2 = """
| A1 header | A2 |
| --- | --- |"""
- let output2 = rstToHtml(input2, {roSupportMarkdown}, defaultConfig())
+ let output2 = input2.toHtml
doAssert output2 == """"""
@@ -225,7 +254,7 @@ A0 A1 X
let input1 = """
Check that a few punctuation symbols are not parsed as adornments:
:word1: word2 .... word3 """
- let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
+ let output1 = input1.toHtml
discard output1
test "RST sections":
@@ -233,7 +262,7 @@ Check that a few punctuation symbols are not parsed as adornments:
Long chapter name
'''''''''''''''''''
"""
- let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
+ let output1 = input1.toHtml
doAssert "Long chapter name" in output1 and "Some chapter
" in output6
# check that overline and underline match
@@ -287,16 +317,19 @@ Some chapter
Some chapter
-----------
"""
- expect(EParseError):
- let output7 = rstToHtml(input7, {roSupportMarkdown}, defaultConfig())
+ let output7 = input7.toHtml(
+ expectError = "input(1, 0) Error: new section expected (underline " &
+ "\'-----------\' does not match overline \'------------\')")
let input8 = dedent """
-----------
Overflow
-----------
"""
- expect(EParseError):
- let output8 = rstToHtml(input8, {roSupportMarkdown}, defaultConfig())
+ # TODO: too many errors
+ let output8 = input8.toHtml(
+ expectError = "input(1, 0) Error: new section expected (overline " &
+ "\'-----------\' is too short)")
# check that hierarchy of title styles works
let input9good = dedent """
@@ -319,7 +352,7 @@ Some chapter
~~~~~
"""
- let output9good = rstToHtml(input9good, {roSupportMarkdown}, defaultConfig())
+ let output9good = input9good.toHtml
doAssert "Level1
" in output9good
doAssert "Level2
" in output9good
doAssert "Level3
" in output9good
@@ -348,8 +381,11 @@ Some chapter
-------
"""
- expect(EParseError):
- let output9Bad = rstToHtml(input9Bad, {roSupportMarkdown}, defaultConfig())
+ let output9Bad = input9bad.toHtml(
+ expectError = "input(15, 0) Error: new section expected (section " &
+ "level inconsistent: underline ~~~~~ unexpectedly found, while " &
+ "the following intermediate section level(s) are missing on " &
+ "lines 12..15: underline -----)")
# the same as input9good but with overline headings
# first overline heading has a special meaning: document title
@@ -464,7 +500,7 @@ Some chapter
Want to learn about `my favorite programming language`_?
.. _my favorite programming language: https://nim-lang.org"""
- let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
+ let output1 = input1.toHtml
doAssert "" in output1
test "Markdown code block":
@@ -503,7 +540,7 @@ Test literal block
```
let x = 1
``` """
- let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
+ let output1 = input1.toHtml
doAssert "
Paragraph2
\n" == output2
let input3 = dedent"""
@@ -563,7 +600,7 @@ Test1
| yyy
| zzz"""
- let output3 = rstToHtml(input3, {roSupportMarkdown}, defaultConfig())
+ let output3 = input3.toHtml
doAssert "xxx
" in output3
doAssert "yyy
" in output3
doAssert "zzz
" in output3
@@ -574,7 +611,7 @@ Test1
|
| zzz"""
- let output4 = rstToHtml(input4, {roSupportMarkdown}, defaultConfig())
+ let output4 = input4.toHtml
doAssert "xxx
" in output4
doAssert "zzz
" in output4
@@ -597,7 +634,7 @@ Test1
5. line5
5
"""
- let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
+ let output1 = input1.toHtml
for i in 1..5:
doAssert ($i & ". line" & $i) notin output1
doAssert ("
line" & $i & " " & $i & "") in output1
@@ -619,7 +656,7 @@ Test1
8. line8
"""
- let output2 = rstToHtml(input2, {roSupportMarkdown}, defaultConfig())
+ let output2 = input2.toHtml
for i in [3, 4, 5, 7, 8]:
doAssert ($i & ". line" & $i) notin output2
doAssert ("line" & $i & "") in output2
@@ -629,7 +666,7 @@ Test1
1. a) string1
2. string2
"""
- let output3 = rstToHtml(input3, {roSupportMarkdown}, defaultConfig())
+ let output3 = input3.toHtml
doAssert count(output3, "") == 2
doAssert "- string1
" in output3 and "- string2
" in output3
@@ -645,7 +682,7 @@ Test1
c) string5
e) string6
"""
- let output4 = rstToHtml(input4, {roSupportMarkdown}, defaultConfig())
+ let output4 = input4.toHtml
doAssert count(output4, "") == 4
for enumerator in [9, 12]:
@@ -665,7 +702,7 @@ Test1
#) string5
#) string6
"""
- let output5 = rstToHtml(input5, {roSupportMarkdown}, defaultConfig())
+ let output5 = input5.toHtml
doAssert count(output5, "") == 2
doAssert count(output5, "- ") == 5
@@ -677,7 +714,7 @@ Test1
#. string2
#. string3
"""
- let output5a = rstToHtml(input5a, {roSupportMarkdown}, defaultConfig())
+ let output5a = input5a.toHtml
doAssert count(output5a, "
") == 1
doAssert count(output5a, "- ") == 3
@@ -689,7 +726,7 @@ Test1
#. string2
#. string3
"""
- let output6 = rstToHtml(input6, {roSupportMarkdown}, defaultConfig())
+ let output6 = input6.toHtml
doAssert count(output6, "
") == 1
doAssert count(output6, "- ") == 3
@@ -702,7 +739,7 @@ Test1
#. string2
#. string3
"""
- let output7 = rstToHtml(input7, {roSupportMarkdown}, defaultConfig())
+ let output7 = input7.toHtml
doAssert count(output7, "
") == 1
doAssert count(output7, "- ") == 3
@@ -710,12 +747,19 @@ Test1
# check that it's not recognized as enum.list without indentation on 2nd line
let input8 = dedent """
+ Paragraph.
+
A. string1
string2
"""
- # TODO: find out hot to catch warning here instead of throwing a defect
- expect(AssertionDefect):
- let output8 = input8.toHtml
+ let output8 = input8.toHtml(
+ expectWarnings = @["input(3, 0) Warning: RST style: \n" &
+ """
+ not enough indentation on line 4
+ (if it's continuation of enumeration list),
+ or no blank line after line 3 (if it should be the next paragraph),
+ or no escaping \ at the beginning of line 3
+ (if lines 3..4 are a normal paragraph, not enum. list)""".unindent(10)])
test "Markdown enumerated lists":
let input1 = dedent """
@@ -729,7 +773,7 @@ Test1
#. lineA
"""
- let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
+ let output1 = input1.toHtml
for i in 1..5:
doAssert ($i & ". line" & $i) notin output1
doAssert ("
- line" & $i & "
") in output1
@@ -755,7 +799,7 @@ Test1
* line5
5
"""
- let output1 = rstToHtml(input1, {roSupportMarkdown}, defaultConfig())
+ let output1 = input1.toHtml
for i in 1..5:
doAssert ("- line" & $i & " " & $i & "
") in output1
doAssert count(output1, "