summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2014-05-26 00:12:25 +0200
committerAndreas Rumpf <rumpf_a@web.de>2014-05-26 00:12:25 +0200
commit97fa3391f2e7e8fefe247117bc2da9a848c4fd15 (patch)
tree19503d3b5300e8001b18d24cd87474d1ae5d1868
parentab5f2273a6d1ff0bf40306ad9d2e8de3e4748e9e (diff)
parent489d7e526de7f24996e3d0054a050649cb83bbd9 (diff)
downloadNim-97fa3391f2e7e8fefe247117bc2da9a848c4fd15.tar.gz
Merge pull request #1132 from gradha/pr_index_improvements
Documentation index improvements
-rw-r--r--compiler/docgen.nim10
-rw-r--r--doc/apis.txt13
-rw-r--r--doc/c2nim.txt6
-rw-r--r--doc/docgen.txt72
-rw-r--r--doc/endb.txt12
-rw-r--r--doc/estp.txt8
-rw-r--r--doc/filters.txt8
-rw-r--r--doc/idetools.txt4
-rw-r--r--doc/intern.txt8
-rw-r--r--doc/manual.txt220
-rw-r--r--doc/nimgrep.txt6
-rw-r--r--doc/niminst.txt6
-rw-r--r--doc/nimrodc.txt44
-rw-r--r--doc/subexes.txt1
-rw-r--r--doc/tools.txt6
-rw-r--r--doc/tut1.txt32
-rw-r--r--doc/tut2.txt16
-rw-r--r--lib/packages/docutils/rstgen.nim439
18 files changed, 629 insertions, 282 deletions
diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index 6948c4979..4c9803401 100644
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -541,8 +541,14 @@ proc genOutFile(d: PDoc): PRope =
   if toc != nil:
     toc = ropeFormatNamedVars(getConfigVar("doc.toc"), ["content"], [toc])
   for i in countup(low(TSymKind), high(TSymKind)): app(code, d.section[i])
-  if d.meta[metaTitle].len != 0: title = d.meta[metaTitle]
-  else: title = "Module " & extractFilename(changeFileExt(d.filename, ""))
+
+  # Extract the title. Non API modules generate an entry in the index table.
+  if d.meta[metaTitle].len != 0:
+    title = d.meta[metaTitle]
+    setIndexTerm(d[], "", title)
+  else:
+    # Modules get an automatic title for the HTML, but no entry in the index.
+    title = "Module " & extractFilename(changeFileExt(d.filename, ""))
 
   let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc"
   content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
diff --git a/doc/apis.txt b/doc/apis.txt
index d76bd721e..9906f6bbc 100644
--- a/doc/apis.txt
+++ b/doc/apis.txt
@@ -1,6 +1,6 @@
-==========
-API design
-==========
+=================
+API naming design
+=================
 
 The API is designed to be **easy to use** and consistent. Ease of use is
 measured by the number of calls to achieve a concrete high level action.
@@ -79,3 +79,10 @@ string                  str
 identifier              ident
 indentation             indent
 -------------------     ------------   --------------------------------------
+
+
+Coding Guidelines
+=================
+
+For coding guidelines see the `Internals of the Nimrod Compiler
+<intern.html#coding-guidelines>`_ documentation.
diff --git a/doc/c2nim.txt b/doc/c2nim.txt
index 6788ef569..237af7fb2 100644
--- a/doc/c2nim.txt
+++ b/doc/c2nim.txt
@@ -1,6 +1,6 @@
-=================================
-  c2nim  User's manual
-=================================
+=======================
+  c2nim User's manual
+=======================
 
 :Author: Andreas Rumpf
 :Version: |nimrodversion|
diff --git a/doc/docgen.txt b/doc/docgen.txt
index 520d5e8a0..30d0c6ff2 100644
--- a/doc/docgen.txt
+++ b/doc/docgen.txt
@@ -164,20 +164,10 @@ Index switch
   nimrod doc2 --index:on filename.nim
 
 This will generate an index of all the exported symbols in the input Nimrod
-module, and put it into a neighboring file with the extension of `.idx`. The
-index file is line oriented (newlines have to be escaped). Each line represents
-a tab separated record of several columns, the first two mandatory, the rest
-optional:
-
-1. Mandatory term being indexed. Terms can include quoting according to
-   Nimrod's rules (eg. ```^```)
-2. Base filename plus anchor hyper link (eg.
-   ``algorithm.html#*,int,TSortOrder``).
-3. Optional human readable string to display as hyper link. If the value is not
-   present or is the empty string, the hyper link will be rendered using the
-   term.
-4. Optional title or description of the hyper link. Browsers usually display
-   this as a tooltip after hovering a moment over the hyper link.
+module, and put it into a neighboring file with the extension of ``.idx``. The
+index file is line oriented (newlines have to be escaped). Each line
+represents a tab separated record of several columns, the first two mandatory,
+the rest optional. See the `Index (idx) file format`_ section for details.
 
 Once index files have been generated for one or more modules, the Nimrod
 compiler command ``buildIndex directory`` can be run to go over all the index
@@ -295,6 +285,60 @@ symbols in the `system module <system.html>`_.
   <system.html#newException.t,typedesc,string>`_
 
 
+Index (idx) file format
+=======================
+
+Files with the ``.idx`` extension are generated when you use the `Index
+switch`_ along with commands to generate documentation from source or text
+files. You can programatically generate indices with the `setIndexTerm()
+<rstgen.html#setIndexTerm>`_ and `writeIndexFile()
+<rstgen.html#writeIndexFile>`_ procs. The purpose of ``idx`` files is to hold
+the interesting symbols and their HTML references so they can be later
+concatenated into a big index file with `mergeIndexes()
+<rstgen.html#mergeIndexes>`_.  This section documents the file format in
+detail.
+
+Index files are line oriented and tab separated (newline and tab characters
+have to be escaped). Each line represents a record with at least two fields,
+but can have up to four (additional columns are ignored). The content of these
+columns is:
+
+1. Mandatory term being indexed. Terms can include quoting according to
+   Nimrod's rules (eg. \`^\` like in `the actors module
+   <actors.html#^,ptr.TChannel[T]>`_).
+2. Base filename plus anchor hyper link (eg.
+   ``algorithm.html#*,int,TSortOrder``).
+3. Optional human readable string to display as hyper link. If the value is not
+   present or is the empty string, the hyper link will be rendered
+   using the term. Prefix whitespace indicates that this entry is
+   not for an API symbol but for a TOC entry.
+4. Optional title or description of the hyper link. Browsers usually display
+   this as a tooltip after hovering a moment over the hyper link.
+
+The index generation tools try to differentiate between documentation
+generated from ``.nim`` files and documentation generated from ``.txt`` or
+``.rst`` files. The former are always closely related to source code and
+consist mainly of API entries. The latter are generic documents meant for
+human reading.
+
+To differentiate both types (documents and APIs), the index generator will add
+to the index of documents an entry with the title of the document. Since the
+title is the topmost element, it will be added with a second field containing
+just the filename without any HTML anchor.  By convention this entry without
+anchor is the *title entry*, and since entries in the index file are added as
+they are scanned, the title entry will be the first line. The title for APIs
+is not present because it can be generated concatenating the name of the file
+to the word **Module**.
+
+Normal symbols are added to the index with surrounding whitespaces removed. An
+exception to this are table of content (TOC) entries. TOC entries are added to
+the index file with their third column having as much prefix spaces as their
+level is in the TOC (at least 1 character). The prefix whitespace helps to
+filter TOC entries from API or text symbols. This is important because the
+amount of spaces is used to replicate the hiearchy for document TOCs in the
+final index, and TOC entries found in ``.nim`` files are discarded.
+
+
 Additional resources
 ====================
 
diff --git a/doc/endb.txt b/doc/endb.txt
index d4437e5d9..e9a01b583 100644
--- a/doc/endb.txt
+++ b/doc/endb.txt
@@ -1,6 +1,6 @@
-===========================================

-  Embedded Nimrod Debugger User Guide

-===========================================

+==============================================

+  Embedded Nimrod Debugger (ENDB) User Guide

+==============================================

 

 :Author: Andreas Rumpf

 :Version: |nimrodversion|

@@ -9,7 +9,7 @@
 

 

 Nimrod comes with a platform independent debugger -

-the `Embedded Nimrod Debugger`:idx: (`ENDB`:idx:). The debugger is

+the Embedded Nimrod Debugger (ENDB). The debugger is

 *embedded* into your executable if it has been

 compiled with the ``--debugger:on`` command line option.

 This also defines the conditional symbol ``ENDB`` for you.

@@ -102,7 +102,7 @@ necessary: A special pragma has been defined for this:
 The ``breakpoint`` pragma

 -------------------------

 

-The `breakpoint`:idx: pragma is syntactically a statement. It can be used

+The ``breakpoint`` pragma is syntactically a statement. It can be used

 to mark the *following line* as a breakpoint:

 

 .. code-block:: Nimrod

@@ -122,7 +122,7 @@ debugging.
 The ``watchpoint`` pragma

 -------------------------

 

-The `watchpoint`:idx: pragma is syntactically a statement. It can be used

+The ``watchpoint`` pragma is syntactically a statement. It can be used

 to mark a location as a watchpoint:

 

 .. code-block:: Nimrod

diff --git a/doc/estp.txt b/doc/estp.txt
index 353e4576f..704bc33f2 100644
--- a/doc/estp.txt
+++ b/doc/estp.txt
@@ -1,13 +1,13 @@
-============================================

-  Embedded Stack Trace Profiler User Guide

-============================================

+===================================================

+  Embedded Stack Trace Profiler (ESTP) User Guide

+===================================================

 

 :Author: Andreas Rumpf

 :Version: |nimrodversion|

 

 

 Nimrod comes with a platform independent profiler -

-the `Embedded Stack Trace Profiler`:idx: (`ESTP`:idx:). The profiler 
+the Embedded Stack Trace Profiler (ESTP). The profiler 
 is *embedded* into your executable. To activate the profiler you need to do: 
 
 * compile your program with the ``--profiler:on --stackTrace:on`` command 
diff --git a/doc/filters.txt b/doc/filters.txt
index 683599a03..961a0ea49 100644
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -26,7 +26,7 @@ available parameters depend on the invoked filter.
 Pipe operator
 =============
 
-Filters can be combined with the ``|`` `pipe operator`:idx:\ ::
+Filters can be combined with the ``|`` pipe operator::
 
   #! strip(startswith="<") | stdtmpl
   #proc generateXML(name, age: string): string =
@@ -46,7 +46,7 @@ after each filter application.
 Replace filter
 --------------
 
-The `replace`:idx: filter replaces substrings in each line.
+The replace filter replaces substrings in each line.
 
 Parameters and their defaults:
 
@@ -60,7 +60,7 @@ Parameters and their defaults:
 Strip filter
 ------------
 
-The `strip`:idx: filter simply removes leading and trailing whitespace from
+The strip filter simply removes leading and trailing whitespace from
 each line.
 
 Parameters and their defaults:
@@ -79,7 +79,7 @@ Parameters and their defaults:
 StdTmpl filter
 --------------
 
-The `stdtmpl`:idx: filter provides a simple templating engine for Nimrod. The
+The stdtmpl filter provides a simple templating engine for Nimrod. The
 filter uses a line based parser: Lines prefixed with a *meta character*
 (default: ``#``) contain Nimrod code, other lines are verbatim. Because
 indentation-based parsing is not suited for a templating engine, control flow
diff --git a/doc/idetools.txt b/doc/idetools.txt
index 0c554a80b..97e110b1d 100644
--- a/doc/idetools.txt
+++ b/doc/idetools.txt
@@ -16,7 +16,7 @@
 Nimrod differs from many other compilers in that it is really fast,
 and being so fast makes it suited to provide external queries for
 text editors about the source code being written. Through the
-`idetools`:idx: command of `the compiler <nimrodc.html>`_, any IDE
+``idetools`` command of `the compiler <nimrodc.html>`_, any IDE
 can query a ``.nim`` source file and obtain useful information like
 definition of symbols or suggestions for completion.
 
@@ -169,7 +169,7 @@ clicks it and after a second or two the IDE displays where that
 symbol is defined. Such latencies would be terrible for features
 like symbol suggestion, plus why wait at all if we can avoid it?
 
-The idetools command can be run as a compiler service (`caas`:idx:),
+The idetools command can be run as a compiler service (CAAS),
 where you first launch the compiler and it will stay online as a
 server, accepting queries in a telnet like fashion. The advantage
 of staying on is that for many queries the compiler can cache the
diff --git a/doc/intern.txt b/doc/intern.txt
index c602e4933..ec6db8709 100644
--- a/doc/intern.txt
+++ b/doc/intern.txt
@@ -69,8 +69,10 @@ Coding Guidelines
 * Max line length is 80 characters.
 * Provide spaces around binary operators if that enhances readability.
 * Use a space after a colon, but not before it.
-* Start types with a capital ``T``, unless they are pointers/references which start
-  with ``P``. 
+* Start types with a capital ``T``, unless they are pointers/references which
+  start with ``P``.
+
+See also the `API naming design <apis.html>`_ document.
 
 
 Porting to new platforms
@@ -156,7 +158,7 @@ generator.
 Compilation cache
 =================
 
-The implementation of the `compilation cache`:idx: is tricky: There are lots
+The implementation of the compilation cache is tricky: There are lots
 of issues to be solved for the front- and backend. In the following 
 sections *global* means *shared between modules* or *property of the whole
 program*.
diff --git a/doc/manual.txt b/doc/manual.txt
index a87abab7a..f0389a35e 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -152,7 +152,7 @@ statements (simplified example)::
 Comments
 --------
 
-`Comments`:idx: start anywhere outside a string or character literal with the
+Comments start anywhere outside a string or character literal with the
 hash character ``#``.
 Comments consist of a concatenation of `comment pieces`:idx:. A comment piece
 starts with ``#`` and runs until the end of the line. The end of line characters
@@ -188,7 +188,7 @@ which code snippet the comment refers to.
 Identifiers & Keywords
 ----------------------
 
-`Identifiers`:idx: in Nimrod can be any string of letters, digits
+Identifiers in Nimrod can be any string of letters, digits
 and underscores, beginning with a letter. Two immediate following
 underscores ``__`` are not allowed::
 
@@ -201,7 +201,7 @@ classified as a ``letter`` and may thus be part of an identifier but later
 versions of the language may assign some Unicode characters to belong to the
 operator characters instead.
 
-The following `keywords`:idx: are reserved and cannot be used as identifiers:
+The following keywords are reserved and cannot be used as identifiers:
 
 .. code-block:: nimrod
    :file: keywords.txt
@@ -224,7 +224,7 @@ String literals
 
 Terminal symbol in the grammar: ``STR_LIT``.
 
-`String literals`:idx: can be delimited by matching double quotes, and can
+String literals can be delimited by matching double quotes, and can
 contain the following `escape sequences`:idx:\ :
 
 ==================         ===================================================
@@ -280,7 +280,7 @@ Raw string literals
 
 Terminal symbol in the grammar: ``RSTR_LIT``.
 
-There are also `raw string literals`:idx: that are preceded with the 
+There are also raw string literals that are preceded with the 
 letter ``r`` (or ``R``) and are delimited by matching double quotes (just 
 like ordinary string literals) and do not interpret the escape sequences. 
 This is especially convenient for regular expressions or Windows paths:
@@ -313,7 +313,7 @@ Terminal symbols in the grammar: ``GENERALIZED_STR_LIT``,
 
 The construct ``identifier"string literal"`` (without whitespace between the
 identifier and the opening quotation mark) is a
-`generalized raw string literal`:idx:. It is a shortcut for the construct
+generalized raw string literal. It is a shortcut for the construct
 ``identifier(r"string literal")``, so it denotes a procedure call with a
 raw string literal as its only argument. Generalized raw string literals
 are especially convenient for embedding mini languages directly into Nimrod
@@ -365,7 +365,7 @@ type is used for Unicode characters, it can represent any Unicode character.
 Numerical constants
 -------------------
 
-`Numerical constants`:idx: are of a single type and have the form::
+Numerical constants are of a single type and have the form::
 
   hexdigit = digit | 'A'..'F' | 'a'..'f'
   octdigit = '0'..'7'
@@ -440,7 +440,7 @@ is approximately 1.72826e35 according to the IEEE floating point standard.
 Operators
 ---------
 
-In Nimrod one can define his own operators. An `operator`:idx: is any
+In Nimrod one can define his own operators. An operator is any
 combination of the following characters::
 
        =     +     -     *     /     <     >
@@ -587,7 +587,7 @@ The grammar's start symbol is ``module``.
 Types
 =====
 
-All expressions have a `type`:idx: which is known at compile time. Nimrod
+All expressions have a type which is known at compile time. Nimrod
 is statically typed. One can declare new types, which is in essence defining
 an identifier that can be used to denote this custom type.
 
@@ -605,7 +605,7 @@ These are the major type classes:
 
 Ordinal types
 -------------
-`Ordinal types`:idx: have the following characteristics:
+Ordinal types have the following characteristics:
 
 - Ordinal types are countable and ordered. This property allows
   the operation of functions as ``Inc``, ``Ord``, ``Dec`` on ordinal types to
@@ -705,7 +705,7 @@ For further details, see `Convertible relation`_.
 
 Subrange types
 --------------
-A `subrange`:idx: type is a range of values from an ordinal type (the base
+A subrange type is a range of values from an ordinal type (the base
 type). To define a subrange type, one must specify it's limiting values: the
 lowest and highest value of the type:
 
@@ -806,7 +806,7 @@ the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
 
 Boolean type
 ------------
-The `boolean`:idx: type is named `bool`:idx: in Nimrod and can be one of the two
+The boolean type is named `bool`:idx: in Nimrod and can be one of the two
 pre-defined values ``true`` and ``false``. Conditions in while,
 if, elif, when statements need to be of type bool.
 
@@ -830,7 +830,7 @@ The size of the bool type is one byte.
 
 Character type
 --------------
-The `character type`:idx: is named ``char`` in Nimrod. Its size is one byte.
+The character type is named ``char`` in Nimrod. Its size is one byte.
 Thus it cannot represent an UTF-8 character, but a part of it.
 The reason for this is efficiency: for the overwhelming majority of use-cases,
 the resulting programs will still handle UTF-8 properly as UTF-8 was specially
@@ -845,7 +845,7 @@ character. ``TRune`` is declared in the `unicode module <unicode.html>`_.
 
 Enumeration types
 -----------------
-`Enumeration`:idx: types define a new type whose values consist of the ones
+Enumeration types define a new type whose values consist of the ones
 specified. The values are ordered. Example:
 
 .. code-block:: nimrod
@@ -915,7 +915,7 @@ via ``TMyEnum.value``:
 
 String type
 -----------
-All string literals are of the type `string`:idx:. A string in Nimrod is very
+All string literals are of the type ``string``. A string in Nimrod is very
 similar to a sequence of characters. However, strings in Nimrod are both
 zero-terminated and have a length field. One can retrieve the length with the
 builtin ``len`` procedure; the length never counts the terminating zero.
@@ -942,7 +942,7 @@ i-th *unichar*. The iterator ``runes`` from the `unicode module
 
 CString type
 ------------
-The `cstring`:idx: type represents a pointer to a zero-terminated char array
+The ``cstring`` type represents a pointer to a zero-terminated char array
 compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy
 interfacing with C. The index operation ``s[i]`` means the i-th *char* of 
 ``s``; however no bounds checking for ``cstring`` is performed making the
@@ -976,20 +976,20 @@ string from a cstring:
 
 Structured types
 ----------------
-A variable of a `structured type`:idx: can hold multiple values at the same
+A variable of a structured type can hold multiple values at the same
 time. Structured types can be nested to unlimited levels. Arrays, sequences,
 tuples, objects and sets belong to the structured types.
 
 Array and sequence types
 ------------------------
-`Arrays`:idx: are a homogeneous type, meaning that each element in the array
+Arrays are a homogeneous type, meaning that each element in the array
 has the same type. Arrays always have a fixed length which is specified at
 compile time (except for open arrays). They can be indexed by any ordinal type.
 A parameter ``A`` may be an *open array*, in which case it is indexed by
 integers from 0 to ``len(A)-1``. An array expression may be constructed by the
 array constructor ``[]``.
 
-`Sequences`:idx: are similar to arrays but of dynamic length which may change
+Sequences are similar to arrays but of dynamic length which may change
 during runtime (like strings). Sequences are implemented as growable arrays, 
 allocating pieces of memory as items are added. A sequence ``S`` is always
 indexed by integers from 0 to ``len(S)-1`` and its bounds are checked. 
@@ -1046,7 +1046,7 @@ supported because this is seldom needed and cannot be done efficiently.
 Varargs
 -------
 
-A `varargs`:idx: parameter is an openarray parameter that additionally
+A ``varargs`` parameter is an openarray parameter that additionally
 allows to pass a variable number of arguments to a procedure. The compiler 
 converts the list of arguments to an array implicitly:
 
@@ -1081,7 +1081,7 @@ parameter ``a``. (Note that ``$`` applied to strings is a nop.)
 
 Tuples and object types
 -----------------------
-A variable of a `tuple`:idx: or `object`:idx: type is a heterogeneous storage
+A variable of a tuple or object type is a heterogeneous storage
 container.
 A tuple or object defines various named *fields* of a type. A tuple also
 defines an *order* of the fields. Tuples are meant for heterogeneous storage
@@ -1161,7 +1161,7 @@ For a ``ref object`` type ``system.new`` is invoked implicitly.
 Object variants
 ---------------
 Often an object hierarchy is overkill in certain situations where simple
-`variant`:idx: types are needed.
+variant types are needed.
 
 An example:
 
@@ -1219,7 +1219,7 @@ branch switch ``system.reset`` has to be used.
 
 Set type
 --------
-The `set type`:idx: models the mathematical notion of a set. The set's
+The set type models the mathematical notion of a set. The set's
 basetype can only be an ordinal type. The reason is that sets are implemented
 as high performance bit vectors.
 
@@ -1254,7 +1254,7 @@ operation             meaning
 
 Reference and pointer types
 ---------------------------
-References (similar to `pointers`:idx: in other programming languages) are a
+References (similar to pointers in other programming languages) are a
 way to introduce many-to-one relationships. This means different references can
 point to and modify the same location in memory (also called `aliasing`:idx:).
 
@@ -1352,7 +1352,7 @@ Not nil annotation
 ------------------
 
 All types for that ``nil`` is a valid value can be annotated to 
-exclude ``nil`` as a valid value with the `not nil`:idx: annotation:
+exclude ``nil`` as a valid value with the ``not nil`` annotation:
 
 .. code-block:: nimrod
   type
@@ -1377,7 +1377,7 @@ here.
 Memory regions
 --------------
 
-The types ``ref`` and ``ptr`` can get an optional `region`:idx: annotation.
+The types ``ref`` and ``ptr`` can get an optional ``region`` annotation.
 A region has to be an object type.
 
 Regions are very useful to separate user space and kernel memory in the
@@ -1436,7 +1436,7 @@ Future directions:
 
 Procedural type
 ---------------
-A `procedural type`:idx: is internally a pointer to a procedure. ``nil`` is
+A procedural type is internally a pointer to a procedure. ``nil`` is
 an allowed value for variables of a procedural type. Nimrod uses procedural
 types to achieve `functional`:idx: programming techniques.
 
@@ -1544,7 +1544,7 @@ accesses its environment. If it does so, it has the calling convention
 Distinct type
 -------------
 
-A `distinct type`:idx: is new type derived from a `base type`:idx: that is
+A ``distinct`` type is new type derived from a `base type`:idx: that is
 incompatible with its base type. In particular, it is an essential property
 of a distinct type that it **does not** imply a subtype relation between it
 and its base type. Explicit type conversions from a distinct type to its
@@ -1727,7 +1727,7 @@ modules like `db_sqlite <db_sqlite.html>`_.
 Void type
 ---------
 
-The `void`:idx: type denotes the absense of any type. Parameters of 
+The ``void`` type denotes the absense of any type. Parameters of 
 type ``void`` are treated as non-existent, ``void`` as a return type means that
 the procedure does not return a value:
 
@@ -1960,7 +1960,7 @@ To be written.
 Statements and expressions
 ==========================
 
-Nimrod uses the common statement/expression paradigm: `Statements`:idx: do not
+Nimrod uses the common statement/expression paradigm: Statements do not
 produce a value in contrast to expressions. However, some expressions are 
 statements.
 
@@ -1977,7 +1977,7 @@ Statement list expression
 
 Statements can also occur in an expression context that looks 
 like ``(stmt1; stmt2; ...; ex)``. This is called
-an `statement list expression`:idx: or ``(;)``. The type 
+an statement list expression or ``(;)``. The type 
 of ``(stmt1; stmt2; ...; ex)`` is the type of ``ex``. All the other statements
 must be of type ``void``. (One can use ``discard`` to produce a ``void`` type.)
 ``(;)`` does not introduce a new scope.
@@ -1994,7 +1994,7 @@ Example:
 
   discard p(3, 4) # discard the return value of `p`
 
-The `discard`:idx: statement evaluates its expression for side-effects and
+The ``discard`` statement evaluates its expression for side-effects and
 throws the expression's resulting value away. 
 
 Ignoring the return value of a procedure without using a discard statement is
@@ -2022,7 +2022,7 @@ An empty ``discard`` statement is often used as a null statement:
 Var statement
 -------------
 
-`Var`:idx: statements declare new local and global variables and
+Var statements declare new local and global variables and
 initialize them. A comma separated list of variables can be used to specify
 variables of the same type:
 
@@ -2091,7 +2091,7 @@ initialized and does not rely on syntactic properties:
 let statement
 -------------
 
-A `Let`:idx: statement declares new local and global `single assignment`:idx:
+A ``let`` statement declares new local and global `single assignment`:idx:
 variables and binds a value to them. The syntax is the of the ``var`` 
 statement, except that the keyword ``var`` is replaced by the keyword ``let``.
 Let variables are not l-values and can thus not be passed to ``var`` parameters
@@ -2133,7 +2133,7 @@ they contain such a type.
 Static statement/expression
 ---------------------------
 
-A `static`:idx: statement/expression can be used to enforce compile 
+A static statement/expression can be used to enforce compile 
 time evaluation explicitly. Enforced compile time evaluation can even evaluate
 code that has side effects: 
 
@@ -2167,7 +2167,7 @@ Example:
   else:
     echo("Boring name...")
 
-The `if`:idx: statement is a simple way to make a branch in the control flow:
+The ``if`` statement is a simple way to make a branch in the control flow:
 The expression after the keyword ``if`` is evaluated, if it is true
 the corresponding statements after the ``:`` are executed. Otherwise
 the expression after the ``elif`` is evaluated (if there is an
@@ -2213,7 +2213,7 @@ Example:
     else:                   echo("unknown command")
   
 
-The `case`:idx: statement is similar to the if statement, but it represents
+The ``case`` statement is similar to the if statement, but it represents
 a multi-branch selection. The expression after the keyword ``case`` is
 evaluated and if its value is in a *slicelist* the corresponding statements
 (after the ``of`` keyword) are executed. If the value is not in any
@@ -2267,7 +2267,7 @@ Example:
   else:
     echo("cannot happen!")
 
-The `when`:idx: statement is almost identical to the ``if`` statement with some
+The ``when`` statement is almost identical to the ``if`` statement with some
 exceptions:
 
 * Each condition (``expr``) has to be a constant expression (of type ``bool``).
@@ -2289,7 +2289,7 @@ Example:
 .. code-block:: nimrod
   return 40+2
 
-The `return`:idx: statement ends the execution of the current procedure.
+The ``return`` statement ends the execution of the current procedure.
 It is only allowed in procedures. If there is an ``expr``, this is syntactic
 sugar for:
 
@@ -2316,7 +2316,7 @@ Example:
 .. code-block:: nimrod
   yield (1, 2, 3)
 
-The `yield`:idx: statement is used instead of the ``return`` statement in
+The ``yield`` statement is used instead of the ``return`` statement in
 iterators. It is only valid in iterators. Execution is returned to the body
 of the for loop that called the iterator. Yield does not end the iteration
 process, but execution is passed back to the iterator if the next iteration
@@ -2339,7 +2339,7 @@ Example:
           break myblock # leave the block, in this case both for-loops
   echo(found)
 
-The block statement is a means to group statements to a (named) `block`:idx:.
+The block statement is a means to group statements to a (named) ``block``.
 Inside the block, the ``break`` statement is allowed to leave the block
 immediately. A ``break`` statement can contain a name of a surrounding
 block to specify which block is to leave.
@@ -2353,7 +2353,7 @@ Example:
 .. code-block:: nimrod
   break
 
-The `break`:idx: statement is used to leave a block immediately. If ``symbol``
+The ``break`` statement is used to leave a block immediately. If ``symbol``
 is given, it is the name of the enclosing block that is to leave. If it is
 absent, the innermost block is left.
 
@@ -2371,7 +2371,7 @@ Example:
     pw = readLine(stdin)
 
 
-The `while`:idx: statement is executed until the ``expr`` evaluates to false.
+The ``while`` statement is executed until the ``expr`` evaluates to false.
 Endless loops are no error. ``while`` statements open an `implicit block`,
 so that they can be left with a ``break`` statement.
 
@@ -2379,7 +2379,7 @@ so that they can be left with a ``break`` statement.
 Continue statement
 ------------------
 
-A `continue`:idx: statement leads to the immediate next iteration of the
+A ``continue`` statement leads to the immediate next iteration of the
 surrounding loop construct. It is only allowed within a loop. A continue
 statement is syntactic sugar for a nested block:
 
@@ -2402,7 +2402,7 @@ Is equivalent to:
 Assembler statement
 -------------------
 
-The direct embedding of `assembler`:idx: code into Nimrod code is supported
+The direct embedding of assembler code into Nimrod code is supported
 by the unsafe ``asm`` statement. Identifiers in the assembler code that refer to
 Nimrod identifiers shall be enclosed in a special character which can be
 specified in the statement's pragmas. The default special character is ``'`'``:
@@ -2449,7 +2449,7 @@ Using statement
 
 **Warning**: The ``using`` statement is highly experimental!
 
-The `using statement`:idx: provides syntactic convenience for procs that
+The using statement provides syntactic convenience for procs that
 heavily use a single contextual parameter. When applied to a variable or a
 constant, it will instruct Nimrod to automatically consider the used symbol as
 a hidden leading parameter for any procedure calls, following the using
@@ -2534,7 +2534,7 @@ the last expression as the result value, much like in an `expr` template.
 Table constructor
 -----------------
 
-A `table constructor`:idx: is syntactic sugar for an array constructor:
+A table constructor is syntactic sugar for an array constructor:
 
 .. code-block:: nimrod
   {"key1": "value1", "key2", "key3": "value2"}
@@ -2581,7 +2581,7 @@ only needed for low-level programming and are inherently unsafe.
 
 The addr operator
 -----------------
-The `addr`:idx: operator returns the address of an l-value. If the type of the
+The ``addr`` operator returns the address of an l-value. If the type of the
 location is ``T``, the `addr` operator result is of the type ``ptr T``. An
 address is always an untraced reference. Taking the address of an object that
 resides on the stack is **unsafe**, as the pointer may live longer than the
@@ -2682,7 +2682,7 @@ For object oriented programming, the syntax ``obj.method(args)`` can be used
 instead of ``method(obj, args)``. The parentheses can be omitted if there are no
 remaining arguments: ``obj.len`` (instead of ``len(obj)``).
 
-This `method call syntax`:idx: is not restricted to objects, it can be used
+This method call syntax is not restricted to objects, it can be used
 to supply any type of first argument for procedures:
 
 .. code-block:: nimrod
@@ -2727,7 +2727,7 @@ Command invocation syntax
 -------------------------
 
 Routines can be invoked without the ``()`` if the call is syntatically
-a statement. This `command invocation syntax`:idx: also works for
+a statement. This command invocation syntax also works for
 expressions, but then only a single argument may follow. This restriction
 means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as
 ``echo(f(1, f(2)))``. The method call syntax may be used to provide one
@@ -2924,7 +2924,7 @@ The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
 Multi-methods
 =============
 
-Procedures always use static dispatch. `Multi-methods`:idx: use dynamic
+Procedures always use static dispatch. Multi-methods use dynamic
 dispatch.
 
 .. code-block:: nimrod
@@ -3177,7 +3177,7 @@ Example:
       line: int       # the line the symbol was declared in
       code: PNode     # the symbol's abstract syntax tree
 
-A `type`:idx: section begins with the ``type`` keyword. It contains multiple
+A type section begins with the ``type`` keyword. It contains multiple
 type definitions. A type definition binds a type to a name. Type definitions
 can be recursive or even mutually recursive. Mutually recursive types are only
 possible within a single ``type`` section. Nominal types like ``objects`` 
@@ -3214,7 +3214,7 @@ Example:
       close(f)
 
 
-The statements after the `try`:idx: are executed in sequential order unless
+The statements after the ``try`` are executed in sequential order unless
 an exception ``e`` is raised. If the exception type of ``e`` matches any
 listed in an ``except`` clause the corresponding statements are executed.
 The statements following the ``except`` clauses are called
@@ -3236,7 +3236,7 @@ is not executed (if an exception occurs).
 Except and finally statements
 -----------------------------
 
-`except`:idx: and `finally`:idx: can also be used as a stand-alone statements.
+``except`` and ``finally`` can also be used as a stand-alone statements.
 Any statements following them in the current block will be considered to be 
 in an implicit try block:
 
@@ -3285,9 +3285,9 @@ exception (unless a raise hook has been provided).
 OnRaise builtin
 ---------------
 
-``system.onRaise`` can be used to override the behaviour of ``raise`` for a
-single ``try`` statement. `onRaise`:idx: has to be called within the ``try`` 
-statement that should be affected.
+`system.onRaise() <system.html#onRaise>`_ can be used to override the
+behaviour of ``raise`` for a single ``try`` statement. ``onRaise`` has to be
+called within the ``try`` statement that should be affected.
 
 This allows for a Lisp-like `condition system`:idx:\:
 
@@ -3316,7 +3316,7 @@ Effect system
 Exception tracking
 ------------------
 
-Nimrod supports `exception tracking`:idx:. The `raises`:idx: pragma can be used
+Nimrod supports exception tracking. The `raises`:idx: pragma can be used
 to explicitly define which exceptions a proc/iterator/method/converter is 
 allowed to raise. The compiler verifies this:
 
@@ -3424,7 +3424,7 @@ exception tracking.
 Effects pragma
 --------------
 
-The `effects`:idx: pragma has been designed to assist the programmer with the
+The ``effects`` pragma has been designed to assist the programmer with the
 effects analysis. It is a statement that makes the compiler output all inferred
 effects up to the ``effects``'s position:
 
@@ -3493,7 +3493,7 @@ Example:
   for str in inorder(root):
     writeln(stdout, str)
 
-`Generics`:idx: are Nimrod's means to parametrize procs, iterators or types with
+Generics are Nimrod's means to parametrize procs, iterators or types with
 `type parameters`:idx:. Depending on context, the brackets are used either to
 introduce type parameters or to instantiate a generic proc, iterator or type.
 
@@ -3501,7 +3501,7 @@ introduce type parameters or to instantiate a generic proc, iterator or type.
 Is operator
 -----------
 
-The `is`:idx: operator checks for type equivalence at compile time. It is
+The ``is`` operator checks for type equivalence at compile time. It is
 therefore very useful for type specialization within generic code: 
 
 .. code-block:: nimrod
@@ -3516,7 +3516,7 @@ therefore very useful for type specialization within generic code:
 Type operator
 -------------
 
-The `type`:idx: (in many other languages called `typeof`:idx:) operator can
+The ``type`` (in many other languages called `typeof`:idx:) operator can
 be used to get the type of an expression: 
 
 .. code-block:: nimrod
@@ -3539,7 +3539,7 @@ other interpretations:
 Type Classes
 ------------
 
-A `type class`:idx: is a special pseudo-type that can be used to match against
+A type class is a special pseudo-type that can be used to match against
 types in the context of overload resolution or the ``is`` operator. 
 Nimrod supports the following built-in type classes:
 
@@ -3757,7 +3757,7 @@ A symbol can be forced to be open by a `mixin`:idx: declaration:
 Bind statement
 --------------
 
-The `bind`:idx: statement is the counterpart to the ``mixin`` statement. It 
+The ``bind`` statement is the counterpart to the ``mixin`` statement. It 
 can be used to explicitly declare identifiers that should be bound early (i.e.
 the identifiers should be looked up in the scope of the template/generic
 definition):
@@ -3785,7 +3785,7 @@ scope is the default.
 Templates
 =========
 
-A `template`:idx: is a simple form of a macro: It is a simple substitution
+A template is a simple form of a macro: It is a simple substitution
 mechanism that operates on Nimrod's abstract syntax trees. It is processed in
 the semantic pass of the compiler.
 
@@ -3817,7 +3817,7 @@ expected.
 Ordinary vs immediate templates
 -------------------------------
 
-There are two different kinds of templates: `immediate`:idx: templates and
+There are two different kinds of templates: immediate templates and
 ordinary templates. Ordinary templates take part in overloading resolution. As
 such their arguments need to be type checked before the template is invoked.
 So ordinary templates cannot receive undeclared identifiers:
@@ -4012,7 +4012,7 @@ a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates.
 Macros
 ======
 
-A `macro`:idx: is a special kind of low level template. Macros can be used
+A macro is a special kind of low level template. Macros can be used
 to implement `domain specific languages`:idx:. Like templates, macros come in
 the 2 flavors *immediate* and *ordinary*.
 
@@ -4390,7 +4390,7 @@ This operator will be matched against assignments to missing fields.
 Term rewriting macros
 =====================
 
-`Term rewriting macros`:idx: are macros or templates that have not only
+Term rewriting macros are macros or templates that have not only
 a *name* but also a *pattern* that is searched for after the semantic checking
 phase of the compiler: This means they provide an easy way to enhance the 
 compilation pipeline with user defined optimizations:
@@ -4726,7 +4726,7 @@ ordinary routines.
 Move optimization
 -----------------
 
-The ``call`` constraint is particularly useful to implement a `move`:idx: 
+The ``call`` constraint is particularly useful to implement a move 
 optimization for types that have copying semantics:
 
 .. code-block:: nimrod
@@ -4752,7 +4752,7 @@ optimization for types that have copying semantics:
 
 Modules
 =======
-Nimrod supports splitting a program into pieces by a `module`:idx: concept.
+Nimrod supports splitting a program into pieces by a module concept.
 Each module needs to be in its own file and has its own `namespace`:idx:.
 Modules enable `information hiding`:idx: and `separate compilation`:idx:.
 A module may gain access to symbols of another module by the `import`:idx:
@@ -4795,7 +4795,7 @@ This is best illustrated by an example:
 Import statement
 ~~~~~~~~~~~~~~~~
 
-After the `import`:idx: statement a list of module names can follow or a single
+After the ``import`` statement a list of module names can follow or a single
 module name followed by an ``except`` to prevent some symbols to be imported:
 
 .. code-block:: nimrod
@@ -4838,7 +4838,7 @@ Likewise the following does not make sense as the name is ``strutils`` already:
 From import statement
 ~~~~~~~~~~~~~~~~~~~~~
 
-After the `from`:idx: statement a module name follows followed by 
+After the ``from`` statement a module name follows followed by 
 an ``import`` to list the symbols one likes to use without explict
 full qualification:
 
@@ -4857,7 +4857,7 @@ in ``module``.
 Export statement
 ~~~~~~~~~~~~~~~~
 
-An `export`:idx: statement can be used for symbol fowarding so that client
+An ``export`` statement can be used for symbol fowarding so that client
 modules don't need to import a module's dependencies:
 
 .. code-block:: nimrod
@@ -4885,7 +4885,7 @@ Scope rules
 -----------
 Identifiers are valid from the point of their declaration until the end of
 the block in which the declaration occurred. The range where the identifier
-is known is the `scope`:idx: of the identifier. The exact scope of an
+is known is the scope of the identifier. The exact scope of an
 identifier depends on the way it was declared.
 
 Block scope
@@ -4958,7 +4958,7 @@ to access the feature becomes available.
 
 noSideEffect pragma
 -------------------
-The `noSideEffect`:idx: pragma is used to mark a proc/iterator to have no side
+The ``noSideEffect`` pragma is used to mark a proc/iterator to have no side
 effects. This means that the proc/iterator only changes locations that are
 reachable from its parameters and the return value only depends on the
 arguments. If none of its parameters have the type ``var T``
@@ -4980,7 +4980,7 @@ proc with no side effects:
 destructor pragma
 -----------------
 
-The `destructor`:idx: pragma is used to mark a proc to act as a type destructor.
+The ``destructor`` pragma is used to mark a proc to act as a type destructor.
 The proc must have a single parameter with a concrete type (the name of a
 generic type is allowed too).
 
@@ -5040,25 +5040,25 @@ the ``finalizer`` parameter to ``new``.
 
 procvar pragma
 --------------
-The `procvar`:idx: pragma is used to mark a proc that it can be passed to a
+The ``procvar`` pragma is used to mark a proc that it can be passed to a
 procedural variable.
 
 
 compileTime pragma
 ------------------
-The `compileTime`:idx: pragma is used to mark a proc to be used at compile
+The ``compileTime`` pragma is used to mark a proc to be used at compile
 time only. No code will be generated for it. Compile time procs are useful
 as helpers for macros.
 
 
 noReturn pragma
 ---------------
-The `noreturn`:idx: pragma is used to mark a proc that never returns. 
+The ``noreturn`` pragma is used to mark a proc that never returns. 
 
 
 Acyclic pragma
 --------------
-The `acyclic`:idx: pragma can be used for object types to mark them as acyclic
+The ``acyclic`` pragma can be used for object types to mark them as acyclic
 even though they seem to be cyclic. This is an **optimization** for the garbage
 collector to not consider objects of this type as part of a cycle:
 
@@ -5089,13 +5089,13 @@ memory, but nothing worse happens.
 
 Final pragma
 ------------
-The `final`:idx: pragma can be used for an object type to specify that it
+The ``final`` pragma can be used for an object type to specify that it
 cannot be inherited from.
 
 
 shallow pragma
 --------------
-The `shallow`:idx: pragma affects the semantics of a type: The compiler is
+The ``shallow`` pragma affects the semantics of a type: The compiler is
 allowed to make a shallow copy. This can cause serious semantic issues and
 break memory safety! However, it can speed up assignments considerably, 
 because the semantics of Nimrod require deep copying of sequences and strings. 
@@ -5115,14 +5115,14 @@ structure:
 
 Pure pragma
 -----------
-An object type can be marked with the `pure`:idx: pragma so that its type 
+An object type can be marked with the ``pure`` pragma so that its type 
 field which is used for runtime type identification is omitted. This is
 necessary for binary compatibility with other compiled languages.
 
 
 AsmNoStackFrame pragma
 ----------------------
-A proc can be marked with the `AsmNoStackFrame`:idx: pragma to tell the compiler
+A proc can be marked with the ``AsmNoStackFrame`` pragma to tell the compiler
 it should not generate a stack frame for the proc. There are also no exit
 statements like ``return result;`` generated and the generated C function is
 declared as ``__declspec(naked)`` or ``__attribute__((naked))`` (depending on
@@ -5133,7 +5133,7 @@ assembler statements.
 
 error pragma
 ------------
-The `error`:idx: pragma is used to make the compiler output an error message
+The ``error`` pragma is used to make the compiler output an error message
 with the given content. Compilation does not necessarily abort after an error
 though. 
 
@@ -5149,7 +5149,7 @@ operation is valid due to overloading and type conversions:
 
 fatal pragma
 ------------
-The `fatal`:idx: pragma is used to make the compiler output an error message
+The ``fatal`` pragma is used to make the compiler output an error message
 with the given content. In contrast to the ``error`` pragma, compilation
 is guaranteed to be aborted by this pragma. Example:
 
@@ -5159,17 +5159,17 @@ is guaranteed to be aborted by this pragma. Example:
 
 warning pragma
 --------------
-The `warning`:idx: pragma is used to make the compiler output a warning message
+The ``warning`` pragma is used to make the compiler output a warning message
 with the given content. Compilation continues after the warning.
 
 hint pragma
 -----------
-The `hint`:idx: pragma is used to make the compiler output a hint message with
+The ``hint`` pragma is used to make the compiler output a hint message with
 the given content. Compilation continues after the hint.
 
 line pragma
 -----------
-The `line`:idx: pragma can be used to affect line information of the annotated
+The ``line`` pragma can be used to affect line information of the annotated
 statement as seen in stack backtraces:
 
 .. code-block:: nimrod
@@ -5187,7 +5187,7 @@ If the ``line`` pragma is used with a parameter, the parameter needs be a
 
 linearScanEnd pragma
 --------------------
-The `linearScanEnd`:idx: pragma can be used to tell the compiler how to 
+The ``linearScanEnd`` pragma can be used to tell the compiler how to 
 compile a Nimrod `case`:idx: statement. Syntactically it has to be used as a
 statement:
 
@@ -5215,7 +5215,7 @@ whole ``case`` statement, the whole ``case`` statement uses linear scanning.
 
 computedGoto pragma
 -------------------
-The `computedGoto`:idx: pragma can be used to tell the compiler how to 
+The ``computedGoto`` pragma can be used to tell the compiler how to 
 compile a Nimrod `case`:idx: in a ``while true`` statement. 
 Syntactically it has to be used as a statement inside the loop:
 
@@ -5260,7 +5260,7 @@ extension the pragma is simply ignored.
 
 unroll pragma
 -------------
-The `unroll`:idx: pragma can be used to tell the compiler that it should unroll
+The ``unroll`` pragma can be used to tell the compiler that it should unroll
 a `for`:idx: or `while`:idx: loop for runtime efficiency: 
 
 .. code-block:: nimrod
@@ -5339,7 +5339,7 @@ but are used to override the settings temporarily. Example:
 
 register pragma
 ---------------
-The `register`:idx: pragma is for variables only. It declares the variable as
+The ``register`` pragma is for variables only. It declares the variable as
 ``register``, giving the compiler a hint that the variable should be placed
 in a hardware register for faster access. C compilers usually ignore this
 though and for good reasons: Often they do a better job without it anyway.
@@ -5350,7 +5350,7 @@ example) it may provide benefits, though.
 
 global pragma
 -------------
-The `global`:idx: pragma can be applied to a variable within a proc to instruct
+The ``global`` pragma can be applied to a variable within a proc to instruct
 the compiler to store it in a global location and initialize it once at program
 startup.
 
@@ -5367,7 +5367,7 @@ and before any variable in a module that imports it.
 
 DeadCodeElim pragma
 -------------------
-The `deadCodeElim`:idx: pragma only applies to whole modules: It tells the
+The ``deadCodeElim`` pragma only applies to whole modules: It tells the
 compiler to activate (or deactivate) dead code elimination for the module the
 pragma appears in.
 
@@ -5385,7 +5385,7 @@ Example:
 ..
   NoForward pragma
   ----------------
-  The `noforward`:idx: pragma can be used to turn on and off a special compilation
+  The ``noforward`` pragma can be used to turn on and off a special compilation
   mode that to large extent eliminates the need for forward declarations. In this
   mode, the proc definitions may appear out of order and the compiler will postpone
   their semantic analysis and compilation until it actually needs to generate code
@@ -5433,7 +5433,7 @@ Example:
 Pragma pragma
 -------------
 
-The `pragma`:idx: pragma can be used to declare user defined pragmas. This is 
+The ``pragma`` pragma can be used to declare user defined pragmas. This is 
 useful because Nimrod's templates and macros do not affect pragmas. User 
 defined pragmas are in a different module-wide scope than all other symbols. 
 They cannot be imported from a module.
@@ -5477,7 +5477,7 @@ are documented here.
 
 Importc pragma
 --------------
-The `importc`:idx: pragma provides a means to import a proc or a variable
+The ``importc`` pragma provides a means to import a proc or a variable
 from C. The optional argument is a string containing the C identifier. If
 the argument is missing, the C name is the Nimrod identifier *exactly as
 spelled*:
@@ -5491,7 +5491,7 @@ the same feature under the same name.
 
 Exportc pragma
 --------------
-The `exportc`:idx: pragma provides a means to export a type, a variable, or a
+The ``exportc`` pragma provides a means to export a type, a variable, or a
 procedure to C. Enums and constants can't be exported. The optional argument
 is a string containing the C identifier.  If the argument is missing, the C
 name is the Nimrod identifier *exactly as spelled*:
@@ -5505,7 +5505,7 @@ the same feature under the same name.
 
 Extern pragma
 -------------
-Like ``exportc`` or ``importc`` the `extern`:idx: pragma affects name
+Like ``exportc`` or ``importc``, the ``extern`` pragma affects name
 mangling. The string literal passed to ``extern`` can be a format string:
 
 .. code-block:: Nimrod
@@ -5518,7 +5518,7 @@ In the example the external name of ``p`` is set to ``prefixp``.
 Bycopy pragma
 -------------
 
-The `bycopy`:idx: pragma can be applied to an object or tuple type and
+The ``bycopy`` pragma can be applied to an object or tuple type and
 instructs the compiler to pass the type by value to procs:
 
 .. code-block:: nimrod
@@ -5530,13 +5530,13 @@ instructs the compiler to pass the type by value to procs:
 Byref pragma
 ------------
 
-The `byref`:idx: pragma can be applied to an object or tuple type and instructs
+The ``byref`` pragma can be applied to an object or tuple type and instructs
 the compiler to pass the type by reference (hidden pointer) to procs.
 
 
 Varargs pragma
 --------------
-The `varargs`:idx: pragma can be applied to procedures only (and procedure 
+The ``varargs`` pragma can be applied to procedures only (and procedure 
 types). It tells Nimrod that the proc can take a variable number of parameters 
 after the last specified parameter. Nimrod string values will be converted to C
 strings automatically:
@@ -5549,7 +5549,7 @@ strings automatically:
 
 Union pragma
 ------------
-The `union`:idx: pragma can be applied to any ``object`` type. It means all
+The ``union`` pragma can be applied to any ``object`` type. It means all
 of the object's fields are overlaid in memory. This produces a ``union``
 instead of a ``struct`` in the generated C/C++ code. The object declaration
 then must not use inheritance or any GC'ed memory but this is currently not
@@ -5560,7 +5560,7 @@ should scan unions conservatively.
 
 Packed pragma
 -------------
-The `packed`:idx: pragma can be applied to any ``object`` type. It ensures 
+The ``packed`` pragma can be applied to any ``object`` type. It ensures 
 that the fields of an object are packed back-to-back in memory. It is useful 
 to store packets or messages from/to network or hardware drivers, and for 
 interoperability with C. Combining packed pragma with inheritance is not 
@@ -5571,7 +5571,7 @@ compile-time error. Usage with inheritance should be defined and documented.
 
 Unchecked pragma
 ----------------
-The `unchecked`:idx: pragma can be used to mark a named array as ``unchecked``
+The ``unchecked`` pragma can be used to mark a named array as ``unchecked``
 meaning its bounds are not checked. This is often useful when one wishes to
 implement his own flexibly sized arrays. Additionally an unchecked array is
 translated into a C array of undetermined size:
@@ -5606,7 +5606,7 @@ runtime size of the array.
 
 Dynlib pragma for import
 ------------------------
-With the `dynlib`:idx: pragma a procedure or a variable can be imported from
+With the ``dynlib`` pragma a procedure or a variable can be imported from
 a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). 
 The non-optional argument has to be the name of the dynamic library:
 
@@ -5696,7 +5696,7 @@ Thread pragma
 -------------
 
 A proc that is executed as a new thread of execution should be marked by the
-`thread pragma`:idx:. The compiler checks procedures marked as ``thread`` for
+``thread`` pragma. The compiler checks procedures marked as ``thread`` for
 violations of the `no heap sharing restriction`:idx:\: This restriction implies
 that it is invalid to construct a data structure that consists of memory 
 allocated from different (thread local) heaps. 
@@ -5737,7 +5737,7 @@ Future directions:
 Threadvar pragma
 ----------------
 
-A global variable can be marked with the `threadvar`:idx: pragma; it is 
+A global variable can be marked with the ``threadvar`` pragma; it is 
 a `thread-local`:idx: variable then:
 
 .. code-block:: nimrod
@@ -5789,7 +5789,7 @@ Taint mode
 ==========
 
 The Nimrod compiler and most parts of the standard library support 
-a `taint mode`:idx:. Input strings are declared with the `TaintedString`:idx: 
+a taint mode. Input strings are declared with the `TaintedString`:idx: 
 string type declared in the ``system`` module.
 
 If the taint mode is turned on (via the ``--taintMode:on`` command line 
diff --git a/doc/nimgrep.txt b/doc/nimgrep.txt
index c231bf31b..67aaa427e 100644
--- a/doc/nimgrep.txt
+++ b/doc/nimgrep.txt
@@ -1,6 +1,6 @@
-=================================
-  nimgrep  User's manual
-=================================
+=========================
+  nimgrep User's manual
+=========================
 
 :Author: Andreas Rumpf
 :Version: 0.9
diff --git a/doc/niminst.txt b/doc/niminst.txt
index ebed396e4..8d95d01c9 100644
--- a/doc/niminst.txt
+++ b/doc/niminst.txt
@@ -1,6 +1,6 @@
-=================================
-  niminst  User's manual
-=================================
+=========================
+  niminst User's manual
+=========================
 
 :Author: Andreas Rumpf
 :Version: |nimrodversion|
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index d1925547e..379e8469e 100644
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -116,7 +116,7 @@ The default build of a project is a `debug build`:idx:. To compile a
 Search path handling
 --------------------
 
-Nimrod has the concept of a global `search path`:idx: (PATH) that is queried to
+Nimrod has the concept of a global search path (PATH) that is queried to
 determine where to find imported modules or include files. If multiple files are
 found an ambiguity error is produced.
 
@@ -174,7 +174,7 @@ is not shared between different projects.
 Cross compilation

 =================

 

-To `cross compile`:idx:, use for example::

+To cross compile, use for example::

 

   nimrod c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim

 

@@ -200,7 +200,7 @@ DLL generation
 

 Nimrod supports the generation of DLLs. However, there must be only one 

 instance of the GC per process/address space. This instance is contained in

-``nimrtl.dll``. This means that every generated Nimrod `DLL`:idx: depends

+``nimrtl.dll``. This means that every generated Nimrod DLL depends

 on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command::

   

   nimrod c -d:release lib/nimrtl.nim

@@ -251,7 +251,7 @@ generator and are subject to change.
 

 NoDecl pragma

 -------------

-The `noDecl`:idx: pragma can be applied to almost any symbol (variable, proc,

+The ``noDecl`` pragma can be applied to almost any symbol (variable, proc,

 type, etc.) and is sometimes useful for interoperability with C:

 It tells Nimrod that it should not generate a declaration for the symbol in

 the C code. For example:

@@ -268,7 +268,7 @@ However, the ``header`` pragma is often the better alternative.
 

 Header pragma

 -------------

-The `header`:idx: pragma is very similar to the ``noDecl`` pragma: It can be

+The ``header`` pragma is very similar to the ``noDecl`` pragma: It can be

 applied to almost any symbol and specifies that it should not be declared

 and instead the generated code should contain an ``#include``:

 

@@ -287,7 +287,7 @@ encloses the header file in ``""`` in the generated C code.
 

 IncompleteStruct pragma

 -----------------------

-The `incompleteStruct`:idx: pragma tells the compiler to not use the 

+The ``incompleteStruct`` pragma tells the compiler to not use the 

 underlying C ``struct`` in a ``sizeof`` expression:

 

 .. code-block:: Nimrod

@@ -298,7 +298,7 @@ underlying C ``struct`` in a ``sizeof`` expression:
 

 Compile pragma

 --------------

-The `compile`:idx: pragma can be used to compile and link a C/C++ source file 

+The ``compile`` pragma can be used to compile and link a C/C++ source file 

 with the project: 

 

 .. code-block:: Nimrod

@@ -311,7 +311,7 @@ of the file.
 

 Link pragma

 -----------

-The `link`:idx: pragma can be used to link an additional file with the project: 

+The ``link`` pragma can be used to link an additional file with the project: 

 

 .. code-block:: Nimrod

   {.link: "myfile.o".}

@@ -319,7 +319,7 @@ The `link`:idx: pragma can be used to link an additional file with the project:
 

 PassC pragma
 ------------
-The `passC`:idx: pragma can be used to pass additional parameters to the C
+The ``passC`` pragma can be used to pass additional parameters to the C
 compiler like you would using the commandline switch ``--passC``:
 
 .. code-block:: Nimrod
@@ -333,7 +333,7 @@ embed parameters from an external command at compile time:
 
 PassL pragma
 ------------
-The `passL`:idx: pragma can be used to pass additional parameters to the linker
+The ``passL`` pragma can be used to pass additional parameters to the linker
 like you would using the commandline switch ``--passL``:
 
 .. code-block:: Nimrod
@@ -348,7 +348,7 @@ embed parameters from an external command at compile time:
 
 Emit pragma

 -----------

-The `emit`:idx: pragma can be used to directly affect the output of the 

+The ``emit`` pragma can be used to directly affect the output of the 

 compiler's code generator. So it makes your code unportable to other code

 generators/backends. Its usage is highly discouraged! However, it can be

 extremely useful for interfacing with `C++`:idx: or `Objective C`:idx: code.

@@ -370,7 +370,7 @@ Example:
 

 ImportCpp pragma

 ----------------

-The `importcpp`:idx: pragma can be used to import `C++`:idx: methods. The

+The ``importcpp`` pragma can be used to import `C++`:idx: methods. The

 generated code then uses the C++ method calling syntax: ``obj->method(arg)``.

 In addition with the ``header`` and ``emit`` pragmas this allows *sloppy*

 interfacing with libraries written in C++:

@@ -408,7 +408,7 @@ emits C++ code.
 

 ImportObjC pragma

 -----------------

-The `importobjc`:idx: pragma can be used to import `Objective C`:idx: methods. 

+The ``importobjc`` pragma can be used to import `Objective C`:idx: methods. 

 The generated code then uses the Objective C method calling 

 syntax: ``[obj method param1: arg]``.

 In addition with the ``header`` and ``emit`` pragmas this allows *sloppy*

@@ -458,7 +458,7 @@ emits Objective C code.
 CodegenDecl pragma
 ------------------
 
-The `codegenDecl`:idx: pragma can be used to directly influence Nimrod's code
+The ``codegenDecl`` pragma can be used to directly influence Nimrod's code
 generator. It receives a format string that determines how the variable or 
 proc is declared in the generated code:
 
@@ -473,7 +473,7 @@ proc is declared in the generated code:
 InjectStmt pragma
 -----------------
 
-The `injectStmt`:idx: pragma can be used to inject a statement before every
+The ``injectStmt`` pragma can be used to inject a statement before every
 other statement in the current module. It is only supposed to be used for
 debugging:
 
@@ -485,28 +485,28 @@ debugging:
 

 LineDir option

 --------------

-The `lineDir`:idx: option can be turned on or off. If turned on the

+The ``lineDir`` option can be turned on or off. If turned on the

 generated C code contains ``#line`` directives. This may be helpful for

 debugging with GDB.

 

 

 StackTrace option

 -----------------

-If the `stackTrace`:idx: option is turned on, the generated C contains code to

+If the ``stackTrace`` option is turned on, the generated C contains code to

 ensure that proper stack traces are given if the program crashes or an

 uncaught exception is raised.

 

 

 LineTrace option

 ----------------

-The `lineTrace`:idx: option implies the ``stackTrace`` option. If turned on,

+The ``lineTrace`` option implies the ``stackTrace`` option. If turned on,

 the generated C contains code to ensure that proper stack traces with line

 number information are given if the program crashes or an uncaught exception

 is raised.

 

 Debugger option

 ---------------

-The `debugger`:idx: option enables or disables the *Embedded Nimrod Debugger*.

+The ``debugger`` option enables or disables the *Embedded Nimrod Debugger*.

 See the documentation of endb_ for further information.

 

 

@@ -518,7 +518,7 @@ ENDB. See the documentation of `endb <endb.html>`_ for further information.
 

 Volatile pragma

 ---------------

-The `volatile`:idx: pragma is for variables only. It declares the variable as

+The ``volatile`` pragma is for variables only. It declares the variable as

 ``volatile``, whatever that means in C/C++ (its semantics are not well defined

 in C/C++).

 

@@ -530,7 +530,7 @@ DynlibOverride
 
 By default Nimrod's ``dynlib`` pragma causes the compiler to generate 
 ``GetProcAddress`` (or their Unix counterparts)
-calls to bind to a DLL. With the `dynlibOverride`:idx: command line switch this
+calls to bind to a DLL. With the ``dynlibOverride`` command line switch this
 can be prevented and then via ``--passL`` the static library can be linked
 against. For instance, to link statically against Lua this command might work
 on Linux::
@@ -556,7 +556,7 @@ for further information.
 Nimrod interactive mode

 =======================

 

-The Nimrod compiler supports an `interactive mode`:idx:. This is also known as

+The Nimrod compiler supports an interactive mode. This is also known as

 a `REPL`:idx: (*read eval print loop*). If Nimrod has been built with the 

 ``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal

 input management. To start Nimrod in interactive mode use the command 

diff --git a/doc/subexes.txt b/doc/subexes.txt
index 10e0f4cc1..3b688fd0a 100644
--- a/doc/subexes.txt
+++ b/doc/subexes.txt
@@ -1,4 +1,3 @@
-================================
 Substitution Expressions (subex)
 ================================
 
diff --git a/doc/tools.txt b/doc/tools.txt
index ae739e778..0127bc4a8 100644
--- a/doc/tools.txt
+++ b/doc/tools.txt
@@ -1,6 +1,6 @@
-=====
-Tools
-=====
+===========================
+Tools available with Nimrod
+===========================
 
 The standard distribution ships with the following tools:
 
diff --git a/doc/tut1.txt b/doc/tut1.txt
index 46eda7ae3..8c6f140eb 100644
--- a/doc/tut1.txt
+++ b/doc/tut1.txt
@@ -110,7 +110,7 @@ useful for embedding HTML code templates for example.
 Comments
 --------
 
-`Comments`:idx: start anywhere outside a string or character literal with the
+Comments start anywhere outside a string or character literal with the
 hash character ``#``. Documentation comments start with ``##``. Multiline
 comments need to be aligned at the same column:
 
@@ -224,7 +224,7 @@ different values! For safety use only constant values.
 Constants
 =========
 
-`Constants`:idx: are symbols which are bound to a value. The constant's value
+Constants are symbols which are bound to a value. The constant's value
 cannot change. The compiler must be able to evaluate the expression in a
 constant declaration at compile time:
 
@@ -369,7 +369,7 @@ he types in nothing (only presses RETURN).
 For statement
 -------------
 
-The `for`:idx: statement is a construct to loop over any element an *iterator*
+The ``for`` statement is a construct to loop over any element an *iterator*
 provides. The example uses the built-in ``countup`` iterator:
 
 .. code-block:: nimrod
@@ -481,7 +481,7 @@ Example:
   else:
     echo("unknown operating system")
 
-The `when`:idx: statement is almost identical to the ``if`` statement with some
+The ``when`` statement is almost identical to the ``if`` statement with some
 differences:
 
 * Each condition has to be a constant expression since it is evaluated by the
@@ -791,7 +791,7 @@ However, this cannot be done for mutually recursive procedures:
 
 Here ``odd`` depends on ``even`` and vice versa. Thus ``even`` needs to be
 introduced to the compiler before it is completely defined. The syntax for
-such a `forward declaration`:idx: is simple: just omit the ``=`` and the
+such a forward declaration is simple: just omit the ``=`` and the
 procedure's body.
 
 Later versions of the language may get rid of the need for forward
@@ -863,7 +863,7 @@ that are available for them in detail.
 Booleans
 --------
 
-The `boolean`:idx: type is named ``bool`` in Nimrod and consists of the two
+The boolean type is named ``bool`` in Nimrod and consists of the two
 pre-defined values ``true`` and ``false``. Conditions in while,
 if, elif, when statements need to be of type bool.
 
@@ -1030,7 +1030,7 @@ Enumeration and object types cannot be defined on the fly, but only within a
 
 Enumerations
 ------------
-A variable of an `enumeration`:idx: type can only be assigned a value of a
+A variable of an enumeration type can only be assigned a value of a
 limited set. This set consists of ordered symbols. Each symbol is mapped
 to an integer value internally. The first symbol is represented
 at runtime by 0, the second by 1 and so on. Example:
@@ -1069,7 +1069,7 @@ An explicit ordered enum can have *holes*:
 Ordinal types
 -------------
 Enumerations without holes, integer types, ``char`` and ``bool`` (and
-subranges) are called `ordinal`:idx: types. Ordinal types have quite
+subranges) are called ordinal types. Ordinal types have quite
 a few special operations:
 
 -----------------     --------------------------------------------------------
@@ -1094,7 +1094,7 @@ checks turned on.)
 
 Subranges
 ---------
-A `subrange`:idx: type is a range of values from an integer or enumeration type
+A subrange type is a range of values from an integer or enumeration type
 (the base type). Example:
 
 .. code-block:: nimrod
@@ -1117,7 +1117,7 @@ avoid this common programming error.
 
 Sets
 ----
-The `set type`:idx: models the mathematical notion of a set. The set's
+The set type models the mathematical notion of a set. The set's
 basetype can only be an ordinal type. The reason is that sets are implemented
 as high performance bit vectors.
 
@@ -1161,7 +1161,7 @@ constants that should be ``or``'ed together.
 
 Arrays
 ------
-An `array`:idx: is a simple fixed length container. Each element in
+An array is a simple fixed length container. Each element in
 the array has the same type. The array's index type can be any ordinal type.
 
 Arrays can be constructed via ``[]``: 
@@ -1253,7 +1253,7 @@ to specify a range from zero to the specified index minus one:
 
 Sequences
 ---------
-`Sequences`:idx: are similar to arrays but of dynamic length which may change
+Sequences are similar to arrays but of dynamic length which may change
 during runtime (like strings). Since sequences are resizable they are always
 allocated on the heap and garbage collected.
 
@@ -1471,7 +1471,7 @@ won't compile:
 
 Reference and pointer types
 ---------------------------
-References (similar to `pointers`:idx: in other programming languages) are a
+References (similar to pointers in other programming languages) are a
 way to introduce many-to-one relationships. This means different references can
 point to and modify the same location in memory.
 
@@ -1513,7 +1513,7 @@ If a reference points to *nothing*, it has the value ``nil``.
 
 Procedural type
 ---------------
-A `procedural type`:idx: is a (somewhat abstract) pointer to a procedure.
+A procedural type is a (somewhat abstract) pointer to a procedure.
 ``nil`` is an allowed value for a variable of a procedural type.
 Nimrod uses procedural types to achieve `functional`:idx: programming
 techniques.
@@ -1543,7 +1543,7 @@ listed in the `manual <manual.html>`_.
 
 Modules
 =======
-Nimrod supports splitting a program into pieces with a `module`:idx: concept.
+Nimrod supports splitting a program into pieces with a module concept.
 Each module is in its own file. Modules enable `information hiding`:idx: and
 `separate compilation`:idx:. A module may gain access to symbols of another
 module by the `import`:idx: statement. Only top-level symbols that are marked
@@ -1698,7 +1698,7 @@ define a shorter alias to use when qualifying symbols.
 
 Include statement
 -----------------
-The `include`:idx: statement does something fundamentally different than
+The ``include`` statement does something fundamentally different than
 importing a module: it merely includes the contents of a file. The ``include``
 statement is useful to split up a large module into several files:
 
diff --git a/doc/tut2.txt b/doc/tut2.txt
index ea6733c07..11b485f50 100644
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -135,7 +135,7 @@ The ``EInvalidObjectConversion`` exception is raised if ``x`` is not a
 Object variants
 ---------------
 Often an object hierarchy is overkill in certain situations where simple
-`variant`:idx: types are needed.
+variant types are needed.
 
 An example:
 
@@ -182,7 +182,7 @@ bound to a class. This has disadvantages:
   ``join`` a string method or an array method?
 
 Nimrod avoids these problems by not assigning methods to a class. All methods
-in Nimrod are `multi-methods`:idx:. As we will see later, multi-methods are
+in Nimrod are multi-methods. As we will see later, multi-methods are
 distinguished from procs only for dynamic binding purposes.
 
 
@@ -194,7 +194,7 @@ The syntax ``obj.method(args)`` can be used instead of ``method(obj, args)``.
 If there are no remaining arguments, the parentheses can be omitted:
 ``obj.len`` (instead of ``len(obj)``).
 
-This `method call syntax`:idx: is not restricted to objects, it can be used
+This method call syntax is not restricted to objects, it can be used
 for any type:
 
 .. code-block:: nimrod
@@ -343,7 +343,7 @@ evaluation or dead code elimination do not work with methods.
 Exceptions
 ==========
 
-In Nimrod `exceptions`:idx: are objects. By convention, exception types are
+In Nimrod exceptions are objects. By convention, exception types are
 prefixed with an 'E', not 'T'. The `system <system.html>`_ module defines an
 exception hierarchy that you might want to stick to. Exceptions derive from
 E_Base, which provides the common interface.
@@ -380,7 +380,7 @@ the template ``newException`` in the ``system`` module can be used:
 Try statement
 -------------
 
-The `try`:idx: statement handles exceptions:
+The ``try`` statement handles exceptions:
 
 .. code-block:: nimrod
   # read the first two lines of a text file that should contain numbers
@@ -513,7 +513,7 @@ procs with the list of raised exceptions. You can read more about Nimrod's
 Generics
 ========
 
-`Generics`:idx: are Nimrod's means to parametrize procs, iterators or types
+Generics are Nimrod's means to parametrize procs, iterators or types
 with `type parameters`:idx:. They are most useful for efficient type safe
 containers:
 
@@ -714,9 +714,9 @@ know how the Nimrod concrete syntax is converted to an abstract syntax tree
 (AST). The AST is documented in the `macros <macros.html>`_ module.
 
 Once your macro is finished, there are two ways to invoke it:
-(1) invoking a macro like a procedure call (`expression macros`:idx:)
+(1) invoking a macro like a procedure call (expression macros)
 (2) invoking a macro with the special ``macrostmt``
-    syntax (`statement macros`:idx:)
+    syntax (statement macros)
 
 
 Expression Macros
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index cead17f2b..fdbca4ca8 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -23,7 +23,8 @@
 ## many options and tweaking, but you are not limited to snippets and can
 ## generate `LaTeX documents <https://en.wikipedia.org/wiki/LaTeX>`_ too.
 
-import strutils, os, hashes, strtabs, rstast, rst, highlite
+import strutils, os, hashes, strtabs, rstast, rst, highlite, tables, sequtils,
+  algorithm
 
 const
   HtmlExt = "html"
@@ -56,6 +57,9 @@ type
     currentSection: string ## \
     ## Stores the empty string or the last headline/overline found in the rst
     ## document, so it can be used as a prettier name for term index generation.
+    seenIndexTerms: TTable[string, int] ## \
+    ## Keeps count of same text index terms to generate different identifiers
+    ## for hyperlinks. See renderIndexTerm proc for details.
   
   PDoc = var TRstGenerator ## Alias to type less.
 
@@ -68,10 +72,16 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
   ##
   ## You need to call this before using a ``TRstGenerator`` with any other
   ## procs in this module. Pass a non ``nil`` ``PStringTable`` value as
-  ## ``config`` with parameters used by the HTML output generator.  If you
-  ## don't know what to use, pass the results of the ``defaultConfig()`` proc.
-  ## The ``filename`` is symbolic and used only for error reporting, you can
-  ## pass any non ``nil`` string here.
+  ## `config` with parameters used by the HTML output generator.  If you don't
+  ## know what to use, pass the results of the `defaultConfig()
+  ## <#defaultConfig>_` proc.
+  ##
+  ## The `filename` parameter will be used for error reporting and creating
+  ## index hyperlinks to the file, but you can pass an empty string here if you
+  ## are parsing a stream in memory. If `filename` ends with the ``.nim``
+  ## extension, the title for the document will be set by default to ``Module
+  ## filename``.  This default title can be overriden by the embedded rst, but
+  ## it helps to prettify the generated index if no title is found.
   ##
   ## The ``TRstParseOptions``, ``TFindFileHandler`` and ``TMsgHandler`` types
   ## are defined in the the `packages/docutils/rst module <rst.html>`_.
@@ -111,6 +121,10 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
   g.options = options
   g.findFile = findFile
   g.currentSection = ""
+  let fileParts = filename.splitFile
+  if fileParts.ext == ".nim":
+    g.currentSection = "Module " & fileParts.name
+  g.seenIndexTerms = initTable[string, int]()
   g.msgHandler = msgHandler
   
   let s = config["split.item.toc"]
@@ -120,8 +134,8 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget,
 proc writeIndexFile*(g: var TRstGenerator, outfile: string) =
   ## Writes the current index buffer to the specified output file.
   ##
-  ## You previously need to add entries to the index with the ``setIndexTerm``
-  ## proc. If the index is empty the file won't be created.
+  ## You previously need to add entries to the index with the `setIndexTerm()
+  ## <#setIndexTerm>`_ proc. If the index is empty the file won't be created.
   if g.theIndex.len > 0: writeFile(outfile, g.theIndex)
   
 proc addXmlChar(dest: var string, c: char) = 
@@ -207,6 +221,9 @@ proc dispA(target: TOutputTarget, dest: var string,
   if target != outLatex: addf(dest, xml, args)
   else: addf(dest, tex, args)
   
+proc `or`(x, y: string): string {.inline.} =
+  result = if x.isNil: y else: x
+
 proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string)
   ## Writes into ``result`` the rst ast ``n`` using the ``d`` configuration.
   ##
@@ -224,7 +241,7 @@ proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string)
 proc renderAux(d: PDoc, n: PRstNode, result: var string) = 
   for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], result)
 
-proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) = 
+proc renderAux(d: PDoc, n: PRstNode, frmtA, frmtB: string, result: var string) =
   var tmp = ""
   for i in countup(0, len(n)-1): renderRstToOut(d, n.sons[i], tmp)
   if d.target != outLatex:
@@ -254,25 +271,45 @@ proc setIndexTerm*(d: var TRstGenerator, id, term: string,
                    linkTitle, linkDesc = "") =
   ## Adds a `term` to the index using the specified hyperlink identifier.
   ##
-  ## The ``d.theIndex`` string will be used to append the term in the format
-  ## ``term<tab>file#id``. The anchor will be the based on the name of the file
-  ## currently being parsed plus the `id`, which will be appended after a hash.
+  ## A new entry will be added to the index using the format
+  ## ``term<tab>file#id``. The file part will come from the `filename`
+  ## parameter used in a previous call to the `initRstGenerator()
+  ## <#initRstGenerator>`_ proc.
+  ##
+  ## The `id` will be appended with a hash character only if its length is not
+  ## zero, otherwise no specific anchor will be generated. In general you
+  ## should only pass an empty `id` value for the title of standalone rst
+  ## documents (they are special for the `mergeIndexes() <#mergeIndexes>`_
+  ## proc, see `Index (idx) file format <docgen.html#index-idx-file-format>`_
+  ## for more information). Unlike other index terms, title entries are
+  ## inserted at the beginning of the accumulated buffer to maintain a logical
+  ## order of entries.
+  ##
   ## If `linkTitle` or `linkDesc` are not the empty string, two additional
   ## columns with their contents will be added.
   ##
-  ## The index won't be written to disk unless you call ``writeIndexFile``. The
-  ## purpose of the index is documented in the `docgen tools guide
-  ## <docgen.html#index-switch>`_.
-  d.theIndex.add(term)
-  d.theIndex.add('\t')
+  ## The index won't be written to disk unless you call `writeIndexFile()
+  ## <#writeIndexFile>`_. The purpose of the index is documented in the `docgen
+  ## tools guide <docgen.html#index-switch>`_.
+  assert(not d.theIndex.isNil)
+  var
+    entry = term
+    isTitle = false
+  entry.add('\t')
   let htmlFile = changeFileExt(extractFilename(d.filename), HtmlExt)
-  d.theIndex.add(htmlFile)
-  d.theIndex.add('#')
-  d.theIndex.add(id)
+  entry.add(htmlFile)
+  if id.len > 0:
+    entry.add('#')
+    entry.add(id)
+  else:
+    isTitle = true
   if linkTitle.len > 0 or linkDesc.len > 0:
-    d.theIndex.add('\t' & linkTitle.quoteIndexColumn)
-    d.theIndex.add('\t' & linkDesc.quoteIndexColumn)
-  d.theIndex.add("\n")
+    entry.add('\t' & linkTitle.quoteIndexColumn)
+    entry.add('\t' & linkDesc.quoteIndexColumn)
+  entry.add("\n")
+
+  if isTitle: d.theIndex.insert(entry)
+  else: d.theIndex.add(entry)
 
 proc hash(n: PRstNode): int =
   if n.kind == rnLeaf:
@@ -283,8 +320,20 @@ proc hash(n: PRstNode): int =
       result = result !& hash(n.sons[i])
     result = !$result
 
-proc renderIndexTerm(d: PDoc, n: PRstNode, result: var string) =
-  let id = rstnodeToRefname(n) & '_' & $abs(hash(n))
+proc renderIndexTerm*(d: PDoc, n: PRstNode, result: var string) =
+  ## Renders the string decorated within \`foobar\`\:idx\: markers.
+  ##
+  ## Additionally adds the encosed text to the index as a term. Since we are
+  ## interested in different instances of the same term to have different
+  ## entries, a table is used to keep track of the amount of times a term has
+  ## previously appeared to give a different identifier value for each.
+  let refname = n.rstnodeToRefname
+  if d.seenIndexTerms.hasKey(refname):
+    d.seenIndexTerms[refname] = d.seenIndexTerms[refname] + 1
+  else:
+    d.seenIndexTerms[refname] = 1
+  let id = refname & '_' & $d.seenIndexTerms[refname]
+
   var term = ""
   renderAux(d, n, term)
   setIndexTerm(d, id, term, d.currentSection)
@@ -298,12 +347,34 @@ type
     linkTitle: string ## If not nil, contains a prettier text for the href
     linkDesc: string ## If not nil, the title attribute of the final href
 
+  TIndexedDocs {.pure, final.} = TTable[TIndexEntry, seq[TIndexEntry]] ## \
+    ## Contains the index sequences for doc types.
+    ##
+    ## The key is a *fake* TIndexEntry which will contain the title of the
+    ## document in the `keyword` field and `link` will contain the html
+    ## filename for the document. `linkTitle` and `linkDesc` will be nil.
+    ##
+    ## The value indexed by this TIndexEntry is a sequence with the real index
+    ## entries found in the ``.idx`` file.
+
+
 proc cmp(a, b: TIndexEntry): int =
   ## Sorts two ``TIndexEntry`` first by `keyword` field, then by `link`.
   result = cmpIgnoreStyle(a.keyword, b.keyword)
   if result == 0:
     result = cmpIgnoreStyle(a.link, b.link)
 
+proc hash(x: TIndexEntry): THash =
+  ## Returns the hash for the combined fields of the type.
+  ##
+  ## The hash is computed as the chained hash of the individual string hashes.
+  assert(not x.keyword.isNil)
+  assert(not x.link.isNil)
+  result = x.keyword.hash !& x.link.hash
+  result = result !& (x.linkTitle or "").hash
+  result = result !& (x.linkDesc or "").hash
+  result = !$result
+
 proc `<-`(a: var TIndexEntry, b: TIndexEntry) =
   shallowCopy a.keyword, b.keyword
   shallowCopy a.link, b.link
