Added jsondoc compiler switch
Outputs top-level exported information in JSON
This commit is contained in:
parent
efc0d8557a
commit
aaf49947e9
3 changed files with 211 additions and 132 deletions
|
|
@ -11,10 +11,10 @@
|
||||||
# semantic checking is done for the code. Cross-references are generated
|
# semantic checking is done for the code. Cross-references are generated
|
||||||
# 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, ropes, idents,
|
||||||
wordrecg, syntaxes, renderer, lexer, rstast, rst, rstgen, times, highlite,
|
wordrecg, syntaxes, renderer, lexer, rstast, rst, rstgen, times, highlite,
|
||||||
importer, sempass2
|
importer, sempass2, json
|
||||||
|
|
||||||
type
|
type
|
||||||
TSections = array[TSymKind, PRope]
|
TSections = array[TSymKind, PRope]
|
||||||
|
|
@ -25,7 +25,7 @@ type
|
||||||
indexValFilename: string
|
indexValFilename: string
|
||||||
|
|
||||||
PDoc* = ref TDocumentor
|
PDoc* = ref TDocumentor
|
||||||
|
|
||||||
proc compilerMsgHandler(filename: string, line, col: int,
|
proc compilerMsgHandler(filename: string, line, col: int,
|
||||||
msgKind: rst.TMsgKind, arg: string) {.procvar.} =
|
msgKind: rst.TMsgKind, arg: string) {.procvar.} =
|
||||||
# translate msg kind:
|
# translate msg kind:
|
||||||
|
|
@ -41,69 +41,69 @@ proc compilerMsgHandler(filename: string, line, col: int,
|
||||||
of mwUnknownSubstitution: k = warnUnknownSubstitutionX
|
of mwUnknownSubstitution: k = warnUnknownSubstitutionX
|
||||||
of mwUnsupportedLanguage: k = warnLanguageXNotSupported
|
of mwUnsupportedLanguage: k = warnLanguageXNotSupported
|
||||||
GlobalError(newLineInfo(filename, line, col), k, arg)
|
GlobalError(newLineInfo(filename, line, col), k, arg)
|
||||||
|
|
||||||
proc parseRst(text, filename: string,
|
proc parseRst(text, filename: string,
|
||||||
line, column: int, hasToc: var bool,
|
line, column: int, hasToc: var bool,
|
||||||
rstOptions: TRstParseOptions): PRstNode =
|
rstOptions: TRstParseOptions): PRstNode =
|
||||||
result = rstParse(text, filename, line, column, hasToc, rstOptions,
|
result = rstParse(text, filename, line, column, hasToc, rstOptions,
|
||||||
options.FindFile, compilerMsgHandler)
|
options.FindFile, compilerMsgHandler)
|
||||||
|
|
||||||
proc newDocumentor*(filename: string, config: PStringTable): PDoc =
|
proc newDocumentor*(filename: string, config: PStringTable): PDoc =
|
||||||
new(result)
|
new(result)
|
||||||
initRstGenerator(result[], (if gCmd != cmdRst2Tex: outHtml else: outLatex),
|
initRstGenerator(result[], (if gCmd != cmdRst2Tex: outHtml else: outLatex),
|
||||||
options.gConfigVars, filename, {roSupportRawDirective},
|
options.gConfigVars, filename, {roSupportRawDirective},
|
||||||
options.FindFile, compilerMsgHandler)
|
options.FindFile, compilerMsgHandler)
|
||||||
result.id = 100
|
result.id = 100
|
||||||
|
|
||||||
proc dispA(dest: var PRope, xml, tex: string, args: openarray[PRope]) =
|
proc dispA(dest: var PRope, xml, tex: string, args: openarray[PRope]) =
|
||||||
if gCmd != cmdRst2Tex: appf(dest, xml, args)
|
if gCmd != cmdRst2Tex: appf(dest, xml, args)
|
||||||
else: appf(dest, tex, args)
|
else: appf(dest, tex, args)
|
||||||
|
|
||||||
proc getVarIdx(varnames: openarray[string], id: string): int =
|
proc getVarIdx(varnames: openarray[string], id: string): int =
|
||||||
for i in countup(0, high(varnames)):
|
for i in countup(0, high(varnames)):
|
||||||
if cmpIgnoreStyle(varnames[i], id) == 0:
|
if cmpIgnoreStyle(varnames[i], id) == 0:
|
||||||
return i
|
return i
|
||||||
result = -1
|
result = -1
|
||||||
|
|
||||||
proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
|
proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
|
||||||
varvalues: openarray[PRope]): PRope =
|
varvalues: openarray[PRope]): PRope =
|
||||||
var i = 0
|
var i = 0
|
||||||
var L = len(frmt)
|
var L = len(frmt)
|
||||||
result = nil
|
result = nil
|
||||||
var num = 0
|
var num = 0
|
||||||
while i < L:
|
while i < L:
|
||||||
if frmt[i] == '$':
|
if frmt[i] == '$':
|
||||||
inc(i) # skip '$'
|
inc(i) # skip '$'
|
||||||
case frmt[i]
|
case frmt[i]
|
||||||
of '#':
|
of '#':
|
||||||
app(result, varvalues[num])
|
app(result, varvalues[num])
|
||||||
inc(num)
|
inc(num)
|
||||||
inc(i)
|
inc(i)
|
||||||
of '$':
|
of '$':
|
||||||
app(result, "$")
|
app(result, "$")
|
||||||
inc(i)
|
inc(i)
|
||||||
of '0'..'9':
|
of '0'..'9':
|
||||||
var j = 0
|
var j = 0
|
||||||
while true:
|
while true:
|
||||||
j = (j * 10) + Ord(frmt[i]) - ord('0')
|
j = (j * 10) + Ord(frmt[i]) - ord('0')
|
||||||
inc(i)
|
inc(i)
|
||||||
if (i > L + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
|
if (i > L + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
|
||||||
if j > high(varvalues) + 1: internalError("ropeFormatNamedVars")
|
if j > high(varvalues) + 1: internalError("ropeFormatNamedVars")
|
||||||
num = j
|
num = j
|
||||||
app(result, varvalues[j - 1])
|
app(result, varvalues[j - 1])
|
||||||
of 'A'..'Z', 'a'..'z', '\x80'..'\xFF':
|
of 'A'..'Z', 'a'..'z', '\x80'..'\xFF':
|
||||||
var id = ""
|
var id = ""
|
||||||
while true:
|
while true:
|
||||||
add(id, frmt[i])
|
add(id, frmt[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
if not (frmt[i] in {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}): break
|
if not (frmt[i] in {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}): break
|
||||||
var idx = getVarIdx(varnames, id)
|
var idx = getVarIdx(varnames, id)
|
||||||
if idx >= 0: app(result, varvalues[idx])
|
if idx >= 0: app(result, varvalues[idx])
|
||||||
else: rawMessage(errUnkownSubstitionVar, id)
|
else: rawMessage(errUnkownSubstitionVar, id)
|
||||||
of '{':
|
of '{':
|
||||||
var id = ""
|
var id = ""
|
||||||
inc(i)
|
inc(i)
|
||||||
while frmt[i] != '}':
|
while frmt[i] != '}':
|
||||||
if frmt[i] == '\0': rawMessage(errTokenExpected, "}")
|
if frmt[i] == '\0': rawMessage(errTokenExpected, "}")
|
||||||
add(id, frmt[i])
|
add(id, frmt[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
@ -124,17 +124,17 @@ proc genComment(d: PDoc, n: PNode): string =
|
||||||
var dummyHasToc: bool
|
var dummyHasToc: bool
|
||||||
if n.comment != nil and startsWith(n.comment, "##"):
|
if n.comment != nil and startsWith(n.comment, "##"):
|
||||||
renderRstToOut(d[], parseRst(n.comment, toFilename(n.info),
|
renderRstToOut(d[], parseRst(n.comment, toFilename(n.info),
|
||||||
toLineNumber(n.info), toColumn(n.info),
|
toLineNumber(n.info), toColumn(n.info),
|
||||||
dummyHasToc, d.options + {roSkipPounds}), result)
|
dummyHasToc, d.options + {roSkipPounds}), result)
|
||||||
|
|
||||||
proc genRecComment(d: PDoc, n: PNode): PRope =
|
proc genRecComment(d: PDoc, n: PNode): PRope =
|
||||||
if n == nil: return nil
|
if n == nil: return nil
|
||||||
result = genComment(d, n).toRope
|
result = genComment(d, n).toRope
|
||||||
if result == nil:
|
if result == nil:
|
||||||
if n.kind notin {nkEmpty..nkNilLit}:
|
if n.kind notin {nkEmpty..nkNilLit}:
|
||||||
for i in countup(0, len(n)-1):
|
for i in countup(0, len(n)-1):
|
||||||
result = genRecComment(d, n.sons[i])
|
result = genRecComment(d, n.sons[i])
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
else:
|
else:
|
||||||
n.comment = nil
|
n.comment = nil
|
||||||
|
|
||||||
|
|
@ -158,10 +158,10 @@ proc extractDocComment*(s: PSym, d: PDoc = nil): string =
|
||||||
else:
|
else:
|
||||||
result = n.comment.substr(2).replace("\n##", "\n").strip
|
result = n.comment.substr(2).replace("\n##", "\n").strip
|
||||||
|
|
||||||
proc isVisible(n: PNode): bool =
|
proc isVisible(n: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
if n.kind == nkPostfix:
|
if n.kind == nkPostfix:
|
||||||
if n.len == 2 and n.sons[0].kind == nkIdent:
|
if n.len == 2 and n.sons[0].kind == nkIdent:
|
||||||
var v = n.sons[0].ident
|
var v = n.sons[0].ident
|
||||||
result = v.id == ord(wStar) or v.id == ord(wMinus)
|
result = v.id == ord(wStar) or v.id == ord(wMinus)
|
||||||
elif n.kind == nkSym:
|
elif n.kind == nkSym:
|
||||||
|
|
@ -171,36 +171,36 @@ proc isVisible(n: PNode): bool =
|
||||||
result = {sfExported, sfFromGeneric, sfForward}*n.sym.flags == {sfExported}
|
result = {sfExported, sfFromGeneric, sfForward}*n.sym.flags == {sfExported}
|
||||||
elif n.kind == nkPragmaExpr:
|
elif n.kind == nkPragmaExpr:
|
||||||
result = isVisible(n.sons[0])
|
result = isVisible(n.sons[0])
|
||||||
|
|
||||||
proc getName(d: PDoc, n: PNode, splitAfter = -1): string =
|
proc getName(d: PDoc, n: PNode, splitAfter = -1): string =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkPostfix: result = getName(d, n.sons[1], splitAfter)
|
of nkPostfix: result = getName(d, n.sons[1], splitAfter)
|
||||||
of nkPragmaExpr: result = getName(d, n.sons[0], splitAfter)
|
of nkPragmaExpr: result = getName(d, n.sons[0], splitAfter)
|
||||||
of nkSym: result = esc(d.target, n.sym.renderDefinitionName, splitAfter)
|
of nkSym: result = esc(d.target, n.sym.renderDefinitionName, splitAfter)
|
||||||
of nkIdent: result = esc(d.target, n.ident.s, splitAfter)
|
of nkIdent: result = esc(d.target, n.ident.s, splitAfter)
|
||||||
of nkAccQuoted:
|
of nkAccQuoted:
|
||||||
result = esc(d.target, "`")
|
result = esc(d.target, "`")
|
||||||
for i in 0.. <n.len: result.add(getName(d, n[i], splitAfter))
|
for i in 0.. <n.len: result.add(getName(d, n[i], splitAfter))
|
||||||
result.add esc(d.target, "`")
|
result.add esc(d.target, "`")
|
||||||
else:
|
else:
|
||||||
internalError(n.info, "getName()")
|
internalError(n.info, "getName()")
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
proc getRstName(n: PNode): PRstNode =
|
proc getRstName(n: PNode): PRstNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkPostfix: result = getRstName(n.sons[1])
|
of nkPostfix: result = getRstName(n.sons[1])
|
||||||
of nkPragmaExpr: result = getRstName(n.sons[0])
|
of nkPragmaExpr: result = getRstName(n.sons[0])
|
||||||
of nkSym: result = newRstNode(rnLeaf, n.sym.renderDefinitionName)
|
of nkSym: result = newRstNode(rnLeaf, n.sym.renderDefinitionName)
|
||||||
of nkIdent: result = newRstNode(rnLeaf, n.ident.s)
|
of nkIdent: result = newRstNode(rnLeaf, n.ident.s)
|
||||||
of nkAccQuoted:
|
of nkAccQuoted:
|
||||||
result = getRstName(n.sons[0])
|
result = getRstName(n.sons[0])
|
||||||
for i in 1 .. <n.len: result.text.add(getRstName(n[i]).text)
|
for i in 1 .. <n.len: result.text.add(getRstName(n[i]).text)
|
||||||
else:
|
else:
|
||||||
internalError(n.info, "getRstName()")
|
internalError(n.info, "getRstName()")
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
||||||
if not isVisible(nameNode): return
|
if not isVisible(nameNode): return
|
||||||
var name = toRope(getName(d, nameNode))
|
var name = toRope(getName(d, nameNode))
|
||||||
var result: PRope = nil
|
var result: PRope = nil
|
||||||
var literal = ""
|
var literal = ""
|
||||||
|
|
@ -208,73 +208,89 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
||||||
var comm = genRecComment(d, n) # call this here for the side-effect!
|
var comm = genRecComment(d, n) # call this here for the side-effect!
|
||||||
var r: TSrcGen
|
var r: TSrcGen
|
||||||
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
|
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
|
||||||
while true:
|
while true:
|
||||||
getNextTok(r, kind, literal)
|
getNextTok(r, kind, literal)
|
||||||
case kind
|
case kind
|
||||||
of tkEof:
|
of tkEof:
|
||||||
break
|
break
|
||||||
of tkComment:
|
of tkComment:
|
||||||
dispA(result, "<span class=\"Comment\">$1</span>", "\\spanComment{$1}",
|
dispA(result, "<span class=\"Comment\">$1</span>", "\\spanComment{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
of tokKeywordLow..tokKeywordHigh:
|
of tokKeywordLow..tokKeywordHigh:
|
||||||
dispA(result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}",
|
dispA(result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}",
|
||||||
[toRope(literal)])
|
[toRope(literal)])
|
||||||
of tkOpr:
|
of tkOpr:
|
||||||
dispA(result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}",
|
dispA(result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
of tkStrLit..tkTripleStrLit:
|
of tkStrLit..tkTripleStrLit:
|
||||||
dispA(result, "<span class=\"StringLit\">$1</span>",
|
dispA(result, "<span class=\"StringLit\">$1</span>",
|
||||||
"\\spanStringLit{$1}", [toRope(esc(d.target, literal))])
|
"\\spanStringLit{$1}", [toRope(esc(d.target, literal))])
|
||||||
of tkCharLit:
|
of tkCharLit:
|
||||||
dispA(result, "<span class=\"CharLit\">$1</span>", "\\spanCharLit{$1}",
|
dispA(result, "<span class=\"CharLit\">$1</span>", "\\spanCharLit{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
of tkIntLit..tkUInt64Lit:
|
of tkIntLit..tkUInt64Lit:
|
||||||
dispA(result, "<span class=\"DecNumber\">$1</span>",
|
dispA(result, "<span class=\"DecNumber\">$1</span>",
|
||||||
"\\spanDecNumber{$1}", [toRope(esc(d.target, literal))])
|
"\\spanDecNumber{$1}", [toRope(esc(d.target, literal))])
|
||||||
of tkFloatLit..tkFloat128Lit:
|
of tkFloatLit..tkFloat128Lit:
|
||||||
dispA(result, "<span class=\"FloatNumber\">$1</span>",
|
dispA(result, "<span class=\"FloatNumber\">$1</span>",
|
||||||
"\\spanFloatNumber{$1}", [toRope(esc(d.target, literal))])
|
"\\spanFloatNumber{$1}", [toRope(esc(d.target, literal))])
|
||||||
of tkSymbol:
|
of tkSymbol:
|
||||||
dispA(result, "<span class=\"Identifier\">$1</span>",
|
dispA(result, "<span class=\"Identifier\">$1</span>",
|
||||||
"\\spanIdentifier{$1}", [toRope(esc(d.target, literal))])
|
"\\spanIdentifier{$1}", [toRope(esc(d.target, literal))])
|
||||||
of tkSpaces, tkInvalid:
|
of tkSpaces, tkInvalid:
|
||||||
app(result, literal)
|
app(result, literal)
|
||||||
of tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi,
|
of tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi,
|
||||||
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi, tkParDotLe,
|
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi, tkParDotLe,
|
||||||
tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot,
|
tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot,
|
||||||
tkAccent, tkColonColon,
|
tkAccent, tkColonColon,
|
||||||
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr:
|
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr:
|
||||||
dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
||||||
[toRope(esc(d.target, literal))])
|
[toRope(esc(d.target, literal))])
|
||||||
inc(d.id)
|
inc(d.id)
|
||||||
app(d.section[k], ropeFormatNamedVars(getConfigVar("doc.item"),
|
app(d.section[k], ropeFormatNamedVars(getConfigVar("doc.item"),
|
||||||
["name", "header", "desc", "itemID"],
|
["name", "header", "desc", "itemID"],
|
||||||
[name, result, comm, toRope(d.id)]))
|
[name, result, comm, toRope(d.id)]))
|
||||||
app(d.toc[k], ropeFormatNamedVars(getConfigVar("doc.item.toc"),
|
app(d.toc[k], ropeFormatNamedVars(getConfigVar("doc.item.toc"),
|
||||||
["name", "header", "desc", "itemID"], [
|
["name", "header", "desc", "itemID"], [
|
||||||
toRope(getName(d, nameNode, d.splitAfter)), result, comm, toRope(d.id)]))
|
toRope(getName(d, nameNode, d.splitAfter)), result, comm, toRope(d.id)]))
|
||||||
setIndexTerm(d[], $d.id, getName(d, nameNode))
|
setIndexTerm(d[], $d.id, getName(d, nameNode))
|
||||||
|
|
||||||
proc checkForFalse(n: PNode): bool =
|
proc genJSONItem(d: PDoc, n, nameNode: PNode, k: TSymKind): PJsonNode =
|
||||||
|
if not isVisible(nameNode): return
|
||||||
|
var
|
||||||
|
name = getName(d, nameNode)
|
||||||
|
comm = genRecComment(d, n).ropeToStr()
|
||||||
|
r: TSrcGen
|
||||||
|
|
||||||
|
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
|
||||||
|
|
||||||
|
result = %{ "name": %name, "type": %($k) }
|
||||||
|
|
||||||
|
if comm != nil and comm != "":
|
||||||
|
result["description"] = %comm
|
||||||
|
if r.buf != nil:
|
||||||
|
result["code"] = %r.buf
|
||||||
|
|
||||||
|
proc checkForFalse(n: PNode): bool =
|
||||||
result = n.kind == nkIdent and IdentEq(n.ident, "false")
|
result = n.kind == nkIdent and IdentEq(n.ident, "false")
|
||||||
|
|
||||||
proc traceDeps(d: PDoc, n: PNode) =
|
proc traceDeps(d: PDoc, n: PNode) =
|
||||||
const k = skModule
|
const k = skModule
|
||||||
if d.section[k] != nil: app(d.section[k], ", ")
|
if d.section[k] != nil: app(d.section[k], ", ")
|
||||||
dispA(d.section[k],
|
dispA(d.section[k],
|
||||||
"<a class=\"reference external\" href=\"$1.html\">$1</a>",
|
"<a class=\"reference external\" href=\"$1.html\">$1</a>",
|
||||||
"$1", [toRope(getModuleName(n))])
|
"$1", [toRope(getModuleName(n))])
|
||||||
|
|
||||||
proc generateDoc*(d: PDoc, n: PNode) =
|
proc generateDoc*(d: PDoc, n: PNode) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCommentStmt: app(d.modDesc, genComment(d, n))
|
of nkCommentStmt: app(d.modDesc, genComment(d, n))
|
||||||
of nkProcDef:
|
of nkProcDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
genItem(d, n, n.sons[namePos], skProc)
|
genItem(d, n, n.sons[namePos], skProc)
|
||||||
of nkMethodDef:
|
of nkMethodDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
genItem(d, n, n.sons[namePos], skMethod)
|
genItem(d, n, n.sons[namePos], skMethod)
|
||||||
of nkIteratorDef:
|
of nkIteratorDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
genItem(d, n, n.sons[namePos], skIterator)
|
genItem(d, n, n.sons[namePos], skIterator)
|
||||||
of nkMacroDef: genItem(d, n, n.sons[namePos], skMacro)
|
of nkMacroDef: genItem(d, n, n.sons[namePos], skMacro)
|
||||||
|
|
@ -284,27 +300,69 @@ proc generateDoc*(d: PDoc, n: PNode) =
|
||||||
genItem(d, n, n.sons[namePos], skConverter)
|
genItem(d, n, n.sons[namePos], skConverter)
|
||||||
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
|
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if n.sons[i].kind != nkCommentStmt:
|
if n.sons[i].kind != nkCommentStmt:
|
||||||
# order is always 'type var let const':
|
# order is always 'type var let const':
|
||||||
genItem(d, n.sons[i], n.sons[i].sons[0],
|
genItem(d, n.sons[i], n.sons[i].sons[0],
|
||||||
succ(skType, ord(n.kind)-ord(nkTypeSection)))
|
succ(skType, ord(n.kind)-ord(nkTypeSection)))
|
||||||
of nkStmtList:
|
of nkStmtList:
|
||||||
for i in countup(0, sonsLen(n) - 1): generateDoc(d, n.sons[i])
|
for i in countup(0, sonsLen(n) - 1): generateDoc(d, n.sons[i])
|
||||||
of nkWhenStmt:
|
of nkWhenStmt:
|
||||||
# generate documentation for the first branch only:
|
# generate documentation for the first branch only:
|
||||||
if not checkForFalse(n.sons[0].sons[0]):
|
if not checkForFalse(n.sons[0].sons[0]):
|
||||||
generateDoc(d, lastSon(n.sons[0]))
|
generateDoc(d, lastSon(n.sons[0]))
|
||||||
of nkImportStmt:
|
of nkImportStmt:
|
||||||
for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i])
|
for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i])
|
||||||
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0])
|
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0])
|
||||||
else: nil
|
else: nil
|
||||||
|
|
||||||
proc genSection(d: PDoc, kind: TSymKind) =
|
proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode =
|
||||||
|
case n.kind
|
||||||
|
of nkCommentStmt:
|
||||||
|
if n.comment != nil and startsWith(n.comment, "##"):
|
||||||
|
let stripped = n.comment.substr(2).strip
|
||||||
|
result = %{ "comment": %stripped }
|
||||||
|
of nkProcDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skProc)
|
||||||
|
of nkMethodDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skMethod)
|
||||||
|
of nkIteratorDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skIterator)
|
||||||
|
of nkMacroDef:
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skMacro)
|
||||||
|
of nkTemplateDef:
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skTemplate)
|
||||||
|
of nkConverterDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
result = genJSONItem(d, n, n.sons[namePos], skConverter)
|
||||||
|
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
|
||||||
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
|
if n.sons[i].kind != nkCommentStmt:
|
||||||
|
# order is always 'type var let const':
|
||||||
|
result = genJSONItem(d, n.sons[i], n.sons[i].sons[0],
|
||||||
|
succ(skType, ord(n.kind)-ord(nkTypeSection)))
|
||||||
|
of nkStmtList:
|
||||||
|
var elem = jArray
|
||||||
|
if elem == nil: elem = newJArray()
|
||||||
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
|
var r = generateJson(d, n.sons[i], elem)
|
||||||
|
if r != nil:
|
||||||
|
elem.add(r)
|
||||||
|
if result == nil: result = elem
|
||||||
|
of nkWhenStmt:
|
||||||
|
# generate documentation for the first branch only:
|
||||||
|
if not checkForFalse(n.sons[0].sons[0]) and jArray != nil:
|
||||||
|
discard generateJson(d, lastSon(n.sons[0]), jArray)
|
||||||
|
else: nil
|
||||||
|
|
||||||
|
proc genSection(d: PDoc, kind: TSymKind) =
|
||||||
const sectionNames: array[skModule..skTemplate, string] = [
|
const sectionNames: array[skModule..skTemplate, string] = [
|
||||||
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Methods",
|
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Methods",
|
||||||
"Iterators", "Converters", "Macros", "Templates"
|
"Iterators", "Converters", "Macros", "Templates"
|
||||||
]
|
]
|
||||||
if d.section[kind] == nil: return
|
if d.section[kind] == nil: return
|
||||||
var title = sectionNames[kind].toRope
|
var title = sectionNames[kind].toRope
|
||||||
d.section[kind] = ropeFormatNamedVars(getConfigVar("doc.section"), [
|
d.section[kind] = ropeFormatNamedVars(getConfigVar("doc.section"), [
|
||||||
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
||||||
|
|
@ -313,7 +371,7 @@ proc genSection(d: PDoc, kind: TSymKind) =
|
||||||
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
|
||||||
ord(kind).toRope, title, toRope(ord(kind) + 50), d.toc[kind]])
|
ord(kind).toRope, title, toRope(ord(kind) + 50), d.toc[kind]])
|
||||||
|
|
||||||
proc genOutFile(d: PDoc): PRope =
|
proc genOutFile(d: PDoc): PRope =
|
||||||
var
|
var
|
||||||
code, content: PRope
|
code, content: PRope
|
||||||
title = ""
|
title = ""
|
||||||
|
|
@ -321,7 +379,7 @@ proc genOutFile(d: PDoc): PRope =
|
||||||
var tmp = ""
|
var tmp = ""
|
||||||
renderTocEntries(d[], j, 1, tmp)
|
renderTocEntries(d[], j, 1, tmp)
|
||||||
var toc = tmp.toRope
|
var toc = tmp.toRope
|
||||||
for i in countup(low(TSymKind), high(TSymKind)):
|
for i in countup(low(TSymKind), high(TSymKind)):
|
||||||
genSection(d, i)
|
genSection(d, i)
|
||||||
app(toc, d.toc[i])
|
app(toc, d.toc[i])
|
||||||
if toc != nil:
|
if toc != nil:
|
||||||
|
|
@ -329,30 +387,30 @@ proc genOutFile(d: PDoc): PRope =
|
||||||
for i in countup(low(TSymKind), high(TSymKind)): app(code, d.section[i])
|
for i in countup(low(TSymKind), high(TSymKind)): app(code, d.section[i])
|
||||||
if d.meta[metaTitle].len != 0: title = d.meta[metaTitle]
|
if d.meta[metaTitle].len != 0: title = d.meta[metaTitle]
|
||||||
else: title = "Module " & extractFilename(changeFileExt(d.filename, ""))
|
else: title = "Module " & extractFilename(changeFileExt(d.filename, ""))
|
||||||
|
|
||||||
let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc"
|
let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc"
|
||||||
content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
|
content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
|
||||||
"tableofcontents", "moduledesc", "date", "time", "content"],
|
"tableofcontents", "moduledesc", "date", "time", "content"],
|
||||||
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
|
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
|
||||||
toRope(getClockStr()), code])
|
toRope(getClockStr()), code])
|
||||||
if optCompileOnly notin gGlobalOptions:
|
if optCompileOnly notin gGlobalOptions:
|
||||||
# XXX what is this hack doing here? 'optCompileOnly' means raw output!?
|
# XXX what is this hack doing here? 'optCompileOnly' means raw output!?
|
||||||
code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
|
code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
|
||||||
"tableofcontents", "moduledesc", "date", "time",
|
"tableofcontents", "moduledesc", "date", "time",
|
||||||
"content", "author", "version"],
|
"content", "author", "version"],
|
||||||
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
|
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
|
||||||
toRope(getClockStr()), content, d.meta[metaAuthor].toRope,
|
toRope(getClockStr()), content, d.meta[metaAuthor].toRope,
|
||||||
d.meta[metaVersion].toRope])
|
d.meta[metaVersion].toRope])
|
||||||
else:
|
else:
|
||||||
code = content
|
code = content
|
||||||
result = code
|
result = code
|
||||||
|
|
||||||
proc generateIndex*(d: PDoc) =
|
proc generateIndex*(d: PDoc) =
|
||||||
if optGenIndex in gGlobalOptions:
|
if optGenIndex in gGlobalOptions:
|
||||||
writeIndexFile(d[], splitFile(options.outFile).dir /
|
writeIndexFile(d[], splitFile(options.outFile).dir /
|
||||||
splitFile(d.filename).name & indexExt)
|
splitFile(d.filename).name & indexExt)
|
||||||
|
|
||||||
proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
|
proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
|
||||||
var content = genOutFile(d)
|
var content = genOutFile(d)
|
||||||
if optStdout in gGlobalOptions:
|
if optStdout in gGlobalOptions:
|
||||||
writeRope(stdout, content)
|
writeRope(stdout, content)
|
||||||
|
|
@ -361,7 +419,7 @@ proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
|
||||||
|
|
||||||
proc CommandDoc*() =
|
proc CommandDoc*() =
|
||||||
var ast = parseFile(gProjectMainIdx)
|
var ast = parseFile(gProjectMainIdx)
|
||||||
if ast == nil: return
|
if ast == nil: return
|
||||||
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
generateDoc(d, ast)
|
generateDoc(d, ast)
|
||||||
|
|
@ -388,12 +446,26 @@ proc CommandRst2TeX*() =
|
||||||
splitter = "\\-"
|
splitter = "\\-"
|
||||||
CommandRstAux(gProjectFull, TexExt)
|
CommandRstAux(gProjectFull, TexExt)
|
||||||
|
|
||||||
|
proc CommandJSON*() =
|
||||||
|
var ast = parseFile(gProjectMainIdx)
|
||||||
|
if ast == nil: return
|
||||||
|
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||||
|
d.hasToc = true
|
||||||
|
var json = generateJson(d, ast)
|
||||||
|
var content = newRope(pretty(json))
|
||||||
|
|
||||||
|
if optStdout in gGlobalOptions:
|
||||||
|
writeRope(stdout, content)
|
||||||
|
else:
|
||||||
|
echo getOutFile(gProjectFull, JsonExt)
|
||||||
|
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
|
||||||
|
|
||||||
proc CommandBuildIndex*() =
|
proc CommandBuildIndex*() =
|
||||||
var content = mergeIndexes(gProjectFull).toRope
|
var content = mergeIndexes(gProjectFull).toRope
|
||||||
|
|
||||||
let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
|
let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
|
||||||
"tableofcontents", "moduledesc", "date", "time",
|
"tableofcontents", "moduledesc", "date", "time",
|
||||||
"content", "author", "version"],
|
"content", "author", "version"],
|
||||||
["Index".toRope, nil, nil, toRope(getDateStr()),
|
["Index".toRope, nil, nil, toRope(getDateStr()),
|
||||||
toRope(getClockStr()), content, nil, nil])
|
toRope(getClockStr()), content, nil, nil])
|
||||||
writeRope(code, getOutFile("theindex", HtmlExt))
|
writeRope(code, getOutFile("theindex", HtmlExt))
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
# implements the command dispatcher and several commands
|
# implements the command dispatcher and several commands
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
|
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
|
||||||
os, condsyms, rodread, rodwrite, times,
|
os, condsyms, rodread, rodwrite, times,
|
||||||
wordrecg, sem, semdata, idents, passes, docgen, extccomp,
|
wordrecg, sem, semdata, idents, passes, docgen, extccomp,
|
||||||
cgen, jsgen, json, nversion,
|
cgen, jsgen, json, nversion,
|
||||||
|
|
@ -98,7 +98,7 @@ proc CommandCompileToC =
|
||||||
# rodread.rodcompilerProcs
|
# rodread.rodcompilerProcs
|
||||||
# rodread.gTypeTable
|
# rodread.gTypeTable
|
||||||
# rodread.gMods
|
# rodread.gMods
|
||||||
|
|
||||||
# !! ropes.cache
|
# !! ropes.cache
|
||||||
# semthreads.computed?
|
# semthreads.computed?
|
||||||
#
|
#
|
||||||
|
|
@ -166,7 +166,7 @@ proc commandEval(exp: string) =
|
||||||
proc CommandPrettyOld =
|
proc CommandPrettyOld =
|
||||||
var projectFile = addFileExt(mainCommandArg(), NimExt)
|
var projectFile = addFileExt(mainCommandArg(), NimExt)
|
||||||
var module = parseFile(projectFile.fileInfoIdx)
|
var module = parseFile(projectFile.fileInfoIdx)
|
||||||
if module != nil:
|
if module != nil:
|
||||||
renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt))
|
renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt))
|
||||||
|
|
||||||
proc CommandPretty =
|
proc CommandPretty =
|
||||||
|
|
@ -175,24 +175,24 @@ proc CommandPretty =
|
||||||
registerPass(prettyPass)
|
registerPass(prettyPass)
|
||||||
compileProject()
|
compileProject()
|
||||||
pretty.overwriteFiles()
|
pretty.overwriteFiles()
|
||||||
|
|
||||||
proc CommandScan =
|
proc CommandScan =
|
||||||
var f = addFileExt(mainCommandArg(), nimExt)
|
var f = addFileExt(mainCommandArg(), nimExt)
|
||||||
var stream = LLStreamOpen(f, fmRead)
|
var stream = LLStreamOpen(f, fmRead)
|
||||||
if stream != nil:
|
if stream != nil:
|
||||||
var
|
var
|
||||||
L: TLexer
|
L: TLexer
|
||||||
tok: TToken
|
tok: TToken
|
||||||
initToken(tok)
|
initToken(tok)
|
||||||
openLexer(L, f, stream)
|
openLexer(L, f, stream)
|
||||||
while true:
|
while true:
|
||||||
rawGetTok(L, tok)
|
rawGetTok(L, tok)
|
||||||
PrintTok(tok)
|
PrintTok(tok)
|
||||||
if tok.tokType == tkEof: break
|
if tok.tokType == tkEof: break
|
||||||
CloseLexer(L)
|
CloseLexer(L)
|
||||||
else:
|
else:
|
||||||
rawMessage(errCannotOpenFile, f)
|
rawMessage(errCannotOpenFile, f)
|
||||||
|
|
||||||
proc CommandSuggest =
|
proc CommandSuggest =
|
||||||
if isServing:
|
if isServing:
|
||||||
# XXX: hacky work-around ahead
|
# XXX: hacky work-around ahead
|
||||||
|
|
@ -246,7 +246,7 @@ proc resetMemory =
|
||||||
for i in low(buckets)..high(buckets):
|
for i in low(buckets)..high(buckets):
|
||||||
buckets[i] = nil
|
buckets[i] = nil
|
||||||
idAnon = nil
|
idAnon = nil
|
||||||
|
|
||||||
# XXX: clean these global vars
|
# XXX: clean these global vars
|
||||||
# ccgstmts.gBreakpoints
|
# ccgstmts.gBreakpoints
|
||||||
# ccgthreadvars.nimtv
|
# ccgthreadvars.nimtv
|
||||||
|
|
@ -262,7 +262,7 @@ proc resetMemory =
|
||||||
# rodread.rodcompilerProcs
|
# rodread.rodcompilerProcs
|
||||||
# rodread.gTypeTable
|
# rodread.gTypeTable
|
||||||
# rodread.gMods
|
# rodread.gMods
|
||||||
|
|
||||||
# !! ropes.cache
|
# !! ropes.cache
|
||||||
# semthreads.computed?
|
# semthreads.computed?
|
||||||
#
|
#
|
||||||
|
|
@ -289,7 +289,7 @@ const
|
||||||
proc MainCommand* =
|
proc MainCommand* =
|
||||||
when SimiluateCaasMemReset:
|
when SimiluateCaasMemReset:
|
||||||
gGlobalOptions.incl(optCaasEnabled)
|
gGlobalOptions.incl(optCaasEnabled)
|
||||||
|
|
||||||
# In "nimrod serve" scenario, each command must reset the registered passes
|
# In "nimrod serve" scenario, each command must reset the registered passes
|
||||||
clearPasses()
|
clearPasses()
|
||||||
gLastCmdTime = epochTime()
|
gLastCmdTime = epochTime()
|
||||||
|
|
@ -301,7 +301,7 @@ proc MainCommand* =
|
||||||
passes.gIncludeFile = includeModule
|
passes.gIncludeFile = includeModule
|
||||||
passes.gImportModule = importModule
|
passes.gImportModule = importModule
|
||||||
case command.normalize
|
case command.normalize
|
||||||
of "c", "cc", "compile", "compiletoc":
|
of "c", "cc", "compile", "compiletoc":
|
||||||
# compile means compileToC currently
|
# compile means compileToC currently
|
||||||
gCmd = cmdCompileToC
|
gCmd = cmdCompileToC
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
|
|
@ -325,13 +325,13 @@ proc MainCommand* =
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
extccomp.setCC("tcc")
|
extccomp.setCC("tcc")
|
||||||
CommandCompileToC()
|
CommandCompileToC()
|
||||||
else:
|
else:
|
||||||
rawMessage(errInvalidCommandX, command)
|
rawMessage(errInvalidCommandX, command)
|
||||||
of "js", "compiletojs":
|
of "js", "compiletojs":
|
||||||
gCmd = cmdCompileToJS
|
gCmd = cmdCompileToJS
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandCompileToJS()
|
CommandCompileToJS()
|
||||||
of "compiletollvm":
|
of "compiletollvm":
|
||||||
gCmd = cmdCompileToLLVM
|
gCmd = cmdCompileToLLVM
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
when has_LLVM_Backend:
|
when has_LLVM_Backend:
|
||||||
|
|
@ -353,21 +353,27 @@ proc MainCommand* =
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
DefineSymbol("nimdoc")
|
DefineSymbol("nimdoc")
|
||||||
CommandDoc2()
|
CommandDoc2()
|
||||||
of "rst2html":
|
of "rst2html":
|
||||||
gCmd = cmdRst2html
|
gCmd = cmdRst2html
|
||||||
LoadConfigs(DocConfig)
|
LoadConfigs(DocConfig)
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandRst2Html()
|
CommandRst2Html()
|
||||||
of "rst2tex":
|
of "rst2tex":
|
||||||
gCmd = cmdRst2tex
|
gCmd = cmdRst2tex
|
||||||
LoadConfigs(DocTexConfig)
|
LoadConfigs(DocTexConfig)
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandRst2TeX()
|
CommandRst2TeX()
|
||||||
|
of "jsondoc":
|
||||||
|
gCmd = cmdDoc
|
||||||
|
LoadConfigs(DocConfig)
|
||||||
|
wantMainModule()
|
||||||
|
DefineSymbol("nimdoc")
|
||||||
|
CommandJSON()
|
||||||
of "buildindex":
|
of "buildindex":
|
||||||
gCmd = cmdDoc
|
gCmd = cmdDoc
|
||||||
LoadConfigs(DocConfig)
|
LoadConfigs(DocConfig)
|
||||||
CommandBuildIndex()
|
CommandBuildIndex()
|
||||||
of "gendepend":
|
of "gendepend":
|
||||||
gCmd = cmdGenDepend
|
gCmd = cmdGenDepend
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandGenDepend()
|
CommandGenDepend()
|
||||||
|
|
@ -400,16 +406,16 @@ proc MainCommand* =
|
||||||
gCmd = cmdCheck
|
gCmd = cmdCheck
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandCheck()
|
CommandCheck()
|
||||||
of "parse":
|
of "parse":
|
||||||
gCmd = cmdParse
|
gCmd = cmdParse
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
discard parseFile(gProjectMainIdx)
|
discard parseFile(gProjectMainIdx)
|
||||||
of "scan":
|
of "scan":
|
||||||
gCmd = cmdScan
|
gCmd = cmdScan
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
CommandScan()
|
CommandScan()
|
||||||
MsgWriteln("Beware: Indentation tokens depend on the parser\'s state!")
|
MsgWriteln("Beware: Indentation tokens depend on the parser\'s state!")
|
||||||
of "i":
|
of "i":
|
||||||
gCmd = cmdInteractive
|
gCmd = cmdInteractive
|
||||||
CommandInteractive()
|
CommandInteractive()
|
||||||
of "e":
|
of "e":
|
||||||
|
|
@ -427,11 +433,11 @@ proc MainCommand* =
|
||||||
of "serve":
|
of "serve":
|
||||||
isServing = true
|
isServing = true
|
||||||
gGlobalOptions.incl(optCaasEnabled)
|
gGlobalOptions.incl(optCaasEnabled)
|
||||||
msgs.gErrorMax = high(int) # do not stop after first error
|
msgs.gErrorMax = high(int) # do not stop after first error
|
||||||
serve(MainCommand)
|
serve(MainCommand)
|
||||||
else:
|
else:
|
||||||
rawMessage(errInvalidCommandX, command)
|
rawMessage(errInvalidCommandX, command)
|
||||||
|
|
||||||
if (msgs.gErrorCounter == 0 and
|
if (msgs.gErrorCounter == 0 and
|
||||||
gCmd notin {cmdInterpret, cmdRun, cmdDump} and
|
gCmd notin {cmdInterpret, cmdRun, cmdDump} and
|
||||||
gVerbosity > 0):
|
gVerbosity > 0):
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ const
|
||||||
NimExt* = "nim"
|
NimExt* = "nim"
|
||||||
RodExt* = "rod"
|
RodExt* = "rod"
|
||||||
HtmlExt* = "html"
|
HtmlExt* = "html"
|
||||||
|
JsonExt* = "json"
|
||||||
TexExt* = "tex"
|
TexExt* = "tex"
|
||||||
IniExt* = "ini"
|
IniExt* = "ini"
|
||||||
DefaultConfig* = "nimrod.cfg"
|
DefaultConfig* = "nimrod.cfg"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue