docgen: get rid of ropes (#17939)
This commit is contained in:
parent
00bb3c779e
commit
706562f661
1 changed files with 146 additions and 190 deletions
|
|
@ -11,7 +11,7 @@
|
||||||
# by knowing how the anchors are going to be named.
|
# by knowing how the anchors are going to be named.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, strutils, strtabs, options, msgs, os, ropes, idents,
|
ast, strutils, strtabs, options, msgs, os, idents,
|
||||||
wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast,
|
wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast,
|
||||||
packages/docutils/rst, packages/docutils/rstgen,
|
packages/docutils/rst, packages/docutils/rstgen,
|
||||||
json, xmltree, trees, types,
|
json, xmltree, trees, types,
|
||||||
|
|
@ -28,7 +28,7 @@ const
|
||||||
DocColOffset = "## ".len # assuming that a space was added after ##
|
DocColOffset = "## ".len # assuming that a space was added after ##
|
||||||
|
|
||||||
type
|
type
|
||||||
TSections = array[TSymKind, Rope]
|
TSections = array[TSymKind, string]
|
||||||
ExampleGroup = ref object
|
ExampleGroup = ref object
|
||||||
## a group of runnableExamples with same rdoccmd
|
## a group of runnableExamples with same rdoccmd
|
||||||
rdoccmd: string ## from 1st arg in `runnableExamples(rdoccmd): body`
|
rdoccmd: string ## from 1st arg in `runnableExamples(rdoccmd): body`
|
||||||
|
|
@ -36,11 +36,11 @@ type
|
||||||
code: string ## contains imports; each import contains `body`
|
code: string ## contains imports; each import contains `body`
|
||||||
index: int ## group index
|
index: int ## group index
|
||||||
TDocumentor = object of rstgen.RstGenerator
|
TDocumentor = object of rstgen.RstGenerator
|
||||||
modDesc: Rope # module description
|
modDesc: string # module description
|
||||||
module: PSym
|
module: PSym
|
||||||
modDeprecationMsg: Rope
|
modDeprecationMsg: string
|
||||||
toc, toc2, section: TSections
|
toc, toc2, section: TSections
|
||||||
tocTable: array[TSymKind, Table[string, Rope]]
|
tocTable: array[TSymKind, Table[string, string]]
|
||||||
indexValFilename: string
|
indexValFilename: string
|
||||||
analytics: string # Google Analytics javascript, "" if doesn't exist
|
analytics: string # Google Analytics javascript, "" if doesn't exist
|
||||||
seenSymbols: StringTableRef # avoids duplicate symbol generation for HTML.
|
seenSymbols: StringTableRef # avoids duplicate symbol generation for HTML.
|
||||||
|
|
@ -247,7 +247,8 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
|
||||||
result.destFile = getOutFile2(conf, presentationPath(conf, filename), outExt, false).string
|
result.destFile = getOutFile2(conf, presentationPath(conf, filename), outExt, false).string
|
||||||
result.thisDir = result.destFile.AbsoluteFile.splitFile.dir
|
result.thisDir = result.destFile.AbsoluteFile.splitFile.dir
|
||||||
|
|
||||||
template dispA(conf: ConfigRef; dest: var Rope, xml, tex: string, args: openArray[Rope]) =
|
template dispA(conf: ConfigRef; dest: var string, xml, tex: string,
|
||||||
|
args: openArray[string]) =
|
||||||
if conf.cmd != cmdRst2tex: dest.addf(xml, args)
|
if conf.cmd != cmdRst2tex: dest.addf(xml, args)
|
||||||
else: dest.addf(tex, args)
|
else: dest.addf(tex, args)
|
||||||
|
|
||||||
|
|
@ -257,64 +258,6 @@ proc getVarIdx(varnames: openArray[string], id: string): int =
|
||||||
return i
|
return i
|
||||||
result = -1
|
result = -1
|
||||||
|
|
||||||
proc ropeFormatNamedVars(conf: ConfigRef; frmt: FormatStr,
|
|
||||||
varnames: openArray[string],
|
|
||||||
varvalues: openArray[Rope]): Rope =
|
|
||||||
var i = 0
|
|
||||||
result = nil
|
|
||||||
var num = 0
|
|
||||||
while i < frmt.len:
|
|
||||||
if frmt[i] == '$':
|
|
||||||
inc(i) # skip '$'
|
|
||||||
case frmt[i]
|
|
||||||
of '#':
|
|
||||||
result.add(varvalues[num])
|
|
||||||
inc(num)
|
|
||||||
inc(i)
|
|
||||||
of '$':
|
|
||||||
result.add("$")
|
|
||||||
inc(i)
|
|
||||||
of '0'..'9':
|
|
||||||
var j = 0
|
|
||||||
while true:
|
|
||||||
j = (j * 10) + ord(frmt[i]) - ord('0')
|
|
||||||
inc(i)
|
|
||||||
if (i > frmt.len + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
|
|
||||||
if j > high(varvalues) + 1:
|
|
||||||
rawMessage(conf, errGenerated, "Invalid format string; too many $s: " & frmt)
|
|
||||||
num = j
|
|
||||||
result.add(varvalues[j - 1])
|
|
||||||
of 'A'..'Z', 'a'..'z', '\x80'..'\xFF':
|
|
||||||
var id = ""
|
|
||||||
while true:
|
|
||||||
id.add(frmt[i])
|
|
||||||
inc(i)
|
|
||||||
if not (frmt[i] in {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}): break
|
|
||||||
var idx = getVarIdx(varnames, id)
|
|
||||||
if idx >= 0: result.add(varvalues[idx])
|
|
||||||
else: rawMessage(conf, errGenerated, "unknown substition variable: " & id)
|
|
||||||
of '{':
|
|
||||||
var id = ""
|
|
||||||
inc(i)
|
|
||||||
while i < frmt.len and frmt[i] != '}':
|
|
||||||
id.add(frmt[i])
|
|
||||||
inc(i)
|
|
||||||
if i >= frmt.len:
|
|
||||||
rawMessage(conf, errGenerated, "expected closing '}'")
|
|
||||||
else:
|
|
||||||
inc(i) # skip }
|
|
||||||
# search for the variable:
|
|
||||||
let idx = getVarIdx(varnames, id)
|
|
||||||
if idx >= 0: result.add(varvalues[idx])
|
|
||||||
else: rawMessage(conf, errGenerated, "unknown substition variable: " & id)
|
|
||||||
else:
|
|
||||||
result.add("$")
|
|
||||||
var start = i
|
|
||||||
while i < frmt.len:
|
|
||||||
if frmt[i] != '$': inc(i)
|
|
||||||
else: break
|
|
||||||
if i - 1 >= start: result.add(substr(frmt, start, i - 1))
|
|
||||||
|
|
||||||
proc genComment(d: PDoc, n: PNode): string =
|
proc genComment(d: PDoc, n: PNode): string =
|
||||||
result = ""
|
result = ""
|
||||||
if n.comment.len > 0:
|
if n.comment.len > 0:
|
||||||
|
|
@ -329,23 +272,23 @@ proc genComment(d: PDoc, n: PNode): string =
|
||||||
(var dummy: bool; dummy), d.options, d.conf),
|
(var dummy: bool; dummy), d.options, d.conf),
|
||||||
result)
|
result)
|
||||||
|
|
||||||
proc genRecCommentAux(d: PDoc, n: PNode): Rope =
|
proc genRecCommentAux(d: PDoc, n: PNode): string =
|
||||||
if n == nil: return nil
|
if n == nil: return ""
|
||||||
result = genComment(d, n).rope
|
result = genComment(d, n)
|
||||||
if result == nil:
|
if result == "":
|
||||||
if n.kind in {nkStmtList, nkStmtListExpr, nkTypeDef, nkConstDef,
|
if n.kind in {nkStmtList, nkStmtListExpr, nkTypeDef, nkConstDef,
|
||||||
nkObjectTy, nkRefTy, nkPtrTy, nkAsgn, nkFastAsgn, nkHiddenStdConv}:
|
nkObjectTy, nkRefTy, nkPtrTy, nkAsgn, nkFastAsgn, nkHiddenStdConv}:
|
||||||
# notin {nkEmpty..nkNilLit, nkEnumTy, nkTupleTy}:
|
# notin {nkEmpty..nkNilLit, nkEnumTy, nkTupleTy}:
|
||||||
for i in 0..<n.len:
|
for i in 0..<n.len:
|
||||||
result = genRecCommentAux(d, n[i])
|
result = genRecCommentAux(d, n[i])
|
||||||
if result != nil: return
|
if result != "": return
|
||||||
else:
|
else:
|
||||||
n.comment = ""
|
n.comment = ""
|
||||||
|
|
||||||
proc genRecComment(d: PDoc, n: PNode): Rope =
|
proc genRecComment(d: PDoc, n: PNode): string =
|
||||||
if n == nil: return nil
|
if n == nil: return ""
|
||||||
result = genComment(d, n).rope
|
result = genComment(d, n)
|
||||||
if result == nil:
|
if result == "":
|
||||||
if n.kind in {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef,
|
if n.kind in {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef,
|
||||||
nkMacroDef, nkTemplateDef, nkConverterDef}:
|
nkMacroDef, nkTemplateDef, nkConverterDef}:
|
||||||
result = genRecCommentAux(d, n[bodyPos])
|
result = genRecCommentAux(d, n[bodyPos])
|
||||||
|
|
@ -377,15 +320,16 @@ proc externalDep(d: PDoc; module: PSym): string =
|
||||||
else:
|
else:
|
||||||
result = extractFilename toFullPath(d.conf, FileIndex module.position)
|
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 string;
|
||||||
procLink: Rope) =
|
renderFlags: TRenderFlags = {};
|
||||||
|
procLink: string) =
|
||||||
var r: TSrcGen
|
var r: TSrcGen
|
||||||
var literal = ""
|
var literal = ""
|
||||||
initTokRender(r, n, renderFlags)
|
initTokRender(r, n, renderFlags)
|
||||||
var kind = tkEof
|
var kind = tkEof
|
||||||
var tokenPos = 0
|
var tokenPos = 0
|
||||||
var procTokenPos = 0
|
var procTokenPos = 0
|
||||||
template escLit(): untyped = rope(esc(d.target, literal))
|
template escLit(): untyped = esc(d.target, literal)
|
||||||
while true:
|
while true:
|
||||||
getNextTok(r, kind, literal)
|
getNextTok(r, kind, literal)
|
||||||
inc tokenPos
|
inc tokenPos
|
||||||
|
|
@ -399,7 +343,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe
|
||||||
if kind in {tkProc, tkMethod, tkIterator, tkMacro, tkTemplate, tkFunc, tkConverter}:
|
if kind in {tkProc, tkMethod, tkIterator, tkMacro, tkTemplate, tkFunc, tkConverter}:
|
||||||
procTokenPos = tokenPos
|
procTokenPos = tokenPos
|
||||||
dispA(d.conf, result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}",
|
dispA(d.conf, result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}",
|
||||||
[rope(literal)])
|
[literal])
|
||||||
of tkOpr:
|
of tkOpr:
|
||||||
dispA(d.conf, result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}",
|
dispA(d.conf, result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}",
|
||||||
[escLit])
|
[escLit])
|
||||||
|
|
@ -418,7 +362,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe
|
||||||
of tkSymbol:
|
of tkSymbol:
|
||||||
let s = getTokSym(r)
|
let s = getTokSym(r)
|
||||||
# -2 because of the whitespace in between:
|
# -2 because of the whitespace in between:
|
||||||
if procTokenPos == tokenPos-2 and procLink != nil:
|
if procTokenPos == tokenPos-2 and procLink != "":
|
||||||
dispA(d.conf, result, "<a href=\"#$2\"><span class=\"Identifier\">$1</span></a>",
|
dispA(d.conf, result, "<a href=\"#$2\"><span class=\"Identifier\">$1</span></a>",
|
||||||
"\\spanIdentifier{$1}", [escLit, procLink])
|
"\\spanIdentifier{$1}", [escLit, procLink])
|
||||||
elif s != nil and s.kind in {skType, skVar, skLet, skConst} and
|
elif s != nil and s.kind in {skType, skVar, skLet, skConst} and
|
||||||
|
|
@ -426,7 +370,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe
|
||||||
belongsToPackage(d.conf, s.owner) and d.target == outHtml:
|
belongsToPackage(d.conf, s.owner) and d.target == outHtml:
|
||||||
let external = externalDep(d, s.owner)
|
let external = externalDep(d, s.owner)
|
||||||
result.addf "<a href=\"$1#$2\"><span class=\"Identifier\">$3</span></a>",
|
result.addf "<a href=\"$1#$2\"><span class=\"Identifier\">$3</span></a>",
|
||||||
[rope changeFileExt(external, "html"), rope literal,
|
[changeFileExt(external, "html"), literal,
|
||||||
escLit]
|
escLit]
|
||||||
else:
|
else:
|
||||||
dispA(d.conf, result, "<span class=\"Identifier\">$1</span>",
|
dispA(d.conf, result, "<span class=\"Identifier\">$1</span>",
|
||||||
|
|
@ -570,7 +514,9 @@ type RunnableState = enum
|
||||||
rsRunnable
|
rsRunnable
|
||||||
rsDone
|
rsDone
|
||||||
|
|
||||||
proc getAllRunnableExamplesImpl(d: PDoc; n: PNode, dest: var Rope, state: RunnableState, topLevel: bool): RunnableState =
|
proc getAllRunnableExamplesImpl(d: PDoc; n: PNode, dest: var string,
|
||||||
|
state: RunnableState, topLevel: bool):
|
||||||
|
RunnableState =
|
||||||
##[
|
##[
|
||||||
Simple state machine to tell whether we render runnableExamples and doc comments.
|
Simple state machine to tell whether we render runnableExamples and doc comments.
|
||||||
This is to ensure that we can interleave runnableExamples and doc comments freely;
|
This is to ensure that we can interleave runnableExamples and doc comments freely;
|
||||||
|
|
@ -600,7 +546,7 @@ proc getAllRunnableExamplesImpl(d: PDoc; n: PNode, dest: var Rope, state: Runnab
|
||||||
var msg = "Example:"
|
var msg = "Example:"
|
||||||
if rdoccmd.len > 0: msg.add " cmd: " & rdoccmd
|
if rdoccmd.len > 0: msg.add " cmd: " & rdoccmd
|
||||||
dispA(d.conf, dest, "\n<p><strong class=\"examples_text\">$1</strong></p>\n",
|
dispA(d.conf, dest, "\n<p><strong class=\"examples_text\">$1</strong></p>\n",
|
||||||
"\n\\textbf{$1}\n", [msg.rope])
|
"\n\\textbf{$1}\n", [msg])
|
||||||
inc d.listingCounter
|
inc d.listingCounter
|
||||||
let id = $d.listingCounter
|
let id = $d.listingCounter
|
||||||
dest.add(d.config.getOrDefault"doc.listing_start" % [id, "langNim", ""])
|
dest.add(d.config.getOrDefault"doc.listing_start" % [id, "langNim", ""])
|
||||||
|
|
@ -646,12 +592,12 @@ proc getRoutineBody(n: PNode): PNode =
|
||||||
doAssert result.len == 2
|
doAssert result.len == 2
|
||||||
result = result[1]
|
result = result[1]
|
||||||
|
|
||||||
proc getAllRunnableExamples(d: PDoc, n: PNode, dest: var Rope) =
|
proc getAllRunnableExamples(d: PDoc, n: PNode, dest: var string) =
|
||||||
var n = n
|
var n = n
|
||||||
var state = rsStart
|
var state = rsStart
|
||||||
template fn(n2, topLevel) =
|
template fn(n2, topLevel) =
|
||||||
state = getAllRunnableExamplesImpl(d, n2, dest, state, topLevel)
|
state = getAllRunnableExamplesImpl(d, n2, dest, state, topLevel)
|
||||||
dest.add genComment(d, n).rope
|
dest.add genComment(d, n)
|
||||||
case n.kind
|
case n.kind
|
||||||
of routineDefs:
|
of routineDefs:
|
||||||
n = n.getRoutineBody
|
n = n.getRoutineBody
|
||||||
|
|
@ -806,20 +752,18 @@ proc docstringSummary(rstText: string): string =
|
||||||
result.delete(pos, last)
|
result.delete(pos, last)
|
||||||
result.add("…")
|
result.add("…")
|
||||||
|
|
||||||
proc genDeprecationMsg(d: PDoc, n: PNode): Rope =
|
proc genDeprecationMsg(d: PDoc, n: PNode): string =
|
||||||
## Given a nkPragma wDeprecated node output a well-formatted section
|
## Given a nkPragma wDeprecated node output a well-formatted section
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
|
|
||||||
case n.safeLen:
|
case n.safeLen:
|
||||||
of 0: # Deprecated w/o any message
|
of 0: # Deprecated w/o any message
|
||||||
result = ropeFormatNamedVars(d.conf,
|
result = getConfigVar(d.conf, "doc.deprecationmsg") % [
|
||||||
getConfigVar(d.conf, "doc.deprecationmsg"), ["label", "message"],
|
"label" , "Deprecated", "message", ""]
|
||||||
[~"Deprecated", nil])
|
|
||||||
of 2: # Deprecated w/ a message
|
of 2: # Deprecated w/ a message
|
||||||
if n[1].kind in {nkStrLit..nkTripleStrLit}:
|
if n[1].kind in {nkStrLit..nkTripleStrLit}:
|
||||||
result = ropeFormatNamedVars(d.conf,
|
result = getConfigVar(d.conf, "doc.deprecationmsg") % [
|
||||||
getConfigVar(d.conf, "doc.deprecationmsg"), ["label", "message"],
|
"label", "Deprecated:", "message", xmltree.escape(n[1].strVal)]
|
||||||
[~"Deprecated:", rope(xmltree.escape(n[1].strVal))])
|
|
||||||
else:
|
else:
|
||||||
doAssert false
|
doAssert false
|
||||||
|
|
||||||
|
|
@ -827,7 +771,7 @@ type DocFlags = enum
|
||||||
kDefault
|
kDefault
|
||||||
kForceExport
|
kForceExport
|
||||||
|
|
||||||
proc genSeeSrcRope(d: PDoc, path: string, line: int): Rope =
|
proc genSeeSrc(d: PDoc, path: string, line: int): string =
|
||||||
let docItemSeeSrc = getConfigVar(d.conf, "doc.item.seesrc")
|
let docItemSeeSrc = getConfigVar(d.conf, "doc.item.seesrc")
|
||||||
if docItemSeeSrc.len > 0:
|
if docItemSeeSrc.len > 0:
|
||||||
let path = relativeTo(AbsoluteFile path, AbsoluteDir getCurrentDir(), '/')
|
let path = relativeTo(AbsoluteFile path, AbsoluteDir getCurrentDir(), '/')
|
||||||
|
|
@ -843,20 +787,19 @@ proc genSeeSrcRope(d: PDoc, path: string, line: int): Rope =
|
||||||
else: "version-$1-$2" % [$NimMajor, $NimMinor]
|
else: "version-$1-$2" % [$NimMajor, $NimMinor]
|
||||||
let commit = getConfigVar(d.conf, "git.commit", defaultBranch)
|
let commit = getConfigVar(d.conf, "git.commit", defaultBranch)
|
||||||
let develBranch = getConfigVar(d.conf, "git.devel", "devel")
|
let develBranch = getConfigVar(d.conf, "git.devel", "devel")
|
||||||
dispA(d.conf, result, "$1", "", [ropeFormatNamedVars(d.conf, docItemSeeSrc,
|
dispA(d.conf, result, "$1", "", [docItemSeeSrc % [
|
||||||
["path", "line", "url", "commit", "devel"], [rope path.string,
|
"path", path.string, "line", $line, "url", gitUrl,
|
||||||
rope($line), rope gitUrl, rope commit, rope develBranch])])
|
"commit", commit, "devel", develBranch]])
|
||||||
|
|
||||||
proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
|
proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
|
||||||
if (docFlags != kForceExport) and not isVisible(d, nameNode): return
|
if (docFlags != kForceExport) and not isVisible(d, nameNode): return
|
||||||
let
|
let
|
||||||
name = getName(d, nameNode)
|
name = getName(d, nameNode)
|
||||||
nameRope = name.rope
|
|
||||||
var plainDocstring = getPlainDocstring(n) # call here before genRecComment!
|
var plainDocstring = getPlainDocstring(n) # call here before genRecComment!
|
||||||
var result: Rope = nil
|
var result = ""
|
||||||
var literal, plainName = ""
|
var literal, plainName = ""
|
||||||
var kind = tkEof
|
var kind = tkEof
|
||||||
var comm: Rope = nil
|
var comm = ""
|
||||||
if n.kind in routineDefs:
|
if n.kind in routineDefs:
|
||||||
getAllRunnableExamples(d, n, comm)
|
getAllRunnableExamples(d, n, comm)
|
||||||
else:
|
else:
|
||||||
|
|
@ -878,35 +821,33 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
|
||||||
|
|
||||||
inc(d.id)
|
inc(d.id)
|
||||||
let
|
let
|
||||||
plainNameRope = rope(xmltree.escape(plainName.strip))
|
plainNameEsc = xmltree.escape(plainName.strip)
|
||||||
cleanPlainSymbol = renderPlainSymbolName(nameNode)
|
cleanPlainSymbol = renderPlainSymbolName(nameNode)
|
||||||
complexSymbol = complexName(k, n, cleanPlainSymbol)
|
complexSymbol = complexName(k, n, cleanPlainSymbol)
|
||||||
plainSymbolRope = rope(cleanPlainSymbol)
|
plainSymbolEnc = encodeUrl(cleanPlainSymbol)
|
||||||
plainSymbolEncRope = rope(encodeUrl(cleanPlainSymbol))
|
|
||||||
itemIDRope = rope(d.id)
|
|
||||||
symbolOrId = d.newUniquePlainSymbol(complexSymbol)
|
symbolOrId = d.newUniquePlainSymbol(complexSymbol)
|
||||||
symbolOrIdRope = symbolOrId.rope
|
symbolOrIdEnc = encodeUrl(symbolOrId)
|
||||||
symbolOrIdEncRope = encodeUrl(symbolOrId).rope
|
deprecationMsg = genDeprecationMsg(d, pragmaNode)
|
||||||
deprecationMsgRope = genDeprecationMsg(d, pragmaNode)
|
|
||||||
|
|
||||||
nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments,
|
nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments,
|
||||||
renderDocComments, renderSyms}, symbolOrIdEncRope)
|
renderDocComments, renderSyms}, symbolOrIdEnc)
|
||||||
|
|
||||||
let seeSrcRope = genSeeSrcRope(d, toFullPath(d.conf, n.info), n.info.line.int)
|
let seeSrc = genSeeSrc(d, toFullPath(d.conf, n.info), n.info.line.int)
|
||||||
d.section[k].add(ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.item"),
|
|
||||||
["name", "header", "desc", "itemID", "header_plain", "itemSym",
|
d.section[k].add(getConfigVar(d.conf, "doc.item") %
|
||||||
"itemSymOrID", "itemSymEnc", "itemSymOrIDEnc", "seeSrc", "deprecationMsg"],
|
["name", name, "header", result, "desc", comm, "itemID", $d.id,
|
||||||
[nameRope, result, comm, itemIDRope, plainNameRope, plainSymbolRope,
|
"header_plain", plainNameEsc, "itemSym", cleanPlainSymbol,
|
||||||
symbolOrIdRope, plainSymbolEncRope, symbolOrIdEncRope, seeSrcRope,
|
"itemSymOrID", symbolOrId, "itemSymEnc", plainSymbolEnc,
|
||||||
deprecationMsgRope]))
|
"itemSymOrIDEnc", symbolOrIdEnc, "seeSrc", seeSrc,
|
||||||
|
"deprecationMsg", deprecationMsg])
|
||||||
|
|
||||||
let external = d.destFile.AbsoluteFile.relativeTo(d.conf.outDir, '/').changeFileExt(HtmlExt).string
|
let external = d.destFile.AbsoluteFile.relativeTo(d.conf.outDir, '/').changeFileExt(HtmlExt).string
|
||||||
|
|
||||||
var attype: Rope
|
var attype = ""
|
||||||
if k in routineKinds and nameNode.kind == nkSym:
|
if k in routineKinds and nameNode.kind == nkSym:
|
||||||
let att = attachToType(d, nameNode.sym)
|
let att = attachToType(d, nameNode.sym)
|
||||||
if att != nil:
|
if att != nil:
|
||||||
attype = rope esc(d.target, att.name.s)
|
attype = esc(d.target, att.name.s)
|
||||||
elif k == skType and nameNode.kind == nkSym and nameNode.sym.typ.kind in {tyEnum, tyBool}:
|
elif k == skType and nameNode.kind == nkSym and nameNode.sym.typ.kind in {tyEnum, tyBool}:
|
||||||
let etyp = nameNode.sym.typ
|
let etyp = nameNode.sym.typ
|
||||||
for e in etyp.n:
|
for e in etyp.n:
|
||||||
|
|
@ -916,14 +857,15 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) =
|
||||||
setIndexTerm(d[], external, symbolOrId, plain, nameNode.sym.name.s & '.' & plain,
|
setIndexTerm(d[], external, symbolOrId, plain, nameNode.sym.name.s & '.' & plain,
|
||||||
xmltree.escape(getPlainDocstring(e).docstringSummary))
|
xmltree.escape(getPlainDocstring(e).docstringSummary))
|
||||||
|
|
||||||
d.toc[k].add(ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.item.toc"),
|
d.toc[k].add(getConfigVar(d.conf, "doc.item.toc") % [
|
||||||
["name", "header_plain", "itemSymOrIDEnc"],
|
"name", name, "header_plain", plainNameEsc,
|
||||||
[nameRope, plainNameRope, symbolOrIdEncRope]))
|
"itemSymOrIDEnc", symbolOrIdEnc])
|
||||||
|
|
||||||
d.tocTable[k].mgetOrPut(cleanPlainSymbol, nil).add(ropeFormatNamedVars(
|
d.tocTable[k].mgetOrPut(cleanPlainSymbol, "").add(
|
||||||
d.conf, getConfigVar(d.conf, "doc.item.tocTable"),
|
getConfigVar(d.conf, "doc.item.tocTable") % [
|
||||||
["name", "header_plain", "itemSymOrID", "itemSymOrIDEnc"],
|
"name", name, "header_plain", plainNameEsc,
|
||||||
[nameRope, plainNameRope, rope(symbolOrId.replace(",", ",<wbr>")), symbolOrIdEncRope]))
|
"itemSymOrID", symbolOrId.replace(",", ",<wbr>"),
|
||||||
|
"itemSymOrIDEnc", symbolOrIdEnc])
|
||||||
|
|
||||||
# Ironically for types the complexSymbol is *cleaner* than the plainName
|
# Ironically for types the complexSymbol is *cleaner* than the plainName
|
||||||
# because it doesn't include object fields or documentation comments. So we
|
# because it doesn't include object fields or documentation comments. So we
|
||||||
|
|
@ -941,7 +883,7 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonNode =
|
||||||
if not isVisible(d, nameNode): return
|
if not isVisible(d, nameNode): return
|
||||||
var
|
var
|
||||||
name = getName(d, nameNode)
|
name = getName(d, nameNode)
|
||||||
comm = $genRecComment(d, n)
|
comm = genRecComment(d, n)
|
||||||
r: TSrcGen
|
r: TSrcGen
|
||||||
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
|
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
|
||||||
result = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
|
result = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
|
||||||
|
|
@ -997,35 +939,35 @@ proc traceDeps(d: PDoc, it: PNode) =
|
||||||
traceDeps(d, a)
|
traceDeps(d, a)
|
||||||
elif it.kind == nkSym and belongsToPackage(d.conf, it.sym):
|
elif it.kind == nkSym and belongsToPackage(d.conf, it.sym):
|
||||||
let external = externalDep(d, it.sym)
|
let external = externalDep(d, it.sym)
|
||||||
if d.section[k] != nil: d.section[k].add(", ")
|
if d.section[k] != "": d.section[k].add(", ")
|
||||||
dispA(d.conf, d.section[k],
|
dispA(d.conf, d.section[k],
|
||||||
"<a class=\"reference external\" href=\"$2\">$1</a>",
|
"<a class=\"reference external\" href=\"$2\">$1</a>",
|
||||||
"$1", [rope esc(d.target, external.prettyLink),
|
"$1", [esc(d.target, external.prettyLink),
|
||||||
rope changeFileExt(external, "html")])
|
changeFileExt(external, "html")])
|
||||||
|
|
||||||
proc exportSym(d: PDoc; s: PSym) =
|
proc exportSym(d: PDoc; s: PSym) =
|
||||||
const k = exportSection
|
const k = exportSection
|
||||||
if s.kind == skModule and belongsToPackage(d.conf, s):
|
if s.kind == skModule and belongsToPackage(d.conf, s):
|
||||||
let external = externalDep(d, s)
|
let external = externalDep(d, s)
|
||||||
if d.section[k] != nil: d.section[k].add(", ")
|
if d.section[k] != "": d.section[k].add(", ")
|
||||||
dispA(d.conf, d.section[k],
|
dispA(d.conf, d.section[k],
|
||||||
"<a class=\"reference external\" href=\"$2\">$1</a>",
|
"<a class=\"reference external\" href=\"$2\">$1</a>",
|
||||||
"$1", [rope esc(d.target, external.prettyLink),
|
"$1", [esc(d.target, external.prettyLink),
|
||||||
rope changeFileExt(external, "html")])
|
changeFileExt(external, "html")])
|
||||||
elif s.kind != skModule and s.owner != nil:
|
elif s.kind != skModule and s.owner != nil:
|
||||||
let module = originatingModule(s)
|
let module = originatingModule(s)
|
||||||
if belongsToPackage(d.conf, module):
|
if belongsToPackage(d.conf, module):
|
||||||
let
|
let
|
||||||
complexSymbol = complexName(s.kind, s.ast, s.name.s)
|
complexSymbol = complexName(s.kind, s.ast, s.name.s)
|
||||||
symbolOrIdRope = rope(d.newUniquePlainSymbol(complexSymbol))
|
symbolOrId = d.newUniquePlainSymbol(complexSymbol)
|
||||||
external = externalDep(d, module)
|
external = externalDep(d, module)
|
||||||
if d.section[k] != nil: d.section[k].add(", ")
|
if d.section[k] != "": d.section[k].add(", ")
|
||||||
# XXX proper anchor generation here
|
# XXX proper anchor generation here
|
||||||
dispA(d.conf, d.section[k],
|
dispA(d.conf, d.section[k],
|
||||||
"<a href=\"$2#$3\"><span class=\"Identifier\">$1</span></a>",
|
"<a href=\"$2#$3\"><span class=\"Identifier\">$1</span></a>",
|
||||||
"$1", [rope esc(d.target, s.name.s),
|
"$1", [esc(d.target, s.name.s),
|
||||||
rope changeFileExt(external, "html"),
|
changeFileExt(external, "html"),
|
||||||
symbolOrIdRope])
|
symbolOrId])
|
||||||
|
|
||||||
proc documentNewEffect(cache: IdentCache; n: PNode): PNode =
|
proc documentNewEffect(cache: IdentCache; n: PNode): PNode =
|
||||||
let s = n[namePos].sym
|
let s = n[namePos].sym
|
||||||
|
|
@ -1130,9 +1072,9 @@ proc generateDoc*(d: PDoc, n, orig: PNode, docFlags: DocFlags = kDefault) =
|
||||||
of nkExportExceptStmt: discard "transformed into nkExportStmt by semExportExcept"
|
of nkExportExceptStmt: discard "transformed into nkExportStmt by semExportExcept"
|
||||||
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n[0])
|
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n[0])
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
var comm: Rope = nil
|
var comm = ""
|
||||||
getAllRunnableExamples(d, n, comm)
|
getAllRunnableExamples(d, n, comm)
|
||||||
if comm != nil: d.modDesc.add(comm)
|
if comm != "": d.modDesc.add(comm)
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc add(d: PDoc; j: JsonNode) =
|
proc add(d: PDoc; j: JsonNode) =
|
||||||
|
|
@ -1179,7 +1121,7 @@ proc generateJson*(d: PDoc, n: PNode, includeComments: bool = true) =
|
||||||
proc genTagsItem(d: PDoc, n, nameNode: PNode, k: TSymKind): string =
|
proc genTagsItem(d: PDoc, n, nameNode: PNode, k: TSymKind): string =
|
||||||
result = getName(d, nameNode) & "\n"
|
result = getName(d, nameNode) & "\n"
|
||||||
|
|
||||||
proc generateTags*(d: PDoc, n: PNode, r: var Rope) =
|
proc generateTags*(d: PDoc, n: PNode, r: var string) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCommentStmt:
|
of nkCommentStmt:
|
||||||
if startsWith(n.comment, "##"):
|
if startsWith(n.comment, "##"):
|
||||||
|
|
@ -1224,41 +1166,41 @@ proc genSection(d: PDoc, kind: TSymKind, groupedToc = false) =
|
||||||
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Funcs",
|
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Funcs",
|
||||||
"Methods", "Iterators", "Converters", "Macros", "Templates", "Exports"
|
"Methods", "Iterators", "Converters", "Macros", "Templates", "Exports"
|
||||||
]
|
]
|
||||||
if d.section[kind] == nil: return
|
if d.section[kind] == "": return
|
||||||
var title = sectionNames[kind].rope
|
var title = sectionNames[kind]
|
||||||
d.section[kind] = ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.section"), [
|
d.section[kind] = getConfigVar(d.conf, "doc.section") % [
|
||||||
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
"sectionid", $ord(kind), "sectionTitle", title,
|
||||||
ord(kind).rope, title, rope(ord(kind) + 50), d.section[kind]])
|
"sectionTitleID", $(ord(kind) + 50), "content", d.section[kind]]
|
||||||
|
|
||||||
var tocSource = d.toc
|
var tocSource = d.toc
|
||||||
if groupedToc:
|
if groupedToc:
|
||||||
for p in d.tocTable[kind].keys:
|
for p in d.tocTable[kind].keys:
|
||||||
d.toc2[kind].add ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.section.toc2"), [
|
d.toc2[kind].add getConfigVar(d.conf, "doc.section.toc2") % [
|
||||||
"sectionid", "sectionTitle", "sectionTitleID", "content", "plainName"], [
|
"sectionid", $ord(kind), "sectionTitle", title,
|
||||||
ord(kind).rope, title, rope(ord(kind) + 50), d.tocTable[kind][p], p.rope])
|
"sectionTitleID", $(ord(kind) + 50),
|
||||||
|
"content", d.tocTable[kind][p], "plainName", p]
|
||||||
tocSource = d.toc2
|
tocSource = d.toc2
|
||||||
|
|
||||||
d.toc[kind] = ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.section.toc"), [
|
d.toc[kind] = getConfigVar(d.conf, "doc.section.toc") % [
|
||||||
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
"sectionid", $ord(kind), "sectionTitle", title,
|
||||||
ord(kind).rope, title, rope(ord(kind) + 50), tocSource[kind]])
|
"sectionTitleID", $(ord(kind) + 50), "content", tocSource[kind]]
|
||||||
|
|
||||||
proc relLink(outDir: AbsoluteDir, destFile: AbsoluteFile, linkto: RelativeFile): Rope =
|
proc relLink(outDir: AbsoluteDir, destFile: AbsoluteFile, linkto: RelativeFile): string =
|
||||||
rope($relativeTo(outDir / linkto, destFile.splitFile().dir, '/'))
|
$relativeTo(outDir / linkto, destFile.splitFile().dir, '/')
|
||||||
|
|
||||||
proc genOutFile(d: PDoc, groupedToc = false): Rope =
|
proc genOutFile(d: PDoc, groupedToc = false): string =
|
||||||
var
|
var
|
||||||
code, content: Rope
|
code, content: string
|
||||||
title = ""
|
title = ""
|
||||||
var j = 0
|
var j = 0
|
||||||
var tmp = ""
|
var toc = ""
|
||||||
renderTocEntries(d[], j, 1, tmp)
|
renderTocEntries(d[], j, 1, toc)
|
||||||
var toc = tmp.rope
|
|
||||||
for i in TSymKind:
|
for i in TSymKind:
|
||||||
var shouldSort = i in routineKinds and groupedToc
|
var shouldSort = i in routineKinds and groupedToc
|
||||||
genSection(d, i, shouldSort)
|
genSection(d, i, shouldSort)
|
||||||
toc.add(d.toc[i])
|
toc.add(d.toc[i])
|
||||||
if toc != nil:
|
if toc != "":
|
||||||
toc = ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.toc"), ["content"], [toc])
|
toc = getConfigVar(d.conf, "doc.toc") % ["content", toc]
|
||||||
for i in TSymKind: code.add(d.section[i])
|
for i in TSymKind: code.add(d.section[i])
|
||||||
|
|
||||||
# Extract the title. Non API modules generate an entry in the index table.
|
# Extract the title. Non API modules generate an entry in the index table.
|
||||||
|
|
@ -1269,10 +1211,10 @@ proc genOutFile(d: PDoc, groupedToc = false): Rope =
|
||||||
else:
|
else:
|
||||||
# Modules get an automatic title for the HTML, but no entry in the index.
|
# Modules get an automatic title for the HTML, but no entry in the index.
|
||||||
title = canonicalImport(d.conf, AbsoluteFile d.filename)
|
title = canonicalImport(d.conf, AbsoluteFile d.filename)
|
||||||
var subtitle = "".rope
|
var subtitle = ""
|
||||||
if d.meta[metaSubtitle] != "":
|
if d.meta[metaSubtitle] != "":
|
||||||
dispA(d.conf, subtitle, "<h2 class=\"subtitle\">$1</h2>",
|
dispA(d.conf, subtitle, "<h2 class=\"subtitle\">$1</h2>",
|
||||||
"\\\\\\vspace{0.5em}\\large $1", [d.meta[metaSubtitle].rope])
|
"\\\\\\vspace{0.5em}\\large $1", [d.meta[metaSubtitle]])
|
||||||
|
|
||||||
var groupsection = getConfigVar(d.conf, "doc.body_toc_groupsection")
|
var groupsection = getConfigVar(d.conf, "doc.body_toc_groupsection")
|
||||||
let bodyname = if d.hasToc and not d.isPureRst:
|
let bodyname = if d.hasToc and not d.isPureRst:
|
||||||
|
|
@ -1280,20 +1222,27 @@ proc genOutFile(d: PDoc, groupedToc = false): Rope =
|
||||||
"doc.body_toc_group"
|
"doc.body_toc_group"
|
||||||
elif d.hasToc: "doc.body_toc"
|
elif d.hasToc: "doc.body_toc"
|
||||||
else: "doc.body_no_toc"
|
else: "doc.body_no_toc"
|
||||||
let seeSrcRope = genSeeSrcRope(d, d.filename, 1)
|
let seeSrc = genSeeSrc(d, d.filename, 1)
|
||||||
content = ropeFormatNamedVars(d.conf, getConfigVar(d.conf, bodyname), ["title", "subtitle",
|
content = getConfigVar(d.conf, bodyname) % [
|
||||||
"tableofcontents", "moduledesc", "date", "time", "content", "deprecationMsg", "theindexhref", "body_toc_groupsection", "seeSrc"],
|
"title", title, "subtitle", subtitle,
|
||||||
[title.rope, subtitle, toc, d.modDesc, rope(getDateStr()),
|
"tableofcontents", toc, "moduledesc", d.modDesc, "date", getDateStr(),
|
||||||
rope(getClockStr()), code, d.modDeprecationMsg, relLink(d.conf.outDir, d.destFile.AbsoluteFile, theindexFname.RelativeFile), groupsection.rope, seeSrcRope])
|
"time", getClockStr(), "content", code,
|
||||||
|
"deprecationMsg", d.modDeprecationMsg,
|
||||||
|
"theindexhref", relLink(d.conf.outDir, d.destFile.AbsoluteFile,
|
||||||
|
theindexFname.RelativeFile),
|
||||||
|
"body_toc_groupsection", groupsection, "seeSrc", seeSrc]
|
||||||
if optCompileOnly notin d.conf.globalOptions:
|
if optCompileOnly notin d.conf.globalOptions:
|
||||||
# XXX what is this hack doing here? 'optCompileOnly' means raw output!?
|
# XXX what is this hack doing here? 'optCompileOnly' means raw output!?
|
||||||
code = ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.file"), [
|
code = getConfigVar(d.conf, "doc.file") % [
|
||||||
"nimdoccss", "dochackjs", "title", "subtitle", "tableofcontents", "moduledesc", "date", "time",
|
"nimdoccss", relLink(d.conf.outDir, d.destFile.AbsoluteFile,
|
||||||
"content", "author", "version", "analytics", "deprecationMsg"],
|
nimdocOutCss.RelativeFile),
|
||||||
[relLink(d.conf.outDir, d.destFile.AbsoluteFile, nimdocOutCss.RelativeFile),
|
"dochackjs", relLink(d.conf.outDir, d.destFile.AbsoluteFile,
|
||||||
relLink(d.conf.outDir, d.destFile.AbsoluteFile, docHackJsFname.RelativeFile),
|
docHackJsFname.RelativeFile),
|
||||||
title.rope, subtitle, toc, d.modDesc, rope(getDateStr()), rope(getClockStr()),
|
"title", title, "subtitle", subtitle, "tableofcontents", toc,
|
||||||
content, d.meta[metaAuthor].rope, d.meta[metaVersion].rope, d.analytics.rope, d.modDeprecationMsg])
|
"moduledesc", d.modDesc, "date", getDateStr(), "time", getClockStr(),
|
||||||
|
"content", content, "author", d.meta[metaAuthor],
|
||||||
|
"version", d.meta[metaVersion], "analytics", d.analytics,
|
||||||
|
"deprecationMsg", d.modDeprecationMsg]
|
||||||
else:
|
else:
|
||||||
code = content
|
code = content
|
||||||
result = code
|
result = code
|
||||||
|
|
@ -1316,17 +1265,19 @@ proc writeOutput*(d: PDoc, useWarning = false, groupedToc = false) =
|
||||||
runAllExamples(d)
|
runAllExamples(d)
|
||||||
var content = genOutFile(d, groupedToc)
|
var content = genOutFile(d, groupedToc)
|
||||||
if optStdout in d.conf.globalOptions:
|
if optStdout in d.conf.globalOptions:
|
||||||
writeRope(stdout, content)
|
write(stdout, content)
|
||||||
else:
|
else:
|
||||||
template outfile: untyped = d.destFile.AbsoluteFile
|
template outfile: untyped = d.destFile.AbsoluteFile
|
||||||
#let outfile = getOutFile2(d.conf, shortenDir(d.conf, filename), outExt)
|
#let outfile = getOutFile2(d.conf, shortenDir(d.conf, filename), outExt)
|
||||||
let dir = outfile.splitFile.dir
|
let dir = outfile.splitFile.dir
|
||||||
createDir(dir)
|
createDir(dir)
|
||||||
updateOutfile(d, outfile)
|
updateOutfile(d, outfile)
|
||||||
if not writeRope(content, outfile):
|
try:
|
||||||
|
writeFile(outfile, content)
|
||||||
|
except IOError:
|
||||||
rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile,
|
rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile,
|
||||||
outfile.string)
|
outfile.string)
|
||||||
elif not d.wroteSupportFiles: # nimdoc.css + dochack.js
|
if not d.wroteSupportFiles: # nimdoc.css + dochack.js
|
||||||
let nimr = $d.conf.getPrefixDir()
|
let nimr = $d.conf.getPrefixDir()
|
||||||
copyFile(docCss.interp(nimr = nimr), $d.conf.outDir / nimdocOutCss)
|
copyFile(docCss.interp(nimr = nimr), $d.conf.outDir / nimdocOutCss)
|
||||||
if optGenIndex in d.conf.globalOptions:
|
if optGenIndex in d.conf.globalOptions:
|
||||||
|
|
@ -1386,7 +1337,7 @@ proc commandRstAux(cache: IdentCache, conf: ConfigRef;
|
||||||
conf)
|
conf)
|
||||||
var modDesc = newStringOfCap(30_000)
|
var modDesc = newStringOfCap(30_000)
|
||||||
renderRstToOut(d[], rst, modDesc)
|
renderRstToOut(d[], rst, modDesc)
|
||||||
d.modDesc = rope(modDesc)
|
d.modDesc = modDesc
|
||||||
writeOutput(d)
|
writeOutput(d)
|
||||||
generateIndex(d)
|
generateIndex(d)
|
||||||
|
|
||||||
|
|
@ -1407,14 +1358,16 @@ proc commandJson*(cache: IdentCache, conf: ConfigRef) =
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
generateJson(d, ast)
|
generateJson(d, ast)
|
||||||
let json = d.jArray
|
let json = d.jArray
|
||||||
let content = rope(pretty(json))
|
let content = pretty(json)
|
||||||
|
|
||||||
if optStdout in d.conf.globalOptions:
|
if optStdout in d.conf.globalOptions:
|
||||||
writeRope(stdout, content)
|
write(stdout, content)
|
||||||
else:
|
else:
|
||||||
#echo getOutFile(gProjectFull, JsonExt)
|
#echo getOutFile(gProjectFull, JsonExt)
|
||||||
let filename = getOutFile(conf, RelativeFile conf.projectName, JsonExt)
|
let filename = getOutFile(conf, RelativeFile conf.projectName, JsonExt)
|
||||||
if not writeRope(content, filename):
|
try:
|
||||||
|
writeFile(filename, content)
|
||||||
|
except:
|
||||||
rawMessage(conf, errCannotOpenFile, filename.string)
|
rawMessage(conf, errCannotOpenFile, filename.string)
|
||||||
|
|
||||||
proc commandTags*(cache: IdentCache, conf: ConfigRef) =
|
proc commandTags*(cache: IdentCache, conf: ConfigRef) =
|
||||||
|
|
@ -1427,33 +1380,36 @@ proc commandTags*(cache: IdentCache, conf: ConfigRef) =
|
||||||
warnUser, "the ':test:' attribute is not supported by this backend")
|
warnUser, "the ':test:' attribute is not supported by this backend")
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
var
|
var
|
||||||
content: Rope
|
content = ""
|
||||||
generateTags(d, ast, content)
|
generateTags(d, ast, content)
|
||||||
|
|
||||||
if optStdout in d.conf.globalOptions:
|
if optStdout in d.conf.globalOptions:
|
||||||
writeRope(stdout, content)
|
write(stdout, content)
|
||||||
else:
|
else:
|
||||||
#echo getOutFile(gProjectFull, TagsExt)
|
#echo getOutFile(gProjectFull, TagsExt)
|
||||||
let filename = getOutFile(conf, RelativeFile conf.projectName, TagsExt)
|
let filename = getOutFile(conf, RelativeFile conf.projectName, TagsExt)
|
||||||
if not writeRope(content, filename):
|
try:
|
||||||
|
writeFile(filename, content)
|
||||||
|
except:
|
||||||
rawMessage(conf, errCannotOpenFile, filename.string)
|
rawMessage(conf, errCannotOpenFile, filename.string)
|
||||||
|
|
||||||
proc commandBuildIndex*(conf: ConfigRef, dir: string, outFile = RelativeFile"") =
|
proc commandBuildIndex*(conf: ConfigRef, dir: string, outFile = RelativeFile"") =
|
||||||
var content = mergeIndexes(dir).rope
|
var content = mergeIndexes(dir)
|
||||||
|
|
||||||
var outFile = outFile
|
var outFile = outFile
|
||||||
if outFile.isEmpty: outFile = theindexFname.RelativeFile.changeFileExt("")
|
if outFile.isEmpty: outFile = theindexFname.RelativeFile.changeFileExt("")
|
||||||
let filename = getOutFile(conf, outFile, HtmlExt)
|
let filename = getOutFile(conf, outFile, HtmlExt)
|
||||||
|
|
||||||
let code = ropeFormatNamedVars(conf, getConfigVar(conf, "doc.file"), [
|
let code = getConfigVar(conf, "doc.file") % [
|
||||||
"nimdoccss", "dochackjs",
|
"nimdoccss", relLink(conf.outDir, filename, nimdocOutCss.RelativeFile),
|
||||||
"title", "subtitle", "tableofcontents", "moduledesc", "date", "time",
|
"dochackjs", relLink(conf.outDir, filename, docHackJsFname.RelativeFile),
|
||||||
"content", "author", "version", "analytics"],
|
"title", "Index",
|
||||||
[relLink(conf.outDir, filename, nimdocOutCss.RelativeFile),
|
"subtitle", "", "tableofcontents", "", "moduledesc", "",
|
||||||
relLink(conf.outDir, filename, docHackJsFname.RelativeFile),
|
"date", getDateStr(), "time", getClockStr(),
|
||||||
rope"Index", rope"", nil, nil, rope(getDateStr()),
|
"content", content, "author", "", "version", "", "analytics", ""]
|
||||||
rope(getClockStr()), content, nil, nil, nil])
|
|
||||||
# no analytics because context is not available
|
# no analytics because context is not available
|
||||||
|
|
||||||
if not writeRope(code, filename):
|
try:
|
||||||
|
writeFile(filename, code)
|
||||||
|
except:
|
||||||
rawMessage(conf, errCannotOpenFile, filename.string)
|
rawMessage(conf, errCannotOpenFile, filename.string)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue