summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorMiran <narimiran@disroot.org>2020-11-13 10:25:00 +0100
committerGitHub <noreply@github.com>2020-11-13 10:25:00 +0100
commit8a21f94c7263f10c12c62ec2beb736ab8ce183c9 (patch)
tree58bd8da5a6854686692683fa2745db6fc23fad09
parent778914c3ca9d6c57b0158d8bf69f92b01b0bd2e1 (diff)
downloadNim-8a21f94c7263f10c12c62ec2beb736ab8ce183c9.tar.gz
refactoring: modernize rst.nim (#15953)
-rw-r--r--lib/packages/docutils/rst.nim958
1 files changed, 449 insertions, 509 deletions
diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index c04a6e07c..a72ee17b6 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -33,37 +33,22 @@ type
     mcError = "Error"
 
   MsgKind* = enum          ## the possible messages
-    meCannotOpenFile,
-    meExpected,
-    meGridTableNotImplemented,
-    meMarkdownIllformedTable,
-    meNewSectionExpected,
-    meGeneralParseError,
-    meInvalidDirective,
-    mwRedefinitionOfLabel,
-    mwUnknownSubstitution,
-    mwUnsupportedLanguage,
-    mwUnsupportedField
+    meCannotOpenFile = "cannot open '$1'",
+    meExpected = "'$1' expected",
+    meGridTableNotImplemented = "grid table is not implemented",
+    meMarkdownIllformedTable = "illformed delimiter row of a markdown table",
+    meNewSectionExpected = "new section expected",
+    meGeneralParseError = "general parse error",
+    meInvalidDirective = "invalid directive: '$1'",
+    mwRedefinitionOfLabel = "redefinition of label '$1'",
+    mwUnknownSubstitution = "unknown substitution '$1'",
+    mwUnsupportedLanguage = "language '$1' not supported",
+    mwUnsupportedField = "field '$1' not supported"
 
   MsgHandler* = proc (filename: string, line, col: int, msgKind: MsgKind,
                        arg: string) {.closure, gcsafe.} ## what to do in case of an error
   FindFileHandler* = proc (filename: string): string {.closure, gcsafe.}
 
-const
-  messages: array[MsgKind, string] = [
-    meCannotOpenFile: "cannot open '$1'",
-    meExpected: "'$1' expected",
-    meGridTableNotImplemented: "grid table is not implemented",
-    meMarkdownIllformedTable: "illformed delimiter row of a markdown table",
-    meNewSectionExpected: "new section expected",
-    meGeneralParseError: "general parse error",
-    meInvalidDirective: "invalid directive: '$1'",
-    mwRedefinitionOfLabel: "redefinition of label '$1'",
-    mwUnknownSubstitution: "unknown substitution '$1'",
-    mwUnsupportedLanguage: "language '$1' not supported",
-    mwUnsupportedField: "field '$1' not supported"
-  ]
-
 proc rstnodeToRefname*(n: PRstNode): string
 proc addNodes*(n: PRstNode): string
 proc getFieldValue*(n: PRstNode, fieldname: string): string
@@ -136,10 +121,10 @@ proc getThing(L: var Lexer, tok: var Token, s: set[char]) =
   tok.col = L.col
   var pos = L.bufpos
   while true:
-    add(tok.symbol, L.buf[pos])
-    inc(pos)
+    tok.symbol.add(L.buf[pos])
+    inc pos
     if L.buf[pos] notin s: break
-  inc(L.col, pos - L.bufpos)
+  inc L.col, pos - L.bufpos
   L.bufpos = pos
 
 proc getAdornment(L: var Lexer, tok: var Token) =
@@ -147,19 +132,19 @@ proc getAdornment(L: var Lexer, tok: var Token) =
   tok.line = L.line
   tok.col = L.col
   var pos = L.bufpos
-  var c = L.buf[pos]
+  let c = L.buf[pos]
   while true:
-    add(tok.symbol, L.buf[pos])
-    inc(pos)
+    tok.symbol.add(L.buf[pos])
+    inc pos
     if L.buf[pos] != c: break
-  inc(L.col, pos - L.bufpos)
+  inc L.col, pos - L.bufpos
   L.bufpos = pos
 
 proc getBracket(L: var Lexer, tok: var Token) =
   tok.kind = tkPunct
   tok.line = L.line
   tok.col = L.col
-  add(tok.symbol, L.buf[L.bufpos])
+  tok.symbol.add(L.buf[L.bufpos])
   inc L.col
   inc L.bufpos
 
@@ -167,26 +152,26 @@ proc getIndentAux(L: var Lexer, start: int): int =
   var pos = start
   # skip the newline (but include it in the token!)
   if L.buf[pos] == '\x0D':
-    if L.buf[pos + 1] == '\x0A': inc(pos, 2)
-    else: inc(pos)
+    if L.buf[pos + 1] == '\x0A': inc pos, 2
+    else: inc pos
   elif L.buf[pos] == '\x0A':
-    inc(pos)
+    inc pos
   if L.skipPounds:
-    if L.buf[pos] == '#': inc(pos)
-    if L.buf[pos] == '#': inc(pos)
+    if L.buf[pos] == '#': inc pos
+    if L.buf[pos] == '#': inc pos
   while true:
     case L.buf[pos]
     of ' ', '\x0B', '\x0C':
-      inc(pos)
-      inc(result)
+      inc pos
+      inc result
     of '\x09':
-      inc(pos)
+      inc pos
       result = result - (result mod 8) + 8
     else:
       break                   # EndOfFile also leaves the loop
   if L.buf[pos] == '\0':
     result = 0
-  elif (L.buf[pos] == '\x0A') or (L.buf[pos] == '\x0D'):
+  elif L.buf[pos] == '\x0A' or L.buf[pos] == '\x0D':
     # look at the next line for proper indentation:
     result = getIndentAux(L, pos)
   L.bufpos = pos              # no need to set back buf
@@ -219,7 +204,7 @@ proc rawGetTok(L: var Lexer, tok: var Token) =
      '/', ':', ';', '<', '=', '>', '?', '@', '\\', '^', '_', '`',
      '|', '~':
     getAdornment(L, tok)
-    if len(tok.symbol) <= 3: tok.kind = tkPunct
+    if tok.symbol.len <= 3: tok.kind = tkPunct
   of '(', ')', '[', ']', '{', '}':
     getBracket(L, tok)
   else:
@@ -229,39 +214,39 @@ proc rawGetTok(L: var Lexer, tok: var Token) =
       tok.kind = tkEof
     else:
       tok.kind = tkOther
-      add(tok.symbol, c)
-      inc(L.bufpos)
-      inc(L.col)
+      tok.symbol.add(c)
+      inc L.bufpos
+      inc L.col
   tok.col = max(tok.col - L.baseIndent, 0)
 
 proc getTokens(buffer: string, skipPounds: bool, tokens: var TokenSeq): int =
   var L: Lexer
-  var length = len(tokens)
+  var length = tokens.len
   L.buf = cstring(buffer)
   L.line = 0                  # skip UTF-8 BOM
-  if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'):
-    inc(L.bufpos, 3)
+  if L.buf[0] == '\xEF' and L.buf[1] == '\xBB' and L.buf[2] == '\xBF':
+    inc L.bufpos, 3
   L.skipPounds = skipPounds
   if skipPounds:
     if L.buf[L.bufpos] == '#':
-      inc(L.bufpos)
-      inc(result)
+      inc L.bufpos
+      inc result
     if L.buf[L.bufpos] == '#':
-      inc(L.bufpos)
-      inc(result)
+      inc L.bufpos
+      inc result
     L.baseIndent = 0
     while L.buf[L.bufpos] == ' ':
-      inc(L.bufpos)
-      inc(L.baseIndent)
-      inc(result)
+      inc L.bufpos
+      inc L.baseIndent
+      inc result
   while true:
-    inc(length)
+    inc length
     setLen(tokens, length)
     rawGetTok(L, tokens[length - 1])
     if tokens[length - 1].kind == tkEof: break
   if tokens[0].kind == tkWhite:
     # BUGFIX
-    tokens[0].ival = len(tokens[0].symbol)
+    tokens[0].ival = tokens[0].symbol.len
     tokens[0].kind = tkIndent
 
 type
@@ -298,6 +283,10 @@ type
 
   EParseError* = object of ValueError
 
+template currentTok(p: RstParser): Token = p.tok[p.idx]
+template prevTok(p: RstParser): Token = p.tok[p.idx - 1]
+template nextTok(p: RstParser): Token = p.tok[p.idx + 1]
+
 proc whichMsgClass*(k: MsgKind): MsgClass =
   ## returns which message class `k` belongs to.
   case ($k)[1]
@@ -309,7 +298,7 @@ proc whichMsgClass*(k: MsgKind): MsgClass =
 proc defaultMsgHandler*(filename: string, line, col: int, msgkind: MsgKind,
                         arg: string) =
   let mc = msgkind.whichMsgClass
-  let a = messages[msgkind] % arg
+  let a = $msgkind % arg
   let message = "$1($2, $3) $4: $5" % [filename, $line, $col, $mc, a]
   if mc == mcError: raise newException(EParseError, message)
   else: writeLine(stdout, message)
@@ -334,26 +323,26 @@ proc findRelativeFile(p: RstParser; filename: string): string =
     result = p.s.findFile(filename)
 
 proc rstMessage(p: RstParser, msgKind: MsgKind, arg: string) =
-  p.s.msgHandler(p.filename, p.line + p.tok[p.idx].line,
-                             p.col + p.tok[p.idx].col, msgKind, arg)
+  p.s.msgHandler(p.filename, p.line + currentTok(p).line,
+                             p.col + currentTok(p).col, msgKind, arg)
 
 proc rstMessage(p: RstParser, msgKind: MsgKind, arg: string, line, col: int) =
   p.s.msgHandler(p.filename, p.line + line,
                              p.col + col, msgKind, arg)
 
 proc rstMessage(p: RstParser, msgKind: MsgKind) =
-  p.s.msgHandler(p.filename, p.line + p.tok[p.idx].line,
-                             p.col + p.tok[p.idx].col, msgKind,
-                             p.tok[p.idx].symbol)
+  p.s.msgHandler(p.filename, p.line + currentTok(p).line,
+                             p.col + currentTok(p).col, msgKind,
+                             currentTok(p).symbol)
 
 proc currInd(p: RstParser): int =
   result = p.indentStack[high(p.indentStack)]
 
 proc pushInd(p: var RstParser, ind: int) =
-  add(p.indentStack, ind)
+  p.indentStack.add(ind)
 
 proc popInd(p: var RstParser) =
-  if len(p.indentStack) > 1: setLen(p.indentStack, len(p.indentStack) - 1)
+  if p.indentStack.len > 1: setLen(p.indentStack, p.indentStack.len - 1)
 
 proc initParser(p: var RstParser, sharedState: PSharedState) =
   p.indentStack = @[0]
@@ -367,41 +356,40 @@ proc initParser(p: var RstParser, sharedState: PSharedState) =
 
 proc addNodesAux(n: PRstNode, result: var string) =
   if n.kind == rnLeaf:
-    add(result, n.text)
+    result.add(n.text)
   else:
-    for i in countup(0, len(n) - 1): addNodesAux(n.sons[i], result)
+    for i in 0 ..< n.len: addNodesAux(n.sons[i], result)
 
 proc addNodes(n: PRstNode): string =
-  result = ""
-  addNodesAux(n, result)
+  n.addNodesAux(result)
 
 proc rstnodeToRefnameAux(n: PRstNode, r: var string, b: var bool) =
   template special(s) =
     if b:
-      add(r, '-')
+      r.add('-')
       b = false
-    add(r, s)
+    r.add(s)
 
   if n == nil: return
   if n.kind == rnLeaf:
-    for i in countup(0, len(n.text) - 1):
+    for i in 0 ..< n.text.len:
       case n.text[i]
       of '0'..'9':
         if b:
-          add(r, '-')
+          r.add('-')
           b = false
-        if len(r) == 0: add(r, 'Z')
-        add(r, n.text[i])
+        if r.len == 0: r.add('Z')
+        r.add(n.text[i])
       of 'a'..'z', '\128'..'\255':
         if b:
-          add(r, '-')
+          r.add('-')
           b = false
-        add(r, n.text[i])
+        r.add(n.text[i])
       of 'A'..'Z':
         if b:
-          add(r, '-')
+          r.add('-')
           b = false
-        add(r, chr(ord(n.text[i]) - ord('A') + ord('a')))
+        r.add(chr(ord(n.text[i]) - ord('A') + ord('a')))
       of '$': special "dollar"
       of '%': special "percent"
       of '&': special "amp"
@@ -422,12 +410,11 @@ proc rstnodeToRefnameAux(n: PRstNode, r: var string, b: var bool) =
       of '@': special "at"
       of '|': special "bar"
       else:
-        if len(r) > 0: b = true
+        if r.len > 0: b = true
   else:
-    for i in countup(0, len(n) - 1): rstnodeToRefnameAux(n.sons[i], r, b)
+    for i in 0 ..< n.len: rstnodeToRefnameAux(n.sons[i], r, b)
 
 proc rstnodeToRefname(n: PRstNode): string =
-  result = ""
   var b = false
   rstnodeToRefnameAux(n, result, b)
 
@@ -443,27 +430,22 @@ proc findSub(p: var RstParser, n: PRstNode): int =
   result = -1
 
 proc setSub(p: var RstParser, key: string, value: PRstNode) =
-  var length = len(p.s.subs)
-  for i in countup(0, length - 1):
+  var length = p.s.subs.len
+  for i in 0 ..< length:
     if key == p.s.subs[i].key:
       p.s.subs[i].value = value
       return
-  setLen(p.s.subs, length + 1)
-  p.s.subs[length].key = key
-  p.s.subs[length].value = value
+  p.s.subs.add(Substitution(key: key, value: value))
 
 proc setRef(p: var RstParser, key: string, value: PRstNode) =
-  var length = len(p.s.refs)
-  for i in countup(0, length - 1):
+  var length = p.s.refs.len
+  for i in 0 ..< length:
     if key == p.s.refs[i].key:
       if p.s.refs[i].value.addNodes != value.addNodes:
         rstMessage(p, mwRedefinitionOfLabel, key)
-
       p.s.refs[i].value = value
       return
-  setLen(p.s.refs, length + 1)
-  p.s.refs[length].key = key
-  p.s.refs[length].value = value
+  p.s.refs.add(Substitution(key: key, value: value))
 
 proc findRef(p: var RstParser, key: string): PRstNode =
   for i in countup(0, high(p.s.refs)):
@@ -471,73 +453,73 @@ proc findRef(p: var RstParser, key: string): PRstNode =
       return p.s.refs[i].value
 
 proc newLeaf(p: var RstParser): PRstNode =
-  result = newRstNode(rnLeaf, p.tok[p.idx].symbol)
+  result = newRstNode(rnLeaf, currentTok(p).symbol)
 
 proc getReferenceName(p: var RstParser, endStr: string): PRstNode =
   var res = newRstNode(rnInner)
   while true:
-    case p.tok[p.idx].kind
+    case currentTok(p).kind
     of tkWord, tkOther, tkWhite:
-      add(res, newLeaf(p))
+      res.add(newLeaf(p))
     of tkPunct:
-      if p.tok[p.idx].symbol == endStr:
-        inc(p.idx)
+      if currentTok(p).symbol == endStr:
+        inc p.idx
         break
       else:
-        add(res, newLeaf(p))
+        res.add(newLeaf(p))
     else:
       rstMessage(p, meExpected, endStr)
       break
-    inc(p.idx)
+    inc p.idx
   result = res
 
 proc untilEol(p: var RstParser): PRstNode =
   result = newRstNode(rnInner)
-  while not (p.tok[p.idx].kind in {tkIndent, tkEof}):
-    add(result, newLeaf(p))
-    inc(p.idx)
+  while currentTok(p).kind notin {tkIndent, tkEof}:
+    result.add(newLeaf(p))
+    inc p.idx
 
 proc expect(p: var RstParser, tok: string) =
-  if p.tok[p.idx].symbol == tok: inc(p.idx)
+  if currentTok(p).symbol == tok: inc p.idx
   else: rstMessage(p, meExpected, tok)
 
 proc isInlineMarkupEnd(p: RstParser, markup: string): bool =
-  result = p.tok[p.idx].symbol == markup
-  if not result:
-    return                    # Rule 3:
-  result = not (p.tok[p.idx - 1].kind in {tkIndent, tkWhite})
-  if not result:
-    return                    # Rule 4:
-  result = (p.tok[p.idx + 1].kind in {tkIndent, tkWhite, tkEof}) or
-      (markup in ["``", "`"] and p.tok[p.idx + 1].kind in {tkIndent, tkWhite, tkWord, tkEof}) or
-      (p.tok[p.idx + 1].symbol[0] in
-      {'\'', '\"', ')', ']', '}', '>', '-', '/', '\\', ':', '.', ',', ';', '!',
-       '?', '_'})
-  if not result:
-    return                    # Rule 7:
+  # rst rules: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#inline-markup-recognition-rules
+  result = currentTok(p).symbol == markup
+  if not result: return
+  # Rule 2:
+  result = prevTok(p).kind notin {tkIndent, tkWhite}
+  if not result: return
+  # Rule 7:
+  result = nextTok(p).kind in {tkIndent, tkWhite, tkEof} or
+      markup in ["``", "`"] and nextTok(p).kind in {tkIndent, tkWhite, tkWord, tkEof} or
+      nextTok(p).symbol[0] in
+      {'\'', '\"', ')', ']', '}', '>', '-', '/', '\\', ':', '.', ',', ';', '!', '?', '_'}
+  if not result: return
+  # Rule 4:
   if p.idx > 0:
-    if (markup != "``") and (p.tok[p.idx - 1].symbol == "\\"):
+    if markup != "``" and prevTok(p).symbol == "\\":
       result = false
 
 proc isInlineMarkupStart(p: RstParser, markup: string): bool =
+  # rst rules: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#inline-markup-recognition-rules
   var d: char
-  result = p.tok[p.idx].symbol == markup
-  if not result:
-    return                    # Rule 1:
-  result = (p.idx == 0) or (p.tok[p.idx - 1].kind in {tkIndent, tkWhite}) or
-      (markup in ["``", "`"] and p.tok[p.idx - 1].kind in {tkIndent, tkWhite, tkWord}) or
-      (p.tok[p.idx - 1].symbol[0] in
-      {'\'', '\"', '(', '[', '{', '<', '-', '/', ':', '_'})
-  if not result:
-    return                    # Rule 2:
-  result = not (p.tok[p.idx + 1].kind in {tkIndent, tkWhite, tkEof})
-  if not result:
-    return                    # Rule 5 & 7:
+  result = currentTok(p).symbol == markup
+  if not result: return
+  # Rule 6:
+  result = p.idx == 0 or prevTok(p).kind in {tkIndent, tkWhite} or
+      (markup in ["``", "`"] and prevTok(p).kind in {tkIndent, tkWhite, tkWord}) or
+      prevTok(p).symbol[0] in {'\'', '\"', '(', '[', '{', '<', '-', '/', ':', '_'}
+  if not result: return
+  # Rule 1:
+  result = nextTok(p).kind notin {tkIndent, tkWhite, tkEof}
+  if not result: return
+  # Rules 4 & 5:
   if p.idx > 0:
-    if p.tok[p.idx - 1].symbol == "\\":
+    if prevTok(p).symbol == "\\":
       result = false
     else:
-      var c = p.tok[p.idx - 1].symbol[0]
+      var c = prevTok(p).symbol[0]
       case c
       of '\'', '\"': d = c
       of '(': d = ')'
@@ -545,7 +527,7 @@ proc isInlineMarkupStart(p: RstParser, markup: string): bool =
       of '{': d = '}'
       of '<': d = '>'
       else: d = '\0'
-      if d != '\0': result = p.tok[p.idx + 1].symbol[0] != d
+      if d != '\0': result = nextTok(p).symbol[0] != d
 
 proc match(p: RstParser, start: int, expr: string): bool =
   # regular expressions are:
@@ -560,7 +542,7 @@ proc match(p: RstParser, start: int, expr: string): bool =
   # 'e'              tkWord or '#' (for enumeration lists)
   var i = 0
   var j = start
-  var last = len(expr) - 1
+  var last = expr.len - 1
   while i <= last:
     case expr[i]
     of 'w': result = p.tok[j].kind == tkWord
@@ -572,79 +554,79 @@ proc match(p: RstParser, start: int, expr: string): bool =
     of 'T': result = true
     of 'E': result = p.tok[j].kind in {tkEof, tkWhite, tkIndent}
     of 'e':
-      result = (p.tok[j].kind == tkWord) or (p.tok[j].symbol == "#")
+      result = p.tok[j].kind == tkWord or p.tok[j].symbol == "#"
       if result:
         case p.tok[j].symbol[0]
-        of 'a'..'z', 'A'..'Z', '#': result = len(p.tok[j].symbol) == 1
+        of 'a'..'z', 'A'..'Z', '#': result = p.tok[j].symbol.len == 1
         of '0'..'9': result = allCharsInSet(p.tok[j].symbol, {'0'..'9'})
         else: result = false
     else:
       var c = expr[i]
       var length = 0
-      while (i <= last) and (expr[i] == c):
-        inc(i)
-        inc(length)
-      dec(i)
-      result = (p.tok[j].kind in {tkPunct, tkAdornment}) and
-          (len(p.tok[j].symbol) == length) and (p.tok[j].symbol[0] == c)
+      while i <= last and expr[i] == c:
+        inc i
+        inc length
+      dec i
+      result = p.tok[j].kind in {tkPunct, tkAdornment} and
+          p.tok[j].symbol.len == length and p.tok[j].symbol[0] == c
     if not result: return
-    inc(j)
-    inc(i)
+    inc j
+    inc i
   result = true
 
 proc fixupEmbeddedRef(n, a, b: PRstNode) =
   var sep = - 1
-  for i in countdown(len(n) - 2, 0):
+  for i in countdown(n.len - 2, 0):
     if n.sons[i].text == "<":
       sep = i
       break
-  var incr = if (sep > 0) and (n.sons[sep - 1].text[0] == ' '): 2 else: 1
-  for i in countup(0, sep - incr): add(a, n.sons[i])
-  for i in countup(sep + 1, len(n) - 2): add(b, n.sons[i])
+  var incr = if sep > 0 and n.sons[sep - 1].text[0] == ' ': 2 else: 1
+  for i in countup(0, sep - incr): a.add(n.sons[i])
+  for i in countup(sep + 1, n.len - 2): b.add(n.sons[i])
 
 proc parsePostfix(p: var RstParser, n: PRstNode): PRstNode =
   result = n
   if isInlineMarkupEnd(p, "_") or isInlineMarkupEnd(p, "__"):
-    inc(p.idx)
+    inc p.idx
     if p.tok[p.idx-2].symbol == "`" and p.tok[p.idx-3].symbol == ">":
       var a = newRstNode(rnInner)
       var b = newRstNode(rnInner)
       fixupEmbeddedRef(n, a, b)
-      if len(a) == 0:
+      if a.len == 0:
         result = newRstNode(rnStandaloneHyperlink)
-        add(result, b)
+        result.add(b)
       else:
         result = newRstNode(rnHyperlink)
-        add(result, a)
-        add(result, b)
+        result.add(a)
+        result.add(b)
         setRef(p, rstnodeToRefname(a), b)
     elif n.kind == rnInterpretedText:
       n.kind = rnRef
     else:
       result = newRstNode(rnRef)
-      add(result, n)
+      result.add(n)
   elif match(p, p.idx, ":w:"):
     # a role:
-    if p.tok[p.idx + 1].symbol == "idx":
+    if nextTok(p).symbol == "idx":
       n.kind = rnIdx
-    elif p.tok[p.idx + 1].symbol == "literal":
+    elif nextTok(p).symbol == "literal":
       n.kind = rnInlineLiteral
-    elif p.tok[p.idx + 1].symbol == "strong":
+    elif nextTok(p).symbol == "strong":
       n.kind = rnStrongEmphasis
-    elif p.tok[p.idx + 1].symbol == "emphasis":
+    elif nextTok(p).symbol == "emphasis":
       n.kind = rnEmphasis
-    elif (p.tok[p.idx + 1].symbol == "sub") or
-        (p.tok[p.idx + 1].symbol == "subscript"):
+    elif nextTok(p).symbol == "sub" or
+        nextTok(p).symbol == "subscript":
       n.kind = rnSub
-    elif (p.tok[p.idx + 1].symbol == "sup") or
-        (p.tok[p.idx + 1].symbol == "supscript"):
+    elif nextTok(p).symbol == "sup" or
+        nextTok(p).symbol == "supscript":
       n.kind = rnSup
     else:
       result = newRstNode(rnGeneralRole)
       n.kind = rnInner
-      add(result, n)
-      add(result, newRstNode(rnLeaf, p.tok[p.idx + 1].symbol))
-    inc(p.idx, 3)
+      result.add(n)
+      result.add(newRstNode(rnLeaf, nextTok(p).symbol))
+    inc p.idx, 3
 
 proc matchVerbatim(p: RstParser, start: int, expr: string): int =
   result = start
@@ -656,7 +638,7 @@ proc matchVerbatim(p: RstParser, start: int, expr: string): int =
   if j < expr.len: result = 0
 
 proc parseSmiley(p: var RstParser): PRstNode =
-  if p.tok[p.idx].symbol[0] notin SmileyStartChars: return
+  if currentTok(p).symbol[0] notin SmileyStartChars: return
   for key, val in items(Smilies):
     let m = matchVerbatim(p, p.idx, key)
     if m > 0:
@@ -665,135 +647,105 @@ proc parseSmiley(p: var RstParser): PRstNode =
       result.text = val
       return
 
-when false:
-  const
-    urlChars = {'A'..'Z', 'a'..'z', '0'..'9', ':', '#', '@', '%', '/', ';',
-                 '$', '(', ')', '~', '_', '?', '+', '-', '=', '\\', '.', '&',
-                 '\128'..'\255'}
-
 proc isUrl(p: RstParser, i: int): bool =
-  result = (p.tok[i+1].symbol == ":") and (p.tok[i+2].symbol == "//") and
-    (p.tok[i+3].kind == tkWord) and
-    (p.tok[i].symbol in ["http", "https", "ftp", "telnet", "file"])
+  result = p.tok[i+1].symbol == ":" and p.tok[i+2].symbol == "//" and
+    p.tok[i+3].kind == tkWord and
+    p.tok[i].symbol in ["http", "https", "ftp", "telnet", "file"]
 
 proc parseUrl(p: var RstParser, father: PRstNode) =
-  #if p.tok[p.idx].symbol[strStart] == '<':
+  #if currentTok(p).symbol[strStart] == '<':
   if isUrl(p, p.idx):
     var n = newRstNode(rnStandaloneHyperlink)
     while true:
-      case p.tok[p.idx].kind
+      case currentTok(p).kind
       of tkWord, tkAdornment, tkOther: discard
       of tkPunct:
-        if p.tok[p.idx+1].kind notin {tkWord, tkAdornment, tkOther, tkPunct}:
+        if nextTok(p).kind notin {tkWord, tkAdornment, tkOther, tkPunct}:
           break
       else: break
-      add(n, newLeaf(p))
-      inc(p.idx)
-    add(father, n)
+      n.add(newLeaf(p))
+      inc p.idx
+    father.add(n)
   else:
     var n = newLeaf(p)
-    inc(p.idx)
-    if p.tok[p.idx].symbol == "_": n = parsePostfix(p, n)
-    add(father, n)
+    inc p.idx
+    if currentTok(p).symbol == "_": n = parsePostfix(p, n)
+    father.add(n)
 
 proc parseBackslash(p: var RstParser, father: PRstNode) =
-  assert(p.tok[p.idx].kind == tkPunct)
-  if p.tok[p.idx].symbol == "\\\\":
-    add(father, newRstNode(rnLeaf, "\\"))
-    inc(p.idx)
-  elif p.tok[p.idx].symbol == "\\":
+  assert(currentTok(p).kind == tkPunct)
+  if currentTok(p).symbol == "\\\\":
+    father.add(newRstNode(rnLeaf, "\\"))
+    inc p.idx
+  elif currentTok(p).symbol == "\\":
     # XXX: Unicode?
-    inc(p.idx)
-    if p.tok[p.idx].kind != tkWhite: add(father, newLeaf(p))
-    if p.tok[p.idx].kind != tkEof: inc(p.idx)
+    inc p.idx
+    if currentTok(p).kind != tkWhite: father.add(newLeaf(p))
+    if currentTok(p).kind != tkEof: inc p.idx
   else:
-    add(father, newLeaf(p))
-    inc(p.idx)
-
-when false:
-  proc parseAdhoc(p: var RstParser, father: PRstNode, verbatim: bool) =
-    if not verbatim and isURL(p, p.idx):
-      var n = newRstNode(rnStandaloneHyperlink)
-      while true:
-        case p.tok[p.idx].kind
-        of tkWord, tkAdornment, tkOther: nil
-        of tkPunct:
-          if p.tok[p.idx+1].kind notin {tkWord, tkAdornment, tkOther, tkPunct}:
-            break
-        else: break
-        add(n, newLeaf(p))
-        inc(p.idx)
-      add(father, n)
-    elif not verbatim and roSupportSmilies in p.sharedState.options:
-      let n = parseSmiley(p)
-      if s != nil:
-        add(father, n)
-    else:
-      var n = newLeaf(p)
-      inc(p.idx)
-      if p.tok[p.idx].symbol == "_": n = parsePostfix(p, n)
-      add(father, n)
+    father.add(newLeaf(p))
+    inc p.idx
 
 proc parseUntil(p: var RstParser, father: PRstNode, postfix: string,
                 interpretBackslash: bool) =
   let
-    line = p.tok[p.idx].line
-    col = p.tok[p.idx].col
+    line = currentTok(p).line
+    col = currentTok(p).col
   inc p.idx
   while true:
-    case p.tok[p.idx].kind
+    case currentTok(p).kind
     of tkPunct:
       if isInlineMarkupEnd(p, postfix):
-        inc(p.idx)
+        inc p.idx
         break
       elif interpretBackslash:
         parseBackslash(p, father)
       else:
-        add(father, newLeaf(p))
-        inc(p.idx)
+        father.add(newLeaf(p))
+        inc p.idx
     of tkAdornment, tkWord, tkOther:
-      add(father, newLeaf(p))
-      inc(p.idx)
+      father.add(newLeaf(p))
+      inc p.idx
     of tkIndent:
-      add(father, newRstNode(rnLeaf, " "))
-      inc(p.idx)
-      if p.tok[p.idx].kind == tkIndent:
+      father.add(newRstNode(rnLeaf, " "))
+      inc p.idx
+      if currentTok(p).kind == tkIndent:
         rstMessage(p, meExpected, postfix, line, col)
         break
     of tkWhite:
-      add(father, newRstNode(rnLeaf, " "))
-      inc(p.idx)
+      father.add(newRstNode(rnLeaf, " "))
+      inc p.idx
     else: rstMessage(p, meExpected, postfix, line, col)
 
 proc parseMarkdownCodeblock(p: var RstParser): PRstNode =
   var args = newRstNode(rnDirArg)
-  if p.tok[p.idx].kind == tkWord:
-    add(args, newLeaf(p))
-    inc(p.idx)
+  if currentTok(p).kind == tkWord:
+    args.add(newLeaf(p))
+    inc p.idx
   else:
     args = nil
   var n = newRstNode(rnLeaf, "")
   while true:
-    case p.tok[p.idx].kind
+    case currentTok(p).kind
     of tkEof:
       rstMessage(p, meExpected, "```")
       break
     of tkPunct:
-      if p.tok[p.idx].symbol == "```":
-        inc(p.idx)
+      if currentTok(p).symbol == "```":
+        inc p.idx
         break
       else:
-        add(n.text, p.tok[p.idx].symbol)
-        inc(p.idx)
+        n.text.add(currentTok(p).symbol)
+        inc p.idx
     else:
-      add(n.text, p.tok[p.idx].symbol)
-      inc(p.idx)
+      n.text.add(currentTok(p).symbol)
+      inc p.idx
   var lb = newRstNode(rnLiteralBlock)
-  add(lb, n)
+  lb.add(n)
   result = newRstNode(rnCodeBlock)
-  add(result, args)
-  add(result, PRstNode(nil))
-  add(result, lb)
+  result.add(args)
+  result.add(PRstNode(nil))
+  result.add(lb)
 
 proc parseMarkdownLink(p: var RstParser; father: PRstNode): bool =
   result = true
@@ -821,78 +773,78 @@ proc parseMarkdownLink(p: var RstParser; father: PRstNode): bool =
   result = true
 
 proc parseInline(p: var RstParser, father: PRstNode) =
-  case p.tok[p.idx].kind
+  case currentTok(p).kind
   of tkPunct:
     if isInlineMarkupStart(p, "***"):
       var n = newRstNode(rnTripleEmphasis)
       parseUntil(p, n, "***", true)
-      add(father, n)
+      father.add(n)
     elif isInlineMarkupStart(p, "**"):
       var n = newRstNode(rnStrongEmphasis)
       parseUntil(p, n, "**", true)
-      add(father, n)
+      father.add(n)
     elif isInlineMarkupStart(p, "*"):
       var n = newRstNode(rnEmphasis)
       parseUntil(p, n, "*", true)
-      add(father, n)
-    elif roSupportMarkdown in p.s.options and p.tok[p.idx].symbol == "```":
-      inc(p.idx)
-      add(father, parseMarkdownCodeblock(p))
+      father.add(n)
+    elif roSupportMarkdown in p.s.options and currentTok(p).symbol == "```":
+      inc p.idx
+      father.add(parseMarkdownCodeblock(p))
     elif isInlineMarkupStart(p, "``"):
       var n = newRstNode(rnInlineLiteral)
       parseUntil(p, n, "``", false)
-      add(father, n)
+      father.add(n)
     elif isInlineMarkupStart(p, "`"):
       var n = newRstNode(rnInterpretedText)
       parseUntil(p, n, "`", true)
       n = parsePostfix(p, n)
-      add(father, n)
+      father.add(n)
     elif isInlineMarkupStart(p, "|"):
       var n = newRstNode(rnSubstitutionReferences)
       parseUntil(p, n, "|", false)
-      add(father, n)
+      father.add(n)
     elif roSupportMarkdown in p.s.options and
-        p.tok[p.idx].symbol == "[" and p.tok[p.idx+1].symbol != "[" and
+        currentTok(p).symbol == "[" and nextTok(p).symbol != "[" and
         parseMarkdownLink(p, father):
       discard "parseMarkdownLink already processed it"
     else:
       if roSupportSmilies in p.s.options:
         let n = parseSmiley(p)
         if n != nil:
-          add(father, n)
+          father.add(n)
           return
       parseBackslash(p, father)
   of tkWord:
     if roSupportSmilies in p.s.options:
       let n = parseSmiley(p)
       if n != nil:
-        add(father, n)
+        father.add(n)
         return
     parseUrl(p, father)
   of tkAdornment, tkOther, tkWhite:
     if roSupportSmilies in p.s.options:
       let n = parseSmiley(p)
       if n != nil:
-        add(father, n)
+        father.add(n)
         return
-    add(father, newLeaf(p))
-    inc(p.idx)
+    father.add(newLeaf(p))
+    inc p.idx
   else: discard
 
 proc getDirective(p: var RstParser): string =
-  if p.tok[p.idx].kind == tkWhite and p.tok[p.idx+1].kind == tkWord:
+  if currentTok(p).kind == tkWhite and nextTok(p).kind == tkWord:
     var j = p.idx
-    inc(p.idx)
-    result = p.tok[p.idx].symbol
-    inc(p.idx)
-    while p.tok[p.idx].kind in {tkWord, tkPunct, tkAdornment, tkOther}:
-      if p.tok[p.idx].symbol == "::": break
-      add(result, p.tok[p.idx].symbol)
-      inc(p.idx)
-    if p.tok[p.idx].kind == tkWhite: inc(p.idx)
-    if p.tok[p.idx].symbol == "::":
-      inc(p.idx)
-      if (p.tok[p.idx].kind == tkWhite): inc(p.idx)
+    inc p.idx
+    result = currentTok(p).symbol
+    inc p.idx
+    while currentTok(p).kind in {tkWord, tkPunct, tkAdornment, tkOther}:
+      if currentTok(p).symbol == "::": break
+      result.add(currentTok(p).symbol)
+      inc p.idx
+    if currentTok(p).kind == tkWhite: inc p.idx
+    if currentTok(p).symbol == "::":
+      inc p.idx
+      if currentTok(p).kind == tkWhite: inc p.idx
     else:
       p.idx = j               # set back
       result = ""             # error
@@ -900,23 +852,23 @@ proc getDirective(p: var RstParser): string =
     result = ""
 
 proc parseComment(p: var RstParser): PRstNode =
-  case p.tok[p.idx].kind
+  case currentTok(p).kind
   of tkIndent, tkEof:
-    if p.tok[p.idx].kind != tkEof and p.tok[p.idx + 1].kind == tkIndent:
-      inc(p.idx)              # empty comment
+    if currentTok(p).kind != tkEof and nextTok(p).kind == tkIndent:
+      inc p.idx              # empty comment
     else:
-      var indent = p.tok[p.idx].ival
+      var indent = currentTok(p).ival
       while true:
-        case p.tok[p.idx].kind
+        case currentTok(p).kind
         of tkEof:
           break
         of tkIndent:
-          if (p.tok[p.idx].ival < indent): break
+          if currentTok(p).ival < indent: break
         else:
           discard
-        inc(p.idx)
+        inc p.idx
   else:
-    while p.tok[p.idx].kind notin {tkIndent, tkEof}: inc(p.idx)
+    while currentTok(p).kind notin {tkIndent, tkEof}: inc p.idx
   result = nil
 
 type
@@ -936,13 +888,13 @@ proc getDirKind(s: string): DirKind =
 
 proc parseLine(p: var RstParser, father: PRstNode) =
   while true:
-    case p.tok[p.idx].kind
+    case currentTok(p).kind
     of tkWhite, tkWord, tkOther, tkPunct: parseInline(p, father)
     else: break
 
 proc parseUntilNewline(p: var RstParser, father: PRstNode) =
   while true:
-    case p.tok[p.idx].kind
+    case currentTok(p).kind
     of tkWhite, tkWord, tkAdornment, tkOther, tkPunct: parseInline(p, father)
     of tkEof, tkIndent: break
 
@@ -952,19 +904,19 @@ proc parseField(p: var RstParser): PRstNode =
   ##
   ## rnField nodes have two children nodes, a rnFieldName and a rnFieldBody.
   result = newRstNode(rnField)
-  var col = p.tok[p.idx].col
+  var col = currentTok(p).col
   var fieldname = newRstNode(rnFieldName)
   parseUntil(p, fieldname, ":", false)
   var fieldbody = newRstNode(rnFieldBody)
-  if p.tok[p.idx].kind != tkIndent: parseLine(p, fieldbody)
-  if p.tok[p.idx].kind == tkIndent:
-    var indent = p.tok[p.idx].ival
+  if currentTok(p).kind != tkIndent: parseLine(p, fieldbody)
+  if currentTok(p).kind == tkIndent:
+    var indent = currentTok(p).ival
     if indent > col:
       pushInd(p, indent)
       parseSection(p, fieldbody)
       popInd(p)
-  add(result, fieldname)
-  add(result, fieldbody)
+  result.add(fieldname)
+  result.add(fieldbody)
 
 proc parseFields(p: var RstParser): PRstNode =
   ## Parses fields for a section or directive block.
@@ -973,16 +925,16 @@ proc parseFields(p: var RstParser): PRstNode =
   ## otherwise it will return a node of rnFieldList type with children.
   result = nil
   var atStart = p.idx == 0 and p.tok[0].symbol == ":"
-  if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx + 1].symbol == ":") or
+  if currentTok(p).kind == tkIndent and nextTok(p).symbol == ":" or
       atStart:
-    var col = if atStart: p.tok[p.idx].col else: p.tok[p.idx].ival
+    var col = if atStart: currentTok(p).col else: currentTok(p).ival
     result = newRstNode(rnFieldList)
-    if not atStart: inc(p.idx)
+    if not atStart: inc p.idx
     while true:
-      add(result, parseField(p))
-      if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
-          (p.tok[p.idx + 1].symbol == ":"):
-        inc(p.idx)
+      result.add(parseField(p))
+      if currentTok(p).kind == tkIndent and currentTok(p).ival == col and
+          nextTok(p).symbol == ":":
+        inc p.idx
       else:
         break
 
@@ -999,13 +951,12 @@ proc getFieldValue*(n: PRstNode): string =
   result = addNodes(n.sons[1]).strip
 
 proc getFieldValue(n: PRstNode, fieldname: string): string =
-  result = ""
   if n.sons[1] == nil: return
-  if (n.sons[1].kind != rnFieldList):
+  if n.sons[1].kind != rnFieldList:
     #InternalError("getFieldValue (2): " & $n.sons[1].kind)
     # We don't like internal errors here anymore as that would break the forum!
     return
-  for i in countup(0, len(n.sons[1]) - 1):
+  for i in 0 ..< n.sons[1].len:
     var f = n.sons[1].sons[i]
     if cmpIgnoreStyle(addNodes(f.sons[0]), fieldname) == 0:
       result = addNodes(f.sons[1])
@@ -1020,32 +971,32 @@ proc parseDotDot(p: var RstParser): PRstNode {.gcsafe.}
 proc parseLiteralBlock(p: var RstParser): PRstNode =
   result = newRstNode(rnLiteralBlock)
   var n = newRstNode(rnLeaf, "")
-  if p.tok[p.idx].kind == tkIndent:
-    var indent = p.tok[p.idx].ival
-    inc(p.idx)
+  if currentTok(p).kind == tkIndent:
+    var indent = currentTok(p).ival
+    inc p.idx
     while true:
-      case p.tok[p.idx].kind
+      case currentTok(p).kind
       of tkEof:
         break
       of tkIndent:
-        if (p.tok[p.idx].ival < indent):
+        if currentTok(p).ival < indent:
           break
         else:
-          add(n.text, "\n")
-          add(n.text, spaces(p.tok[p.idx].ival - indent))
-          inc(p.idx)
+          n.text.add("\n")
+          n.text.add(spaces(currentTok(p).ival - indent))
+          inc p.idx
       else:
-        add(n.text, p.tok[p.idx].symbol)
-        inc(p.idx)
+        n.text.add(currentTok(p).symbol)
+        inc p.idx
   else:
-    while not (p.tok[p.idx].kind in {tkIndent, tkEof}):
-      add(n.text, p.tok[p.idx].symbol)
-      inc(p.idx)
-  add(result, n)
+    while currentTok(p).kind notin {tkIndent, tkEof}:
+      n.text.add(currentTok(p).symbol)
+      inc p.idx
+  result.add(n)
 
 proc getLevel(map: var LevelMap, lvl: var int, c: char): int =
   if map[c] == 0:
-    inc(lvl)
+    inc lvl
     map[c] = lvl
   result = map[c]
 
@@ -1056,26 +1007,26 @@ proc tokenAfterNewline(p: RstParser): int =
     of tkEof:
       break
     of tkIndent:
-      inc(result)
+      inc result
       break
-    else: inc(result)
+    else: inc result
 
 proc isLineBlock(p: RstParser): bool =
   var j = tokenAfterNewline(p)
-  result = (p.tok[p.idx].col == p.tok[j].col) and (p.tok[j].symbol == "|") or
-      (p.tok[j].col > p.tok[p.idx].col)
+  result = currentTok(p).col == p.tok[j].col and p.tok[j].symbol == "|" or
+      p.tok[j].col > currentTok(p).col
 
 proc predNL(p: RstParser): bool =
   result = true
   if p.idx > 0:
-    result = p.tok[p.idx-1].kind == tkIndent and
-        p.tok[p.idx-1].ival == currInd(p)
+    result = prevTok(p).kind == tkIndent and
+        prevTok(p).ival == currInd(p)
 
 proc isDefList(p: RstParser): bool =
   var j = tokenAfterNewline(p)
-  result = (p.tok[p.idx].col < p.tok[j].col) and
-      (p.tok[j].kind in {tkWord, tkOther, tkPunct}) and
-      (p.tok[j - 2].symbol != "::")
+  result = currentTok(p).col < p.tok[j].col and
+      p.tok[j].kind in {tkWord, tkOther, tkPunct} and
+      p.tok[j - 2].symbol != "::"
 
 proc isOptionList(p: RstParser): bool =
   result = match(p, p.idx, "-w") or match(p, p.idx, "--w") or
@@ -1089,7 +1040,7 @@ proc isMarkdownHeadlinePattern(s: string): bool =
 
 proc isMarkdownHeadline(p: RstParser): bool =
   if roSupportMarkdown in p.s.options:
-    if isMarkdownHeadlinePattern(p.tok[p.idx].symbol) and p.tok[p.idx+1].kind == tkWhite:
+    if isMarkdownHeadlinePattern(currentTok(p).symbol) and nextTok(p).kind == tkWhite:
       if p.tok[p.idx+2].kind in {tkWord, tkOther, tkPunct}:
         result = true
 
@@ -1101,7 +1052,7 @@ proc findPipe(p: RstParser, start: int): bool =
     inc i
 
 proc whichSection(p: RstParser): RstNodeKind =
-  case p.tok[p.idx].kind
+  case currentTok(p).kind
   of tkAdornment:
     if match(p, p.idx + 1, "ii"): result = rnTransition
     elif match(p, p.idx + 1, " a"): result = rnTable
@@ -1116,22 +1067,21 @@ proc whichSection(p: RstParser): RstNodeKind =
     elif roSupportMarkdown in p.s.options and predNL(p) and
         match(p, p.idx, "| w") and findPipe(p, p.idx+3):
       result = rnMarkdownTable
-    elif p.tok[p.idx].symbol == "```":
+    elif currentTok(p).symbol == "```":
       result = rnCodeBlock
     elif match(p, tokenAfterNewline(p), "ai"):
       result = rnHeadline
-    elif p.tok[p.idx].symbol == "::":
+    elif currentTok(p).symbol == "::":
       result = rnLiteralBlock
     elif predNL(p) and
-        ((p.tok[p.idx].symbol == "+") or (p.tok[p.idx].symbol == "*") or
-        (p.tok[p.idx].symbol == "-")) and (p.tok[p.idx + 1].kind == tkWhite):
+        currentTok(p).symbol in ["+", "*", "-"] and nextTok(p).kind == tkWhite:
       result = rnBulletList
-    elif (p.tok[p.idx].symbol == "|") and isLineBlock(p):
+    elif currentTok(p).symbol == "|" and isLineBlock(p):
       result = rnLineBlock
-    elif (p.tok[p.idx].symbol == "..") and predNL(p):
+    elif currentTok(p).symbol == ".." and predNL(p):
       result = rnDirective
     elif match(p, p.idx, ":w:") and predNL(p):
-      # (p.tok[p.idx].symbol == ":")
+      # (currentTok(p).symbol == ":")
       result = rnFieldList
     elif match(p, p.idx, "(e) ") or match(p, p.idx, "e. "):
       result = rnEnumList
@@ -1153,47 +1103,46 @@ proc whichSection(p: RstParser): RstNodeKind =
 
 proc parseLineBlock(p: var RstParser): PRstNode =
   result = nil
-  if p.tok[p.idx + 1].kind == tkWhite:
-    var col = p.tok[p.idx].col
+  if nextTok(p).kind == tkWhite:
+    var col = currentTok(p).col
     result = newRstNode(rnLineBlock)
     pushInd(p, p.tok[p.idx + 2].col)
-    inc(p.idx, 2)
+    inc p.idx, 2
     while true:
       var item = newRstNode(rnLineBlockItem)
       parseSection(p, item)
-      add(result, item)
-      if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
-          (p.tok[p.idx + 1].symbol == "|") and
-          (p.tok[p.idx + 2].kind == tkWhite):
-        inc(p.idx, 3)
+      result.add(item)
+      if currentTok(p).kind == tkIndent and currentTok(p).ival == col and
+          nextTok(p).symbol == "|" and p.tok[p.idx + 2].kind == tkWhite:
+        inc p.idx, 3
       else:
         break
     popInd(p)
 
 proc parseParagraph(p: var RstParser, result: PRstNode) =
   while true:
-    case p.tok[p.idx].kind
+    case currentTok(p).kind
     of tkIndent:
-      if p.tok[p.idx + 1].kind == tkIndent:
-        inc(p.idx)
+      if nextTok(p).kind == tkIndent:
+        inc p.idx
         break
-      elif (p.tok[p.idx].ival == currInd(p)):
-        inc(p.idx)
+      elif currentTok(p).ival == currInd(p):
+        inc p.idx
         case whichSection(p)
         of rnParagraph, rnLeaf, rnHeadline, rnOverline, rnDirective:
-          add(result, newRstNode(rnLeaf, " "))
+          result.add(newRstNode(rnLeaf, " "))
         of rnLineBlock:
-          addIfNotNil(result, parseLineBlock(p))
+          result.addIfNotNil(parseLineBlock(p))
         else: break
       else:
         break
     of tkPunct:
-      if (p.tok[p.idx].symbol == "::") and
-          (p.tok[p.idx + 1].kind == tkIndent) and
-          (currInd(p) < p.tok[p.idx + 1].ival):
-        add(result, newRstNode(rnLeaf, ":"))
-        inc(p.idx)            # skip '::'
-        add(result, parseLiteralBlock(p))
+      if currentTok(p).symbol == "::" and
+          nextTok(p).kind == tkIndent and
+          currInd(p) < nextTok(p).ival:
+        result.add(newRstNode(rnLeaf, ":"))
+        inc p.idx            # skip '::'
+        result.add(parseLiteralBlock(p))
         break
       else:
         parseInline(p, result)
@@ -1204,16 +1153,16 @@ proc parseParagraph(p: var RstParser, result: PRstNode) =
 proc parseHeadline(p: var RstParser): PRstNode =
   result = newRstNode(rnHeadline)
   if isMarkdownHeadline(p):
-    result.level = p.tok[p.idx].symbol.len
-    assert(p.tok[p.idx+1].kind == tkWhite)
+    result.level = currentTok(p).symbol.len
+    assert(nextTok(p).kind == tkWhite)
     inc p.idx, 2
     parseUntilNewline(p, result)
   else:
     parseUntilNewline(p, result)
-    assert(p.tok[p.idx].kind == tkIndent)
-    assert(p.tok[p.idx + 1].kind == tkAdornment)
-    var c = p.tok[p.idx + 1].symbol[0]
-    inc(p.idx, 2)
+    assert(currentTok(p).kind == tkIndent)
+    assert(nextTok(p).kind == tkAdornment)
+    var c = nextTok(p).symbol[0]
+    inc p.idx, 2
     result.level = getLevel(p.s.underlineToLevel, p.s.uLevel, c)
 
 type
@@ -1223,20 +1172,20 @@ type
   ColSeq = seq[ColumnLimits]
 
 proc tokEnd(p: RstParser): int =
-  result = p.tok[p.idx].col + len(p.tok[p.idx].symbol) - 1
+  result = currentTok(p).col + currentTok(p).symbol.len - 1
 
 proc getColumns(p: var RstParser, cols: var IntSeq) =
   var L = 0
   while true:
-    inc(L)
+    inc L
     setLen(cols, L)
     cols[L - 1] = tokEnd(p)
-    assert(p.tok[p.idx].kind == tkAdornment)
-    inc(p.idx)
-    if p.tok[p.idx].kind != tkWhite: break
-    inc(p.idx)
-    if p.tok[p.idx].kind != tkAdornment: break
-  if p.tok[p.idx].kind == tkIndent: inc(p.idx)
+    assert(currentTok(p).kind == tkAdornment)
+    inc p.idx
+    if currentTok(p).kind != tkWhite: break
+    inc p.idx
+    if currentTok(p).kind != tkAdornment: break
+  if currentTok(p).kind == tkIndent: inc p.idx
   # last column has no limit:
   cols[L - 1] = 32000
 
@@ -1254,35 +1203,35 @@ proc parseSimpleTable(p: var RstParser): PRstNode =
   cols = @[]
   row = @[]
   a = nil
-  c = p.tok[p.idx].symbol[0]
+  c = currentTok(p).symbol[0]
   while true:
-    if p.tok[p.idx].kind == tkAdornment:
+    if currentTok(p).kind == tkAdornment:
       last = tokenAfterNewline(p)
       if p.tok[last].kind in {tkEof, tkIndent}:
         # skip last adornment line:
         p.idx = last
         break
       getColumns(p, cols)
-      setLen(row, len(cols))
+      setLen(row, cols.len)
       if a != nil:
-        for j in 0..len(a)-1: a.sons[j].kind = rnTableHeaderCell
-    if p.tok[p.idx].kind == tkEof: break
+        for j in 0 ..< a.len: a.sons[j].kind = rnTableHeaderCell
+    if currentTok(p).kind == tkEof: break
     for j in countup(0, high(row)): row[j] = ""
     # the following while loop iterates over the lines a single cell may span:
-    line = p.tok[p.idx].line
+    line = currentTok(p).line
     while true:
       i = 0
-      while not (p.tok[p.idx].kind in {tkIndent, tkEof}):
-        if (tokEnd(p) <= cols[i]):
-          add(row[i], p.tok[p.idx].symbol)
-          inc(p.idx)
+      while currentTok(p).kind notin {tkIndent, tkEof}:
+        if tokEnd(p) <= cols[i]:
+          row[i].add(currentTok(p).symbol)
+          inc p.idx
         else:
-          if p.tok[p.idx].kind == tkWhite: inc(p.idx)
-          inc(i)
-      if p.tok[p.idx].kind == tkIndent: inc(p.idx)
+          if currentTok(p).kind == tkWhite: inc p.idx
+          inc i
+      if currentTok(p).kind == tkIndent: inc p.idx
       if tokEnd(p) <= cols[0]: break
-      if p.tok[p.idx].kind in {tkEof, tkAdornment}: break
-      for j in countup(1, high(row)): add(row[j], '\x0A')
+      if currentTok(p).kind in {tkEof, tkAdornment}: break
+      for j in countup(1, high(row)): row[j].add('\x0A')
     a = newRstNode(rnTableRow)
     for j in countup(0, high(row)):
       initParser(q, p.s)
@@ -1291,21 +1240,21 @@ proc parseSimpleTable(p: var RstParser): PRstNode =
       q.filename = p.filename
       q.col += getTokens(row[j], false, q.tok)
       b = newRstNode(rnTableDataCell)
-      add(b, parseDoc(q))
-      add(a, b)
-    add(result, a)
+      b.add(parseDoc(q))
+      a.add(b)
+    result.add(a)
 
 proc readTableRow(p: var RstParser): ColSeq =
-  if p.tok[p.idx].symbol == "|": inc p.idx
-  while p.tok[p.idx].kind notin {tkIndent, tkEof}:
+  if currentTok(p).symbol == "|": inc p.idx
+  while currentTok(p).kind notin {tkIndent, tkEof}:
     var limits: ColumnLimits
     limits.first = p.idx
-    while p.tok[p.idx].kind notin {tkIndent, tkEof}:
-      if p.tok[p.idx].symbol == "|" and p.tok[p.idx-1].symbol != "\\": break
+    while currentTok(p).kind notin {tkIndent, tkEof}:
+      if currentTok(p).symbol == "|" and prevTok(p).symbol != "\\": break
       inc p.idx
     limits.last = p.idx
     result.add(limits)
-    if p.tok[p.idx].kind in {tkIndent, tkEof}: break
+    if currentTok(p).kind in {tkIndent, tkEof}: break
     inc p.idx
   p.idx = tokenAfterNewline(p)
 
@@ -1340,7 +1289,7 @@ proc parseMarkdownTable(p: var RstParser): PRstNode =
       b = newRstNode(cellKind)
       initParser(q, p.s)
       q.col = p.col
-      q.line = p.tok[p.idx].line - 1
+      q.line = currentTok(p).line - 1
       q.filename = p.filename
       q.col += getTokens(getColContents(p, row[j]), false, q.tok)
       b.add(parseDoc(q))
@@ -1349,50 +1298,50 @@ proc parseMarkdownTable(p: var RstParser): PRstNode =
 
   parseRow(p, rnTableHeaderCell, result)
   if not isValidDelimiterRow(p, colNum): rstMessage(p, meMarkdownIllformedTable)
-  while predNL(p) and p.tok[p.idx].symbol == "|":
+  while predNL(p) and currentTok(p).symbol == "|":
     parseRow(p, rnTableDataCell, result)
 
 proc parseTransition(p: var RstParser): PRstNode =
   result = newRstNode(rnTransition)
-  inc(p.idx)
-  if p.tok[p.idx].kind == tkIndent: inc(p.idx)
-  if p.tok[p.idx].kind == tkIndent: inc(p.idx)
+  inc p.idx
+  if currentTok(p).kind == tkIndent: inc p.idx
+  if currentTok(p).kind == tkIndent: inc p.idx
 
 proc parseOverline(p: var RstParser): PRstNode =
-  var c = p.tok[p.idx].symbol[0]
-  inc(p.idx, 2)
+  var c = currentTok(p).symbol[0]
+  inc p.idx, 2
   result = newRstNode(rnOverline)
   while true:
     parseUntilNewline(p, result)
-    if p.tok[p.idx].kind == tkIndent:
-      inc(p.idx)
-      if p.tok[p.idx - 1].ival > currInd(p):
-        add(result, newRstNode(rnLeaf, " "))
+    if currentTok(p).kind == tkIndent:
+      inc p.idx
+      if prevTok(p).ival > currInd(p):
+        result.add(newRstNode(rnLeaf, " "))
       else:
         break
     else:
       break
   result.level = getLevel(p.s.overlineToLevel, p.s.oLevel, c)
-  if p.tok[p.idx].kind == tkAdornment:
-    inc(p.idx)                # XXX: check?
-    if p.tok[p.idx].kind == tkIndent: inc(p.idx)
+  if currentTok(p).kind == tkAdornment:
+    inc p.idx                # XXX: check?
+    if currentTok(p).kind == tkIndent: inc p.idx
 
 proc parseBulletList(p: var RstParser): PRstNode =
   result = nil
-  if p.tok[p.idx + 1].kind == tkWhite:
-    var bullet = p.tok[p.idx].symbol
-    var col = p.tok[p.idx].col
+  if nextTok(p).kind == tkWhite:
+    var bullet = currentTok(p).symbol
+    var col = currentTok(p).col
     result = newRstNode(rnBulletList)
     pushInd(p, p.tok[p.idx + 2].col)
-    inc(p.idx, 2)
+    inc p.idx, 2
     while true:
       var item = newRstNode(rnBulletItem)
       parseSection(p, item)
-      add(result, item)
-      if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
-          (p.tok[p.idx + 1].symbol == bullet) and
-          (p.tok[p.idx + 2].kind == tkWhite):
-        inc(p.idx, 3)
+      result.add(item)
+      if currentTok(p).kind == tkIndent and currentTok(p).ival == col and
+          nextTok(p).symbol == bullet and
+          p.tok[p.idx + 2].kind == tkWhite:
+        inc p.idx, 3
       else:
         break
     popInd(p)
@@ -1404,63 +1353,62 @@ proc parseOptionList(p: var RstParser): PRstNode =
       var a = newRstNode(rnOptionGroup)
       var b = newRstNode(rnDescription)
       var c = newRstNode(rnOptionListItem)
-      if match(p, p.idx, "//w"): inc(p.idx)
-      while not (p.tok[p.idx].kind in {tkIndent, tkEof}):
-        if (p.tok[p.idx].kind == tkWhite) and (len(p.tok[p.idx].symbol) > 1):
-          inc(p.idx)
+      if match(p, p.idx, "//w"): inc p.idx
+      while currentTok(p).kind notin {tkIndent, tkEof}:
+        if currentTok(p).kind == tkWhite and currentTok(p).symbol.len > 1:
+          inc p.idx
           break
-        add(a, newLeaf(p))
-        inc(p.idx)
+        a.add(newLeaf(p))
+        inc p.idx
       var j = tokenAfterNewline(p)
-      if (j > 0) and (p.tok[j - 1].kind == tkIndent) and
-          (p.tok[j - 1].ival > currInd(p)):
+      if j > 0 and p.tok[j - 1].kind == tkIndent and p.tok[j - 1].ival > currInd(p):
         pushInd(p, p.tok[j - 1].ival)
         parseSection(p, b)
         popInd(p)
       else:
         parseLine(p, b)
-      if (p.tok[p.idx].kind == tkIndent): inc(p.idx)
-      add(c, a)
-      add(c, b)
-      add(result, c)
+      if currentTok(p).kind == tkIndent: inc p.idx
+      c.add(a)
+      c.add(b)
+      result.add(c)
     else:
       break
 
 proc parseDefinitionList(p: var RstParser): PRstNode =
   result = nil
   var j = tokenAfterNewline(p) - 1
-  if (j >= 1) and (p.tok[j].kind == tkIndent) and
-      (p.tok[j].ival > currInd(p)) and (p.tok[j - 1].symbol != "::"):
-    var col = p.tok[p.idx].col
+  if j >= 1 and p.tok[j].kind == tkIndent and
+      p.tok[j].ival > currInd(p) and p.tok[j - 1].symbol != "::":
+    var col = currentTok(p).col
     result = newRstNode(rnDefList)
     while true:
       j = p.idx
       var a = newRstNode(rnDefName)
       parseLine(p, a)
-      if (p.tok[p.idx].kind == tkIndent) and
-          (p.tok[p.idx].ival > currInd(p)) and
-          (p.tok[p.idx + 1].symbol != "::") and
-          not (p.tok[p.idx + 1].kind in {tkIndent, tkEof}):
-        pushInd(p, p.tok[p.idx].ival)
+      if currentTok(p).kind == tkIndent and
+          currentTok(p).ival > currInd(p) and
+          nextTok(p).symbol != "::" and
+          nextTok(p).kind notin {tkIndent, tkEof}:
+        pushInd(p, currentTok(p).ival)
         var b = newRstNode(rnDefBody)
         parseSection(p, b)
         var c = newRstNode(rnDefItem)
-        add(c, a)
-        add(c, b)
-        add(result, c)
+        c.add(a)
+        c.add(b)
+        result.add(c)
         popInd(p)
       else:
         p.idx = j
         break
-      if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col):
-        inc(p.idx)
+      if currentTok(p).kind == tkIndent and currentTok(p).ival == col:
+        inc p.idx
         j = tokenAfterNewline(p) - 1
         if j >= 1 and p.tok[j].kind == tkIndent and p.tok[j].ival > col and
             p.tok[j-1].symbol != "::" and p.tok[j+1].kind != tkIndent:
           discard
         else:
           break
-    if len(result) == 0: result = nil
+    if result.len == 0: result = nil
 
 proc parseEnumList(p: var RstParser): PRstNode =
   const
@@ -1470,54 +1418,54 @@ proc parseEnumList(p: var RstParser): PRstNode =
   var w = 0
   while w <= 2:
     if match(p, p.idx, wildcards[w]): break
-    inc(w)
+    inc w
   if w <= 2:
-    var col = p.tok[p.idx].col
+    var col = currentTok(p).col
     result = newRstNode(rnEnumList)
-    inc(p.idx, wildpos[w] + 3)
+    inc p.idx, wildpos[w] + 3
     var j = tokenAfterNewline(p)
-    if (p.tok[j].col == p.tok[p.idx].col) or match(p, j, wildcards[w]):
-      pushInd(p, p.tok[p.idx].col)
+    if p.tok[j].col == currentTok(p).col or match(p, j, wildcards[w]):
+      pushInd(p, currentTok(p).col)
       while true:
         var item = newRstNode(rnEnumItem)
         parseSection(p, item)
-        add(result, item)
-        if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival == col) and
+        result.add(item)
+        if currentTok(p).kind == tkIndent and currentTok(p).ival == col and
             match(p, p.idx + 1, wildcards[w]):
-          inc(p.idx, wildpos[w] + 4)
+          inc p.idx, wildpos[w] + 4
         else:
           break
       popInd(p)
     else:
-      dec(p.idx, wildpos[w] + 3)
+      dec p.idx, wildpos[w] + 3
       result = nil
 
 proc sonKind(father: PRstNode, i: int): RstNodeKind =
   result = rnLeaf
-  if i < len(father): result = father.sons[i].kind
+  if i < father.len: result = father.sons[i].kind
 
 proc parseSection(p: var RstParser, result: PRstNode) =
   while true:
     var leave = false
     assert(p.idx >= 0)
-    while p.tok[p.idx].kind == tkIndent:
-      if currInd(p) == p.tok[p.idx].ival:
-        inc(p.idx)
-      elif p.tok[p.idx].ival > currInd(p):
-        pushInd(p, p.tok[p.idx].ival)
+    while currentTok(p).kind == tkIndent:
+      if currInd(p) == currentTok(p).ival:
+        inc p.idx
+      elif currentTok(p).ival > currInd(p):
+        pushInd(p, currentTok(p).ival)
         var a = newRstNode(rnBlockQuote)
         parseSection(p, a)
-        add(result, a)
+        result.add(a)
         popInd(p)
       else:
         leave = true
         break
-    if leave or p.tok[p.idx].kind == tkEof: break
+    if leave or currentTok(p).kind == tkEof: break
     var a: PRstNode = nil
     var k = whichSection(p)
     case k
     of rnLiteralBlock:
-      inc(p.idx)              # skip '::'
+      inc p.idx              # skip '::'
       a = parseLiteralBlock(p)
     of rnBulletList: a = parseBulletList(p)
     of rnLineBlock: a = parseLineBlock(p)
@@ -1527,7 +1475,7 @@ proc parseSection(p: var RstParser, result: PRstNode) =
     of rnParagraph: discard
     of rnDefList: a = parseDefinitionList(p)
     of rnFieldList:
-      if p.idx > 0: dec(p.idx)
+      if p.idx > 0: dec p.idx
       a = parseFields(p)
     of rnTransition: a = parseTransition(p)
     of rnHeadline: a = parseHeadline(p)
@@ -1541,14 +1489,14 @@ proc parseSection(p: var RstParser, result: PRstNode) =
     if a == nil and k != rnDirective:
       a = newRstNode(rnParagraph)
       parseParagraph(p, a)
-    addIfNotNil(result, a)
+    result.addIfNotNil(a)
   if sonKind(result, 0) == rnParagraph and sonKind(result, 1) != rnParagraph:
     result.sons[0].kind = rnInner
 
 proc parseSectionWrapper(p: var RstParser): PRstNode =
   result = newRstNode(rnInner)
   parseSection(p, result)
-  while (result.kind == rnInner) and (len(result) == 1):
+  while result.kind == rnInner and result.len == 1:
     result = result.sons[0]
 
 proc `$`(t: Token): string =
@@ -1556,15 +1504,7 @@ proc `$`(t: Token): string =
 
 proc parseDoc(p: var RstParser): PRstNode =
   result = parseSectionWrapper(p)
-  if p.tok[p.idx].kind != tkEof:
-    when false:
-      assert isAllocatedPtr(cast[pointer](p.tok))
-      for i in 0 .. high(p.tok):
-        assert isNil(p.tok[i].symbol) or
-               isAllocatedPtr(cast[pointer](p.tok[i].symbol))
-      echo "index: ", p.idx, " length: ", high(p.tok), "##",
-          p.tok[p.idx-1], p.tok[p.idx], p.tok[p.idx+1]
-    #assert isAllocatedPtr(cast[pointer](p.indentStack))
+  if currentTok(p).kind != tkEof:
     rstMessage(p, meGeneralParseError)
 
 type
@@ -1590,29 +1530,29 @@ proc parseDirective(p: var RstParser, flags: DirFlags): PRstNode =
     args = newRstNode(rnDirArg)
     if argIsFile in flags:
       while true:
-        case p.tok[p.idx].kind
+        case currentTok(p).kind
         of tkWord, tkOther, tkPunct, tkAdornment:
-          add(args, newLeaf(p))
-          inc(p.idx)
+          args.add(newLeaf(p))
+          inc p.idx
         else: break
     elif argIsWord in flags:
-      while p.tok[p.idx].kind == tkWhite: inc(p.idx)
-      if p.tok[p.idx].kind == tkWord:
-        add(args, newLeaf(p))
-        inc(p.idx)
+      while currentTok(p).kind == tkWhite: inc p.idx
+      if currentTok(p).kind == tkWord:
+        args.add(newLeaf(p))
+        inc p.idx
       else:
         args = nil
     else:
       parseLine(p, args)
-  add(result, args)
+  result.add(args)
   if hasOptions in flags:
-    if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx].ival >= 3) and
-        (p.tok[p.idx + 1].symbol == ":"):
+    if currentTok(p).kind == tkIndent and currentTok(p).ival >= 3 and
+        nextTok(p).symbol == ":":
       options = parseFields(p)
-  add(result, options)
+  result.add(options)
 
 proc indFollows(p: RstParser): bool =
-  result = p.tok[p.idx].kind == tkIndent and p.tok[p.idx].ival > currInd(p)
+  result = currentTok(p).kind == tkIndent and currentTok(p).ival > currInd(p)
 
 proc parseDirective(p: var RstParser, flags: DirFlags,
                     contentParser: SectionParser): PRstNode =
@@ -1621,16 +1561,16 @@ proc parseDirective(p: var RstParser, flags: DirFlags,
   ## The children are rnDirArg, rnFieldList and rnLineBlock. Any might be nil.
   result = parseDirective(p, flags)
   if not isNil(contentParser) and indFollows(p):
-    pushInd(p, p.tok[p.idx].ival)
+    pushInd(p, currentTok(p).ival)
     var content = contentParser(p)
     popInd(p)
-    add(result, content)
+    result.add(content)
   else:
-    add(result, PRstNode(nil))
+    result.add(PRstNode(nil))
 
 proc parseDirBody(p: var RstParser, contentParser: SectionParser): PRstNode =
   if indFollows(p):
-    pushInd(p, p.tok[p.idx].ival)
+    pushInd(p, currentTok(p).ival)
     result = contentParser(p)
     popInd(p)
 
@@ -1666,7 +1606,7 @@ proc dirInclude(p: var RstParser): PRstNode =
     # XXX: error handling; recursive file inclusion!
     if getFieldValue(n, "literal") != "":
       result = newRstNode(rnLiteralBlock)
-      add(result, newRstNode(rnLeaf, readFile(path)))
+      result.add(newRstNode(rnLeaf, readFile(path)))
     else:
       let inputString = readFile(path).string()
       let startPosition =
@@ -1674,7 +1614,7 @@ proc dirInclude(p: var RstParser): PRstNode =
           let searchFor = n.getFieldValue("start-after").strip()
           if searchFor != "":
             let pos = inputString.find(searchFor)
-            if pos != -1: pos + searchFor.len()
+            if pos != -1: pos + searchFor.len
             else: 0
           else:
             0
@@ -1724,7 +1664,7 @@ proc dirCodeBlock(p: var RstParser, nimExtension = false): PRstNode =
     var path = p.findRelativeFile(filename)
     if path == "": rstMessage(p, meCannotOpenFile, filename)
     var n = newRstNode(rnLiteralBlock)
-    add(n, newRstNode(rnLeaf, readFile(path)))
+    n.add(newRstNode(rnLeaf, readFile(path)))
     result.sons[2] = n
 
   # Extend the field block if we are using our custom extension.
@@ -1745,7 +1685,7 @@ proc dirCodeBlock(p: var RstParser, nimExtension = false): PRstNode =
 proc dirContainer(p: var RstParser): PRstNode =
   result = parseDirective(p, {hasArg}, parseSectionWrapper)
   assert(result.kind == rnDirective)
-  assert(len(result) == 3)
+  assert(result.len == 3)
   result.kind = rnContainer
 
 proc dirImage(p: var RstParser): PRstNode =
@@ -1779,10 +1719,10 @@ proc dirRawAux(p: var RstParser, result: var PRstNode, kind: RstNodeKind,
     else:
       var f = readFile(path)
       result = newRstNode(kind)
-      add(result, newRstNode(rnLeaf, f))
+      result.add(newRstNode(rnLeaf, f))
   else:
     result.kind = kind
-    add(result, parseDirBody(p, contentParser))
+    result.add(parseDirBody(p, contentParser))
 
 proc dirRaw(p: var RstParser): PRstNode =
   #
@@ -1806,8 +1746,8 @@ proc dirRaw(p: var RstParser): PRstNode =
 
 proc parseDotDot(p: var RstParser): PRstNode =
   result = nil
-  var col = p.tok[p.idx].col
-  inc(p.idx)
+  var col = currentTok(p).col
+  inc p.idx
   var d = getDirective(p)
   if d != "":
     pushInd(p, col)
@@ -1830,32 +1770,32 @@ proc parseDotDot(p: var RstParser): PRstNode =
     popInd(p)
   elif match(p, p.idx, " _"):
     # hyperlink target:
-    inc(p.idx, 2)
+    inc p.idx, 2
     var a = getReferenceName(p, ":")
-    if p.tok[p.idx].kind == tkWhite: inc(p.idx)
+    if currentTok(p).kind == tkWhite: inc p.idx
     var b = untilEol(p)
     setRef(p, rstnodeToRefname(a), b)
   elif match(p, p.idx, " |"):
     # substitution definitions:
-    inc(p.idx, 2)
+    inc p.idx, 2
     var a = getReferenceName(p, "|")
     var b: PRstNode
-    if p.tok[p.idx].kind == tkWhite: inc(p.idx)
-    if cmpIgnoreStyle(p.tok[p.idx].symbol, "replace") == 0:
-      inc(p.idx)
+    if currentTok(p).kind == tkWhite: inc p.idx
+    if cmpIgnoreStyle(currentTok(p).symbol, "replace") == 0:
+      inc p.idx
       expect(p, "::")
       b = untilEol(p)
-    elif cmpIgnoreStyle(p.tok[p.idx].symbol, "image") == 0:
-      inc(p.idx)
+    elif cmpIgnoreStyle(currentTok(p).symbol, "image") == 0:
+      inc p.idx
       b = dirImage(p)
     else:
-      rstMessage(p, meInvalidDirective, p.tok[p.idx].symbol)
+      rstMessage(p, meInvalidDirective, currentTok(p).symbol)
     setSub(p, addNodes(a), b)
   elif match(p, p.idx, " ["):
     # footnotes, citations
-    inc(p.idx, 2)
+    inc p.idx, 2
     var a = getReferenceName(p, "]")
-    if p.tok[p.idx].kind == tkWhite: inc(p.idx)
+    if currentTok(p).kind == tkWhite: inc p.idx
     var b = untilEol(p)
     setRef(p, rstnodeToRefname(a), b)
   else:
@@ -1879,14 +1819,14 @@ proc resolveSubs(p: var RstParser, n: PRstNode): PRstNode =
     if y != nil:
       result = newRstNode(rnHyperlink)
       n.kind = rnInner
-      add(result, n)
-      add(result, y)
+      result.add(n)
+      result.add(y)
   of rnLeaf:
     discard
   of rnContents:
     p.hasToc = true
   else:
-    for i in countup(0, len(n) - 1): n.sons[i] = resolveSubs(p, n.sons[i])
+    for i in 0 ..< n.len: n.sons[i] = resolveSubs(p, n.sons[i])
 
 proc rstParse*(text, filename: string,
                line, column: int, hasToc: var bool,