some progress on documentation building

This commit is contained in:
Araq 2014-09-17 10:04:36 +02:00
commit 17ce01c3e1
6 changed files with 119 additions and 109 deletions

View file

@ -40,7 +40,7 @@ Possible Commands:
boot [options] bootstraps with given command line options boot [options] bootstraps with given command line options
install [dir] installs to given directory install [dir] installs to given directory
clean cleans Nimrod project; removes generated files clean cleans Nimrod project; removes generated files
web generates the website web [options] generates the website
csource [options] builds the C sources for installation csource [options] builds the C sources for installation
zip builds the installation ZIP package zip builds the installation ZIP package
inno [options] builds the Inno Setup installer (for Windows) inno [options] builds the Inno Setup installer (for Windows)
@ -105,8 +105,8 @@ proc install(args: string) =
exec("sh ./install.sh $#" % args) exec("sh ./install.sh $#" % args)
proc web(args: string) = proc web(args: string) =
exec("$# cc -r tools/nimweb.nim web/nim --putenv:nimversion=$#" % exec("$# cc -r tools/nimweb.nim $# web/nim --putenv:nimversion=$#" %
[findNim(), NimVersion]) [findNim(), args, NimVersion])
# -------------- boot --------------------------------------------------------- # -------------- boot ---------------------------------------------------------
@ -298,7 +298,7 @@ proc temp(args: string) =
if args.len > 0: exec(finalDest & " " & args) if args.len > 0: exec(finalDest & " " & args)
proc showHelp() = proc showHelp() =
quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)), quit(HelpText % [NimVersion & repeatChar(44-len(NimVersion)),
CompileDate, CompileTime]) CompileDate, CompileTime])
var op = initOptParser() var op = initOptParser()
@ -323,4 +323,3 @@ of cmdArgument:
of "temp": temp(op.cmdLineRest) of "temp": temp(op.cmdLineRest)
else: showHelp() else: showHelp()
of cmdEnd: showHelp() of cmdEnd: showHelp()

View file

@ -15,24 +15,24 @@
import openssl, strutils, os import openssl, strutils, os
type type
TSecureSocket* {.final.} = object TSecureSocket* = object
ssl: PSSL ssl: SslPtr
bio: PBIO bio: BIO
proc connect*(sock: var TSecureSocket, address: string, proc connect*(sock: var TSecureSocket, address: string,
port: int): Int = port: int): int =
## Connects to the specified `address` on the specified `port`. ## Connects to the specified `address` on the specified `port`.
## Returns the result of the certificate validation. ## Returns the result of the certificate validation.
SslLoadErrorStrings() SslLoadErrorStrings()
ERR_load_BIO_strings() ERR_load_BIO_strings()
if SSL_library_init() != 1: if SSL_library_init() != 1:
OSError() raiseOSError(osLastError())
var ctx = SSL_CTX_new(SSLv23_client_method()) var ctx = SSL_CTX_new(SSLv23_client_method())
if ctx == nil: if ctx == nil:
ERR_print_errors_fp(stderr) ERR_print_errors_fp(stderr)
OSError() raiseOSError(osLastError())
#if SSL_CTX_load_verify_locations(ctx, #if SSL_CTX_load_verify_locations(ctx,
# "/tmp/openssl-0.9.8e/certs/vsign1.pem", NIL) == 0: # "/tmp/openssl-0.9.8e/certs/vsign1.pem", NIL) == 0:
@ -41,14 +41,14 @@ proc connect*(sock: var TSecureSocket, address: string,
sock.bio = BIO_new_ssl_connect(ctx) sock.bio = BIO_new_ssl_connect(ctx)
if BIO_get_ssl(sock.bio, addr(sock.ssl)) == 0: if BIO_get_ssl(sock.bio, addr(sock.ssl)) == 0:
OSError() raiseOSError(osLastError())
if BIO_set_conn_hostname(sock.bio, address & ":" & $port) != 1: if BIO_set_conn_hostname(sock.bio, address & ":" & $port) != 1:
OSError() raiseOSError(osLastError())
if BIO_do_connect(sock.bio) <= 0: if BIO_do_connect(sock.bio) <= 0:
ERR_print_errors_fp(stderr) ERR_print_errors_fp(stderr)
OSError() raiseOSError(osLastError())
result = SSL_get_verify_result(sock.ssl) result = SSL_get_verify_result(sock.ssl)
@ -57,30 +57,30 @@ proc recvLine*(sock: TSecureSocket, line: var TaintedString): bool =
## Returns false when no data is available to be read. ## Returns false when no data is available to be read.
## `Line` must be initialized and not nil! ## `Line` must be initialized and not nil!
setLen(line.string, 0) setLen(line.string, 0)
while True: while true:
var c: array[0..0, char] var c: array[0..0, char]
var n = BIO_read(sock.bio, c, c.len.cint) var n = BIO_read(sock.bio, c, c.len.cint)
if n <= 0: return False if n <= 0: return false
if c[0] == '\r': if c[0] == '\r':
n = BIO_read(sock.bio, c, c.len.cint) n = BIO_read(sock.bio, c, c.len.cint)
if n > 0 and c[0] == '\L': if n > 0 and c[0] == '\L':
return True return true
elif n <= 0: elif n <= 0:
return False return false
elif c[0] == '\L': return True elif c[0] == '\L': return true
add(line.string, c) add(line.string, c)
proc send*(sock: TSecureSocket, data: string) = proc send*(sock: TSecureSocket, data: string) =
## Writes `data` to the socket. ## Writes `data` to the socket.
if BIO_write(sock.bio, data, data.len.cint) <= 0: if BIO_write(sock.bio, data, data.len.cint) <= 0:
OSError() raiseOSError(osLastError())
proc close*(sock: TSecureSocket) = proc close*(sock: TSecureSocket) =
## Closes the socket ## Closes the socket
if BIO_free(sock.bio) <= 0: if BIO_free(sock.bio) <= 0:
ERR_print_errors_fp(stderr) ERR_print_errors_fp(stderr)
OSError() raiseOSError(osLastError())
when isMainModule: when isMainModule:
var s: TSecureSocket var s: TSecureSocket

View file

@ -480,7 +480,7 @@ proc hexStr (buf:cstring): string =
for i in 0 .. <16: for i in 0 .. <16:
result.add toHex(buf[i].ord, 2).toLower result.add toHex(buf[i].ord, 2).toLower
proc md5_File* (file: string): string {.raises:[EIO,Ebase].} = proc md5_File* (file: string): string {.raises: [IOError,Exception].} =
## Generate MD5 hash for a file. Result is a 32 character ## Generate MD5 hash for a file. Result is a 32 character
# hex string with lowercase characters (like the output # hex string with lowercase characters (like the output
# of `md5sum` # of `md5sum`
@ -500,7 +500,7 @@ proc md5_File* (file: string): string {.raises:[EIO,Ebase].} =
result = hexStr(buf) result = hexStr(buf)
proc md5_Str* (str:string): string {.raises:[EIO].} = proc md5_Str* (str:string): string {.raises:[IOError].} =
##Generate MD5 hash for a string. Result is a 32 character ##Generate MD5 hash for a string. Result is a 32 character
#hex string with lowercase characters #hex string with lowercase characters
var var

View file

@ -1,3 +1,18 @@
discard """
output: '''12
1xxx
true0
12
testtest
1010
11string
testtest1
seq
seq
seq
foo seq
foo of numeric'''"""
type type
TFoo[T] = object TFoo[T] = object
val: T val: T

View file

@ -1,7 +1,7 @@
# #
# #
# Nim Website Generator # Nim Website Generator
# (c) Copyright 2012 Andreas Rumpf # (c) Copyright 2014 Andreas Rumpf
# #
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.
@ -13,14 +13,14 @@ import
type type
TKeyValPair = tuple[key, id, val: string] TKeyValPair = tuple[key, id, val: string]
TConfigData = object of TObject 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, outdir, ticker: string
vars: PStringTable vars: StringTableRef
nimrodArgs: string nimArgs: string
gitCommit: string gitCommit: string
quotations: TTable[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.
TRssItem = object TRssItem = object
year, month, day, title: string year, month, day, title: string
@ -35,7 +35,7 @@ proc initConfigData(c: var TConfigData) =
c.pdf = @[] c.pdf = @[]
c.infile = "" c.infile = ""
c.outdir = "" c.outdir = ""
c.nimrodArgs = "--hint[Conf]:off " c.nimArgs = "--hint[Conf]:off "
c.authors = "" c.authors = ""
c.projectTitle = "" c.projectTitle = ""
c.projectName = "" c.projectName = ""
@ -58,7 +58,7 @@ const
version = "0.7" version = "0.7"
usage = "nimweb - Nim Website Generator Version " & version & """ usage = "nimweb - Nim Website Generator Version " & version & """
(c) 2012 Andreas Rumpf (c) 2014 Andreas Rumpf
Usage: Usage:
nimweb [options] ini-file[.ini] [compile_options] nimweb [options] ini-file[.ini] [compile_options]
Options: Options:
@ -112,7 +112,7 @@ proc parseCmdLine(c: var TConfigData) =
case kind case kind
of cmdArgument: of cmdArgument:
c.infile = addFileExt(key, "ini") c.infile = addFileExt(key, "ini")
c.nimrodArgs.add(cmdLineRest(p)) c.nimArgs.add(cmdLineRest(p))
break break
of cmdLongOption, cmdShortOption: of cmdLongOption, cmdShortOption:
case normalize(key) case normalize(key)
@ -127,7 +127,7 @@ proc parseCmdLine(c: var TConfigData) =
try: try:
let num = parseInt(val) let num = parseInt(val)
if num != 0: c.numProcessors = num if num != 0: c.numProcessors = num
except EInvalidValue: except ValueError:
quit("invalid numeric value for --parallelBuild") quit("invalid numeric value for --parallelBuild")
of "var": of "var":
var idx = val.find('=') var idx = val.find('=')
@ -155,68 +155,65 @@ proc addFiles(s: var seq[string], dir, ext: string, patterns: seq[string]) =
proc parseIniFile(c: var TConfigData) = proc parseIniFile(c: var TConfigData) =
var var
p: TCfgParser p: CfgParser
section: string # current section section: string # current section
var input = newFileStream(c.infile, fmRead) var input = newFileStream(c.infile, fmRead)
if input != nil: if input == nil: quit("cannot open: " & c.infile)
open(p, input, c.infile) open(p, input, c.infile)
while true: while true:
var k = next(p) var k = next(p)
case k.kind case k.kind
of cfgEof: break of cfgEof: break
of cfgSectionStart: of cfgSectionStart:
section = normalize(k.section) section = normalize(k.section)
case section case section
of "project", "links", "tabs", "ticker", "documentation", "var": discard of "project", "links", "tabs", "ticker", "documentation", "var": discard
else: echo("[Warning] Skipping unknown section: " & section) else: echo("[Warning] Skipping unknown section: " & section)
of cfgKeyValuePair: of cfgKeyValuePair:
var v = k.value % c.vars var v = k.value % c.vars
c.vars[k.key] = v c.vars[k.key] = v
case section case section
of "project": of "project":
case normalize(k.key) case normalize(k.key)
of "name": c.projectName = v of "name": c.projectName = v
of "title": c.projectTitle = v of "title": c.projectTitle = v
of "logo": c.logo = v of "logo": c.logo = v
of "authors": c.authors = v of "authors": c.authors = v
else: quit(errorStr(p, "unknown variable: " & k.key)) else: quit(errorStr(p, "unknown variable: " & k.key))
of "var": discard of "var": discard
of "links": of "links":
let valID = v.split(';') let valID = v.split(';')
add(c.links, (k.key.replace('_', ' '), valID[1], valID[0])) add(c.links, (k.key.replace('_', ' '), valID[1], valID[0]))
of "tabs": add(c.tabs, (k.key, "", v)) of "tabs": add(c.tabs, (k.key, "", v))
of "ticker": c.ticker = v of "ticker": c.ticker = v
of "documentation": of "documentation":
case normalize(k.key) case normalize(k.key)
of "doc": addFiles(c.doc, "doc", ".txt", split(v, {';'})) of "doc": addFiles(c.doc, "doc", ".txt", split(v, {';'}))
of "pdf": addFiles(c.pdf, "doc", ".txt", split(v, {';'})) of "pdf": addFiles(c.pdf, "doc", ".txt", split(v, {';'}))
of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'})) of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'}))
of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'})) of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'}))
of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'})) of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'}))
of "parallelbuild": of "parallelbuild":
try: try:
let num = parseInt(v) let num = parseInt(v)
if num != 0: c.numProcessors = num if num != 0: c.numProcessors = num
except EInvalidValue: except ValueError:
quit("invalid numeric value for --parallelBuild in config") quit("invalid numeric value for --parallelBuild in config")
else: quit(errorStr(p, "unknown variable: " & k.key)) else: quit(errorStr(p, "unknown variable: " & k.key))
of "quotations": of "quotations":
let vSplit = v.split('-') let vSplit = v.split('-')
doAssert vSplit.len == 2 doAssert vSplit.len == 2
c.quotations[k.key.normalize] = (vSplit[0], vSplit[1]) c.quotations[k.key.normalize] = (vSplit[0], vSplit[1])
else: discard else: discard
of cfgOption: quit(errorStr(p, "syntax error"))
of cfgOption: quit(errorStr(p, "syntax error")) of cfgError: quit(errorStr(p, k.msg))
of cfgError: quit(errorStr(p, k.msg)) 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:
if c.outdir.len == 0: c.outdir = splitFile(c.infile).dir
c.outdir = splitFile(c.infile).dir
else:
quit("cannot open: " & c.infile)
# Ugly hack to override git command output when building private repo. # Ugly hack to override git command output when building private repo.
if c.vars.hasKey("githash"): if c.vars.hasKey("githash"):
let githash = c.vars["githash"].strip let githash = c.vars["githash"].strip
@ -238,8 +235,7 @@ proc mexec(cmds: openarray[string], processors: int) =
if processors < 2: if processors < 2:
sexec(cmds) sexec(cmds)
return return
if execProcesses(cmds, {poStdErrToStdOut, poParentStreams, poEchoCmd}) != 0:
if 0 != execProcesses(cmds, {poStdErrToStdOut, poParentStreams, poEchoCmd}):
echo "external program failed, retrying serial work queue for logs!" echo "external program failed, retrying serial work queue for logs!"
sexec(cmds) sexec(cmds)
@ -251,9 +247,9 @@ proc buildDocSamples(c: var TConfigData, destPath: string) =
## documentation builders. ## documentation builders.
const src = "doc"/"docgen_sample.nim" const src = "doc"/"docgen_sample.nim"
exec("nim doc $# -o:$# $#" % exec("nim doc $# -o:$# $#" %
[c.nimrodArgs, destPath / "docgen_sample.html", src]) [c.nimArgs, destPath / "docgen_sample.html", src])
exec("nim doc2 $# -o:$# $#" % exec("nim doc2 $# -o:$# $#" %
[c.nimrodArgs, destPath / "docgen_sample2.html", src]) [c.nimArgs, destPath / "docgen_sample2.html", src])
proc buildDoc(c: var TConfigData, destPath: string) = proc buildDoc(c: var TConfigData, destPath: string) =
# call nim for the documentation: # call nim for the documentation:
@ -262,17 +258,17 @@ proc buildDoc(c: var TConfigData, destPath: string) =
i = 0 i = 0
for d in items(c.doc): for d in items(c.doc):
commands[i] = "nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" % commands[i] = "nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" %
[c.nimrodArgs, c.gitCommit, [c.nimArgs, c.gitCommit,
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] = "nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" % commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" %
[c.nimrodArgs, c.gitCommit, [c.nimArgs, c.gitCommit,
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] = "nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" % commands[i] = "nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" %
[c.nimrodArgs, c.gitCommit, [c.nimArgs, c.gitCommit,
destPath / changeFileExt(splitFile(d).name, "html"), d] destPath / changeFileExt(splitFile(d).name, "html"), d]
i.inc i.inc
@ -284,7 +280,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) =
echo "pdflatex not found; no PDF documentation generated" echo "pdflatex not found; no PDF documentation generated"
else: else:
for d in items(c.pdf): for d in items(c.pdf):
exec("nim rst2tex $# $#" % [c.nimrodArgs, d]) exec("nim rst2tex $# $#" % [c.nimArgs, d])
# call LaTeX twice to get cross references right: # call LaTeX twice to get cross references right:
exec("pdflatex " & changeFileExt(d, "tex")) exec("pdflatex " & changeFileExt(d, "tex"))
exec("pdflatex " & changeFileExt(d, "tex")) exec("pdflatex " & changeFileExt(d, "tex"))
@ -303,7 +299,7 @@ proc buildAddDoc(c: var TConfigData, destPath: string) =
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] = "nim doc $# --docSeeSrcUrl:$# -o:$# $#" % commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# $#" %
[c.nimrodArgs, c.gitCommit, [c.nimArgs, c.gitCommit,
destPath / changeFileExt(splitFile(doc).name, "html"), doc] destPath / changeFileExt(splitFile(doc).name, "html"), doc]
mexec(commands, c.numProcessors) mexec(commands, c.numProcessors)
@ -311,7 +307,7 @@ proc parseNewsTitles(inputFilename: string): seq[TRssItem] =
# parses the file for titles and returns them as TRssItem blocks. # parses the file for titles and returns them as TRssItem blocks.
let reYearMonthDayTitle = re(rYearMonthDayTitle) let reYearMonthDayTitle = re(rYearMonthDayTitle)
var var
input: TFile input: File
line = "" line = ""
result = @[] result = @[]
@ -347,7 +343,7 @@ proc genNewsLink(title: string): string =
proc generateRss(outputFilename: string, news: seq[TRssItem]) = proc generateRss(outputFilename: string, news: seq[TRssItem]) =
# Given a list of rss items generates an rss overwriting destination. # Given a list of rss items generates an rss overwriting destination.
var var
output: TFile output: File
if not open(output, outputFilename, mode = fmWrite): if not open(output, outputFilename, mode = fmWrite):
quit("Could not write to $1 for rss generation" % [outputFilename]) quit("Could not write to $1 for rss generation" % [outputFilename])
@ -396,19 +392,19 @@ proc main(c: var TConfigData) =
if c.ticker.len > 0: if c.ticker.len > 0:
try: try:
c.ticker = readFile("web" / c.ticker) c.ticker = readFile("web" / c.ticker)
except EIO: except IOError:
quit("[Error] cannot open: " & c.ticker) quit("[Error] cannot open: " & c.ticker)
for i in 0..c.tabs.len-1: for i in 0..c.tabs.len-1:
var file = c.tabs[i].val var file = c.tabs[i].val
let rss = if file in ["news", "index"]: extractFilename(rssUrl) else: "" let rss = if file in ["news", "index"]: extractFilename(rssUrl) else: ""
exec(cmd % [c.nimrodArgs, file]) exec(cmd % [c.nimArgs, file])
var temp = "web" / changeFileExt(file, "temp") var temp = "web" / changeFileExt(file, "temp")
var content: string var content: string
try: try:
content = readFile(temp) content = readFile(temp)
except EIO: except IOError:
quit("[Error] cannot open: " & temp) quit("[Error] cannot open: " & temp)
var f: TFile var f: File
var outfile = "web/upload/$#.html" % file var outfile = "web/upload/$#.html" % file
if not existsDir("web/upload"): if not existsDir("web/upload"):
createDir("web/upload") createDir("web/upload")

View file

@ -104,7 +104,7 @@ the use of an ``await`` macro which behaves similar to C#'s await. The
following is a very simple chat server demonstrating Nimrod's new async following is a very simple chat server demonstrating Nimrod's new async
capabilities. capabilities.
.. code-block::nimrod .. code-block::nim
import asyncnet, asyncdispatch import asyncnet, asyncdispatch
var clients: seq[PAsyncSocket] = @[] var clients: seq[PAsyncSocket] = @[]
@ -137,7 +137,7 @@ Syntactic sugar for anonymous procedures has also been introduced. It too has
been implemented as a macro. The following shows some simple usage of the new been implemented as a macro. The following shows some simple usage of the new
syntax: syntax:
.. code-block::nimrod .. code-block::nim
import future import future
var s = @[1, 2, 3, 4, 5] var s = @[1, 2, 3, 4, 5]