Improve Markdown code blocks & start moving docs to Markdown style (#19954)

- 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
This commit is contained in:
Andrey Makarov 2022-07-15 20:27:54 +03:00 • committed by GitHub
commit 417b90a7e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 341 additions and 126 deletions

View file

@ -449,6 +449,8 @@ proc parseCommand*(command: string): Command =
of "doc2", "doc": cmdDoc of "doc2", "doc": cmdDoc
of "doc2tex": cmdDoc2tex of "doc2tex": cmdDoc2tex
of "rst2html": cmdRst2html of "rst2html": cmdRst2html
of "md2tex": cmdMd2tex
of "md2html": cmdMd2html
of "rst2tex": cmdRst2tex of "rst2tex": cmdRst2tex
of "jsondoc0": cmdJsondoc0 of "jsondoc0": cmdJsondoc0
of "jsondoc2", "jsondoc": cmdJsondoc of "jsondoc2", "jsondoc": cmdJsondoc
@ -480,7 +482,8 @@ proc setCommandEarly*(conf: ConfigRef, command: string) =
# command early customizations # command early customizations
# must be handled here to honor subsequent `--hint:x:on|off` # must be handled here to honor subsequent `--hint:x:on|off`
case conf.cmd 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} conf.foreignPackageNotes = {hintSuccessX}
else: else:
conf.foreignPackageNotes = foreignPackageNotesDefault conf.foreignPackageNotes = foreignPackageNotesDefault

View file

@ -88,7 +88,7 @@ type
jEntriesFinal: JsonNode # final JSON after RST pass 2 and rendering jEntriesFinal: JsonNode # final JSON after RST pass 2 and rendering
types: TStrTable types: TStrTable
sharedState: PRstSharedState sharedState: PRstSharedState
isPureRst: bool standaloneDoc: bool
conf*: ConfigRef conf*: ConfigRef
cache*: IdentCache cache*: IdentCache
exampleCounter: int exampleCounter: int
@ -230,6 +230,7 @@ template declareClosures =
case msgKind case msgKind
of meCannotOpenFile: k = errCannotOpenFile of meCannotOpenFile: k = errCannotOpenFile
of meExpected: k = errXExpected of meExpected: k = errXExpected
of meMissingClosing: k = errRstMissingClosing
of meGridTableNotImplemented: k = errRstGridTableNotImplemented of meGridTableNotImplemented: k = errRstGridTableNotImplemented
of meMarkdownIllformedTable: k = errRstMarkdownIllformedTable of meMarkdownIllformedTable: k = errRstMarkdownIllformedTable
of meIllformedTable: k = errRstIllformedTable 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, proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
outExt: string = HtmlExt, module: PSym = nil, outExt: string = HtmlExt, module: PSym = nil,
isPureRst = false): PDoc = standaloneDoc = false, preferMarkdown = true): PDoc =
declareClosures() declareClosures()
new(result) new(result)
result.module = module result.module = module
result.conf = conf result.conf = conf
result.cache = cache result.cache = cache
result.outDir = conf.outDir.string result.outDir = conf.outDir.string
result.isPureRst = isPureRst result.standaloneDoc = standaloneDoc
var options= {roSupportRawDirective, roSupportMarkdown, roPreferMarkdown, roSandboxDisabled} var options= {roSupportRawDirective, roSupportMarkdown, roSandboxDisabled}
if not isPureRst: options.incl roNimFile if preferMarkdown:
options.incl roPreferMarkdown
if not standaloneDoc: options.incl roNimFile
result.sharedState = newRstSharedState( result.sharedState = newRstSharedState(
options, filename.string, options, filename.string,
docgenFindFile, compilerMsgHandler) docgenFindFile, compilerMsgHandler)
@ -333,7 +336,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
# Make sure the destination directory exists # Make sure the destination directory exists
createDir(outp.splitFile.dir) createDir(outp.splitFile.dir)
# Include the current file if we're parsing a nim file # 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) writeFile(outp, importStmt & content)
proc interpSnippetCmd(cmd: string): string = 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])]) "\\\\\\vspace{0.5em}\\large $1", [esc(d.target, d.meta[metaSubtitle])])
var groupsection = getConfigVar(d.conf, "doc.body_toc_groupsection") 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 groupsection.setLen 0
"doc.body_toc_group" "doc.body_toc_group"
elif d.hasToc: "doc.body_toc" elif d.hasToc: "doc.body_toc"
@ -1626,9 +1629,11 @@ proc commandDoc*(cache: IdentCache, conf: ConfigRef) =
generateIndex(d) generateIndex(d)
proc commandRstAux(cache: IdentCache, conf: ConfigRef; proc commandRstAux(cache: IdentCache, conf: ConfigRef;
filename: AbsoluteFile, outExt: string) = filename: AbsoluteFile, outExt: string,
preferMarkdown: bool) =
var filen = addFileExt(filename, "txt") 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), let rst = parseRst(readFile(filen.string),
line=LineRstInit, column=ColRstInit, line=LineRstInit, column=ColRstInit,
conf, d.sharedState) conf, d.sharedState)
@ -1637,11 +1642,13 @@ proc commandRstAux(cache: IdentCache, conf: ConfigRef;
writeOutput(d) writeOutput(d)
generateIndex(d) generateIndex(d)
proc commandRst2Html*(cache: IdentCache, conf: ConfigRef) = proc commandRst2Html*(cache: IdentCache, conf: ConfigRef,
commandRstAux(cache, conf, conf.projectFull, HtmlExt) preferMarkdown=false) =
commandRstAux(cache, conf, conf.projectFull, HtmlExt, preferMarkdown)
proc commandRst2TeX*(cache: IdentCache, conf: ConfigRef) = proc commandRst2TeX*(cache: IdentCache, conf: ConfigRef,
commandRstAux(cache, conf, conf.projectFull, TexExt) preferMarkdown=false) =
commandRstAux(cache, conf, conf.projectFull, TexExt, preferMarkdown)
proc commandJson*(cache: IdentCache, conf: ConfigRef) = proc commandJson*(cache: IdentCache, conf: ConfigRef) =
## implementation of a deprecated jsondoc0 command ## implementation of a deprecated jsondoc0 command

View file

@ -32,6 +32,7 @@ type
# non-fatal errors # non-fatal errors
errIllFormedAstX, errCannotOpenFile, errIllFormedAstX, errCannotOpenFile,
errXExpected, errXExpected,
errRstMissingClosing,
errRstGridTableNotImplemented, errRstGridTableNotImplemented,
errRstMarkdownIllformedTable, errRstMarkdownIllformedTable,
errRstIllformedTable, errRstIllformedTable,
@ -105,6 +106,7 @@ const
errIllFormedAstX: "illformed AST: $1", errIllFormedAstX: "illformed AST: $1",
errCannotOpenFile: "cannot open '$1'", errCannotOpenFile: "cannot open '$1'",
errXExpected: "'$1' expected", errXExpected: "'$1' expected",
errRstMissingClosing: "$1",
errRstGridTableNotImplemented: "grid table is not implemented", errRstGridTableNotImplemented: "grid table is not implemented",
errRstMarkdownIllformedTable: "illformed delimiter row of a markdown table", errRstMarkdownIllformedTable: "illformed delimiter row of a markdown table",
errRstIllformedTable: "Illformed table: $1", errRstIllformedTable: "Illformed table: $1",

View file

@ -276,7 +276,8 @@ proc mainCommand*(graph: ModuleGraph) =
var ret = if optUseNimcache in conf.globalOptions: getNimcacheDir(conf) var ret = if optUseNimcache in conf.globalOptions: getNimcacheDir(conf)
else: conf.projectPath else: conf.projectPath
doAssert ret.string.isAbsolute # `AbsoluteDir` is not a real guarantee 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 conf.outDir = ret
## process all commands ## process all commands
@ -302,7 +303,7 @@ proc mainCommand*(graph: ModuleGraph) =
commandDoc2(graph, HtmlExt) commandDoc2(graph, HtmlExt)
if optGenIndex in conf.globalOptions and optWholeProject in conf.globalOptions: if optGenIndex in conf.globalOptions and optWholeProject in conf.globalOptions:
commandBuildIndex(conf, $conf.outDir) commandBuildIndex(conf, $conf.outDir)
of cmdRst2html: of cmdRst2html, cmdMd2html:
# XXX: why are warnings disabled by default for rst2html and rst2tex? # XXX: why are warnings disabled by default for rst2html and rst2tex?
for warn in rstWarnings: for warn in rstWarnings:
conf.setNoteDefaults(warn, true) conf.setNoteDefaults(warn, true)
@ -311,16 +312,16 @@ proc mainCommand*(graph: ModuleGraph) =
conf.quitOrRaise "compiler wasn't built with documentation generator" conf.quitOrRaise "compiler wasn't built with documentation generator"
else: else:
loadConfigs(DocConfig, cache, conf, graph.idgen) loadConfigs(DocConfig, cache, conf, graph.idgen)
commandRst2Html(cache, conf) commandRst2Html(cache, conf, preferMarkdown = (conf.cmd == cmdMd2html))
of cmdRst2tex, cmdDoc2tex: of cmdRst2tex, cmdMd2tex, cmdDoc2tex:
for warn in rstWarnings: for warn in rstWarnings:
conf.setNoteDefaults(warn, true) conf.setNoteDefaults(warn, true)
when defined(leanCompiler): when defined(leanCompiler):
conf.quitOrRaise "compiler wasn't built with documentation generator" conf.quitOrRaise "compiler wasn't built with documentation generator"
else: else:
if conf.cmd == cmdRst2tex: if conf.cmd in {cmdRst2tex, cmdMd2tex}:
loadConfigs(DocTexConfig, cache, conf, graph.idgen) loadConfigs(DocTexConfig, cache, conf, graph.idgen)
commandRst2TeX(cache, conf) commandRst2TeX(cache, conf, preferMarkdown = (conf.cmd == cmdMd2tex))
else: else:
docLikeCmd commandDoc2(graph, TexExt) docLikeCmd commandDoc2(graph, TexExt)
of cmdJsondoc0: docLikeCmd commandJson(cache, conf) of cmdJsondoc0: docLikeCmd commandJson(cache, conf)

View file

@ -122,7 +122,7 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
# `The parameter is incorrect` # `The parameter is incorrect`
let cmd = cmdPrefix & output.quoteShell & ' ' & conf.arguments let cmd = cmdPrefix & output.quoteShell & ' ' & conf.arguments
execExternalProgram(conf, cmd.strip(leading=false,trailing=true)) 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: if conf.arguments.len > 0:
# reserved for future use # reserved for future use
rawMessage(conf, errGenerated, "'$1 cannot handle arguments" % [$conf.cmd]) rawMessage(conf, errGenerated, "'$1 cannot handle arguments" % [$conf.cmd])

View file

@ -153,6 +153,8 @@ type
cmdDoc2tex # convert .nim doc comments to LaTeX cmdDoc2tex # convert .nim doc comments to LaTeX
cmdRst2html # convert a reStructuredText file to HTML cmdRst2html # convert a reStructuredText file to HTML
cmdRst2tex # convert a reStructuredText file to TeX cmdRst2tex # convert a reStructuredText file to TeX
cmdMd2html # convert a Markdown file to HTML
cmdMd2tex # convert a Markdown file to TeX
cmdJsondoc0 cmdJsondoc0
cmdJsondoc cmdJsondoc
cmdCtags cmdCtags

View file

@ -10,7 +10,8 @@
.. no syntax highlighting here by default: .. no syntax highlighting here by default:
.. contents:: .. contents::
"Heresy grows from idleness." -- Unknown.
> "Heresy grows from idleness." -- Unknown.
Introduction Introduction

View file

@ -581,7 +581,7 @@ Code reviews
.. include:: docstyle.rst .. include:: docstyle.md
Evolving the stdlib Evolving the stdlib

View file

@ -35,14 +35,13 @@ Quick start
Generate HTML documentation for a file: Generate HTML documentation for a file:
.. code:: cmd ```cmd
nim doc <filename>.nim nim doc <filename>.nim
```
Generate HTML documentation for a whole project: Generate HTML documentation for a whole project:
.. code:: cmd ```cmd
# delete any htmldocs/*.idx file before starting # delete any htmldocs/*.idx file before starting
nim doc --project --index:on --git.url:<url> --git.commit:<tag> --outdir:htmldocs <main_filename>.nim nim doc --project --index:on --git.url:<url> --git.commit:<tag> --outdir:htmldocs <main_filename>.nim
# this will generate html files, a theindex.html index, css and js under `htmldocs` # 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; # or `$nimcache/htmldocs` with `--usenimcache` which avoids clobbering your sources;
# and likewise without `--project`. # and likewise without `--project`.
# Adding `-r` will open in a browser directly. # Adding `-r` will open in a browser directly.
```
Documentation Comments Documentation Comments
---------------------- ----------------------
@ -120,8 +119,8 @@ Example of Nim file input
The following examples will generate documentation for this sample The following examples will generate documentation for this sample
*Nim* module, aptly named ``doc/docgen_sample.nim``: *Nim* module, aptly named ``doc/docgen_sample.nim``:
.. code:: nim ```nim file=docgen_sample.nim
:file: docgen_sample.nim ```
All the below commands save their output to ``htmldocs`` directory relative to All the below commands save their output to ``htmldocs`` directory relative to
the directory of file; the directory of file;
@ -137,9 +136,9 @@ optionally, an index file.
The `doc`:option: command: The `doc`:option: command:
.. code:: cmd ```cmd
nim doc docgen_sample.nim nim doc docgen_sample.nim
```
Partial Output:: Partial Output::
... ...
@ -159,8 +158,7 @@ HTML -> PDF conversion).
The `doc2tex`:option: command: The `doc2tex`:option: command:
.. code:: cmd ```cmd
nim doc2tex docgen_sample.nim nim doc2tex docgen_sample.nim
cd htmldocs cd htmldocs
xelatex docgen_sample.tex xelatex docgen_sample.tex
@ -169,6 +167,7 @@ The `doc2tex`:option: command:
# large documents) to get all labels generated. # large documents) to get all labels generated.
# That depends on this warning in the end of `xelatex` output: # That depends on this warning in the end of `xelatex` output:
# LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right. # LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
```
The output is ``docgen_sample.pdf``. 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: The `jsondoc`:option: command:
.. code:: cmd ```cmd
nim jsondoc docgen_sample.nim nim jsondoc docgen_sample.nim
```
Output:: Output::
{ {
@ -209,9 +208,9 @@ renamed to `jsondoc0`:option:.
The `jsondoc0`:option: command: The `jsondoc0`:option: command:
.. code:: cmd ```cmd
nim jsondoc0 docgen_sample.nim nim jsondoc0 docgen_sample.nim
```
Output:: Output::
[ [
@ -249,9 +248,9 @@ the anchor [*]_ of Nim symbol that corresponds to link text.
If you have a constant: If you have a constant:
.. code:: Nim ```Nim
const pi* = 3.14 const pi* = 3.14
```
then it should be referenced in one of the 2 forms: 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: For routine kinds there are more options. Consider this definition:
.. code:: Nim ```Nim
proc foo*(a: int, b: float): string proc foo*(a: int, b: float): string
```
Generally following syntax is allowed for referencing `foo`: Generally following syntax is allowed for referencing `foo`:
@ -352,11 +351,11 @@ recognized fine::
(without parameter names, see form A.2 above). (without parameter names, see form A.2 above).
E.g. for this signature: E.g. for this signature:
.. code:: Nim ```Nim
proc binarySearch*[T, K](a: openArray[T]; key: K; proc binarySearch*[T, K](a: openArray[T]; key: K;
cmp: proc (x: T; y: K): int {.closure.}): int cmp: proc (x: T; y: K): int {.closure.}): int
~~ ~~ ~~~~~ ~~ ~~ ~~~~~
```
you cannot use names underlined by `~~` so it must be referenced with you cannot use names underlined by `~~` so it must be referenced with
``cmp: proc(T, K)``. Hence these forms are valid:: ``cmp: proc(T, K)``. Hence these forms are valid::
@ -379,10 +378,10 @@ recognized fine::
.. Note:: A bit special case is operators .. Note:: A bit special case is operators
(as their signature is also defined with `\``): (as their signature is also defined with `\``):
.. code:: Nim ```Nim
func `$`(x: MyType): string func `$`(x: MyType): string
func `[]`*[T](x: openArray[T]): T func `[]`*[T](x: openArray[T]): T
```
A short form works without additional backticks:: A short form works without additional backticks::
@ -412,9 +411,9 @@ Related Options
Project switch Project switch
-------------- --------------
.. code:: cmd ```cmd
nim doc --project filename.nim nim doc --project filename.nim
```
This will recursively generate documentation of all Nim modules imported This will recursively generate documentation of all Nim modules imported
into the input module that belong to the Nimble package that ``filename.nim`` into the input module that belong to the Nimble package that ``filename.nim``
@ -425,9 +424,9 @@ also be generated.
Index switch Index switch
------------ ------------
.. code:: cmd ```cmd
nim doc --index:on filename.nim nim doc --index:on filename.nim
```
This will generate an index of all the exported symbols in the input 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 module, and put it into a neighboring file with the extension of ``.idx``. The
@ -443,9 +442,9 @@ file.
See source switch See source switch
----------------- -----------------
.. code:: cmd ```cmd
nim doc --git.url:<url> filename.nim nim doc --git.url:<url> filename.nim
```
With the `git.url`:option: switch the *See source* hyperlink will appear below each 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 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: Usage:
.. code:: cmd ```cmd
nim rst2html docgen.rst nim rst2html docgen.rst
```
Output:: Output::
You're reading it! You're reading it!

View file

@ -10,7 +10,7 @@
.. include:: rstcommon.rst .. include:: rstcommon.rst
.. contents:: .. contents::
"Abstraction is layering ignorance on top of reality." -- Richard Gabriel > "Abstraction is layering ignorance on top of reality." -- Richard Gabriel
Directory structure Directory structure

View file

@ -10,9 +10,9 @@ Nim Manual
.. contents:: .. contents::
"Complexity" seems to be a lot like "energy": you can transfer it from the > "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 > end-user to one/some of the other players, but the total amount seems to remain
pretty much constant for a given task. -- Ran > pretty much constant for a given task. -- Ran
About this document 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. starts with the prefix `m` per convention.
.. include:: manual/var_t_return.rst .. include:: manual/var_t_return.md
Future directions Future directions
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

View file

@ -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 non-nilable pointers. The details of this analysis are still to be specified
here. here.
.. include:: manual_experimental_strictnotnil.rst .. include:: manual_experimental_strictnotnil.md
Aliasing restrictions in parameter passing Aliasing restrictions in parameter passing

View file

@ -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 Multi-paradigm Memory Management Strategies

View file

@ -11,9 +11,9 @@
.. ..
"Look at you, hacker. A pathetic creature of meat and bone, panting and > "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, > sweating as you run through my corridors. How can you challenge a perfect,
immortal machine?" > immortal machine?"
Introduction Introduction

View file

@ -54,7 +54,7 @@ All examples below use default PCRE Regex patterns:
nimgrep --excludeDir:'^\.git$' --excludeDir:'^\.hg$' --excludeDir:'^\.svn$' nimgrep --excludeDir:'^\.git$' --excludeDir:'^\.hg$' --excludeDir:'^\.svn$'
# short: --ed:'^\.git$' --ed:'^\.hg$' --ed:'^\.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 .. code:: cmd
nimgrep --recursive --includeDir:'(^|/)tests($|/)' nimgrep --recursive --includeDir:'(^|/)tests($|/)'

View file

@ -5,5 +5,5 @@ Nim Documentation Overview
:Author: Andreas Rumpf :Author: Andreas Rumpf
:Version: |nimversion| :Version: |nimversion|
.. include:: docs.rst .. include:: docs.md

View file

@ -13,7 +13,7 @@ Nim Tutorial (Part II)
Introduction 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* This document is a tutorial for the advanced constructs of the *Nim*
programming language. **Note that this document is somewhat obsolete as the** programming language. **Note that this document is somewhat obsolete as the**

View file

@ -13,7 +13,7 @@ Nim Tutorial (Part III)
Introduction 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. This document is a tutorial about Nim's macro system.
A macro is a function that is executed at compile-time and transforms A macro is a function that is executed at compile-time and transforms

View file

@ -125,9 +125,7 @@ proc initGeneralTokenizer*(g: var GeneralTokenizer, buf: cstring) =
g.length = 0 g.length = 0
g.state = low(TokenClass) g.state = low(TokenClass)
g.lang = low(SourceLanguage) g.lang = low(SourceLanguage)
var pos = 0 # skip initial whitespace: g.pos = 0
while g.buf[pos] in {' ', '\t'..'\r'}: inc(pos)
g.pos = pos
proc initGeneralTokenizer*(g: var GeneralTokenizer, buf: string) = proc initGeneralTokenizer*(g: var GeneralTokenizer, buf: string) =
initGeneralTokenizer(g, cstring(buf)) initGeneralTokenizer(g, cstring(buf))

View file

@ -8,20 +8,23 @@
# #
## ================================== ## ==================================
## rst ## packages/docutils/rst
## ================================== ## ==================================
## ##
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Nim-flavored reStructuredText and Markdown ## 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 ## A large subset is implemented with some limitations_ and
## `Nim-specific features`_. ## `Nim-specific features`_.
## A few `extra features`_ of the `Markdown`:idx: syntax are ## Both Markdown and RST are mark-up languages whose goal is to
## also supported. ## 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 ## .. [#html] commands `nim doc`:cmd: for ``*.nim`` files and
## `nim rst2html`:cmd: for ``*.rst`` files ## `nim rst2html`:cmd: for ``*.rst`` files
@ -29,11 +32,13 @@
## .. [#latex] commands `nim doc2tex`:cmd: for ``*.nim`` and ## .. [#latex] commands `nim doc2tex`:cmd: for ``*.nim`` and
## `nim rst2tex`:cmd: for ``*.rst``. ## `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`_ ## 1) `Markdown Basic Syntax`_
## 2) an `RST reference`_: a comprehensive cheatsheet for RST ## 2) a long specification of Markdown: `CommonMark Spec`_
## 3) a more formal 50-page `RST specification`_. ## 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 ## Features
## -------- ## --------
@ -120,7 +125,13 @@
## ##
## * emoji / smiley symbols ## * emoji / smiley symbols
## * Markdown tables ## * 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 links
## * Markdown headlines ## * Markdown headlines
## * Markdown block quotes ## * Markdown block quotes
@ -211,6 +222,8 @@
## See `packages/docutils/rstgen module <rstgen.html>`_ to know how to ## See `packages/docutils/rstgen module <rstgen.html>`_ to know how to
## generate HTML or Latex strings to embed them into your documents. ## 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 ## .. _quick introduction: https://docutils.sourceforge.io/docs/user/rst/quickstart.html
## .. _RST reference: https://docutils.sourceforge.io/docs/user/rst/quickref.html ## .. _RST reference: https://docutils.sourceforge.io/docs/user/rst/quickref.html
## .. _RST specification: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html ## .. _RST specification: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html
@ -253,6 +266,7 @@ type
MsgKind* = enum ## the possible messages MsgKind* = enum ## the possible messages
meCannotOpenFile = "cannot open '$1'", meCannotOpenFile = "cannot open '$1'",
meExpected = "'$1' expected", meExpected = "'$1' expected",
meMissingClosing = "$1",
meGridTableNotImplemented = "grid table is not implemented", meGridTableNotImplemented = "grid table is not implemented",
meMarkdownIllformedTable = "illformed delimiter row of a Markdown table", meMarkdownIllformedTable = "illformed delimiter row of a Markdown table",
meIllformedTable = "Illformed table: $1", meIllformedTable = "Illformed table: $1",
@ -323,7 +337,10 @@ const
":geek:": "icon_e_geek", ":geek:": "icon_e_geek",
":ugeek:": "icon_e_ugeek" ":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 type
TokType = enum TokType = enum
@ -1616,27 +1633,81 @@ proc parseUntil(p: var RstParser, father: PRstNode, postfix: string,
inc p.idx inc p.idx
else: rstMessage(p, meExpected, postfix, line, col) 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 = proc parseMarkdownCodeblock(p: var RstParser): PRstNode =
result = newRstNodeA(p, rnCodeBlock) 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) result.info = lineInfo(p)
var args = newRstNode(rnDirArg) var args = newRstNode(rnDirArg)
var fields: PRstNode = nil
if currentTok(p).kind == tkWord: if currentTok(p).kind == tkWord:
args.add(newLeaf(p)) args.add(newLeaf(p))
inc p.idx inc p.idx
fields = parseMarkdownCodeblockFields(p)
else: else:
args = nil args = nil
var n = newLeaf("") var n = newLeaf("")
while true: while true:
case currentTok(p).kind if currentTok(p).kind == tkEof:
of tkEof: rstMessage(p, meMissingClosing,
rstMessage(p, meExpected, "```") "$1 (started at line $2)" % [baseSym, $line])
break break
of tkPunct, tkAdornment: elif nextTok(p).kind in {tkPunct, tkAdornment} and
if currentTok(p).symbol == "```": nextTok(p).symbol[0] == baseSym[0] and
inc p.idx nextTok(p).symbol.len >= baseSym.len:
inc p.idx, 2
break break
else: elif currentTok(p).kind == tkIndent:
n.text.add(currentTok(p).symbol) 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 inc p.idx
else: else:
n.text.add(currentTok(p).symbol) n.text.add(currentTok(p).symbol)
@ -1644,7 +1715,7 @@ proc parseMarkdownCodeblock(p: var RstParser): PRstNode =
var lb = newRstNode(rnLiteralBlock) var lb = newRstNode(rnLiteralBlock)
lb.add(n) lb.add(n)
result.add(args) result.add(args)
result.add(PRstNode(nil)) result.add(fields)
result.add(lb) result.add(lb)
proc parseMarkdownLink(p: var RstParser; father: PRstNode): bool = proc parseMarkdownLink(p: var RstParser; father: PRstNode): bool =
@ -1730,6 +1801,12 @@ proc parseFootnoteName(p: var RstParser, reference: bool): PRstNode =
inc i inc i
p.idx = 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) = proc parseInline(p: var RstParser, father: PRstNode) =
var n: PRstNode # to be used in `if` condition var n: PRstNode # to be used in `if` condition
let saveIdx = p.idx let saveIdx = p.idx
@ -1755,8 +1832,7 @@ proc parseInline(p: var RstParser, father: PRstNode) =
addAnchorRst(p, name = linkName(n), refn = refn, reset = true, addAnchorRst(p, name = linkName(n), refn = refn, reset = true,
anchorType=manualInlineAnchor) anchorType=manualInlineAnchor)
father.add(n) father.add(n)
elif roSupportMarkdown in p.s.options and currentTok(p).symbol == "```": elif isMarkdownCodeBlock(p):
inc p.idx
father.add(parseMarkdownCodeblock(p)) father.add(parseMarkdownCodeblock(p))
elif isInlineMarkupStart(p, "``"): elif isInlineMarkupStart(p, "``"):
var n = newRstNode(rnInlineLiteral) var n = newRstNode(rnInlineLiteral)
@ -1816,8 +1892,7 @@ proc parseInline(p: var RstParser, father: PRstNode) =
return return
parseWordOrRef(p, father) parseWordOrRef(p, father)
of tkAdornment, tkOther, tkWhite: of tkAdornment, tkOther, tkWhite:
if roSupportMarkdown in p.s.options and currentTok(p).symbol == "```": if isMarkdownCodeBlock(p):
inc p.idx
father.add(parseMarkdownCodeblock(p)) father.add(parseMarkdownCodeblock(p))
return return
if roSupportSmilies in p.s.options: if roSupportSmilies in p.s.options:
@ -2194,7 +2269,7 @@ proc findPipe(p: RstParser, start: int): bool =
proc whichSection(p: RstParser): RstNodeKind = proc whichSection(p: RstParser): RstNodeKind =
if currentTok(p).kind in {tkAdornment, tkPunct}: if currentTok(p).kind in {tkAdornment, tkPunct}:
# for punctuation sequences that can be both tkAdornment and 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 return rnCodeBlock
elif currentTok(p).symbol == "::": elif currentTok(p).symbol == "::":
return rnLiteralBlock return rnLiteralBlock
@ -2633,7 +2708,9 @@ proc parseSimpleTable(p: var RstParser): PRstNode =
# fix rnTableDataCell -> rnTableHeaderCell for previous table rows: # fix rnTableDataCell -> rnTableHeaderCell for previous table rows:
for nRow in 0 ..< result.sons.len: for nRow in 0 ..< result.sons.len:
for nCell in 0 ..< result.sons[nRow].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 if currentTok(p).kind == tkEof: break
let tabRow = parseSimpleTableRow(p, cols, colChar) let tabRow = parseSimpleTableRow(p, cols, colChar)
result.add tabRow result.add tabRow
@ -2892,6 +2969,14 @@ proc parseSection(p: var RstParser, result: PRstNode) =
if currInd(p) == currentTok(p).ival: if currInd(p) == currentTok(p).ival:
inc p.idx inc p.idx
elif currentTok(p).ival > currInd(p): elif currentTok(p).ival > currInd(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) pushInd(p, currentTok(p).ival)
var a = newRstNodeA(p, rnBlockQuote) var a = newRstNodeA(p, rnBlockQuote)
parseSection(p, a) parseSection(p, a)

View file

@ -12,6 +12,12 @@ block: # Nim tokenizing
@[("\"\"\"ok1\\nok2\\nok3\"\"\"", gtLongStringLit) @[("\"\"\"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 block: # Cmd (shell) tokenizing
test "cmd with dollar and output": test "cmd with dollar and output":
check( check(

View file

@ -24,8 +24,11 @@ import unittest, strutils
import std/private/miscdollars import std/private/miscdollars
import os import os
const preferMarkdown = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}
const preferRst = {roSupportMarkdown, roNimFile, roSandboxDisabled}
proc toAst(input: string, proc toAst(input: string,
rstOptions: RstParseOptions = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}, rstOptions: RstParseOptions = preferMarkdown,
error: ref string = nil, error: ref string = nil,
warnings: ref seq[string] = nil): string = warnings: ref seq[string] = nil): string =
## If `error` is nil then no errors should be generated. ## If `error` is nil then no errors should be generated.
@ -451,7 +454,7 @@ suite "RST parsing":
> - y > - y
> >
> Paragraph. > Paragraph.
""".toAst == dedent""" """.toAst(rstOptions = preferRst) == dedent"""
rnMarkdownBlockQuote rnMarkdownBlockQuote
rnMarkdownBlockQuoteItem quotationDepth=1 rnMarkdownBlockQuoteItem quotationDepth=1
rnInner rnInner
@ -468,6 +471,93 @@ suite "RST parsing":
rnLeaf '.' 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": test "option list has priority over definition list":
check(dedent""" check(dedent"""
--defusages --defusages
@ -562,7 +652,7 @@ suite "RST parsing":
notAcomment1 notAcomment1
notAcomment2 notAcomment2
someParagraph""".toAst == someParagraph""".toAst(rstOptions = preferRst) ==
dedent""" dedent"""
rnInner rnInner
rnBlockQuote rnBlockQuote
@ -574,6 +664,25 @@ suite "RST parsing":
rnLeaf 'someParagraph' 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": test "but blank lines after 2nd non-empty line don't end the comment":
check(dedent""" check(dedent"""
.. ..
@ -592,7 +701,7 @@ suite "RST parsing":
.. ..
someBlockQuote""".toAst == someBlockQuote""".toAst(rstOptions = preferRst) ==
dedent""" dedent"""
rnInner rnInner
rnAdmonition adType=note rnAdmonition adType=note

View file

@ -9,8 +9,13 @@ import ../../lib/packages/docutils/rst
import unittest, strutils, strtabs import unittest, strutils, strtabs
import std/private/miscdollars import std/private/miscdollars
const
NoSandboxOpts = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}
preferMarkdown = {roPreferMarkdown, roSupportMarkdown, roNimFile}
preferRst = {roSupportMarkdown, roNimFile}
proc toHtml(input: string, proc toHtml(input: string,
rstOptions: RstParseOptions = {roPreferMarkdown, roSupportMarkdown, roNimFile}, rstOptions: RstParseOptions = preferMarkdown,
error: ref string = nil, error: ref string = nil,
warnings: ref seq[string] = nil): string = warnings: ref seq[string] = nil): string =
## If `error` is nil then no errors should be generated. ## If `error` is nil then no errors should be generated.
@ -47,9 +52,6 @@ proc optionListLabel(opt: string): string =
opt & opt &
"</span></tt></div>" "</span></tt></div>"
const
NoSandboxOpts = {roPreferMarkdown, roSupportMarkdown, roNimFile, roSandboxDisabled}
suite "YAML syntax highlighting": suite "YAML syntax highlighting":
test "Basics": test "Basics":
@ -1180,7 +1182,7 @@ Test1
"input(8, 4) Warning: language 'anotherLang' not supported" "input(8, 4) Warning: language 'anotherLang' not supported"
]) ])
check(output == "<pre class = \"listing\">anything</pre>" & check(output == "<pre class = \"listing\">anything</pre>" &
"<p><pre class = \"listing\">\nsomeCode\n</pre> </p>") "<p><pre class = \"listing\">\nsomeCode</pre> </p>")
test "RST admonitions": test "RST admonitions":
# check that all admonitions are implemented # check that all admonitions are implemented
@ -1321,7 +1323,7 @@ Test1
That was a transition. That was a transition.
""" """
let output1 = input1.toHtml( let output1 = input1.toHtml(
NoSandboxOpts preferRst
) )
doAssert "<p id=\"target000\"" in output1 doAssert "<p id=\"target000\"" in output1
doAssert "<ul id=\"target001\"" in output1 doAssert "<ul id=\"target001\"" in output1
@ -1543,7 +1545,7 @@ Test1
"""<td>text</td></tr>""" & "\n</tbody></table>") """<td>text</td></tr>""" & "\n</tbody></table>")
test "Field list: body after newline": test "Field list: body after newline":
let output = dedent """ let output = dedent"""
:field: :field:
text1""".toHtml text1""".toHtml
check "<table class=\"docinfo\"" in output check "<table class=\"docinfo\"" in output

View file

@ -107,18 +107,18 @@ proc nimCompileFold*(desc, input: string, outputDir = "bin", mode = "c", options
let cmd = findNim().quoteShell() & " " & mode & " -o:" & output & " " & options & " " & input let cmd = findNim().quoteShell() & " " & mode & " -o:" & output & " " & options & " " & input
execFold(desc, cmd) execFold(desc, cmd)
proc getRst2html(): seq[string] = proc getMd2html(): seq[string] =
for a in walkDirRecFilter("doc"): for a in walkDirRecFilter("doc"):
let path = a.path let path = a.path
if a.kind == pcFile and path.splitFile.ext == ".rst" and path.lastPathPart notin if a.kind == pcFile and path.splitFile.ext == ".md" and path.lastPathPart notin
["docs.rst", "nimfix.rst", ["docs.md", "nimfix.md",
"docstyle.rst" # docstyle.rst shouldn't be converted to html separately; "docstyle.md" # docstyle.md shouldn't be converted to html separately;
# it's included in contributing.rst. # it's included in contributing.md.
]: ]:
# maybe we should still show nimfix, could help reviving it # maybe we should still show nimfix, could help reviving it
# `docs` is redundant with `overview`, might as well remove that file? # `docs` is redundant with `overview`, might as well remove that file?
result.add path result.add path
doAssert "doc/manual/var_t_return.rst".unixToNativePath in result # sanity check doAssert "doc/manual/var_t_return.md".unixToNativePath in result # sanity check
const const
rstPdfList = """ rstPdfList = """
@ -253,13 +253,13 @@ proc buildDocPackages(nimArgs, destPath: string) =
proc buildDoc(nimArgs, destPath: string) = proc buildDoc(nimArgs, destPath: string) =
# call nim for the documentation: # call nim for the documentation:
let rst2html = getRst2html() let rst2html = getMd2html()
var var
commands = newSeq[string](rst2html.len + len(doc0) + len(doc) + withoutIndex.len) commands = newSeq[string](rst2html.len + len(doc0) + len(doc) + withoutIndex.len)
i = 0 i = 0
let nim = findNim().quoteShell() let nim = findNim().quoteShell()
for d in items(rst2html): for d in items(rst2html):
commands[i] = nim & " rst2html $# --git.url:$# -o:$# --index:on $#" % commands[i] = nim & " md2html $# --git.url:$# -o:$# --index:on $#" %
[nimArgs, gitUrl, [nimArgs, gitUrl,
destPath / changeFileExt(splitFile(d).name, "html"), d] destPath / changeFileExt(splitFile(d).name, "html"), d]
i.inc i.inc