diff options
45 files changed, 1866 insertions, 494 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim index a252f505f..73140036a 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -820,7 +820,13 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; if conf != nil: conf.headerFile = arg incl(conf.globalOptions, optGenIndex) of "index": - processOnOffSwitchG(conf, {optGenIndex}, arg, pass, info) + case arg.normalize + of "", "on": conf.globalOptions.incl {optGenIndex} + of "only": conf.globalOptions.incl {optGenIndexOnly, optGenIndex} + of "off": conf.globalOptions.excl {optGenIndex, optGenIndexOnly} + else: localError(conf, info, errOnOrOffExpectedButXFound % arg) + of "noimportdoc": + processOnOffSwitchG(conf, {optNoImportdoc}, arg, pass, info) of "import": expectArg(conf, switch, arg, pass, info) if pass in {passCmd2, passPP}: diff --git a/compiler/docgen.nim b/compiler/docgen.nim index f8a804cec..cab334e7a 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -7,13 +7,17 @@ # distribution, for details about the copyright. # -# This is the documentation generator. Cross-references are generated -# by knowing how the anchors are going to be named. +## This is the Nim documentation generator. Cross-references are generated +## by knowing how the anchors are going to be named. +## +## .. importdoc:: ../docgen.md +## +## For corresponding users' documentation see [Nim DocGen Tools Guide]. import ast, strutils, strtabs, algorithm, sequtils, options, msgs, os, idents, wordrecg, syntaxes, renderer, lexer, - packages/docutils/[rst, rstgen, dochelpers], + packages/docutils/[rst, rstidx, rstgen, dochelpers], json, xmltree, trees, types, typesrenderer, astalgo, lineinfos, intsets, pathutils, tables, nimpaths, renderverbatim, osproc, packages @@ -91,7 +95,7 @@ type jEntriesFinal: JsonNode # final JSON after RST pass 2 and rendering types: TStrTable sharedState: PRstSharedState - standaloneDoc: bool + standaloneDoc: bool # is markup (.rst/.md) document? conf*: ConfigRef cache*: IdentCache exampleCounter: int @@ -225,7 +229,7 @@ proc attachToType(d: PDoc; p: PSym): PSym = if params.len > 0: check(0) for i in 2..<params.len: check(i) -template declareClosures = +template declareClosures(currentFilename: AbsoluteFile, destFile: string) = proc compilerMsgHandler(filename: string, line, col: int, msgKind: rst.MsgKind, arg: string) {.gcsafe.} = # translate msg kind: @@ -249,6 +253,7 @@ template declareClosures = of mwBrokenLink: k = warnRstBrokenLink of mwUnsupportedLanguage: k = warnRstLanguageXNotSupported of mwUnsupportedField: k = warnRstFieldXNotSupported + of mwUnusedImportdoc: k = warnRstUnusedImportdoc of mwRstStyle: k = warnRstStyle {.gcsafe.}: globalError(conf, newLineInfo(conf, AbsoluteFile filename, line, col), k, arg) @@ -259,10 +264,29 @@ template declareClosures = result = getCurrentDir() / s if not fileExists(result): result = "" + proc docgenFindRefFile(targetRelPath: string): + tuple[targetPath: string, linkRelPath: string] {.gcsafe.} = + let fromDir = splitFile(destFile).dir # dir where we reference from + let basedir = os.splitFile(currentFilename.string).dir + let outDirPath: RelativeFile = + presentationPath(conf, AbsoluteFile(basedir / targetRelPath)) + # use presentationPath because `..` path can be be mangled to `_._` + result.targetPath = string(conf.outDir / outDirPath) + if not fileExists(result.targetPath): + # this can happen if targetRelPath goes to parent directory `OUTDIR/..`. + # Trying it, this may cause ambiguities, but allows us to insert + # "packages" into each other, which is actually used in Nim repo itself. + let destPath = fromDir / targetRelPath + if destPath != result.targetPath and fileExists(destPath): + result.targetPath = destPath + + result.linkRelPath = relativePath(result.targetPath.splitFile.dir, + fromDir).replace('\\', '/') + + proc parseRst(text: string, line, column: int, conf: ConfigRef, sharedState: PRstSharedState): PRstNode = - declareClosures() result = rstParsePass1(text, line, column, sharedState) proc getOutFile2(conf: ConfigRef; filename: RelativeFile, @@ -283,7 +307,8 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef, outExt: string = HtmlExt, module: PSym = nil, standaloneDoc = false, preferMarkdown = true, hasToc = true): PDoc = - declareClosures() + let destFile = getOutFile2(conf, presentationPath(conf, filename), outExt, false).string + declareClosures(currentFilename = filename, destFile = destFile) new(result) result.module = module result.conf = conf @@ -298,7 +323,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef, result.hasToc = hasToc result.sharedState = newRstSharedState( options, filename.string, - docgenFindFile, compilerMsgHandler, hasToc) + docgenFindFile, docgenFindRefFile, compilerMsgHandler, hasToc) initRstGenerator(result[], (if conf.isLatexCmd: outLatex else: outHtml), conf.configVars, filename.string, docgenFindFile, compilerMsgHandler) @@ -373,7 +398,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef, if gotten != status: rawMessage(conf, errGenerated, "snippet failed: cmd: '$1' status: $2 expected: $3 output: $4" % [cmd, $gotten, $status, output]) result.emitted = initIntSet() - result.destFile = getOutFile2(conf, presentationPath(conf, filename), outExt, false).string + result.destFile = destFile result.thisDir = result.destFile.AbsoluteFile.splitFile.dir template dispA(conf: ConfigRef; dest: var string, xml, tex: string, @@ -765,21 +790,24 @@ proc isVisible(d: PDoc; n: PNode): bool = elif n.kind == nkPragmaExpr: result = isVisible(d, n[0]) -proc getName(d: PDoc, n: PNode, splitAfter = -1): string = +proc getName(n: PNode): string = case n.kind - of nkPostfix: result = getName(d, n[1], splitAfter) - of nkPragmaExpr: result = getName(d, n[0], splitAfter) - of nkSym: result = esc(d.target, n.sym.renderDefinitionName, splitAfter) - of nkIdent: result = esc(d.target, n.ident.s, splitAfter) + of nkPostfix: result = getName(n[1]) + of nkPragmaExpr: result = getName(n[0]) + of nkSym: result = n.sym.renderDefinitionName + of nkIdent: result = n.ident.s of nkAccQuoted: - result = esc(d.target, "`") - for i in 0..<n.len: result.add(getName(d, n[i], splitAfter)) - result.add esc(d.target, "`") + result = "`" + for i in 0..<n.len: result.add(getName(n[i])) + result = "`" of nkOpenSymChoice, nkClosedSymChoice: - result = getName(d, n[0], splitAfter) + result = getName(n[0]) else: result = "" +proc getNameEsc(d: PDoc, n: PNode): string = + esc(d.target, getName(n)) + proc getNameIdent(cache: IdentCache; n: PNode): PIdent = case n.kind of nkPostfix: result = getNameIdent(cache, n[1]) @@ -928,6 +956,13 @@ proc symbolPriority(k: TSymKind): int = else: 0 # including skProc which have higher priority # documentation itself has even higher priority 1 +proc getTypeKind(n: PNode): string = + case n[2].kind + of nkEnumTy: "enum" + of nkObjectTy: "object" + of nkTupleTy: "tuple" + else: "" + proc toLangSymbol(k: TSymKind, n: PNode, baseName: string): LangSymbol = ## Converts symbol info (names/types/parameters) in `n` into format ## `LangSymbol` convenient for ``rst.nim``/``dochelpers.nim``. @@ -971,17 +1006,13 @@ proc toLangSymbol(k: TSymKind, n: PNode, baseName: string): LangSymbol = if kind != tkSpaces: result.generics.add(literal.nimIdentNormalize) - if k == skType: - case n[2].kind - of nkEnumTy: result.symTypeKind = "enum" - of nkObjectTy: result.symTypeKind = "object" - of nkTupleTy: result.symTypeKind = "tuple" - else: discard + if k == skType: result.symTypeKind = getTypeKind(n) proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) = if (docFlags != kForceExport) and not isVisible(d, nameNode): return let - name = getName(d, nameNode) + name = getName(nameNode) + nameEsc = esc(d.target, name) var plainDocstring = getPlainDocstring(n) # call here before genRecComment! var result = "" var literal, plainName = "" @@ -1008,9 +1039,12 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) = inc(d.id) let plainNameEsc = esc(d.target, plainName.strip) - detailedName = k.toHumanStr & " " & ( + typeDescr = + if k == skType and getTypeKind(n) != "": getTypeKind(n) + else: k.toHumanStr + detailedName = typeDescr & " " & ( if k in routineKinds: plainName else: name) - uniqueName = if k in routineKinds: plainNameEsc else: name + uniqueName = if k in routineKinds: plainNameEsc else: nameEsc sortName = if k in routineKinds: plainName.strip else: name cleanPlainSymbol = renderPlainSymbolName(nameNode) complexSymbol = complexName(k, n, cleanPlainSymbol) @@ -1024,8 +1058,9 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) = let lineinfo = rstast.TLineInfo( line: nameNode.info.line, col: nameNode.info.col, fileIndex: addRstFileIndex(d, nameNode.info)) - addAnchorNim(d.sharedState, refn = symbolOrId, tooltip = detailedName, - rstLangSymbol, priority = symbolPriority(k), info = lineinfo) + addAnchorNim(d.sharedState, external = false, refn = symbolOrId, + tooltip = detailedName, langSym = rstLangSymbol, + priority = symbolPriority(k), info = lineinfo) nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments, renderDocComments, renderSyms, renderExpandUsing}, symbolOrIdEnc) @@ -1060,8 +1095,10 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) = if e.sym.kind != skEnumField: continue let plain = renderPlainSymbolName(e) let symbolOrId = d.newUniquePlainSymbol(plain) - setIndexTerm(d[], external, symbolOrId, plain, nameNode.sym.name.s & '.' & plain, - xmltree.escape(getPlainDocstring(e).docstringSummary)) + setIndexTerm(d[], ieNim, htmlFile = external, id = symbolOrId, + term = plain, linkTitle = nameNode.sym.name.s & '.' & plain, + linkDesc = xmltree.escape(getPlainDocstring(e).docstringSummary), + line = n.info.line.int) d.tocSimple[k].add TocItem( sortName: sortName, @@ -1076,22 +1113,17 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) = "itemSymOrID", symbolOrId.replace(",", ",<wbr>"), "itemSymOrIDEnc", symbolOrIdEnc]) - # Ironically for types the complexSymbol is *cleaner* than the plainName - # because it doesn't include object fields or documentation comments. So we - # use the plain one for callable elements, and the complex for the rest. - var linkTitle = changeFileExt(extractFilename(d.filename), "") & ": " - if n.kind in routineDefs: linkTitle.add(xmltree.escape(plainName.strip)) - else: linkTitle.add(xmltree.escape(complexSymbol.strip)) - - setIndexTerm(d[], external, symbolOrId, name, linkTitle, - xmltree.escape(plainDocstring.docstringSummary)) + setIndexTerm(d[], ieNim, htmlFile = external, id = symbolOrId, term = name, + linkTitle = detailedName, + linkDesc = xmltree.escape(plainDocstring.docstringSummary), + line = n.info.line.int) if k == skType and nameNode.kind == nkSym: d.types.strTableAdd nameNode.sym proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonItem = if not isVisible(d, nameNode): return var - name = getName(d, nameNode) + name = getNameEsc(d, nameNode) comm = genRecComment(d, n) r: TSrcGen initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments, renderExpandUsing}) @@ -1337,9 +1369,31 @@ proc generateDoc*(d: PDoc, n, orig: PNode, docFlags: DocFlags = kDefault) = proc overloadGroupName(s: string, k: TSymKind): string = ## Turns a name like `f` into anchor `f-procs-all` - #s & " " & k.toHumanStr & "s all" s & "-" & k.toHumanStr & "s-all" +proc setIndexTitle(d: PDoc, useMetaTitle: bool) = + let titleKind = if d.standaloneDoc: ieMarkupTitle else: ieNimTitle + let external = AbsoluteFile(d.destFile) + .relativeTo(d.conf.outDir, '/') + .changeFileExt(HtmlExt) + .string + var term, linkTitle: string + if useMetaTitle and d.meta[metaTitle].len != 0: + term = d.meta[metaTitleRaw] + linkTitle = d.meta[metaTitleRaw] + else: + let filename = extractFilename(d.filename) + term = + if d.standaloneDoc: filename # keep .rst/.md extension + else: changeFileExt(filename, "") # rm .nim extension + linkTitle = + if d.standaloneDoc: term # keep .rst/.md extension + else: canonicalImport(d.conf, AbsoluteFile d.filename) + if not d.standaloneDoc: + linkTitle = "module " & linkTitle + setIndexTerm(d[], titleKind, htmlFile = external, id = "", + term = term, linkTitle = linkTitle) + proc finishGenerateDoc*(d: var PDoc) = ## Perform 2nd RST pass for resolution of links/footnotes/headings... # copy file map `filenames` to ``rstgen.nim`` for its warnings @@ -1352,7 +1406,24 @@ proc finishGenerateDoc*(d: var PDoc) = firstRst = fragment.rst break d.hasToc = d.hasToc or d.sharedState.hasToc - preparePass2(d.sharedState, firstRst) + # in --index:only mode we do NOT want to load other .idx, only write ours: + let importdoc = optGenIndexOnly notin d.conf.globalOptions and + optNoImportdoc notin d.conf.globalOptions + preparePass2(d.sharedState, firstRst, importdoc) + + if optGenIndexOnly in d.conf.globalOptions: + # Top-level doc.comments may contain titles and :idx: statements: + for fragment in d.modDescPre: + if fragment.isRst: + traverseForIndex(d[], fragment.rst) + setIndexTitle(d, useMetaTitle = d.standaloneDoc) + # Symbol-associated doc.comments may contain :idx: statements: + for k in TSymKind: + for _, overloadChoices in d.section[k].secItems: + for item in overloadChoices: + for fragment in item.descRst: + if fragment.isRst: + traverseForIndex(d[], fragment.rst) # add anchors to overload groups before RST resolution for k in TSymKind: @@ -1362,14 +1433,25 @@ proc finishGenerateDoc*(d: var PDoc) = let refn = overloadGroupName(plainName, k) let tooltip = "$1 ($2 overloads)" % [ k.toHumanStr & " " & plainName, $overloadChoices.len] - addAnchorNim(d.sharedState, refn, tooltip, + let name = nimIdentBackticksNormalize(plainName) + # save overload group to ``.idx`` + let external = d.destFile.AbsoluteFile.relativeTo(d.conf.outDir, '/'). + changeFileExt(HtmlExt).string + setIndexTerm(d[], ieNimGroup, htmlFile = external, id = refn, + term = name, linkTitle = k.toHumanStr, + linkDesc = "", line = overloadChoices[0].info.line.int) + if optGenIndexOnly in d.conf.globalOptions: continue + addAnchorNim(d.sharedState, external=false, refn, tooltip, LangSymbol(symKind: k.toHumanStr, - name: nimIdentBackticksNormalize(plainName), + name: name, isGroup: true), priority = symbolPriority(k), # select index `0` just to have any meaningful warning: info = overloadChoices[0].info) + if optGenIndexOnly in d.conf.globalOptions: + return + # Finalize fragments of ``.nim`` or ``.rst`` file proc renderItemPre(d: PDoc, fragments: ItemPre, result: var string) = for f in fragments: @@ -1421,6 +1503,9 @@ proc finishGenerateDoc*(d: var PDoc) = d.jEntriesFinal.add entry.json # generates docs + setIndexTitle(d, useMetaTitle = d.standaloneDoc) + completePass2(d.sharedState) + proc add(d: PDoc; j: JsonItem) = if j.json != nil or j.rst != nil: d.jEntriesPre.add j @@ -1467,7 +1552,7 @@ proc generateJson*(d: PDoc, n: PNode, includeComments: bool = true) = else: discard proc genTagsItem(d: PDoc, n, nameNode: PNode, k: TSymKind): string = - result = getName(d, nameNode) & "\n" + result = getNameEsc(d, nameNode) & "\n" proc generateTags*(d: PDoc, n: PNode, r: var string) = case n.kind @@ -1574,13 +1659,7 @@ proc genOutFile(d: PDoc, groupedToc = false): string = # Extract the title. Non API modules generate an entry in the index table. if d.meta[metaTitle].len != 0: title = d.meta[metaTitle] - let external = AbsoluteFile(d.destFile) - .relativeTo(d.conf.outDir, '/') - .changeFileExt(HtmlExt) - .string - setIndexTerm(d[], external, "", title) else: - # Modules get an automatic title for the HTML, but no entry in the index. title = canonicalImport(d.conf, AbsoluteFile d.filename) title = esc(d.target, title) var subtitle = "" @@ -1619,11 +1698,17 @@ proc genOutFile(d: PDoc, groupedToc = false): string = code = content result = code +proc indexFile(d: PDoc): AbsoluteFile = + let dir = d.conf.outDir + result = dir / changeFileExt(presentationPath(d.conf, + AbsoluteFile d.filename), + IndexExt) + let (finalDir, _, _) = result.string.splitFile + createDir(finalDir) + proc generateIndex*(d: PDoc) = if optGenIndex in d.conf.globalOptions: - let dir = d.conf.outDir - createDir(dir) - let dest = dir / changeFileExt(presentationPath(d.conf, AbsoluteFile d.filename), IndexExt) + let dest = indexFile(d) writeIndexFile(d[], dest.string) proc updateOutfile(d: PDoc, outfile: AbsoluteFile) = @@ -1634,6 +1719,9 @@ proc updateOutfile(d: PDoc, outfile: AbsoluteFile) = d.conf.outFile = splitPath(d.conf.outFile.string)[1].RelativeFile proc writeOutput*(d: PDoc, useWarning = false, groupedToc = false) = + if optGenIndexOnly in d.conf.globalOptions: + d.conf.outFile = indexFile(d).relativeTo(d.conf.outDir) # just for display + return runAllExamples(d) var content = genOutFile(d, groupedToc) if optStdout in d.conf.globalOptions: @@ -1772,6 +1860,8 @@ proc commandTags*(cache: IdentCache, conf: ConfigRef) = rawMessage(conf, errCannotOpenFile, filename.string) proc commandBuildIndex*(conf: ConfigRef, dir: string, outFile = RelativeFile"") = + if optGenIndexOnly in conf.globalOptions: + return var content = mergeIndexes(dir) var outFile = outFile diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index cb60d8949..89aff57df 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -57,6 +57,7 @@ type warnRstBrokenLink = "BrokenLink", warnRstLanguageXNotSupported = "LanguageXNotSupported", warnRstFieldXNotSupported = "FieldXNotSupported", + warnRstUnusedImportdoc = "UnusedImportdoc", warnRstStyle = "warnRstStyle", warnCommentXIgnored = "CommentXIgnored", warnTypelessParam = "TypelessParam", @@ -142,6 +143,7 @@ const warnRstBrokenLink: "broken link '$1'", warnRstLanguageXNotSupported: "language '$1' not supported", warnRstFieldXNotSupported: "field '$1' not supported", + warnRstUnusedImportdoc: "importdoc for '$1' is not used", warnRstStyle: "RST style: $1", warnCommentXIgnored: "comment '$1' ignored", warnTypelessParam: "", # deadcode diff --git a/compiler/options.nim b/compiler/options.nim index 47e8155f8..fc970e420 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -78,6 +78,8 @@ type # please make sure we have under 32 options optThreadAnalysis, # thread analysis pass optTlsEmulation, # thread var emulation turned on optGenIndex # generate index file for documentation; + optGenIndexOnly # generate only index file for documentation + optNoImportdoc # disable loading external documentation files optEmbedOrigSrc # embed the original source in the generated code # also: generate header file optIdeDebug # idetools: debug mode diff --git a/doc/advopt.txt b/doc/advopt.txt index 3f439fdab..efff428e8 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -130,7 +130,9 @@ Advanced options: select which memory management to use; default is 'orc' --exceptions:setjmp|cpp|goto|quirky select the exception handling implementation - --index:on|off turn index file generation on|off + --index:on|off|only docgen: turn index file generation? (`only` means + not generate output files like HTML) + --noImportdoc:on|off disable loading documentation ``.idx`` files? --putenv:key=value set an environment variable --NimblePath:PATH add a path for Nimble support --noNimblePath deactivate the Nimble path diff --git a/doc/docgen.md b/doc/docgen.md index e4b040064..70b41f17d 100644 --- a/doc/docgen.md +++ b/doc/docgen.md @@ -9,6 +9,7 @@ .. include:: rstcommon.rst .. contents:: +.. importdoc:: markdown_rst.md, compiler/docgen.nim Introduction ============ @@ -103,6 +104,64 @@ won't influence RST formatting. ## Paragraph. ``` +Structuring output directories +------------------------------ + +Basic directory for output is set by `--outdir:OUTDIR`:option: switch, +by default `OUTDIR` is ``htmldocs`` sub-directory in the directory of +the processed file. + +There are 2 basic options as to how generated HTML output files are stored: + +1) complex hierarchy when docgen-compiling with `--project`:option:, + which follows directory structure of the project itself. + So `nim doc`:cmd: replicates project's directory structure + inside `--outdir:OUTDIR`:option: directory. + `--project`:option: is well suited for projects that have 1 main module. + File name clashes are impossible in this case. + +2) flattened structure, where user-provided script goes through all + needed input files and calls commands like `nim doc`:cmd: + with `--outdir:OUTDIR`:option: switch, thus putting all HTML (and + ``.idx``) files into 1 directory. + + .. Important:: Make sure that you don't have files with same base name + like ``x.nim`` and ``x.md`` in the same package, otherwise you'll + have name conflict for ``x.html``. + + .. Tip:: To structure your output directories and avoid file name + clashes you can split your project into + different *packages* -- parts of your repository that are + docgen-compiled with different `--outdir:OUTDIR`:option: options. + + An example of such strategy is Nim repository itself which has: + + * its stdlib ``.nim`` files from different directories and ``.md`` + documentation from ``doc/`` directory are all docgen-compiled + into `--outdir:web/upload/<version>/`:option: directory + * its ``.nim`` files from ``compiler/`` directory are docgen-compiled + into `--outdir:web/upload/<version>/compiler/`:option: directory. + Interestingly, it's compiled with complex hierarchy using + `--project`:option: switch. + + Contents of ``web/upload/<version>`` are then deployed into Nim's + Web server. + + This output directory structure allows to work correctly with files like + ``compiler/docgen.nim`` (implementation) and ``doc/docgen.md`` (user + documentation) in 1 repository. + + +Index files +----------- + +Index (``.idx``) files are used for 2 different purposes: + +1. easy cross-referencing between different ``.nim`` and/or ``.md`` / ``.rst`` + files described in [Nim external referencing] +2. creating a whole-project index for searching of symbols and keywords, + see [Buildindex command]. + Document Types ============== @@ -226,13 +285,46 @@ Note that the `jsondoc`:option: command outputs its JSON without pretty-printing while `jsondoc0`:option: outputs pretty-printed JSON. -Referencing Nim symbols: simple documentation links -=================================================== - -You can reference Nim identifiers from Nim documentation comments, currently -only inside their ``.nim`` file (or inside a ``.rst`` file included from -a ``.nim``). The point is that such links will be resolved automatically -by `nim doc`:cmd: (or `nim jsondoc`:cmd: or `nim doc2tex`:cmd:). +Simple documentation links +========================== + +It's possible to use normal Markdown/RST syntax to *manually* +reference Nim symbols using HTML anchors, however Nim has an *automatic* +facility that makes referencing inside ``.nim`` and ``.md/.rst`` files and +between them easy and seamless. +The point is that such links will be resolved automatically +by `nim doc`:cmd: (or `md2html`:option:, or `jsondoc`:option:, +or `doc2tex`:option:, ...). And, unlike manual links, such automatic +links **check** that their target exists -- a warning is emitted for +any broken link, so you avoid broken links in your project. + +Nim treats both ``.md/.rst`` files and ``.nim`` modules (their doc comment +part) as *documents* uniformly. +Hence all directions of referencing are equally possible having the same syntax: + +1. ``.md/rst`` -> itself (internal). See [Markup local referencing]. +2. ``.md/rst`` -> external ``.md/rst``. See [Markup external referencing]. + To summarize, referencing in `.md`/`.rst` files was already described in + [Nim-flavored Markdown and reStructuredText] + (particularly it described usage of index files for referencing), + while in this document we focus on Nim-specific details. +3. ``.md/rst`` -> external ``.nim``. See [Nim external referencing]. +4. ``.nim`` -> itself (internal). See [Nim local referencing]. +5. ``.nim`` -> external ``.md/rst``. See [Markup external referencing]. +6. ``.nim`` -> external ``.nim``. See [Nim external referencing]. + +To put it shortly, local referencing always works out of the box, +external referencing requires to use ``.. importdoc:: <file>`` +directive to import `file` and to ensure that the corresponding +``.idx`` file was generated. + + +Nim local referencing +--------------------- + +You can reference Nim identifiers from Nim documentation comments +inside their ``.nim`` file (or inside a ``.rst`` file included from +a ``.nim``). This pertains to any exported symbol like `proc`, `const`, `iterator`, etc. Syntax for referencing is basically a normal RST one: addition of underscore `_` to a *link text*. @@ -405,6 +497,143 @@ recognized fine: ... ## Ref. `CopyFlag enum`_ +Nim external referencing +------------------------ + +Just like for [Markup external referencing], which saves markup anchors, +the Nim symbols are also saved in ``.idx`` files, so one needs +to generate them beforehand, and they should be loaded by +an ``.. importdoc::`` directive. Arguments to ``.. importdoc::`` is a +comma-separated list of Nim modules or Markdown/RST documents. + +`--index:only`:option: tells Nim to only generate ``.idx`` file and +do **not** attempt to generate HTML/LaTeX output. +For ``.nim`` modules there are 2 alternatives to work with ``.idx`` files: + +1. using [Project switch] implies generation of ``.idx`` files, + however, if ``importdoc`` is called on upper modules as its arguments, + their ``.idx`` are not yet created. Thus one should generate **all** + required ``.idx`` first: + ```cmd + nim doc --project --index:only <main>.nim + nim doc --project <main>.nim + ``` +2. or run `nim doc --index:only <module.nim>`:cmd: command for **all** (used) + Nim modules in your project. Then run `nim doc <module.nim>` on them for + output HTML generation. + + .. Warning:: A mere `nim doc --index:on`:cmd: may fail on an attempt to do + ``importdoc`` from another module (for which ``.idx`` was not yet + generated), that's why `--index:only`:option: shall be used instead. + + For ``.md``/``.rst`` markup documents point 2 is the only option. + +Then, you can freely use something like this in ``your_module.nim``: + + ```nim + ## .. importdoc:: user_manual.md, another_module.nim + + ... + ## Ref. [some section from User Manual]. + + ... + ## Ref. [proc f] + ## (assuming you have a proc `f` in ``another_module``). + ``` + +and compile it by `nim doc`:cmd:. Note that link text will +be automatically prefixed by the module name of symbol, +so you will see something like "Ref. [another_module: proc f](#)" +in the generated output. + +It's also possible to reference a whole module by prefixing or +suffixing full canonical module name with "module": + + Ref. [module subdir/name] or [subdir/name module]. + +Markup documents as a whole can be referenced just by their title +(or by their file name if the title was not set) without any prefix. + +.. Tip:: During development process the stage of ``.idx`` files generation + can be done only *once*, after that you use already generated ``.idx`` + files while working with a document *being developed* (unless you do + incompatible changes to *referenced* documents). + +.. Hint:: After changing a *referenced* document file one may need + to regenerate its corresponding ``.idx`` file to get correct results. + Of course, when referencing *internally* inside any given ``.nim`` file, + it's not needed, one can even immediately use any freshly added anchor + (a document's own ``.idx`` file is not used for resolving its internal links). + +If an ``importdoc`` directive fails to find a ``.idx``, then an error +is emitted. + +In case of such compilation failures please note that: + +* **all** relative paths, given to ``importdoc``, relate to insides of + ``OUTDIR``, and **not** project's directory structure. + +* ``importdoc`` searches for ``.idx`` in `--outdir:OUTDIR`:option: directory + (``htmldocs`` by default) and **not** around original modules, so: + + .. Tip:: look into ``OUTDIR`` to understand what's going on. + +* also keep in mind that ``.html`` and ``.idx`` files should always be + output to the same directory, so check this and, if it's not true, check + that both runs *with* and *without* `--index:only`:option: have all + other options the same. + +To summarize, for 2 basic options of [Structuring output directories] +compilation options are different: + +1) complex hierarchy with `--project`:option: switch. + + As the **original** project's directory structure is replicated in + `OUTDIR`, all passed paths are related to this structure also. + + E.g. if a module ``path1/module.nim`` does + ``.. importdoc:: path2/another.nim`` then docgen tries to load file + ``OUTDIR/path1/path2/another.idx``. + + .. Note:: markup documents are just placed into the specified directory + `OUTDIR`:option: by default (i.e. they are **not** affected by + `--project`:option:), so if you have ``PROJECT/doc/manual.md`` + document and want to use complex hirearchy (with ``doc/``), + compile it with `--docroot`:option:\: + ```cmd + # 1st stage + nim md2html --outdir:OUTDIR --docroot:/absolute/path/to/PROJECT \ + --index:only PROJECT/doc/manual.md + ... + # 2nd stage + nim md2html --outdir:OUTDIR --docroot:/absolute/path/to/PROJECT \ + PROJECT/doc/manual.md + ``` + + Then the output file will be placed as ``OUTDIR/doc/manual.idx``. + So if you have ``PROJECT/path1/module.nim``, then ``manual.md`` can + be referenced as ``../doc/manual.md``. + +2) flattened structure. + + E.g. if a module ``path1/module.nim`` does + ``.. importdoc:: path2/another.nim`` then docgen tries to load + ``OUTDIR/path2/another.idx``, so the path ``path1`` + does not matter and providing ``path2`` can be useful only + in the case it contains another package that was placed there + using `--outdir:OUTDIR/path2`:option:. + + The links' text will be prefixed as ``another: ...`` in both cases. + + .. Warning:: Again, the same `--outdir:OUTDIR`:option: option should + be provided to both `doc --index:only`:option: / + `md2html --index:only`:option: and final generation by + `doc`:option:/`md2html`:option: inside 1 package. + +To temporarily disable ``importdoc``, e.g. if you don't need +correct link resolution at the moment, use a `--noImportdoc`:option: switch +(only warnings about unresolved links will be generated for external references). + Related Options =============== @@ -434,10 +663,21 @@ index file is line-oriented (newlines have to be escaped). Each line represents a tab-separated record of several columns, the first two mandatory, the rest optional. See the [Index (idx) file format] section for details. +.. Note:: `--index`:option: switch only affects creation of ``.idx`` + index files, while user-searchable Index HTML file is created by + `buildIndex`:option: commmand. + +Buildindex command +------------------ + Once index files have been generated for one or more modules, the Nim -compiler command `buildIndex directory` can be run to go over all the index +compiler command `nim buildIndex directory`:cmd: can be run to go over all the index files in the specified directory to generate a [theindex.html](theindex.html) -file. +file: + + ```cmd + nim buildIndex -o:path/to/htmldocs/theindex.html path/to/htmldocs + ``` See source switch ----------------- @@ -568,10 +808,22 @@ references so they can be later concatenated into a big index file with the file format in detail. Index files are line-oriented and tab-separated (newline and tab characters -have to be escaped). Each line represents a record with at least two fields -but can have up to four (additional columns are ignored). The content of these -columns is: - +have to be escaped). Each line represents a record with 6 fields. +The content of these columns is: + +0. Discriminator tag denoting type of the index entry, allowed values are: + `markupTitle` + : a title for ``.md``/``.rst`` document + `nimTitle` + : a title of ``.nim`` module + `heading` + : heading of sections, can be both in Nim and markup files + `idx` + : terms marked with :idx: role + `nim` + : a Nim symbol + `nimgrp` + : a Nim group for overloadable symbols like `proc`s 1. Mandatory term being indexed. Terms can include quoting according to Nim's rules (e.g. \`^\`). 2. Base filename plus anchor hyperlink (e.g. ``algorithm.html#*,int,SortOrder``). @@ -581,29 +833,20 @@ columns is: not for an API symbol but for a TOC entry. 4. Optional title or description of the hyperlink. Browsers usually display this as a tooltip after hovering a moment over the hyperlink. +5. A line number of file where the entry was defined. + +The index generation tools differentiate between documentation +generated from ``.nim`` files and documentation generated from ``.md`` or +``.rst`` files by tag `nimTitle` or `markupTitle` in the 1st line of +the ``.idx`` file. -The index generation tools try to differentiate between documentation -generated from ``.nim`` files and documentation generated from ``.txt`` or -``.rst`` files. The former are always closely related to source code and -consist mainly of API entries. The latter are generic documents meant for -human reading. - -To differentiate both types (documents and APIs), the index generator will add -to the index of documents an entry with the title of the document. Since the -title is the topmost element, it will be added with a second field containing -just the filename without any HTML anchor. By convention, this entry without -anchor is the *title entry*, and since entries in the index file are added as -they are scanned, the title entry will be the first line. The title for APIs -is not present because it can be generated concatenating the name of the file -to the word **Module**. - -Normal symbols are added to the index with surrounding whitespaces removed. An -exception to this are the table of content (TOC) entries. TOC entries are added to -the index file with their third column having as much prefix spaces as their -level is in the TOC (at least 1 character). The prefix whitespace helps to -filter TOC entries from API or text symbols. This is important because the -amount of spaces is used to replicate the hierarchy for document TOCs in the -final index, and TOC entries found in ``.nim`` files are discarded. +.. TODO Normal symbols are added to the index with surrounding whitespaces removed. An + exception to this are the table of content (TOC) entries. TOC entries are added to + the index file with their third column having as much prefix spaces as their + level is in the TOC (at least 1 character). The prefix whitespace helps to + filter TOC entries from API or text symbols. This is important because the + amount of spaces is used to replicate the hierarchy for document TOCs in the + final index, and TOC entries found in ``.nim`` files are discarded. Additional resources @@ -615,6 +858,8 @@ Additional resources [Markdown and RST markup languages](markdown_rst.html), which also contains the list of implemented features of these markup languages. +* the implementation is in [module compiler/docgen]. + The output for HTML and LaTeX comes from the ``config/nimdoc.cfg`` and ``config/nimdoc.tex.cfg`` configuration files. You can add and modify these files to your project to change the look of the docgen output. diff --git a/doc/markdown_rst.md b/doc/markdown_rst.md index 5fb3caefc..a374749cb 100644 --- a/doc/markdown_rst.md +++ b/doc/markdown_rst.md @@ -9,6 +9,8 @@ Nim-flavored Markdown and reStructuredText .. include:: rstcommon.rst .. contents:: +.. importdoc:: docgen.md + Both `Markdown`:idx: (md) and `reStructuredText`:idx: (RST) are markup languages whose goal is to typeset texts with complex structure, formatting and references using simple plaintext representation. @@ -110,6 +112,8 @@ Supported standard RST features: Additional Nim-specific features -------------------------------- +* referencing to definitions in external files, see + [Markup external referencing] section * directives: ``code-block`` \[cmp:Sphinx], ``title``, ``index`` \[cmp:Sphinx] * predefined roles @@ -170,6 +174,86 @@ Optional additional features, by default turned on: .. warning:: Using Nim-specific features can cause other RST implementations to fail on your document. +Referencing +=========== + +To be able to copy and share links Nim generates anchors for all +main document elements: + +* headlines (including document title) +* footnotes +* explicitly set anchors: RST internal cross-references and + inline internal targets +* Nim symbols (external referencing), see [Nim DocGen Tools Guide] for details. + +But direct use of those anchors have 2 problems: + +1. the anchors are usually mangled (e.g. spaces substituted to minus + signs, etc). +2. manual usage of anchors is not checked, so it's easy to get broken + links inside your project if e.g. spelling has changed for a heading + or you use a wrong relative path to your document. + +That's why Nim implementation has syntax for using +*original* labels for referencing. +Such referencing can be either local/internal or external: + +* Local referencing (inside any given file) is defined by + RST standard or Pandoc Markdown User guide. +* External (cross-document) referencing is a Nim-specific feature, + though it's not really different from local referencing by its syntax. + +Markup local referencing +------------------------ + +There are 2 syntax option available for referencing to objects +inside any given file, e.g. for headlines: + + Markdown RST + + Some headline Some headline + ============= ============= + + Ref. [Some headline] Ref. `Some headline`_ + + +Markup external referencing +--------------------------- + +The syntax is the same as for local referencing, but the anchors are +saved in ``.idx`` files, so one needs to generate them beforehand, +and they should be loaded by an `.. importdoc::` directive. +E.g. if we want to reference section "Some headline" in ``file1.md`` +from ``file2.md``, then ``file2.md`` may look like: + +``` +.. importdoc:: file1.md + +Ref. [Some headline] +``` + +```cmd +nim md2html --index:only file1.md # creates ``htmldocs/file1.idx`` +nim md2html file2.md # creates ``htmldocs/file2.html`` +``` + +To allow cross-references between any files in any order (especially, if +circular references are present), it's strongly reccommended +to make a run for creating all the indexes first: + +```cmd +nim md2html --index:only file1.md # creates ``htmldocs/file1.idx`` +nim md2html --index:only file2.md # creates ``htmldocs/file2.idx`` +nim md2html file1.md # creates ``htmldocs/file1.html`` +nim md2html file2.md # creates ``htmldocs/file2.html`` +``` + +and then one can freely reference any objects as if these 2 documents +are actually 1 file. + +Other +===== + Idiosyncrasies -------------- diff --git a/lib/core/macros.nim b/lib/core/macros.nim index bcc16038b..beb3aa695 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -23,6 +23,8 @@ when defined(nimPreviewSlimSystem): ## .. include:: ../../doc/astspec.txt +## .. importdoc:: system.nim + # If you look for the implementation of the magic symbol # ``{.magic: "Foo".}``, search for `mFoo` and `opcFoo`. diff --git a/lib/packages/docutils/dochelpers.nim b/lib/packages/docutils/dochelpers.nim index c7f7f73f5..b7cdd16d2 100644 --- a/lib/packages/docutils/dochelpers.nim +++ b/lib/packages/docutils/dochelpers.nim @@ -13,7 +13,7 @@ ## `type LangSymbol`_ in ``rst.nim``, while `match(generated, docLink)`_ ## matches it with `generated`, produced from `PNode` by ``docgen.rst``. -import rstast +import rstast, strutils when defined(nimPreviewSlimSystem): import std/[assertions, syncio] @@ -35,6 +35,12 @@ type ## name-type seq, e.g. for proc outType*: string ## result type, e.g. for proc +proc `$`*(s: LangSymbol): string = # for debug + ("(symkind=$1, symTypeKind=$2, name=$3, generics=$4, isGroup=$5, " & + "parametersProvided=$6, parameters=$7, outType=$8)") % [ + s.symKind, s.symTypeKind , s.name, s.generics, $s.isGroup, + $s.parametersProvided, $s.parameters, s.outType] + func nimIdentBackticksNormalize*(s: string): string = ## Normalizes the string `s` as a Nim identifier. ## @@ -71,6 +77,12 @@ func nimIdentBackticksNormalize*(s: string): string = else: discard # just omit '`' or ' ' if j != s.len: setLen(result, j) +proc langSymbolGroup*(kind: string, name: string): LangSymbol = + if kind notin ["proc", "func", "macro", "method", "iterator", + "template", "converter"]: + raise newException(ValueError, "unknown symbol kind $1" % [kind]) + result = LangSymbol(symKind: kind, name: name, isGroup: true) + proc toLangSymbol*(linkText: PRstNode): LangSymbol = ## Parses `linkText` into a more structured form using a state machine. ## @@ -82,11 +94,14 @@ proc toLangSymbol*(linkText: PRstNode): LangSymbol = ## ## This proc should be kept in sync with the `renderTypes` proc from ## ``compiler/typesrenderer.nim``. - assert linkText.kind in {rnRstRef, rnInner} + template fail(msg: string) = + raise newException(ValueError, msg) + if linkText.kind notin {rnRstRef, rnInner}: + fail("toLangSymbol: wrong input kind " & $linkText.kind) const NimDefs = ["proc", "func", "macro", "method", "iterator", "template", "converter", "const", "type", "var", - "enum", "object", "tuple"] + "enum", "object", "tuple", "module"] template resolveSymKind(x: string) = if x in ["enum", "object", "tuple"]: result.symKind = "type" @@ -109,11 +124,11 @@ proc toLangSymbol*(linkText: PRstNode): LangSymbol = template flushIdent() = if curIdent != "": case state - of inBeginning: doAssert false, "incorrect state inBeginning" + of inBeginning: fail("incorrect state inBeginning") of afterSymKind: resolveSymKind curIdent - of beforeSymbolName: doAssert false, "incorrect state beforeSymbolName" + of beforeSymbolName: fail("incorrect state beforeSymbolName") of atSymbolName: result.name = curIdent.nimIdentBackticksNormalize - of afterSymbolName: doAssert false, "incorrect state afterSymbolName" + of afterSymbolName: fail("incorrect state afterSymbolName") of genericsPar: result.generics = curIdent of parameterName: result.parameters.add (curIdent, "") of parameterType: diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index e9f76a26f..b3b1fb9c0 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -22,7 +22,7 @@ import os, strutils, rstast, dochelpers, std/enumutils, algorithm, lists, sequtils, - std/private/miscdollars, tables, strscans + std/private/miscdollars, tables, strscans, rstidx from highlite import SourceLanguage, getSourceLanguage when defined(nimPreviewSlimSystem): @@ -40,7 +40,7 @@ type roNimFile ## set for Nim files where default interpreted ## text role should be :nim: roSandboxDisabled ## this option enables certain options - ## (e.g. raw, include) + ## (e.g. raw, include, importdoc) ## which are disabled by default as they can ## enable users to read arbitrary data and ## perform XSS if the parser is used in a web @@ -73,11 +73,17 @@ type mwUnsupportedLanguage = "language '$1' not supported", mwUnsupportedField = "field '$1' not supported", mwRstStyle = "RST style: $1", + mwUnusedImportdoc = "importdoc for '$1' is not used", meSandboxedDirective = "disabled directive: '$1'", MsgHandler* = proc (filename: string, line, col: int, msgKind: MsgKind, arg: string) {.closure, gcsafe.} ## what to do in case of an error FindFileHandler* = proc (filename: string): string {.closure, gcsafe.} + FindRefFileHandler* = + proc (targetRelPath: string): + tuple[targetPath: string, linkRelPath: string] {.closure, gcsafe.} + ## returns where .html or .idx file should be found by its relative path; + ## `linkRelPath` is a prefix to be added before a link anchor from such file proc rstnodeToRefname*(n: PRstNode): string proc addNodes*(n: PRstNode): string @@ -333,7 +339,8 @@ type arInternalRst, ## For automatically generated RST anchors (from ## headings, footnotes, inline internal targets): ## case-insensitive, 1-space-significant (by RST spec) - arNim ## For anchors generated by ``docgen.rst``: Nim-style case + arExternalRst, ## For external .nim doc comments or .rst/.md + arNim ## For anchors generated by ``docgen.nim``: Nim-style case ## sensitivity, etc. (see `proc normalizeNimName`_ for details) arHyperlink, ## For links with manually set anchors in ## form `text <pagename.html#anchor>`_ @@ -349,11 +356,15 @@ type of arInternalRst: anchorType: RstAnchorKind target: PRstNode + of arExternalRst: + anchorTypeExt: RstAnchorKind + refnameExt: string of arNim: tooltip: string # displayed tooltip for Nim-generated anchors langSym: LangSymbol refname: string # A reference name that will be inserted directly # into HTML/Latex. + external: bool AnchorSubstTable = Table[string, seq[AnchorSubst]] # use `seq` to account for duplicate anchors FootnoteType = enum @@ -372,6 +383,12 @@ type RstFileTable* = object filenameToIdx*: Table[string, FileIndex] idxToFilename*: seq[string] + ImportdocInfo = object + used: bool # was this import used? + fromInfo: TLineInfo # place of `.. importdoc::` directive + idxPath: string # full path to ``.idx`` file + linkRelPath: string # prefix before target anchor + title: string # document title obtained from ``.idx`` RstSharedState = object options*: RstParseOptions # parsing options hLevels: LevelMap # hierarchy of heading styles @@ -393,12 +410,17 @@ type footnotes: seq[FootnoteSubst] # correspondence b/w footnote label, # number, order of occurrence msgHandler: MsgHandler # How to handle errors. - findFile: FindFileHandler # How to find files. + findFile: FindFileHandler # How to find files for include. + findRefFile: FindRefFileHandler + # How to find files imported by importdoc. filenames*: RstFileTable # map file name <-> FileIndex (for storing # file names for warnings after 1st stage) currFileIdx*: FileIndex # current index in `filenames` tocPart*: seq[PRstNode] # all the headings of a document hasToc*: bool + idxImports*: Table[string, ImportdocInfo] + # map `importdoc`ed filename -> it's info + nimFileImported*: bool # Was any ``.nim`` module `importdoc`ed ? PRstSharedState* = ref RstSharedState ManualAnchor = object @@ -452,6 +474,9 @@ proc defaultFindFile*(filename: string): string = if fileExists(filename): result = filename else: result = "" +proc defaultFindRefFile*(filename: string): (string, string) = + (filename, "") + proc defaultRole(options: RstParseOptions): string = if roNimFile in options: "nim" else: "literal" @@ -492,12 +517,16 @@ proc getFilename(filenames: RstFileTable, fid: FileIndex): string = $fid.int, $(filenames.len - 1)]) result = filenames.idxToFilename[fid.int] +proc getFilename(s: PRstSharedState, subst: AnchorSubst): string = + getFilename(s.filenames, subst.info.fileIndex) + proc currFilename(s: PRstSharedState): string = getFilename(s.filenames, s.currFileIdx) proc newRstSharedState*(options: RstParseOptions, filename: string, findFile: FindFileHandler, + findRefFile: FindRefFileHandler, msgHandler: MsgHandler, hasToc: bool): PRstSharedState = let r = defaultRole(options) @@ -507,6 +536,9 @@ proc newRstSharedState*(options: RstParseOptions, options: options, msgHandler: if not isNil(msgHandler): msgHandler else: defaultMsgHandler, findFile: if not isNil(findFile): findFile else: defaultFindFile, + findRefFile: + if not isNil(findRefFile): findRefFile + else: defaultFindRefFile, hasToc: hasToc ) setCurrFilename(result, filename) @@ -525,6 +557,14 @@ proc rstMessage(p: RstParser, msgKind: MsgKind, arg: string) = proc rstMessage(s: PRstSharedState, msgKind: MsgKind, arg: string) = s.msgHandler(s.currFilename, LineRstInit, ColRstInit, msgKind, arg) +proc rstMessage(s: PRstSharedState, msgKind: MsgKind, arg: string; + line, col: int) = + s.msgHandler(s.currFilename, line, col, msgKind, arg) + +proc rstMessage(s: PRstSharedState, filename: string, msgKind: MsgKind, + arg: string) = + s.msgHandler(filename, LineRstInit, ColRstInit, msgKind, arg) + proc rstMessage*(filenames: RstFileTable, f: MsgHandler, info: TLineInfo, msgKind: MsgKind, arg: string) = ## Print warnings using `info`, i.e. in 2nd-pass warnings for @@ -756,6 +796,14 @@ proc internalRefPriority(k: RstAnchorKind): int = of footnoteAnchor: result = 4 of headlineAnchor: result = 3 +proc `$`(subst: AnchorSubst): string = # for debug + let s = + case subst.kind + of arInternalRst: "type=" & $subst.anchorType + of arExternalRst: "type=" & $subst.anchorTypeExt + of arNim: "langsym=" & $subst.langSym + result = "(kind=$1, priority=$2, $3)" % [$subst.kind, $subst.priority, s] + proc addAnchorRst(p: var RstParser, name: string, target: PRstNode, anchorType: RstAnchorKind) = ## Associates node `target` (which has field `anchor`) with an @@ -771,31 +819,49 @@ proc addAnchorRst(p: var RstParser, name: string, target: PRstNode, info: prevLineInfo(p), anchorType: anchorType)) p.curAnchors.setLen 0 -proc addAnchorNim*(s: var PRstSharedState, refn: string, tooltip: string, +proc addAnchorExtRst(s: var PRstSharedState, key: string, refn: string, + anchorType: RstAnchorKind, info: TLineInfo) = + let name = key.toLowerAscii + let prio = internalRefPriority(anchorType) + s.anchors.mgetOrPut(name, newSeq[AnchorSubst]()).add( + AnchorSubst(kind: arExternalRst, refnameExt: refn, priority: prio, + info: info, + anchorTypeExt: anchorType)) + +proc addAnchorNim*(s: var PRstSharedState, external: bool, refn: string, tooltip: string, langSym: LangSymbol, priority: int, info: TLineInfo) = ## Adds an anchor `refn`, which follows ## the rule `arNim` (i.e. a symbol in ``*.nim`` file) s.anchors.mgetOrPut(langSym.name, newSeq[AnchorSubst]()).add( - AnchorSubst(kind: arNim, refname: refn, langSym: langSym, + AnchorSubst(kind: arNim, external: external, refname: refn, langSym: langSym, tooltip: tooltip, priority: priority, info: info)) proc findMainAnchorNim(s: PRstSharedState, signature: PRstNode, info: TLineInfo): seq[AnchorSubst] = - let langSym = toLangSymbol(signature) + var langSym: LangSymbol + try: + langSym = toLangSymbol(signature) + except ValueError: # parsing failed, not a Nim symbol + return let substitutions = s.anchors.getOrDefault(langSym.name, newSeq[AnchorSubst]()) if substitutions.len == 0: return - # map symKind (like "proc") -> found symbols/groups: - var found: Table[string, seq[AnchorSubst]] - for s in substitutions: - if s.kind == arNim: - if match(s.langSym, langSym): - found.mgetOrPut(s.langSym.symKind, newSeq[AnchorSubst]()).add s - for symKind, sList in found: + # logic to select only groups instead of concrete symbols + # with overloads, note that the same symbol can be defined + # in multiple modules and `importdoc`ed: + type GroupKey = tuple[symKind: string, origModule: string] + # map (symKind, file) (like "proc", "os.nim") -> found symbols/groups: + var found: Table[GroupKey, seq[AnchorSubst]] + for subst in substitutions: + if subst.kind == arNim: + if match(subst.langSym, langSym): + let key: GroupKey = (subst.langSym.symKind, getFilename(s, subst)) + found.mgetOrPut(key, newSeq[AnchorSubst]()).add subst + for key, sList in found: if sList.len == 1: result.add sList[0] else: # > 1, there are overloads, potential ambiguity in this `symKind` @@ -812,14 +878,16 @@ proc findMainAnchorNim(s: PRstSharedState, signature: PRstNode, result.add s foundGroup = true break - doAssert foundGroup, "docgen has not generated the group" + doAssert(foundGroup, + "docgen has not generated the group for $1 (file $2)" % [ + langSym.name, getFilename(s, sList[0]) ]) proc findMainAnchorRst(s: PRstSharedState, linkText: string, info: TLineInfo): seq[AnchorSubst] = let name = linkText.toLowerAscii let substitutions = s.anchors.getOrDefault(name, newSeq[AnchorSubst]()) for s in substitutions: - if s.kind == arInternalRst: + if s.kind in {arInternalRst, arExternalRst}: result.add s proc addFootnoteNumManual(p: var RstParser, num: int) = @@ -3251,6 +3319,15 @@ proc dirRaw(p: var RstParser): PRstNode = else: dirRawAux(p, result, rnRaw, parseSectionWrapper) +proc dirImportdoc(p: var RstParser): PRstNode = + result = parseDirective(p, rnDirective, {}, parseLiteralBlock) + assert result.sons[2].kind == rnLiteralBlock + assert result.sons[2].sons[0].kind == rnLeaf + let filenames: seq[string] = split(result.sons[2].sons[0].text, seps = {','}) + proc rmSpaces(s: string): string = s.split.join("") + for origFilename in filenames: + p.s.idxImports[origFilename.rmSpaces] = ImportdocInfo(fromInfo: lineInfo(p)) + proc selectDir(p: var RstParser, d: string): PRstNode = result = nil let tok = p.tok[p.idx-2] # report on directive in ".. directive::" @@ -3271,6 +3348,7 @@ proc selectDir(p: var RstParser, d: string): PRstNode = of "hint": result = dirAdmonition(p, d) of "image": result = dirImage(p) of "important": result = dirAdmonition(p, d) + of "importdoc": result = dirImportdoc(p) of "include": result = dirInclude(p) of "index": result = dirIndex(p) of "note": result = dirAdmonition(p, d) @@ -3401,11 +3479,90 @@ proc rstParsePass1*(fragment: string, getTokens(fragment, p.tok) result = parseDoc(p) -proc preparePass2*(s: PRstSharedState, mainNode: PRstNode) = +proc extractLinkEnd(x: string): string = + ## From links like `path/to/file.html#/%` extract `file.html#/%`. + let i = find(x, '#') + let last = + if i >= 0: i + else: x.len - 1 + let j = rfind(x, '/', start=0, last=last) + if j >= 0: + result = x[j+1 .. ^1] + else: + result = x + +proc loadIdxFile(s: var PRstSharedState, origFilename: string) = + doAssert roSandboxDisabled in s.options + var info: TLineInfo + info.fileIndex = addFilename(s, origFilename) + var (dir, basename, ext) = origFilename.splitFile + if ext notin [".md", ".rst", ".nim", ""]: + rstMessage(s.filenames, s.msgHandler, s.idxImports[origFilename].fromInfo, + meCannotOpenFile, origFilename & ": unknown extension") + let idxFilename = dir / basename & ".idx" + let (idxPath, linkRelPath) = s.findRefFile(idxFilename) + s.idxImports[origFilename].linkRelPath = linkRelPath + var + fileEntries: seq[IndexEntry] + title: IndexEntry + try: + (fileEntries, title) = parseIdxFile(idxPath) + except IOError: + rstMessage(s.filenames, s.msgHandler, s.idxImports[origFilename].fromInfo, + meCannotOpenFile, idxPath) + except ValueError as e: + s.msgHandler(idxPath, LineRstInit, ColRstInit, meInvalidField, e.msg) + + var isMarkup = false # for sanity check to avoid mixing .md <-> .nim + for entry in fileEntries: + # Though target .idx already has inside it the path to HTML relative + # project's root, we won't rely on it and use `linkRelPath` instead. + let refn = extractLinkEnd(entry.link) + # select either markup (rst/md) or Nim cases: + if entry.kind in {ieMarkupTitle, ieNimTitle}: + s.idxImports[origFilename].title = entry.keyword + case entry.kind + of ieIdxRole, ieHeading, ieMarkupTitle: + if ext == ".nim" and entry.kind == ieMarkupTitle: + rstMessage(s, idxPath, meInvalidField, + $ieMarkupTitle & " in supposedly .nim-derived file") + if entry.kind == ieMarkupTitle: + isMarkup = true + info.line = entry.line.uint16 + addAnchorExtRst(s, key = entry.keyword, refn = refn, + anchorType = headlineAnchor, info=info) + of ieNim, ieNimGroup, ieNimTitle: + if ext in [".md", ".rst"] or isMarkup: + rstMessage(s, idxPath, meInvalidField, + $entry.kind & " in supposedly markup-derived file") + s.nimFileImported = true + var langSym: LangSymbol + if entry.kind in {ieNim, ieNimTitle}: + var q: RstParser + initParser(q, s) + info.line = entry.line.uint16 + setLen(q.tok, 0) + q.idx = 0 + getTokens(entry.linkTitle, q.tok) + var sons = newSeq[PRstNode](q.tok.len) + for i in 0 ..< q.tok.len: sons[i] = newLeaf(q.tok[i].symbol) + let linkTitle = newRstNode(rnInner, sons) + langSym = linkTitle.toLangSymbol + else: # entry.kind == ieNimGroup + langSym = langSymbolGroup(kind=entry.linkTitle, name=entry.keyword) + addAnchorNim(s, external = true, refn = refn, tooltip = entry.linkDesc, + langSym = langSym, priority = -4, # lowest + info=info) + doAssert s.idxImports[origFilename].title != "" + +proc preparePass2*(s: var PRstSharedState, mainNode: PRstNode, importdoc = true) = ## Records titles in node `mainNode` and orders footnotes. countTitles(s, mainNode) fixHeadlines(s) orderFootnotes(s) + if importdoc: + for origFilename in s.idxImports.keys: + loadIdxFile(s, origFilename) proc resolveLink(s: PRstSharedState, n: PRstNode) : PRstNode = # Associate this link alias with its target and change node kind to @@ -3423,6 +3580,9 @@ proc resolveLink(s: PRstSharedState, n: PRstNode) : PRstNode = tooltip: string target: PRstNode info: TLineInfo + externFilename: string + # when external anchor: origin filename where anchor was defined + isTitle: bool proc cmp(x, y: LinkDef): int = result = cmp(x.priority, y.priority) if result == 0: @@ -3435,26 +3595,67 @@ proc resolveLink(s: PRstSharedState, n: PRstNode) : PRstNode = target: y.value, info: y.info, tooltip: "(" & $y.kind & ")") let substRst = findMainAnchorRst(s, alias.addNodes, n.info) + template getExternFilename(subst: AnchorSubst): string = + if subst.kind == arExternalRst or + (subst.kind == arNim and subst.external): + getFilename(s, subst) + else: "" for subst in substRst: - foundLinks.add LinkDef(ar: arInternalRst, priority: subst.priority, - target: newLeaf(subst.target.anchor), + var refname, fullRefname: string + if subst.kind == arInternalRst: + refname = subst.target.anchor + fullRefname = refname + else: # arExternalRst + refname = subst.refnameExt + fullRefname = s.idxImports[getFilename(s, subst)].linkRelPath & + "/" & refname + let anchorType = + if subst.kind == arInternalRst: subst.anchorType + else: subst.anchorTypeExt # arExternalRst + foundLinks.add LinkDef(ar: subst.kind, priority: subst.priority, + target: newLeaf(fullRefname), info: subst.info, - tooltip: "(" & $subst.anchorType & ")") + externFilename: getExternFilename(subst), + isTitle: isDocumentationTitle(refname), + tooltip: "(" & $anchorType & ")") # find anchors automatically generated from Nim symbols - if roNimFile in s.options: + if roNimFile in s.options or s.nimFileImported: let substNim = findMainAnchorNim(s, signature=alias, n.info) for subst in substNim: - foundLinks.add LinkDef(ar: arNim, priority: subst.priority, - target: newLeaf(subst.refname), + let fullRefname = + if subst.external: + s.idxImports[getFilename(s, subst)].linkRelPath & + "/" & subst.refname + else: subst.refname + foundLinks.add LinkDef(ar: subst.kind, priority: subst.priority, + target: newLeaf(fullRefname), + externFilename: getExternFilename(subst), + isTitle: isDocumentationTitle(subst.refname), info: subst.info, tooltip: subst.tooltip) foundLinks.sort(cmp = cmp, order = Descending) let aliasStr = addNodes(alias) if foundLinks.len >= 1: - let kind = if foundLinks[0].ar == arHyperlink: rnHyperlink - elif foundLinks[0].ar == arNim: rnNimdocRef + if foundLinks[0].externFilename != "": + s.idxImports[foundLinks[0].externFilename].used = true + let kind = if foundLinks[0].ar in {arHyperlink, arExternalRst}: rnHyperlink + elif foundLinks[0].ar == arNim: + if foundLinks[0].externFilename == "": rnNimdocRef + else: rnHyperlink else: rnInternalRef result = newRstNode(kind) - result.sons = @[newRstNode(rnInner, desc.sons), foundLinks[0].target] + let documentName = # filename without ext for `.nim`, title for `.md` + if foundLinks[0].ar == arNim: + changeFileExt(foundLinks[0].externFilename.extractFilename, "") + elif foundLinks[0].externFilename != "": + s.idxImports[foundLinks[0].externFilename].title + else: foundLinks[0].externFilename.extractFilename + let linkText = + if foundLinks[0].externFilename != "": + if foundLinks[0].isTitle: newLeaf(addNodes(desc)) + else: newLeaf(documentName & ": " & addNodes(desc)) + else: + newRstNode(rnInner, desc.sons) + result.sons = @[linkText, foundLinks[0].target] if kind == rnNimdocRef: result.tooltip = foundLinks[0].tooltip if foundLinks.len > 1: # report ambiguous link var targets = newSeq[string]() @@ -3568,20 +3769,28 @@ proc resolveSubs*(s: PRstSharedState, n: PRstNode): PRstNode = inc i result.sons = newSons +proc completePass2*(s: PRstSharedState) = + for (filename, importdocInfo) in s.idxImports.pairs: + if not importdocInfo.used: + rstMessage(s.filenames, s.msgHandler, importdocInfo.fromInfo, + mwUnusedImportdoc, filename) + proc rstParse*(text, filename: string, line, column: int, options: RstParseOptions, findFile: FindFileHandler = nil, + findRefFile: FindRefFileHandler = nil, msgHandler: MsgHandler = nil): tuple[node: PRstNode, filenames: RstFileTable, hasToc: bool] = ## Parses the whole `text`. The result is ready for `rstgen.renderRstToOut`, ## note that 2nd tuple element should be fed to `initRstGenerator` ## argument `filenames` (it is being filled here at least with `filename` ## and possibly with other files from RST ``.. include::`` statement). - var sharedState = newRstSharedState(options, filename, findFile, + var sharedState = newRstSharedState(options, filename, findFile, findRefFile, msgHandler, hasToc=false) let unresolved = rstParsePass1(text, line, column, sharedState) preparePass2(sharedState, unresolved) result.node = resolveSubs(sharedState, unresolved) + completePass2(sharedState) result.filenames = sharedState.filenames result.hasToc = sharedState.hasToc diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 597ee1553..57bc00fcb 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -39,7 +39,8 @@ ## No backreferences are generated since finding all references of a footnote ## can be done by simply searching for ``[footnoteName]``. -import strutils, os, hashes, strtabs, rstast, rst, highlite, tables, sequtils, +import strutils, os, hashes, strtabs, rstast, rst, rstidx, + highlite, tables, sequtils, algorithm, parseutils, std/strbasics @@ -59,7 +60,7 @@ type outLatex # output is Latex MetaEnum* = enum - metaNone, metaTitle, metaSubtitle, metaAuthor, metaVersion + metaNone, metaTitleRaw, metaTitle, metaSubtitle, metaAuthor, metaVersion EscapeMode* = enum # in Latex text inside options [] and URLs is # escaped slightly differently than in normal text @@ -321,31 +322,8 @@ proc renderAux(d: PDoc, n: PRstNode, html, tex: string, result: var string) = # ---------------- index handling -------------------------------------------- -proc quoteIndexColumn(text: string): string = - ## Returns a safe version of `text` for serialization to the ``.idx`` file. - ## - ## The returned version can be put without worries in a line based tab - ## separated column text file. The following character sequence replacements - ## will be performed for that goal: - ## - ## * ``"\\"`` => ``"\\\\"`` - ## * ``"\n"`` => ``"\\n"`` - ## * ``"\t"`` => ``"\\t"`` - result = newStringOfCap(text.len + 3) - for c in text: - case c - of '\\': result.add "\\" - of '\L': result.add "\\n" - of '\C': discard - of '\t': result.add "\\t" - else: result.add c - -proc unquoteIndexColumn(text: string): string = - ## Returns the unquoted version generated by ``quoteIndexColumn``. - result = text.multiReplace(("\\t", "\t"), ("\\n", "\n"), ("\\\\", "\\")) - -proc setIndexTerm*(d: var RstGenerator, htmlFile, id, term: string, - linkTitle, linkDesc = "") = +proc setIndexTerm*(d: var RstGenerator; k: IndexEntryKind, htmlFile, id, term: string, + linkTitle, linkDesc = "", line = 0) = ## Adds a `term` to the index using the specified hyperlink identifier. ## ## A new entry will be added to the index using the format @@ -368,21 +346,8 @@ proc setIndexTerm*(d: var RstGenerator, htmlFile, id, term: string, ## <#writeIndexFile,RstGenerator,string>`_. The purpose of the index is ## documented in the `docgen tools guide ## <docgen.html#related-options-index-switch>`_. - var - entry = term - isTitle = false - entry.add('\t') - entry.add(htmlFile) - if id.len > 0: - entry.add('#') - entry.add(id) - else: - isTitle = true - if linkTitle.len > 0 or linkDesc.len > 0: - entry.add('\t' & linkTitle.quoteIndexColumn) - entry.add('\t' & linkDesc.quoteIndexColumn) - entry.add("\n") - + let (entry, isTitle) = formatIndexEntry(k, htmlFile, id, term, + linkTitle, linkDesc, line) if isTitle: d.theIndex.insert(entry) else: d.theIndex.add(entry) @@ -395,6 +360,15 @@ proc hash(n: PRstNode): int = result = result !& hash(n.sons[i]) result = !$result +proc htmlFileRelPath(d: PDoc): string = + if d.outDir.len == 0: + # /foo/bar/zoo.nim -> zoo.html + changeFileExt(extractFilename(d.filename), HtmlExt) + else: # d is initialized in docgen.nim + # outDir = /foo -\ + # destFile = /foo/bar/zoo.html -|-> bar/zoo.html + d.destFile.relativePath(d.outDir, '/') + proc renderIndexTerm*(d: PDoc, n: PRstNode, result: var string) = ## Renders the string decorated within \`foobar\`\:idx\: markers. ## @@ -411,17 +385,12 @@ proc renderIndexTerm*(d: PDoc, n: PRstNode, result: var string) = var term = "" renderAux(d, n, term) - setIndexTerm(d, changeFileExt(extractFilename(d.filename), HtmlExt), id, term, d.currentSection) + setIndexTerm(d, ieIdxRole, + htmlFileRelPath(d), id, term, d.currentSection) dispA(d.target, result, "<span id=\"$1\">$2</span>", "\\nimindexterm{$1}{$2}", [id, term]) type - IndexEntry* = object - keyword*: string - link*: string - linkTitle*: string ## contains a prettier text for the href - linkDesc*: string ## the title attribute of the final href - IndexedDocs* = Table[IndexEntry, seq[IndexEntry]] ## \ ## Contains the index sequences for doc types. ## @@ -432,21 +401,6 @@ type ## The value indexed by this IndexEntry is a sequence with the real index ## entries found in the ``.idx`` file. -proc cmp(a, b: IndexEntry): int = - ## Sorts two ``IndexEntry`` first by `keyword` field, then by `link`. - result = cmpIgnoreStyle(a.keyword, b.keyword) - if result == 0: - result = cmpIgnoreStyle(a.link, b.link) - -proc hash(x: IndexEntry): Hash = - ## Returns the hash for the combined fields of the type. - ## - ## The hash is computed as the chained hash of the individual string hashes. - result = x.keyword.hash !& x.link.hash - result = result !& x.linkTitle.hash - result = result !& x.linkDesc.hash - result = !$result - when defined(gcDestructors): template `<-`(a, b: var IndexEntry) = a = move(b) else: @@ -455,6 +409,7 @@ else: shallowCopy a.link, b.link shallowCopy a.linkTitle, b.linkTitle shallowCopy a.linkDesc, b.linkDesc + shallowCopy a.module, b.module proc sortIndex(a: var openArray[IndexEntry]) = # we use shellsort here; fast and simple @@ -494,16 +449,20 @@ proc generateSymbolIndex(symbols: seq[IndexEntry]): string = result = "<dl>" var i = 0 while i < symbols.len: - let keyword = symbols[i].keyword + let keyword = esc(outHtml, symbols[i].keyword) let cleanedKeyword = keyword.escapeLink result.addf("<dt><a name=\"$2\" href=\"#$2\"><span>$1:</span></a></dt><dd><ul class=\"simple\">\n", [keyword, cleanedKeyword]) var j = i - while j < symbols.len and keyword == symbols[j].keyword: + while j < symbols.len and symbols[i].keyword == symbols[j].keyword: let url = symbols[j].link.escapeLink - text = if symbols[j].linkTitle.len > 0: symbols[j].linkTitle else: url - desc = if symbols[j].linkDesc.len > 0: symbols[j].linkDesc else: "" + module = symbols[j].module + text = + if symbols[j].linkTitle.len > 0: + esc(outHtml, module & ": " & symbols[j].linkTitle) + else: url + desc = symbols[j].linkDesc if desc.len > 0: result.addf("""<li><a class="reference external" title="$3" data-doc-search-tag="$2" href="$1">$2</a></li> @@ -517,13 +476,6 @@ proc generateSymbolIndex(symbols: seq[IndexEntry]): string = i = j result.add("</dl>") -proc isDocumentationTitle(hyperlink: string): bool = - ## Returns true if the hyperlink is actually a documentation title. - ## - ## Documentation titles lack the hash. See `mergeIndexes() - ## <#mergeIndexes,string>`_ for a more detailed explanation. - result = hyperlink.find('#') < 0 - proc stripTocLevel(s: string): tuple[level: int, text: string] = ## Returns the *level* of the toc along with the text without it. for c in 0 ..< s.len: @@ -557,17 +509,15 @@ proc generateDocumentationToc(entries: seq[IndexEntry]): string = level = 1 levels.newSeq(entries.len) for entry in entries: - let (rawLevel, rawText) = stripTocLevel(entry.linkTitle or entry.keyword) + let (rawLevel, rawText) = stripTocLevel(entry.linkTitle) if rawLevel < 1: # This is a normal symbol, push it *inside* one level from the last one. levels[L].level = level + 1 - # Also, ignore the linkTitle and use directly the keyword. - levels[L].text = entry.keyword else: # The level did change, update the level indicator. level = rawLevel levels[L].level = rawLevel - levels[L].text = rawText + levels[L].text = rawText inc L # Now generate hierarchical lists based on the precalculated levels. @@ -598,7 +548,7 @@ proc generateDocumentationIndex(docs: IndexedDocs): string = for title in titles: let tocList = generateDocumentationToc(docs.getOrDefault(title)) result.add("<ul><li><a href=\"" & - title.link & "\">" & title.keyword & "</a>\n" & tocList & "</li></ul>\n") + title.link & "\">" & title.linkTitle & "</a>\n" & tocList & "</li></ul>\n") proc generateDocumentationJumps(docs: IndexedDocs): string = ## Returns a plain list of hyperlinks to documentation TOCs in HTML. @@ -610,7 +560,7 @@ proc generateDocumentationJumps(docs: IndexedDocs): string = var chunks: seq[string] = @[] for title in titles: - chunks.add("<a href=\"" & title.link & "\">" & title.keyword & "</a>") + chunks.add("<a href=\"" & title.link & "\">" & title.linkTitle & "</a>") result.add(chunks.join(", ") & ".<br/>") @@ -639,39 +589,11 @@ proc readIndexDir*(dir: string): # Scan index files and build the list of symbols. for path in walkDirRec(dir): if path.endsWith(IndexExt): - var - fileEntries: seq[IndexEntry] - title: IndexEntry - f = 0 - newSeq(fileEntries, 500) - setLen(fileEntries, 0) - for line in lines(path): - let s = line.find('\t') - if s < 0: continue - setLen(fileEntries, f+1) - fileEntries[f].keyword = line.substr(0, s-1) - fileEntries[f].link = line.substr(s+1) - # See if we detect a title, a link without a `#foobar` trailing part. - if title.keyword.len == 0 and fileEntries[f].link.isDocumentationTitle: - title.keyword = fileEntries[f].keyword - title.link = fileEntries[f].link - - if fileEntries[f].link.find('\t') > 0: - let extraCols = fileEntries[f].link.split('\t') - fileEntries[f].link = extraCols[0] - assert extraCols.len == 3 - fileEntries[f].linkTitle = extraCols[1].unquoteIndexColumn - fileEntries[f].linkDesc = extraCols[2].unquoteIndexColumn - else: - fileEntries[f].linkTitle = "" - fileEntries[f].linkDesc = "" - inc f + var (fileEntries, title) = parseIdxFile(path) # Depending on type add this to the list of symbols or table of APIs. - if title.keyword.len == 0: - for i in 0 ..< f: - # Don't add to symbols TOC entries (they start with a whitespace). - let toc = fileEntries[i].linkTitle - if toc.len > 0 and toc[0] == ' ': + if title.kind == ieNimTitle: + for i in 0 ..< fileEntries.len: + if fileEntries[i].kind != ieNim: continue # Ok, non TOC entry, add it. setLen(result.symbols, L + 1) @@ -687,7 +609,7 @@ proc readIndexDir*(dir: string): result.modules.add(x.changeFileExt("")) else: # Generate the symbolic anchor for index quickjumps. - title.linkTitle = "doc_toc_" & $result.docs.len + title.aux = "doc_toc_" & $result.docs.len result.docs[title] = fileEntries proc mergeIndexes*(dir: string): string = @@ -747,24 +669,6 @@ proc mergeIndexes*(dir: string): string = # ---------------------------------------------------------------------------- -proc stripTocHtml(s: string): string = - ## Ugly quick hack to remove HTML tags from TOC titles. - ## - ## A TocEntry.header field already contains rendered HTML tags. Instead of - ## implementing a proper version of renderRstToOut() which recursively - ## renders an rst tree to plain text, we simply remove text found between - ## angled brackets. Given the limited possibilities of rst inside TOC titles - ## this should be enough. - result = s - var first = result.find('<') - while first >= 0: - let last = result.find('>', first) - if last < 0: - # Abort, since we didn't found a closing angled bracket. - return - result.delete(first..last) - first = result.find('<', first) - proc renderHeadline(d: PDoc, n: PRstNode, result: var string) = var tmp = "" for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp) @@ -785,19 +689,12 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) = # Generate index entry using spaces to indicate TOC level for the output HTML. assert n.level >= 0 - let - htmlFileRelPath = if d.outDir.len == 0: - # /foo/bar/zoo.nim -> zoo.html - changeFileExt(extractFilename(d.filename), HtmlExt) - else: # d is initialized in docgen.nim - # outDir = /foo -\ - # destFile = /foo/bar/zoo.html -|-> bar/zoo.html - d.destFile.relativePath(d.outDir, '/') - setIndexTerm(d, htmlFileRelPath, n.anchor, tmp.stripTocHtml, - spaces(max(0, n.level)) & tmp) + setIndexTerm(d, ieHeading, htmlFile = d.htmlFileRelPath, id = n.anchor, + term = n.addNodes, linkTitle = spaces(max(0, n.level)) & tmp) proc renderOverline(d: PDoc, n: PRstNode, result: var string) = if n.level == 0 and d.meta[metaTitle].len == 0: + d.meta[metaTitleRaw] = n.addNodes for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], d.meta[metaTitle]) d.currentSection = d.meta[metaTitle] @@ -813,6 +710,8 @@ proc renderOverline(d: PDoc, n: PRstNode, result: var string) = dispA(d.target, result, "<h$1$2><center>$3</center></h$1>", "\\rstov$4[$5]{$3}$2\n", [$n.level, n.anchor.idS, tmp, $chr(n.level - 1 + ord('A')), tocName]) + setIndexTerm(d, ieHeading, htmlFile = d.htmlFileRelPath, id = n.anchor, + term = n.addNodes, linkTitle = spaces(max(0, n.level)) & tmp) proc renderTocEntry(d: PDoc, n: PRstNode, result: var string) = var header = "" @@ -1197,6 +1096,18 @@ proc renderHyperlink(d: PDoc, text, link: PRstNode, result: var string, "\\hyperlink{$2}{$1} (p.~\\pageref{$2})", [textStr, linkStr, nimDocStr, tooltipStr]) +proc traverseForIndex*(d: PDoc, n: PRstNode) = + ## A version of [renderRstToOut] that only fills entries for ``.idx`` files. + var discarded: string + if n == nil: return + case n.kind + of rnIdx: renderIndexTerm(d, n, discarded) + of rnHeadline, rnMarkdownHeadline: renderHeadline(d, n, discarded) + of rnOverline: renderOverline(d, n, discarded) + else: + for i in 0 ..< len(n): + traverseForIndex(d, n.sons[i]) + proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) = if n == nil: return case n.kind @@ -1451,6 +1362,7 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) = of rnTitle: d.meta[metaTitle] = "" renderRstToOut(d, n.sons[0], d.meta[metaTitle]) + d.meta[metaTitleRaw] = n.sons[0].addNodes # ----------------------------------------------------------------------------- @@ -1616,11 +1528,13 @@ proc rstToHtml*(s: string, options: RstParseOptions, proc myFindFile(filename: string): string = # we don't find any files in online mode: result = "" + proc myFindRefFile(filename: string): (string, string) = + result = ("", "") const filen = "input" let (rst, filenames, t) = rstParse(s, filen, line=LineRstInit, column=ColRstInit, - options, myFindFile, msgHandler) + options, myFindFile, myFindRefFile, msgHandler) var d: RstGenerator initRstGenerator(d, outHtml, config, filen, myFindFile, msgHandler, filenames, hasToc = t) diff --git a/lib/packages/docutils/rstidx.nim b/lib/packages/docutils/rstidx.nim new file mode 100644 index 000000000..c109636d7 --- /dev/null +++ b/lib/packages/docutils/rstidx.nim @@ -0,0 +1,138 @@ +# +# Nim's Runtime Library +# (c) Copyright 2022 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. + +## Nim `idx`:idx: file format related definitions. + +import strutils, std/syncio, hashes +from os import splitFile + +type + IndexEntryKind* = enum ## discriminator tag + ieMarkupTitle = "markupTitle" + ## RST/Markdown title, text in `keyword` + + ## HTML text in `linkTitle` + ieNimTitle = "nimTitle" + ## Nim title + ieHeading = "heading" ## RST/Markdown markup heading, escaped + ieIdxRole = "idx" ## RST :idx: definition, escaped + ieNim = "nim" ## Nim symbol, unescaped + ieNimGroup = "nimgrp" ## Nim overload group, unescaped + IndexEntry* = object + kind*: IndexEntryKind ## 0. + keyword*: string ## 1. + link*: string ## 2. + linkTitle*: string ## 3. contains a prettier text for the href + linkDesc*: string ## 4. the title attribute of the final href + line*: int ## 5. + module*: string ## origin file, NOT a field in ``.idx`` file + aux*: string ## auxuliary field, NOT a field in ``.idx`` file + +proc isDocumentationTitle*(hyperlink: string): bool = + ## Returns true if the hyperlink is actually a documentation title. + ## + ## Documentation titles lack the hash. See `mergeIndexes() + ## <#mergeIndexes,string>`_ for a more detailed explanation. + result = hyperlink.find('#') < 0 + +proc `$`*(e: IndexEntry): string = + """("$1", "$2", "$3", "$4", $5)""" % [ + e.keyword, e.link, e.linkTitle, e.linkDesc, $e.line] + +proc quoteIndexColumn(text: string): string = + ## Returns a safe version of `text` for serialization to the ``.idx`` file. + ## + ## The returned version can be put without worries in a line based tab + ## separated column text file. The following character sequence replacements + ## will be performed for that goal: + ## + ## * ``"\\"`` => ``"\\\\"`` + ## * ``"\n"`` => ``"\\n"`` + ## * ``"\t"`` => ``"\\t"`` + result = newStringOfCap(text.len + 3) + for c in text: + case c + of '\\': result.add "\\" + of '\L': result.add "\\n" + of '\C': discard + of '\t': result.add "\\t" + else: result.add c + +proc unquoteIndexColumn*(text: string): string = + ## Returns the unquoted version generated by ``quoteIndexColumn``. + result = text.multiReplace(("\\t", "\t"), ("\\n", "\n"), ("\\\\", "\\")) + +proc formatIndexEntry*(kind: IndexEntryKind; htmlFile, id, term, linkTitle, + linkDesc: string, line: int): + tuple[entry: string, isTitle: bool] = + result.entry = $kind + result.entry.add('\t') + result.entry.add term + result.entry.add('\t') + result.entry.add(htmlFile) + if id.len > 0: + result.entry.add('#') + result.entry.add(id) + result.isTitle = false + else: + result.isTitle = true + result.entry.add('\t' & linkTitle.quoteIndexColumn) + result.entry.add('\t' & linkDesc.quoteIndexColumn) + result.entry.add('\t' & $line) + result.entry.add("\n") + +proc parseIndexEntryKind(s: string): IndexEntryKind = + result = case s: + of "nim": ieNim + of "nimgrp": ieNimGroup + of "heading": ieHeading + of "idx": ieIdxRole + of "nimTitle": ieNimTitle + of "markupTitle": ieMarkupTitle + else: raise newException(ValueError, "unknown index entry value $1" % [s]) + +proc parseIdxFile*(path: string): + tuple[fileEntries: seq[IndexEntry], title: IndexEntry] = + var + f = 0 + newSeq(result.fileEntries, 500) + setLen(result.fileEntries, 0) + let (_, base, _) = path.splitFile + for line in lines(path): + let s = line.find('\t') + if s < 0: continue + setLen(result.fileEntries, f+1) + let cols = line.split('\t') + result.fileEntries[f].kind = parseIndexEntryKind(cols[0]) + result.fileEntries[f].keyword = cols[1] + result.fileEntries[f].link = cols[2] + if result.title.keyword.len == 0: + result.fileEntries[f].module = base + else: + result.fileEntries[f].module = result.title.keyword + + result.fileEntries[f].linkTitle = cols[3].unquoteIndexColumn + result.fileEntries[f].linkDesc = cols[4].unquoteIndexColumn + result.fileEntries[f].line = parseInt(cols[5]) + + if result.fileEntries[f].kind in {ieNimTitle, ieMarkupTitle}: + result.title = result.fileEntries[f] + inc f + +proc cmp*(a, b: IndexEntry): int = + ## Sorts two ``IndexEntry`` first by `keyword` field, then by `link`. + result = cmpIgnoreStyle(a.keyword, b.keyword) + if result == 0: + result = cmpIgnoreStyle(a.link, b.link) + +proc hash*(x: IndexEntry): Hash = + ## Returns the hash for the combined fields of the type. + ## + ## The hash is computed as the chained hash of the individual string hashes. + result = x.keyword.hash !& x.link.hash + result = result !& x.linkTitle.hash + result = result !& x.linkDesc.hash + result = !$result diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 5f8f116d3..ecceed671 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -11,6 +11,8 @@ ## retrieving environment variables, working with directories, ## running shell commands, etc. +## .. importdoc:: symlinks.nim, appdirs.nim, dirs.nim, ospaths2.nim + runnableExamples: let myFile = "/path/to/my/file.nim" assert splitPath(myFile) == (head: "/path/to/my", tail: "file.nim") diff --git a/lib/std/appdirs.nim b/lib/std/appdirs.nim index e648fe0c1..c945ba8ec 100644 --- a/lib/std/appdirs.nim +++ b/lib/std/appdirs.nim @@ -1,5 +1,7 @@ ## This module implements helpers for determining special directories used by apps. +## .. importdoc:: paths.nim + from std/private/osappdirs import nil import std/paths import std/envvars diff --git a/lib/std/private/osappdirs.nim b/lib/std/private/osappdirs.nim index 8e6ae00f8..581b511ff 100644 --- a/lib/std/private/osappdirs.nim +++ b/lib/std/private/osappdirs.nim @@ -1,3 +1,5 @@ +## .. importdoc:: paths.nim, dirs.nim + include system/inclrtl import std/envvars import std/private/ospaths2 diff --git a/lib/std/private/oscommon.nim b/lib/std/private/oscommon.nim index 5b4e1d7e3..3aac58636 100644 --- a/lib/std/private/oscommon.nim +++ b/lib/std/private/oscommon.nim @@ -5,6 +5,8 @@ import std/[oserrors] when defined(nimPreviewSlimSystem): import std/[syncio, assertions, widestrs] +## .. importdoc:: osdirs.nim, os.nim + const weirdTarget* = defined(nimscript) or defined(js) diff --git a/lib/std/private/osdirs.nim b/lib/std/private/osdirs.nim index add9ed424..4af418ead 100644 --- a/lib/std/private/osdirs.nim +++ b/lib/std/private/osdirs.nim @@ -1,3 +1,5 @@ +## .. importdoc:: osfiles.nim, appdirs.nim, paths.nim + include system/inclrtl import std/oserrors diff --git a/lib/std/private/osfiles.nim b/lib/std/private/osfiles.nim index 301f14600..a7a595d97 100644 --- a/lib/std/private/osfiles.nim +++ b/lib/std/private/osfiles.nim @@ -7,6 +7,7 @@ export fileExists import ospaths2, ossymlinks +## .. importdoc:: osdirs.nim, os.nim when defined(nimPreviewSlimSystem): import std/[syncio, assertions, widestrs] @@ -420,4 +421,4 @@ proc moveFile*(source, dest: string) {.rtl, extern: "nos$1", removeFile(source) except: discard tryRemoveFile(dest) - raise \ No newline at end of file + raise diff --git a/lib/std/private/ospaths2.nim b/lib/std/private/ospaths2.nim index 75c34ecf5..5e3bece68 100644 --- a/lib/std/private/ospaths2.nim +++ b/lib/std/private/ospaths2.nim @@ -10,6 +10,8 @@ export ReadDirEffect, WriteDirEffect when defined(nimPreviewSlimSystem): import std/[syncio, assertions, widestrs] +## .. importdoc:: osappdirs.nim, osdirs.nim, osseps.nim, os.nim + const weirdTarget = defined(nimscript) or defined(js) when weirdTarget: diff --git a/lib/std/private/osseps.nim b/lib/std/private/osseps.nim index 1ea587e3c..f2d49d886 100644 --- a/lib/std/private/osseps.nim +++ b/lib/std/private/osseps.nim @@ -3,6 +3,8 @@ # Improved based on info in 'compiler/platform.nim' +## .. importdoc:: ospaths2.nim + const doslikeFileSystem* = defined(windows) or defined(OS2) or defined(DOS) diff --git a/lib/std/private/ossymlinks.nim b/lib/std/private/ossymlinks.nim index cb6287bde..53f59f939 100644 --- a/lib/std/private/ossymlinks.nim +++ b/lib/std/private/ossymlinks.nim @@ -31,6 +31,7 @@ elif defined(js): else: {.pragma: noNimJs.} +## .. importdoc:: os.nim proc createSymlink*(src, dest: string) {.noWeirdTarget.} = ## Create a symbolic link at `dest` which points to the item specified diff --git a/lib/std/symlinks.nim b/lib/std/symlinks.nim index 9e77bbe2a..54ab7b677 100644 --- a/lib/std/symlinks.nim +++ b/lib/std/symlinks.nim @@ -1,10 +1,11 @@ ## This module implements symlink (symbolic link) handling. +## .. importdoc:: os.nim + from paths import Path, ReadDirEffect from std/private/ossymlinks import symlinkExists, createSymlink, expandSymlink - proc symlinkExists*(link: Path): bool {.inline, tags: [ReadDirEffect].} = ## Returns true if the symlink `link` exists. Will return true ## regardless of whether the link points to a directory or file. diff --git a/nimdoc/extlinks/project/doc/manual.md b/nimdoc/extlinks/project/doc/manual.md new file mode 100644 index 000000000..d44b5ca39 --- /dev/null +++ b/nimdoc/extlinks/project/doc/manual.md @@ -0,0 +1,17 @@ +=================== +Nothing User Manual +=================== + +.. importdoc:: ../main.nim, .. / sub / submodule.nim, ../../util.nim + +First section +============= + +Second *section* & +================== + +Ref. [`</a>`] or [submoduleInt] from [module nimdoc/extlinks/project/sub/submodule]. + +Ref. [proc mainfunction*(): int]. + +Ref. [utilfunction(x: int)]. diff --git a/nimdoc/extlinks/project/expected/_._/util.html b/nimdoc/extlinks/project/expected/_._/util.html new file mode 100644 index 000000000..9b9b29a4f --- /dev/null +++ b/nimdoc/extlinks/project/expected/_._/util.html @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- This file is generated by Nim. --> +<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title>nimdoc/extlinks/util</title> + +<!-- Favicon --> +<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/> +<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII="> + +<!-- CSS --> +<link rel="stylesheet" type="text/css" href="../nimdoc.out.css"> + +<!-- JS --> +<script type="text/javascript" src="../dochack.js"></script> +</head> +<body> + <div class="document" id="documentId"> + <div class="container"> + <h1 class="title">nimdoc/extlinks/util</h1> + <div class="row"> + <div class="three columns"> + <div class="theme-select-wrapper"> + <label for="theme-select">Theme: </label> + <select id="theme-select" onchange="setTheme(this.value)"> + <option value="auto">🌗 Match OS</option> + <option value="dark">🌑 Dark</option> + <option value="light">🌕 Light</option> + </select> + </div> + <div id="global-links"> + <ul class="simple"> + <li><a id="indexLink" href="../theindex.html">Index</a></li> + </ul> + </div> + <div id="searchInputDiv"> + Search: <input type="search" id="searchInput" onkeyup="search()"/> + </div> + <div> + Group by: + <select onchange="groupBy(this.value)"> + <option value="section">Section</option> + <option value="type">Type</option> + </select> + </div> + <ul class="simple simple-toc" id="toc-list"> + <li> + <details open> + <summary><a class="reference reference-toplevel" href="#12" id="62">Procs</a></summary> + <ul class="simple simple-toc-section"> + <ul class="simple nested-toc-section">utilfunction + <li><a class="reference" href="#utilfunction%2Cint" title="utilfunction(x: int): int">utilfunction(x: int): int</a></li> + +</ul> + + </ul> + </details> +</li> + +</ul> + + </div> + <div class="nine columns" id="content"> + + <div id="tocRoot"></div> + + <p class="module-desc"></p> + <div class="section" id="12"> + <h1><a class="toc-backref" href="#12">Procs</a></h1> + <dl class="item"> + <div id="utilfunction-procs-all"> + <div id="utilfunction,int"> + <dt><pre><span class="Keyword">proc</span> <a href="#utilfunction%2Cint"><span class="Identifier">utilfunction</span></a><span class="Other">(</span><span class="Identifier">x</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> {.<span><span class="Other pragmadots">...</span></span><span class="pragmawrap"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">forbids</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span>.}</pre></dt> + <dd> + + + + </dd> +</div> + +</div> + + </dl> +</div> + + </div> +</div> + + <div class="twelve-columns footer"> + <span class="nim-sprite"></span> + <br> + <small style="color: var(--hint);">Made with Nim. Generated: 1970-01-02 03:46:40 UTC</small> + </div> + </div> + </div> + + <!-- Google fonts --> + <link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/> + <link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/> +</body> +</html> diff --git a/nimdoc/extlinks/project/expected/_._/util.idx b/nimdoc/extlinks/project/expected/_._/util.idx new file mode 100644 index 000000000..d83d8c97d --- /dev/null +++ b/nimdoc/extlinks/project/expected/_._/util.idx @@ -0,0 +1,2 @@ +nimTitle util _._/util.html module nimdoc/extlinks/util 0 +nim utilfunction _._/util.html#utilfunction,int proc utilfunction(x: int): int 1 diff --git a/nimdoc/extlinks/project/expected/doc/manual.html b/nimdoc/extlinks/project/expected/doc/manual.html new file mode 100644 index 000000000..7b964f4ac --- /dev/null +++ b/nimdoc/extlinks/project/expected/doc/manual.html @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- This file is generated by Nim. --> +<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title>Nothing User Manual</title> + +<!-- Favicon --> +<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/> +<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII="> + +<!-- CSS --> +<link rel="stylesheet" type="text/css" href="../nimdoc.out.css"> + +<!-- JS --> +<script type="text/javascript" src="../dochack.js"></script> +</head> +<body> + <div class="document" id="documentId"> + <div class="container"> + <h1 class="title">Nothing User Manual</h1> + +<h1 id="first-section">First section</h1> +<h1 id="second-section-amp">Second <em>section</em> &</h1><p>Ref. <a class="reference external" href="../sub/submodule.html#</a>,int,int">submodule: `</a>`</a> or <a class="reference external" href="../sub/submodule.html#submoduleInt">submodule: submoduleInt</a> from <a class="reference external" href="../sub/submodule.html">module nimdoc/extlinks/project/sub/submodule</a>.</p> +<p>Ref. <a class="reference external" href="../main.html#mainfunction">main: proc mainfunction*(): int</a>.</p> +<p>Ref. <a class="reference external" href="../_._/util.html#utilfunction,int">util: utilfunction(x: int)</a>. </p> + + + + <div class="twelve-columns footer"> + <span class="nim-sprite"></span> + <br> + <small style="color: var(--hint);">Made with Nim. Generated: 1970-01-02 03:46:40 UTC</small> + </div> + </div> + </div> + + <!-- Google fonts --> + <link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/> + <link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/> +</body> +</html> diff --git a/nimdoc/extlinks/project/expected/doc/manual.idx b/nimdoc/extlinks/project/expected/doc/manual.idx new file mode 100644 index 000000000..158a758f0 --- /dev/null +++ b/nimdoc/extlinks/project/expected/doc/manual.idx @@ -0,0 +1,3 @@ +markupTitle Nothing User Manual doc/manual.html Nothing User Manual 0 +heading First section doc/manual.html#first-section First section 0 +heading Second section & doc/manual.html#second-section-amp Second <em>section</em> & 0 diff --git a/nimdoc/extlinks/project/expected/main.html b/nimdoc/extlinks/project/expected/main.html new file mode 100644 index 000000000..5facedb3b --- /dev/null +++ b/nimdoc/extlinks/project/expected/main.html @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- This file is generated by Nim. --> +<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title>nimdoc/extlinks/project/main</title> + +<!-- Favicon --> +<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/> +<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII="> + +<!-- CSS --> +<link rel="stylesheet" type="text/css" href="nimdoc.out.css"> + +<!-- JS --> +<script type="text/javascript" src="dochack.js"></script> +</head> +<body> + <div class="document" id="documentId"> + <div class="container"> + <h1 class="title">nimdoc/extlinks/project/main</h1> + <div class="row"> + <div class="three columns"> + <div class="theme-select-wrapper"> + <label for="theme-select">Theme: </label> + <select id="theme-select" onchange="setTheme(this.value)"> + <option value="auto">🌗 Match OS</option> + <option value="dark">🌑 Dark</option> + <option value="light">🌕 Light</option> + </select> + </div> + <div id="global-links"> + <ul class="simple"> + <li><a id="indexLink" href="theindex.html">Index</a></li> + </ul> + </div> + <div id="searchInputDiv"> + Search: <input type="search" id="searchInput" onkeyup="search()"/> + </div> + <div> + Group by: + <select onchange="groupBy(this.value)"> + <option value="section">Section</option> + <option value="type">Type</option> + </select> + </div> + <ul class="simple simple-toc" id="toc-list"> + <li><a class="reference" id="my-heading_toc" href="#my-heading">my heading</a></li> +<li> + <a class="reference reference-toplevel" href="#6" id="56">Imports</a> +</li> +<li> + <details open> + <summary><a class="reference reference-toplevel" href="#7" id="57">Types</a></summary> + <ul class="simple simple-toc-section"> + <li><a class="reference" href="#A" title="A = object + x: int">A</a></li> + + </ul> + </details> +</li> +<li> + <details open> + <summary><a class="reference reference-toplevel" href="#12" id="62">Procs</a></summary> + <ul class="simple simple-toc-section"> + <ul class="simple nested-toc-section">mainfunction + <li><a class="reference" href="#mainfunction" title="mainfunction(): int">mainfunction(): int</a></li> + +</ul> + + </ul> + </details> +</li> + +</ul> + + </div> + <div class="nine columns" id="content"> + + <div id="tocRoot"></div> + + <p class="module-desc"> +<h1><a class="toc-backref" id="my-heading" href="#my-heading">my heading</a></h1><p>See also <a class="reference external" href="_._/util.html">module nimdoc/extlinks/util</a> or <a class="reference external" href="sub/submodule.html">nimdoc/extlinks/project/sub/submodule module</a>.</p> +<p>Ref. <a class="reference external" href="sub/submodule.html#</a>,int,int">submodule: `</a>` proc</a>.</p> +<p>Ref. <a class="reference external" href="doc/manual.html#first-section">Nothing User Manual: First section</a> or <a class="reference external" href="doc/manual.html#second-section-amp">Nothing User Manual: Second section &</a> from <a class="reference external" href="doc/manual.html">Nothing User Manual</a>.</p> +</p> + <div class="section" id="6"> + <h1><a class="toc-backref" href="#6">Imports</a></h1> + <dl class="item"> + <a class="reference external" href="_._/util.html">../util</a>, <a class="reference external" href="sub/submodule.html">sub/submodule</a> + </dl> +</div> +<div class="section" id="7"> + <h1><a class="toc-backref" href="#7">Types</a></h1> + <dl class="item"> + <div id="A"> + <dt><pre><a href="main.html#A"><span class="Identifier">A</span></a> <span class="Other">=</span> <span class="Keyword">object</span> + <span class="Identifier">x</span><span class="Other">:</span> <span class="Identifier">int</span> +</pre></dt> + <dd> + + + + </dd> +</div> + + </dl> +</div> +<div class="section" id="12"> + <h1><a class="toc-backref" href="#12">Procs</a></h1> + <dl class="item"> + <div id="mainfunction-procs-all"> + <div id="mainfunction"> + <dt><pre><span class="Keyword">proc</span> <a href="#mainfunction"><span class="Identifier">mainfunction</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> {.<span><span class="Other pragmadots">...</span></span><span class="pragmawrap"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">forbids</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span>.}</pre></dt> + <dd> + + + + </dd> +</div> + +</div> + + </dl> +</div> + + </div> +</div> + + <div class="twelve-columns footer"> + <span class="nim-sprite"></span> + <br> + <small style="color: var(--hint);">Made with Nim. Generated: 1970-01-02 03:46:40 UTC</small> + </div> + </div> + </div> + + <!-- Google fonts --> + <link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/> + <link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/> +</body> +</html> diff --git a/nimdoc/extlinks/project/expected/main.idx b/nimdoc/extlinks/project/expected/main.idx new file mode 100644 index 000000000..d01f2e4c5 --- /dev/null +++ b/nimdoc/extlinks/project/expected/main.idx @@ -0,0 +1,4 @@ +nimTitle main main.html module nimdoc/extlinks/project/main 0 +nim A main.html#A object A 17 +nim mainfunction main.html#mainfunction proc mainfunction(): int 20 +heading my heading main.html#my-heading my heading 0 diff --git a/nimdoc/extlinks/project/expected/sub/submodule.html b/nimdoc/extlinks/project/expected/sub/submodule.html new file mode 100644 index 000000000..913138d6e --- /dev/null +++ b/nimdoc/extlinks/project/expected/sub/submodule.html @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- This file is generated by Nim. --> +<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title>nimdoc/extlinks/project/sub/submodule</title> + +<!-- Favicon --> +<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/> +<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII="> + +<!-- CSS --> +<link rel="stylesheet" type="text/css" href="../nimdoc.out.css"> + +<!-- JS --> +<script type="text/javascript" src="../dochack.js"></script> +</head> +<body> + <div class="document" id="documentId"> + <div class="container"> + <h1 class="title">nimdoc/extlinks/project/sub/submodule</h1> + <div class="row"> + <div class="three columns"> + <div class="theme-select-wrapper"> + <label for="theme-select">Theme: </label> + <select id="theme-select" onchange="setTheme(this.value)"> + <option value="auto">🌗 Match OS</option> + <option value="dark">🌑 Dark</option> + <option value="light">🌕 Light</option> + </select> + </div> + <div id="global-links"> + <ul class="simple"> + <li><a id="indexLink" href="../theindex.html">Index</a></li> + </ul> + </div> + <div id="searchInputDiv"> + Search: <input type="search" id="searchInput" onkeyup="search()"/> + </div> + <div> + Group by: + <select onchange="groupBy(this.value)"> + <option value="section">Section</option> + <option value="type">Type</option> + </select> + </div> + <ul class="simple simple-toc" id="toc-list"> + <li> + <details open> + <summary><a class="reference reference-toplevel" href="#7" id="57">Types</a></summary> + <ul class="simple simple-toc-section"> + <li><a class="reference" href="#submoduleInt" title="submoduleInt = distinct int">submoduleInt</a></li> + + </ul> + </details> +</li> +<li> + <details open> + <summary><a class="reference reference-toplevel" href="#12" id="62">Procs</a></summary> + <ul class="simple simple-toc-section"> + <ul class="simple nested-toc-section"></a> + <li><a class="reference" href="#%3C%2Fa%3E%2Cint%2Cint" title="`</a>`(x, y: int): bool">`</a>`(x, y: int): bool</a></li> + +</ul> + + </ul> + </details> +</li> + +</ul> + + </div> + <div class="nine columns" id="content"> + + <div id="tocRoot"></div> + + <p class="module-desc"><p>Ref. <a class="reference external" href="../main.html#A">main: object A</a> from <a class="reference external" href="../main.html">module nimdoc/extlinks/project/main</a>.</p> +<p>Ref. <a class="reference external" href="../_._/util.html#utilfunction,int">util: utilfunction(x: int)</a>.</p> +<p>Ref. <a class="reference external" href="../doc/manual.html#second-section-amp">Nothing User Manual: Second section &</a> from <a class="reference external" href="../doc/manual.html">Nothing User Manual</a>.</p> +</p> + <div class="section" id="7"> + <h1><a class="toc-backref" href="#7">Types</a></h1> + <dl class="item"> + <div id="submoduleInt"> + <dt><pre><a href="submodule.html#submoduleInt"><span class="Identifier">submoduleInt</span></a> <span class="Other">=</span> <span class="Keyword">distinct</span> <span class="Identifier">int</span></pre></dt> + <dd> + + + + </dd> +</div> + + </dl> +</div> +<div class="section" id="12"> + <h1><a class="toc-backref" href="#12">Procs</a></h1> + <dl class="item"> + <div id="</a>-procs-all"> + <div id="</a>,int,int"> + <dt><pre><span class="Keyword">proc</span> <a href="#%3C%2Fa%3E%2Cint%2Cint"><span class="Identifier">`</a>`</span></a><span class="Other">(</span><span class="Identifier">x</span><span class="Other">,</span> <span class="Identifier">y</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> {.<span><span class="Other pragmadots">...</span></span><span class="pragmawrap"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">forbids</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span>.}</pre></dt> + <dd> + + Attempt to break HTML formatting. + + </dd> +</div> + +</div> + + </dl> +</div> + + </div> +</div> + + <div class="twelve-columns footer"> + <span class="nim-sprite"></span> + <br> + <small style="color: var(--hint);">Made with Nim. Generated: 1970-01-02 03:46:40 UTC</small> + </div> + </div> + </div> + + <!-- Google fonts --> + <link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/> + <link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/> +</body> +</html> diff --git a/nimdoc/extlinks/project/expected/sub/submodule.idx b/nimdoc/extlinks/project/expected/sub/submodule.idx new file mode 100644 index 000000000..2b02c889e --- /dev/null +++ b/nimdoc/extlinks/project/expected/sub/submodule.idx @@ -0,0 +1,3 @@ +nimTitle submodule sub/submodule.html module nimdoc/extlinks/project/sub/submodule 0 +nim `</a>` sub/submodule.html#</a>,int,int proc `</a>`(x, y: int): bool 9 +nim submoduleInt sub/submodule.html#submoduleInt type submoduleInt 13 diff --git a/nimdoc/extlinks/project/expected/theindex.html b/nimdoc/extlinks/project/expected/theindex.html new file mode 100644 index 000000000..9d2f6723c --- /dev/null +++ b/nimdoc/extlinks/project/expected/theindex.html @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- This file is generated by Nim. --> +<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title>Index</title> + +<!-- Favicon --> +<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/> +<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII="> + +<!-- CSS --> +<link rel="stylesheet" type="text/css" href="nimdoc.out.css"> + +<!-- JS --> +<script type="text/javascript" src="dochack.js"></script> +</head> +<body> + <div class="document" id="documentId"> + <div class="container"> + <h1 class="title">Index</h1> + Documents: <a href="doc/manual.html">Nothing User Manual</a>.<br/><p />Modules: <a href="_._/util.html">../util</a>, <a href="main.html">main</a>, <a href="sub/submodule.html">sub/submodule</a>.<br/><p /><h2>API symbols</h2> +<dl><dt><a name="%60%26lt%3B/a%26gt%3B%60" href="#%60%26lt%3B/a%26gt%3B%60"><span>`</a>`:</span></a></dt><dd><ul class="simple"> +<li><a class="reference external" + data-doc-search-tag="submodule: proc `</a>`(x, y: int): bool" href="sub/submodule.html#%3C/a%3E%2Cint%2Cint">submodule: proc `</a>`(x, y: int): bool</a></li> + </ul></dd> +<dt><a name="A" href="#A"><span>A:</span></a></dt><dd><ul class="simple"> +<li><a class="reference external" + data-doc-search-tag="main: object A" href="main.html#A">main: object A</a></li> + </ul></dd> +<dt><a name="mainfunction" href="#mainfunction"><span>mainfunction:</span></a></dt><dd><ul class="simple"> +<li><a class="reference external" + data-doc-search-tag="main: proc mainfunction(): int" href="main.html#mainfunction">main: proc mainfunction(): int</a></li> + </ul></dd> +<dt><a name="submoduleInt" href="#submoduleInt"><span>submoduleInt:</span></a></dt><dd><ul class="simple"> +<li><a class="reference external" + data-doc-search-tag="submodule: type submoduleInt" href="sub/submodule.html#submoduleInt">submodule: type submoduleInt</a></li> + </ul></dd> +<dt><a name="utilfunction" href="#utilfunction"><span>utilfunction:</span></a></dt><dd><ul class="simple"> +<li><a class="reference external" + data-doc-search-tag="util: proc utilfunction(x: int): int" href="_._/util.html#utilfunction%2Cint">util: proc utilfunction(x: int): int</a></li> + </ul></dd> +</dl> + <div class="twelve-columns footer"> + <span class="nim-sprite"></span> + <br> + <small style="color: var(--hint);">Made with Nim. Generated: 1970-01-02 03:46:40 UTC</small> + </div> + </div> + </div> + + <!-- Google fonts --> + <link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/> + <link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/> +</body> +</html> diff --git a/nimdoc/extlinks/project/main.nim b/nimdoc/extlinks/project/main.nim new file mode 100644 index 000000000..36b778af6 --- /dev/null +++ b/nimdoc/extlinks/project/main.nim @@ -0,0 +1,23 @@ +## my heading +## ========== +## +## .. importdoc:: sub/submodule.nim, ../util.nim, doc/manual.md +## +## .. See also [Second&&&] and particularly [first section] and [Second section &]. +## +## See also [module nimdoc/extlinks/util] or [nimdoc/extlinks/project/sub/submodule module]. +## +## Ref. [`</a>` proc]. +## +## Ref. [First section] or [Second section &] from [Nothing User Manual]. + + +import ../util, sub/submodule + +type A* = object + x: int + +proc mainfunction*(): int = + # just to suppress "not used" warnings: + if `</a>`(1, 2): + result = utilfunction(0) diff --git a/nimdoc/extlinks/project/sub/submodule.nim b/nimdoc/extlinks/project/sub/submodule.nim new file mode 100644 index 000000000..876e00684 --- /dev/null +++ b/nimdoc/extlinks/project/sub/submodule.nim @@ -0,0 +1,13 @@ +## .. importdoc:: ../../util.nim, ../main.nim, ../doc/manual.md +## +## Ref. [object A] from [module nimdoc/extlinks/project/main]. +## +## Ref. [utilfunction(x: int)]. +## +## Ref. [Second section &] from [Nothing User Manual]. + +proc `</a>`*(x, y: int): bool = + ## Attempt to break HTML formatting. + result = x < y + +type submoduleInt* = distinct int diff --git a/nimdoc/extlinks/util.nim b/nimdoc/extlinks/util.nim new file mode 100644 index 000000000..f208f98c1 --- /dev/null +++ b/nimdoc/extlinks/util.nim @@ -0,0 +1,2 @@ +proc utilfunction*(x: int): int = + x + 42 diff --git a/nimdoc/test_out_index_dot_html/expected/foo.idx b/nimdoc/test_out_index_dot_html/expected/foo.idx index a8dabb67e..ac76aa532 100644 --- a/nimdoc/test_out_index_dot_html/expected/foo.idx +++ b/nimdoc/test_out_index_dot_html/expected/foo.idx @@ -1 +1,2 @@ -foo index.html#foo foo: foo() +nimTitle foo index.html module nimdoc/test_out_index_dot_html/foo 0 +nim foo index.html#foo proc foo() 1 diff --git a/nimdoc/test_out_index_dot_html/expected/theindex.html b/nimdoc/test_out_index_dot_html/expected/theindex.html index 2a0ea7900..ea3486d4b 100644 --- a/nimdoc/test_out_index_dot_html/expected/theindex.html +++ b/nimdoc/test_out_index_dot_html/expected/theindex.html @@ -24,7 +24,7 @@ Modules: <a href="index.html">index</a>.<br/><p /><h2>API symbols</h2> <dl><dt><a name="foo" href="#foo"><span>foo:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="foo: foo()" href="index.html#foo">foo: foo()</a></li> + data-doc-search-tag="foo: proc foo()" href="index.html#foo">foo: proc foo()</a></li> </ul></dd> </dl> <div class="twelve-columns footer"> diff --git a/nimdoc/tester.nim b/nimdoc/tester.nim index ef82ae1b9..e94caae7c 100644 --- a/nimdoc/tester.nim +++ b/nimdoc/tester.nim @@ -12,11 +12,16 @@ var const baseDir = "nimdoc" +let + baseDirAbs = getCurrentDir() / baseDir type NimSwitches = object doc: seq[string] + docStage2: seq[string] buildIndex: seq[string] + md2html: seq[string] + md2htmlStage2: seq[string] proc exec(cmd: string) = if execShellCmd(cmd) != 0: @@ -25,6 +30,9 @@ proc exec(cmd: string) = proc testNimDoc(prjDir, docsDir: string; switches: NimSwitches; fixup = false) = let nimDocSwitches = switches.doc.join(" ") + nimDocStage2Switches = switches.docStage2.join(" ") + nimMd2HtmlSwitches = switches.md2html.join(" ") + nimMd2HtmlStage2Switches = switches.md2htmlStage2.join(" ") nimBuildIndexSwitches = switches.buildIndex.join(" ") putEnv("SOURCE_DATE_EPOCH", "100000") @@ -32,9 +40,23 @@ proc testNimDoc(prjDir, docsDir: string; switches: NimSwitches; fixup = false) = if nimDocSwitches != "": exec("$1 doc $2" % [nimExe, nimDocSwitches]) + echo("$1 doc $2" % [nimExe, nimDocSwitches]) + + if nimMd2HtmlSwitches != "": + exec("$1 md2html $2" % [nimExe, nimMd2HtmlSwitches]) + echo("$1 md2html $2" % [nimExe, nimMd2HtmlSwitches]) + + if nimDocStage2Switches != "": + exec("$1 doc $2" % [nimExe, nimDocStage2Switches]) + echo("$1 doc $2" % [nimExe, nimDocStage2Switches]) + + if nimMd2HtmlStage2Switches != "": + exec("$1 md2html $2" % [nimExe, nimMd2HtmlStage2Switches]) + echo("$1 md2html $2" % [nimExe, nimMd2HtmlStage2Switches]) if nimBuildIndexSwitches != "": exec("$1 buildIndex $2" % [nimExe, nimBuildIndexSwitches]) + echo("$1 buildIndex $2" % [nimExe, nimBuildIndexSwitches]) for expected in walkDirRec(prjDir / "expected/", checkDir=true): let produced = expected.replace('\\', '/').replace("/expected/", "/$1/" % [docsDir]) @@ -88,5 +110,46 @@ let test3Switches = NimSwitches(doc: @["$1/$2.nim" % [test3Dir, test3PrjName]]) testNimDoc(test3Dir, test3DocsDir, test3Switches, fixup) + +# Test concise external links (RFC#125) that work with `.idx` files. +# extlinks +# ├── project +# │  ├── main.nim +# │  ├── manual.md +# │  └── sub +# │  └── submodule.nim +# └── util.nim +# +# `main.nim` imports `submodule.nim` and `../utils.nim`. +# `main.nim`, `submodule.nim`, `manual.md` do importdoc and reference each other. +let + test4PrjName = "extlinks/project" + test4Dir = baseDir / test4PrjName + test4DirAbs = baseDirAbs / test4PrjName + test4MainModule = "main" + test4MarkupDoc = "doc" / "manual.md" + test4DocsDir = "htmldocs" + # 1st stage is with --index:only, 2nd is final + test4Switches = NimSwitches( + doc: @["--project", + "--outdir:$1/$2" % [test4Dir, test4DocsDir], + "--index:only", + "$1/$2.nim" % [test4Dir, test4MainModule]], + md2html: + @["--outdir:$1/$2" % [test4Dir, test4DocsDir], + "--docroot:$1" % [test4DirAbs], + "--index:only", + "$1/$2" % [test4Dir, test4MarkupDoc]], + docStage2: + @["--project", + "--outdir:$1/$2" % [test4Dir, test4DocsDir], + "$1/$2.nim" % [test4Dir, test4MainModule]], + md2htmlStage2: + @["--outdir:$1/$2" % [test4Dir, test4DocsDir], + "--docroot:$1" % [test4DirAbs], + "$1/$2" % [test4Dir, test4MarkupDoc]], + ) +testNimDoc(test4Dir, test4DocsDir, test4Switches, fixup) + if failures > 0: quit "$# failures occurred; see note in nimdoc/tester.nim regarding -d:nimTestsNimdocFixup" % $failures diff --git a/nimdoc/testproject/expected/subdir/subdir_b/utils.html b/nimdoc/testproject/expected/subdir/subdir_b/utils.html index 7d59e9e86..f0f30536f 100644 --- a/nimdoc/testproject/expected/subdir/subdir_b/utils.html +++ b/nimdoc/testproject/expected/subdir/subdir_b/utils.html @@ -226,7 +226,7 @@ cmp: proc (x: T; y: K): int {.closure.}): int" href="#binarySearch,openArray[T],K,proc(T,K)">binary search</a>.</p> <p>Note that <tt class="docutils literal"><span class="pre"><span class="Keyword">proc</span></span></tt> can be used in postfix form: <a class="reference internal nimdoc" title="proc binarySearch[T, K](a: openArray[T]; key: K; cmp: proc (x: T; y: K): int {.closure.}): int" href="#binarySearch,openArray[T],K,proc(T,K)">binarySearch proc</a>.</p> -<p>Ref. type like <a class="reference internal nimdoc" title="type G" href="#G">G</a> and <a class="reference internal nimdoc" title="type G" href="#G">type G</a> and <a class="reference internal nimdoc" title="type G" href="#G">G[T]</a> and <a class="reference internal nimdoc" title="type G" href="#G">type G*[T]</a>.</p> +<p>Ref. type like <a class="reference internal nimdoc" title="object G" href="#G">G</a> and <a class="reference internal nimdoc" title="object G" href="#G">type G</a> and <a class="reference internal nimdoc" title="object G" href="#G">G[T]</a> and <a class="reference internal nimdoc" title="object G" href="#G">type G*[T]</a>.</p> <p>Group ref. with capital letters works: <a class="reference internal nimdoc" title="proc fN11 (2 overloads)" href="#fN11-procs-all">fN11</a> or <a class="reference internal nimdoc" title="proc fN11 (2 overloads)" href="#fN11-procs-all">fn11</a> </p> Ref. <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href="#[],G[T]">[]</a> is the same as <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href="#[],G[T]">proc `[]`(G[T])</a> because there are no overloads. The full form: <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href="#[],G[T]">proc `[]`*[T](x: G[T]): T</a>Ref. <a class="reference internal nimdoc" title="proc `[]=`[T](a: var G[T]; index: int; value: T)" href="#[]=,G[T],int,T">[]=</a> aka <a class="reference internal nimdoc" title="proc `[]=`[T](a: var G[T]; index: int; value: T)" href="#[]=,G[T],int,T">`[]=`(G[T], int, T)</a>.Ref. <a class="reference internal nimdoc" title="proc $ (2 overloads)" href="#$-procs-all">$</a> aka <a class="reference internal nimdoc" title="proc $ (2 overloads)" href="#$-procs-all">proc $</a> or <a class="reference internal nimdoc" title="proc $ (2 overloads)" href="#$-procs-all">proc `$`</a>.Ref. <a class="reference internal nimdoc" title="proc `$`[T](a: ref SomeType): string" href="#$,ref.SomeType">$(a: ref SomeType)</a>.Ref. <a class="reference internal nimdoc" title="iterator fooBar(a: seq[SomeType]): int" href="#fooBar.i,seq[SomeType]">foo_bar</a> aka <a class="reference internal nimdoc" title="iterator fooBar(a: seq[SomeType]): int" href="#fooBar.i,seq[SomeType]">iterator foo_bar_</a>.Ref. <a class="reference internal nimdoc" title="proc fn[T; U, V: SomeFloat]()" href="#fn">fn[T; U,V: SomeFloat]()</a>.Ref. <a class="reference internal nimdoc" title="proc `'big`(a: string): SomeType" href="#'big,string">'big</a> or <a class="reference internal nimdoc" title="proc `'big`(a: string): SomeType" href="#'big,string">func `'big`</a> or <a class="reference internal nimdoc" title="proc `'big`(a: string): SomeType" href="#'big,string">`'big`(string)</a>. <h1><a class="toc-backref" id="pandoc-markdown" href="#pandoc-markdown">Pandoc Markdown</a></h1><p>Now repeat all the auto links of above in Pandoc Markdown Syntax.</p> @@ -240,11 +240,11 @@ Ref. <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href= cmp: proc (x: T; y: K): int {.closure.}): int" href="#binarySearch,openArray[T],K,proc(T,K)">binary search</a>.</p> <p>Note that <tt class="docutils literal"><span class="pre"><span class="Keyword">proc</span></span></tt> can be used in postfix form: <a class="reference internal nimdoc" title="proc binarySearch[T, K](a: openArray[T]; key: K; cmp: proc (x: T; y: K): int {.closure.}): int" href="#binarySearch,openArray[T],K,proc(T,K)">binarySearch proc</a>.</p> -<p>Ref. type like <a class="reference internal nimdoc" title="type G" href="#G">G</a> and <a class="reference internal nimdoc" title="type G" href="#G">type G</a> and <a class="reference internal nimdoc" title="type G" href="#G">G[T]</a> and <a class="reference internal nimdoc" title="type G" href="#G">type G*[T]</a>.</p> +<p>Ref. type like <a class="reference internal nimdoc" title="object G" href="#G">G</a> and <a class="reference internal nimdoc" title="object G" href="#G">type G</a> and <a class="reference internal nimdoc" title="object G" href="#G">G[T]</a> and <a class="reference internal nimdoc" title="object G" href="#G">type G*[T]</a>.</p> <p>Group ref. with capital letters works: <a class="reference internal nimdoc" title="proc fN11 (2 overloads)" href="#fN11-procs-all">fN11</a> or <a class="reference internal nimdoc" title="proc fN11 (2 overloads)" href="#fN11-procs-all">fn11</a></p> <p>Ref. <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href="#[],G[T]">`[]`</a> is the same as <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href="#[],G[T]">proc `[]`(G[T])</a> because there are no overloads. The full form: <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href="#[],G[T]">proc `[]`*[T](x: G[T]): T</a> Ref. <a class="reference internal nimdoc" title="proc `[]=`[T](a: var G[T]; index: int; value: T)" href="#[]=,G[T],int,T">`[]=`</a> aka <a class="reference internal nimdoc" title="proc `[]=`[T](a: var G[T]; index: int; value: T)" href="#[]=,G[T],int,T">`[]=`(G[T], int, T)</a>. Ref. <a class="reference internal nimdoc" title="proc $ (2 overloads)" href="#$-procs-all">$</a> aka <a class="reference internal nimdoc" title="proc $ (2 overloads)" href="#$-procs-all">proc $</a> or <a class="reference internal nimdoc" title="proc $ (2 overloads)" href="#$-procs-all">proc `$`</a>. Ref. <a class="reference internal nimdoc" title="proc `$`[T](a: ref SomeType): string" href="#$,ref.SomeType">$(a: ref SomeType)</a>. Ref. <a class="reference internal nimdoc" title="iterator fooBar(a: seq[SomeType]): int" href="#fooBar.i,seq[SomeType]">foo_bar</a> aka <a class="reference internal nimdoc" title="iterator fooBar(a: seq[SomeType]): int" href="#fooBar.i,seq[SomeType]">iterator foo_bar_</a>. Ref. <a class="reference internal nimdoc" title="proc fn[T; U, V: SomeFloat]()" href="#fn">fn[T; U,V: SomeFloat]()</a>. Ref. <a class="reference internal nimdoc" title="proc `'big`(a: string): SomeType" href="#'big,string">'big</a> or <a class="reference internal nimdoc" title="proc `'big`(a: string): SomeType" href="#'big,string">func `'big`</a> or <a class="reference internal nimdoc" title="proc `'big`(a: string): SomeType" href="#'big,string">`'big`(string)</a>.</p> -<h2><a class="toc-backref" id="pandoc-markdown-link-name-syntax" href="#pandoc-markdown-link-name-syntax">Link name syntax</a></h2><p>Pandoc Markdown has synax for changing text of links: Ref. <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href="#[],G[T]">this proc</a> or <a class="reference internal nimdoc" title="type G" href="#G">another symbol</a>.</p> +<h2><a class="toc-backref" id="pandoc-markdown-link-name-syntax" href="#pandoc-markdown-link-name-syntax">Link name syntax</a></h2><p>Pandoc Markdown has synax for changing text of links: Ref. <a class="reference internal nimdoc" title="proc `[]`[T](x: G[T]): T" href="#[],G[T]">this proc</a> or <a class="reference internal nimdoc" title="object G" href="#G">another symbol</a>.</p> <h2><a class="toc-backref" id="pandoc-markdown-symbols-documentation" href="#pandoc-markdown-symbols-documentation">Symbols documentation</a></h2><p>Let us repeat auto links from symbols section below:</p> <p>There is also variant <a class="reference internal nimdoc" title="proc f(x: G[string])" href="#f,G[string]">f(G[string])</a>. See also <a class="reference internal nimdoc" title="proc f(x: G[int])" href="#f,G[int]">f(G[int])</a>.</p> diff --git a/nimdoc/testproject/expected/subdir/subdir_b/utils.idx b/nimdoc/testproject/expected/subdir/subdir_b/utils.idx index 007101b37..c2f148a92 100644 --- a/nimdoc/testproject/expected/subdir/subdir_b/utils.idx +++ b/nimdoc/testproject/expected/subdir/subdir_b/utils.idx @@ -1,41 +1,46 @@ -funWithGenerics subdir/subdir_b/utils.html#funWithGenerics,T,U utils: funWithGenerics[T, U: SomeFloat](a: T; b: U) -enumValueA subdir/subdir_b/utils.html#enumValueA SomeType.enumValueA -enumValueB subdir/subdir_b/utils.html#enumValueB SomeType.enumValueB -enumValueC subdir/subdir_b/utils.html#enumValueC SomeType.enumValueC -SomeType subdir/subdir_b/utils.html#SomeType utils: SomeType -G subdir/subdir_b/utils.html#G utils: G -someType subdir/subdir_b/utils.html#someType_2 utils: someType(): SomeType -fn2 subdir/subdir_b/utils.html#fn2 utils: fn2() -fn2 subdir/subdir_b/utils.html#fn2,int utils: fn2(x: int) -fn2 subdir/subdir_b/utils.html#fn2,int,float utils: fn2(x: int; y: float) -binarySearch subdir/subdir_b/utils.html#binarySearch,openArray[T],K,proc(T,K) utils: binarySearch[T, K](a: openArray[T]; key: K;\n cmp: proc (x: T; y: K): int {.closure.}): int -fn3 subdir/subdir_b/utils.html#fn3 utils: fn3(): auto -fn4 subdir/subdir_b/utils.html#fn4 utils: fn4(): auto -fn5 subdir/subdir_b/utils.html#fn5 utils: fn5() -fn6 subdir/subdir_b/utils.html#fn6 utils: fn6() -fn7 subdir/subdir_b/utils.html#fn7 utils: fn7() -fn8 subdir/subdir_b/utils.html#fn8 utils: fn8(): auto -fn9 subdir/subdir_b/utils.html#fn9,int utils: fn9(a: int): int -fn10 subdir/subdir_b/utils.html#fn10,int utils: fn10(a: int): int -fN11 subdir/subdir_b/utils.html#fN11 utils: fN11() -fN11 subdir/subdir_b/utils.html#fN11,int utils: fN11(x: int) -aEnum subdir/subdir_b/utils.html#aEnum.t utils: aEnum(): untyped -bEnum subdir/subdir_b/utils.html#bEnum.t utils: bEnum(): untyped -fromUtilsGen subdir/subdir_b/utils.html#fromUtilsGen.t utils: fromUtilsGen(): untyped -f subdir/subdir_b/utils.html#f,G[int] utils: f(x: G[int]) -f subdir/subdir_b/utils.html#f,G[string] utils: f(x: G[string]) -`[]` subdir/subdir_b/utils.html#[],G[T] utils: `[]`[T](x: G[T]): T -`[]=` subdir/subdir_b/utils.html#[]=,G[T],int,T utils: `[]=`[T](a: var G[T]; index: int; value: T) -`$` subdir/subdir_b/utils.html#$,G[T] utils: `$`[T](a: G[T]): string -`$` subdir/subdir_b/utils.html#$,ref.SomeType utils: `$`[T](a: ref SomeType): string -fooBar subdir/subdir_b/utils.html#fooBar.i,seq[SomeType] utils: fooBar(a: seq[SomeType]): int -fn subdir/subdir_b/utils.html#fn utils: fn[T; U, V: SomeFloat]() -`'big` subdir/subdir_b/utils.html#'big,string utils: `'big`(a: string): SomeType -This is now a header subdir/subdir_b/utils.html#this-is-now-a-header This is now a header -Next header subdir/subdir_b/utils.html#this-is-now-a-header-next-header Next header -And so on subdir/subdir_b/utils.html#next-header-and-so-on And so on -More headers subdir/subdir_b/utils.html#more-headers More headers -Up to level 6 subdir/subdir_b/utils.html#more-headers-up-to-level-6 Up to level 6 -Pandoc Markdown subdir/subdir_b/utils.html#pandoc-markdown Pandoc Markdown -Link name syntax subdir/subdir_b/utils.html#pandoc-markdown-link-name-syntax Link name syntax -Symbols documentation subdir/subdir_b/utils.html#pandoc-markdown-symbols-documentation Symbols documentation +nimTitle utils subdir/subdir_b/utils.html module subdir/subdir_b/utils 0 +nim funWithGenerics subdir/subdir_b/utils.html#funWithGenerics,T,U proc funWithGenerics[T, U: SomeFloat](a: T; b: U) 1 +nim enumValueA subdir/subdir_b/utils.html#enumValueA SomeType.enumValueA 45 +nim enumValueB subdir/subdir_b/utils.html#enumValueB SomeType.enumValueB 45 +nim enumValueC subdir/subdir_b/utils.html#enumValueC SomeType.enumValueC 45 +nim SomeType subdir/subdir_b/utils.html#SomeType enum SomeType 45 +nim G subdir/subdir_b/utils.html#G object G 49 +nim someType subdir/subdir_b/utils.html#someType_2 proc someType(): SomeType 52 +nim fn2 subdir/subdir_b/utils.html#fn2 proc fn2() 57 +nim fn2 subdir/subdir_b/utils.html#fn2,int proc fn2(x: int) 58 +nim fn2 subdir/subdir_b/utils.html#fn2,int,float proc fn2(x: int; y: float) 61 +nim binarySearch subdir/subdir_b/utils.html#binarySearch,openArray[T],K,proc(T,K) proc binarySearch[T, K](a: openArray[T]; key: K;\n cmp: proc (x: T; y: K): int {.closure.}): int 63 +nim fn3 subdir/subdir_b/utils.html#fn3 proc fn3(): auto 66 +nim fn4 subdir/subdir_b/utils.html#fn4 proc fn4(): auto 67 +nim fn5 subdir/subdir_b/utils.html#fn5 proc fn5() 69 +nim fn6 subdir/subdir_b/utils.html#fn6 proc fn6() 70 +nim fn7 subdir/subdir_b/utils.html#fn7 proc fn7() 72 +nim fn8 subdir/subdir_b/utils.html#fn8 proc fn8(): auto 75 +nim fn9 subdir/subdir_b/utils.html#fn9,int proc fn9(a: int): int 78 +nim fn10 subdir/subdir_b/utils.html#fn10,int proc fn10(a: int): int 79 +nim fN11 subdir/subdir_b/utils.html#fN11 proc fN11() 85 +nim fN11 subdir/subdir_b/utils.html#fN11,int proc fN11(x: int) 86 +nim aEnum subdir/subdir_b/utils.html#aEnum.t template aEnum(): untyped 90 +nim bEnum subdir/subdir_b/utils.html#bEnum.t template bEnum(): untyped 95 +nim fromUtilsGen subdir/subdir_b/utils.html#fromUtilsGen.t template fromUtilsGen(): untyped 106 +nim f subdir/subdir_b/utils.html#f,G[int] proc f(x: G[int]) 130 +nim f subdir/subdir_b/utils.html#f,G[string] proc f(x: G[string]) 133 +nim `[]` subdir/subdir_b/utils.html#[],G[T] proc `[]`[T](x: G[T]): T 140 +nim `[]=` subdir/subdir_b/utils.html#[]=,G[T],int,T proc `[]=`[T](a: var G[T]; index: int; value: T) 144 +nim `$` subdir/subdir_b/utils.html#$,G[T] proc `$`[T](a: G[T]): string 148 +nim `$` subdir/subdir_b/utils.html#$,ref.SomeType proc `$`[T](a: ref SomeType): string 152 +nim fooBar subdir/subdir_b/utils.html#fooBar.i,seq[SomeType] iterator fooBar(a: seq[SomeType]): int 156 +nim fn subdir/subdir_b/utils.html#fn proc fn[T; U, V: SomeFloat]() 160 +nim `'big` subdir/subdir_b/utils.html#'big,string proc `'big`(a: string): SomeType 164 +nimgrp $ subdir/subdir_b/utils.html#$-procs-all proc 148 +nimgrp fn11 subdir/subdir_b/utils.html#fN11-procs-all proc 85 +nimgrp fn2 subdir/subdir_b/utils.html#fn2-procs-all proc 57 +nimgrp f subdir/subdir_b/utils.html#f-procs-all proc 130 +heading This is now a header subdir/subdir_b/utils.html#this-is-now-a-header This is now a header 0 +heading Next header subdir/subdir_b/utils.html#this-is-now-a-header-next-header Next header 0 +heading And so on subdir/subdir_b/utils.html#next-header-and-so-on And so on 0 +heading More headers subdir/subdir_b/utils.html#more-headers More headers 0 +heading Up to level 6 subdir/subdir_b/utils.html#more-headers-up-to-level-6 Up to level 6 0 +heading Pandoc Markdown subdir/subdir_b/utils.html#pandoc-markdown Pandoc Markdown 0 +heading Link name syntax subdir/subdir_b/utils.html#pandoc-markdown-link-name-syntax Link name syntax 0 +heading Symbols documentation subdir/subdir_b/utils.html#pandoc-markdown-symbols-documentation Symbols documentation 0 diff --git a/nimdoc/testproject/expected/testproject.idx b/nimdoc/testproject/expected/testproject.idx index 4d0172313..e69bedf33 100644 --- a/nimdoc/testproject/expected/testproject.idx +++ b/nimdoc/testproject/expected/testproject.idx @@ -1,64 +1,67 @@ -someVariable testproject.html#someVariable testproject: someVariable -C_A testproject.html#C_A testproject: C_A -C_B testproject.html#C_B testproject: C_B -C_C testproject.html#C_C testproject: C_C -C_D testproject.html#C_D testproject: C_D -bar testproject.html#bar,T,T testproject: bar[T](a, b: T): T -baz testproject.html#baz,T,T testproject: baz[T](a, b: T): T -buzz testproject.html#buzz,T,T testproject: buzz[T](a, b: T): T -FooBuzz testproject.html#FooBuzz testproject: FooBuzz -bar testproject.html#bar testproject: bar(f: FooBuzz) -aVariable testproject.html#aVariable testproject: aVariable -A testproject.html#A testproject: A -B testproject.html#B testproject: B -someFunc testproject.html#someFunc testproject: someFunc() -fromUtils1 testproject.html#fromUtils1.i testproject: fromUtils1(): int -fromUtils2 testproject.html#fromUtils2.t testproject: fromUtils2() -fromUtils3 testproject.html#fromUtils3 testproject: fromUtils3() -isValid testproject.html#isValid,T testproject: isValid[T](x: T): bool -enumValueA2 testproject.html#enumValueA2 Foo.enumValueA2 -Foo testproject.html#Foo testproject: Foo -z1 testproject.html#z1 testproject: z1(): Foo -z2 testproject.html#z2 testproject: z2() -z3 testproject.html#z3 testproject: z3() -z4 testproject.html#z4 testproject: z4() -z5 testproject.html#z5 testproject: z5(): int -z6 testproject.html#z6 testproject: z6(): int -z6t testproject.html#z6t.t testproject: z6t(): int -z7 testproject.html#z7 testproject: z7(): int -z8 testproject.html#z8 testproject: z8(): int -z9 testproject.html#z9 testproject: z9() -z10 testproject.html#z10 testproject: z10() -z11 testproject.html#z11 testproject: z11() -z12 testproject.html#z12 testproject: z12(): int -z13 testproject.html#z13 testproject: z13() -baz testproject.html#baz testproject: baz() -z17 testproject.html#z17 testproject: z17() -p1 testproject.html#p1 testproject: p1() -addfBug14485 testproject.html#addfBug14485 testproject: addfBug14485() -c_printf testproject.html#c_printf,cstring testproject: c_printf(frmt: cstring): cint -c_nonexistent testproject.html#c_nonexistent,cstring testproject: c_nonexistent(frmt: cstring): cint -low testproject.html#low,T testproject: low[T: Ordinal | enum | range](x: T): T -low2 testproject.html#low2,T testproject: low2[T: Ordinal | enum | range](x: T): T -tripleStrLitTest testproject.html#tripleStrLitTest testproject: tripleStrLitTest() -method1 testproject.html#method1.e,Moo testproject: method1(self: Moo) -method2 testproject.html#method2.e,Moo testproject: method2(self: Moo): int -method3 testproject.html#method3.e,Moo testproject: method3(self: Moo): int -iter1 testproject.html#iter1.i,int testproject: iter1(n: int): int -iter2 testproject.html#iter2.i,int testproject: iter2(n: int): int -bar testproject.html#bar.m testproject: bar(): untyped -z16 testproject.html#z16.m testproject: z16() -z18 testproject.html#z18.m testproject: z18(): int -foo testproject.html#foo.t,SomeType,SomeType testproject: foo(a, b: SomeType) -myfn testproject.html#myfn.t testproject: myfn() -z14 testproject.html#z14.t testproject: z14() -z15 testproject.html#z15.t testproject: z15() -asyncFun1 testproject.html#asyncFun1 testproject: asyncFun1(): Future[int] -asyncFun2 testproject.html#asyncFun2 testproject: asyncFun2(): owned(Future[void]) -asyncFun3 testproject.html#asyncFun3 testproject: asyncFun3(): owned(Future[void]) -testNimDocTrailingExample testproject.html#testNimDocTrailingExample.t testproject: testNimDocTrailingExample() -Circle testproject.html#Circle Shapes.Circle -Triangle testproject.html#Triangle Shapes.Triangle -Rectangle testproject.html#Rectangle Shapes.Rectangle -Shapes testproject.html#Shapes testproject: Shapes -anything testproject.html#anything testproject: anything() +nimTitle testproject testproject.html module testproject 0 +nim someVariable testproject.html#someVariable var someVariable 13 +nim C_A testproject.html#C_A const C_A 26 +nim C_B testproject.html#C_B const C_B 27 +nim C_C testproject.html#C_C const C_C 28 +nim C_D testproject.html#C_D const C_D 29 +nim bar testproject.html#bar,T,T proc bar[T](a, b: T): T 31 +nim baz testproject.html#baz,T,T proc baz[T](a, b: T): T 34 +nim buzz testproject.html#buzz,T,T proc buzz[T](a, b: T): T 38 +nim FooBuzz testproject.html#FooBuzz type FooBuzz 43 +nim bar testproject.html#bar proc bar(f: FooBuzz) 47 +nim aVariable testproject.html#aVariable var aVariable 52 +nim A testproject.html#A enum A 92 +nim B testproject.html#B enum B 97 +nim someFunc testproject.html#someFunc proc someFunc() 56 +nim fromUtils1 testproject.html#fromUtils1.i iterator fromUtils1(): int 112 +nim fromUtils2 testproject.html#fromUtils2.t template fromUtils2() 119 +nim fromUtils3 testproject.html#fromUtils3 proc fromUtils3() 57 +nim isValid testproject.html#isValid,T proc isValid[T](x: T): bool 59 +nim enumValueA2 testproject.html#enumValueA2 Foo.enumValueA2 66 +nim Foo testproject.html#Foo enum Foo 66 +nim z1 testproject.html#z1 proc z1(): Foo 69 +nim z2 testproject.html#z2 proc z2() 73 +nim z3 testproject.html#z3 proc z3() 78 +nim z4 testproject.html#z4 proc z4() 81 +nim z5 testproject.html#z5 proc z5(): int 87 +nim z6 testproject.html#z6 proc z6(): int 91 +nim z6t testproject.html#z6t.t template z6t(): int 95 +nim z7 testproject.html#z7 proc z7(): int 99 +nim z8 testproject.html#z8 proc z8(): int 103 +nim z9 testproject.html#z9 proc z9() 111 +nim z10 testproject.html#z10 proc z10() 114 +nim z11 testproject.html#z11 proc z11() 119 +nim z12 testproject.html#z12 proc z12(): int 124 +nim z13 testproject.html#z13 proc z13() 129 +nim baz testproject.html#baz proc baz() 134 +nim z17 testproject.html#z17 proc z17() 144 +nim p1 testproject.html#p1 proc p1() 156 +nim addfBug14485 testproject.html#addfBug14485 proc addfBug14485() 177 +nim c_printf testproject.html#c_printf,cstring proc c_printf(frmt: cstring): cint 193 +nim c_nonexistent testproject.html#c_nonexistent,cstring proc c_nonexistent(frmt: cstring): cint 197 +nim low testproject.html#low,T proc low[T: Ordinal | enum | range](x: T): T 200 +nim low2 testproject.html#low2,T proc low2[T: Ordinal | enum | range](x: T): T 210 +nim tripleStrLitTest testproject.html#tripleStrLitTest proc tripleStrLitTest() 223 +nim method1 testproject.html#method1.e,Moo method method1(self: Moo) 264 +nim method2 testproject.html#method2.e,Moo method method2(self: Moo): int 266 +nim method3 testproject.html#method3.e,Moo method method3(self: Moo): int 269 +nim iter1 testproject.html#iter1.i,int iterator iter1(n: int): int 274 +nim iter2 testproject.html#iter2.i,int iterator iter2(n: int): int 278 +nim bar testproject.html#bar.m macro bar(): untyped 285 +nim z16 testproject.html#z16.m macro z16() 288 +nim z18 testproject.html#z18.m macro z18(): int 297 +nim foo testproject.html#foo.t,SomeType,SomeType template foo(a, b: SomeType) 302 +nim myfn testproject.html#myfn.t template myfn() 307 +nim z14 testproject.html#z14.t template z14() 328 +nim z15 testproject.html#z15.t template z15() 333 +nim asyncFun1 testproject.html#asyncFun1 proc asyncFun1(): Future[int] 358 +nim asyncFun2 testproject.html#asyncFun2 proc asyncFun2(): owned(Future[void]) 361 +nim asyncFun3 testproject.html#asyncFun3 proc asyncFun3(): owned(Future[void]) 362 +nim testNimDocTrailingExample testproject.html#testNimDocTrailingExample.t template testNimDocTrailingExample() 371 +nim Circle testproject.html#Circle Shapes.Circle 380 +nim Triangle testproject.html#Triangle Shapes.Triangle 380 +nim Rectangle testproject.html#Rectangle Shapes.Rectangle 380 +nim Shapes testproject.html#Shapes enum Shapes 380 +nim anything testproject.html#anything proc anything() 387 +nimgrp bar testproject.html#bar-procs-all proc 31 +nimgrp baz testproject.html#baz-procs-all proc 34 diff --git a/nimdoc/testproject/expected/theindex.html b/nimdoc/testproject/expected/theindex.html index 9f73040f2..7b4a95561 100644 --- a/nimdoc/testproject/expected/theindex.html +++ b/nimdoc/testproject/expected/theindex.html @@ -24,377 +24,377 @@ Modules: <a href="subdir/subdir_b/utils.html">subdir/subdir_b/utils</a>, <a href="testproject.html">testproject</a>.<br/><p /><h2>API symbols</h2> <dl><dt><a name="%60%24%60" href="#%60%24%60"><span>`$`:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: `$`[T](a: G[T]): string" href="subdir/subdir_b/utils.html#%24%2CG%5BT%5D">utils: `$`[T](a: G[T]): string</a></li> + data-doc-search-tag="utils: proc `$`[T](a: G[T]): string" href="subdir/subdir_b/utils.html#%24%2CG%5BT%5D">utils: proc `$`[T](a: G[T]): string</a></li> <li><a class="reference external" - data-doc-search-tag="utils: `$`[T](a: ref SomeType): string" href="subdir/subdir_b/utils.html#%24%2Cref.SomeType">utils: `$`[T](a: ref SomeType): string</a></li> + data-doc-search-tag="utils: proc `$`[T](a: ref SomeType): string" href="subdir/subdir_b/utils.html#%24%2Cref.SomeType">utils: proc `$`[T](a: ref SomeType): string</a></li> </ul></dd> <dt><a name="%60%27big%60" href="#%60%27big%60"><span>`'big`:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: `'big`(a: string): SomeType" href="subdir/subdir_b/utils.html#%27big%2Cstring">utils: `'big`(a: string): SomeType</a></li> + data-doc-search-tag="utils: proc `'big`(a: string): SomeType" href="subdir/subdir_b/utils.html#%27big%2Cstring">utils: proc `'big`(a: string): SomeType</a></li> </ul></dd> <dt><a name="%60%5B%5D%3D%60" href="#%60%5B%5D%3D%60"><span>`[]=`:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: `[]=`[T](a: var G[T]; index: int; value: T)" href="subdir/subdir_b/utils.html#%5B%5D%3D%2CG%5BT%5D%2Cint%2CT">utils: `[]=`[T](a: var G[T]; index: int; value: T)</a></li> + data-doc-search-tag="utils: proc `[]=`[T](a: var G[T]; index: int; value: T)" href="subdir/subdir_b/utils.html#%5B%5D%3D%2CG%5BT%5D%2Cint%2CT">utils: proc `[]=`[T](a: var G[T]; index: int; value: T)</a></li> </ul></dd> <dt><a name="%60%5B%5D%60" href="#%60%5B%5D%60"><span>`[]`:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: `[]`[T](x: G[T]): T" href="subdir/subdir_b/utils.html#%5B%5D%2CG%5BT%5D">utils: `[]`[T](x: G[T]): T</a></li> + data-doc-search-tag="utils: proc `[]`[T](x: G[T]): T" href="subdir/subdir_b/utils.html#%5B%5D%2CG%5BT%5D">utils: proc `[]`[T](x: G[T]): T</a></li> </ul></dd> <dt><a name="A" href="#A"><span>A:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: A" href="testproject.html#A">testproject: A</a></li> + data-doc-search-tag="testproject: enum A" href="testproject.html#A">testproject: enum A</a></li> </ul></dd> <dt><a name="addfBug14485" href="#addfBug14485"><span>addfBug14485:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: addfBug14485()" href="testproject.html#addfBug14485">testproject: addfBug14485()</a></li> + data-doc-search-tag="testproject: proc addfBug14485()" href="testproject.html#addfBug14485">testproject: proc addfBug14485()</a></li> </ul></dd> <dt><a name="aEnum" href="#aEnum"><span>aEnum:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: aEnum(): untyped" href="subdir/subdir_b/utils.html#aEnum.t">utils: aEnum(): untyped</a></li> + data-doc-search-tag="utils: template aEnum(): untyped" href="subdir/subdir_b/utils.html#aEnum.t">utils: template aEnum(): untyped</a></li> </ul></dd> <dt><a name="anything" href="#anything"><span>anything:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: anything()" href="testproject.html#anything">testproject: anything()</a></li> + data-doc-search-tag="testproject: proc anything()" href="testproject.html#anything">testproject: proc anything()</a></li> </ul></dd> <dt><a name="asyncFun1" href="#asyncFun1"><span>asyncFun1:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: asyncFun1(): Future[int]" href="testproject.html#asyncFun1">testproject: asyncFun1(): Future[int]</a></li> + data-doc-search-tag="testproject: proc asyncFun1(): Future[int]" href="testproject.html#asyncFun1">testproject: proc asyncFun1(): Future[int]</a></li> </ul></dd> <dt><a name="asyncFun2" href="#asyncFun2"><span>asyncFun2:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: asyncFun2(): owned(Future[void])" href="testproject.html#asyncFun2">testproject: asyncFun2(): owned(Future[void])</a></li> + data-doc-search-tag="testproject: proc asyncFun2(): owned(Future[void])" href="testproject.html#asyncFun2">testproject: proc asyncFun2(): owned(Future[void])</a></li> </ul></dd> <dt><a name="asyncFun3" href="#asyncFun3"><span>asyncFun3:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: asyncFun3(): owned(Future[void])" href="testproject.html#asyncFun3">testproject: asyncFun3(): owned(Future[void])</a></li> + data-doc-search-tag="testproject: proc asyncFun3(): owned(Future[void])" href="testproject.html#asyncFun3">testproject: proc asyncFun3(): owned(Future[void])</a></li> </ul></dd> <dt><a name="aVariable" href="#aVariable"><span>aVariable:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: aVariable" href="testproject.html#aVariable">testproject: aVariable</a></li> + data-doc-search-tag="testproject: var aVariable" href="testproject.html#aVariable">testproject: var aVariable</a></li> </ul></dd> <dt><a name="B" href="#B"><span>B:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: B" href="testproject.html#B">testproject: B</a></li> + data-doc-search-tag="testproject: enum B" href="testproject.html#B">testproject: enum B</a></li> </ul></dd> <dt><a name="bar" href="#bar"><span>bar:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: bar(f: FooBuzz)" href="testproject.html#bar">testproject: bar(f: FooBuzz)</a></li> + data-doc-search-tag="testproject: proc bar(f: FooBuzz)" href="testproject.html#bar">testproject: proc bar(f: FooBuzz)</a></li> <li><a class="reference external" - data-doc-search-tag="testproject: bar[T](a, b: T): T" href="testproject.html#bar%2CT%2CT">testproject: bar[T](a, b: T): T</a></li> + data-doc-search-tag="testproject: proc bar[T](a, b: T): T" href="testproject.html#bar%2CT%2CT">testproject: proc bar[T](a, b: T): T</a></li> <li><a class="reference external" - data-doc-search-tag="testproject: bar(): untyped" href="testproject.html#bar.m">testproject: bar(): untyped</a></li> + data-doc-search-tag="testproject: macro bar(): untyped" href="testproject.html#bar.m">testproject: macro bar(): untyped</a></li> </ul></dd> <dt><a name="baz" href="#baz"><span>baz:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: baz()" href="testproject.html#baz">testproject: baz()</a></li> + data-doc-search-tag="testproject: proc baz()" href="testproject.html#baz">testproject: proc baz()</a></li> <li><a class="reference external" - data-doc-search-tag="testproject: baz[T](a, b: T): T" href="testproject.html#baz%2CT%2CT">testproject: baz[T](a, b: T): T</a></li> + data-doc-search-tag="testproject: proc baz[T](a, b: T): T" href="testproject.html#baz%2CT%2CT">testproject: proc baz[T](a, b: T): T</a></li> </ul></dd> <dt><a name="bEnum" href="#bEnum"><span>bEnum:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: bEnum(): untyped" href="subdir/subdir_b/utils.html#bEnum.t">utils: bEnum(): untyped</a></li> + data-doc-search-tag="utils: template bEnum(): untyped" href="subdir/subdir_b/utils.html#bEnum.t">utils: template bEnum(): untyped</a></li> </ul></dd> <dt><a name="binarySearch" href="#binarySearch"><span>binarySearch:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: binarySearch[T, K](a: openArray[T]; key: K; - cmp: proc (x: T; y: K): int {.closure.}): int" href="subdir/subdir_b/utils.html#binarySearch%2CopenArray%5BT%5D%2CK%2Cproc%28T%2CK%29">utils: binarySearch[T, K](a: openArray[T]; key: K; + data-doc-search-tag="utils: proc binarySearch[T, K](a: openArray[T]; key: K; + cmp: proc (x: T; y: K): int {.closure.}): int" href="subdir/subdir_b/utils.html#binarySearch%2CopenArray%5BT%5D%2CK%2Cproc%28T%2CK%29">utils: proc binarySearch[T, K](a: openArray[T]; key: K; cmp: proc (x: T; y: K): int {.closure.}): int</a></li> </ul></dd> <dt><a name="buzz" href="#buzz"><span>buzz:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: buzz[T](a, b: T): T" href="testproject.html#buzz%2CT%2CT">testproject: buzz[T](a, b: T): T</a></li> + data-doc-search-tag="testproject: proc buzz[T](a, b: T): T" href="testproject.html#buzz%2CT%2CT">testproject: proc buzz[T](a, b: T): T</a></li> </ul></dd> <dt><a name="C_A" href="#C_A"><span>C_A:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: C_A" href="testproject.html#C_A">testproject: C_A</a></li> + data-doc-search-tag="testproject: const C_A" href="testproject.html#C_A">testproject: const C_A</a></li> </ul></dd> <dt><a name="C_B" href="#C_B"><span>C_B:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: C_B" href="testproject.html#C_B">testproject: C_B</a></li> + data-doc-search-tag="testproject: const C_B" href="testproject.html#C_B">testproject: const C_B</a></li> </ul></dd> <dt><a name="C_C" href="#C_C"><span>C_C:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: C_C" href="testproject.html#C_C">testproject: C_C</a></li> + data-doc-search-tag="testproject: const C_C" href="testproject.html#C_C">testproject: const C_C</a></li> </ul></dd> <dt><a name="C_D" href="#C_D"><span>C_D:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: C_D" href="testproject.html#C_D">testproject: C_D</a></li> + data-doc-search-tag="testproject: const C_D" href="testproject.html#C_D">testproject: const C_D</a></li> </ul></dd> <dt><a name="Circle" href="#Circle"><span>Circle:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="Shapes.Circle" href="testproject.html#Circle">Shapes.Circle</a></li> + data-doc-search-tag="testproject: Shapes.Circle" href="testproject.html#Circle">testproject: Shapes.Circle</a></li> </ul></dd> <dt><a name="c_nonexistent" href="#c_nonexistent"><span>c_nonexistent:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: c_nonexistent(frmt: cstring): cint" href="testproject.html#c_nonexistent%2Ccstring">testproject: c_nonexistent(frmt: cstring): cint</a></li> + data-doc-search-tag="testproject: proc c_nonexistent(frmt: cstring): cint" href="testproject.html#c_nonexistent%2Ccstring">testproject: proc c_nonexistent(frmt: cstring): cint</a></li> </ul></dd> <dt><a name="c_printf" href="#c_printf"><span>c_printf:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: c_printf(frmt: cstring): cint" href="testproject.html#c_printf%2Ccstring">testproject: c_printf(frmt: cstring): cint</a></li> + data-doc-search-tag="testproject: proc c_printf(frmt: cstring): cint" href="testproject.html#c_printf%2Ccstring">testproject: proc c_printf(frmt: cstring): cint</a></li> </ul></dd> <dt><a name="enumValueA" href="#enumValueA"><span>enumValueA:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="SomeType.enumValueA" href="subdir/subdir_b/utils.html#enumValueA">SomeType.enumValueA</a></li> + data-doc-search-tag="utils: SomeType.enumValueA" href="subdir/subdir_b/utils.html#enumValueA">utils: SomeType.enumValueA</a></li> </ul></dd> <dt><a name="enumValueA2" href="#enumValueA2"><span>enumValueA2:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="Foo.enumValueA2" href="testproject.html#enumValueA2">Foo.enumValueA2</a></li> + data-doc-search-tag="testproject: Foo.enumValueA2" href="testproject.html#enumValueA2">testproject: Foo.enumValueA2</a></li> </ul></dd> <dt><a name="enumValueB" href="#enumValueB"><span>enumValueB:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="SomeType.enumValueB" href="subdir/subdir_b/utils.html#enumValueB">SomeType.enumValueB</a></li> + data-doc-search-tag="utils: SomeType.enumValueB" href="subdir/subdir_b/utils.html#enumValueB">utils: SomeType.enumValueB</a></li> </ul></dd> <dt><a name="enumValueC" href="#enumValueC"><span>enumValueC:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="SomeType.enumValueC" href="subdir/subdir_b/utils.html#enumValueC">SomeType.enumValueC</a></li> + data-doc-search-tag="utils: SomeType.enumValueC" href="subdir/subdir_b/utils.html#enumValueC">utils: SomeType.enumValueC</a></li> </ul></dd> <dt><a name="f" href="#f"><span>f:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: f(x: G[int])" href="subdir/subdir_b/utils.html#f%2CG%5Bint%5D">utils: f(x: G[int])</a></li> + data-doc-search-tag="utils: proc f(x: G[int])" href="subdir/subdir_b/utils.html#f%2CG%5Bint%5D">utils: proc f(x: G[int])</a></li> <li><a class="reference external" - data-doc-search-tag="utils: f(x: G[string])" href="subdir/subdir_b/utils.html#f%2CG%5Bstring%5D">utils: f(x: G[string])</a></li> + data-doc-search-tag="utils: proc f(x: G[string])" href="subdir/subdir_b/utils.html#f%2CG%5Bstring%5D">utils: proc f(x: G[string])</a></li> </ul></dd> <dt><a name="fn" href="#fn"><span>fn:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn[T; U, V: SomeFloat]()" href="subdir/subdir_b/utils.html#fn">utils: fn[T; U, V: SomeFloat]()</a></li> + data-doc-search-tag="utils: proc fn[T; U, V: SomeFloat]()" href="subdir/subdir_b/utils.html#fn">utils: proc fn[T; U, V: SomeFloat]()</a></li> </ul></dd> <dt><a name="fn10" href="#fn10"><span>fn10:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn10(a: int): int" href="subdir/subdir_b/utils.html#fn10%2Cint">utils: fn10(a: int): int</a></li> + data-doc-search-tag="utils: proc fn10(a: int): int" href="subdir/subdir_b/utils.html#fn10%2Cint">utils: proc fn10(a: int): int</a></li> </ul></dd> <dt><a name="fN11" href="#fN11"><span>fN11:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fN11()" href="subdir/subdir_b/utils.html#fN11">utils: fN11()</a></li> + data-doc-search-tag="utils: proc fN11()" href="subdir/subdir_b/utils.html#fN11">utils: proc fN11()</a></li> <li><a class="reference external" - data-doc-search-tag="utils: fN11(x: int)" href="subdir/subdir_b/utils.html#fN11%2Cint">utils: fN11(x: int)</a></li> + data-doc-search-tag="utils: proc fN11(x: int)" href="subdir/subdir_b/utils.html#fN11%2Cint">utils: proc fN11(x: int)</a></li> </ul></dd> <dt><a name="fn2" href="#fn2"><span>fn2:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn2()" href="subdir/subdir_b/utils.html#fn2">utils: fn2()</a></li> + data-doc-search-tag="utils: proc fn2()" href="subdir/subdir_b/utils.html#fn2">utils: proc fn2()</a></li> <li><a class="reference external" - data-doc-search-tag="utils: fn2(x: int)" href="subdir/subdir_b/utils.html#fn2%2Cint">utils: fn2(x: int)</a></li> + data-doc-search-tag="utils: proc fn2(x: int)" href="subdir/subdir_b/utils.html#fn2%2Cint">utils: proc fn2(x: int)</a></li> <li><a class="reference external" - data-doc-search-tag="utils: fn2(x: int; y: float)" href="subdir/subdir_b/utils.html#fn2%2Cint%2Cfloat">utils: fn2(x: int; y: float)</a></li> + data-doc-search-tag="utils: proc fn2(x: int; y: float)" href="subdir/subdir_b/utils.html#fn2%2Cint%2Cfloat">utils: proc fn2(x: int; y: float)</a></li> </ul></dd> <dt><a name="fn3" href="#fn3"><span>fn3:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn3(): auto" href="subdir/subdir_b/utils.html#fn3">utils: fn3(): auto</a></li> + data-doc-search-tag="utils: proc fn3(): auto" href="subdir/subdir_b/utils.html#fn3">utils: proc fn3(): auto</a></li> </ul></dd> <dt><a name="fn4" href="#fn4"><span>fn4:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn4(): auto" href="subdir/subdir_b/utils.html#fn4">utils: fn4(): auto</a></li> + data-doc-search-tag="utils: proc fn4(): auto" href="subdir/subdir_b/utils.html#fn4">utils: proc fn4(): auto</a></li> </ul></dd> <dt><a name="fn5" href="#fn5"><span>fn5:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn5()" href="subdir/subdir_b/utils.html#fn5">utils: fn5()</a></li> + data-doc-search-tag="utils: proc fn5()" href="subdir/subdir_b/utils.html#fn5">utils: proc fn5()</a></li> </ul></dd> <dt><a name="fn6" href="#fn6"><span>fn6:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn6()" href="subdir/subdir_b/utils.html#fn6">utils: fn6()</a></li> + data-doc-search-tag="utils: proc fn6()" href="subdir/subdir_b/utils.html#fn6">utils: proc fn6()</a></li> </ul></dd> <dt><a name="fn7" href="#fn7"><span>fn7:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn7()" href="subdir/subdir_b/utils.html#fn7">utils: fn7()</a></li> + data-doc-search-tag="utils: proc fn7()" href="subdir/subdir_b/utils.html#fn7">utils: proc fn7()</a></li> </ul></dd> <dt><a name="fn8" href="#fn8"><span>fn8:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn8(): auto" href="subdir/subdir_b/utils.html#fn8">utils: fn8(): auto</a></li> + data-doc-search-tag="utils: proc fn8(): auto" href="subdir/subdir_b/utils.html#fn8">utils: proc fn8(): auto</a></li> </ul></dd> <dt><a name="fn9" href="#fn9"><span>fn9:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fn9(a: int): int" href="subdir/subdir_b/utils.html#fn9%2Cint">utils: fn9(a: int): int</a></li> + data-doc-search-tag="utils: proc fn9(a: int): int" href="subdir/subdir_b/utils.html#fn9%2Cint">utils: proc fn9(a: int): int</a></li> </ul></dd> <dt><a name="Foo" href="#Foo"><span>Foo:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: Foo" href="testproject.html#Foo">testproject: Foo</a></li> + data-doc-search-tag="testproject: enum Foo" href="testproject.html#Foo">testproject: enum Foo</a></li> </ul></dd> <dt><a name="foo" href="#foo"><span>foo:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: foo(a, b: SomeType)" href="testproject.html#foo.t%2CSomeType%2CSomeType">testproject: foo(a, b: SomeType)</a></li> + data-doc-search-tag="testproject: template foo(a, b: SomeType)" href="testproject.html#foo.t%2CSomeType%2CSomeType">testproject: template foo(a, b: SomeType)</a></li> </ul></dd> <dt><a name="fooBar" href="#fooBar"><span>fooBar:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fooBar(a: seq[SomeType]): int" href="subdir/subdir_b/utils.html#fooBar.i%2Cseq%5BSomeType%5D">utils: fooBar(a: seq[SomeType]): int</a></li> + data-doc-search-tag="utils: iterator fooBar(a: seq[SomeType]): int" href="subdir/subdir_b/utils.html#fooBar.i%2Cseq%5BSomeType%5D">utils: iterator fooBar(a: seq[SomeType]): int</a></li> </ul></dd> <dt><a name="FooBuzz" href="#FooBuzz"><span>FooBuzz:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: FooBuzz" href="testproject.html#FooBuzz">testproject: FooBuzz</a></li> + data-doc-search-tag="testproject: type FooBuzz" href="testproject.html#FooBuzz">testproject: type FooBuzz</a></li> </ul></dd> <dt><a name="fromUtils1" href="#fromUtils1"><span>fromUtils1:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: fromUtils1(): int" href="testproject.html#fromUtils1.i">testproject: fromUtils1(): int</a></li> + data-doc-search-tag="testproject: iterator fromUtils1(): int" href="testproject.html#fromUtils1.i">testproject: iterator fromUtils1(): int</a></li> </ul></dd> <dt><a name="fromUtils2" href="#fromUtils2"><span>fromUtils2:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: fromUtils2()" href="testproject.html#fromUtils2.t">testproject: fromUtils2()</a></li> + data-doc-search-tag="testproject: template fromUtils2()" href="testproject.html#fromUtils2.t">testproject: template fromUtils2()</a></li> </ul></dd> <dt><a name="fromUtils3" href="#fromUtils3"><span>fromUtils3:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: fromUtils3()" href="testproject.html#fromUtils3">testproject: fromUtils3()</a></li> + data-doc-search-tag="testproject: proc fromUtils3()" href="testproject.html#fromUtils3">testproject: proc fromUtils3()</a></li> </ul></dd> <dt><a name="fromUtilsGen" href="#fromUtilsGen"><span>fromUtilsGen:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: fromUtilsGen(): untyped" href="subdir/subdir_b/utils.html#fromUtilsGen.t">utils: fromUtilsGen(): untyped</a></li> + data-doc-search-tag="utils: template fromUtilsGen(): untyped" href="subdir/subdir_b/utils.html#fromUtilsGen.t">utils: template fromUtilsGen(): untyped</a></li> </ul></dd> <dt><a name="funWithGenerics" href="#funWithGenerics"><span>funWithGenerics:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: funWithGenerics[T, U: SomeFloat](a: T; b: U)" href="subdir/subdir_b/utils.html#funWithGenerics%2CT%2CU">utils: funWithGenerics[T, U: SomeFloat](a: T; b: U)</a></li> + data-doc-search-tag="utils: proc funWithGenerics[T, U: SomeFloat](a: T; b: U)" href="subdir/subdir_b/utils.html#funWithGenerics%2CT%2CU">utils: proc funWithGenerics[T, U: SomeFloat](a: T; b: U)</a></li> </ul></dd> <dt><a name="G" href="#G"><span>G:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: G" href="subdir/subdir_b/utils.html#G">utils: G</a></li> + data-doc-search-tag="utils: object G" href="subdir/subdir_b/utils.html#G">utils: object G</a></li> </ul></dd> <dt><a name="isValid" href="#isValid"><span>isValid:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: isValid[T](x: T): bool" href="testproject.html#isValid%2CT">testproject: isValid[T](x: T): bool</a></li> + data-doc-search-tag="testproject: proc isValid[T](x: T): bool" href="testproject.html#isValid%2CT">testproject: proc isValid[T](x: T): bool</a></li> </ul></dd> <dt><a name="iter1" href="#iter1"><span>iter1:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: iter1(n: int): int" href="testproject.html#iter1.i%2Cint">testproject: iter1(n: int): int</a></li> + data-doc-search-tag="testproject: iterator iter1(n: int): int" href="testproject.html#iter1.i%2Cint">testproject: iterator iter1(n: int): int</a></li> </ul></dd> <dt><a name="iter2" href="#iter2"><span>iter2:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: iter2(n: int): int" href="testproject.html#iter2.i%2Cint">testproject: iter2(n: int): int</a></li> + data-doc-search-tag="testproject: iterator iter2(n: int): int" href="testproject.html#iter2.i%2Cint">testproject: iterator iter2(n: int): int</a></li> </ul></dd> <dt><a name="low" href="#low"><span>low:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: low[T: Ordinal | enum | range](x: T): T" href="testproject.html#low%2CT">testproject: low[T: Ordinal | enum | range](x: T): T</a></li> + data-doc-search-tag="testproject: proc low[T: Ordinal | enum | range](x: T): T" href="testproject.html#low%2CT">testproject: proc low[T: Ordinal | enum | range](x: T): T</a></li> </ul></dd> <dt><a name="low2" href="#low2"><span>low2:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: low2[T: Ordinal | enum | range](x: T): T" href="testproject.html#low2%2CT">testproject: low2[T: Ordinal | enum | range](x: T): T</a></li> + data-doc-search-tag="testproject: proc low2[T: Ordinal | enum | range](x: T): T" href="testproject.html#low2%2CT">testproject: proc low2[T: Ordinal | enum | range](x: T): T</a></li> </ul></dd> <dt><a name="method1" href="#method1"><span>method1:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: method1(self: Moo)" href="testproject.html#method1.e%2CMoo">testproject: method1(self: Moo)</a></li> + data-doc-search-tag="testproject: method method1(self: Moo)" href="testproject.html#method1.e%2CMoo">testproject: method method1(self: Moo)</a></li> </ul></dd> <dt><a name="method2" href="#method2"><span>method2:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: method2(self: Moo): int" href="testproject.html#method2.e%2CMoo">testproject: method2(self: Moo): int</a></li> + data-doc-search-tag="testproject: method method2(self: Moo): int" href="testproject.html#method2.e%2CMoo">testproject: method method2(self: Moo): int</a></li> </ul></dd> <dt><a name="method3" href="#method3"><span>method3:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: method3(self: Moo): int" href="testproject.html#method3.e%2CMoo">testproject: method3(self: Moo): int</a></li> + data-doc-search-tag="testproject: method method3(self: Moo): int" href="testproject.html#method3.e%2CMoo">testproject: method method3(self: Moo): int</a></li> </ul></dd> <dt><a name="myfn" href="#myfn"><span>myfn:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: myfn()" href="testproject.html#myfn.t">testproject: myfn()</a></li> + data-doc-search-tag="testproject: template myfn()" href="testproject.html#myfn.t">testproject: template myfn()</a></li> </ul></dd> <dt><a name="p1" href="#p1"><span>p1:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: p1()" href="testproject.html#p1">testproject: p1()</a></li> + data-doc-search-tag="testproject: proc p1()" href="testproject.html#p1">testproject: proc p1()</a></li> </ul></dd> <dt><a name="Rectangle" href="#Rectangle"><span>Rectangle:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="Shapes.Rectangle" href="testproject.html#Rectangle">Shapes.Rectangle</a></li> + data-doc-search-tag="testproject: Shapes.Rectangle" href="testproject.html#Rectangle">testproject: Shapes.Rectangle</a></li> </ul></dd> <dt><a name="Shapes" href="#Shapes"><span>Shapes:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: Shapes" href="testproject.html#Shapes">testproject: Shapes</a></li> + data-doc-search-tag="testproject: enum Shapes" href="testproject.html#Shapes">testproject: enum Shapes</a></li> </ul></dd> <dt><a name="someFunc" href="#someFunc"><span>someFunc:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: someFunc()" href="testproject.html#someFunc">testproject: someFunc()</a></li> + data-doc-search-tag="testproject: proc someFunc()" href="testproject.html#someFunc">testproject: proc someFunc()</a></li> </ul></dd> <dt><a name="SomeType" href="#SomeType"><span>SomeType:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: SomeType" href="subdir/subdir_b/utils.html#SomeType">utils: SomeType</a></li> + data-doc-search-tag="utils: enum SomeType" href="subdir/subdir_b/utils.html#SomeType">utils: enum SomeType</a></li> </ul></dd> <dt><a name="someType" href="#someType"><span>someType:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="utils: someType(): SomeType" href="subdir/subdir_b/utils.html#someType_2">utils: someType(): SomeType</a></li> + data-doc-search-tag="utils: proc someType(): SomeType" href="subdir/subdir_b/utils.html#someType_2">utils: proc someType(): SomeType</a></li> </ul></dd> <dt><a name="someVariable" href="#someVariable"><span>someVariable:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: someVariable" href="testproject.html#someVariable">testproject: someVariable</a></li> + data-doc-search-tag="testproject: var someVariable" href="testproject.html#someVariable">testproject: var someVariable</a></li> </ul></dd> <dt><a name="testNimDocTrailingExample" href="#testNimDocTrailingExample"><span>testNimDocTrailingExample:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: testNimDocTrailingExample()" href="testproject.html#testNimDocTrailingExample.t">testproject: testNimDocTrailingExample()</a></li> + data-doc-search-tag="testproject: template testNimDocTrailingExample()" href="testproject.html#testNimDocTrailingExample.t">testproject: template testNimDocTrailingExample()</a></li> </ul></dd> <dt><a name="Triangle" href="#Triangle"><span>Triangle:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="Shapes.Triangle" href="testproject.html#Triangle">Shapes.Triangle</a></li> + data-doc-search-tag="testproject: Shapes.Triangle" href="testproject.html#Triangle">testproject: Shapes.Triangle</a></li> </ul></dd> <dt><a name="tripleStrLitTest" href="#tripleStrLitTest"><span>tripleStrLitTest:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: tripleStrLitTest()" href="testproject.html#tripleStrLitTest">testproject: tripleStrLitTest()</a></li> + data-doc-search-tag="testproject: proc tripleStrLitTest()" href="testproject.html#tripleStrLitTest">testproject: proc tripleStrLitTest()</a></li> </ul></dd> <dt><a name="z1" href="#z1"><span>z1:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z1(): Foo" href="testproject.html#z1">testproject: z1(): Foo</a></li> + data-doc-search-tag="testproject: proc z1(): Foo" href="testproject.html#z1">testproject: proc z1(): Foo</a></li> </ul></dd> <dt><a name="z10" href="#z10"><span>z10:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z10()" href="testproject.html#z10">testproject: z10()</a></li> + data-doc-search-tag="testproject: proc z10()" href="testproject.html#z10">testproject: proc z10()</a></li> </ul></dd> <dt><a name="z11" href="#z11"><span>z11:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z11()" href="testproject.html#z11">testproject: z11()</a></li> + data-doc-search-tag="testproject: proc z11()" href="testproject.html#z11">testproject: proc z11()</a></li> </ul></dd> <dt><a name="z12" href="#z12"><span>z12:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z12(): int" href="testproject.html#z12">testproject: z12(): int</a></li> + data-doc-search-tag="testproject: proc z12(): int" href="testproject.html#z12">testproject: proc z12(): int</a></li> </ul></dd> <dt><a name="z13" href="#z13"><span>z13:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z13()" href="testproject.html#z13">testproject: z13()</a></li> + data-doc-search-tag="testproject: proc z13()" href="testproject.html#z13">testproject: proc z13()</a></li> </ul></dd> <dt><a name="z14" href="#z14"><span>z14:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z14()" href="testproject.html#z14.t">testproject: z14()</a></li> + data-doc-search-tag="testproject: template z14()" href="testproject.html#z14.t">testproject: template z14()</a></li> </ul></dd> <dt><a name="z15" href="#z15"><span>z15:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z15()" href="testproject.html#z15.t">testproject: z15()</a></li> + data-doc-search-tag="testproject: template z15()" href="testproject.html#z15.t">testproject: template z15()</a></li> </ul></dd> <dt><a name="z16" href="#z16"><span>z16:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z16()" href="testproject.html#z16.m">testproject: z16()</a></li> + data-doc-search-tag="testproject: macro z16()" href="testproject.html#z16.m">testproject: macro z16()</a></li> </ul></dd> <dt><a name="z17" href="#z17"><span>z17:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z17()" href="testproject.html#z17">testproject: z17()</a></li> + data-doc-search-tag="testproject: proc z17()" href="testproject.html#z17">testproject: proc z17()</a></li> </ul></dd> <dt><a name="z18" href="#z18"><span>z18:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z18(): int" href="testproject.html#z18.m">testproject: z18(): int</a></li> + data-doc-search-tag="testproject: macro z18(): int" href="testproject.html#z18.m">testproject: macro z18(): int</a></li> </ul></dd> <dt><a name="z2" href="#z2"><span>z2:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z2()" href="testproject.html#z2">testproject: z2()</a></li> + data-doc-search-tag="testproject: proc z2()" href="testproject.html#z2">testproject: proc z2()</a></li> </ul></dd> <dt><a name="z3" href="#z3"><span>z3:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z3()" href="testproject.html#z3">testproject: z3()</a></li> + data-doc-search-tag="testproject: proc z3()" href="testproject.html#z3">testproject: proc z3()</a></li> </ul></dd> <dt><a name="z4" href="#z4"><span>z4:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z4()" href="testproject.html#z4">testproject: z4()</a></li> + data-doc-search-tag="testproject: proc z4()" href="testproject.html#z4">testproject: proc z4()</a></li> </ul></dd> <dt><a name="z5" href="#z5"><span>z5:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z5(): int" href="testproject.html#z5">testproject: z5(): int</a></li> + data-doc-search-tag="testproject: proc z5(): int" href="testproject.html#z5">testproject: proc z5(): int</a></li> </ul></dd> <dt><a name="z6" href="#z6"><span>z6:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z6(): int" href="testproject.html#z6">testproject: z6(): int</a></li> + data-doc-search-tag="testproject: proc z6(): int" href="testproject.html#z6">testproject: proc z6(): int</a></li> </ul></dd> <dt><a name="z6t" href="#z6t"><span>z6t:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z6t(): int" href="testproject.html#z6t.t">testproject: z6t(): int</a></li> + data-doc-search-tag="testproject: template z6t(): int" href="testproject.html#z6t.t">testproject: template z6t(): int</a></li> </ul></dd> <dt><a name="z7" href="#z7"><span>z7:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z7(): int" href="testproject.html#z7">testproject: z7(): int</a></li> + data-doc-search-tag="testproject: proc z7(): int" href="testproject.html#z7">testproject: proc z7(): int</a></li> </ul></dd> <dt><a name="z8" href="#z8"><span>z8:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z8(): int" href="testproject.html#z8">testproject: z8(): int</a></li> + data-doc-search-tag="testproject: proc z8(): int" href="testproject.html#z8">testproject: proc z8(): int</a></li> </ul></dd> <dt><a name="z9" href="#z9"><span>z9:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" - data-doc-search-tag="testproject: z9()" href="testproject.html#z9">testproject: z9()</a></li> + data-doc-search-tag="testproject: proc z9()" href="testproject.html#z9">testproject: proc z9()</a></li> </ul></dd> </dl> <div class="twelve-columns footer"> diff --git a/tests/stdlib/tdochelpers.nim b/tests/stdlib/tdochelpers.nim index 15d538891..300ce76dc 100644 --- a/tests/stdlib/tdochelpers.nim +++ b/tests/stdlib/tdochelpers.nim @@ -202,3 +202,19 @@ suite "Integration with Nim": name: "Copyflag") check inputRst.fromRst == expected check inputMd.fromMd == expected + + test "prefixed module": + let inputRst = "`module std / paths`_" + let inputMd = "[module std / paths]" + let expected = LangSymbol(symKind: "module", + name: "std/paths") + check inputRst.fromRst == expected + check inputMd.fromMd == expected + + test "postfixed module": + let inputRst = "`std / paths module`_" + let inputMd = "[std / paths module]" + let expected = LangSymbol(symKind: "module", + name: "std/paths") + check inputRst.fromRst == expected + check inputMd.fromMd == expected diff --git a/tests/stdlib/trst.nim b/tests/stdlib/trst.nim index 3575d17aa..da787d274 100644 --- a/tests/stdlib/trst.nim +++ b/tests/stdlib/trst.nim @@ -60,7 +60,7 @@ proc toAst(input: string, result = "" var (rst, _, _) = rstParse(input, filen, line=LineRstInit, column=ColRstInit, - rstOptions, myFindFile, testMsgHandler) + rstOptions, myFindFile, nil, testMsgHandler) result = treeRepr(rst) except EParseError as e: if e.msg != "": diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 4fffc7533..f63aea030 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -240,27 +240,28 @@ proc buildDocSamples(nimArgs, destPath: string) = exec(findNim().quoteShell() & " doc $# -o:$# $#" % [nimArgs, destPath / "docgen_sample.html", "doc" / "docgen_sample.nim"]) -proc buildDocPackages(nimArgs, destPath: string) = +proc buildDocPackages(nimArgs, destPath: string, indexOnly: bool) = # compiler docs; later, other packages (perhaps tools, testament etc) let nim = findNim().quoteShell() # to avoid broken links to manual from compiler dir, but a multi-package # structure could be supported later proc docProject(outdir, options, mainproj: string) = - exec("$nim doc --project --outdir:$outdir $nimArgs --git.url:$gitUrl $options $mainproj" % [ + exec("$nim doc --project --outdir:$outdir $nimArgs --git.url:$gitUrl $index $options $mainproj" % [ "nim", nim, "outdir", outdir, "nimArgs", nimArgs, "gitUrl", gitUrl, "options", options, "mainproj", mainproj, + "index", if indexOnly: "--index:only" else: "" ]) 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) = +proc buildDoc(nimArgs, destPath: string, indexOnly: bool) = # call nim for the documentation: let rst2html = getMd2html() var @@ -268,17 +269,19 @@ proc buildDoc(nimArgs, destPath: string) = officialPackagesList.len + officialPackagesListWithoutIndex.len) i = 0 let nim = findNim().quoteShell() + + let index = if indexOnly: "--index:only" else: "" for d in items(rst2html): - commands[i] = nim & " md2html $# --git.url:$# -o:$# --index:on $#" % + commands[i] = nim & " md2html $# --git.url:$# -o:$# $# $#" % [nimArgs, gitUrl, - destPath / changeFileExt(splitFile(d).name, "html"), d] + destPath / changeFileExt(splitFile(d).name, "html"), index, d] i.inc for d in items(doc): let extra = if isJsOnly(d): "--backend:js" else: "" var nimArgs2 = nimArgs if d.isRelativeTo("compiler"): doAssert false - commands[i] = nim & " doc $# $# --git.url:$# --outdir:$# --index:on $#" % - [extra, nimArgs2, gitUrl, destPath, d] + commands[i] = nim & " doc $# $# --git.url:$# --outdir:$# $# $#" % + [extra, nimArgs2, gitUrl, destPath, index, d] i.inc for d in items(withoutIndex): commands[i] = nim & " doc $# --git.url:$# -o:$# $#" % @@ -300,12 +303,6 @@ proc buildDoc(nimArgs, destPath: string) = i.inc mexec(commands) - exec(nim & " buildIndex -o:$1/theindex.html $1" % [destPath]) - # caveat: this works so long it's called before `buildDocPackages` which - # populates `compiler/` with unrelated idx files that shouldn't be in index, - # so should work in CI but you may need to remove your generated html files - # locally after calling `./koch docs`. The clean fix would be for `idx` files - # to be transient with `--project` (eg all in memory). proc nim2pdf(src: string, dst: string, nimArgs: string) = # xxx expose as a `nim` command or in some other reusable way. @@ -351,9 +348,23 @@ proc buildDocsDir*(args: string, dir: string) = gitClonePackages(@["asyncftpclient", "punycode", "smtp", "db_connector"]) createDir(dir) buildDocSamples(args, dir) - buildDoc(args, dir) # bottleneck + + # generate `.idx` files and top-level `theindex.html`: + buildDoc(args, dir, indexOnly=true) # bottleneck + let nim = findNim().quoteShell() + exec(nim & " buildIndex -o:$1/theindex.html $1" % [dir]) + # caveat: this works so long it's called before `buildDocPackages` which + # populates `compiler/` with unrelated idx files that shouldn't be in index, + # so should work in CI but you may need to remove your generated html files + # locally after calling `./koch docs`. The clean fix would be for `idx` files + # to be transient with `--project` (eg all in memory). + buildDocPackages(args, dir, indexOnly=true) + + # generate HTML and package-level `theindex.html`: + buildDoc(args, dir, indexOnly=false) # bottleneck + buildDocPackages(args, dir, indexOnly=false) + copyFile(dir / "overview.html", dir / "index.html") - buildDocPackages(args, dir) copyFile(docHackJsSource, dir / docHackJsSource.lastPathPart) proc buildDocs*(args: string, localOnly = false, localOutDir = "") = |