diff options
author | Andrey Makarov <ph.makarov@gmail.com> | 2021-03-12 10:33:21 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-12 08:33:21 +0100 |
commit | d97bf4f1c80ef41789ecfc3430e04293d2b20043 (patch) | |
tree | d72e80c79d4fcd1757107cad251a2ed32ee2c327 /lib | |
parent | 97825805e047ae02003dfd2ed4c0bb3d0d9dc29a (diff) | |
download | Nim-d97bf4f1c80ef41789ecfc3430e04293d2b20043.tar.gz |
fix RST parsing when no indent after enum.item (fix #17249) (#17257)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/impure/db_sqlite.nim | 2 | ||||
-rw-r--r-- | lib/packages/docutils/rst.nim | 51 | ||||
-rw-r--r-- | lib/packages/docutils/rstgen.nim | 8 |
3 files changed, 51 insertions, 10 deletions
diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 6ca81db9e..832407960 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -154,7 +154,7 @@ ## The reasoning is as follows: ## 1. it's close to what many DBs offer natively (char**) ## 2. it hides the number of types that the DB supports -## (int? int64? decimal up to 10 places? geo coords?) +## (int? int64? decimal up to 10 places? geo coords?) ## 3. it's convenient when all you do is to forward the data to somewhere else (echo, log, put the data into a new query) ## ## See also diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 61b17bed1..ea0c079da 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -467,12 +467,20 @@ type s*: PSharedState indentStack*: seq[int] filename*: string - line*, col*: int + line*, col*: int ## initial line/column of whole text or + ## documenation fragment that will be added + ## in case of error/warning reporting to + ## (relative) line/column of the token. hasToc*: bool curAnchor*: string # variable to track latest anchor in s.anchors EParseError* = object of ValueError +const + LineRstInit* = 1 ## Initial line number for standalone RST text + ColRstInit* = 0 ## Initial column number for standalone RST text + ## (Nim global reporting adds ColOffset=1) + template currentTok(p: RstParser): Token = p.tok[p.idx] template prevTok(p: RstParser): Token = p.tok[p.idx - 1] template nextTok(p: RstParser): Token = p.tok[p.idx + 1] @@ -542,8 +550,8 @@ proc initParser(p: var RstParser, sharedState: PSharedState) = p.idx = 0 p.filename = "" p.hasToc = false - p.col = 0 - p.line = 1 + p.col = ColRstInit + p.line = LineRstInit p.s = sharedState proc addNodesAux(n: PRstNode, result: var string) = @@ -1439,8 +1447,8 @@ proc countTitles(p: var RstParser, n: PRstNode) = if p.s.hTitleCnt >= 2: break -proc tokenAfterNewline(p: RstParser): int = - result = p.idx +proc tokenAfterNewline(p: RstParser, start: int): int = + result = start while true: case p.tok[result].kind of tkEof: @@ -1450,6 +1458,9 @@ proc tokenAfterNewline(p: RstParser): int = break else: inc result +proc tokenAfterNewline(p: RstParser): int {.inline.} = + result = tokenAfterNewline(p, p.idx) + proc isAdornmentHeadline(p: RstParser, adornmentIdx: int): bool = ## check that underline/overline length is enough for the heading. ## No support for Unicode. @@ -1937,13 +1948,34 @@ proc parseEnumList(p: var RstParser): PRstNode = wildToken: array[0..5, int] = [4, 3, 3, 4, 3, 3] # number of tokens wildIndex: array[0..5, int] = [1, 0, 0, 1, 0, 0] # position of enumeration sequence (number/letter) in enumerator - result = newRstNodeA(p, rnEnumList) let col = currentTok(p).col var w = 0 while w < wildcards.len: if match(p, p.idx, wildcards[w]): break inc w assert w < wildcards.len + proc checkAfterNewline(p: RstParser, report: bool): bool = + let j = tokenAfterNewline(p, start=p.idx+1) + if p.tok[j].kind notin {tkIndent, tkEof} and + p.tok[j].col < p.tok[p.idx+wildToken[w]].col and + (p.tok[j].col > col or + (p.tok[j].col == col and not match(p, j, wildcards[w]))): + if report: + let n = p.line + p.tok[j].line + let msg = "\n" & """ + not enough indentation on line $2 + (if it's continuation of enumeration list), + or no blank line after line $1 (if it should be the next paragraph), + or no escaping \ at the beginning of line $1 + (if lines $1..$2 are a normal paragraph, not enum. list)""". + unindent(8) + rstMessage(p, mwRstStyle, msg % [$(n-1), $n]) + result = false + else: + result = true + if not checkAfterNewline(p, report = true): + return nil + result = newRstNodeA(p, rnEnumList) let autoEnums = if roSupportMarkdown in p.s.options: @["#", "1"] else: @["#"] var prevAE = "" # so as not allow mixing auto-enumerators `1` and `#` var curEnum = 1 @@ -1963,6 +1995,10 @@ proc parseEnumList(p: var RstParser): PRstNode = result.add(item) if currentTok(p).kind == tkIndent and currentTok(p).ival == col and match(p, p.idx+1, wildcards[w]): + # don't report to avoid duplication of warning since for + # subsequent enum. items parseEnumList will be called second time: + if not checkAfterNewline(p, report = false): + break let enumerator = p.tok[p.idx + 1 + wildIndex[w]].symbol # check that it's in sequence: enumerator == next(prevEnum) if "n" in wildcards[w]: # arabic numeral @@ -2336,7 +2372,8 @@ proc selectDir(p: var RstParser, d: string): PRstNode = of "warning": result = dirAdmonition(p, d) of "default-role": result = dirDefaultRole(p) else: - rstMessage(p, meInvalidDirective, d) + let tok = p.tok[p.idx-2] # report on directive in ".. directive::" + rstMessage(p, meInvalidDirective, d, tok.line, tok.col) proc prefix(ftnType: FootnoteType): string = case ftnType diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 59a9ba09a..f72ff9e8f 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -1506,7 +1506,8 @@ proc rstToHtml*(s: string, options: RstParseOptions, initRstGenerator(d, outHtml, config, filen, options, myFindFile, rst.defaultMsgHandler) var dummyHasToc = false - var rst = rstParse(s, filen, 0, 1, dummyHasToc, options) + var rst = rstParse(s, filen, line=LineRstInit, column=ColRstInit, + dummyHasToc, options) result = "" renderRstToOut(d, rst, result) @@ -1518,4 +1519,7 @@ proc rstToLatex*(rstSource: string; options: RstParseOptions): string {.inline, var option: bool var rstGenera: RstGenerator rstGenera.initRstGenerator(outLatex, defaultConfig(), "input", options) - rstGenera.renderRstToOut(rstParse(rstSource, "", 1, 1, option, options), result) + rstGenera.renderRstToOut( + rstParse(rstSource, "", line=LineRstInit, column=ColRstInit, + option, options), + result) |