summary refs log tree commit diff stats
path: root/lib/packages/docutils/rst.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/packages/docutils/rst.nim')
-rw-r--r--lib/packages/docutils/rst.nim73
1 files changed, 62 insertions, 11 deletions
diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index 161509afe..551df9919 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -560,9 +560,9 @@ proc match(p: RstParser, start: int, expr: string): bool =
       result = (p.tok[j].kind == tkWord) or (p.tok[j].symbol == "#")
       if result:
         case p.tok[j].symbol[0]
-        of 'a'..'z', 'A'..'Z': result = len(p.tok[j].symbol) == 1
+        of 'a'..'z', 'A'..'Z', '#': result = len(p.tok[j].symbol) == 1
         of '0'..'9': result = allCharsInSet(p.tok[j].symbol, {'0'..'9'})
-        else: discard
+        else: result = false
     else:
       var c = expr[i]
       var length = 0
@@ -780,6 +780,31 @@ proc parseMarkdownCodeblock(p: var RstParser): PRstNode =
   add(result, nil)
   add(result, lb)
 
+proc parseMarkdownLink(p: var RstParser; father: PRstNode): bool =
+  result = true
+  var desc, link = ""
+  var i = p.idx
+
+  template parse(endToken, dest) =
+    inc i # skip begin token
+    while true:
+      if p.tok[i].kind in {tkEof, tkIndent}: return false
+      if p.tok[i].symbol == endToken: break
+      dest.add p.tok[i].symbol
+      inc i
+    inc i # skip end token
+
+  parse("]", desc)
+  if p.tok[i].symbol != "(": return false
+  parse(")", link)
+  let child = newRstNode(rnHyperlink)
+  child.add desc
+  child.add link
+  # only commit if we detected no syntax error:
+  father.add child
+  p.idx = i
+  result = true
+
 proc parseInline(p: var RstParser, father: PRstNode) =
   case p.tok[p.idx].kind
   of tkPunct:
@@ -811,6 +836,9 @@ proc parseInline(p: var RstParser, father: PRstNode) =
       var n = newRstNode(rnSubstitutionReferences)
       parseUntil(p, n, "|", false)
       add(father, n)
+    elif roSupportMarkdown in p.s.options and p.tok[p.idx].symbol == "[" and
+        parseMarkdownLink(p, father):
+      discard "parseMarkdownLink already processed it"
     else:
       if roSupportSmilies in p.s.options:
         let n = parseSmiley(p)
@@ -1037,15 +1065,32 @@ proc isOptionList(p: RstParser): bool =
   result = match(p, p.idx, "-w") or match(p, p.idx, "--w") or
            match(p, p.idx, "/w") or match(p, p.idx, "//w")
 
+proc isMarkdownHeadlinePattern(s: string): bool =
+  if s.len >= 1 and s.len <= 6:
+    for c in s:
+      if c != '#': return false
+    result = true
+
+proc isMarkdownHeadline(p: RstParser): bool =
+  if roSupportMarkdown in p.s.options:
+    if isMarkdownHeadlinePattern(p.tok[p.idx].symbol) and p.tok[p.idx+1].kind == tkWhite:
+      if p.tok[p.idx+2].kind in {tkWord, tkOther, tkPunct}:
+        result = true
+
 proc whichSection(p: RstParser): RstNodeKind =
   case p.tok[p.idx].kind
   of tkAdornment:
     if match(p, p.idx + 1, "ii"): result = rnTransition
     elif match(p, p.idx + 1, " a"): result = rnTable
     elif match(p, p.idx + 1, "i"): result = rnOverline
-    else: result = rnLeaf
+    elif isMarkdownHeadline(p):
+      result = rnHeadline
+    else:
+      result = rnLeaf
   of tkPunct:
-    if match(p, tokenAfterNewline(p), "ai"):
+    if isMarkdownHeadline(p):
+      result = rnHeadline
+    elif match(p, tokenAfterNewline(p), "ai"):
       result = rnHeadline
     elif p.tok[p.idx].symbol == "::":
       result = rnLiteralBlock
@@ -1060,7 +1105,7 @@ proc whichSection(p: RstParser): RstNodeKind =
     elif match(p, p.idx, ":w:") and predNL(p):
       # (p.tok[p.idx].symbol == ":")
       result = rnFieldList
-    elif match(p, p.idx, "(e) "):
+    elif match(p, p.idx, "(e) ") or match(p, p.idx, "e. "):
       result = rnEnumList
     elif match(p, p.idx, "+a+"):
       result = rnGridTable
@@ -1130,12 +1175,18 @@ proc parseParagraph(p: var RstParser, result: PRstNode) =
 
 proc parseHeadline(p: var RstParser): PRstNode =
   result = newRstNode(rnHeadline)
-  parseUntilNewline(p, result)
-  assert(p.tok[p.idx].kind == tkIndent)
-  assert(p.tok[p.idx + 1].kind == tkAdornment)
-  var c = p.tok[p.idx + 1].symbol[0]
-  inc(p.idx, 2)
-  result.level = getLevel(p.s.underlineToLevel, p.s.uLevel, c)
+  if isMarkdownHeadline(p):
+    result.level = p.tok[p.idx].symbol.len
+    assert(p.tok[p.idx+1].kind == tkWhite)
+    inc p.idx, 2
+    parseUntilNewline(p, result)
+  else:
+    parseUntilNewline(p, result)
+    assert(p.tok[p.idx].kind == tkIndent)
+    assert(p.tok[p.idx + 1].kind == tkAdornment)
+    var c = p.tok[p.idx + 1].symbol[0]
+    inc(p.idx, 2)
+    result.level = getLevel(p.s.underlineToLevel, p.s.uLevel, c)
 
 type
   IntSeq = seq[int]