diff options
Diffstat (limited to 'compiler/docgen.nim')
-rw-r--r-- | compiler/docgen.nim | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 33cd98f38..a7f7d77b5 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -144,28 +144,28 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef, initStrTable result.types result.onTestSnippet = proc (gen: var RstGenerator; filename, cmd: string; status: int; content: string) = - var d = TDocumentor(gen) - var outp: AbsoluteFile - if filename.len == 0: - inc(d.id) - let nameOnly = splitFile(d.filename).name - let subdir = getNimcacheDir(conf) / RelativeDir(nameOnly) - createDir(subdir) - outp = subdir / RelativeFile(nameOnly & "_snippet_" & $d.id & ".nim") - elif isAbsolute(filename): - outp = AbsoluteFile filename - else: - # Nim's convention: every path is relative to the file it was written in: - outp = splitFile(d.filename).dir.AbsoluteDir / RelativeFile(filename) - # Include the current file if we're parsing a nim file - let importStmt = if d.isPureRst: "" else: "import \"$1\"\n" % [d.filename] - writeFile(outp, importStmt & content) - let c = if cmd.startsWith("nim "): os.getAppFilename() & cmd.substr(3) - else: cmd - let c2 = c % quoteShell(outp) - rawMessage(conf, hintExecuting, c2) - if execShellCmd(c2) != status: - rawMessage(conf, errGenerated, "executing of external program failed: " & c2) + var d = TDocumentor(gen) + var outp: AbsoluteFile + if filename.len == 0: + inc(d.id) + let nameOnly = splitFile(d.filename).name + let subdir = getNimcacheDir(conf) / RelativeDir(nameOnly) + createDir(subdir) + outp = subdir / RelativeFile(nameOnly & "_snippet_" & $d.id & ".nim") + elif isAbsolute(filename): + outp = AbsoluteFile filename + else: + # Nim's convention: every path is relative to the file it was written in: + outp = splitFile(d.filename).dir.AbsoluteDir / RelativeFile(filename) + # Include the current file if we're parsing a nim file + let importStmt = if d.isPureRst: "" else: "import \"$1\"\n" % [d.filename] + writeFile(outp, importStmt & content) + let c = if cmd.startsWith("nim "): os.getAppFilename() & cmd.substr(3) + else: cmd + let c2 = c % quoteShell(outp) + rawMessage(conf, hintExecuting, c2) + if execShellCmd(c2) != status: + rawMessage(conf, errGenerated, "executing of external program failed: " & c2) result.emitted = initIntSet() result.destFile = getOutFile2(conf, relativeTo(filename, conf.projectPath), outExt, RelativeDir"htmldocs", false) @@ -300,13 +300,17 @@ proc externalDep(d: PDoc; module: PSym): string = else: result = extractFilename toFullPath(d.conf, FileIndex module.position) -proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRenderFlags = {}) = +proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRenderFlags = {}; + procLink: Rope) = var r: TSrcGen var literal = "" initTokRender(r, n, renderFlags) var kind = tkEof + var tokenPos = 0 + var procTokenPos = 0 while true: getNextTok(r, kind, literal) + inc tokenPos case kind of tkEof: break @@ -314,6 +318,8 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe dispA(d.conf, result, "<span class=\"Comment\">$1</span>", "\\spanComment{$1}", [rope(esc(d.target, literal))]) of tokKeywordLow..tokKeywordHigh: + if kind in {tkProc, tkMethod, tkIterator, tkMacro, tkTemplate, tkFunc, tkConverter}: + procTokenPos = tokenPos dispA(d.conf, result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}", [rope(literal)]) of tkOpr: @@ -333,7 +339,11 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe "\\spanFloatNumber{$1}", [rope(esc(d.target, literal))]) of tkSymbol: let s = getTokSym(r) - if s != nil and s.kind == skType and sfExported in s.flags and + # -2 because of the whitespace in between: + if procTokenPos == tokenPos-2 and procLink != nil: + dispA(d.conf, result, "<a href=\"#$2\"><span class=\"Identifier\">$1</span></a>", + "\\spanIdentifier{$1}", [rope(esc(d.target, literal)), procLink]) + elif s != nil and s.kind == skType and sfExported in s.flags and s.owner != nil and belongsToPackage(d.conf, s.owner) and d.target == outHtml: let external = externalDep(d, s.owner) @@ -445,7 +455,7 @@ proc getAllRunnableExamplesRec(d: PDoc; n, orig: PNode; dest: var Rope) = for b in body: if i > 0: dest.add "\n" inc i - nodeToHighlightedHtml(d, b, dest, {}) + nodeToHighlightedHtml(d, b, dest, {}, nil) dest.add(d.config.getOrDefault"doc.listing_end" % id) else: discard for i in 0 ..< n.safeLen: @@ -464,7 +474,10 @@ proc isVisible(d: PDoc; n: PNode): bool = # we cannot generate code for forwarded symbols here as we have no # exception tracking information here. Instead we copy over the comment # from the proc header. - result = {sfExported, sfFromGeneric, sfForward}*n.sym.flags == {sfExported} + if optDocInternal in d.conf.globalOptions: + result = {sfFromGeneric, sfForward}*n.sym.flags == {} + else: + result = {sfExported, sfFromGeneric, sfForward}*n.sym.flags == {sfExported} if result and containsOrIncl(d.emitted, n.sym.id): result = false elif n.kind == nkPragmaExpr: @@ -545,16 +558,19 @@ proc complexName(k: TSymKind, n: PNode, baseName: string): string = ## If you modify the output of this proc, please update the anchor generation ## section of ``doc/docgen.txt``. result = baseName - case k: - of skProc, skFunc: result.add(defaultParamSeparator) - of skMacro: result.add(".m" & defaultParamSeparator) - of skMethod: result.add(".e" & defaultParamSeparator) - of skIterator: result.add(".i" & defaultParamSeparator) - of skTemplate: result.add(".t" & defaultParamSeparator) - of skConverter: result.add(".c" & defaultParamSeparator) + case k + of skProc, skFunc: discard + of skMacro: result.add(".m") + of skMethod: result.add(".e") + of skIterator: result.add(".i") + of skTemplate: result.add(".t") + of skConverter: result.add(".c") else: discard if len(n) > paramsPos and n[paramsPos].kind == nkFormalParams: - result.add(renderParamTypes(n[paramsPos])) + let params = renderParamTypes(n[paramsPos]) + if params.len > 0: + result.add(defaultParamSeparator) + result.add(params) proc isCallable(n: PNode): bool = ## Returns true if `n` contains a callable node. @@ -612,9 +628,6 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = break plainName.add(literal) - nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments, - renderDocComments, renderSyms}) - inc(d.id) let plainNameRope = rope(xmltree.escape(plainName.strip)) @@ -627,6 +640,9 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = symbolOrIdRope = symbolOrId.rope symbolOrIdEncRope = encodeUrl(symbolOrId).rope + nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments, + renderDocComments, renderSyms}, symbolOrIdEncRope) + var seeSrcRope: Rope = nil let docItemSeeSrc = getConfigVar(d.conf, "doc.item.seesrc") if docItemSeeSrc.len > 0: |