support for .. raw:: html for the docgen
This commit is contained in:
parent
5978983e97
commit
3644bc7212
4 changed files with 124 additions and 110 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
191
rod/rst.nim
191
rod/rst.nim
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ Bugfixes
|
||||||
enities like ``<XX``.
|
enities like ``<XX``.
|
||||||
- ``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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue