summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndrey Makarov <ph.makarov@gmail.com>2023-04-18 11:37:47 +0300
committerGitHub <noreply@github.com>2023-04-18 10:37:47 +0200
commit24b6378382f4bcde3b354f0a8137604192c7570f (patch)
tree1e79a1bc20cd83daf9f74cb972b2d52a0fca93be
parent2f547afb0f2ca38d317d95cd9fc17fafc6b403df (diff)
downloadNim-24b6378382f4bcde3b354f0a8137604192c7570f.tar.gz
Fix RST/Markdown false heading detection (#21685)
-rw-r--r--lib/packages/docutils/rst.nim30
-rw-r--r--tests/stdlib/trst.nim39
-rw-r--r--tests/stdlib/trstgen.nim2
3 files changed, 57 insertions, 14 deletions
diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index 4bb623d20..ae564b643 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -2124,17 +2124,20 @@ proc isAdornmentHeadline(p: RstParser, adornmentIdx: int): bool =
     while p.tok[i].kind notin {tkEof, tkIndent}:
       headlineLen += p.tok[i].symbol.len
       inc i
-    result = p.tok[adornmentIdx].symbol.len >= headlineLen and
-         headlineLen != 0
-    if result:
-      result = result and p.tok[i].kind == tkIndent and
-         p.tok[i+1].kind == tkAdornment and
-         p.tok[i+1].symbol == p.tok[adornmentIdx].symbol
-      if not result:
-        failure = "(underline '" & p.tok[i+1].symbol & "' does not match " &
-            "overline '" & p.tok[adornmentIdx].symbol & "')"
-    else:
-      failure = "(overline '" & p.tok[adornmentIdx].symbol & "' is too short)"
+    if p.tok[i].kind == tkIndent and
+       p.tok[i+1].kind == tkAdornment and
+       p.tok[i+1].symbol[0] == p.tok[adornmentIdx].symbol[0]:
+      result = p.tok[adornmentIdx].symbol.len >= headlineLen and
+           headlineLen != 0
+      if result:
+        result = p.tok[i+1].symbol == p.tok[adornmentIdx].symbol
+        if not result:
+          failure = "(underline '" & p.tok[i+1].symbol & "' does not match " &
+              "overline '" & p.tok[adornmentIdx].symbol & "')"
+      else:
+        failure = "(overline '" & p.tok[adornmentIdx].symbol & "' is too short)"
+    else:  # it's not overline/underline section, not reporting error
+      return false
   if not result:
     rstMessage(p, meNewSectionExpected, failure)
 
@@ -2261,10 +2264,11 @@ proc whichSection(p: RstParser): RstNodeKind =
       result = rnLineBlock
     elif roSupportMarkdown in p.s.options and isMarkdownBlockQuote(p):
       result = rnMarkdownBlockQuote
-    elif match(p, p.idx + 1, "i") and isAdornmentHeadline(p, p.idx):
+    elif (match(p, p.idx + 1, "i") and not match(p, p.idx + 2, "I")) and
+         isAdornmentHeadline(p, p.idx):
       result = rnOverline
     else:
-      result = rnLeaf
+      result = rnParagraph
   of tkPunct:
     if isMarkdownHeadline(p):
       result = rnMarkdownHeadline
diff --git a/tests/stdlib/trst.nim b/tests/stdlib/trst.nim
index c32ed1762..c9024ded8 100644
--- a/tests/stdlib/trst.nim
+++ b/tests/stdlib/trst.nim
@@ -67,6 +67,45 @@ proc toAst(input: string,
       result = e.msg
 
 suite "RST parsing":
+  test "Standalone punctuation is not parsed as heading overlines":
+    check(dedent"""
+        Paragraph
+
+        !""".toAst ==
+      dedent"""
+        rnInner
+          rnParagraph
+            rnLeaf  'Paragraph'
+          rnParagraph
+            rnLeaf  '!'
+      """)
+
+    check(dedent"""
+        Paragraph1
+
+        ...
+
+        Paragraph2""".toAst ==
+      dedent"""
+        rnInner
+          rnParagraph
+            rnLeaf  'Paragraph1'
+          rnParagraph
+            rnLeaf  '...'
+          rnParagraph
+            rnLeaf  'Paragraph2'
+      """)
+
+    check(dedent"""
+        ---
+        Paragraph""".toAst ==
+      dedent"""
+        rnInner
+          rnLeaf  '---'
+          rnLeaf  ' '
+          rnLeaf  'Paragraph'
+      """)
+
   test "References are whitespace-neutral and case-insensitive":
     # refname is 'lexical-analysis', the same for all the 3 variants:
     check(dedent"""
diff --git a/tests/stdlib/trstgen.nim b/tests/stdlib/trstgen.nim
index 8c07b35f0..dae4ea1cf 100644
--- a/tests/stdlib/trstgen.nim
+++ b/tests/stdlib/trstgen.nim
@@ -617,8 +617,8 @@ context2
 This is too short to be a transition:
 
 ---
-
 context2
+---
 """
     var error2 = new string
     let output2 = input2.toHtml(error=error2)