Skip to content

Commit 64fd62f

Browse files
committed
replace docgen by arraymancer inspired docgen
Note: `gen_docs` depends on the fact that the module ***has*** to be "developed", i.e. `nimble develop` ***must*** be run. Otherwise this cannot work. Thank nimble for that.
1 parent c8c47e8 commit 64fd62f

File tree

3 files changed

+185
-25
lines changed

3 files changed

+185
-25
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
run: |
4545
sudo apt-get install libcairo2 libcairo2-dev imagemagick \
4646
libgtk-3-dev webkit2gtk-driver libwebkitgtk-dev \
47-
libwebkit2gtk-4.0 libwebkit2gtk-4.0-dev
47+
libwebkit2gtk-4.0 libwebkit2gtk-4.0-dev pandoc
4848
4949
- name: Install dependencies (OSX)
5050
if: ${{matrix.target == 'macos'}}
@@ -85,13 +85,10 @@ jobs:
8585
shell: bash
8686
run: |
8787
cd ggplotnim
88-
branch=${{ github.ref }}
89-
branch=${branch##*/}
90-
nimble doc --project --outdir:docs \
91-
'--git.url:https://github.com/${{ github.repository }}' \
92-
'--git.commit:${{ github.sha }}' \
93-
"--git.devel:$branch" \
94-
src/ggplotnim.nim
88+
# **HAVE** to call `develop`, cuz we're getting screwed by
89+
# logic otherwise
90+
nimble develop -y
91+
nimble gen_docs
9592
# TODO: fix this, need to iterate over all files, do similar to arraymancer docs
9693
# Ignore failures for older Nim
9794
cp docs/{the,}index.html || true

docs/docs.nim

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import macros, strformat, strutils, sequtils, sets, tables, algorithm
2+
3+
from os import parentDir, getCurrentCompilerExe, DirSep, extractFilename, `/`, setCurrentDir
4+
5+
# NOTE:
6+
# for some time on devel 1.3.x `paramCount` and `paramStr` had to be imported
7+
# os, because they were removed for nimscript. This was reverted in:
8+
# https://github.com/nim-lang/Nim/pull/14658
9+
# For `nimdoc` we still have to import those from `os`!
10+
when defined(nimdoc):
11+
from os import getCurrentDir, paramCount, paramStr
12+
13+
#[
14+
This file is a slightly modified version of the same file of `nimterop`:
15+
https://github.com/nimterop/nimterop/blob/master/nimterop/docs.nim
16+
]#
17+
18+
19+
proc getNimRootDir(): string =
20+
#[
21+
hack, but works
22+
alternatively (but more complex), use (from a nim file, not nims otherwise
23+
you get Error: ambiguous call; both system.fileExists):
24+
import "$nim/testament/lib/stdtest/specialpaths.nim"
25+
nimRootDir
26+
]#
27+
fmt"{currentSourcePath}".parentDir.parentDir.parentDir
28+
29+
const
30+
DirSep = when defined(windows): '\\' else: '/'
31+
32+
proc execAction(cmd: string): string =
33+
var
34+
ccmd = ""
35+
ret = 0
36+
when defined(Windows):
37+
ccmd = "cmd /c " & cmd
38+
elif defined(posix):
39+
ccmd = cmd
40+
else:
41+
doAssert false
42+
43+
(result, ret) = gorgeEx(ccmd)
44+
doAssert ret == 0, "Command failed: " & $ret & "\ncmd: " & ccmd & "\nresult:\n" & result
45+
46+
template genRemove(name: untyped): untyped =
47+
proc `name`(s, toRemove: string): string =
48+
result = s
49+
result.`name`(toRemove)
50+
genRemove(removePrefix)
51+
genRemove(removeSuffix)
52+
53+
proc getFiles*(path: string): seq[string] =
54+
# Add files and dirs here, which should be skipped.
55+
#const excludeDirs = []
56+
#let ExcludeDirSet = toSet(excludeDirs)
57+
#if path.extractFilename in ExcludeDirSet: return
58+
# The files below are not valid by themselves, they are only included
59+
# from other files
60+
const excludeFiles = [ "formula.nim" ]
61+
let ExcludeFileSet = toSet(excludeFiles)
62+
63+
for file in listFiles(path):
64+
if file.endsWith(".nim") and file.extractFilename notin ExcludeFileSet:
65+
result.add file
66+
for dir in listDirs(path):
67+
result.add getFiles(dir)
68+
69+
proc buildDocs*(path: string, docPath: string,
70+
defaultFlags = "",
71+
masterBranch = "master",
72+
defines: openArray[string] = @[]) =
73+
## Generate docs for all nim files in `path` and output all HTML files to the
74+
## `docPath` in a flattened form (subdirectories are removed).
75+
##
76+
## If duplicate filenames are detected, they will be printed at the end.
77+
##
78+
## WARNING: not in use! `baseDir` is the project path by default and `files` and `path` are relative
79+
## to that directory. Set to "" if using absolute paths.
80+
##
81+
## `masterBranch` is the name of the default branch to which the docs should link
82+
## when clicking the `Source` button below a procedure etc.
83+
##
84+
## `defines` is a list of `-d:xxx` define flags (the `xxx` part) that should be passed
85+
## to `nim doc` so that `getHeader()` is invoked correctly.
86+
##
87+
## Use the `--publish` flag with nimble to publish docs contained in
88+
## `path` to Github in the `gh-pages` branch. This requires the ghp-import
89+
## package for Python: `pip install ghp-import`
90+
##
91+
## WARNING: `--publish` will destroy any existing content in this branch.
92+
##
93+
## NOTE: `buildDocs()` only works correctly on Windows with Nim 1.0+ since
94+
## https://github.com/nim-lang/Nim/pull/11814 is required.
95+
##
96+
##
97+
const gitUrl = "https://github.com/Vindaar/ggplotnim"
98+
## WARNING: this means `gen_docs` *only* works if you use `nimble develop` on
99+
## the repository. Nimble cannot deal with ****. This is frustrating. Thanks.
100+
let baseDir = execAction("nimble path ggplotnim").parentDir & $DirSep
101+
when defined(windows) and (NimMajor, NimMinor, NimPatch) < (1, 0, 0):
102+
echo "buildDocs() unsupported on Windows for Nim < 1.0 - requires PR #11814"
103+
else:
104+
let
105+
docPath = baseDir & docPath
106+
path = baseDir & path
107+
defStr = block:
108+
var defStr = " " & defaultFlags
109+
for def in defines:
110+
defStr &= " -d:" & def
111+
defStr
112+
nim = getCurrentCompilerExe()
113+
114+
# now we walk the whole `path` and build the documentation for each `.nim` file.
115+
# While doing that we flatten the directory structure for the generated HTML files.
116+
# `src/foo/bar/baz.nim` just becomes
117+
# `docPath/baz.html`.
118+
# This allows for all files to be in the `docPath` directory, which means each
119+
# file will be able to find the `dochack.js` file, which will be put into
120+
# the `docPath` directory, too (the inclusion of the `dochack.js` is done statically
121+
# via our generated nimdoc.cfg file and is fixed for each generated HTML).
122+
let files = getFiles(path)
123+
var idx = 0
124+
var fileSet = initHashSet[string]()
125+
var duplSet = initHashSet[string]()
126+
for file in files:
127+
let baseName = file.extractFilename()
128+
let relPath = file.removePrefix(path).removeSuffix(baseName)
129+
let prefix = relPath.strip(chars = {'/'}) # remove possible trailing `/`
130+
.split('/') # split path parts
131+
.join(".") # concat by `.` instead
132+
var outfile = baseName.replace(".nim", ".html")
133+
if outfile in fileSet:
134+
duplSet.incl outfile
135+
else:
136+
fileSet.incl outfile
137+
outfile = docPath / outfile
138+
echo "Processing: ", outfile, " [", idx, "/", files.len, "]"
139+
# NOTE: Changing the current working directory to the project path is required in order for
140+
# `git.commit:` to work! Otherwise we sit in `docs` and for some reason the relative path
141+
# will eat one piece of the resulting `source` links and thereby removing the actual branch
142+
# and we end up with a broken link!
143+
echo execAction(&"cd {baseDir} && {nim} doc {defStr} --git.url:{gitUrl} --git.commit:{masterBranch} --git.devel:{masterBranch} -o:{outfile} --index:on {file}")
144+
inc idx
145+
## now build the index
146+
echo execAction(&"{nim} buildIndex -o:{docPath}/theindex.html {docPath}")
147+
when declared(getNimRootDir):
148+
#[
149+
NOTE: running it locally doesn't work anymore on modern chromium browser,
150+
because they block "access from origin 'null' due to CORS policy".
151+
this enables doc search, works at least locally with:
152+
cd {docPath} && python -m SimpleHTTPServer 9009
153+
]#
154+
echo execAction(&"{nim} js -o:{docPath}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim")
155+
156+
# echo "Processed files: ", fileSet
157+
if duplSet.card > 0:
158+
echo "WARNING: Duplicate filenames detected: ", duplSet

ggplotnim.nimble

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,28 @@ proc removePrefix(f, prefix: string): string =
5555
result = f
5656
result.removePrefix(prefix)
5757

58-
# doc generation inspired by `strfmt`
59-
task docs, "Generate HTML docs using the Org file":
60-
# https://github.com/jgm/pandoc/issues/4749
61-
exec "pandoc " & orgFile & " -o " & rstFile
62-
var files: seq[string]
63-
template walk(path: string, outf: untyped): untyped {.dirty.} =
64-
for filePath in listFiles(path):
65-
if filePath.endsWith(".nim"):
66-
let outfile = outf
67-
exec &"nim doc {outfile} {filePath}"
68-
files.add outfile.removePrefix("-o:")
69-
walk("src", "-o:index.html")
70-
walk("src" / pkgName, &"-o:{filePath.basename}.html")
71-
mvFile rstFile, rstFileAuto
72-
for f in files:
73-
let fname = f.basename & ".html"
74-
mvFile fname, "docs/" & $fname
58+
template canImport(x: untyped): untyped =
59+
compiles:
60+
import x
61+
62+
when canImport(docs / docs):
63+
# can define the `gen_docs` task (docs already imported now)
64+
# this is to hack around weird nimble + nimscript behavior.
65+
# when overwriting an install nimble will try to parse the generated
66+
# nimscript file and for some reason then it won't be able to import
67+
# the module (even if it's put into `src/`).
68+
task gen_docs, "Generate ggplotnim documentation":
69+
# build the actual docs and the index
70+
exec "pandoc " & orgFile & " -o " & rstFile
71+
buildDocs(
72+
"src/",
73+
defaultFlags = "--hints:off --warnings:off"
74+
)
75+
# Process the rst
76+
for filePath in listFiles("docs/"):
77+
if filePath[^4..^1] == ".rst":
78+
let modName = filePath[5..^5]
79+
exec r"nim rst2html -o:docs/" & modName & ".html " & filePath
7580

7681
task recipes, "Generate and run all recipes":
7782
when not defined(windows):

0 commit comments

Comments
 (0)