From 692616f3029616b51761975845013daace3b1295 Mon Sep 17 00:00:00 2001
From: Andrey Makarov
Date: Fri, 1 Jul 2022 13:20:12 +0300
Subject: [PATCH] Improve Markdown code blocks & start moving docs to Markdown
style
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- add additional parameters parsing (other implementations will just
ignore them). E.g. if in RST we have:
.. code:: nim
:test: "nim c $1"
...
then in Markdown that will be:
```nim test="nim c $1"
...
```
- implement Markdown interpretation of additional indentation which is
less than 4 spaces (>=4 spaces is a code block but it's not
implemented yet). RST interpretes it as quoted block, for Markdown it's
just normal paragraphs.
- add separate `md2html` and `md2tex` commands. This is to separate
Markdown behavior in cases when it diverges w.r.t. RST significantly —
most conspicously like in the case of additional indentation above, and
also currently the contradicting inline rule of Markdown is also turned
on only in `md2html` and `md2tex`. **Rationale:** mixing Markdown and
RST arbitrarily is a way to nowhere, we need to provide a way to fix the
particular behavior. Note that still all commands have **both** Markdown
and RST features **enabled**. In this PR `*.nim` files can be processed
only in Markdown mode, while `md2html` is for `*.md` files and
`rst2html` for `*.rst` files.
- rename `*.rst` files to `.*md` as our current default behavior is
already Markdown-ish
- convert code blocks in `docgen.rst` to Markdown style as an example.
Other code blocks will be converted in the follow-up PRs
- fix indentation inside Markdown code blocks — additional indentation
is preserved there
- allow more than 3 backticks open/close blocks (tildas \~ are still not
allowed to avoid conflict with RST adornment headings) see also
https://github.com/nim-lang/RFCs/issues/355
- better error messages
- (other) fix a bug that admonitions cannot be used in sandbox mode; fix
annoying warning on line 2711
---
compiler/commands.nim | 5 +-
compiler/docgen.nim | 33 ++--
compiler/lineinfos.nim | 2 +
compiler/main.nim | 13 +-
compiler/nim.nim | 2 +-
compiler/options.nim | 2 +
doc/{apis.rst => apis.md} | 0
doc/{backends.rst => backends.md} | 3 +-
doc/{contributing.rst => contributing.md} | 2 +-
doc/{destructors.rst => destructors.md} | 0
doc/{docgen.rst => docgen.md} | 63 ++++----
doc/{docs.rst => docs.md} | 0
doc/{docstyle.rst => docstyle.md} | 0
doc/{drnim.rst => drnim.md} | 0
doc/{estp.rst => estp.md} | 0
doc/{filters.rst => filters.md} | 0
doc/{hcr.rst => hcr.md} | 0
doc/{idetools.rst => idetools.md} | 0
doc/{intern.rst => intern.md} | 6 +-
doc/{koch.rst => koch.md} | 0
doc/{lib.rst => lib.md} | 0
doc/{manual.rst => manual.md} | 8 +-
.../{var_t_return.rst => var_t_return.md} | 0
...xperimental.rst => manual_experimental.md} | 2 +-
...st => manual_experimental_strictnotnil.md} | 0
doc/{mm.rst => mm.md} | 2 +-
doc/{nep1.rst => nep1.md} | 0
doc/{nimc.rst => nimc.md} | 6 +-
doc/{nimfix.rst => nimfix.md} | 0
doc/{nimgrep.rst => nimgrep.md} | 2 +-
doc/{niminst.rst => niminst.md} | 0
doc/{nims.rst => nims.md} | 0
doc/{nimsuggest.rst => nimsuggest.md} | 0
doc/{overview.rst => overview.md} | 2 +-
doc/{packaging.rst => packaging.md} | 0
doc/{refc.rst => refc.md} | 0
doc/{testament.rst => testament.md} | 0
doc/{tools.rst => tools.md} | 0
doc/{tut1.rst => tut1.md} | 0
doc/{tut2.rst => tut2.md} | 2 +-
doc/{tut3.rst => tut3.md} | 2 +-
lib/packages/docutils/highlite.nim | 4 +-
lib/packages/docutils/rst.nim | 151 ++++++++++++++----
tests/stdlib/thighlite.nim | 6 +
tests/stdlib/trst.nim | 117 +++++++++++++-
tests/stdlib/trstgen.nim | 16 +-
tools/kochdocs.nim | 16 +-
47 files changed, 341 insertions(+), 126 deletions(-)
rename doc/{apis.rst => apis.md} (100%)
rename doc/{backends.rst => backends.md} (99%)
rename doc/{contributing.rst => contributing.md} (99%)
rename doc/{destructors.rst => destructors.md} (100%)
rename doc/{docgen.rst => docgen.md} (98%)
rename doc/{docs.rst => docs.md} (100%)
rename doc/{docstyle.rst => docstyle.md} (100%)
rename doc/{drnim.rst => drnim.md} (100%)
rename doc/{estp.rst => estp.md} (100%)
rename doc/{filters.rst => filters.md} (100%)
rename doc/{hcr.rst => hcr.md} (100%)
rename doc/{idetools.rst => idetools.md} (100%)
rename doc/{intern.rst => intern.md} (99%)
rename doc/{koch.rst => koch.md} (100%)
rename doc/{lib.rst => lib.md} (100%)
rename doc/{manual.rst => manual.md} (99%)
rename doc/manual/{var_t_return.rst => var_t_return.md} (100%)
rename doc/{manual_experimental.rst => manual_experimental.md} (99%)
rename doc/{manual_experimental_strictnotnil.rst => manual_experimental_strictnotnil.md} (100%)
rename doc/{mm.rst => mm.md} (98%)
rename doc/{nep1.rst => nep1.md} (100%)
rename doc/{nimc.rst => nimc.md} (99%)
rename doc/{nimfix.rst => nimfix.md} (100%)
rename doc/{nimgrep.rst => nimgrep.md} (99%)
rename doc/{niminst.rst => niminst.md} (100%)
rename doc/{nims.rst => nims.md} (100%)
rename doc/{nimsuggest.rst => nimsuggest.md} (100%)
rename doc/{overview.rst => overview.md} (86%)
rename doc/{packaging.rst => packaging.md} (100%)
rename doc/{refc.rst => refc.md} (100%)
rename doc/{testament.rst => testament.md} (100%)
rename doc/{tools.rst => tools.md} (100%)
rename doc/{tut1.rst => tut1.md} (100%)
rename doc/{tut2.rst => tut2.md} (99%)
rename doc/{tut3.rst => tut3.md} (99%)
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 31e637abac08b..b849f503d35e6 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -449,6 +449,8 @@ proc parseCommand*(command: string): Command =
of "doc2", "doc": cmdDoc
of "doc2tex": cmdDoc2tex
of "rst2html": cmdRst2html
+ of "md2tex": cmdMd2tex
+ of "md2html": cmdMd2html
of "rst2tex": cmdRst2tex
of "jsondoc0": cmdJsondoc0
of "jsondoc2", "jsondoc": cmdJsondoc
@@ -480,7 +482,8 @@ proc setCommandEarly*(conf: ConfigRef, command: string) =
# command early customizations
# must be handled here to honor subsequent `--hint:x:on|off`
case conf.cmd
- of cmdRst2html, cmdRst2tex: # xxx see whether to add others: cmdGendepend, etc.
+ of cmdRst2html, cmdRst2tex, cmdMd2html, cmdMd2tex:
+ # xxx see whether to add others: cmdGendepend, etc.
conf.foreignPackageNotes = {hintSuccessX}
else:
conf.foreignPackageNotes = foreignPackageNotesDefault
diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index 390f44f2e39db..ed5fe06ef55d1 100644
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -88,7 +88,7 @@ type
jEntriesFinal: JsonNode # final JSON after RST pass 2 and rendering
types: TStrTable
sharedState: PRstSharedState
- isPureRst: bool
+ standaloneDoc: bool
conf*: ConfigRef
cache*: IdentCache
exampleCounter: int
@@ -230,6 +230,7 @@ template declareClosures =
case msgKind
of meCannotOpenFile: k = errCannotOpenFile
of meExpected: k = errXExpected
+ of meMissingClosing: k = errRstMissingClosing
of meGridTableNotImplemented: k = errRstGridTableNotImplemented
of meMarkdownIllformedTable: k = errRstMarkdownIllformedTable
of meIllformedTable: k = errRstIllformedTable
@@ -276,16 +277,18 @@ proc isLatexCmd(conf: ConfigRef): bool = conf.cmd in {cmdRst2tex, cmdDoc2tex}
proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
outExt: string = HtmlExt, module: PSym = nil,
- isPureRst = false): PDoc =
+ standaloneDoc = false, preferMarkdown = true): PDoc =
declareClosures()
new(result)
result.module = module
result.conf = conf
result.cache = cache
result.outDir = conf.outDir.string
- result.isPureRst = isPureRst
- var options= {roSupportRawDirective, roSupportMarkdown, roPreferMarkdown, roSandboxDisabled}
- if not isPureRst: options.incl roNimFile
+ result.standaloneDoc = standaloneDoc
+ var options= {roSupportRawDirective, roSupportMarkdown, roSandboxDisabled}
+ if preferMarkdown:
+ options.incl roPreferMarkdown
+ if not standaloneDoc: options.incl roNimFile
result.sharedState = newRstSharedState(
options, filename.string,
docgenFindFile, compilerMsgHandler)
@@ -333,7 +336,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
# Make sure the destination directory exists
createDir(outp.splitFile.dir)
# Include the current file if we're parsing a nim file
- let importStmt = if d.isPureRst: "" else: "import \"$1\"\n" % [d.filename.replace("\\", "/")]
+ let importStmt = if d.standaloneDoc: "" else: "import \"$1\"\n" % [d.filename.replace("\\", "/")]
writeFile(outp, importStmt & content)
proc interpSnippetCmd(cmd: string): string =
@@ -1512,7 +1515,7 @@ proc genOutFile(d: PDoc, groupedToc = false): string =
"\\\\\\vspace{0.5em}\\large $1", [esc(d.target, d.meta[metaSubtitle])])
var groupsection = getConfigVar(d.conf, "doc.body_toc_groupsection")
- let bodyname = if d.hasToc and not d.isPureRst and not d.conf.isLatexCmd:
+ let bodyname = if d.hasToc and not d.standaloneDoc and not d.conf.isLatexCmd:
groupsection.setLen 0
"doc.body_toc_group"
elif d.hasToc: "doc.body_toc"
@@ -1626,9 +1629,11 @@ proc commandDoc*(cache: IdentCache, conf: ConfigRef) =
generateIndex(d)
proc commandRstAux(cache: IdentCache, conf: ConfigRef;
- filename: AbsoluteFile, outExt: string) =
+ filename: AbsoluteFile, outExt: string,
+ preferMarkdown: bool) =
var filen = addFileExt(filename, "txt")
- var d = newDocumentor(filen, cache, conf, outExt, isPureRst = true)
+ var d = newDocumentor(filen, cache, conf, outExt, standaloneDoc = true,
+ preferMarkdown = preferMarkdown)
let rst = parseRst(readFile(filen.string),
line=LineRstInit, column=ColRstInit,
conf, d.sharedState)
@@ -1637,11 +1642,13 @@ proc commandRstAux(cache: IdentCache, conf: ConfigRef;
writeOutput(d)
generateIndex(d)
-proc commandRst2Html*(cache: IdentCache, conf: ConfigRef) =
- commandRstAux(cache, conf, conf.projectFull, HtmlExt)
+proc commandRst2Html*(cache: IdentCache, conf: ConfigRef,
+ preferMarkdown=false) =
+ commandRstAux(cache, conf, conf.projectFull, HtmlExt, preferMarkdown)
-proc commandRst2TeX*(cache: IdentCache, conf: ConfigRef) =
- commandRstAux(cache, conf, conf.projectFull, TexExt)
+proc commandRst2TeX*(cache: IdentCache, conf: ConfigRef,
+ preferMarkdown=false) =
+ commandRstAux(cache, conf, conf.projectFull, TexExt, preferMarkdown)
proc commandJson*(cache: IdentCache, conf: ConfigRef) =
## implementation of a deprecated jsondoc0 command
diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim
index 105de1636ff8e..071316f15b76c 100644
--- a/compiler/lineinfos.nim
+++ b/compiler/lineinfos.nim
@@ -32,6 +32,7 @@ type
# non-fatal errors
errIllFormedAstX, errCannotOpenFile,
errXExpected,
+ errRstMissingClosing,
errRstGridTableNotImplemented,
errRstMarkdownIllformedTable,
errRstIllformedTable,
@@ -105,6 +106,7 @@ const
errIllFormedAstX: "illformed AST: $1",
errCannotOpenFile: "cannot open '$1'",
errXExpected: "'$1' expected",
+ errRstMissingClosing: "$1",
errRstGridTableNotImplemented: "grid table is not implemented",
errRstMarkdownIllformedTable: "illformed delimiter row of a markdown table",
errRstIllformedTable: "Illformed table: $1",
diff --git a/compiler/main.nim b/compiler/main.nim
index a4425e510c92f..0354bec9c7261 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -276,7 +276,8 @@ proc mainCommand*(graph: ModuleGraph) =
var ret = if optUseNimcache in conf.globalOptions: getNimcacheDir(conf)
else: conf.projectPath
doAssert ret.string.isAbsolute # `AbsoluteDir` is not a real guarantee
- if conf.cmd in cmdDocLike + {cmdRst2html, cmdRst2tex}: ret = ret / htmldocsDir
+ if conf.cmd in cmdDocLike + {cmdRst2html, cmdRst2tex, cmdMd2html, cmdMd2tex}:
+ ret = ret / htmldocsDir
conf.outDir = ret
## process all commands
@@ -302,7 +303,7 @@ proc mainCommand*(graph: ModuleGraph) =
commandDoc2(graph, HtmlExt)
if optGenIndex in conf.globalOptions and optWholeProject in conf.globalOptions:
commandBuildIndex(conf, $conf.outDir)
- of cmdRst2html:
+ of cmdRst2html, cmdMd2html:
# XXX: why are warnings disabled by default for rst2html and rst2tex?
for warn in rstWarnings:
conf.setNoteDefaults(warn, true)
@@ -311,16 +312,16 @@ proc mainCommand*(graph: ModuleGraph) =
conf.quitOrRaise "compiler wasn't built with documentation generator"
else:
loadConfigs(DocConfig, cache, conf, graph.idgen)
- commandRst2Html(cache, conf)
- of cmdRst2tex, cmdDoc2tex:
+ commandRst2Html(cache, conf, preferMarkdown = (conf.cmd == cmdMd2html))
+ of cmdRst2tex, cmdMd2tex, cmdDoc2tex:
for warn in rstWarnings:
conf.setNoteDefaults(warn, true)
when defined(leanCompiler):
conf.quitOrRaise "compiler wasn't built with documentation generator"
else:
- if conf.cmd == cmdRst2tex:
+ if conf.cmd in {cmdRst2tex, cmdMd2tex}:
loadConfigs(DocTexConfig, cache, conf, graph.idgen)
- commandRst2TeX(cache, conf)
+ commandRst2TeX(cache, conf, preferMarkdown = (conf.cmd == cmdMd2tex))
else:
docLikeCmd commandDoc2(graph, TexExt)
of cmdJsondoc0: docLikeCmd commandJson(cache, conf)
diff --git a/compiler/nim.nim b/compiler/nim.nim
index bfb07ba20ae83..48472507da17a 100644
--- a/compiler/nim.nim
+++ b/compiler/nim.nim
@@ -122,7 +122,7 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
# `The parameter is incorrect`
let cmd = cmdPrefix & output.quoteShell & ' ' & conf.arguments
execExternalProgram(conf, cmd.strip(leading=false,trailing=true))
- of cmdDocLike, cmdRst2html, cmdRst2tex: # bugfix(cmdRst2tex was missing)
+ of cmdDocLike, cmdRst2html, cmdRst2tex, cmdMd2html, cmdMd2tex: # bugfix(cmdRst2tex was missing)
if conf.arguments.len > 0:
# reserved for future use
rawMessage(conf, errGenerated, "'$1 cannot handle arguments" % [$conf.cmd])
diff --git a/compiler/options.nim b/compiler/options.nim
index 792f15d58e0bb..d1aa232bc27b6 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -153,6 +153,8 @@ type
cmdDoc2tex # convert .nim doc comments to LaTeX
cmdRst2html # convert a reStructuredText file to HTML
cmdRst2tex # convert a reStructuredText file to TeX
+ cmdMd2html # convert a Markdown file to HTML
+ cmdMd2tex # convert a Markdown file to TeX
cmdJsondoc0
cmdJsondoc
cmdCtags
diff --git a/doc/apis.rst b/doc/apis.md
similarity index 100%
rename from doc/apis.rst
rename to doc/apis.md
diff --git a/doc/backends.rst b/doc/backends.md
similarity index 99%
rename from doc/backends.rst
rename to doc/backends.md
index 65dd8a6f24c6d..a135e78b0ec8e 100644
--- a/doc/backends.rst
+++ b/doc/backends.md
@@ -10,7 +10,8 @@
.. no syntax highlighting here by default:
.. contents::
- "Heresy grows from idleness." -- Unknown.
+
+> "Heresy grows from idleness." -- Unknown.
Introduction
diff --git a/doc/contributing.rst b/doc/contributing.md
similarity index 99%
rename from doc/contributing.rst
rename to doc/contributing.md
index 0ca0d0cbc453a..51d1d5065a98c 100644
--- a/doc/contributing.rst
+++ b/doc/contributing.md
@@ -581,7 +581,7 @@ Code reviews
-.. include:: docstyle.rst
+.. include:: docstyle.md
Evolving the stdlib
diff --git a/doc/destructors.rst b/doc/destructors.md
similarity index 100%
rename from doc/destructors.rst
rename to doc/destructors.md
diff --git a/doc/docgen.rst b/doc/docgen.md
similarity index 98%
rename from doc/docgen.rst
rename to doc/docgen.md
index 48166b2c5c89e..5f5c4ecc0dc39 100644
--- a/doc/docgen.rst
+++ b/doc/docgen.md
@@ -35,14 +35,13 @@ Quick start
Generate HTML documentation for a file:
-.. code:: cmd
-
+ ```cmd
nim doc .nim
+ ```
Generate HTML documentation for a whole project:
-.. code:: cmd
-
+ ```cmd
# delete any htmldocs/*.idx file before starting
nim doc --project --index:on --git.url: --git.commit: --outdir:htmldocs .nim
# this will generate html files, a theindex.html index, css and js under `htmldocs`
@@ -54,7 +53,7 @@ Generate HTML documentation for a whole project:
# or `$nimcache/htmldocs` with `--usenimcache` which avoids clobbering your sources;
# and likewise without `--project`.
# Adding `-r` will open in a browser directly.
-
+ ```
Documentation Comments
----------------------
@@ -120,8 +119,8 @@ Example of Nim file input
The following examples will generate documentation for this sample
*Nim* module, aptly named ``doc/docgen_sample.nim``:
-.. code:: nim
- :file: docgen_sample.nim
+ ```nim file=docgen_sample.nim
+ ```
All the below commands save their output to ``htmldocs`` directory relative to
the directory of file;
@@ -137,9 +136,9 @@ optionally, an index file.
The `doc`:option: command:
-.. code:: cmd
-
+ ```cmd
nim doc docgen_sample.nim
+ ```
Partial Output::
...
@@ -159,8 +158,7 @@ HTML -> PDF conversion).
The `doc2tex`:option: command:
-.. code:: cmd
-
+ ```cmd
nim doc2tex docgen_sample.nim
cd htmldocs
xelatex docgen_sample.tex
@@ -169,6 +167,7 @@ The `doc2tex`:option: command:
# large documents) to get all labels generated.
# That depends on this warning in the end of `xelatex` output:
# LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
+ ```
The output is ``docgen_sample.pdf``.
@@ -183,9 +182,9 @@ Note that this tool is built off of the `doc`:option: command
The `jsondoc`:option: command:
-.. code:: cmd
-
+ ```cmd
nim jsondoc docgen_sample.nim
+ ```
Output::
{
@@ -209,9 +208,9 @@ renamed to `jsondoc0`:option:.
The `jsondoc0`:option: command:
-.. code:: cmd
-
+ ```cmd
nim jsondoc0 docgen_sample.nim
+ ```
Output::
[
@@ -249,9 +248,9 @@ the anchor [*]_ of Nim symbol that corresponds to link text.
If you have a constant:
-.. code:: Nim
-
+ ```Nim
const pi* = 3.14
+ ```
then it should be referenced in one of the 2 forms:
@@ -262,9 +261,9 @@ B. qualified (with symbol kind specification)::
For routine kinds there are more options. Consider this definition:
-.. code:: Nim
-
+ ```Nim
proc foo*(a: int, b: float): string
+ ```
Generally following syntax is allowed for referencing `foo`:
@@ -352,11 +351,11 @@ recognized fine::
(without parameter names, see form A.2 above).
E.g. for this signature:
- .. code:: Nim
-
+ ```Nim
proc binarySearch*[T, K](a: openArray[T]; key: K;
cmp: proc (x: T; y: K): int {.closure.}): int
~~ ~~ ~~~~~
+ ```
you cannot use names underlined by `~~` so it must be referenced with
``cmp: proc(T, K)``. Hence these forms are valid::
@@ -379,10 +378,10 @@ recognized fine::
.. Note:: A bit special case is operators
(as their signature is also defined with `\``):
- .. code:: Nim
-
+ ```Nim
func `$`(x: MyType): string
func `[]`*[T](x: openArray[T]): T
+ ```
A short form works without additional backticks::
@@ -412,9 +411,9 @@ Related Options
Project switch
--------------
-.. code:: cmd
-
+ ```cmd
nim doc --project filename.nim
+ ```
This will recursively generate documentation of all Nim modules imported
into the input module that belong to the Nimble package that ``filename.nim``
@@ -425,9 +424,9 @@ also be generated.
Index switch
------------
-.. code:: cmd
-
+ ```cmd
nim doc --index:on filename.nim
+ ```
This will generate an index of all the exported symbols in the input Nim
module, and put it into a neighboring file with the extension of ``.idx``. The
@@ -443,9 +442,9 @@ file.
See source switch
-----------------
-.. code:: cmd
-
+ ```cmd
nim doc --git.url: filename.nim
+ ```
With the `git.url`:option: switch the *See source* hyperlink will appear below each
documented item in your source code pointing to the implementation of that
@@ -490,9 +489,9 @@ supports highlighting of a few other languages supported by the
Usage:
-.. code:: cmd
-
+ ```cmd
nim rst2html docgen.rst
+ ```
Output::
You're reading it!
@@ -528,7 +527,7 @@ HTML file, most browsers will go to the first one. To differentiate the rest,
you will need to use the complex name. A complex name for a callable type is
made up of several parts:
- (**plain symbol**)(**.type**),(**first param**)?(**,param type**)\*
+ (**plain symbol**)(**.type**),(**first param**)?(**,param type**)\*
The first thing to note is that all callable types have at least a comma, even
if they don't have any parameters. If there are parameters, they are
diff --git a/doc/docs.rst b/doc/docs.md
similarity index 100%
rename from doc/docs.rst
rename to doc/docs.md
diff --git a/doc/docstyle.rst b/doc/docstyle.md
similarity index 100%
rename from doc/docstyle.rst
rename to doc/docstyle.md
diff --git a/doc/drnim.rst b/doc/drnim.md
similarity index 100%
rename from doc/drnim.rst
rename to doc/drnim.md
diff --git a/doc/estp.rst b/doc/estp.md
similarity index 100%
rename from doc/estp.rst
rename to doc/estp.md
diff --git a/doc/filters.rst b/doc/filters.md
similarity index 100%
rename from doc/filters.rst
rename to doc/filters.md
diff --git a/doc/hcr.rst b/doc/hcr.md
similarity index 100%
rename from doc/hcr.rst
rename to doc/hcr.md
diff --git a/doc/idetools.rst b/doc/idetools.md
similarity index 100%
rename from doc/idetools.rst
rename to doc/idetools.md
diff --git a/doc/intern.rst b/doc/intern.md
similarity index 99%
rename from doc/intern.rst
rename to doc/intern.md
index 9103c694cc433..0fd995582fdaf 100644
--- a/doc/intern.rst
+++ b/doc/intern.md
@@ -10,7 +10,7 @@
.. include:: rstcommon.rst
.. contents::
- "Abstraction is layering ignorance on top of reality." -- Richard Gabriel
+> "Abstraction is layering ignorance on top of reality." -- Richard Gabriel
Directory structure
@@ -276,8 +276,8 @@ and `exitingDebugSection()`:nim:.
#. Compile the temp compiler with `--debugger:native -d:nimDebugUtils`:option:
#. Set your desired breakpoints or watchpoints.
#. Configure your debugger:
- * GDB: execute `source tools/compiler.gdb` at startup
- * LLDB execute `command source tools/compiler.lldb` at startup
+ * GDB: execute `source tools/compiler.gdb` at startup
+ * LLDB execute `command source tools/compiler.lldb` at startup
#. Use one of the scoping helpers like so:
.. code-block:: nim
diff --git a/doc/koch.rst b/doc/koch.md
similarity index 100%
rename from doc/koch.rst
rename to doc/koch.md
diff --git a/doc/lib.rst b/doc/lib.md
similarity index 100%
rename from doc/lib.rst
rename to doc/lib.md
diff --git a/doc/manual.rst b/doc/manual.md
similarity index 99%
rename from doc/manual.rst
rename to doc/manual.md
index 571379a87b098..503b9538b02c9 100644
--- a/doc/manual.rst
+++ b/doc/manual.md
@@ -10,9 +10,9 @@ Nim Manual
.. contents::
- "Complexity" seems to be a lot like "energy": you can transfer it from the
- end-user to one/some of the other players, but the total amount seems to remain
- pretty much constant for a given task. -- Ran
+> "Complexity" seems to be a lot like "energy": you can transfer it from the
+> end-user to one/some of the other players, but the total amount seems to remain
+> pretty much constant for a given task. -- Ran
About this document
@@ -4025,7 +4025,7 @@ In the standard library every name of a routine that returns a `var` type
starts with the prefix `m` per convention.
-.. include:: manual/var_t_return.rst
+.. include:: manual/var_t_return.md
Future directions
~~~~~~~~~~~~~~~~~
diff --git a/doc/manual/var_t_return.rst b/doc/manual/var_t_return.md
similarity index 100%
rename from doc/manual/var_t_return.rst
rename to doc/manual/var_t_return.md
diff --git a/doc/manual_experimental.rst b/doc/manual_experimental.md
similarity index 99%
rename from doc/manual_experimental.rst
rename to doc/manual_experimental.md
index 3089755cbb1a6..3968163c58d47 100644
--- a/doc/manual_experimental.rst
+++ b/doc/manual_experimental.md
@@ -505,7 +505,7 @@ The compiler ensures that every code path initializes variables which contain
non-nilable pointers. The details of this analysis are still to be specified
here.
-.. include:: manual_experimental_strictnotnil.rst
+.. include:: manual_experimental_strictnotnil.md
Aliasing restrictions in parameter passing
diff --git a/doc/manual_experimental_strictnotnil.rst b/doc/manual_experimental_strictnotnil.md
similarity index 100%
rename from doc/manual_experimental_strictnotnil.rst
rename to doc/manual_experimental_strictnotnil.md
diff --git a/doc/mm.rst b/doc/mm.md
similarity index 98%
rename from doc/mm.rst
rename to doc/mm.md
index b6941a901cdec..09b235228e73a 100644
--- a/doc/mm.rst
+++ b/doc/mm.md
@@ -11,7 +11,7 @@ Nim's Memory Management
..
- "The road to hell is paved with good intentions."
+> "The road to hell is paved with good intentions."
Multi-paradigm Memory Management Strategies
diff --git a/doc/nep1.rst b/doc/nep1.md
similarity index 100%
rename from doc/nep1.rst
rename to doc/nep1.md
diff --git a/doc/nimc.rst b/doc/nimc.md
similarity index 99%
rename from doc/nimc.rst
rename to doc/nimc.md
index aa665049142a6..28a917d9236f0 100644
--- a/doc/nimc.rst
+++ b/doc/nimc.md
@@ -11,9 +11,9 @@
..
- "Look at you, hacker. A pathetic creature of meat and bone, panting and
- sweating as you run through my corridors. How can you challenge a perfect,
- immortal machine?"
+> "Look at you, hacker. A pathetic creature of meat and bone, panting and
+> sweating as you run through my corridors. How can you challenge a perfect,
+> immortal machine?"
Introduction
diff --git a/doc/nimfix.rst b/doc/nimfix.md
similarity index 100%
rename from doc/nimfix.rst
rename to doc/nimfix.md
diff --git a/doc/nimgrep.rst b/doc/nimgrep.md
similarity index 99%
rename from doc/nimgrep.rst
rename to doc/nimgrep.md
index 6088a4c458594..ff2bf3a8d3f36 100644
--- a/doc/nimgrep.rst
+++ b/doc/nimgrep.md
@@ -54,7 +54,7 @@ All examples below use default PCRE Regex patterns:
nimgrep --excludeDir:'^\.git$' --excludeDir:'^\.hg$' --excludeDir:'^\.svn$'
# short: --ed:'^\.git$' --ed:'^\.hg$' --ed:'^\.svn$'
-+ To search only in paths containing the `tests` sub-directory recursively::
++ To search only in paths containing the `tests` sub-directory recursively:
.. code:: cmd
nimgrep --recursive --includeDir:'(^|/)tests($|/)'
diff --git a/doc/niminst.rst b/doc/niminst.md
similarity index 100%
rename from doc/niminst.rst
rename to doc/niminst.md
diff --git a/doc/nims.rst b/doc/nims.md
similarity index 100%
rename from doc/nims.rst
rename to doc/nims.md
diff --git a/doc/nimsuggest.rst b/doc/nimsuggest.md
similarity index 100%
rename from doc/nimsuggest.rst
rename to doc/nimsuggest.md
diff --git a/doc/overview.rst b/doc/overview.md
similarity index 86%
rename from doc/overview.rst
rename to doc/overview.md
index e01520d7c82d7..b21eb1e689e81 100644
--- a/doc/overview.rst
+++ b/doc/overview.md
@@ -5,5 +5,5 @@ Nim Documentation Overview
:Author: Andreas Rumpf
:Version: |nimversion|
-.. include:: docs.rst
+.. include:: docs.md
diff --git a/doc/packaging.rst b/doc/packaging.md
similarity index 100%
rename from doc/packaging.rst
rename to doc/packaging.md
diff --git a/doc/refc.rst b/doc/refc.md
similarity index 100%
rename from doc/refc.rst
rename to doc/refc.md
diff --git a/doc/testament.rst b/doc/testament.md
similarity index 100%
rename from doc/testament.rst
rename to doc/testament.md
diff --git a/doc/tools.rst b/doc/tools.md
similarity index 100%
rename from doc/tools.rst
rename to doc/tools.md
diff --git a/doc/tut1.rst b/doc/tut1.md
similarity index 100%
rename from doc/tut1.rst
rename to doc/tut1.md
diff --git a/doc/tut2.rst b/doc/tut2.md
similarity index 99%
rename from doc/tut2.rst
rename to doc/tut2.md
index 725f68dd55dd0..d37d6a16a0671 100644
--- a/doc/tut2.rst
+++ b/doc/tut2.md
@@ -13,7 +13,7 @@ Nim Tutorial (Part II)
Introduction
============
- "Repetition renders the ridiculous reasonable." -- Norman Wildberger
+> "Repetition renders the ridiculous reasonable." -- Norman Wildberger
This document is a tutorial for the advanced constructs of the *Nim*
programming language. **Note that this document is somewhat obsolete as the**
diff --git a/doc/tut3.rst b/doc/tut3.md
similarity index 99%
rename from doc/tut3.rst
rename to doc/tut3.md
index c2c95610786b1..2fcfd4220c0f0 100644
--- a/doc/tut3.rst
+++ b/doc/tut3.md
@@ -13,7 +13,7 @@ Nim Tutorial (Part III)
Introduction
============
- "With Great Power Comes Great Responsibility." -- Spider Man's Uncle
+> "With Great Power Comes Great Responsibility." -- Spider Man's Uncle
This document is a tutorial about Nim's macro system.
A macro is a function that is executed at compile-time and transforms
diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim
index d36b2c877e3c8..3af94ab21cef4 100644
--- a/lib/packages/docutils/highlite.nim
+++ b/lib/packages/docutils/highlite.nim
@@ -125,9 +125,7 @@ proc initGeneralTokenizer*(g: var GeneralTokenizer, buf: cstring) =
g.length = 0
g.state = low(TokenClass)
g.lang = low(SourceLanguage)
- var pos = 0 # skip initial whitespace:
- while g.buf[pos] in {' ', '\t'..'\r'}: inc(pos)
- g.pos = pos
+ g.pos = 0
proc initGeneralTokenizer*(g: var GeneralTokenizer, buf: string) =
initGeneralTokenizer(g, cstring(buf))
diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index cd5f262789d86..1721674c8b397 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -8,20 +8,23 @@
#
## ==================================
-## rst
+## packages/docutils/rst
## ==================================
##
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Nim-flavored reStructuredText and Markdown
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##
-## This module implements a `reStructuredText`:idx: (RST) parser.
+## This module implements a `reStructuredText`:idx: (RST) and
+## `Markdown`:idx: parser.
## A large subset is implemented with some limitations_ and
## `Nim-specific features`_.
-## A few `extra features`_ of the `Markdown`:idx: syntax are
-## also supported.
+## Both Markdown and RST are mark-up languages whose goal is to
+## typeset texts with complex structure, formatting and references
+## using simple plaintext representation.
##
-## Nim can output the result to HTML [#html]_ or Latex [#latex]_.
+## This module is also embedded into Nim compiler; the compiler can output
+## the result to HTML [#html]_ or Latex [#latex]_.
##
## .. [#html] commands `nim doc`:cmd: for ``*.nim`` files and
## `nim rst2html`:cmd: for ``*.rst`` files
@@ -29,11 +32,13 @@
## .. [#latex] commands `nim doc2tex`:cmd: for ``*.nim`` and
## `nim rst2tex`:cmd: for ``*.rst``.
##
-## If you are new to RST please consider reading the following:
+## If you are new to Markdown/RST please consider reading the following:
##
-## 1) a short `quick introduction`_
-## 2) an `RST reference`_: a comprehensive cheatsheet for RST
-## 3) a more formal 50-page `RST specification`_.
+## 1) `Markdown Basic Syntax`_
+## 2) a long specification of Markdown: `CommonMark Spec`_
+## 3) a short `quick introduction`_ to RST
+## 4) an `RST reference`_: a comprehensive cheatsheet for RST
+## 5) a more formal 50-page `RST specification`_.
##
## Features
## --------
@@ -120,7 +125,13 @@
##
## * emoji / smiley symbols
## * Markdown tables
-## * Markdown code blocks
+## * Markdown code blocks. For them the same additional arguments as for RST
+## code blocks can be provided (e.g. `test` or `number-lines`) but with
+## a one-line syntax like this::
+##
+## ```nim test number-lines=10
+## echo "ok"
+## ```
## * Markdown links
## * Markdown headlines
## * Markdown block quotes
@@ -211,6 +222,8 @@
## See `packages/docutils/rstgen module `_ to know how to
## generate HTML or Latex strings to embed them into your documents.
##
+## .. _Markdown Basic Syntax: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax
+## .. _CommonMark Spec: https://spec.commonmark.org/0.30
## .. _quick introduction: https://docutils.sourceforge.io/docs/user/rst/quickstart.html
## .. _RST reference: https://docutils.sourceforge.io/docs/user/rst/quickref.html
## .. _RST specification: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html
@@ -253,6 +266,7 @@ type
MsgKind* = enum ## the possible messages
meCannotOpenFile = "cannot open '$1'",
meExpected = "'$1' expected",
+ meMissingClosing = "$1",
meGridTableNotImplemented = "grid table is not implemented",
meMarkdownIllformedTable = "illformed delimiter row of a Markdown table",
meIllformedTable = "Illformed table: $1",
@@ -323,7 +337,10 @@ const
":geek:": "icon_e_geek",
":ugeek:": "icon_e_ugeek"
}
- SandboxDirAllowlist = ["image", "code", "code-block"]
+ SandboxDirAllowlist = [
+ "image", "code", "code-block", "admonition", "attention", "caution",
+ "container", "contents", "danger", "default-role", "error", "figure",
+ "hint", "important", "index", "note", "role", "tip", "title", "warning"]
type
TokType = enum
@@ -1616,35 +1633,89 @@ proc parseUntil(p: var RstParser, father: PRstNode, postfix: string,
inc p.idx
else: rstMessage(p, meExpected, postfix, line, col)
+proc parseMarkdownCodeblockFields(p: var RstParser): PRstNode =
+ ## Parses additional (after language string) code block parameters
+ ## in a format *suggested* in the `CommonMark Spec`_ with handling of `"`.
+ if currentTok(p).kind == tkIndent:
+ result = nil
+ else:
+ result = newRstNode(rnFieldList)
+ while currentTok(p).kind != tkIndent:
+ if currentTok(p).kind == tkWhite:
+ inc p.idx
+ else:
+ let field = newRstNode(rnField)
+ var fieldName = ""
+ while currentTok(p).kind notin {tkWhite, tkIndent, tkEof} and
+ currentTok(p).symbol != "=":
+ fieldName.add currentTok(p).symbol
+ inc p.idx
+ field.add(newRstNode(rnFieldName, @[newLeaf(fieldName)]))
+ if currentTok(p).kind == tkWhite: inc p.idx
+ let fieldBody = newRstNode(rnFieldBody)
+ if currentTok(p).symbol == "=":
+ inc p.idx
+ if currentTok(p).kind == tkWhite: inc p.idx
+ var fieldValue = ""
+ if currentTok(p).symbol == "\"":
+ while true:
+ fieldValue.add currentTok(p).symbol
+ inc p.idx
+ if currentTok(p).kind == tkEof:
+ rstMessage(p, meExpected, "\"")
+ elif currentTok(p).symbol == "\"":
+ fieldValue.add "\""
+ inc p.idx
+ break
+ else:
+ while currentTok(p).kind notin {tkWhite, tkIndent, tkEof}:
+ fieldValue.add currentTok(p).symbol
+ inc p.idx
+ fieldBody.add newLeaf(fieldValue)
+ field.add(fieldBody)
+ result.add(field)
+
proc parseMarkdownCodeblock(p: var RstParser): PRstNode =
result = newRstNodeA(p, rnCodeBlock)
+ let line = curLine(p)
+ let baseCol = currentTok(p).col
+ let baseSym = currentTok(p).symbol # usually just ```
+ inc p.idx
result.info = lineInfo(p)
var args = newRstNode(rnDirArg)
+ var fields: PRstNode = nil
if currentTok(p).kind == tkWord:
args.add(newLeaf(p))
inc p.idx
+ fields = parseMarkdownCodeblockFields(p)
else:
args = nil
var n = newLeaf("")
while true:
- case currentTok(p).kind
- of tkEof:
- rstMessage(p, meExpected, "```")
+ if currentTok(p).kind == tkEof:
+ rstMessage(p, meMissingClosing,
+ "$1 (started at line $2)" % [baseSym, $line])
break
- of tkPunct, tkAdornment:
- if currentTok(p).symbol == "```":
- inc p.idx
- break
- else:
- n.text.add(currentTok(p).symbol)
- inc p.idx
+ elif nextTok(p).kind in {tkPunct, tkAdornment} and
+ nextTok(p).symbol[0] == baseSym[0] and
+ nextTok(p).symbol.len >= baseSym.len:
+ inc p.idx, 2
+ break
+ elif currentTok(p).kind == tkIndent:
+ n.text.add "\n"
+ if currentTok(p).ival > baseCol:
+ n.text.add " ".repeat(currentTok(p).ival - baseCol)
+ elif currentTok(p).ival < baseCol:
+ rstMessage(p, mwRstStyle,
+ "unexpected de-indentation in Markdown code block")
+ inc p.idx
else:
n.text.add(currentTok(p).symbol)
inc p.idx
var lb = newRstNode(rnLiteralBlock)
lb.add(n)
result.add(args)
- result.add(PRstNode(nil))
+ result.add(fields)
result.add(lb)
proc parseMarkdownLink(p: var RstParser; father: PRstNode): bool =
@@ -1730,6 +1801,12 @@ proc parseFootnoteName(p: var RstParser, reference: bool): PRstNode =
inc i
p.idx = i
+proc isMarkdownCodeBlock(p: RstParser): bool =
+ result = (roSupportMarkdown in p.s.options and
+ currentTok(p).kind in {tkPunct, tkAdornment} and
+ currentTok(p).symbol[0] == '`' and # tilde ~ is not supported
+ currentTok(p).symbol.len >= 3)
+
proc parseInline(p: var RstParser, father: PRstNode) =
var n: PRstNode # to be used in `if` condition
let saveIdx = p.idx
@@ -1755,8 +1832,7 @@ proc parseInline(p: var RstParser, father: PRstNode) =
addAnchorRst(p, name = linkName(n), refn = refn, reset = true,
anchorType=manualInlineAnchor)
father.add(n)
- elif roSupportMarkdown in p.s.options and currentTok(p).symbol == "```":
- inc p.idx
+ elif isMarkdownCodeBlock(p):
father.add(parseMarkdownCodeblock(p))
elif isInlineMarkupStart(p, "``"):
var n = newRstNode(rnInlineLiteral)
@@ -1816,8 +1892,7 @@ proc parseInline(p: var RstParser, father: PRstNode) =
return
parseWordOrRef(p, father)
of tkAdornment, tkOther, tkWhite:
- if roSupportMarkdown in p.s.options and currentTok(p).symbol == "```":
- inc p.idx
+ if isMarkdownCodeBlock(p):
father.add(parseMarkdownCodeblock(p))
return
if roSupportSmilies in p.s.options:
@@ -2194,7 +2269,7 @@ proc findPipe(p: RstParser, start: int): bool =
proc whichSection(p: RstParser): RstNodeKind =
if currentTok(p).kind in {tkAdornment, tkPunct}:
# for punctuation sequences that can be both tkAdornment and tkPunct
- if roSupportMarkdown in p.s.options and currentTok(p).symbol == "```":
+ if isMarkdownCodeBlock(p):
return rnCodeBlock
elif currentTok(p).symbol == "::":
return rnLiteralBlock
@@ -2633,7 +2708,9 @@ proc parseSimpleTable(p: var RstParser): PRstNode =
# fix rnTableDataCell -> rnTableHeaderCell for previous table rows:
for nRow in 0 ..< result.sons.len:
for nCell in 0 ..< result.sons[nRow].len:
- result.sons[nRow].sons[nCell].kind = rnTableHeaderCell
+ template cell: PRstNode = result.sons[nRow].sons[nCell]
+ cell = PRstNode(kind: rnTableHeaderCell, sons: cell.sons,
+ span: cell.span, anchor: cell.anchor)
if currentTok(p).kind == tkEof: break
let tabRow = parseSimpleTableRow(p, cols, colChar)
result.add tabRow
@@ -2892,11 +2969,19 @@ proc parseSection(p: var RstParser, result: PRstNode) =
if currInd(p) == currentTok(p).ival:
inc p.idx
elif currentTok(p).ival > currInd(p):
- pushInd(p, currentTok(p).ival)
- var a = newRstNodeA(p, rnBlockQuote)
- parseSection(p, a)
- result.add(a)
- popInd(p)
+ if roPreferMarkdown in p.s.options: # Markdown => normal paragraphs
+ if currentTok(p).ival - currInd(p) >= 4:
+ rstMessage(p, mwRstStyle,
+ "Markdown indented code not implemented")
+ pushInd(p, currentTok(p).ival)
+ parseSection(p, result)
+ popInd(p)
+ else: # RST mode => block quotes
+ pushInd(p, currentTok(p).ival)
+ var a = newRstNodeA(p, rnBlockQuote)
+ parseSection(p, a)
+ result.add(a)
+ popInd(p)
else:
while currentTok(p).kind != tkEof and nextTok(p).kind == tkIndent:
inc p.idx # skip blank lines
diff --git a/tests/stdlib/thighlite.nim b/tests/stdlib/thighlite.nim
index 4113a6a80e84c..5134215c1c8e9 100644
--- a/tests/stdlib/thighlite.nim
+++ b/tests/stdlib/thighlite.nim
@@ -12,6 +12,12 @@ block: # Nim tokenizing
@[("\"\"\"ok1\\nok2\\nok3\"\"\"", gtLongStringLit)
])
+ test "whitespace at beginning of line is preserved":
+ check(" discard 1".tokenize(langNim) ==
+ @[(" ", gtWhitespace), ("discard", gtKeyword), (" ", gtWhitespace),
+ ("1", gtDecNumber)
+ ])
+
block: # Cmd (shell) tokenizing
test "cmd with dollar and output":
check(
diff --git a/tests/stdlib/trst.nim b/tests/stdlib/trst.nim
index 24bc03027c3a1..823697336badc 100644
--- a/tests/stdlib/trst.nim
+++ b/tests/stdlib/trst.nim
@@ -24,8 +24,11 @@ import unittest, strutils
import std/private/miscdollars
import os
+const preferMarkdown = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}
+const preferRst = {roSupportMarkdown, roNimFile, roSandboxDisabled}
+
proc toAst(input: string,
- rstOptions: RstParseOptions = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled},
+ rstOptions: RstParseOptions = preferMarkdown,
error: ref string = nil,
warnings: ref seq[string] = nil): string =
## If `error` is nil then no errors should be generated.
@@ -451,7 +454,7 @@ suite "RST parsing":
> - y
>
> Paragraph.
- """.toAst == dedent"""
+ """.toAst(rstOptions = preferRst) == dedent"""
rnMarkdownBlockQuote
rnMarkdownBlockQuoteItem quotationDepth=1
rnInner
@@ -468,6 +471,93 @@ suite "RST parsing":
rnLeaf '.'
""")
+ test "Markdown code blocks with more > 3 backticks":
+ check(dedent"""
+ ````
+ let a = 1
+ ```
+ ````""".toAst ==
+ dedent"""
+ rnCodeBlock
+ [nil]
+ [nil]
+ rnLiteralBlock
+ rnLeaf '
+ let a = 1
+ ```'
+ """)
+
+ test "Markdown code blocks with Nim-specific arguments":
+ check(dedent"""
+ ```nim number-lines=1 test
+ let a = 1
+ ```""".toAst ==
+ dedent"""
+ rnCodeBlock
+ rnDirArg
+ rnLeaf 'nim'
+ rnFieldList
+ rnField
+ rnFieldName
+ rnLeaf 'number-lines'
+ rnFieldBody
+ rnLeaf '1'
+ rnField
+ rnFieldName
+ rnLeaf 'test'
+ rnFieldBody
+ rnLiteralBlock
+ rnLeaf '
+ let a = 1'
+ """)
+
+ check(dedent"""
+ ```nim test = "nim c $1" number-lines = 1
+ let a = 1
+ ```""".toAst ==
+ dedent"""
+ rnCodeBlock
+ rnDirArg
+ rnLeaf 'nim'
+ rnFieldList
+ rnField
+ rnFieldName
+ rnLeaf 'test'
+ rnFieldBody
+ rnLeaf '"nim c $1"'
+ rnField
+ rnFieldName
+ rnLeaf 'number-lines'
+ rnFieldBody
+ rnLeaf '1'
+ rnLiteralBlock
+ rnLeaf '
+ let a = 1'
+ """)
+
+ test "additional indentation < 4 spaces is handled fine":
+ check(dedent"""
+ Indentation
+
+ ```nim
+ let a = 1
+ ```""".toAst ==
+ dedent"""
+ rnInner
+ rnParagraph
+ rnLeaf 'Indentation'
+ rnParagraph
+ rnCodeBlock
+ rnDirArg
+ rnLeaf 'nim'
+ [nil]
+ rnLiteralBlock
+ rnLeaf '
+ let a = 1'
+ """)
+ # | |
+ # | \ indentation of exactly two spaces before 'let a = 1'
+
test "option list has priority over definition list":
check(dedent"""
--defusages
@@ -562,7 +652,7 @@ suite "RST parsing":
notAcomment1
notAcomment2
- someParagraph""".toAst ==
+ someParagraph""".toAst(rstOptions = preferRst) ==
dedent"""
rnInner
rnBlockQuote
@@ -574,6 +664,25 @@ suite "RST parsing":
rnLeaf 'someParagraph'
""")
+ test "check that additional line right after .. ends comment (Markdown mode)":
+ # in Markdown small indentation does not matter so this should
+ # just be split to 2 paragraphs.
+ check(dedent"""
+ ..
+
+ notAcomment1
+ notAcomment2
+ someParagraph""".toAst ==
+ dedent"""
+ rnInner
+ rnInner
+ rnLeaf 'notAcomment1'
+ rnLeaf ' '
+ rnLeaf 'notAcomment2'
+ rnParagraph
+ rnLeaf 'someParagraph'
+ """)
+
test "but blank lines after 2nd non-empty line don't end the comment":
check(dedent"""
..
@@ -592,7 +701,7 @@ suite "RST parsing":
..
- someBlockQuote""".toAst ==
+ someBlockQuote""".toAst(rstOptions = preferRst) ==
dedent"""
rnInner
rnAdmonition adType=note
diff --git a/tests/stdlib/trstgen.nim b/tests/stdlib/trstgen.nim
index d91b5615eb3b9..7fae4ba8b68a0 100644
--- a/tests/stdlib/trstgen.nim
+++ b/tests/stdlib/trstgen.nim
@@ -9,8 +9,13 @@ import ../../lib/packages/docutils/rst
import unittest, strutils, strtabs
import std/private/miscdollars
+const
+ NoSandboxOpts = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}
+ preferMarkdown = {roPreferMarkdown, roSupportMarkdown, roNimFile}
+ preferRst = {roSupportMarkdown, roNimFile}
+
proc toHtml(input: string,
- rstOptions: RstParseOptions = {roPreferMarkdown, roSupportMarkdown, roNimFile},
+ rstOptions: RstParseOptions = preferMarkdown,
error: ref string = nil,
warnings: ref seq[string] = nil): string =
## If `error` is nil then no errors should be generated.
@@ -47,9 +52,6 @@ proc optionListLabel(opt: string): string =
opt &
""
-const
- NoSandboxOpts = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}
-
suite "YAML syntax highlighting":
test "Basics":
@@ -1180,7 +1182,7 @@ Test1
"input(8, 4) Warning: language 'anotherLang' not supported"
])
check(output == "anything
" &
- "\nsomeCode\n
")
+ "\nsomeCode
")
test "RST admonitions":
# check that all admonitions are implemented
@@ -1321,7 +1323,7 @@ Test1
That was a transition.
"""
let output1 = input1.toHtml(
- NoSandboxOpts
+ preferRst
)
doAssert "text""" & "\n")
test "Field list: body after newline":
- let output = dedent """
+ let output = dedent"""
:field:
text1""".toHtml
check "