@@ -332,43 +403,18 @@ proc sortIndex(a: var openArray[TIndexEntry]) =
       a[j] <- v
     if h == 1: break
 
-proc mergeIndexes*(dir: string): string =
-  ## merges all index files in `dir` and returns the generated index as HTML.
-  ## The result is no full HTML for flexibility.
-  var a: seq[TIndexEntry]
-  newSeq(a, 15_000)
-  setLen(a, 0)
-  var L = 0
-  for kind, path in walkDir(dir):
-    if kind == pcFile and path.endsWith(IndexExt):
-      for line in lines(path):
-        let s = line.find('\t')
-        if s < 0: continue
-        setLen(a, L+1)
-        a[L].keyword = line.substr(0, s-1)
-        a[L].link = line.substr(s+1)
-        if a[L].link.find('\t') > 0:
-          let extraCols = a[L].link.split('\t')
-          a[L].link = extraCols[0]
-          assert extraCols.len == 3
-          a[L].linkTitle = extraCols[1].unquoteIndexColumn
-          a[L].linkDesc = extraCols[2].unquoteIndexColumn
-        else:
-          a[L].linkTitle = nil
-          a[L].linkDesc = nil
-        inc L
-  sortIndex(a)
+proc generateSymbolIndex(symbols: seq[TIndexEntry]): string =
   result = ""
   var i = 0
-  while i < L:
-    result.addf("<dt><span>$1</span></dt><ul class=\"simple\"><dd>\n", 
-                [a[i].keyword])
+  while i < symbols.len:
+    result.addf("<dt><span>$1:</span></dt><ul class=\"simple\"><dd>\n",
+                [symbols[i].keyword])
     var j = i
-    while j < L and a[i].keyword == a[j].keyword:
+    while j < symbols.len and symbols[i].keyword == symbols[j].keyword:
       let
-        url = a[j].link
-        text = if not a[j].linkTitle.isNil: a[j].linkTitle else: url
-        desc = if not a[j].linkDesc.isNil: a[j].linkDesc else: ""
+        url = symbols[j].link
+        text = if not symbols[j].linkTitle.isNil: symbols[j].linkTitle else: url
+        desc = if not symbols[j].linkDesc.isNil: symbols[j].linkDesc else: ""
       if desc.len > 0:
         result.addf("""<li><a class="reference external"
           title="$3" href="$1">$2</a></li>
@@ -379,9 +425,246 @@ proc mergeIndexes*(dir: string): string =
       inc j
     result.add("</ul></dd>\n")
     i = j
+
+proc isDocumentationTitle(hyperlink: string): bool =
+  ## Returns true if the hyperlink is actually a documentation title.
+  ##
+  ## Documentation titles lack the hash. See `mergeIndexes() <#mergeIndexes>`_
+  ## for a more detailed explanation.
+  result = hyperlink.find('#') < 0
+
+proc stripTOCLevel(s: string): tuple[level: int, text: string] =
+  ## Returns the *level* of the toc along with the text without it.
+  for c in 0 .. <s.len:
+    result.level = c
+    if s[c] != ' ': break
+  result.text = s[result.level .. <s.len]
+
+proc indentToLevel(level: var int, newLevel: int): string =
+  ## Returns the sequence of <ul>|</ul> characters to switch to `newLevel`.
+  ##
+  ## The amount of lists added/removed will be based on the `level` variable,
+  ## which will be reset to `newLevel` at the end of the proc.
+  result = ""
+  if level == newLevel:
+    return
+  if newLevel > level:
+    result = repeatStr(newLevel - level, "<ul>")
+  else:
+    result = repeatStr(level - newLevel, "</ul>")
+  level = newLevel
+
+proc generateDocumentationTOC(entries: seq[TIndexEntry]): string =
+  ## Returns the sequence of index entries in an HTML hierarchical list.
+  result = ""
+  # Build a list of levels and extracted titles to make processing easier.
+  var
+    titleRef: string
+    levels: seq[tuple[level: int, text: string]]
+    L = 0
+    level = 1
+  levels.newSeq(entries.len)
+  for entry in entries:
+    let (rawLevel, rawText) = stripTOCLevel(entry.linkTitle or entry.keyword)
+    if rawLevel < 1:
+      # This is a normal symbol, push it *inside* one level from the last one.
+      levels[L].level = level + 1
+      # Also, ignore the linkTitle and use directly the keyword.
+      levels[L].text = entry.keyword
+    else:
+      # The level did change, update the level indicator.
+      level = rawLevel
+      levels[L].level = rawLevel
+      levels[L].text = rawText
+    inc L
+
+  # Now generate hierarchical lists based on the precalculated levels.
+  result = "<ul>\n"
+  level = 1
+  L = 0
+  while L < entries.len:
+    let link = entries[L].link
+    if link.isDocumentationTitle:
+      titleRef = link
+    else:
+      result.add(level.indentToLevel(levels[L].level))
+      result.add("<li><a href=\"" & link & "\">" &
+        levels[L].text & "</a>\n")
+    inc L
+  result.add(level.indentToLevel(1) & "</ul>\n")
+  assert(not titleRef.isNil,
+    "Can't use this proc on an API index, docs always have a title entry")
+
+proc generateDocumentationIndex(docs: TIndexedDocs): string =
+  ## Returns all the documentation TOCs in an HTML hierarchical list.
+  result = ""
+
+  # Sort the titles to generate their toc in alphabetical order.
+  var titles = toSeq(keys[TIndexEntry, seq[TIndexEntry]](docs))
+  sort(titles, cmp)
+
+  for title in titles:
+    let tocList = generateDocumentationTOC(docs[title])
+    result.add("<ul><li><a href=\"" &
+      title.link & "\">" & title.keyword & "</a>\n" & tocList & "</ul>\n")
+
+proc generateDocumentationJumps(docs: TIndexedDocs): string =
+  ## Returns a plain list of hyperlinks to documentation TOCs in HTML.
+  result = "Documents: "
+
+  # Sort the titles to generate their toc in alphabetical order.
+  var titles = toSeq(keys[TIndexEntry, seq[TIndexEntry]](docs))
+  sort(titles, cmp)
+
+  var chunks: seq[string] = @[]
+  for title in titles:
+    chunks.add("<a href=\"" & title.link & "\">" & title.keyword & "</a>")
+
+  result.add(chunks.join(", ") & ".<br>")
+
+proc generateModuleJumps(modules: seq[string]): string =
+  ## Returns a plain list of hyperlinks to the list of modules.
+  result = "Modules: "
+
+  var chunks: seq[string] = @[]
+  for name in modules:
+    chunks.add("<a href=\"" & name & ".html\">" & name & "</a>")
+
+  result.add(chunks.join(", ") & ".<br>")
+
+proc readIndexDir(dir: string):
+    tuple[modules: seq[string], symbols: seq[TIndexEntry], docs: TIndexedDocs] =
+  ## Walks `dir` reading ``.idx`` files converting them in TIndexEntry items.
+  ##
+  ## Returns the list of found module names, the list of free symbol entries
+  ## and the different documentation indexes. The list of modules is sorted.
+  ## See the documentation of ``mergeIndexes`` for details.
+  result.modules = @[]
+  result.docs = initTable[TIndexEntry, seq[TIndexEntry]](32)
+  newSeq(result.symbols, 15_000)
+  setLen(result.symbols, 0)
+  var L = 0
+  # Scan index files and build the list of symbols.
+  for kind, path in walkDir(dir):
+    if kind == pcFile and path.endsWith(IndexExt):
+      var
+        fileEntries: seq[TIndexEntry]
+        title: TIndexEntry
+        F = 0
+      newSeq(fileEntries, 500)
+      setLen(fileEntries, 0)
+      for line in lines(path):
+        let s = line.find('\t')
+        if s < 0: continue
+        setLen(fileEntries, F+1)
+        fileEntries[F].keyword = line.substr(0, s-1)
+        fileEntries[F].link = line.substr(s+1)
+        # See if we detect a title, a link without a `#foobar` trailing part.
+        if title.keyword.isNil and fileEntries[F].link.isDocumentationTitle:
+          title.keyword = fileEntries[F].keyword
+          title.link = fileEntries[F].link
+
+        if fileEntries[F].link.find('\t') > 0:
+          let extraCols = fileEntries[F].link.split('\t')
+          fileEntries[F].link = extraCols[0]
+          assert extraCols.len == 3
+          fileEntries[F].linkTitle = extraCols[1].unquoteIndexColumn
+          fileEntries[F].linkDesc = extraCols[2].unquoteIndexColumn
+        else:
+          fileEntries[F].linkTitle = nil
+          fileEntries[F].linkDesc = nil
+        inc F
+      # Depending on type add this to the list of symbols or table of APIs.
+      if title.keyword.isNil:
+        for i in 0 .. <F:
+          # Don't add to symbols TOC entries (they start with a whitespace).
+          let toc = fileEntries[i].linkTitle
+          if not toc.isNil and toc.len > 0 and toc[0] == ' ':
+            continue
+          # Ok, non TOC entry, add it.
+          setLen(result.symbols, L + 1)
+          result.symbols[L] = fileEntries[i]
+          inc L
+        result.modules.add(path.splitFile.name)
+      else:
+        # Generate the symbolic anchor for index quickjumps.
+        title.linkTitle = "doc_toc_" & $result.docs.len
+        result.docs[title] = fileEntries
+
+  sort(result.modules, system.cmp)
+
+proc mergeIndexes*(dir: string): string =
+  ## Merges all index files in `dir` and returns the generated index as HTML.
+  ##
+  ## This proc will first scan `dir` for index files with the ``.idx``
+  ## extension previously created by commands like ``nimrod doc|rst2html``
+  ## which use the ``--index:on`` switch. These index files are the result of
+  ## calls to `setIndexTerm() <#setIndexTerm>`_ and `writeIndexFile()
+  ## <#writeIndexFile>`_, so they are simple tab separated files.
+  ##
+  ## As convention this proc will split index files into two categories:
+  ## documentation and API. API indices will be all joined together into a
+  ## single big sorted index, making the bulk of the final index. This is good
+  ## for API documentation because many symbols are repated in different
+  ## modules. On the other hand, documentation indices are essentially table of
+  ## contents plus a few special markers. These documents will be rendered in a
+  ## separate section which tries to maintain the order and hierarchy of the
+  ## symbols in the index file.
+  ##
+  ## To differentiate between a documentation and API file a convention is
+  ## used: indices which contain one entry without the HTML hash character (#)
+  ## will be considered `documentation`, since this hash-less entry is the
+  ## explicit title of the document.  Indices without this explicit entry will
+  ## be considered `generated API` extracted out of a source ``.nim`` file.
+  ##
+  ## Returns the merged and sorted indices into a single HTML block which can
+  ## be further embedded into nimdoc templates.
+  var (modules, symbols, docs) = readIndexDir(dir)
+  assert(not symbols.isNil)
+
+  result = ""
+  # Generate a quick jump list of documents.
+  if docs.len > 0:
+    result.add(generateDocumentationJumps(docs))
+    result.add("<p />")
+
+  # Generate hyperlinks to all the linked modules.
+  if modules.len > 0:
+    result.add(generateModuleJumps(modules))
+    result.add("<p />")
+
+  # Generate the HTML block with API documents.
+  if docs.len > 0:
+    result.add("<h2>Documentation files</h2>\n")
+    result.add(generateDocumentationIndex(docs))
+
+  # Generate the HTML block with symbols.
+  if symbols.len > 0:
+    sortIndex(symbols)
+    result.add("<h2>API symbols</h2>\n")
+    result.add(generateSymbolIndex(symbols))
+
   
-# ----------------------------------------------------------------------------      
-  
+# ----------------------------------------------------------------------------
+
+proc stripTOCHTML(s: string): string =
+  ## Ugly quick hack to remove HTML tags from TOC titles.
+  ##
+  ## A TTocEntry.header field already contains rendered HTML tags. Instead of
+  ## implementing a proper version of renderRstToOut() which recursively
+  ## renders an rst tree to plain text, we simply remove text found between
+  ## angled brackets. Given the limited possibilities of rst inside TOC titles
+  ## this should be enough.
+  result = s
+  var first = result.find('<')
+  while first >= 0:
+    let last = result.find('>', first)
+    if last < 0:
+      # Abort, since we didn't found a closing angled bracket.
+      return
+    result.delete(first, last)
+    first = result.find('<', first)
+
 proc renderHeadline(d: PDoc, n: PRstNode, result: var string) = 
   var tmp = ""
   for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp)
@@ -393,27 +676,30 @@ proc renderHeadline(d: PDoc, n: PRstNode, result: var string) =
     d.tocPart[length].refname = refname
     d.tocPart[length].n = n
     d.tocPart[length].header = tmp
-    
-    dispA(d.target, result,
-        "\n<h$1><a class=\"toc-backref\" id=\"$2\" href=\"#$2_toc\">$3</a></h$1>", 
-        "\\rsth$4{$3}\\label{$2}\n", [$n.level, 
-        d.tocPart[length].refname, tmp, 
-        $chr(n.level - 1 + ord('A'))])
+
+    dispA(d.target, result, "\n<h$1><a class=\"toc-backref\" " &
+      "id=\"$2\" href=\"#$2_toc\">$3</a></h$1>", "\\rsth$4{$3}\\label{$2}\n",
+      [$n.level, d.tocPart[length].refname, tmp, $chr(n.level - 1 + ord('A'))])
   else:
     dispA(d.target, result, "\n<h$1 id=\"$2\">$3</h$1>", 
                             "\\rsth$4{$3}\\label{$2}\n", [
         $n.level, refname, tmp, 
         $chr(n.level - 1 + ord('A'))])
-  
+
+  # Generate index entry using spaces to indicate TOC level for the output HTML.
+  assert n.level >= 0
+  setIndexTerm(d, refname, tmp.stripTOCHTML,
+    repeatChar(max(0, n.level), ' ') & tmp)
+
 proc renderOverline(d: PDoc, n: PRstNode, result: var string) = 
   if d.meta[metaTitle].len == 0:
-    d.currentSection = d.meta[metaTitle]
     for i in countup(0, len(n)-1):
       renderRstToOut(d, n.sons[i], d.meta[metaTitle])
+    d.currentSection = d.meta[metaTitle]
   elif d.meta[metaSubtitle].len == 0:
-    d.currentSection = d.meta[metaSubtitle]
     for i in countup(0, len(n)-1):
       renderRstToOut(d, n.sons[i], d.meta[metaSubtitle])
+    d.currentSection = d.meta[metaSubtitle]
   else:
     var tmp = ""
     for i in countup(0, len(n) - 1): renderRstToOut(d, n.sons[i], tmp)
@@ -428,7 +714,8 @@ proc renderTocEntry(d: PDoc, e: TTocEntry, result: var string) =
     "<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])
 
-proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, result: var string) =
+proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int,
+    result: var string) =
   var tmp = ""
   while j <= high(d.tocPart): 
     var a = abs(d.tocPart[j].n.level)
@@ -572,7 +859,8 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
           [tmp])
   of rnField: renderField(d, n, result)
   of rnFieldName: 
-    renderAux(d, n, "<th class=\"docinfo-name\">$1:</th>", "\\item[$1:]", result)
+    renderAux(d, n, "<th class=\"docinfo-name\">$1:</th>",
+                    "\\item[$1:]", result)
   of rnFieldBody: 
     renderAux(d, n, "<td>$1</td>", " $1\n", result)
   of rnIndex: 
@@ -631,8 +919,9 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
   of rnRef: 
     var tmp = ""
     renderAux(d, n, tmp)
-    dispA(d.target, result, "<a class=\"reference external\" href=\"#$2\">$1</a>", 
-                            "$1\\ref{$2}", [tmp, rstnodeToRefname(n)])
+    dispA(d.target, result,
+      "<a class=\"reference external\" href=\"#$2\">$1</a>",
+      "$1\\ref{$2}", [tmp, rstnodeToRefname(n)])
   of rnStandaloneHyperlink: 
     renderAux(d, n, 
       "<a class=\"reference external\" href=\"$1\">$1</a>", 
@@ -642,9 +931,9 @@ proc renderRstToOut(d: PDoc, n: PRstNode, result: var string) =
     var tmp1 = ""
     renderRstToOut(d, n.sons[0], tmp0)
     renderRstToOut(d, n.sons[1], tmp1)
-    dispA(d.target, result, "<a class=\"reference external\" href=\"$2\">$1</a>", 
-                   "\\href{$2}{$1}", 
-                   [tmp0, tmp1])
+    dispA(d.target, result,
+      "<a class=\"reference external\" href=\"$2\">$1</a>",
+      "\\href{$2}{$1}", [tmp0, tmp1])
   of rnDirArg, rnRaw: renderAux(d, n, result)
   of rnRawHtml:
     if d.target != outLatex: