From 554fe8f88fc6d146b17726acbab415f77e346a72 Mon Sep 17 00:00:00 2001
From: Andrey Makarov
Date: Fri, 15 Jan 2021 02:53:36 +0300
Subject: [PATCH] conservative approach to fix #15184 (#16723)
---
compiler/lexer.nim | 29 +++++++++++++-------
doc/docgen.rst | 18 ++++++++++++
doc/manual.rst | 2 +-
nimdoc/testproject/expected/testproject.html | 12 ++++++++
nimdoc/testproject/expected/testproject.idx | 1 +
nimdoc/testproject/expected/theindex.html | 4 +++
nimdoc/testproject/testproject.nim | 6 ++++
7 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index b55dd35859..729ba34352 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -955,8 +955,10 @@ proc skipMultiLineComment(L: var Lexer; tok: var Token; start: int;
# detect the amount of indentation:
if isDoc:
toStrip = getColNumber(L, pos)
- while L.buf[pos] == ' ': inc pos
- if L.buf[pos] in {CR, LF}:
+ while L.buf[pos] == ' ':
+ inc pos
+ inc toStrip
+ while L.buf[pos] in {CR, LF}: # skip blank lines
pos = handleCRLF(L, pos)
toStrip = 0
while L.buf[pos] == ' ':
@@ -1028,11 +1030,17 @@ proc scanComment(L: var Lexer, tok: var Token) =
inc(pos, 2)
var toStrip = 0
- while L.buf[pos] == ' ':
- inc pos
- inc toStrip
+ var stripInit = false
while true:
+ if not stripInit: # find baseline indentation inside comment
+ while L.buf[pos] == ' ':
+ inc pos
+ inc toStrip
+ if L.buf[pos] in {CR, LF}: # don't set toStrip in blank comment lines
+ toStrip = 0
+ else: # found first non-whitespace character
+ stripInit = true
var lastBackslash = -1
while L.buf[pos] notin {CR, LF, nimlexbase.EndOfFile}:
if L.buf[pos] == '\\': lastBackslash = pos+1
@@ -1048,11 +1056,12 @@ proc scanComment(L: var Lexer, tok: var Token) =
if L.buf[pos] == '#' and L.buf[pos+1] == '#':
tok.literal.add "\n"
inc(pos, 2)
- var c = toStrip
- while L.buf[pos] == ' ' and c > 0:
- inc pos
- dec c
- inc tok.iNumber
+ if stripInit:
+ var c = toStrip
+ while L.buf[pos] == ' ' and c > 0:
+ inc pos
+ dec c
+ inc tok.iNumber
else:
if L.buf[pos] > ' ':
L.indentAhead = indent
diff --git a/doc/docgen.rst b/doc/docgen.rst
index bbf0838bb5..09f6504c81 100644
--- a/doc/docgen.rst
+++ b/doc/docgen.rst
@@ -76,6 +76,24 @@ Note that without the `*` following the name of the type, the documentation for
this type would not be generated. Documentation will only be generated for
*exported* types/procedures/etc.
+It's recommended to always add exactly **one** space after `##` for readability
+of comments — this extra space will be cropped from the parsed comments and
+won't influence RST formatting.
+
+.. note:: Generally, this baseline indentation level inside a documentation
+ comment may not be 1: it can be any since it is determined by the offset
+ of the first non-whitespace character in the comment.
+ After that indentation **must** be consistent on the following lines of
+ the same comment.
+ If you still need to add an additional indentation at the very beginning
+ (for RST block quote syntax) use backslash \\ before it:
+
+ .. code-block:: nim
+ ## \
+ ##
+ ## Block quote at the first line.
+ ##
+ ## Paragraph.
Nim file input
-----------------
diff --git a/doc/manual.rst b/doc/manual.rst
index 9fabee1e8d..4ef962f3ad 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -247,7 +247,7 @@ Multiline documentation comments also exist and support nesting too:
.. code-block:: nim
proc foo =
##[Long documentation comment
- here.
+ here.
]##
diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html
index 2bf8855c73..c60d9f26a9 100644
--- a/nimdoc/testproject/expected/testproject.html
+++ b/nimdoc/testproject/expected/testproject.html
@@ -190,6 +190,11 @@ window.addEventListener('DOMContentLoaded', main);
z6
+
+
discard
ok1
+
+
+proc anything() {...}{.raises: [], tags: [].}
+
+
+There is no block quote after blank lines at the beginning.
+
diff --git a/nimdoc/testproject/expected/testproject.idx b/nimdoc/testproject/expected/testproject.idx
index 5714efac04..1d8be99dac 100644
--- a/nimdoc/testproject/expected/testproject.idx
+++ b/nimdoc/testproject/expected/testproject.idx
@@ -59,3 +59,4 @@ Circle testproject.html#Circle Shapes.Circle
Triangle testproject.html#Triangle Shapes.Triangle
Rectangle testproject.html#Rectangle Shapes.Rectangle
Shapes testproject.html#Shapes testproject: Shapes
+anything testproject.html#anything testproject: anything()
diff --git a/nimdoc/testproject/expected/theindex.html b/nimdoc/testproject/expected/theindex.html
index 978560e0f9..81370d115c 100644
--- a/nimdoc/testproject/expected/theindex.html
+++ b/nimdoc/testproject/expected/theindex.html
@@ -78,6 +78,10 @@ window.addEventListener('DOMContentLoaded', main);
utils: aEnum(): untyped
+anything:
asyncFun1:
- testproject: asyncFun1(): Future[int]
diff --git a/nimdoc/testproject/testproject.nim b/nimdoc/testproject/testproject.nim
index eea399f82c..69edb0d235 100644
--- a/nimdoc/testproject/testproject.nim
+++ b/nimdoc/testproject/testproject.nim
@@ -375,3 +375,9 @@ when true: # issue #15702
Circle, ## A circle
Triangle, ## A three-sided shape
Rectangle ## A four-sided shape
+
+when true: # issue #15184
+ proc anything* =
+ ##
+ ## There is no block quote after blank lines at the beginning.
+ discard