fixes #8419 fixes #8420 ; workaround #6071 workaround nim-lang/website#98 (#8423)
add --git.devel option to override doc generated "edit" links; add --nimCompiler option to nimweb
This commit is contained in:
parent
f2ddd99539
commit
c0f78ec012
5 changed files with 70 additions and 52 deletions
|
|
@ -517,12 +517,11 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
|
||||||
path = path[cwd.len+1 .. ^1].replace('\\', '/')
|
path = path[cwd.len+1 .. ^1].replace('\\', '/')
|
||||||
let gitUrl = getConfigVar(d.conf, "git.url")
|
let gitUrl = getConfigVar(d.conf, "git.url")
|
||||||
if gitUrl.len > 0:
|
if gitUrl.len > 0:
|
||||||
var commit = getConfigVar(d.conf, "git.commit")
|
let commit = getConfigVar(d.conf, "git.commit", "master")
|
||||||
if commit.len == 0: commit = "master"
|
let develBranch = getConfigVar(d.conf, "git.devel", "devel")
|
||||||
dispA(d.conf, seeSrcRope, "$1", "", [ropeFormatNamedVars(d.conf, docItemSeeSrc,
|
dispA(d.conf, seeSrcRope, "$1", "", [ropeFormatNamedVars(d.conf, docItemSeeSrc,
|
||||||
["path", "line", "url", "commit"], [rope path,
|
["path", "line", "url", "commit", "devel"], [rope path,
|
||||||
rope($n.info.line), rope gitUrl,
|
rope($n.info.line), rope gitUrl, rope commit, rope develBranch])])
|
||||||
rope commit])])
|
|
||||||
|
|
||||||
add(d.section[k], ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.item"),
|
add(d.section[k], ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.item"),
|
||||||
["name", "header", "desc", "itemID", "header_plain", "itemSym",
|
["name", "header", "desc", "itemID", "header_plain", "itemSym",
|
||||||
|
|
|
||||||
|
|
@ -406,8 +406,8 @@ proc mainCommandArg*(conf: ConfigRef): string =
|
||||||
proc existsConfigVar*(conf: ConfigRef; key: string): bool =
|
proc existsConfigVar*(conf: ConfigRef; key: string): bool =
|
||||||
result = hasKey(conf.configVars, key)
|
result = hasKey(conf.configVars, key)
|
||||||
|
|
||||||
proc getConfigVar*(conf: ConfigRef; key: string): string =
|
proc getConfigVar*(conf: ConfigRef; key: string, default = ""): string =
|
||||||
result = conf.configVars.getOrDefault key
|
result = conf.configVars.getOrDefault(key, default)
|
||||||
|
|
||||||
proc setConfigVar*(conf: ConfigRef; key, val: string) =
|
proc setConfigVar*(conf: ConfigRef; key, val: string) =
|
||||||
conf.configVars[key] = val
|
conf.configVars[key] = val
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ doc.item.toc = """
|
||||||
# HTML rendered for doc.item's seeSrc variable. Note that this will render to
|
# HTML rendered for doc.item's seeSrc variable. Note that this will render to
|
||||||
# the empty string if you don't pass anything through --docSeeSrcURL. Available
|
# the empty string if you don't pass anything through --docSeeSrcURL. Available
|
||||||
# substitutaion variables here are:
|
# substitutaion variables here are:
|
||||||
|
# * $commit: branch/commit to use in source link.
|
||||||
|
# * $devel: branch to use in edit link.
|
||||||
# * $path: relative path to the file being processed.
|
# * $path: relative path to the file being processed.
|
||||||
# * $line: line of the item in the original source file.
|
# * $line: line of the item in the original source file.
|
||||||
# * $url: whatever you did pass through the --docSeeSrcUrl switch (which also
|
# * $url: whatever you did pass through the --docSeeSrcUrl switch (which also
|
||||||
|
|
@ -62,7 +64,7 @@ doc.item.toc = """
|
||||||
doc.item.seesrc = """ <a
|
doc.item.seesrc = """ <a
|
||||||
href="${url}/tree/${commit}/${path}#L${line}"
|
href="${url}/tree/${commit}/${path}#L${line}"
|
||||||
class="link-seesrc" target="_blank">Source</a>
|
class="link-seesrc" target="_blank">Source</a>
|
||||||
<a href="${url}/edit/devel/${path}#L${line}" class="link-seesrc" target="_blank" >Edit</a>
|
<a href="${url}/edit/${devel}/${path}#L${line}" class="link-seesrc" target="_blank" >Edit</a>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
doc.toc = """
|
doc.toc = """
|
||||||
|
|
|
||||||
1
koch.nim
1
koch.nim
|
|
@ -50,6 +50,7 @@ Boot options:
|
||||||
|
|
||||||
Commands for core developers:
|
Commands for core developers:
|
||||||
web [options] generates the website and the full documentation
|
web [options] generates the website and the full documentation
|
||||||
|
(see `nimweb.nim` for cmd line options)
|
||||||
website [options] generates only the website
|
website [options] generates only the website
|
||||||
csource -d:release builds the C sources for installation
|
csource -d:release builds the C sources for installation
|
||||||
pdf builds the PDF documentation
|
pdf builds the PDF documentation
|
||||||
|
|
|
||||||
104
tools/nimweb.nim
104
tools/nimweb.nim
|
|
@ -13,16 +13,18 @@ import
|
||||||
|
|
||||||
from xmltree import escape
|
from xmltree import escape
|
||||||
|
|
||||||
const gitRepo = "https://github.com/nim-lang/Nim"
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TKeyValPair = tuple[key, id, val: string]
|
TKeyValPair = tuple[key, id, val: string]
|
||||||
TConfigData = object of RootObj
|
TConfigData = object of RootObj
|
||||||
tabs, links: seq[TKeyValPair]
|
tabs, links: seq[TKeyValPair]
|
||||||
doc, srcdoc, srcdoc2, webdoc, pdf: seq[string]
|
doc, srcdoc, srcdoc2, webdoc, pdf: seq[string]
|
||||||
authors, projectName, projectTitle, logo, infile, outdir, ticker: string
|
authors, projectName, projectTitle, logo, infile, ticker: string
|
||||||
vars: StringTableRef
|
vars: StringTableRef
|
||||||
|
nimCompiler: string
|
||||||
nimArgs: string
|
nimArgs: string
|
||||||
|
gitURL: string
|
||||||
|
docHTMLOutput: string
|
||||||
|
webUploadOutput: string
|
||||||
quotations: Table[string, tuple[quote, author: string]]
|
quotations: Table[string, tuple[quote, author: string]]
|
||||||
numProcessors: int # Set by parallelBuild:n, only works for values > 0.
|
numProcessors: int # Set by parallelBuild:n, only works for values > 0.
|
||||||
gaId: string # google analytics ID, nil means analytics are disabled
|
gaId: string # google analytics ID, nil means analytics are disabled
|
||||||
|
|
@ -51,8 +53,10 @@ proc initConfigData(c: var TConfigData) =
|
||||||
c.webdoc = @[]
|
c.webdoc = @[]
|
||||||
c.pdf = @[]
|
c.pdf = @[]
|
||||||
c.infile = ""
|
c.infile = ""
|
||||||
c.outdir = ""
|
|
||||||
c.nimArgs = "--hint[Conf]:off --hint[Path]:off --hint[Processing]:off -d:boot "
|
c.nimArgs = "--hint[Conf]:off --hint[Path]:off --hint[Processing]:off -d:boot "
|
||||||
|
c.gitURL = "https://github.com/nim-lang/Nim"
|
||||||
|
c.docHTMLOutput = "doc/html"
|
||||||
|
c.webUploadOutput = "web/upload"
|
||||||
c.authors = ""
|
c.authors = ""
|
||||||
c.projectTitle = ""
|
c.projectTitle = ""
|
||||||
c.projectName = ""
|
c.projectName = ""
|
||||||
|
|
@ -79,14 +83,19 @@ const
|
||||||
Usage:
|
Usage:
|
||||||
nimweb [options] ini-file[.ini] [compile_options]
|
nimweb [options] ini-file[.ini] [compile_options]
|
||||||
Options:
|
Options:
|
||||||
-o, --output:dir set the output directory (default: same as ini-file)
|
|
||||||
--var:name=value set the value of a variable
|
|
||||||
-h, --help shows this help
|
-h, --help shows this help
|
||||||
-v, --version shows the version
|
-v, --version shows the version
|
||||||
|
-o, --output overrides output directory instead of default
|
||||||
|
web/upload and doc/html
|
||||||
|
--nimCompiler overrides nim compiler; default = bin/nim
|
||||||
|
--var:name=value set the value of a variable
|
||||||
--website only build the website, not the full documentation
|
--website only build the website, not the full documentation
|
||||||
--pdf build the PDF version of the documentation
|
--pdf build the PDF version of the documentation
|
||||||
--json2 build JSON of the documentation
|
--json2 build JSON of the documentation
|
||||||
--onlyDocs build only the documentation
|
--onlyDocs build only the documentation
|
||||||
|
--git.url override base url in generated doc links
|
||||||
|
--git.commit override commit/branch in generated doc links 'source'
|
||||||
|
--git.devel override devel branch in generated doc links 'edit'
|
||||||
Compile_options:
|
Compile_options:
|
||||||
will be passed to the Nim compiler
|
will be passed to the Nim compiler
|
||||||
"""
|
"""
|
||||||
|
|
@ -145,7 +154,11 @@ proc parseCmdLine(c: var TConfigData) =
|
||||||
of "version", "v":
|
of "version", "v":
|
||||||
stdout.write(version & "\n")
|
stdout.write(version & "\n")
|
||||||
quit(0)
|
quit(0)
|
||||||
of "o", "output": c.outdir = val
|
of "output", "o":
|
||||||
|
c.webUploadOutput = val
|
||||||
|
c.docHTMLOutput = val / "docs"
|
||||||
|
of "nimcompiler":
|
||||||
|
c.nimCompiler = val
|
||||||
of "parallelbuild":
|
of "parallelbuild":
|
||||||
try:
|
try:
|
||||||
let num = parseInt(val)
|
let num = parseInt(val)
|
||||||
|
|
@ -163,8 +176,14 @@ proc parseCmdLine(c: var TConfigData) =
|
||||||
of "googleanalytics":
|
of "googleanalytics":
|
||||||
c.gaId = val
|
c.gaId = val
|
||||||
c.nimArgs.add("--doc.googleAnalytics:" & val & " ")
|
c.nimArgs.add("--doc.googleAnalytics:" & val & " ")
|
||||||
|
of "git.url":
|
||||||
|
c.gitURL = val
|
||||||
|
of "git.commit":
|
||||||
|
c.nimArgs.add("--git.commit:" & val & " ")
|
||||||
|
of "git.devel":
|
||||||
|
c.nimArgs.add("--git.devel:" & val & " ")
|
||||||
else:
|
else:
|
||||||
echo("Invalid argument $1" % [key])
|
echo("Invalid argument '$1'" % [key])
|
||||||
quit(usage)
|
quit(usage)
|
||||||
of cmdEnd: break
|
of cmdEnd: break
|
||||||
if c.infile.len == 0: quit(usage)
|
if c.infile.len == 0: quit(usage)
|
||||||
|
|
@ -244,15 +263,14 @@ proc parseIniFile(c: var TConfigData) =
|
||||||
close(p)
|
close(p)
|
||||||
if c.projectName.len == 0:
|
if c.projectName.len == 0:
|
||||||
c.projectName = changeFileExt(extractFilename(c.infile), "")
|
c.projectName = changeFileExt(extractFilename(c.infile), "")
|
||||||
if c.outdir.len == 0:
|
|
||||||
c.outdir = splitFile(c.infile).dir
|
|
||||||
|
|
||||||
# ------------------- main ----------------------------------------------------
|
# ------------------- main ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
proc exe(f: string): string = return addFileExt(f, ExeExt)
|
proc exe(f: string): string = return addFileExt(f, ExeExt)
|
||||||
|
|
||||||
proc findNim(): string =
|
proc findNim(c: TConfigData): string =
|
||||||
|
if c.nimCompiler.len > 0: return c.nimCompiler
|
||||||
var nim = "nim".exe
|
var nim = "nim".exe
|
||||||
result = "bin" / nim
|
result = "bin" / nim
|
||||||
if existsFile(result): return
|
if existsFile(result): return
|
||||||
|
|
@ -289,9 +307,9 @@ proc buildDocSamples(c: var TConfigData, destPath: string) =
|
||||||
## it didn't make much sense to integrate into the existing generic
|
## it didn't make much sense to integrate into the existing generic
|
||||||
## documentation builders.
|
## documentation builders.
|
||||||
const src = "doc"/"docgen_sample.nim"
|
const src = "doc"/"docgen_sample.nim"
|
||||||
exec(findNim() & " doc $# -o:$# $#" %
|
exec(findNim(c) & " doc $# -o:$# $#" %
|
||||||
[c.nimArgs, destPath / "docgen_sample.html", src])
|
[c.nimArgs, destPath / "docgen_sample.html", src])
|
||||||
exec(findNim() & " doc2 $# -o:$# $#" %
|
exec(findNim(c) & " doc2 $# -o:$# $#" %
|
||||||
[c.nimArgs, destPath / "docgen_sample2.html", src])
|
[c.nimArgs, destPath / "docgen_sample2.html", src])
|
||||||
|
|
||||||
proc pathPart(d: string): string = splitFile(d).dir.replace('\\', '/')
|
proc pathPart(d: string): string = splitFile(d).dir.replace('\\', '/')
|
||||||
|
|
@ -302,23 +320,23 @@ proc buildDoc(c: var TConfigData, destPath: string) =
|
||||||
commands = newSeq[string](len(c.doc) + len(c.srcdoc) + len(c.srcdoc2))
|
commands = newSeq[string](len(c.doc) + len(c.srcdoc) + len(c.srcdoc2))
|
||||||
i = 0
|
i = 0
|
||||||
for d in items(c.doc):
|
for d in items(c.doc):
|
||||||
commands[i] = findNim() & " rst2html $# --git.url:$# -o:$# --index:on $#" %
|
commands[i] = findNim(c) & " rst2html $# --git.url:$# -o:$# --index:on $#" %
|
||||||
[c.nimArgs, gitRepo,
|
[c.nimArgs, c.gitURL,
|
||||||
destPath / changeFileExt(splitFile(d).name, "html"), d]
|
destPath / changeFileExt(splitFile(d).name, "html"), d]
|
||||||
i.inc
|
i.inc
|
||||||
for d in items(c.srcdoc):
|
for d in items(c.srcdoc):
|
||||||
commands[i] = findNim() & " doc0 $# --git.url:$# -o:$# --index:on $#" %
|
commands[i] = findNim(c) & " doc0 $# --git.url:$# -o:$# --index:on $#" %
|
||||||
[c.nimArgs, gitRepo,
|
[c.nimArgs, c.gitURL,
|
||||||
destPath / changeFileExt(splitFile(d).name, "html"), d]
|
destPath / changeFileExt(splitFile(d).name, "html"), d]
|
||||||
i.inc
|
i.inc
|
||||||
for d in items(c.srcdoc2):
|
for d in items(c.srcdoc2):
|
||||||
commands[i] = findNim() & " doc2 $# --git.url:$# -o:$# --index:on $#" %
|
commands[i] = findNim(c) & " doc2 $# --git.url:$# -o:$# --index:on $#" %
|
||||||
[c.nimArgs, gitRepo,
|
[c.nimArgs, c.gitURL,
|
||||||
destPath / changeFileExt(splitFile(d).name, "html"), d]
|
destPath / changeFileExt(splitFile(d).name, "html"), d]
|
||||||
i.inc
|
i.inc
|
||||||
|
|
||||||
mexec(commands, c.numProcessors)
|
mexec(commands, c.numProcessors)
|
||||||
exec(findNim() & " buildIndex -o:$1/theindex.html $1" % [destPath])
|
exec(findNim(c) & " buildIndex -o:$1/theindex.html $1" % [destPath])
|
||||||
|
|
||||||
proc buildPdfDoc(c: var TConfigData, destPath: string) =
|
proc buildPdfDoc(c: var TConfigData, destPath: string) =
|
||||||
createDir(destPath)
|
createDir(destPath)
|
||||||
|
|
@ -327,7 +345,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) =
|
||||||
else:
|
else:
|
||||||
const pdflatexcmd = "pdflatex -interaction=nonstopmode "
|
const pdflatexcmd = "pdflatex -interaction=nonstopmode "
|
||||||
for d in items(c.pdf):
|
for d in items(c.pdf):
|
||||||
exec(findNim() & " rst2tex $# $#" % [c.nimArgs, d])
|
exec(findNim(c) & " rst2tex $# $#" % [c.nimArgs, d])
|
||||||
# call LaTeX twice to get cross references right:
|
# call LaTeX twice to get cross references right:
|
||||||
exec(pdflatexcmd & changeFileExt(d, "tex"))
|
exec(pdflatexcmd & changeFileExt(d, "tex"))
|
||||||
exec(pdflatexcmd & changeFileExt(d, "tex"))
|
exec(pdflatexcmd & changeFileExt(d, "tex"))
|
||||||
|
|
@ -347,8 +365,8 @@ proc buildAddDoc(c: var TConfigData, destPath: string) =
|
||||||
# build additional documentation (without the index):
|
# build additional documentation (without the index):
|
||||||
var commands = newSeq[string](c.webdoc.len)
|
var commands = newSeq[string](c.webdoc.len)
|
||||||
for i, doc in pairs(c.webdoc):
|
for i, doc in pairs(c.webdoc):
|
||||||
commands[i] = findNim() & " doc2 $# --git.url:$# -o:$# $#" %
|
commands[i] = findNim(c) & " doc2 $# --git.url:$# -o:$# $#" %
|
||||||
[c.nimArgs, gitRepo,
|
[c.nimArgs, c.gitURL,
|
||||||
destPath / changeFileExt(splitFile(doc).name, "html"), doc]
|
destPath / changeFileExt(splitFile(doc).name, "html"), doc]
|
||||||
mexec(commands, c.numProcessors)
|
mexec(commands, c.numProcessors)
|
||||||
|
|
||||||
|
|
@ -431,9 +449,9 @@ proc buildNewsRss(c: var TConfigData, destPath: string) =
|
||||||
|
|
||||||
generateRss(destFilename, parseNewsTitles(srcFilename))
|
generateRss(destFilename, parseNewsTitles(srcFilename))
|
||||||
|
|
||||||
proc buildJS(destPath: string) =
|
proc buildJS(c: TConfigData) =
|
||||||
exec(findNim() & " js -d:release --out:$1 web/nimblepkglist.nim" %
|
exec(findNim(c) & " js -d:release --out:$1 web/nimblepkglist.nim" %
|
||||||
[destPath / "nimblepkglist.js"])
|
[c.webUploadOutput / "nimblepkglist.js"])
|
||||||
|
|
||||||
proc readSponsors(sponsorsFile: string): seq[Sponsor] =
|
proc readSponsors(sponsorsFile: string): seq[Sponsor] =
|
||||||
result = @[]
|
result = @[]
|
||||||
|
|
@ -464,7 +482,7 @@ const
|
||||||
cmdRst2Html = " rst2html --compileonly $1 -o:web/$2.temp web/$2.rst"
|
cmdRst2Html = " rst2html --compileonly $1 -o:web/$2.temp web/$2.rst"
|
||||||
|
|
||||||
proc buildPage(c: var TConfigData, file, title, rss: string, assetDir = "") =
|
proc buildPage(c: var TConfigData, file, title, rss: string, assetDir = "") =
|
||||||
exec(findNim() & cmdRst2Html % [c.nimArgs, file])
|
exec(findNim(c) & cmdRst2Html % [c.nimArgs, file])
|
||||||
var temp = "web" / changeFileExt(file, "temp")
|
var temp = "web" / changeFileExt(file, "temp")
|
||||||
var content: string
|
var content: string
|
||||||
try:
|
try:
|
||||||
|
|
@ -472,7 +490,7 @@ proc buildPage(c: var TConfigData, file, title, rss: string, assetDir = "") =
|
||||||
except IOError:
|
except IOError:
|
||||||
quit("[Error] cannot open: " & temp)
|
quit("[Error] cannot open: " & temp)
|
||||||
var f: File
|
var f: File
|
||||||
var outfile = "web/upload/$#.html" % file
|
var outfile = c.webUploadOutput / "$#.html" % file
|
||||||
if not existsDir(outfile.splitFile.dir):
|
if not existsDir(outfile.splitFile.dir):
|
||||||
createDir(outfile.splitFile.dir)
|
createDir(outfile.splitFile.dir)
|
||||||
if open(f, outfile, fmWrite):
|
if open(f, outfile, fmWrite):
|
||||||
|
|
@ -502,27 +520,25 @@ proc buildWebsite(c: var TConfigData) =
|
||||||
let rss = if file in ["news", "index"]: extractFilename(rssUrl) else: ""
|
let rss = if file in ["news", "index"]: extractFilename(rssUrl) else: ""
|
||||||
if '.' in file: continue
|
if '.' in file: continue
|
||||||
buildPage(c, file, if file == "question": "FAQ" else: file, rss)
|
buildPage(c, file, if file == "question": "FAQ" else: file, rss)
|
||||||
copyDir("web/assets", "web/upload/assets")
|
copyDir("web/assets", c.webUploadOutput / "assets")
|
||||||
buildNewsRss(c, "web/upload")
|
buildNewsRss(c, c.webUploadOutput)
|
||||||
buildSponsors(c, "web/upload")
|
buildSponsors(c, c.webUploadOutput)
|
||||||
buildNews(c, "web/news", "web/upload/news")
|
buildNews(c, "web/news", c.webUploadOutput / "news")
|
||||||
|
|
||||||
|
proc onlyDocs(c: var TConfigData) =
|
||||||
|
createDir(c.docHTMLOutput)
|
||||||
|
buildDocSamples(c, c.docHTMLOutput)
|
||||||
|
buildDoc(c, c.docHTMLOutput)
|
||||||
|
|
||||||
proc main(c: var TConfigData) =
|
proc main(c: var TConfigData) =
|
||||||
buildWebsite(c)
|
buildWebsite(c)
|
||||||
buildJS("web/upload")
|
buildJS(c)
|
||||||
const docup = "web/upload/" & NimVersion
|
let docup = c.webUploadOutput / NimVersion
|
||||||
createDir(docup)
|
createDir(docup)
|
||||||
buildAddDoc(c, docup)
|
buildAddDoc(c, docup)
|
||||||
buildDocSamples(c, docup)
|
buildDocSamples(c, docup)
|
||||||
buildDoc(c, docup)
|
buildDoc(c, docup)
|
||||||
createDir("doc/html")
|
onlyDocs(c)
|
||||||
buildDocSamples(c, "doc/html")
|
|
||||||
buildDoc(c, "doc/html")
|
|
||||||
|
|
||||||
proc onlyDocs(c: var TConfigData) =
|
|
||||||
createDir("doc/html")
|
|
||||||
buildDocSamples(c, "doc/html")
|
|
||||||
buildDoc(c, "doc/html")
|
|
||||||
|
|
||||||
proc json2(c: var TConfigData) =
|
proc json2(c: var TConfigData) =
|
||||||
const destPath = "web/json2"
|
const destPath = "web/json2"
|
||||||
|
|
@ -530,8 +546,8 @@ proc json2(c: var TConfigData) =
|
||||||
var i = 0
|
var i = 0
|
||||||
for d in items(c.srcdoc2):
|
for d in items(c.srcdoc2):
|
||||||
createDir(destPath / splitFile(d).dir)
|
createDir(destPath / splitFile(d).dir)
|
||||||
commands[i] = findNim() & " jsondoc2 $# --git.url:$# -o:$# --index:on $#" %
|
commands[i] = findNim(c) & " jsondoc2 $# --git.url:$# -o:$# --index:on $#" %
|
||||||
[c.nimArgs, gitRepo,
|
[c.nimArgs, c.gitURL,
|
||||||
destPath / changeFileExt(d, "json"), d]
|
destPath / changeFileExt(d, "json"), d]
|
||||||
i.inc
|
i.inc
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue