RST: improve line blocks (#16518)
This commit is contained in:
parent
17992fca1d
commit
5984f7a7dd
5 changed files with 68 additions and 17 deletions
|
|
@ -1147,7 +1147,8 @@ proc isAdornmentHeadline(p: RstParser, adornmentIdx: int): bool =
|
||||||
proc isLineBlock(p: RstParser): bool =
|
proc isLineBlock(p: RstParser): bool =
|
||||||
var j = tokenAfterNewline(p)
|
var j = tokenAfterNewline(p)
|
||||||
result = currentTok(p).col == p.tok[j].col and p.tok[j].symbol == "|" or
|
result = currentTok(p).col == p.tok[j].col and p.tok[j].symbol == "|" or
|
||||||
p.tok[j].col > currentTok(p).col
|
p.tok[j].col > currentTok(p).col or
|
||||||
|
p.tok[j].symbol == "\n"
|
||||||
|
|
||||||
proc predNL(p: RstParser): bool =
|
proc predNL(p: RstParser): bool =
|
||||||
result = true
|
result = true
|
||||||
|
|
@ -1245,21 +1246,28 @@ proc whichSection(p: RstParser): RstNodeKind =
|
||||||
|
|
||||||
proc parseLineBlock(p: var RstParser): PRstNode =
|
proc parseLineBlock(p: var RstParser): PRstNode =
|
||||||
result = nil
|
result = nil
|
||||||
if nextTok(p).kind == tkWhite:
|
if nextTok(p).kind in {tkWhite, tkIndent}:
|
||||||
var col = currentTok(p).col
|
var col = currentTok(p).col
|
||||||
result = newRstNode(rnLineBlock)
|
result = newRstNode(rnLineBlock)
|
||||||
pushInd(p, p.tok[p.idx + 2].col)
|
|
||||||
inc p.idx, 2
|
|
||||||
while true:
|
while true:
|
||||||
var item = newRstNode(rnLineBlockItem)
|
var item = newRstNode(rnLineBlockItem)
|
||||||
parseSection(p, item)
|
if nextTok(p).kind == tkWhite:
|
||||||
|
if nextTok(p).symbol.len > 1: # pass additional indentation after '| '
|
||||||
|
item.text = nextTok(p).symbol
|
||||||
|
inc p.idx, 2
|
||||||
|
pushInd(p, p.tok[p.idx].col)
|
||||||
|
parseSection(p, item)
|
||||||
|
popInd(p)
|
||||||
|
else: # tkIndent => add an empty line
|
||||||
|
item.text = "\n"
|
||||||
|
inc p.idx, 1
|
||||||
result.add(item)
|
result.add(item)
|
||||||
if currentTok(p).kind == tkIndent and currentTok(p).ival == col and
|
if currentTok(p).kind == tkIndent and currentTok(p).ival == col and
|
||||||
nextTok(p).symbol == "|" and p.tok[p.idx + 2].kind == tkWhite:
|
nextTok(p).symbol == "|" and
|
||||||
inc p.idx, 3
|
p.tok[p.idx + 2].kind in {tkWhite, tkIndent}:
|
||||||
|
inc p.idx, 1
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
popInd(p)
|
|
||||||
|
|
||||||
proc parseParagraph(p: var RstParser, result: PRstNode) =
|
proc parseParagraph(p: var RstParser, result: PRstNode) =
|
||||||
while true:
|
while true:
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ type
|
||||||
rnOptionList, rnOptionListItem, rnOptionGroup, rnOption, rnOptionString,
|
rnOptionList, rnOptionListItem, rnOptionGroup, rnOption, rnOptionString,
|
||||||
rnOptionArgument, rnDescription, rnLiteralBlock, rnQuotedLiteralBlock,
|
rnOptionArgument, rnDescription, rnLiteralBlock, rnQuotedLiteralBlock,
|
||||||
rnLineBlock, # the | thingie
|
rnLineBlock, # the | thingie
|
||||||
rnLineBlockItem, # sons of the | thing
|
rnLineBlockItem, # a son of rnLineBlock - one line inside it.
|
||||||
|
# When `RstNode` text="\n" the line's empty
|
||||||
rnBlockQuote, # text just indented
|
rnBlockQuote, # text just indented
|
||||||
rnTable, rnGridTable, rnMarkdownTable, rnTableRow, rnTableHeaderCell, rnTableDataCell,
|
rnTable, rnGridTable, rnMarkdownTable, rnTableRow, rnTableHeaderCell, rnTableDataCell,
|
||||||
rnLabel, # used for footnotes and other things
|
rnLabel, # used for footnotes and other things
|
||||||
|
|
@ -73,7 +74,7 @@ type
|
||||||
kind*: RstNodeKind ## the node's kind
|
kind*: RstNodeKind ## the node's kind
|
||||||
text*: string ## valid for leafs in the AST; and the title of
|
text*: string ## valid for leafs in the AST; and the title of
|
||||||
## the document or the section; and rnEnumList
|
## the document or the section; and rnEnumList
|
||||||
## and rnAdmonition
|
## and rnAdmonition; and rnLineBlockItem
|
||||||
level*: int ## valid for some node kinds
|
level*: int ## valid for some node kinds
|
||||||
sons*: RstNodeSeq ## the node's sons
|
sons*: RstNodeSeq ## the node's sons
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1160,9 +1160,21 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
|
||||||
of rnQuotedLiteralBlock:
|
of rnQuotedLiteralBlock:
|
||||||
doAssert false, "renderRstToOut"
|
doAssert false, "renderRstToOut"
|
||||||
of rnLineBlock:
|
of rnLineBlock:
|
||||||
renderAux(d, n, "<p>$1</p>", "$1\n\n", result)
|
if n.sons.len == 1 and n.sons[0].text == "\n":
|
||||||
|
# whole line block is one empty line, no need to add extra spacing
|
||||||
|
renderAux(d, n, "<p>$1</p> ", "\n\n$1", result)
|
||||||
|
else: # add extra spacing around the line block for Latex
|
||||||
|
renderAux(d, n, "<p>$1</p>", "\n\\vspace{0.5em}\n$1\\vspace{0.5em}\n", result)
|
||||||
of rnLineBlockItem:
|
of rnLineBlockItem:
|
||||||
renderAux(d, n, "$1<br />", "$1\\\\\n", result)
|
if n.text.len == 0: # normal case - no additional indentation
|
||||||
|
renderAux(d, n, "$1<br/>", "\\noindent $1\n\n", result)
|
||||||
|
elif n.text == "\n": # add one empty line
|
||||||
|
renderAux(d, n, "<br/>", "\\vspace{1em}\n", result)
|
||||||
|
else: # additional indentation w.r.t. '| '
|
||||||
|
let indent = $(0.5 * (n.text.len - 1).toFloat) & "em"
|
||||||
|
renderAux(d, n,
|
||||||
|
"<span style=\"margin-left: " & indent & "\">$1</span><br/>",
|
||||||
|
"\\noindent\\hspace{" & indent & "}$1\n\n", result)
|
||||||
of rnBlockQuote:
|
of rnBlockQuote:
|
||||||
renderAux(d, n, "<blockquote><p>$1</p></blockquote>\n",
|
renderAux(d, n, "<blockquote><p>$1</p></blockquote>\n",
|
||||||
"\\begin{quote}$1\\end{quote}\n", result)
|
"\\begin{quote}$1\\end{quote}\n", result)
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ stmt = IND{>} stmt ^+ IND{=} DED # list of statements
|
||||||
<p>Apart from built-in operations like array indexing, memory allocation, etc. the <tt class="docutils literal"><span class="pre">raise</span></tt> statement is the only way to raise an exception.</p>
|
<p>Apart from built-in operations like array indexing, memory allocation, etc. the <tt class="docutils literal"><span class="pre">raise</span></tt> statement is the only way to raise an exception.</p>
|
||||||
<p><tt class="docutils literal"><span class="pre">typedesc</span></tt> used as a parameter type also introduces an implicit generic. <tt class="docutils literal"><span class="pre">typedesc</span></tt> has its own set of rules:</p>
|
<p><tt class="docutils literal"><span class="pre">typedesc</span></tt> used as a parameter type also introduces an implicit generic. <tt class="docutils literal"><span class="pre">typedesc</span></tt> has its own set of rules:</p>
|
||||||
<p>The <tt class="docutils literal"><span class="pre">!=</span></tt>, <tt class="docutils literal"><span class="pre">></span></tt>, <tt class="docutils literal"><span class="pre">>=</span></tt>, <tt class="docutils literal"><span class="pre">in</span></tt>, <tt class="docutils literal"><span class="pre">notin</span></tt>, <tt class="docutils literal"><span class="pre">isnot</span></tt> operators are in fact templates:</p>
|
<p>The <tt class="docutils literal"><span class="pre">!=</span></tt>, <tt class="docutils literal"><span class="pre">></span></tt>, <tt class="docutils literal"><span class="pre">>=</span></tt>, <tt class="docutils literal"><span class="pre">in</span></tt>, <tt class="docutils literal"><span class="pre">notin</span></tt>, <tt class="docutils literal"><span class="pre">isnot</span></tt> operators are in fact templates:</p>
|
||||||
<p><tt class="docutils literal"><span class="pre">a > b</span></tt> is transformed into <tt class="docutils literal"><span class="pre">b < a</span></tt>.<br /><tt class="docutils literal"><span class="pre">a in b</span></tt> is transformed into <tt class="docutils literal"><span class="pre">contains(b, a)</span></tt>.<br /><tt class="docutils literal"><span class="pre">notin</span></tt> and <tt class="docutils literal"><span class="pre">isnot</span></tt> have the obvious meanings.<br /></p><p>A template where every parameter is <tt class="docutils literal"><span class="pre">untyped</span></tt> is called an <span id="immediate_1">immediate</span> template. For historical reasons templates can be explicitly annotated with an <tt class="docutils literal"><span class="pre">immediate</span></tt> pragma and then these templates do not take part in overloading resolution and the parameters' types are <em>ignored</em> by the compiler. Explicit immediate templates are now deprecated.</p>
|
<p><tt class="docutils literal"><span class="pre">a > b</span></tt> is transformed into <tt class="docutils literal"><span class="pre">b < a</span></tt>.<br/><tt class="docutils literal"><span class="pre">a in b</span></tt> is transformed into <tt class="docutils literal"><span class="pre">contains(b, a)</span></tt>.<br/><tt class="docutils literal"><span class="pre">notin</span></tt> and <tt class="docutils literal"><span class="pre">isnot</span></tt> have the obvious meanings.<br/></p><p>A template where every parameter is <tt class="docutils literal"><span class="pre">untyped</span></tt> is called an <span id="immediate_1">immediate</span> template. For historical reasons templates can be explicitly annotated with an <tt class="docutils literal"><span class="pre">immediate</span></tt> pragma and then these templates do not take part in overloading resolution and the parameters' types are <em>ignored</em> by the compiler. Explicit immediate templates are now deprecated.</p>
|
||||||
|
|
||||||
<h2><a class="toc-backref" id="constants-and-constant-expressions-symbol-lookup-in-generics" href="#constants-and-constant-expressions-symbol-lookup-in-generics">Symbol lookup in generics</a></h2>
|
<h2><a class="toc-backref" id="constants-and-constant-expressions-symbol-lookup-in-generics" href="#constants-and-constant-expressions-symbol-lookup-in-generics">Symbol lookup in generics</a></h2>
|
||||||
<h3><a class="toc-backref" id="symbol-lookup-in-generics-open-and-closed-symbols" href="#symbol-lookup-in-generics-open-and-closed-symbols">Open and Closed symbols</a></h3><p>The symbol binding rules in generics are slightly subtle: There are "open" and "closed" symbols. A "closed" symbol cannot be re-bound in the instantiation context, an "open" symbol can. Per default overloaded symbols are open and every other symbol is closed.</p>
|
<h3><a class="toc-backref" id="symbol-lookup-in-generics-open-and-closed-symbols" href="#symbol-lookup-in-generics-open-and-closed-symbols">Open and Closed symbols</a></h3><p>The symbol binding rules in generics are slightly subtle: There are "open" and "closed" symbols. A "closed" symbol cannot be re-bound in the instantiation context, an "open" symbol can. Per default overloaded symbols are open and every other symbol is closed.</p>
|
||||||
|
|
|
||||||
|
|
@ -355,11 +355,41 @@ Test1
|
||||||
rstGenera.renderRstToOut(rstParse(input1, "", 1, 1, option, {}), output1)
|
rstGenera.renderRstToOut(rstParse(input1, "", 1, 1, option, {}), output1)
|
||||||
doAssert rstGenera.meta[metaTitle] == "Test1"
|
doAssert rstGenera.meta[metaTitle] == "Test1"
|
||||||
# check that title was not overwritten to '|'
|
# check that title was not overwritten to '|'
|
||||||
doAssert "line block<br />" in output1
|
doAssert output1 == "<p><br/><br/>line block<br/>other line<br/></p>"
|
||||||
doAssert "other line<br />" in output1
|
|
||||||
let output1l = rstToLatex(input1, {})
|
let output1l = rstToLatex(input1, {})
|
||||||
doAssert "line block\\\\" in output1l
|
doAssert "line block\n\n" in output1l
|
||||||
doAssert "other line\\\\" in output1l
|
doAssert "other line\n\n" in output1l
|
||||||
|
doAssert output1l.count("\\vspace") == 2 + 2 # +2 surrounding paddings
|
||||||
|
|
||||||
|
let input2 = dedent"""
|
||||||
|
Paragraph1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
|
Paragraph2"""
|
||||||
|
|
||||||
|
let output2 = rstToHtml(input2, {roSupportMarkdown}, defaultConfig())
|
||||||
|
doAssert "Paragraph1<p><br/></p> <p>Paragraph2</p>\n" == output2
|
||||||
|
|
||||||
|
let input3 = dedent"""
|
||||||
|
| xxx
|
||||||
|
| yyy
|
||||||
|
| zzz"""
|
||||||
|
|
||||||
|
let output3 = rstToHtml(input3, {roSupportMarkdown}, defaultConfig())
|
||||||
|
doAssert "xxx<br/>" in output3
|
||||||
|
doAssert "<span style=\"margin-left: 1.0em\">yyy</span><br/>" in output3
|
||||||
|
doAssert "<span style=\"margin-left: 2.0em\">zzz</span><br/>" in output3
|
||||||
|
|
||||||
|
# check that '| ' with a few spaces is still parsed as new line
|
||||||
|
let input4 = dedent"""
|
||||||
|
| xxx
|
||||||
|
|
|
||||||
|
| zzz"""
|
||||||
|
|
||||||
|
let output4 = rstToHtml(input4, {roSupportMarkdown}, defaultConfig())
|
||||||
|
doAssert "xxx<br/><br/>" in output4
|
||||||
|
doAssert "<span style=\"margin-left: 2.0em\">zzz</span><br/>" in output4
|
||||||
|
|
||||||
test "RST enumerated lists":
|
test "RST enumerated lists":
|
||||||
let input1 = dedent """
|
let input1 = dedent """
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue