support for .. raw:: html for the docgen

This commit is contained in:
Andreas Rumpf 2010-02-07 18:08:12 +01:00
commit 3644bc7212
4 changed files with 124 additions and 110 deletions

View file

@ -1020,7 +1020,7 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) =
res = res and not FILE_ATTRIBUTE_READONLY res = res and not FILE_ATTRIBUTE_READONLY
else: else:
res = res or FILE_ATTRIBUTE_READONLY res = res or FILE_ATTRIBUTE_READONLY
if SetFileAttributesA(filename, res) != 0'i32: if SetFileAttributesA(filename, res) == - 1'i32:
OSError() OSError()
proc inclFilePermissions*(filename: string, proc inclFilePermissions*(filename: string,

View file

@ -67,7 +67,7 @@ proc initIndexFile(d: PDoc) =
var var
h: PRstNode h: PRstNode
dummyHasToc: bool dummyHasToc: bool
if gIndexFile == "": return if gIndexFile.len == 0: return
gIndexFile = addFileExt(gIndexFile, "txt") gIndexFile = addFileExt(gIndexFile, "txt")
d.indexValFilename = changeFileExt(extractFilename(d.filename), HtmlExt) d.indexValFilename = changeFileExt(extractFilename(d.filename), HtmlExt)
if ExistsFile(gIndexFile): if ExistsFile(gIndexFile):
@ -107,14 +107,11 @@ proc getVarIdx(varnames: openarray[string], id: string): int =
proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string], proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
varvalues: openarray[PRope]): PRope = varvalues: openarray[PRope]): PRope =
var var i = 0
i, j, L, start, idx, num: int var L = len(frmt)
id: string
i = 0
L = len(frmt)
result = nil result = nil
num = 0 var num = 0
while i <= L + 0 - 1: while i < L:
if frmt[i] == '$': if frmt[i] == '$':
inc(i) # skip '$' inc(i) # skip '$'
case frmt[i] case frmt[i]
@ -126,7 +123,7 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
app(result, "$") app(result, "$")
inc(i) inc(i)
of '0'..'9': of '0'..'9':
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)
@ -135,16 +132,16 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
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':
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
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 '{':
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, "}")
@ -152,12 +149,12 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openarray[string],
inc(i) inc(i)
inc(i) # skip } inc(i) # skip }
# search for the variable: # search for the variable:
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)
else: InternalError("ropeFormatNamedVars") else: InternalError("ropeFormatNamedVars")
start = i var start = i
while (i <= L + 0 - 1): while i < L:
if (frmt[i] != '$'): inc(i) if (frmt[i] != '$'): inc(i)
else: break else: break
if i - 1 >= start: app(result, copy(frmt, start, i - 1)) if i - 1 >= start: app(result, copy(frmt, start, i - 1))
@ -240,6 +237,7 @@ proc dispA(dest: var PRope, xml, tex: string, args: openarray[PRope]) =
else: appf(dest, tex, args) else: appf(dest, tex, args)
proc renderRstToOut(d: PDoc, n: PRstNode): PRope proc renderRstToOut(d: PDoc, n: PRstNode): PRope
proc renderAux(d: PDoc, n: PRstNode, outer: string = "$1"): PRope = proc renderAux(d: PDoc, n: PRstNode, outer: string = "$1"): PRope =
result = nil result = nil
for i in countup(0, rsonsLen(n) - 1): app(result, renderRstToOut(d, n.sons[i])) for i in countup(0, rsonsLen(n) - 1): app(result, renderRstToOut(d, n.sons[i]))
@ -723,6 +721,13 @@ proc renderRstToOut(d: PDoc, n: PRstNode): PRope =
"\\href{$2}{$1}", "\\href{$2}{$1}",
[renderRstToOut(d, n.sons[0]), renderRstToOut(d, n.sons[1])]) [renderRstToOut(d, n.sons[0]), renderRstToOut(d, n.sons[1])])
of rnDirArg, rnRaw: result = renderAux(d, n) of rnDirArg, rnRaw: result = renderAux(d, n)
of rnRawHtml:
if gCmd != cmdRst2Tex:
result = toRope(addNodes(lastSon(n)))
of rnRawLatex:
if gCmd == cmdRst2Tex:
result = toRope(addNodes(lastSon(n)))
of rnImage, rnFigure: result = renderImage(d, n) of rnImage, rnFigure: result = renderImage(d, n)
of rnCodeBlock: result = renderCodeBlock(d, n) of rnCodeBlock: result = renderCodeBlock(d, n)
of rnContainer: result = renderContainer(d, n) of rnContainer: result = renderContainer(d, n)

View file

@ -1,7 +1,7 @@
# #
# #
# The Nimrod Compiler # The Nimrod Compiler
# (c) Copyright 2009 Andreas Rumpf # (c) Copyright 2010 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.
@ -43,6 +43,7 @@ type
rnCitation, # similar to footnote rnCitation, # similar to footnote
rnStandaloneHyperlink, rnHyperlink, rnRef, rnDirective, # a directive rnStandaloneHyperlink, rnHyperlink, rnRef, rnDirective, # a directive
rnDirArg, rnRaw, rnTitle, rnContents, rnImage, rnFigure, rnCodeBlock, rnDirArg, rnRaw, rnTitle, rnContents, rnImage, rnFigure, rnCodeBlock,
rnRawHtml, rnRawLatex,
rnContainer, # ``container`` directive rnContainer, # ``container`` directive
rnIndex, # index directve: rnIndex, # index directve:
# .. index:: # .. index::
@ -109,11 +110,10 @@ type
proc getThing(L: var TLexer, tok: var TToken, s: TCharSet) = proc getThing(L: var TLexer, tok: var TToken, s: TCharSet) =
var pos: int
tok.kind = tkWord tok.kind = tkWord
tok.line = L.line tok.line = L.line
tok.col = L.col tok.col = L.col
pos = L.bufpos var pos = L.bufpos
while True: while True:
add(tok.symbol, L.buf[pos]) add(tok.symbol, L.buf[pos])
inc(pos) inc(pos)
@ -122,14 +122,11 @@ proc getThing(L: var TLexer, tok: var TToken, s: TCharSet) =
L.bufpos = pos L.bufpos = pos
proc getAdornment(L: var TLexer, tok: var TToken) = proc getAdornment(L: var TLexer, tok: var TToken) =
var
pos: int
c: char
tok.kind = tkAdornment tok.kind = tkAdornment
tok.line = L.line tok.line = L.line
tok.col = L.col tok.col = L.col
pos = L.bufpos var pos = L.bufpos
c = L.buf[pos] var c = L.buf[pos]
while True: while True:
add(tok.symbol, L.buf[pos]) add(tok.symbol, L.buf[pos])
inc(pos) inc(pos)
@ -138,11 +135,9 @@ proc getAdornment(L: var TLexer, tok: var TToken) =
L.bufpos = pos L.bufpos = pos
proc getIndentAux(L: var TLexer, start: int): int = proc getIndentAux(L: var TLexer, start: int): int =
var var pos = start
buf: cstring var buf = L.buf
pos: int # skip the newline (but include it in the token!)
pos = start
buf = L.buf # skip the newline (but include it in the token!)
if buf[pos] == '\x0D': if buf[pos] == '\x0D':
if buf[pos + 1] == '\x0A': inc(pos, 2) if buf[pos + 1] == '\x0A': inc(pos, 2)
else: inc(pos) else: inc(pos)
@ -151,7 +146,6 @@ proc getIndentAux(L: var TLexer, start: int): int =
if L.skipPounds: if L.skipPounds:
if buf[pos] == '#': inc(pos) if buf[pos] == '#': inc(pos)
if buf[pos] == '#': inc(pos) if buf[pos] == '#': inc(pos)
result = 0
while True: while True:
case buf[pos] case buf[pos]
of ' ', '\x0B', '\x0C': of ' ', '\x0B', '\x0C':
@ -180,10 +174,9 @@ proc getIndent(L: var TLexer, tok: var TToken) =
tok.symbol = "\n" & repeatChar(tok.ival) tok.symbol = "\n" & repeatChar(tok.ival)
proc rawGetTok(L: var TLexer, tok: var TToken) = proc rawGetTok(L: var TLexer, tok: var TToken) =
var c: Char
tok.symbol = "" tok.symbol = ""
tok.ival = 0 tok.ival = 0
c = L.buf[L.bufpos] var c = L.buf[L.bufpos]
case c case c
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '0'..'9': of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '0'..'9':
getThing(L, tok, SymChars) getThing(L, tok, SymChars)
@ -212,10 +205,8 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
tok.col = max(tok.col - L.baseIndent, 0) tok.col = max(tok.col - L.baseIndent, 0)
proc getTokens(buffer: string, skipPounds: bool, tokens: var TTokenSeq) = proc getTokens(buffer: string, skipPounds: bool, tokens: var TTokenSeq) =
var var L: TLexer
L: TLexer var length = len(tokens)
length: int
length = len(tokens)
L.buf = cstring(buffer) L.buf = cstring(buffer)
L.line = 1 # skip UTF-8 BOM L.line = 1 # skip UTF-8 BOM
if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'): if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'):
@ -239,10 +230,7 @@ proc getTokens(buffer: string, skipPounds: bool, tokens: var TTokenSeq) =
tokens[0].kind = tkIndent tokens[0].kind = tkIndent
proc addSon(father, son: PRstNode) = proc addSon(father, son: PRstNode) =
var L: int add(father.sons, son)
L = len(father.sons)
setlen(father.sons, L + 1)
father.sons[L] = son
proc addSonIfNotNil(father, son: PRstNode) = proc addSonIfNotNil(father, son: PRstNode) =
if son != nil: addSon(father, son) if son != nil: addSon(father, son)
@ -252,13 +240,16 @@ proc rsonsLen(n: PRstNode): int =
proc newRstNode(kind: TRstNodeKind): PRstNode = proc newRstNode(kind: TRstNodeKind): PRstNode =
new(result) new(result)
result.sons = @ [] result.sons = @[]
result.kind = kind result.kind = kind
proc newRstNode(kind: TRstNodeKind, s: string): PRstNode = proc newRstNode(kind: TRstNodeKind, s: string): PRstNode =
result = newRstNode(kind) result = newRstNode(kind)
result.text = s result.text = s
proc lastSon*(n: PRstNode): PRstNode =
result = n.sons[len(n.sons)-1]
type type
TLevelMap = array[Char, int] TLevelMap = array[Char, int]
TSubstitution{.final.} = object TSubstitution{.final.} = object
@ -269,10 +260,13 @@ type
uLevel*, oLevel*: int # counters for the section levels uLevel*, oLevel*: int # counters for the section levels
subs*: seq[TSubstitution] # substitutions subs*: seq[TSubstitution] # substitutions
refs*: seq[TSubstitution] # references refs*: seq[TSubstitution] # references
underlineToLevel*: TLevelMap # Saves for each possible title adornment character its level in the underlineToLevel*: TLevelMap # Saves for each possible title adornment
# current document. This is for single underline adornments. # character its level in the
overlineToLevel*: TLevelMap # Saves for each possible title adornment character its level in the # current document.
# current document. This is for over-underline adornments. # This is for single underline adornments.
overlineToLevel*: TLevelMap # Saves for each possible title adornment
# character its level in the current document.
# This is for over-underline adornments.
PSharedState = ref TSharedState PSharedState = ref TSharedState
TRstParser = object of TObject TRstParser = object of TObject
@ -287,8 +281,8 @@ type
proc newSharedState(): PSharedState = proc newSharedState(): PSharedState =
new(result) new(result)
result.subs = @ [] result.subs = @[]
result.refs = @ [] result.refs = @[]
proc tokInfo(p: TRstParser, tok: TToken): TLineInfo = proc tokInfo(p: TRstParser, tok: TToken): TLineInfo =
result = newLineInfo(p.filename, p.line + tok.line, p.col + tok.col) result = newLineInfo(p.filename, p.line + tok.line, p.col + tok.col)
@ -303,17 +297,14 @@ proc currInd(p: TRstParser): int =
result = p.indentStack[high(p.indentStack)] result = p.indentStack[high(p.indentStack)]
proc pushInd(p: var TRstParser, ind: int) = proc pushInd(p: var TRstParser, ind: int) =
var length: int add(p.indentStack, ind)
length = len(p.indentStack)
setlen(p.indentStack, length + 1)
p.indentStack[length] = ind
proc popInd(p: var TRstParser) = proc popInd(p: var TRstParser) =
if len(p.indentStack) > 1: setlen(p.indentStack, len(p.indentStack) - 1) if len(p.indentStack) > 1: setlen(p.indentStack, len(p.indentStack) - 1)
proc initParser(p: var TRstParser, sharedState: PSharedState) = proc initParser(p: var TRstParser, sharedState: PSharedState) =
p.indentStack = @ [0] p.indentStack = @[0]
p.tok = @ [] p.tok = @[]
p.idx = 0 p.idx = 0
p.filename = "" p.filename = ""
p.hasToc = false p.hasToc = false
@ -357,14 +348,13 @@ proc rstnodeToRefnameAux(n: PRstNode, r: var string, b: var bool) =
for i in countup(0, rsonsLen(n) - 1): rstnodeToRefnameAux(n.sons[i], r, b) for i in countup(0, rsonsLen(n) - 1): rstnodeToRefnameAux(n.sons[i], r, b)
proc rstnodeToRefname(n: PRstNode): string = proc rstnodeToRefname(n: PRstNode): string =
var b: bool
result = "" result = ""
b = false var b = false
rstnodeToRefnameAux(n, result, b) rstnodeToRefnameAux(n, result, b)
proc findSub(p: var TRstParser, n: PRstNode): int = proc findSub(p: var TRstParser, n: PRstNode): int =
var key: string var key = addNodes(n)
key = addNodes(n) # the spec says: if no exact match, try one without case distinction: # the spec says: if no exact match, try one without case distinction:
for i in countup(0, high(p.s.subs)): for i in countup(0, high(p.s.subs)):
if key == p.s.subs[i].key: if key == p.s.subs[i].key:
return i return i
@ -374,8 +364,7 @@ proc findSub(p: var TRstParser, n: PRstNode): int =
result = - 1 result = - 1
proc setSub(p: var TRstParser, key: string, value: PRstNode) = proc setSub(p: var TRstParser, key: string, value: PRstNode) =
var length: int var length = len(p.s.subs)
length = len(p.s.subs)
for i in countup(0, length - 1): for i in countup(0, length - 1):
if key == p.s.subs[i].key: if key == p.s.subs[i].key:
p.s.subs[i].value = value p.s.subs[i].value = value
@ -385,8 +374,7 @@ proc setSub(p: var TRstParser, key: string, value: PRstNode) =
p.s.subs[length].value = value p.s.subs[length].value = value
proc setRef(p: var TRstParser, key: string, value: PRstNode) = proc setRef(p: var TRstParser, key: string, value: PRstNode) =
var length: int var length = len(p.s.refs)
length = len(p.s.refs)
for i in countup(0, length - 1): for i in countup(0, length - 1):
if key == p.s.refs[i].key: if key == p.s.refs[i].key:
p.s.refs[i].value = value p.s.refs[i].value = value
@ -400,32 +388,27 @@ proc findRef(p: var TRstParser, key: string): PRstNode =
for i in countup(0, high(p.s.refs)): for i in countup(0, high(p.s.refs)):
if key == p.s.refs[i].key: if key == p.s.refs[i].key:
return p.s.refs[i].value return p.s.refs[i].value
result = nil
proc cmpNodes(a, b: PRstNode): int = proc cmpNodes(a, b: PRstNode): int =
var x, y: PRstNode
assert(a.kind == rnDefItem) assert(a.kind == rnDefItem)
assert(b.kind == rnDefItem) assert(b.kind == rnDefItem)
x = a.sons[0] var x = a.sons[0]
y = b.sons[0] var y = b.sons[0]
result = cmpIgnoreStyle(addNodes(x), addNodes(y)) result = cmpIgnoreStyle(addNodes(x), addNodes(y))
proc sortIndex(a: PRstNode) = proc sortIndex(a: PRstNode) =
# we use shellsort here; fast and simple # we use shellsort here; fast and simple
var
N, j, h: int
v: PRstNode
assert(a.kind == rnDefList) assert(a.kind == rnDefList)
N = rsonsLen(a) var N = rsonsLen(a)
h = 1 var h = 1
while true: while true:
h = 3 * h + 1 h = 3 * h + 1
if h > N: break if h > N: break
while true: while true:
h = h div 3 h = h div 3
for i in countup(h, N - 1): for i in countup(h, N - 1):
v = a.sons[i] var v = a.sons[i]
j = i var j = i
while cmpNodes(a.sons[j - h], v) >= 0: while cmpNodes(a.sons[j - h], v) >= 0:
a.sons[j] = a.sons[j - h] a.sons[j] = a.sons[j - h]
j = j - h j = j - h
@ -434,7 +417,6 @@ proc sortIndex(a: PRstNode) =
if h == 1: break if h == 1: break
proc eqRstNodes(a, b: PRstNode): bool = proc eqRstNodes(a, b: PRstNode): bool =
result = false
if a.kind != b.kind: return if a.kind != b.kind: return
if a.kind == rnLeaf: if a.kind == rnLeaf:
result = a.text == b.text result = a.text == b.text
@ -445,12 +427,11 @@ proc eqRstNodes(a, b: PRstNode): bool =
result = true result = true
proc matchesHyperlink(h: PRstNode, filename: string): bool = proc matchesHyperlink(h: PRstNode, filename: string): bool =
var s: string
if h.kind == rnInner: # this may happen in broken indexes! if h.kind == rnInner: # this may happen in broken indexes!
assert(rsonsLen(h) == 1) assert(rsonsLen(h) == 1)
result = matchesHyperlink(h.sons[0], filename) result = matchesHyperlink(h.sons[0], filename)
elif h.kind == rnHyperlink: elif h.kind == rnHyperlink:
s = addNodes(h.sons[1]) var s = addNodes(h.sons[1])
if startsWith(s, filename) and (s[len(filename) + 0] == '#'): result = true if startsWith(s, filename) and (s[len(filename) + 0] == '#'): result = true
else: result = false else: result = false
else: else:
@ -521,8 +502,7 @@ proc newLeaf(p: var TRstParser): PRstNode =
result = newRstNode(rnLeaf, p.tok[p.idx].symbol) result = newRstNode(rnLeaf, p.tok[p.idx].symbol)
proc getReferenceName(p: var TRstParser, endStr: string): PRstNode = proc getReferenceName(p: var TRstParser, endStr: string): PRstNode =
var res: PRstNode var res = newRstNode(rnInner)
res = newRstNode(rnInner)
while true: while true:
case p.tok[p.idx].kind case p.tok[p.idx].kind
of tkWord, tkOther, tkWhite: of tkWord, tkOther, tkWhite:
@ -637,8 +617,7 @@ proc match(p: TRstParser, start: int, expr: string): bool =
case p.tok[j].symbol[0] case p.tok[j].symbol[0]
of 'a'..'z', 'A'..'Z': result = len(p.tok[j].symbol) == 1 of 'a'..'z', 'A'..'Z': result = len(p.tok[j].symbol) == 1
of '0'..'9': result = allCharsInSet(p.tok[j].symbol, {'0'..'9'}) of '0'..'9': result = allCharsInSet(p.tok[j].symbol, {'0'..'9'})
else: else: nil
nil
else: else:
var c = expr[i] var c = expr[i]
var length = 0 var length = 0
@ -712,10 +691,9 @@ proc isURL(p: TRstParser, i: int): bool =
(p.tok[i + 3].kind == tkWord) and (p.tok[i + 4].symbol == ".") (p.tok[i + 3].kind == tkWord) and (p.tok[i + 4].symbol == ".")
proc parseURL(p: var TRstParser, father: PRstNode) = proc parseURL(p: var TRstParser, father: PRstNode) =
var n: PRstNode
#if p.tok[p.idx].symbol[strStart] = '<' then begin #if p.tok[p.idx].symbol[strStart] = '<' then begin
if isURL(p, p.idx): if isURL(p, p.idx):
n = newRstNode(rnStandaloneHyperlink) var n = newRstNode(rnStandaloneHyperlink)
while true: while true:
case p.tok[p.idx].kind case p.tok[p.idx].kind
of tkWord, tkAdornment, tkOther: of tkWord, tkAdornment, tkOther:
@ -729,7 +707,7 @@ proc parseURL(p: var TRstParser, father: PRstNode) =
inc(p.idx) inc(p.idx)
addSon(father, n) addSon(father, n)
else: else:
n = newLeaf(p) var n = newLeaf(p)
inc(p.idx) inc(p.idx)
if p.tok[p.idx].symbol == "_": n = parsePostfix(p, n) if p.tok[p.idx].symbol == "_": n = parsePostfix(p, n)
addSon(father, n) addSon(father, n)
@ -1091,11 +1069,12 @@ proc getColumns(p: var TRstParser, cols: var TIntSeq) =
if p.tok[p.idx].kind != tkWhite: break if p.tok[p.idx].kind != tkWhite: break
inc(p.idx) inc(p.idx)
if p.tok[p.idx].kind != tkAdornment: break if p.tok[p.idx].kind != tkAdornment: break
if p.tok[p.idx].kind == tkIndent: if p.tok[p.idx].kind == tkIndent: inc(p.idx)
inc(p.idx) # last column has no limit: # last column has no limit:
cols[L - 1] = 32000 cols[L - 1] = 32000
proc parseDoc(p: var TRstParser): PRstNode proc parseDoc(p: var TRstParser): PRstNode
proc parseSimpleTable(p: var TRstParser): PRstNode = proc parseSimpleTable(p: var TRstParser): PRstNode =
var var
cols: TIntSeq cols: TIntSeq
@ -1353,16 +1332,14 @@ proc parseDoc(p: var TRstParser): PRstNode =
type type
TDirFlag = enum TDirFlag = enum
hasArg, hasOptions, argIsFile hasArg, hasOptions, argIsFile, argIsWord
TDirFlags = set[TDirFlag] TDirFlags = set[TDirFlag]
TSectionParser = proc (p: var TRstParser): PRstNode TSectionParser = proc (p: var TRstParser): PRstNode
proc parseDirective(p: var TRstParser, flags: TDirFlags, proc parseDirective(p: var TRstParser, flags: TDirFlags): PRstNode =
contentParser: TSectionParser): PRstNode =
var args, options, content: PRstNode
result = newRstNode(rnDirective) result = newRstNode(rnDirective)
args = nil var args: PRstNode = nil
options = nil var options: PRstNode = nil
if hasArg in flags: if hasArg in flags:
args = newRstNode(rnDirArg) args = newRstNode(rnDirArg)
if argIsFile in flags: if argIsFile in flags:
@ -1372,6 +1349,13 @@ proc parseDirective(p: var TRstParser, flags: TDirFlags,
addSon(args, newLeaf(p)) addSon(args, newLeaf(p))
inc(p.idx) inc(p.idx)
else: break else: break
elif argIsWord in flags:
while p.tok[p.idx].kind == tkWhite: inc(p.idx)
if p.tok[p.idx].kind == tkWord:
addSon(args, newLeaf(p))
inc(p.idx)
else:
args = nil
else: else:
parseLine(p, args) parseLine(p, args)
addSon(result, args) addSon(result, args)
@ -1380,15 +1364,27 @@ proc parseDirective(p: var TRstParser, flags: TDirFlags,
(p.tok[p.idx + 1].symbol == ":"): (p.tok[p.idx + 1].symbol == ":"):
options = parseFields(p) options = parseFields(p)
addSon(result, options) addSon(result, options)
if (not isNil(contentParser)) and (p.tok[p.idx].kind == tkIndent) and
(p.tok[p.idx].ival > currInd(p)): proc indFollows(p: TRstParser): bool =
result = p.tok[p.idx].kind == tkIndent and p.tok[p.idx].ival > currInd(p)
proc parseDirective(p: var TRstParser, flags: TDirFlags,
contentParser: TSectionParser): PRstNode =
result = parseDirective(p, flags)
if not isNil(contentParser) and indFollows(p):
pushInd(p, p.tok[p.idx].ival) pushInd(p, p.tok[p.idx].ival)
content = contentParser(p) var content = contentParser(p)
popInd(p) popInd(p)
addSon(result, content) addSon(result, content)
else: else:
addSon(result, nil) addSon(result, nil)
proc parseDirBody(p: var TRstParser, contentParser: TSectionParser): PRstNode =
if indFollows(p):
pushInd(p, p.tok[p.idx].ival)
result = contentParser(p)
popInd(p)
proc dirInclude(p: var TRstParser): PRstNode = proc dirInclude(p: var TRstParser): PRstNode =
# #
#The following options are recognized: #The following options are recognized:
@ -1464,29 +1460,40 @@ proc dirIndex(p: var TRstParser): PRstNode =
result = parseDirective(p, {}, parseSectionWrapper) result = parseDirective(p, {}, parseSectionWrapper)
result.kind = rnIndex result.kind = rnIndex
proc dirRawAux(p: var TRstParser, result: var PRstNode, kind: TRstNodeKind,
contentParser: TSectionParser) =
var filename = getFieldValue(result, "file")
if filename.len > 0:
var path = findFile(filename)
if path.len == 0:
rstMessage(p, errCannotOpenFile, filename)
else:
var f = readFile(path)
result = newRstNode(kind)
addSon(result, newRstNode(rnLeaf, f))
else:
result.kind = kind
addSon(result, parseDirBody(p, contentParser))
proc dirRaw(p: var TRstParser): PRstNode = proc dirRaw(p: var TRstParser): PRstNode =
# #
#The following options are recognized: #The following options are recognized:
# #
#file : string (newlines removed) #file : string (newlines removed)
# The local filesystem path of a raw data file to be included. # The local filesystem path of a raw data file to be included.
#url : string (whitespace removed)
# An Internet URL reference to a raw data file to be included.
#encoding : name of text encoding
# The text encoding of the external raw data (file or URL).
# Defaults to the document's encoding (if specified).
# #
result = parseDirective(p, {hasOptions}, parseSectionWrapper) # html
result.kind = rnRaw # latex
var filename = getFieldValue(result, "file") result = parseDirective(p, {hasOptions, hasArg, argIsWord})
if filename != "": if result.sons[0] != nil:
var path = findFile(filename) if cmpIgnoreCase(result.sons[0].text, "html") == 0:
if path == "": dirRawAux(p, result, rnRawHtml, parseLiteralBlock)
rstMessage(p, errCannotOpenFile, filename) elif cmpIgnoreCase(result.sons[0].text, "latex") == 0:
dirRawAux(p, result, rnRawLatex, parseLiteralBlock)
else: else:
var f = readFile(path) rstMessage(p, errInvalidDirectiveX, result.sons[0].text)
result = newRstNode(rnRaw) else:
addSon(result, newRstNode(rnLeaf, f)) dirRawAux(p, result, rnRaw, parseSectionWrapper)
proc parseDotDot(p: var TRstParser): PRstNode = proc parseDotDot(p: var TRstParser): PRstNode =
result = nil result = nil

View file

@ -18,6 +18,7 @@ Bugfixes
enities like ``&ltXX``. enities like ``&ltXX``.
- ``system.write(f: TFile, s: string)`` now works even if ``s`` contains binary - ``system.write(f: TFile, s: string)`` now works even if ``s`` contains binary
zeros. zeros.
- Fixed a bug in ``os.setFilePermissions`` for Windows.
Additions Additions
@ -39,6 +40,7 @@ Additions
- More extensive subscript operator overloading. See - More extensive subscript operator overloading. See
`subscript overloading <manual.html#subscript-overloading>`_ for further `subscript overloading <manual.html#subscript-overloading>`_ for further
information. information.
- The documentation generator supports the ``.. raw:: html`` directive.
Changes affecting backwards compatibility Changes affecting backwards compatibility