fix RST parsing after option lists (#17442)
This commit is contained in:
parent
045400ad92
commit
46364e63cd
2 changed files with 121 additions and 1 deletions
|
|
@ -82,6 +82,14 @@
|
|||
## * ***triple emphasis*** (bold and italic) using \*\*\*
|
||||
## * ``:idx:`` role for \`interpreted text\` to include the link to this
|
||||
## text into an index (example: `Nim index`_).
|
||||
## * double slash `//` in option lists serves as a prefix for any option that
|
||||
## starts from a word (without any leading symbols like `-`, `--`, `/`)::
|
||||
##
|
||||
## //compile compile the project
|
||||
## //doc generate documentation
|
||||
##
|
||||
## Here the dummy `//` will disappear, while options ``compile``
|
||||
## and ``doc`` will be left in the final document.
|
||||
##
|
||||
## .. [cmp:Sphinx] similar but different from the directives of
|
||||
## Python `Sphinx directives`_ extensions
|
||||
|
|
@ -548,6 +556,67 @@ proc pushInd(p: var RstParser, ind: int) =
|
|||
proc popInd(p: var RstParser) =
|
||||
if p.indentStack.len > 1: setLen(p.indentStack, p.indentStack.len - 1)
|
||||
|
||||
# Working with indentation in rst.nim
|
||||
# -----------------------------------
|
||||
#
|
||||
# Every line break has an associated tkIndent.
|
||||
# The tokenizer writes back the first column of next non-blank line
|
||||
# in all preceeding tkIndent tokens to the `ival` field of tkIndent.
|
||||
#
|
||||
# RST document is separated into body elements (B.E.), every of which
|
||||
# has a dedicated handler proc (or block of logic when B.E. is a block quote)
|
||||
# that should follow the next rule:
|
||||
# Every B.E. handler proc should finish at tkIndent (newline)
|
||||
# after its B.E. finishes.
|
||||
# Then its callers (which is `parseSection` or another B.E. handler)
|
||||
# check for tkIndent ival (without necessity to advance `p.idx`)
|
||||
# and decide themselves whether they continue processing or also stop.
|
||||
#
|
||||
# An example::
|
||||
#
|
||||
# L RST text fragment indentation
|
||||
# +--------------------+
|
||||
# 1 | | <- (empty line at the start of file) no tokens
|
||||
# 2 |First paragraph. | <- tkIndent has ival=0, and next tkWord has col=0
|
||||
# 3 | | <- tkIndent has ival=0
|
||||
# 4 |* bullet item and | <- tkIndent has ival=0, and next tkPunct has col=0
|
||||
# 5 | its continuation | <- tkIndent has ival=2, and next tkWord has col=2
|
||||
# 6 | | <- tkIndent has ival=4
|
||||
# 7 | Block quote | <- tkIndent has ival=4, and next tkWord has col=4
|
||||
# 8 | | <- tkIndent has ival=0
|
||||
# 9 | | <- tkIndent has ival=0
|
||||
# 10|Final paragraph | <- tkIndent has ival=0, and tkWord has col=0
|
||||
# +--------------------+
|
||||
# C:01234
|
||||
#
|
||||
# Here parser starts with initial `indentStack=[0]` and then calls the
|
||||
# 1st `parseSection`:
|
||||
#
|
||||
# - `parseSection` calls `parseParagraph` and "First paragraph" is parsed
|
||||
# - bullet list handler is started at reaching ``*`` (L4 C0), it
|
||||
# starts bullet item logic (L4 C2), which calls `pushInd(p, ind=2)`,
|
||||
# then calls `parseSection` (2nd call, nested) which parses
|
||||
# paragraph "bullet list and its continuation" and then starts
|
||||
# a block quote logic (L7 C4).
|
||||
# The block quote logic calls calls `pushInd(p, ind=4)` and
|
||||
# calls `parseSection` again, so a (simplified) sequence of calls now is::
|
||||
#
|
||||
# parseSection -> parseBulletList ->
|
||||
# parseSection (+block quote logic) -> parseSection
|
||||
#
|
||||
# 3rd `parseSection` finishes, block quote logic calls `popInd(p)`,
|
||||
# it returns to bullet item logic, which sees that next tkIndent has
|
||||
# ival=0 and stops there since the required indentation for a bullet item
|
||||
# is 2 and 0<2; the bullet item logic calls `popInd(p)`.
|
||||
# Then bullet list handler checks that next tkWord (L10 C0) has the
|
||||
# right indentation but does not have ``*`` so stops at tkIndent (L10).
|
||||
# - 1st `parseSection` invocation calls `parseParagraph` and the
|
||||
# "Final paragraph" is parsed.
|
||||
#
|
||||
# If a B.E. handler has advanced `p.idx` past tkIndent to check
|
||||
# whether it should continue its processing or not, and decided not to,
|
||||
# then this B.E. handler should step back (e.g. do `dec p.idx`).
|
||||
|
||||
proc initParser(p: var RstParser, sharedState: PSharedState) =
|
||||
p.indentStack = @[0]
|
||||
p.tok = @[]
|
||||
|
|
@ -1912,8 +1981,9 @@ proc parseBulletList(p: var RstParser): PRstNode =
|
|||
|
||||
proc parseOptionList(p: var RstParser): PRstNode =
|
||||
result = newRstNodeA(p, rnOptionList)
|
||||
let col = currentTok(p).col
|
||||
while true:
|
||||
if isOptionList(p):
|
||||
if currentTok(p).col == col and isOptionList(p):
|
||||
var a = newRstNode(rnOptionGroup)
|
||||
var b = newRstNode(rnDescription)
|
||||
var c = newRstNode(rnOptionListItem)
|
||||
|
|
@ -1936,6 +2006,7 @@ proc parseOptionList(p: var RstParser): PRstNode =
|
|||
c.add(b)
|
||||
result.add(c)
|
||||
else:
|
||||
dec p.idx # back to tkIndent
|
||||
break
|
||||
|
||||
proc parseDefinitionList(p: var RstParser): PRstNode =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue