@@ -211,6 +180,8 @@ doc.body_toc_group = """
"""
@end
+doc.body_toc %= "${doc.body_toc_group}" # should only be used for boot
+
doc.body_no_toc = """
$moduledesc
$content
diff --git a/doc/idetools.rst b/doc/idetools.rst
index ebb140c5c..e83bfe935 100644
--- a/doc/idetools.rst
+++ b/doc/idetools.rst
@@ -13,6 +13,8 @@
"yes, I'm the creator" -- Araq, 2013-07-26 19:28:32.
+Note: this is mostly outdated, see instead `nimsuggest `_
+
Nim differs from many other compilers in that it is really fast,
and being so fast makes it suited to provide external queries for
text editors about the source code being written. Through the
diff --git a/koch.nim b/koch.nim
index ee7c8006a..c1d8df8da 100644
--- a/koch.nim
+++ b/koch.nim
@@ -651,6 +651,13 @@ when isMainModule:
of "latest": latest = true
of "stable": latest = false
of "nim": nimExe = op.val.absolutePath # absolute so still works with changeDir
+ of "docslocal":
+ # undocumented for now, allows to rebuild local docs in < 40s as follows:
+ # `./koch --nim:$nimb --docslocal:htmldocs2 --doccmd:skip --warnings:off --hints:off`
+ # whereas `./koch docs` takes 190s; useful for development.
+ doAssert op.val.len > 0
+ buildDocsDir(op.cmdLineRest, op.val)
+ break
else: showHelp()
of cmdArgument:
case normalize(op.key)
diff --git a/lib/std/private/globs.nim b/lib/std/private/globs.nim
new file mode 100644
index 000000000..e697ca91c
--- /dev/null
+++ b/lib/std/private/globs.nim
@@ -0,0 +1,54 @@
+##[
+unstable API, internal use only for now.
+this can eventually be moved to std/os and `walkDirRec` can be implemented in terms of this
+to avoid duplication
+]##
+
+import std/[os,strutils]
+
+type
+ PathEntry* = object
+ kind*: PathComponent
+ path*: string
+
+iterator walkDirRecFilter*(dir: string, follow: proc(entry: PathEntry): bool = nil,
+ relative = false, checkDir = true): PathEntry {.tags: [ReadDirEffect].} =
+ ## Improved `os.walkDirRec`.
+ #[
+ note: a yieldFilter isn't needed because caller can filter at call site, without
+ loss of generality, unlike `follow`.
+
+ Future work:
+ * need to document
+ * add a `sort` option, which can be implemented efficiently only here, not at call site.
+ * provide a way to do error reporting, which is tricky because iteration cannot be resumed
+ ]#
+ var stack = @["."]
+ var checkDir = checkDir
+ var entry: PathEntry
+ while stack.len > 0:
+ let d = stack.pop()
+ for k, p in walkDir(dir / d, relative = true, checkDir = checkDir):
+ let rel = d / p
+ entry.kind = k
+ if relative: entry.path = rel
+ else: entry.path = dir / rel
+ if k in {pcDir, pcLinkToDir}:
+ if follow == nil or follow(entry): stack.add rel
+ yield entry
+ checkDir = false
+ # We only check top-level dir, otherwise if a subdir is invalid (eg. wrong
+ # permissions), it'll abort iteration and there would be no way to
+ # continue iteration.
+
+proc nativeToUnixPath*(path: string): string =
+ # pending https://github.com/nim-lang/Nim/pull/13265
+ doAssert not path.isAbsolute # not implemented here; absolute files need more care for the drive
+ when DirSep == '\\':
+ result = replace(path, '\\', '/')
+ else: result = path
+
+when isMainModule:
+ import sugar
+ for a in walkDirRecFilter(".", follow = a=>a.path.lastPathPart notin ["nimcache", ".git", ".csources", "bin"]):
+ echo a
diff --git a/tests/misc/trunner.nim b/tests/misc/trunner.nim
index 566f9f033..382fd35ae 100644
--- a/tests/misc/trunner.nim
+++ b/tests/misc/trunner.nim
@@ -11,6 +11,7 @@ import std/[strformat,os,osproc,unittest]
from std/sequtils import toSeq,mapIt
from std/algorithm import sorted
import stdtest/[specialpaths, unittest_light]
+from std/private/globs import nativeToUnixPath
import "$lib/../compiler/nimpaths"
@@ -90,11 +91,7 @@ else: # don't run twice the same test
removeDir(htmldocsDir)
let (outp, exitCode) = execCmdEx(cmd)
check exitCode == 0
- proc nativeToUnixPathWorkaround(a: string): string =
- # xxx pending https://github.com/nim-lang/Nim/pull/13265 `nativeToUnixPath`
- a.replace(DirSep, '/')
-
- let ret = toSeq(walkDirRec(htmldocsDir, relative=true)).mapIt(it.nativeToUnixPathWorkaround).sorted.join("\n")
+ let ret = toSeq(walkDirRec(htmldocsDir, relative=true)).mapIt(it.nativeToUnixPath).sorted.join("\n")
let context = $(i, ret, cmd)
var expected = ""
case i
diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim
index c39a9c448..80aad4fb6 100644
--- a/tools/kochdocs.nim
+++ b/tools/kochdocs.nim
@@ -1,6 +1,7 @@
## Part of 'koch' responsible for the documentation generation.
import os, strutils, osproc, sets, pathnorm
+from std/private/globs import nativeToUnixPath, walkDirRecFilter, PathEntry
import "../compiler/nimpaths"
const
@@ -85,6 +86,16 @@ proc nimCompileFold*(desc, input: string, outputDir = "bin", mode = "c", options
let cmd = findNim().quoteShell() & " " & mode & " -o:" & output & " " & options & " " & input
execFold(desc, cmd)
+proc getRst2html(): seq[string] =
+ for a in walkDirRecFilter("doc"):
+ let path = a.path
+ if a.kind == pcFile and path.splitFile.ext == ".rst" and path.lastPathPart notin
+ ["docs.rst", "nimfix.rst"]:
+ # maybe we should still show nimfix, could help reviving it
+ # `docs` is redundant with `overview`, might as well remove that file?
+ result.add path
+ doAssert "doc/manual/var_t_return.rst".unixToNativePath in result # sanity check
+
const
pdf = """
doc/manual.rst
@@ -95,39 +106,6 @@ doc/tut3.rst
doc/nimc.rst
doc/niminst.rst
doc/gc.rst
-""".splitWhitespace()
-
- rst2html = """
-doc/intern.rst
-doc/apis.rst
-doc/lib.rst
-doc/manual.rst
-doc/manual_experimental.rst
-doc/destructors.rst
-doc/tut1.rst
-doc/tut2.rst
-doc/tut3.rst
-doc/nimc.rst
-doc/hcr.rst
-doc/drnim.rst
-doc/overview.rst
-doc/filters.rst
-doc/tools.rst
-doc/niminst.rst
-doc/nimgrep.rst
-doc/gc.rst
-doc/estp.rst
-doc/idetools.rst
-doc/docgen.rst
-doc/koch.rst
-doc/backends.rst
-doc/nimsuggest.rst
-doc/nep1.rst
-doc/nims.rst
-doc/contributing.rst
-doc/codeowners.rst
-doc/packaging.rst
-doc/manual/var_t_return.rst
""".splitWhitespace()
doc0 = """
@@ -185,7 +163,7 @@ proc getDocList(): seq[string] =
for a in withoutIndex: docIgnore.incl a
for a in ignoredModules: docIgnore.incl a
- # don't ignore these even though in lib/system
+ # don't ignore these even though in lib/system (not include files)
const goodSystem = """
lib/system/io.nim
lib/system/nimscript.nim
@@ -194,14 +172,14 @@ lib/system/iterators.nim
lib/system/dollars.nim
lib/system/widestrs.nim
""".splitWhitespace()
-
- for a in walkDirRec("lib"):
- if a.splitFile.ext != ".nim" or
- a.isRelativeTo("lib/pure/includes") or
- a.isRelativeTo("lib/genode") or
- a.isRelativeTo("lib/deprecated") or
- (a.isRelativeTo("lib/system") and a.replace('\\', '/') notin goodSystem) or
- a.replace('\\', '/') in docIgnore:
+
+ proc follow(a: PathEntry): bool =
+ a.path.lastPathPart notin ["nimcache", "htmldocs", "includes", "deprecated", "genode"]
+ for entry in walkDirRecFilter("lib", follow = follow):
+ let a = entry.path
+ if entry.kind != pcFile or a.splitFile.ext != ".nim" or
+ (a.isRelativeTo("lib/system") and a.nativeToUnixPath notin goodSystem) or
+ a.nativeToUnixPath in docIgnore:
continue
result.add a
result.add normalizePath("nimsuggest/sexp.nim")
@@ -231,16 +209,28 @@ proc buildDocSamples(nimArgs, destPath: string) =
[nimArgs, destPath / "docgen_sample.html", "doc" / "docgen_sample.nim"])
proc buildDocPackages(nimArgs, destPath: string) =
- # compiler docs, and later, other packages (perhaps tools, testament etc)
+ # compiler docs; later, other packages (perhaps tools, testament etc)
let nim = findNim().quoteShell()
- let extra = "-u:boot"
# to avoid broken links to manual from compiler dir, but a multi-package
# structure could be supported later
- exec("$1 doc --project --outdir:$2/compiler $3 --git.url:$4 $5 compiler/nim.nim" %
- [nim, destPath, nimArgs, gitUrl, extra])
+
+ proc docProject(outdir, options, mainproj: string) =
+ exec("$nim doc --project --outdir:$outdir $nimArgs --git.url:$gitUrl $options $mainproj" % [
+ "nim", nim,
+ "outdir", outdir,
+ "nimArgs", nimArgs,
+ "gitUrl", gitUrl,
+ "options", options,
+ "mainproj", mainproj,
+ ])
+ let extra = "-u:boot"
+ # xxx keep in sync with what's in $nim_prs_D/config/nimdoc.cfg, or, rather,
+ # start using nims instead of nimdoc.cfg
+ docProject(destPath/"compiler", extra, "compiler/index.nim")
proc buildDoc(nimArgs, destPath: string) =
# call nim for the documentation:
+ let rst2html = getRst2html()
var
commands = newSeq[string](rst2html.len + len(doc0) + len(doc) + withoutIndex.len)
i = 0
@@ -305,18 +295,19 @@ proc buildJS(): string =
let nim = findNim()
exec(nim.quoteShell() & " js -d:release --out:$1 tools/nimblepkglist.nim" %
[webUploadOutput / "nimblepkglist.js"])
+ # xxx deadcode? and why is it only for webUploadOutput, not for local docs?
result = getDocHacksJs(nimr = getCurrentDir(), nim)
-proc buildDocs*(args: string) =
+proc buildDocsDir*(args: string, dir: string) =
+ let args = nimArgs & " " & args
let docHackJsSource = buildJS()
- template fn(args, dir) =
- let dir2 = dir
- let args2 = args
- createDir(dir2)
- buildDocSamples(args2, dir2)
- buildDoc(args2, dir2)
- buildDocPackages(args2, dir2)
- copyFile(docHackJsSource, dir2 / docHackJsSource.lastPathPart)
+ createDir(dir)
+ buildDocSamples(args, dir)
+ buildDoc(args, dir) # bottleneck
+ copyFile(dir / "overview.html", dir / "index.html")
+ buildDocPackages(args, dir)
+ copyFile(docHackJsSource, dir / docHackJsSource.lastPathPart)
- fn(nimArgs & " " & args, webUploadOutput / NimVersion)
- fn(nimArgs, docHtmlOutput) # no `args` to avoid offline docs containing the 'gaCode'!
+proc buildDocs*(args: string) =
+ buildDocsDir(args, webUploadOutput / NimVersion)
+ buildDocsDir("", docHtmlOutput) # no `args` to avoid offline docs containing the 'gaCode'!
diff --git a/tools/nimblepkglist.nim b/tools/nimblepkglist.nim
index 870944ab0..c4bec4485 100644
--- a/tools/nimblepkglist.nim
+++ b/tools/nimblepkglist.nim
@@ -1,3 +1,6 @@
+#[
+deadcode?
+]#
import base64, strutils, json, htmlgen, dom, algorithm
type