summary refs log tree commit diff stats
path: root/nim/docgen.pas
diff options
context:
space:
mode:
Diffstat (limited to 'nim/docgen.pas')
-rwxr-xr-xnim/docgen.pas1176
1 files changed, 0 insertions, 1176 deletions
diff --git a/nim/docgen.pas b/nim/docgen.pas
deleted file mode 100755
index 468dd1bc9..000000000
--- a/nim/docgen.pas
+++ /dev/null
@@ -1,1176 +0,0 @@
-//
-//
-//           The Nimrod Compiler
-//        (c) Copyright 2009 Andreas Rumpf
-//
-//    See the file "copying.txt", included in this
-//    distribution, for details about the copyright.
-//
-
-unit docgen;
-
-// This is the documentation generator. It is currently pretty simple: No
-// semantic checking is done for the code. Cross-references are generated
-// by knowing how the anchors are going to be named.
-
-interface
-
-{$include 'config.inc'}
-
-uses
-  nsystem, charsets, ast, astalgo, strutils, nhashes, options, nversion, msgs,
-  nos, ropes, idents, wordrecg, nmath, syntaxes, rnimsyn, scanner, rst, ntime,
-  highlite;
-
-procedure CommandDoc(const filename: string);
-procedure CommandRst2Html(const filename: string);
-procedure CommandRst2TeX(const filename: string);
-
-implementation
-
-type
-  TTocEntry = record
-    n: PRstNode;
-    refname, header: PRope;
-  end;
-  TSections = array [TSymKind] of PRope;
-  TMetaEnum = (metaNone, metaTitle, metaSubtitle, metaAuthor, metaVersion);
-  TDocumentor = record  // contains a module's documentation
-    filename: string;   // filename of the source file; without extension
-    basedir: string;    // base directory (where to put the documentation)
-    modDesc: PRope;     // module description
-    dependsOn: PRope;   // dependencies
-    id: int;            // for generating IDs
-    splitAfter: int;    // split too long entries in the TOC
-    tocPart: array of TTocEntry;
-    hasToc: bool;
-    toc, section: TSections;
-    indexFile, theIndex: PRstNode;
-    indexValFilename: string;
-    indent, verbatim: int;        // for code generation
-    meta: array [TMetaEnum] of PRope;
-  end;
-  PDoc = ^TDocumentor;
-
-var
-  splitter: string = '<wbr />';
-
-function findIndexNode(n: PRstNode): PRstNode;
-var
-  i: int;
-begin
-  if n = nil then
-    result := nil
-  else if n.kind = rnIndex then begin
-    result := n.sons[2];
-    if result = nil then begin
-      result := newRstNode(rnDefList);
-      n.sons[2] := result
-    end
-    else if result.kind = rnInner then
-      result := result.sons[0]
-  end
-  else begin
-    result := nil;
-    for i := 0 to rsonsLen(n)-1 do begin
-      result := findIndexNode(n.sons[i]);
-      if result <> nil then exit
-    end
-  end
-end;
-
-procedure initIndexFile(d: PDoc);
-var
-  h: PRstNode;
-  dummyHasToc: bool;
-begin
-  if gIndexFile = '' then exit;
-  gIndexFile := addFileExt(gIndexFile, 'txt');
-  d.indexValFilename := changeFileExt(extractFilename(d.filename), HtmlExt);
-  if ExistsFile(gIndexFile) then begin
-    d.indexFile := rstParse(readFile(gIndexFile), false, gIndexFile, 0, 1,
-                            dummyHasToc);
-    d.theIndex := findIndexNode(d.indexFile);
-    if (d.theIndex = nil) or (d.theIndex.kind <> rnDefList) then
-      rawMessage(errXisNoValidIndexFile, gIndexFile);
-    clearIndex(d.theIndex, d.indexValFilename);
-  end
-  else begin
-    d.indexFile := newRstNode(rnInner);
-    h := newRstNode(rnOverline);
-    h.level := 1;
-    addSon(h, newRstNode(rnLeaf, 'Index'));
-    addSon(d.indexFile, h);
-    h := newRstNode(rnIndex);
-    addSon(h, nil); // no argument
-    addSon(h, nil); // no options
-    d.theIndex := newRstNode(rnDefList);
-    addSon(h, d.theIndex);
-    addSon(d.indexFile, h);
-  end
-end;
-
-function newDocumentor(const filename: string): PDoc;
-var
-  s: string;
-begin
-  new(result);
-{@ignore}
-  fillChar(result^, sizeof(result^), 0);
-{@emit
-  result.tocPart := @[];
-}
-  result.filename := filename;
-  result.id := 100;
-  result.splitAfter := 20;
-  s := getConfigVar('split.item.toc');
-  if s <> '' then
-    result.splitAfter := parseInt(s);
-end;
-
-function getVarIdx(const varnames: array of string; const id: string): int;
-var
-  i: int;
-begin
-  for i := 0 to high(varnames) do
-    if cmpIgnoreStyle(varnames[i], id) = 0 then begin
-      result := i; exit
-    end;
-  result := -1
-end;
-
-function ropeFormatNamedVars(const frmt: TFormatStr;
-                             const varnames: array of string;
-                             const varvalues: array of PRope): PRope;
-var
-  i, j, L, start, idx, num: int;
-  id: string;
-begin
-  i := strStart;
-  L := length(frmt);
-  result := nil;
-  num := 0;
-  while i <= L + StrStart - 1 do begin
-    if frmt[i] = '$' then begin
-      inc(i);                 // skip '$'
-      case frmt[i] of
-        '#': begin
-          app(result, varvalues[num]);
-          inc(num);
-          inc(i);
-        end;
-        '$': begin
-          app(result, '$'+'');
-          inc(i)
-        end;
-        '0'..'9': begin
-          j := 0;
-          while true do begin
-            j := (j * 10) + Ord(frmt[i]) - ord('0');
-            inc(i);
-            if (i > L+StrStart-1) or not (frmt[i] in ['0'..'9']) then break
-          end;
-          if j > high(varvalues) + 1 then
-            internalError('ropeFormatNamedVars');
-          num := j;
-          app(result, varvalues[j - 1])
-        end;
-        'A'..'Z', 'a'..'z', #128..#255: begin
-          id := '';
-          while true do begin
-            addChar(id, frmt[i]);
-            inc(i);
-            if not (frmt[i] in ['A'..'Z', '_', 'a'..'z', #128..#255]) then break
-          end;
-          // search for the variable:
-          idx := getVarIdx(varnames, id);
-          if idx >= 0 then app(result, varvalues[idx])
-          else rawMessage(errUnkownSubstitionVar, id)
-        end;
-        '{': begin
-          id := '';
-          inc(i);
-          while frmt[i] <> '}' do begin
-            if frmt[i] = #0 then rawMessage(errTokenExpected, '}'+'');
-            addChar(id, frmt[i]);
-            inc(i);
-          end;
-          inc(i); // skip }
-          // search for the variable:
-          idx := getVarIdx(varnames, id);
-          if idx >= 0 then app(result, varvalues[idx])
-          else rawMessage(errUnkownSubstitionVar, id)
-        end
-        else
-          InternalError('ropeFormatNamedVars')
-      end
-    end;
-    start := i;
-    while (i <= L + StrStart - 1) do begin
-      if (frmt[i] <> '$') then
-        inc(i)
-      else
-        break
-    end;
-    if i - 1 >= start then
-      app(result, ncopy(frmt, start, i - 1))
-  end
-end;
-
-// -------------------- dispatcher -------------------------------------------
-
-procedure addXmlChar(var dest: string; c: Char);
-begin
-  case c of
-    '&': add(dest, '&amp;');
-    '<': add(dest, '&lt;');
-    '>': add(dest, '&gt;');
-    '"': add(dest, '&quot;');
-    else addChar(dest, c)
-  end
-end;
-
-procedure addRtfChar(var dest: string; c: Char);
-begin
-  case c of
-    '{': add(dest, '\{');
-    '}': add(dest, '\}');
-    '\': add(dest, '\\');
-    else addChar(dest, c)
-  end
-end;
-
-procedure addTexChar(var dest: string; c: Char);
-begin
-  case c of
-    '_': add(dest, '\_');
-    '{': add(dest, '\symbol{123}');
-    '}': add(dest, '\symbol{125}');
-    '[': add(dest, '\symbol{91}');
-    ']': add(dest, '\symbol{93}');
-    '\': add(dest, '\symbol{92}');
-    '$': add(dest, '\$');
-    '&': add(dest, '\&');
-    '#': add(dest, '\#');
-    '%': add(dest, '\%');
-    '~': add(dest, '\symbol{126}');
-    '@': add(dest, '\symbol{64}');
-    '^': add(dest, '\symbol{94}');
-    '`': add(dest, '\symbol{96}');
-    else addChar(dest, c)
-  end
-end;
-
-procedure escChar(var dest: string; c: Char);
-begin
-  if gCmd <> cmdRst2Tex then addXmlChar(dest, c)
-  else addTexChar(dest, c);
-end;
-
-function nextSplitPoint(const s: string; start: int): int;
-begin
-  result := start;
-  while result < length(s)+strStart do begin
-    case s[result] of
-      '_': exit;
-      'a'..'z': begin
-        if result+1 < length(s)+strStart then
-          if s[result+1] in ['A'..'Z'] then exit;
-      end;
-      else begin end;
-    end;
-    inc(result);
-  end;
-  dec(result); // last valid index
-end;
-
-function esc(const s: string; splitAfter: int = -1): string;
-var
-  i, j, k, partLen: int;
-begin
-  result := '';
-  if splitAfter >= 0 then begin
-    partLen := 0;
-    j := strStart;
-    while j < length(s)+strStart do begin
-      k := nextSplitPoint(s, j);
-      if (splitter <> ' '+'') or (partLen + k - j + 1 > splitAfter) then begin
-        partLen := 0;
-        add(result, splitter);
-      end;
-      for i := j to k do escChar(result, s[i]);
-      inc(partLen, k - j + 1);
-      j := k+1;
-    end;
-  end
-  else begin
-    for i := strStart to length(s)+strStart-1 do escChar(result, s[i])
-  end
-end;
-
-function disp(const xml, tex: string): string;
-begin  
-  if gCmd <> cmdRst2Tex then
-    result := xml
-  else
-    result := tex
-end;
-
-function dispF(const xml, tex: string; const args: array of PRope): PRope;
-begin
-  if gCmd <> cmdRst2Tex then
-    result := ropef(xml, args)
-  else
-    result := ropef(tex, args)
-end;
-
-procedure dispA(var dest: PRope; const xml, tex: string;
-                const args: array of PRope);
-begin
-  if gCmd <> cmdRst2Tex then
-    appf(dest, xml, args)
-  else
-    appf(dest, tex, args)
-end;
-
-// ---------------------------------------------------------------------------
-
-function renderRstToOut(d: PDoc; n: PRstNode): PRope; forward;
-
-function renderAux(d: PDoc; n: PRstNode; const outer: string = '$1'): PRope;
-var
-  i: int;
-begin
-  result := nil;
-  for i := 0 to rsonsLen(n)-1 do
-    app(result, renderRstToOut(d, n.sons[i]));
-  result := ropef(outer, [result]);
-end;
-
-procedure setIndexForSourceTerm(d: PDoc; name: PRstNode; id: int);
-var
-  a, h: PRstNode;
-begin
-  if d.theIndex = nil then exit;
-  h := newRstNode(rnHyperlink);
-  a := newRstNode(rnLeaf, d.indexValFilename +{&} disp('#'+'', '')
-                  +{&} toString(id));
-  addSon(h, a);
-  addSon(h, a);
-  a := newRstNode(rnIdx);
-  addSon(a, name);
-  setIndexPair(d.theIndex, a, h);
-end;
-
-function renderIndexTerm(d: PDoc; n: PRstNode): PRope;
-var
-  a, h: PRstNode;
-begin
-  inc(d.id);
-  result := dispF('<em id="$1">$2</em>',
-                  '$2\label{$1}', [toRope(d.id), renderAux(d, n)]);
-  h := newRstNode(rnHyperlink);
-  a := newRstNode(rnLeaf, d.indexValFilename +{&} disp('#'+'', '')
-                  +{&} toString(d.id));
-  addSon(h, a);
-  addSon(h, a);
-  setIndexPair(d.theIndex, n, h);
-end;
-
-function genComment(d: PDoc; n: PNode): PRope;
-var
-  dummyHasToc: bool;
-begin
-  if (n.comment <> snil) and startsWith(n.comment, '##') then
-    result := renderRstToOut(d, rstParse(n.comment, true, toFilename(n.info),
-                                          toLineNumber(n.info),
-                                          toColumn(n.info), dummyHasToc))
-  else
-    result := nil;
-end;
-
-function genRecComment(d: PDoc; n: PNode): PRope;
-var
-  i: int;
-begin
-  if n = nil then begin result := nil; exit end;
-  result := genComment(d, n);
-  if result = nil then begin
-    if not (n.kind in [nkEmpty..nkNilLit]) then
-      for i := 0 to sonsLen(n)-1 do begin
-        result := genRecComment(d, n.sons[i]);
-        if result <> nil then exit
-      end
-  end
-  else
-    n.comment := snil
-end;
-
-function isVisible(n: PNode): bool;
-var
-  v: PIdent;
-begin
-  result := false;
-  if n.kind = nkPostfix then begin
-    if (sonsLen(n) = 2) and (n.sons[0].kind = nkIdent) then begin
-      v := n.sons[0].ident;
-      result := (v.id = ord(wStar)) or (v.id = ord(wMinus));
-    end
-  end
-  else if n.kind = nkSym then
-    result := sfInInterface in n.sym.flags
-  else if n.kind = nkPragmaExpr then
-    result := isVisible(n.sons[0]);
-end;
-
-function getName(n: PNode; splitAfter: int = -1): string;
-begin
-  case n.kind of
-    nkPostfix: result := getName(n.sons[1], splitAfter);
-    nkPragmaExpr: result := getName(n.sons[0], splitAfter);
-    nkSym: result := esc(n.sym.name.s, splitAfter);
-    nkIdent: result := esc(n.ident.s, splitAfter);
-    nkAccQuoted:
-      result := esc('`'+'') +{&} getName(n.sons[0], splitAfter) +{&}
-                esc('`'+'');
-    else begin
-      internalError(n.info, 'getName()');
-      result := ''
-    end
-  end
-end;
-
-function getRstName(n: PNode): PRstNode;
-begin
-  case n.kind of
-    nkPostfix: result := getRstName(n.sons[1]);
-    nkPragmaExpr: result := getRstName(n.sons[0]);
-    nkSym: result := newRstNode(rnLeaf, n.sym.name.s);
-    nkIdent: result := newRstNode(rnLeaf, n.ident.s);
-    nkAccQuoted: result := getRstName(n.sons[0]);
-    else begin
-      internalError(n.info, 'getRstName()');
-      result := nil
-    end
-  end
-end;
-
-procedure genItem(d: PDoc; n, nameNode: PNode; k: TSymKind);
-var
-  r: TSrcGen;
-  kind: TTokType;
-  literal: string;
-  name, result, comm: PRope;
-begin
-  if not isVisible(nameNode) then exit;
-  name := toRope(getName(nameNode));
-  result := nil;
-  literal := '';
-  kind := tkEof;
-{@ignore}
-  fillChar(r, sizeof(r), 0);
-{@emit}
-  comm := genRecComment(d, n); // call this here for the side-effect!
-  initTokRender(r, n, {@set}[renderNoPragmas, renderNoBody, renderNoComments,
-                             renderDocComments]);
-  while true do begin
-    getNextTok(r, kind, literal);
-    case kind of
-      tkEof: break;
-      tkComment:
-        dispA(result, '<span class="Comment">$1</span>',
-                      '\spanComment{$1}',
-                      [toRope(esc(literal))]);
-      tokKeywordLow..tokKeywordHigh:
-        dispA(result, '<span class="Keyword">$1</span>',
-                      '\spanKeyword{$1}',
-                      [toRope(literal)]);
-      tkOpr, tkHat:
-        dispA(result, '<span class="Operator">$1</span>',
-                      '\spanOperator{$1}',
-                      [toRope(esc(literal))]);
-      tkStrLit..tkTripleStrLit:
-        dispA(result, '<span class="StringLit">$1</span>',
-                      '\spanStringLit{$1}',
-                      [toRope(esc(literal))]);
-      tkCharLit:
-        dispA(result, '<span class="CharLit">$1</span>',
-                      '\spanCharLit{$1}',
-                      [toRope(esc(literal))]);
-      tkIntLit..tkInt64Lit:
-        dispA(result, '<span class="DecNumber">$1</span>',
-                      '\spanDecNumber{$1}',
-                      [toRope(esc(literal))]);
-      tkFloatLit..tkFloat64Lit:
-        dispA(result, '<span class="FloatNumber">$1</span>',
-                      '\spanFloatNumber{$1}',
-                      [toRope(esc(literal))]);
-      tkSymbol:
-        dispA(result, '<span class="Identifier">$1</span>',
-                      '\spanIdentifier{$1}',
-                      [toRope(esc(literal))]);
-      tkInd, tkSad, tkDed, tkSpaces: begin
-        app(result, literal)
-      end;
-      tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi,
-      tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi,
-      tkParDotLe, tkParDotRi, tkComma, tkSemiColon, tkColon,
-      tkEquals, tkDot, tkDotDot, tkAccent:
-        dispA(result, '<span class="Other">$1</span>',
-                      '\spanOther{$1}',
-                      [toRope(esc(literal))]);
-      else InternalError(n.info, 'docgen.genThing(' + toktypeToStr[kind] + ')');
-    end
-  end;
-  inc(d.id);
-  app(d.section[k], ropeFormatNamedVars(getConfigVar('doc.item'),
-      ['name', 'header', 'desc', 'itemID'],
-      [name, result, comm, toRope(d.id)]));
-  app(d.toc[k], ropeFormatNamedVars(getConfigVar('doc.item.toc'),
-      ['name', 'header', 'desc', 'itemID'],
-      [toRope(getName(nameNode, d.splitAfter)), result, comm, toRope(d.id)]));
-  setIndexForSourceTerm(d, getRstName(nameNode), d.id);
-end;
-
-function renderHeadline(d: PDoc; n: PRstNode): PRope;
-var
-  i, len: int;
-  refname: PRope;
-begin
-  result := nil;
-  for i := 0 to rsonsLen(n)-1 do
-    app(result, renderRstToOut(d, n.sons[i]));
-  refname := toRope(rstnodeToRefname(n));
-  if d.hasToc then begin
-    len := length(d.tocPart);
-    setLength(d.tocPart, len+1);
-    d.tocPart[len].refname := refname;
-    d.tocPart[len].n := n;
-    d.tocPart[len].header := result;
-    result := dispF(
-      '<h$1><a class="toc-backref" id="$2" href="#$2_toc">$3</a></h$1>',
-      '\rsth$4{$3}\label{$2}$n',
-      [toRope(n.level), d.tocPart[len].refname, result,
-       toRope(chr(n.level-1+ord('A'))+'')]);
-  end
-  else
-    result := dispF('<h$1 id="$2">$3</h$1>',
-                    '\rsth$4{$3}\label{$2}$n',
-                    [toRope(n.level), refname, result,
-                     toRope(chr(n.level-1+ord('A'))+'')]);
-end;
-
-function renderOverline(d: PDoc; n: PRstNode): PRope;
-var
-  i: int;
-  t: PRope;
-begin
-  t := nil;
-  for i := 0 to rsonsLen(n)-1 do
-    app(t, renderRstToOut(d, n.sons[i]));
-  result := nil;
-  if d.meta[metaTitle] = nil then d.meta[metaTitle] := t
-  else if d.meta[metaSubtitle] = nil then d.meta[metaSubtitle] := t
-  else
-    result := dispF('<h$1 id="$2"><center>$3</center></h$1>',
-                    '\rstov$4{$3}\label{$2}$n',
-                    [toRope(n.level), toRope(rstnodeToRefname(n)), t,
-                     toRope(chr(n.level-1+ord('A'))+'')]);
-end;
-
-function renderRstToRst(d: PDoc; n: PRstNode): PRope; forward;
-
-function renderRstSons(d: PDoc; n: PRstNode): PRope;
-var
-  i: int;
-begin
-  result := nil;
-  for i := 0 to rsonsLen(n)-1 do app(result, renderRstToRst(d, n.sons[i]));
-end;
-
-function renderRstToRst(d: PDoc; n: PRstNode): PRope;
-// this is needed for the index generation; it may also be useful for
-// debugging, but most code is already debugged...
-const
-  lvlToChar: array [0..8] of char = ('!', '=', '-', '~', '`',
-                                     '<', '*', '|', '+');
-var
-  L: int;
-  ind: PRope;
-begin
-  result := nil;
-  if n = nil then exit;
-  ind := toRope(repeatChar(d.indent));
-  case n.kind of
-    rnInner: result := renderRstSons(d, n);
-    rnHeadline: begin
-      result := renderRstSons(d, n);
-      L := ropeLen(result);
-      result := ropef('$n$1$2$n$1$3', [ind, result,
-                      toRope(repeatChar(L, lvlToChar[n.level]))]);
-    end;
-    rnOverline: begin
-      result := renderRstSons(d, n);
-      L := ropeLen(result);
-      result := ropef('$n$1$3$n$1$2$n$1$3', [ind, result,
-                      toRope(repeatChar(L, lvlToChar[n.level]))]);
-    end;
-    rnTransition:
-      result := ropef('$n$n$1$2$n$n',
-                     [ind, toRope(repeatChar(78-d.indent, '-'))]);
-    rnParagraph: begin
-      result := renderRstSons(d, n);
-      result := ropef('$n$n$1$2', [ind, result]);
-    end;
-    rnBulletItem: begin
-      inc(d.indent, 2);
-      result := renderRstSons(d, n);
-      if result <> nil then result := ropef('$n$1* $2', [ind, result]);
-      dec(d.indent, 2);
-    end;
-    rnEnumItem: begin
-      inc(d.indent, 4);
-      result := renderRstSons(d, n);
-      if result <> nil then result := ropef('$n$1(#) $2', [ind, result]);
-      dec(d.indent, 4);
-    end;
-    rnOptionList, rnFieldList, rnDefList, rnDefItem, rnLineBlock, rnFieldName,
-    rnFieldBody, rnStandaloneHyperlink, rnBulletList, rnEnumList:
-      result := renderRstSons(d, n);
-    rnDefName: begin
-      result := renderRstSons(d, n);
-      result := ropef('$n$n$1$2', [ind, result]);
-    end;
-    rnDefBody: begin
-      inc(d.indent, 2);
-      result := renderRstSons(d, n);
-      if n.sons[0].kind <> rnBulletList then
-        result := ropef('$n$1  $2', [ind, result]);
-      dec(d.indent, 2);
-    end;
-    rnField: begin
-      result := renderRstToRst(d, n.sons[0]);
-      L := max(ropeLen(result)+3, 30);
-      inc(d.indent, L);
-      result := ropef('$n$1:$2:$3$4', [
-        ind, result, toRope(repeatChar(L-ropeLen(result)-2)),
-        renderRstToRst(d, n.sons[1])]);
-      dec(d.indent, L);
-    end;
-    rnLineBlockItem: begin
-      result := renderRstSons(d, n);
-      result := ropef('$n$1| $2', [ind, result]);
-    end;
-    rnBlockQuote: begin
-      inc(d.indent, 2);
-      result := renderRstSons(d, n);
-      dec(d.indent, 2);
-    end;
-    rnRef: begin
-      result := renderRstSons(d, n);
-      result := ropef('`$1`_', [result]);
-    end;
-    rnHyperlink: begin
-      result := ropef('`$1 <$2>`_', [renderRstToRst(d, n.sons[0]),
-                                     renderRstToRst(d, n.sons[1])]);
-    end;
-    rnGeneralRole: begin
-      result := renderRstToRst(d, n.sons[0]);
-      result := ropef('`$1`:$2:', [result, renderRstToRst(d, n.sons[1])]);
-    end;
-    rnSub: begin
-      result := renderRstSons(d, n);
-      result := ropef('`$1`:sub:', [result]);
-    end;
-    rnSup: begin
-      result := renderRstSons(d, n);
-      result := ropef('`$1`:sup:', [result]);
-    end;
-    rnIdx: begin
-      result := renderRstSons(d, n);
-      result := ropef('`$1`:idx:', [result]);
-    end;
-    rnEmphasis: begin
-      result := renderRstSons(d, n);
-      result := ropef('*$1*', [result]);
-    end;
-    rnStrongEmphasis: begin
-      result := renderRstSons(d, n);
-      result := ropef('**$1**', [result]);
-    end;
-    rnInterpretedText: begin
-      result := renderRstSons(d, n);
-      result := ropef('`$1`', [result]);
-    end;
-    rnInlineLiteral: begin
-      inc(d.verbatim);
-      result := renderRstSons(d, n);
-      result := ropef('``$1``', [result]);
-      dec(d.verbatim);
-    end;
-    rnLeaf: begin
-      if (d.verbatim = 0) and (n.text = '\'+'') then
-        result := toRope('\\') // XXX: escape more special characters!
-      else
-        result := toRope(n.text);
-    end;
-    rnIndex: begin
-      inc(d.indent, 3);
-      if n.sons[2] <> nil then
-        result := renderRstSons(d, n.sons[2]);
-      dec(d.indent, 3);
-      result := ropef('$n$n$1.. index::$n$2', [ind, result]);
-    end;
-    rnContents: begin
-      result := ropef('$n$n$1.. contents::', [ind]);
-    end;
-    else rawMessage(errCannotRenderX, rstnodeKindToStr[n.kind]);
-  end;
-end;
-
-function renderTocEntry(d: PDoc; const e: TTocEntry): PRope;
-begin
-  result := dispF(
-    '<li><a class="reference" id="$1_toc" href="#$1">$2</a></li>$n',
-    '\item\label{$1_toc} $2\ref{$1}$n',
-    [e.refname, e.header]);
-end;
-
-function renderTocEntries(d: PDoc; var j: int; lvl: int): PRope;
-var
-  a: int;
-begin
-  result := nil;
-  while (j <= high(d.tocPart)) do begin
-    a := abs(d.tocPart[j].n.level);
-    if (a = lvl) then begin
-      app(result, renderTocEntry(d, d.tocPart[j]));
-      inc(j);
-    end
-    else if (a > lvl) then
-      app(result, renderTocEntries(d, j, a))
-    else
-      break
-  end;
-  if lvl > 1 then
-    result := dispF('<ul class="simple">$1</ul>',
-                    '\begin{enumerate}$1\end{enumerate}', [result]);
-end;
-
-function fieldAux(const s: string): PRope;
-begin
-  result := toRope(strip(s))
-end;
-
-function renderImage(d: PDoc; n: PRstNode): PRope;
-var
-  s, scale: string;
-  options: PRope;
-begin
-  options := nil;
-  s := getFieldValue(n, 'scale');
-  if s <> '' then dispA(options, ' scale="$1"', ' scale=$1', [fieldAux(scale)]);
-  
-  s := getFieldValue(n, 'height');
-  if s <> '' then dispA(options, ' height="$1"', ' height=$1', [fieldAux(s)]);
-  
-  s := getFieldValue(n, 'width');
-  if s <> '' then dispA(options, ' width="$1"', ' width=$1', [fieldAux(s)]);
-  
-  s := getFieldValue(n, 'alt');
-  if s <> '' then dispA(options, ' alt="$1"', '', [fieldAux(s)]);
-  s := getFieldValue(n, 'align');
-  if s <> '' then dispA(options, ' align="$1"', '', [fieldAux(s)]);
-    
-  if options <> nil then options := dispF('$1', '[$1]', [options]);
-  result := dispF('<img src="$1"$2 />',
-    '\includegraphics$2{$1}', [toRope(getArgument(n)), options]);
-  if rsonsLen(n) >= 3 then app(result, renderRstToOut(d, n.sons[2]))
-end;
-
-function renderCodeBlock(d: PDoc; n: PRstNode): PRope;
-var
-  m: PRstNode;
-  g: TGeneralTokenizer;
-  langstr: string;
-  lang: TSourceLanguage;
-begin
-  result := nil;
-  if n.sons[2] = nil then exit;
-  m := n.sons[2].sons[0];
-  if (m.kind <> rnLeaf) then InternalError('renderCodeBlock');
-  langstr := strip(getArgument(n));
-  if langstr = '' then lang := langNimrod // default language
-  else lang := getSourceLanguage(langstr);
-  if lang = langNone then begin
-    rawMessage(warnLanguageXNotSupported, langstr);
-    result := toRope(m.text)
-  end
-  else begin
-    initGeneralTokenizer(g, m.text);
-    while true do begin
-      getNextToken(g, lang);
-      case g.kind of
-        gtEof: break;
-        gtNone, gtWhitespace: begin
-          app(result, ncopy(m.text, g.start+strStart,
-                            g.len+g.start-1+strStart))
-        end
-        else
-          dispA(result,
-                '<span class="$2">$1</span>',
-                '\span$2{$1}',
-                [toRope(esc(ncopy(m.text, g.start+strStart,
-                                  g.len+g.start-1+strStart))),
-                 toRope(tokenClassToStr[g.kind])]);
-      end;
-    end;
-    deinitGeneralTokenizer(g);
-  end;
-  if result <> nil then
-    result := dispF('<pre>$1</pre>', '\begin{rstpre}$n$1$n\end{rstpre}$n',
-                    [result])
-end;
-
-function renderContainer(d: PDoc; n: PRstNode): PRope;
-var
-  arg: PRope;
-begin
-  result := renderRstToOut(d, n.sons[2]);
-  arg := toRope(strip(getArgument(n)));
-  if arg = nil then result := dispF('<div>$1</div>', '$1', [result])
-  else result := dispF('<div class="$1">$2</div>', '$2', [arg, result])  
-end;
-
-function texColumns(n: PRstNode): string;
-var
-  i: int;
-begin
-  result := '';
-  for i := 1 to rsonsLen(n) do add(result, '|X');
-end;
-
-function renderField(d: PDoc; n: PRstNode): PRope;
-var
-  fieldname: string;
-  fieldval: PRope;
-  b: bool;
-begin
-  b := false;
-  if gCmd = cmdRst2Tex then begin
-    fieldname := addNodes(n.sons[0]);
-    fieldval := toRope(esc(strip(addNodes(n.sons[1]))));
-    if cmpIgnoreStyle(fieldname, 'author') = 0 then begin
-      if d.meta[metaAuthor] = nil then begin
-        d.meta[metaAuthor] := fieldval;
-        b := true
-      end
-    end
-    else if cmpIgnoreStyle(fieldName, 'version') = 0 then begin
-      if d.meta[metaVersion] = nil then begin
-        d.meta[metaVersion] := fieldval;
-        b := true
-      end
-    end
-  end;
-  if b then result := nil
-  else result := renderAux(d, n, disp('<tr>$1</tr>$n', '$1'));
-end;
-
-function renderRstToOut(d: PDoc; n: PRstNode): PRope;
-var
-  i: int;
-begin
-  if n = nil then begin result := nil; exit end;
-  case n.kind of
-    rnInner: result := renderAux(d, n);
-    rnHeadline: result := renderHeadline(d, n);
-    rnOverline: result := renderOverline(d, n);
-    rnTransition:
-      result := renderAux(d, n, disp('<hr />'+nl, '\hrule'+nl));
-    rnParagraph:
-      result := renderAux(d, n, disp('<p>$1</p>'+nl, '$1$n$n'));
-    rnBulletList:
-      result := renderAux(d, n, disp('<ul class="simple">$1</ul>'+nl,
-                                '\begin{itemize}$1\end{itemize}'+nl));
-    rnBulletItem, rnEnumItem:
-      result := renderAux(d, n, disp('<li>$1</li>'+nl, '\item $1'+nl));
-    rnEnumList:
-      result := renderAux(d, n, disp('<ol class="simple">$1</ol>'+nl,
-                                     '\begin{enumerate}$1\end{enumerate}'+nl));
-    rnDefList: 
-      result := renderAux(d, n, disp('<dl class="docutils">$1</dl>'+nl,
-                        '\begin{description}$1\end{description}'+nl));
-    rnDefItem: 
-      result := renderAux(d, n);
-    rnDefName:
-      result := renderAux(d, n, disp('<dt>$1</dt>'+nl, '\item[$1] '));
-    rnDefBody:
-      result := renderAux(d, n, disp('<dd>$1</dd>'+nl, '$1'+nl));
-    rnFieldList: begin
-      result := nil;
-      for i := 0 to rsonsLen(n)-1 do app(result, renderRstToOut(d, n.sons[i]));
-      if result <> nil then
-        result := dispf('<table class="docinfo" frame="void" rules="none">' +
-                        '<col class="docinfo-name" />' +
-                        '<col class="docinfo-content" />' +
-                        '<tbody valign="top">$1' +
-                        '</tbody></table>',
-                        '\begin{description}$1\end{description}'+nl, [result]);
-    end;
-    rnField: result := renderField(d, n);
-    rnFieldName:
-      result := renderAux(d, n, disp(
-                  '<th class="docinfo-name">$1:</th>', '\item[$1:]'));
-    rnFieldBody:
-      result := renderAux(d, n, disp('<td>$1</td>', ' $1$n'));
-    rnIndex:
-      result := renderRstToOut(d, n.sons[2]);
-
-    rnOptionList:
-      result := renderAux(d, n, disp('<table frame="void">$1</table>',
-                    '\begin{description}$n$1\end{description}'+nl));
-    rnOptionListItem:
-      result := renderAux(d, n, disp('<tr>$1</tr>$n', '$1'));
-    rnOptionGroup:
-      result := renderAux(d, n, disp('<th align="left">$1</th>', '\item[$1]'));
-    rnDescription:
-      result := renderAux(d, n, disp('<td align="left">$1</td>$n', ' $1$n'));
-    rnOption,
-    rnOptionString,
-    rnOptionArgument: InternalError('renderRstToOut');
-
-    rnLiteralBlock: 
-      result := renderAux(d, n, disp('<pre>$1</pre>$n',
-                                     '\begin{rstpre}$n$1$n\end{rstpre}$n'));
-    rnQuotedLiteralBlock: InternalError('renderRstToOut');
-
-    rnLineBlock: result := renderAux(d, n, disp('<p>$1</p>', '$1$n$n'));
-    rnLineBlockItem: result := renderAux(d, n, disp('$1<br />', '$1\\$n'));
-
-    rnBlockQuote:
-      result := renderAux(d, n, disp('<blockquote><p>$1</p></blockquote>$n',
-                                     '\begin{quote}$1\end{quote}$n'));
-
-    rnTable, rnGridTable: begin
-      result := renderAux(d, n,
-                          disp('<table border="1" class="docutils">$1</table>',
-                               '\begin{table}\begin{rsttab}{' +{&}
-                               texColumns(n) +{&}
-                               '|}$n\hline$n$1\end{rsttab}\end{table}'));
-    end;
-    rnTableRow: begin
-      if rsonsLen(n) >= 1 then begin
-        result := renderRstToOut(d, n.sons[0]);
-        for i := 1 to rsonsLen(n)-1 do
-          dispa(result, '$1', ' & $1', [renderRstToOut(d, n.sons[i])]);
-        result := dispf('<tr>$1</tr>$n', '$1\\$n\hline$n', [result]);
-      end
-      else
-        result := nil;
-    end;
-    rnTableDataCell: result := renderAux(d, n, disp('<td>$1</td>', '$1'));
-    rnTableHeaderCell:
-      result := renderAux(d, n, disp('<th>$1</th>', '\textbf{$1}'));
-
-    rnLabel: InternalError('renderRstToOut'); // used for footnotes and other
-    rnFootnote: InternalError('renderRstToOut'); // a footnote
-
-    rnCitation: InternalError('renderRstToOut');    // similar to footnote
-    rnRef: 
-      result := dispF('<a class="reference external" href="#$2">$1</a>',
-                      '$1\ref{$2}',
-                      [renderAux(d, n), toRope(rstnodeToRefname(n))]);
-    rnStandaloneHyperlink:
-      result := renderAux(d, n, disp(
-                    '<a class="reference external" href="$1">$1</a>',
-                    '\href{$1}{$1}'));
-    rnHyperlink: 
-      result := dispF('<a class="reference external" href="$2">$1</a>',
-                      '\href{$2}{$1}',
-                      [renderRstToOut(d, n.sons[0]),
-                       renderRstToOut(d, n.sons[1])]);
-    rnDirArg, rnRaw: result := renderAux(d, n);
-    rnImage, rnFigure: result := renderImage(d, n);
-    rnCodeBlock: result := renderCodeBlock(d, n);
-    rnContainer: result := renderContainer(d, n);
-    rnSubstitutionReferences, rnSubstitutionDef:
-      result := renderAux(d, n, disp('|$1|', '|$1|'));
-    rnDirective: result := renderAux(d, n, '');
-
-    // Inline markup:
-    rnGeneralRole: 
-      result := dispF('<span class="$2">$1</span>',
-                      '\span$2{$1}',
-                      [renderRstToOut(d, n.sons[0]),
-                       renderRstToOut(d, n.sons[1])]);
-    rnSub: result := renderAux(d, n, disp('<sub>$1</sub>', '\rstsub{$1}'));
-    rnSup: result := renderAux(d, n, disp('<sup>$1</sup>', '\rstsup{$1}'));
-    rnEmphasis: result := renderAux(d, n, disp('<em>$1</em>', '\emph{$1}'));
-    rnStrongEmphasis:
-      result := renderAux(d, n, disp('<strong>$1</strong>', '\textbf{$1}'));
-    rnInterpretedText:
-      result := renderAux(d, n, disp('<cite>$1</cite>', '\emph{$1}'));
-    rnIdx: begin
-      if d.theIndex = nil then
-        result := renderAux(d, n, disp('<em>$1</em>', '\emph{$1}'))
-      else
-        result := renderIndexTerm(d, n);
-    end;
-    rnInlineLiteral:
-      result := renderAux(d, n, disp(
-        '<tt class="docutils literal"><span class="pre">$1</span></tt>',
-        '\texttt{$1}'));
-    rnLeaf: result := toRope(esc(n.text));
-    rnContents: d.hasToc := true;
-    rnTitle: d.meta[metaTitle] := renderRstToOut(d, n.sons[0]);
-    else InternalError('renderRstToOut');
-  end
-end;
-
-procedure generateDoc(d: PDoc; n: PNode);
-var
-  i: int;
-begin
-  if n = nil then exit;
-  case n.kind of
-    nkCommentStmt:  app(d.modDesc, genComment(d, n));
-    nkProcDef:      genItem(d, n, n.sons[namePos], skProc);
-    nkMethodDef:    genItem(d, n, n.sons[namePos], skMethod);
-    nkIteratorDef:  genItem(d, n, n.sons[namePos], skIterator);
-    nkMacroDef:     genItem(d, n, n.sons[namePos], skMacro);
-    nkTemplateDef:  genItem(d, n, n.sons[namePos], skTemplate);
-    nkConverterDef: genItem(d, n, n.sons[namePos], skConverter);
-    nkVarSection: begin
-      for i := 0 to sonsLen(n)-1 do
-        if n.sons[i].kind <> nkCommentStmt then
-          genItem(d, n.sons[i], n.sons[i].sons[0], skVar);
-    end;
-    nkConstSection: begin
-      for i := 0 to sonsLen(n)-1 do
-        if n.sons[i].kind <> nkCommentStmt then
-          genItem(d, n.sons[i], n.sons[i].sons[0], skConst);
-    end;
-    nkTypeSection: begin
-      for i := 0 to sonsLen(n)-1 do
-        if n.sons[i].kind <> nkCommentStmt then
-          genItem(d, n.sons[i], n.sons[i].sons[0], skType);
-    end;
-    nkStmtList: begin
-      for i := 0 to sonsLen(n)-1 do generateDoc(d, n.sons[i]);
-    end;
-    nkWhenStmt: begin
-      // generate documentation for the first branch only:
-      generateDoc(d, lastSon(n.sons[0]));
-    end
-    else begin end
-  end
-end;
-
-procedure genSection(d: PDoc; kind: TSymKind);
-var
-  title: PRope;
-begin
-  if d.section[kind] = nil then exit;
-  title := toRope(ncopy(symKindToStr[kind], strStart+2) + 's');
-  d.section[kind] := ropeFormatNamedVars(getConfigVar('doc.section'),
-    ['sectionid', 'sectionTitle', 'sectionTitleID', 'content'],
-    [toRope(ord(kind)), title, toRope(ord(kind)+50), d.section[kind]]);
-  d.toc[kind] := ropeFormatNamedVars(getConfigVar('doc.section.toc'),
-    ['sectionid', 'sectionTitle', 'sectionTitleID', 'content'],
-    [toRope(ord(kind)), title, toRope(ord(kind)+50), d.toc[kind]]);
-end;
-
-function genOutFile(d: PDoc): PRope;
-var
-  code, toc, title, content: PRope;
-  bodyname: string;
-  i: TSymKind;
-  j: int;
-begin
-  j := 0;
-  toc := renderTocEntries(d, j, 1);
-  code := nil;
-  content := nil;
-  title := nil;
-  for i := low(TSymKind) to high(TSymKind) do begin
-    genSection(d, i);
-    app(toc, d.toc[i]);
-  end;
-  if toc <> nil then
-    toc := ropeFormatNamedVars(getConfigVar('doc.toc'), ['content'], [toc]);
-  for i := low(TSymKind) to high(TSymKind) do app(code, d.section[i]);
-  if d.meta[metaTitle] <> nil then
-    title := d.meta[metaTitle]
-  else
-    title := toRope('Module ' + extractFilename(changeFileExt(d.filename, '')));
-  if d.hasToc then
-    bodyname := 'doc.body_toc'
-  else
-    bodyname := 'doc.body_no_toc';
-  content := ropeFormatNamedVars(getConfigVar(bodyname),
-    ['title', 'tableofcontents', 'moduledesc', 'date', 'time', 'content'],
-    [title, toc, d.modDesc, toRope(getDateStr()), toRope(getClockStr()), code]);
-  if not (optCompileOnly in gGlobalOptions) then
-    code := ropeFormatNamedVars(getConfigVar('doc.file'),
-      ['title', 'tableofcontents', 'moduledesc', 'date', 'time',
-       'content', 'author', 'version'],
-      [title, toc, d.modDesc, toRope(getDateStr()), toRope(getClockStr()),
-       content, d.meta[metaAuthor], d.meta[metaVersion]])
-  else
-    code := content;
-  result := code;
-end;
-
-procedure generateIndex(d: PDoc);
-begin
-  if d.theIndex <> nil then begin
-    sortIndex(d.theIndex);
-    writeRope(renderRstToRst(d, d.indexFile), gIndexFile);
-  end
-end;
-
-procedure CommandDoc(const filename: string);
-var
-  ast: PNode;
-  d: PDoc;
-begin
-  ast := parseFile(addFileExt(filename, nimExt));
-  if ast = nil then exit;
-  d := newDocumentor(filename);
-  initIndexFile(d);
-  d.hasToc := true;
-  generateDoc(d, ast);
-  writeRope(genOutFile(d), getOutFile(filename, HtmlExt));
-  generateIndex(d);
-end;
-
-procedure CommandRstAux(const filename, outExt: string);
-var
-  filen: string;
-  d: PDoc;
-  rst: PRstNode;
-  code: PRope;
-begin
-  filen := addFileExt(filename, 'txt');
-  d := newDocumentor(filen);
-  initIndexFile(d);
-  rst := rstParse(readFile(filen), false, filen, 0, 1, d.hasToc);
-  d.modDesc := renderRstToOut(d, rst);
-  code := genOutFile(d);
-  writeRope(code, getOutFile(filename, outExt));
-  generateIndex(d);
-end;
-
-procedure CommandRst2Html(const filename: string);
-begin
-  CommandRstAux(filename, HtmlExt);
-end;
-
-procedure CommandRst2TeX(const filename: string);
-begin
-  splitter := '\-';
-  CommandRstAux(filename, TexExt);
-end;
-
-end.