From 4bfc5a955120b90faf07f50b54ae29f2c6e6f123 Mon Sep 17 00:00:00 2001 From: Andrey Makarov Date: Wed, 17 Mar 2021 22:13:04 +0300 Subject: Rst test check messages (fix #17280) (#17338) --- lib/packages/docutils/rst.nim | 29 ++++++++++++++++++++--------- lib/packages/docutils/rstgen.nim | 8 ++++---- 2 files changed, 24 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index d54d7fa27..b5eef7610 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -146,7 +146,8 @@ ## .. _Sphinx directives: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html import - os, strutils, rstast, algorithm, lists, sequtils + os, strutils, rstast, std/enumutils, algorithm, lists, sequtils, + std/private/miscdollars type RstParseOption* = enum ## options for the RST parser @@ -477,9 +478,10 @@ type 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) + LineRstInit* = 1 ## Initial line number for standalone RST text + ColRstInit* = 0 ## Initial column number for standalone RST text + ## (Nim global reporting adds ColOffset=1) + ColRstOffset* = 1 ## 1: a replica of ColOffset for internal use template currentTok(p: RstParser): Token = p.tok[p.idx] template prevTok(p: RstParser): Token = p.tok[p.idx - 1] @@ -487,7 +489,7 @@ template nextTok(p: RstParser): Token = p.tok[p.idx + 1] proc whichMsgClass*(k: MsgKind): MsgClass = ## returns which message class `k` belongs to. - case ($k)[1] + case k.symbolName[1] of 'e', 'E': result = mcError of 'w', 'W': result = mcWarning of 'h', 'H': result = mcHint @@ -497,7 +499,9 @@ proc defaultMsgHandler*(filename: string, line, col: int, msgkind: MsgKind, arg: string) = let mc = msgkind.whichMsgClass let a = $msgkind % arg - let message = "$1($2, $3) $4: $5" % [filename, $line, $col, $mc, a] + var message: string + toLocation(message, filename, line, col + ColRstOffset) + message.add " $1: $2" % [$mc, a] if mc == mcError: raise newException(EParseError, message) else: writeLine(stdout, message) @@ -1973,25 +1977,32 @@ proc parseEnumList(p: var RstParser): PRstNode = if match(p, p.idx, wildcards[w]): break inc w assert w < wildcards.len + proc checkAfterNewline(p: RstParser, report: bool): bool = + ## If no indentation on the next line then parse as a normal paragraph + ## according to the RST spec. And report a warning with suggestions let j = tokenAfterNewline(p, start=p.idx+1) + let requiredIndent = p.tok[p.idx+wildToken[w]].col 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 < requiredIndent 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), + (should be at column $3 if it's a continuation of enum. 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]) + let c = p.col + requiredIndent + ColRstOffset + rstMessage(p, mwRstStyle, msg % [$(n-1), $n, $c], + p.tok[j].line, p.tok[j].col) result = false else: result = true + if not checkAfterNewline(p, report = true): return nil result = newRstNodeA(p, rnEnumList) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index f72ff9e8f..c52a0fdcc 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -1476,7 +1476,8 @@ $content # ---------- forum --------------------------------------------------------- proc rstToHtml*(s: string, options: RstParseOptions, - config: StringTableRef): string = + config: StringTableRef, + msgHandler: MsgHandler = rst.defaultMsgHandler): string = ## Converts an input rst string into embeddable HTML. ## ## This convenience proc parses any input string using rst markup (it doesn't @@ -1503,11 +1504,10 @@ proc rstToHtml*(s: string, options: RstParseOptions, const filen = "input" var d: RstGenerator - initRstGenerator(d, outHtml, config, filen, options, myFindFile, - rst.defaultMsgHandler) + initRstGenerator(d, outHtml, config, filen, options, myFindFile, msgHandler) var dummyHasToc = false var rst = rstParse(s, filen, line=LineRstInit, column=ColRstInit, - dummyHasToc, options) + dummyHasToc, options, myFindFile, msgHandler) result = "" renderRstToOut(d, rst, result) -- cgit 1.4.1-2-gfad0