This commit is contained in:
Araq 2015-04-19 02:43:19 +02:00
commit 5cea6807e1
5 changed files with 161 additions and 152 deletions

View file

@ -124,7 +124,7 @@ proc newProc(globals: PGlobals, module: BModule, procDef: PNode,
const const
MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray,
tySet, tyVar, tyRef, tyPtr, tyBigNum, tyVarargs} tySet, tyBigNum, tyVarargs}
proc mapType(typ: PType): TJSTypeKind = proc mapType(typ: PType): TJSTypeKind =
let t = skipTypes(typ, abstractInst) let t = skipTypes(typ, abstractInst)
@ -163,7 +163,8 @@ proc mangleName(s: PSym): Rope =
add(result, rope(s.id)) add(result, rope(s.id))
s.loc.r = result s.loc.r = result
proc makeJSString(s: string): Rope = strutils.escape(s).rope proc makeJSString(s: string): Rope =
(if s.isNil: "null".rope else: strutils.escape(s).rope)
include jstypes include jstypes
@ -937,6 +938,12 @@ proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
r.address = nil r.address = nil
r.kind = resExpr r.kind = resExpr
proc isIndirect(v: PSym): bool =
result = {sfAddrTaken, sfGlobal} * v.flags != {} and
#(mapType(v.typ) != etyObject) and
sfVolatile notin v.flags and
v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator}
proc genAddr(p: PProc, n: PNode, r: var TCompRes) = proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
case n.sons[0].kind case n.sons[0].kind
of nkSym: of nkSym:
@ -945,12 +952,16 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
case s.kind case s.kind
of skVar, skLet, skResult: of skVar, skLet, skResult:
r.kind = resExpr r.kind = resExpr
if mapType(n.sons[0].typ) == etyObject: let jsType = mapType(n.typ)
if jsType == etyObject:
# make addr() a no-op: # make addr() a no-op:
r.typ = etyNone r.typ = etyNone
r.res = s.loc.r if isIndirect(s):
r.res = s.loc.r & "[0]"
else:
r.res = s.loc.r
r.address = nil r.address = nil
elif {sfGlobal, sfAddrTaken} * s.flags != {}: elif {sfGlobal, sfAddrTaken} * s.flags != {} or jsType == etyBaseIndex:
# for ease of code generation, we do not distinguish between # for ease of code generation, we do not distinguish between
# sfAddrTaken and sfGlobal. # sfAddrTaken and sfGlobal.
r.typ = etyBaseIndex r.typ = etyBaseIndex
@ -992,7 +1003,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
else: else:
r.address = s.loc.r r.address = s.loc.r
r.res = s.loc.r & "_Idx" r.res = s.loc.r & "_Idx"
elif k != etyObject and {sfAddrTaken, sfGlobal} * s.flags != {}: elif isIndirect(s):
r.res = "$1[0]" % [s.loc.r] r.res = "$1[0]" % [s.loc.r]
else: else:
r.res = s.loc.r r.res = s.loc.r
@ -1124,7 +1135,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
of tyRange, tyGenericInst: of tyRange, tyGenericInst:
result = createVar(p, lastSon(typ), indirect) result = createVar(p, lastSon(typ), indirect)
of tySet: of tySet:
result = rope("{}") result = putToSeq("{}", indirect)
of tyBool: of tyBool:
result = putToSeq("false", indirect) result = putToSeq("false", indirect)
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
@ -1144,6 +1155,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
add(result, createVar(p, e, false)) add(result, createVar(p, e, false))
inc(i) inc(i)
add(result, "]") add(result, "]")
if indirect: result = "[$1]" % [result]
of tyTuple: of tyTuple:
result = rope("{") result = rope("{")
for i in 0.. <t.sonsLen: for i in 0.. <t.sonsLen:
@ -1151,6 +1163,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
addf(result, "Field$1: $2" | "Field$# = $#", [i.rope, addf(result, "Field$1: $2" | "Field$# = $#", [i.rope,
createVar(p, t.sons[i], false)]) createVar(p, t.sons[i], false)])
add(result, "}") add(result, "}")
if indirect: result = "[$1]" % [result]
of tyObject: of tyObject:
result = rope("{") result = rope("{")
var c = 0 var c = 0
@ -1161,6 +1174,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
add(result, createRecordVarAux(p, t.n, c)) add(result, createRecordVarAux(p, t.n, c))
t = t.sons[0] t = t.sons[0]
add(result, "}") add(result, "}")
if indirect: result = "[$1]" % [result]
of tyVar, tyPtr, tyRef: of tyVar, tyPtr, tyRef:
if mapType(t) == etyBaseIndex: if mapType(t) == etyBaseIndex:
result = putToSeq("[null, 0]" | "{nil, 0}", indirect) result = putToSeq("[null, 0]" | "{nil, 0}", indirect)
@ -1172,11 +1186,6 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
internalError("createVar: " & $t.kind) internalError("createVar: " & $t.kind)
result = nil result = nil
proc isIndirect(v: PSym): bool =
result = {sfAddrTaken, sfGlobal} * v.flags != {} and
(mapType(v.typ) != etyObject) and
v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator}
proc genVarInit(p: PProc, v: PSym, n: PNode) = proc genVarInit(p: PProc, v: PSym, n: PNode) =
var var
a: TCompRes a: TCompRes
@ -1239,7 +1248,7 @@ proc genNew(p: PProc, n: PNode) =
var a: TCompRes var a: TCompRes
gen(p, n.sons[1], a) gen(p, n.sons[1], a)
var t = skipTypes(n.sons[1].typ, abstractVar).sons[0] var t = skipTypes(n.sons[1].typ, abstractVar).sons[0]
addf(p.body, "$1 = $2;$n", [a.res, createVar(p, t, true)]) addf(p.body, "$1 = $2;$n", [a.res, createVar(p, t, false)])
proc genNewSeq(p: PProc, n: PNode) = proc genNewSeq(p: PProc, n: PNode) =
var x, y: TCompRes var x, y: TCompRes

View file

@ -127,8 +127,8 @@ The signature has to be:
.. code-block:: nim .. code-block:: nim
proc `=deepCopy`(x: T): T proc `=deepCopy`(x: T): T
This mechanism is used by most data structures that support shared memory like This mechanism will be used by most data structures that support shared memory
channels to implement thread safe automatic memory management. like channels to implement thread safe automatic memory management.
The builtin ``deepCopy`` can even clone closures and their environments. See The builtin ``deepCopy`` can even clone closures and their environments. See
the documentation of `spawn`_ for details. the documentation of `spawn`_ for details.

View file

@ -34,14 +34,14 @@ type
TOutputTarget* = enum ## which document type to generate TOutputTarget* = enum ## which document type to generate
outHtml, # output is HTML outHtml, # output is HTML
outLatex # output is Latex outLatex # output is Latex
TTocEntry = object TTocEntry = object
n*: PRstNode n*: PRstNode
refname*, header*: string refname*, header*: string
TMetaEnum* = enum TMetaEnum* = enum
metaNone, metaTitle, metaSubtitle, metaAuthor, metaVersion metaNone, metaTitle, metaSubtitle, metaAuthor, metaVersion
TRstGenerator* = object of RootObj TRstGenerator* = object of RootObj
target*: TOutputTarget target*: TOutputTarget
config*: StringTableRef config*: StringTableRef
@ -60,7 +60,7 @@ type
seenIndexTerms: Table[string, int] ## \ seenIndexTerms: Table[string, int] ## \
## Keeps count of same text index terms to generate different identifiers ## Keeps count of same text index terms to generate different identifiers
## for hyperlinks. See renderIndexTerm proc for details. ## for hyperlinks. See renderIndexTerm proc for details.
PDoc = var TRstGenerator ## Alias to type less. PDoc = var TRstGenerator ## Alias to type less.
CodeBlockParams = object ## Stores code block params. CodeBlockParams = object ## Stores code block params.
@ -136,7 +136,7 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
g.currentSection = "Module " & fileParts.name g.currentSection = "Module " & fileParts.name
g.seenIndexTerms = initTable[string, int]() g.seenIndexTerms = initTable[string, int]()
g.msgHandler = msgHandler g.msgHandler = msgHandler
let s = config["split.item.toc"] let s = config["split.item.toc"]
if s != "": g.splitAfter = parseInt(s) if s != "": g.splitAfter = parseInt(s)
for i in low(g.meta)..high(g.meta): g.meta[i] = "" for i in low(g.meta)..high(g.meta): g.meta[i] = ""
@ -147,23 +147,23 @@ proc writeIndexFile*(g: var TRstGenerator, outfile: string) =
## You previously need to add entries to the index with the `setIndexTerm() ## You previously need to add entries to the index with the `setIndexTerm()
## <#setIndexTerm>`_ proc. If the index is empty the file won't be created. ## <#setIndexTerm>`_ proc. If the index is empty the file won't be created.
if g.theIndex.len > 0: writeFile(outfile, g.theIndex) if g.theIndex.len > 0: writeFile(outfile, g.theIndex)
proc addXmlChar(dest: var string, c: char) = proc addXmlChar(dest: var string, c: char) =
case c case c
of '&': add(dest, "&amp;") of '&': add(dest, "&amp;")
of '<': add(dest, "&lt;") of '<': add(dest, "&lt;")
of '>': add(dest, "&gt;") of '>': add(dest, "&gt;")
of '\"': add(dest, "&quot;") of '\"': add(dest, "&quot;")
else: add(dest, c) else: add(dest, c)
proc addRtfChar(dest: var string, c: char) = proc addRtfChar(dest: var string, c: char) =
case c case c
of '{': add(dest, "\\{") of '{': add(dest, "\\{")
of '}': add(dest, "\\}") of '}': add(dest, "\\}")
of '\\': add(dest, "\\\\") of '\\': add(dest, "\\\\")
else: add(dest, c) else: add(dest, c)
proc addTexChar(dest: var string, c: char) = proc addTexChar(dest: var string, c: char) =
case c case c
of '_': add(dest, "\\_") of '_': add(dest, "\\_")
of '{': add(dest, "\\symbol{123}") of '{': add(dest, "\\symbol{123}")
@ -183,54 +183,54 @@ proc addTexChar(dest: var string, c: char) =
var splitter*: string = "<wbr />" var splitter*: string = "<wbr />"
proc escChar*(target: TOutputTarget, dest: var string, c: char) {.inline.} = proc escChar*(target: TOutputTarget, dest: var string, c: char) {.inline.} =
case target case target
of outHtml: addXmlChar(dest, c) of outHtml: addXmlChar(dest, c)
of outLatex: addTexChar(dest, c) of outLatex: addTexChar(dest, c)
proc nextSplitPoint*(s: string, start: int): int = proc nextSplitPoint*(s: string, start: int): int =
result = start result = start
while result < len(s) + 0: while result < len(s) + 0:
case s[result] case s[result]
of '_': return of '_': return
of 'a'..'z': of 'a'..'z':
if result + 1 < len(s) + 0: if result + 1 < len(s) + 0:
if s[result + 1] in {'A'..'Z'}: return if s[result + 1] in {'A'..'Z'}: return
else: discard else: discard
inc(result) inc(result)
dec(result) # last valid index dec(result) # last valid index
proc esc*(target: TOutputTarget, s: string, splitAfter = -1): string = proc esc*(target: TOutputTarget, s: string, splitAfter = -1): string =
result = "" result = ""
if splitAfter >= 0: if splitAfter >= 0:
var partLen = 0 var partLen = 0
var j = 0 var j = 0
while j < len(s): while j < len(s):
var k = nextSplitPoint(s, j) var k = nextSplitPoint(s, j)
if (splitter != " ") or (partLen + k - j + 1 > splitAfter): if (splitter != " ") or (partLen + k - j + 1 > splitAfter):
partLen = 0 partLen = 0
add(result, splitter) add(result, splitter)
for i in countup(j, k): escChar(target, result, s[i]) for i in countup(j, k): escChar(target, result, s[i])
inc(partLen, k - j + 1) inc(partLen, k - j + 1)
j = k + 1 j = k + 1
else: else:
for i in countup(0, len(s) - 1): escChar(target, result, s[i]) for i in countup(0, len(s) - 1): escChar(target, result, s[i])
proc disp(target: TOutputTarget, xml, tex: string): string = proc disp(target: TOutputTarget, xml, tex: string): string =
if target != outLatex: result = xml if target != outLatex: result = xml
else: result = tex else: result = tex
proc dispF(target: TOutputTarget, xml, tex: string, proc dispF(target: TOutputTarget, xml, tex: string,
args: varargs[string]): string = args: varargs[string]): string =
if target != outLatex: result = xml % args if target != outLatex: result = xml % args
else: result = tex % args else: result = tex % args
proc dispA(target: TOutputTarget, dest: var string, proc dispA(target: TOutputTarget, dest: var string,
xml, tex: string, args: varargs[string]) = xml, tex: string, args: varargs[string]) =
if target != outLatex: addf(dest, xml, args) if target != outLatex: addf(dest, xml, args)
else: addf(dest, tex, args) else: addf(dest, tex, args)
proc `or`(x, y: string): string {.inline.} = proc `or`(x, y: string): string {.inline.} =
result = if x.isNil: y else: x result = if x.isNil: y else: x
@ -248,7 +248,7 @@ proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string)
## renderRstToOut(gen, rst, generatedHTML) ## renderRstToOut(gen, rst, generatedHTML)
## echo generatedHTML ## echo generatedHTML
proc renderAux(d: PDoc, n: PRstNode, result: var string) = proc renderAux(d: PDoc, n: PRstNode, result: var string) =
for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], result) for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], result)
proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) = proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) =
@ -347,7 +347,7 @@ proc renderIndexTerm*(d: PDoc, n: PRstNode, result: var string) =
var term = "" var term = ""
renderAux(d, n, term) renderAux(d, n, term)
setIndexTerm(d, id, term, d.currentSection) setIndexTerm(d, id, term, d.currentSection)
dispA(d.target, result, "<span id=\"$1\">$2</span>", "$2\\label{$1}", dispA(d.target, result, "<span id=\"$1\">$2</span>", "$2\\label{$1}",
[id, term]) [id, term])
type type
@ -656,7 +656,7 @@ proc mergeIndexes*(dir: string): string =
result.add("<h2>API symbols</h2>\n") result.add("<h2>API symbols</h2>\n")
result.add(generateSymbolIndex(symbols)) result.add(generateSymbolIndex(symbols))
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
proc stripTOCHTML(s: string): string = proc stripTOCHTML(s: string): string =
@ -677,7 +677,7 @@ proc stripTOCHTML(s: string): string =
result.delete(first, last) result.delete(first, last)
first = result.find('<', first) first = result.find('<', first)
proc renderHeadline(d: PDoc, n: PRstNode, result: var string) = proc renderHeadline(d: PDoc, n: PRstNode, result: var string) =
var tmp = "" var tmp = ""
for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp) for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp)
d.currentSection = tmp d.currentSection = tmp
@ -700,9 +700,9 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) =
"id=\"$2\" href=\"#$2\">$3</a></h$1>", "\\rsth$4{$3}\\label{$2}\n", "id=\"$2\" href=\"#$2\">$3</a></h$1>", "\\rsth$4{$3}\\label{$2}\n",
[$n.level, d.tocPart[length].refname, tmp, $chr(n.level - 1 + ord('A'))]) [$n.level, d.tocPart[length].refname, tmp, $chr(n.level - 1 + ord('A'))])
else: else:
dispA(d.target, result, "\n<h$1 id=\"$2\">$3</h$1>", dispA(d.target, result, "\n<h$1 id=\"$2\">$3</h$1>",
"\\rsth$4{$3}\\label{$2}\n", [ "\\rsth$4{$3}\\label{$2}\n", [
$n.level, refname, tmp, $n.level, refname, tmp,
$chr(n.level - 1 + ord('A'))]) $chr(n.level - 1 + ord('A'))])
# Generate index entry using spaces to indicate TOC level for the output HTML. # Generate index entry using spaces to indicate TOC level for the output HTML.
@ -710,7 +710,7 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) =
setIndexTerm(d, refname, tmp.stripTOCHTML, setIndexTerm(d, refname, tmp.stripTOCHTML,
spaces(max(0, n.level)) & tmp) spaces(max(0, n.level)) & tmp)
proc renderOverline(d: PDoc, n: PRstNode, result: var string) = proc renderOverline(d: PDoc, n: PRstNode, result: var string) =
if d.meta[metaTitle].len == 0: if d.meta[metaTitle].len == 0:
for i in countup(0, len(n)-1): for i in countup(0, len(n)-1):
renderRstToOut(d, n.sons[i], d.meta[metaTitle]) renderRstToOut(d, n.sons[i], d.meta[metaTitle])
@ -723,14 +723,14 @@ proc renderOverline(d: PDoc, n: PRstNode, result: var string) =
var tmp = "" var tmp = ""
for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp) for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp)
d.currentSection = tmp d.currentSection = tmp
dispA(d.target, result, "<h$1 id=\"$2\"><center>$3</center></h$1>", dispA(d.target, result, "<h$1 id=\"$2\"><center>$3</center></h$1>",
"\\rstov$4{$3}\\label{$2}\n", [$n.level, "\\rstov$4{$3}\\label{$2}\n", [$n.level,
rstnodeToRefname(n), tmp, $chr(n.level - 1 + ord('A'))]) rstnodeToRefname(n), tmp, $chr(n.level - 1 + ord('A'))])
proc renderTocEntry(d: PDoc, e: TTocEntry, result: var string) =
proc renderTocEntry(d: PDoc, e: TTocEntry, result: var string) =
dispA(d.target, result, dispA(d.target, result,
"<li><a class=\"reference\" id=\"$1_toc\" href=\"#$1\">$2</a></li>\n", "<li><a class=\"reference\" id=\"$1_toc\" href=\"#$1\">$2</a></li>\n",
"\\item\\label{$1_toc} $2\\ref{$1}\n", [e.refname, e.header]) "\\item\\label{$1_toc} $2\\ref{$1}\n", [e.refname, e.header])
proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int,
@ -759,33 +759,33 @@ proc renderImage(d: PDoc, n: PRstNode, result: var string) =
var options = "" var options = ""
var s = getFieldValue(n, "scale") var s = getFieldValue(n, "scale")
if s.valid: dispA(d.target, options, " scale=\"$1\"", " scale=$1", [strip(s)]) if s.valid: dispA(d.target, options, " scale=\"$1\"", " scale=$1", [strip(s)])
s = getFieldValue(n, "height") s = getFieldValue(n, "height")
if s.valid: dispA(d.target, options, " height=\"$1\"", " height=$1", [strip(s)]) if s.valid: dispA(d.target, options, " height=\"$1\"", " height=$1", [strip(s)])
s = getFieldValue(n, "width") s = getFieldValue(n, "width")
if s.valid: dispA(d.target, options, " width=\"$1\"", " width=$1", [strip(s)]) if s.valid: dispA(d.target, options, " width=\"$1\"", " width=$1", [strip(s)])
s = getFieldValue(n, "alt") s = getFieldValue(n, "alt")
if s.valid: dispA(d.target, options, " alt=\"$1\"", "", [strip(s)]) if s.valid: dispA(d.target, options, " alt=\"$1\"", "", [strip(s)])
s = getFieldValue(n, "align") s = getFieldValue(n, "align")
if s.valid: dispA(d.target, options, " align=\"$1\"", "", [strip(s)]) if s.valid: dispA(d.target, options, " align=\"$1\"", "", [strip(s)])
if options.len > 0: options = dispF(d.target, "$1", "[$1]", [options]) if options.len > 0: options = dispF(d.target, "$1", "[$1]", [options])
let arg = getArgument(n) let arg = getArgument(n)
if arg.valid: if arg.valid:
dispA(d.target, result, "<img src=\"$1\"$2 />", "\\includegraphics$2{$1}", dispA(d.target, result, "<img src=\"$1\"$2 />", "\\includegraphics$2{$1}",
[arg, options]) [arg, options])
if len(n) >= 3: renderRstToOut(d, n.sons[2], result) if len(n) >= 3: renderRstToOut(d, n.sons[2], result)
proc renderSmiley(d: PDoc, n: PRstNode, result: var string) = proc renderSmiley(d: PDoc, n: PRstNode, result: var string) =
dispA(d.target, result, dispA(d.target, result,
"""<img src="$1" width="15" """<img src="$1" width="15"
height="17" hspace="2" vspace="2" class="smiley" />""", height="17" hspace="2" vspace="2" class="smiley" />""",
"\\includegraphics{$1}", [d.config["doc.smiley_format"] % n.text]) "\\includegraphics{$1}", [d.config["doc.smiley_format"] % n.text])
proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) = proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) =
## Parses useful fields which can appear before a code block. ## Parses useful fields which can appear before a code block.
## ##
@ -880,11 +880,11 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) =
else: else:
var g: TGeneralTokenizer var g: TGeneralTokenizer
initGeneralTokenizer(g, m.text) initGeneralTokenizer(g, m.text)
while true: while true:
getNextToken(g, params.lang) getNextToken(g, params.lang)
case g.kind case g.kind
of gtEof: break of gtEof: break
of gtNone, gtWhitespace: of gtNone, gtWhitespace:
add(result, substr(m.text, g.start, g.length + g.start - 1)) add(result, substr(m.text, g.start, g.length + g.start - 1))
else: else:
dispA(d.target, result, "<span class=\"$2\">$1</span>", "\\span$2{$1}", [ dispA(d.target, result, "<span class=\"$2\">$1</span>", "\\span$2{$1}", [
@ -893,36 +893,36 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) =
deinitGeneralTokenizer(g) deinitGeneralTokenizer(g)
dispA(d.target, result, blockEnd, "\n\\end{rstpre}\n") dispA(d.target, result, blockEnd, "\n\\end{rstpre}\n")
proc renderContainer(d: PDoc, n: PRstNode, result: var string) = proc renderContainer(d: PDoc, n: PRstNode, result: var string) =
var tmp = "" var tmp = ""
renderRstToOut(d, n.sons[2], tmp) renderRstToOut(d, n.sons[2], tmp)
var arg = strip(getArgument(n)) var arg = strip(getArgument(n))
if arg == "": if arg == "":
dispA(d.target, result, "<div>$1</div>", "$1", [tmp]) dispA(d.target, result, "<div>$1</div>", "$1", [tmp])
else: else:
dispA(d.target, result, "<div class=\"$1\">$2</div>", "$2", [arg, tmp]) dispA(d.target, result, "<div class=\"$1\">$2</div>", "$2", [arg, tmp])
proc texColumns(n: PRstNode): string = proc texColumns(n: PRstNode): string =
result = "" result = ""
for i in countup(1, len(n)): add(result, "|X") for i in countup(1, len(n)): add(result, "|X")
proc renderField(d: PDoc, n: PRstNode, result: var string) = proc renderField(d: PDoc, n: PRstNode, result: var string) =
var b = false var b = false
if d.target == outLatex: if d.target == outLatex:
var fieldname = addNodes(n.sons[0]) var fieldname = addNodes(n.sons[0])
var fieldval = esc(d.target, strip(addNodes(n.sons[1]))) var fieldval = esc(d.target, strip(addNodes(n.sons[1])))
if cmpIgnoreStyle(fieldname, "author") == 0 or if cmpIgnoreStyle(fieldname, "author") == 0 or
cmpIgnoreStyle(fieldname, "authors") == 0: cmpIgnoreStyle(fieldname, "authors") == 0:
if d.meta[metaAuthor].len == 0: if d.meta[metaAuthor].len == 0:
d.meta[metaAuthor] = fieldval d.meta[metaAuthor] = fieldval
b = true b = true
elif cmpIgnoreStyle(fieldname, "version") == 0: elif cmpIgnoreStyle(fieldname, "version") == 0:
if d.meta[metaVersion].len == 0: if d.meta[metaVersion].len == 0:
d.meta[metaVersion] = fieldval d.meta[metaVersion] = fieldval
b = true b = true
if not b: if not b:
renderAux(d, n, "<tr>$1</tr>\n", "$1", result) renderAux(d, n, "<tr>$1</tr>\n", "$1", result)
proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) = proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
if n == nil: return if n == nil: return
case n.kind case n.kind
@ -947,54 +947,54 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
of rnDefBody: renderAux(d, n, "<dd>$1</dd>\n", "$1\n", result) of rnDefBody: renderAux(d, n, "<dd>$1</dd>\n", "$1\n", result)
of rnFieldList: of rnFieldList:
var tmp = "" var tmp = ""
for i in countup(0, len(n) - 1): for i in countup(0, len(n) - 1):
renderRstToOut(d, n.sons[i], tmp) renderRstToOut(d, n.sons[i], tmp)
if tmp.len != 0: if tmp.len != 0:
dispA(d.target, result, dispA(d.target, result,
"<table class=\"docinfo\" frame=\"void\" rules=\"none\">" & "<table class=\"docinfo\" frame=\"void\" rules=\"none\">" &
"<col class=\"docinfo-name\" />" & "<col class=\"docinfo-name\" />" &
"<col class=\"docinfo-content\" />" & "<col class=\"docinfo-content\" />" &
"<tbody valign=\"top\">$1" & "<tbody valign=\"top\">$1" &
"</tbody></table>", "</tbody></table>",
"\\begin{description}$1\\end{description}\n", "\\begin{description}$1\\end{description}\n",
[tmp]) [tmp])
of rnField: renderField(d, n, result) of rnField: renderField(d, n, result)
of rnFieldName: of rnFieldName:
renderAux(d, n, "<th class=\"docinfo-name\">$1:</th>", renderAux(d, n, "<th class=\"docinfo-name\">$1:</th>",
"\\item[$1:]", result) "\\item[$1:]", result)
of rnFieldBody: of rnFieldBody:
renderAux(d, n, "<td>$1</td>", " $1\n", result) renderAux(d, n, "<td>$1</td>", " $1\n", result)
of rnIndex: of rnIndex:
renderRstToOut(d, n.sons[2], result) renderRstToOut(d, n.sons[2], result)
of rnOptionList: of rnOptionList:
renderAux(d, n, "<table frame=\"void\">$1</table>", renderAux(d, n, "<table frame=\"void\">$1</table>",
"\\begin{description}\n$1\\end{description}\n", result) "\\begin{description}\n$1\\end{description}\n", result)
of rnOptionListItem: of rnOptionListItem:
renderAux(d, n, "<tr>$1</tr>\n", "$1", result) renderAux(d, n, "<tr>$1</tr>\n", "$1", result)
of rnOptionGroup: of rnOptionGroup:
renderAux(d, n, "<th align=\"left\">$1</th>", "\\item[$1]", result) renderAux(d, n, "<th align=\"left\">$1</th>", "\\item[$1]", result)
of rnDescription: of rnDescription:
renderAux(d, n, "<td align=\"left\">$1</td>\n", " $1\n", result) renderAux(d, n, "<td align=\"left\">$1</td>\n", " $1\n", result)
of rnOption, rnOptionString, rnOptionArgument: of rnOption, rnOptionString, rnOptionArgument:
doAssert false, "renderRstToOut" doAssert false, "renderRstToOut"
of rnLiteralBlock: of rnLiteralBlock:
renderAux(d, n, "<pre>$1</pre>\n", renderAux(d, n, "<pre>$1</pre>\n",
"\\begin{rstpre}\n$1\n\\end{rstpre}\n", result) "\\begin{rstpre}\n$1\n\\end{rstpre}\n", result)
of rnQuotedLiteralBlock: of rnQuotedLiteralBlock:
doAssert false, "renderRstToOut" doAssert false, "renderRstToOut"
of rnLineBlock: of rnLineBlock:
renderAux(d, n, "<p>$1</p>", "$1\n\n", result) renderAux(d, n, "<p>$1</p>", "$1\n\n", result)
of rnLineBlockItem: of rnLineBlockItem:
renderAux(d, n, "$1<br />", "$1\\\\\n", result) renderAux(d, n, "$1<br />", "$1\\\\\n", result)
of rnBlockQuote: of rnBlockQuote:
renderAux(d, n, "<blockquote><p>$1</p></blockquote>\n", renderAux(d, n, "<blockquote><p>$1</p></blockquote>\n",
"\\begin{quote}$1\\end{quote}\n", result) "\\begin{quote}$1\\end{quote}\n", result)
of rnTable, rnGridTable: of rnTable, rnGridTable:
renderAux(d, n, renderAux(d, n,
"<table border=\"1\" class=\"docutils\">$1</table>", "<table border=\"1\" class=\"docutils\">$1</table>",
"\\begin{table}\\begin{rsttab}{" & "\\begin{table}\\begin{rsttab}{" &
texColumns(n) & "|}\n\\hline\n$1\\end{rsttab}\\end{table}", result) texColumns(n) & "|}\n\\hline\n$1\\end{rsttab}\\end{table}", result)
of rnTableRow: of rnTableRow:
if len(n) >= 1: if len(n) >= 1:
if d.target == outLatex: if d.target == outLatex:
#var tmp = "" #var tmp = ""
@ -1007,25 +1007,25 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
result.add("<tr>") result.add("<tr>")
renderAux(d, n, result) renderAux(d, n, result)
result.add("</tr>\n") result.add("</tr>\n")
of rnTableDataCell: of rnTableDataCell:
renderAux(d, n, "<td>$1</td>", "$1", result) renderAux(d, n, "<td>$1</td>", "$1", result)
of rnTableHeaderCell: of rnTableHeaderCell:
renderAux(d, n, "<th>$1</th>", "\\textbf{$1}", result) renderAux(d, n, "<th>$1</th>", "\\textbf{$1}", result)
of rnLabel: of rnLabel:
doAssert false, "renderRstToOut" # used for footnotes and other doAssert false, "renderRstToOut" # used for footnotes and other
of rnFootnote: of rnFootnote:
doAssert false, "renderRstToOut" # a footnote doAssert false, "renderRstToOut" # a footnote
of rnCitation: of rnCitation:
doAssert false, "renderRstToOut" # similar to footnote doAssert false, "renderRstToOut" # similar to footnote
of rnRef: of rnRef:
var tmp = "" var tmp = ""
renderAux(d, n, tmp) renderAux(d, n, tmp)
dispA(d.target, result, dispA(d.target, result,
"<a class=\"reference external\" href=\"#$2\">$1</a>", "<a class=\"reference external\" href=\"#$2\">$1</a>",
"$1\\ref{$2}", [tmp, rstnodeToRefname(n)]) "$1\\ref{$2}", [tmp, rstnodeToRefname(n)])
of rnStandaloneHyperlink: of rnStandaloneHyperlink:
renderAux(d, n, renderAux(d, n,
"<a class=\"reference external\" href=\"$1\">$1</a>", "<a class=\"reference external\" href=\"$1\">$1</a>",
"\\href{$1}{$1}", result) "\\href{$1}{$1}", result)
of rnHyperlink: of rnHyperlink:
var tmp0 = "" var tmp0 = ""
@ -1042,11 +1042,11 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
of rnRawLatex: of rnRawLatex:
if d.target == outLatex: if d.target == outLatex:
result.add addNodes(lastSon(n)) result.add addNodes(lastSon(n))
of rnImage, rnFigure: renderImage(d, n, result) of rnImage, rnFigure: renderImage(d, n, result)
of rnCodeBlock: renderCodeBlock(d, n, result) of rnCodeBlock: renderCodeBlock(d, n, result)
of rnContainer: renderContainer(d, n, result) of rnContainer: renderContainer(d, n, result)
of rnSubstitutionReferences, rnSubstitutionDef: of rnSubstitutionReferences, rnSubstitutionDef:
renderAux(d, n, "|$1|", "|$1|", result) renderAux(d, n, "|$1|", "|$1|", result)
of rnDirective: of rnDirective:
renderAux(d, n, "", "", result) renderAux(d, n, "", "", result)
@ -1063,15 +1063,15 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
of rnStrongEmphasis: of rnStrongEmphasis:
renderAux(d, n, "<strong>$1</strong>", "\\textbf{$1}", result) renderAux(d, n, "<strong>$1</strong>", "\\textbf{$1}", result)
of rnTripleEmphasis: of rnTripleEmphasis:
renderAux(d, n, "<strong><em>$1</em></strong>", renderAux(d, n, "<strong><em>$1</em></strong>",
"\\textbf{emph{$1}}", result) "\\textbf{emph{$1}}", result)
of rnInterpretedText: of rnInterpretedText:
renderAux(d, n, "<cite>$1</cite>", "\\emph{$1}", result) renderAux(d, n, "<cite>$1</cite>", "\\emph{$1}", result)
of rnIdx: of rnIdx:
renderIndexTerm(d, n, result) renderIndexTerm(d, n, result)
of rnInlineLiteral: of rnInlineLiteral:
renderAux(d, n, renderAux(d, n,
"<tt class=\"docutils literal\"><span class=\"pre\">$1</span></tt>", "<tt class=\"docutils literal\"><span class=\"pre\">$1</span></tt>",
"\\texttt{$1}", result) "\\texttt{$1}", result)
of rnSmiley: renderSmiley(d, n, result) of rnSmiley: renderSmiley(d, n, result)
of rnLeaf: result.add(esc(d.target, n.text)) of rnLeaf: result.add(esc(d.target, n.text))
@ -1082,55 +1082,55 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
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 formatNamedVars*(frmt: string, varnames: openArray[string], proc formatNamedVars*(frmt: string, varnames: openArray[string],
varvalues: openArray[string]): string = varvalues: openArray[string]): string =
var i = 0 var i = 0
var L = len(frmt) var L = len(frmt)
result = "" result = ""
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 '#':
add(result, varvalues[num]) add(result, varvalues[num])
inc(num) inc(num)
inc(i) inc(i)
of '$': of '$':
add(result, "$") add(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-1 or frmt[i] notin {'0'..'9'}: break if i > L-1 or frmt[i] notin {'0'..'9'}: break
if j > high(varvalues) + 1: if j > high(varvalues) + 1:
raise newException(ValueError, "invalid index: " & $j) raise newException(ValueError, "invalid index: " & $j)
num = j num = j
add(result, varvalues[j - 1]) add(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 frmt[i] notin {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}: break if frmt[i] notin {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}: break
var idx = getVarIdx(varnames, id) var idx = getVarIdx(varnames, id)
if idx >= 0: if idx >= 0:
add(result, varvalues[idx]) add(result, varvalues[idx])
else: else:
raise newException(ValueError, "unknown substitution var: " & id) raise newException(ValueError, "unknown substitution var: " & id)
of '{': of '{':
var id = "" var id = ""
inc(i) inc(i)
while frmt[i] != '}': while frmt[i] != '}':
if frmt[i] == '\0': if frmt[i] == '\0':
raise newException(ValueError, "'}' expected") raise newException(ValueError, "'}' expected")
add(id, frmt[i]) add(id, frmt[i])
inc(i) inc(i)
@ -1138,12 +1138,12 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string],
# search for the variable: # search for the variable:
var idx = getVarIdx(varnames, id) var idx = getVarIdx(varnames, id)
if idx >= 0: add(result, varvalues[idx]) if idx >= 0: add(result, varvalues[idx])
else: else:
raise newException(ValueError, "unknown substitution var: " & id) raise newException(ValueError, "unknown substitution var: " & id)
else: else:
raise newException(ValueError, "unknown substitution: $" & $frmt[i]) raise newException(ValueError, "unknown substitution: $" & $frmt[i])
var start = i var start = i
while i < L: while i < L:
if frmt[i] != '$': inc(i) if frmt[i] != '$': inc(i)
else: break else: break
if i-1 >= start: add(result, substr(frmt, start, i - 1)) if i-1 >= start: add(result, substr(frmt, start, i - 1))
@ -1163,10 +1163,10 @@ proc defaultConfig*(): StringTableRef =
## pages, while this proc returns just the content for procs like ## pages, while this proc returns just the content for procs like
## ``rstToHtml`` to generate the bare minimum HTML. ## ``rstToHtml`` to generate the bare minimum HTML.
result = newStringTable(modeStyleInsensitive) result = newStringTable(modeStyleInsensitive)
template setConfigVar(key, val: expr) = template setConfigVar(key, val: expr) =
result[key] = val result[key] = val
# If you need to modify these values, it might be worth updating the template # If you need to modify these values, it might be worth updating the template
# file in config/nimdoc.cfg. # file in config/nimdoc.cfg.
setConfigVar("split.item.toc", "20") setConfigVar("split.item.toc", "20")
@ -1214,7 +1214,7 @@ $content
# ---------- forum --------------------------------------------------------- # ---------- forum ---------------------------------------------------------
proc rstToHtml*(s: string, options: TRstParseOptions, proc rstToHtml*(s: string, options: TRstParseOptions,
config: StringTableRef): string = config: StringTableRef): string =
## Converts an input rst string into embeddable HTML. ## Converts an input rst string into embeddable HTML.
## ##
@ -1236,13 +1236,13 @@ proc rstToHtml*(s: string, options: TRstParseOptions,
## output you have to create your own ``TRstGenerator`` with ## output you have to create your own ``TRstGenerator`` with
## ``initRstGenerator`` and related procs. ## ``initRstGenerator`` and related procs.
proc myFindFile(filename: string): string = proc myFindFile(filename: string): string =
# we don't find any files in online mode: # we don't find any files in online mode:
result = "" result = ""
const filen = "input" const filen = "input"
var d: TRstGenerator var d: TRstGenerator
initRstGenerator(d, outHtml, config, filen, options, myFindFile, initRstGenerator(d, outHtml, config, filen, options, myFindFile,
rst.defaultMsgHandler) rst.defaultMsgHandler)
var dummyHasToc = false var dummyHasToc = false
var rst = rstParse(s, filen, 0, 1, dummyHasToc, options) var rst = rstParse(s, filen, 0, 1, dummyHasToc, options)

View file

@ -35,9 +35,9 @@ echo ""
proc reraise_in_except = proc reraise_in_except =
try: try:
echo "BEFORE" echo "BEFORE"
raise newException(EIO, "") raise newException(IOError, "")
except EIO: except IOError:
echo "EXCEPT" echo "EXCEPT"
raise raise
@ -52,7 +52,7 @@ echo ""
proc return_in_except = proc return_in_except =
try: try:
echo "BEFORE" echo "BEFORE"
raise newException(EIO, "") raise newException(IOError, "")
except: except:
echo "EXCEPT" echo "EXCEPT"

View file

@ -4,8 +4,8 @@ discard """
exitcode: "1" exitcode: "1"
""" """
type type
ESomething = object of E_Base ESomething = object of Exception
ESomeOtherErr = object of E_Base ESomeOtherErr = object of Exception
proc genErrors(s: string) = proc genErrors(s: string) =
if s == "error!": if s == "error!":