diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index adc83c9af683..4647d3877d57 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -68,7 +68,7 @@ ## substitution references, standalone hyperlinks, ## internal links (inline and outline) ## + \`interpreted text\` with roles ``:literal:``, ``:strong:``, -## ``emphasis``, ``:sub:``/``:subscript:``, ``:sup:``/``:supscript:`` +## ``emphasis``, ``:sub:``/``:subscript:``, ``:sup:``/``:superscript:`` ## (see `RST roles list`_ for description). ## + inline internal targets ## @@ -1021,6 +1021,16 @@ proc fixupEmbeddedRef(n, a, b: PRstNode) = for i in countup(0, sep - incr): a.add(n.sons[i]) for i in countup(sep + 1, n.len - 2): b.add(n.sons[i]) +proc whichRole(sym: string): RstNodeKind = + case sym + of "idx": result = rnIdx + of "literal": result = rnInlineLiteral + of "strong": result = rnStrongEmphasis + of "emphasis": result = rnEmphasis + of "sub", "subscript": result = rnSub + of "sup", "superscript": result = rnSup + else: result = rnGeneralRole + proc parsePostfix(p: var RstParser, n: PRstNode): PRstNode = var newKind = n.kind var newSons = n.sons @@ -1045,22 +1055,8 @@ proc parsePostfix(p: var RstParser, n: PRstNode): PRstNode = result = newRstNode(newKind, newSons) elif match(p, p.idx, ":w:"): # a role: - if nextTok(p).symbol == "idx": - newKind = rnIdx - elif nextTok(p).symbol == "literal": - newKind = rnInlineLiteral - elif nextTok(p).symbol == "strong": - newKind = rnStrongEmphasis - elif nextTok(p).symbol == "emphasis": - newKind = rnEmphasis - elif nextTok(p).symbol == "sub" or - nextTok(p).symbol == "subscript": - newKind = rnSub - elif nextTok(p).symbol == "sup" or - nextTok(p).symbol == "supscript": - newKind = rnSup - else: - newKind = rnGeneralRole + newKind = whichRole(nextTok(p).symbol) + if newKind == rnGeneralRole: let newN = newRstNode(rnInner, n.sons) newSons = @[newN, newLeaf(nextTok(p).symbol)] inc p.idx, 3 @@ -1321,6 +1317,12 @@ proc parseInline(p: var RstParser, father: PRstNode) = var n = newRstNode(rnInlineLiteral) parseUntil(p, n, "``", false) father.add(n) + elif match(p, p.idx, ":w:") and p.tok[p.idx+3].symbol == "`": + let k = whichRole(nextTok(p).symbol) + var n = newRstNode(k) + inc p.idx, 3 + parseUntil(p, n, "`", false) # bug #17260 + father.add(n) elif isInlineMarkupStart(p, "`"): var n = newRstNode(rnInterpretedText) parseUntil(p, n, "`", false) # bug #17260 @@ -1680,7 +1682,7 @@ proc whichSection(p: RstParser): RstNodeKind = elif predNL(p) and currentTok(p).symbol in ["+", "*", "-"] and nextTok(p).kind == tkWhite: result = rnBulletList - elif match(p, p.idx, ":w:") and predNL(p): + elif match(p, p.idx, ":w: ") and predNL(p): # (currentTok(p).symbol == ":") result = rnFieldList elif match(p, p.idx, "(e) ") or match(p, p.idx, "e) ") or diff --git a/tests/stdlib/trstgen.nim b/tests/stdlib/trstgen.nim index 0f3890faa7a4..d0477d73d71e 100644 --- a/tests/stdlib/trstgen.nim +++ b/tests/stdlib/trstgen.nim @@ -1326,6 +1326,45 @@ Test1 output) check("""-doption""" in output) + + test "Roles: subscript prefix/postfix": + let outputPrefix = "See :subscript:`some text`.".toHtml + let outputPostfix = "See `some text`:subscript:.".toHtml + check(outputPrefix == outputPostfix) + check(outputPrefix == "See some text.") + + test "Roles: correct parsing from beginning of line": + let output1 = """:superscript:`3`\ He is an isotope of helium.""".toHtml + check(output1 == "3He is an isotope of helium.") + let output2 = """:sup:`3`\ He is an isotope of helium.""".toHtml + let output3 = """`3`:sup:\ He is an isotope of helium.""".toHtml + let output4 = """`3`:superscript:\ He is an isotope of helium.""".toHtml + check(output2 == output1) + check(output3 == output1) + check(output4 == output1) + + test "(not) Roles: check escaping 1": + let output1 = """See \:subscript:`some text`.""".toHtml + let output2 = """See :subscript\:`some text`.""".toHtml + check(output1 == output2) + check(output1 == """See :subscript:""" & + """some text.""") + + test "(not) Roles: check escaping 2": + let output = """See :subscript:\`some text\`.""".toHtml + check(output == "See :subscript:`some text`.") + + test "Field list": + let output = ":field: text".toHtml + check(output == """""" & + """""" & + """""" & + """""" & "\n
field: text
") + + test "Field list (incorrect)": + let output = ":field:text".toHtml + check(output == ":field:text") + suite "RST/Code highlight": test "Basic Python code highlight": let pythonCode = """