Alternate Markup Languages
==========================

.. $Id: manual-othermarkup.txt 1598 2007-09-06 13:02:50Z dvarrazzo $

Epydoc's default markup language is epytext__, a lightweight markup language
that's easy to write and to understand. But if epytext is not powerful enough
for you, or doesn't suit your needs, epydoc also supports three alternate
markup languages:

.. __: `The Epytext Markup Language`_

reStructuredText__
    is an "easy-to-read, what-you-see-is-what-you-get plaintext markup syntax".
    It is more powerful than epytext (e.g., it includes markup for tables and
    footnotes); but it is also more complex, and sometimes harder to read.

    .. __: http://docutils.sourceforge.net/rst.html

Javadoc__
    is a documentation markup language that was developed for Java. It consists
    of HTML, augmented by a set of special tagged fields.

    .. __: http://java.sun.com/j2se/javadoc/

Plaintext docstrings
    are rendered verbatim (preserving whitespace).

To specify the markup language for a module, you should define a module-level
string variable ``__docformat__``, containing the name of the module's markup
language. The name of the markup language may optionally be followed by a
language code (such as ``en`` for English). Conventionally, the definition of
the ``__docformat__`` variable immediately follows the module's docstring:

.. python::

    # widget.py
    """
    Graphical support for `gizmos` and `widgets`.
    """
    __docformat__ = "restructuredtext en"
    #[...]

To change the default markup language from the command line, use the
``--docformat`` option. For example, the following command generates API
documentation for the existing regular expression package ``re``, which uses
plaintext markup::

    [epydoc]$ epydoc --docformat plaintext re


reStructuredText
----------------

reStructuredText is a markup language that was developed in conjunction with
Docutils_. In order to parse reStructuredText docstrings, Docutils 0.3 or
higher must be installed. If Docutils is not installed, then reStructuredText
docstrings will be rendered as plaintext. Docutils can be downloaded from the
`Docutils SourceForge page`_.

.. _Docutils: http://docutils.sourceforge.net/
.. _Docutils SourceForge page:
    http://sourceforge.net/project/showfiles.php?group_id=38414


Default role
''''''''''''

Epydoc replaces the Docutils' default `interpreted text role`_ with
the creation of  `documentation crossreference links`_. If you want to create
a crossreference link to the ``somemod.Example`` class, you can put backquotes
around your test, typing::

    `somemod.Example`

.. _interpreted text role:  http://docutils.sourceforge.net/
                            docs/ref/rst/roles.html


Consolidated Fields
'''''''''''''''''''

In addition to the `standard set of fields`_, the reStructruedText parser also
supports *consolidated fields*, which combine the documentation for several
objects into a single field. For example, a single ``:Parameters:`` field is
often used to describe all of the parameters for a function or method:

.. python::

    def fox_speed(size, weight, age):
        """
        Return the maximum speed for a fox.

        :Parameters:
        - `size`: The size of the fox (in meters)
        - `weight`: The weight of the fox (in stones)
        - `age`: The age of the fox (in years)
        """
        #[...]

.. _standard set of fields: `Epydoc fields`_

Epydoc will automatically extract information about each parameter from this
list. These *consolidated fields* may be written using either a `bulleted
list`_ or a `definition list`_.

* If a consolidated field is written as a *bulleted list*, then each list item
  must begin with the field's argument, marked as `interpreted text`_, and
  followed by a colon or dash.
* If a consolidated field is written as a *definition list*, then each
  definition item's term should contain the field's argument, (it is not
  mandatory for it being marked as interpreted text).

.. _bulleted list:      http://docutils.sourceforge.net/
                        docs/user/rst/quickref.html#bullet-lists
.. _definition list:    http://docutils.sourceforge.net/
                        docs/user/rst/quickref.html#definition-lists
.. _interpreted text:   http://docutils.sourceforge.net/
                        docs/user/rst/quickref.html#inline-markup

The term classifier, if present, is used to specify the associated type. The
following example shows the use of a definition list to define a consolidated
field (note that docutils requires a space before and after the '``:``' used
to mark classifiers).

.. python::

    def fox_speed(size, weight, age):
        """
        Return the maximum speed for a fox.

        :Parameters:
          size
            The size of the fox (in meters)
          weight : float
            The weight of the fox (in stones)
          age : int
            The age of the fox (in years)
        """
        #[...]

The following consolidated fields are currently supported by epydoc:

.. list-table::
   :header-rows: 1

   * - Consolidated Field Tag
     - Corresponding Base Field Tag
   * - ``:Parameters:``
     - ``:param:``
   * - ``:Exceptions:``
     - ``:except:``
   * - ``:Groups:``
     - ``:group:``
   * - ``:Keywords:``
     - ``:keyword:``
   * - ``:Variables:``
     - ``:var:``
   * - ``:IVariables:``
     - ``:ivar:``
   * - ``:CVariables:``
     - ``:cvar:``
   * - ``:Types:``
     - ``:type:``


Graph directives
''''''''''''''''

The epydoc reStructuredText reader defines several custom `directives`, which
can be used to automatically generate a variety of graphs. The following custom
directives are currently defined:

.. list-table::
   :header-rows: 1
   :widths: 30 70

   *  - Directive
      - Description

   *  - .. parsed-literal::

             .. classtree:: [*classes...*]
                 :dir: *up|down|left|right*

      - Display a class hierarchy for the given class or classes (including all
        superclasses & subclasses). If no class is specified, and the directive
        is used in a class's docstring, then that class's class hierarchy will
        be displayed. The ``dir`` option specifies the orientation for the graph
        (default=\ ``down``).

   *  - .. parsed-literal::

             .. packagetree:: [*modules...*]
                 :dir: *up|down|left|right*
                 :style: *uml|tree*

      - Display a package hierarchy for the given module or modules (including
        all subpackages and submodules). If no module is specified, and the
        directive is used in a module's docstring, then that module's package
        hierarchy will be displayed. The ``dir`` option specifies the
        orientation for the graph (default=\ ``down``). The ``style`` option
        specifies whether packages should be displayed in a tree, or using
        nested UML symbols.

   *  - .. parsed-literal::

            .. importgraph:: [*modules...*]
                :dir: *up|down|left|right*

      - Display an import graph for the given module or modules. If no module
        is specified, and the directive is used in a module's docstring, then
        that module's import graph will be displayed. The ``dir`` option
        specifies the orientation for the graph (default=\ ``left``).

   *  - .. parsed-literal::

            .. callgraph:: [*functions...*]
                :dir: *up|down|left|right*

      - Display a call graph for the given function or functions. If no
        function is specified, and the directive is used in a function's
        docstring, then that function's call graph will be displayed. The
        ``dir`` option specifies the orientation for the graph (default=\
        ``right``).

   *  - .. parsed-literal::

            .. dotgraph:: [*title...*]
                :caption: *text...*
                *graph...*

      - Display a custom Graphviz dot graph. The body of the directive
        (``graph...``) should contain the body of a dot graph. The optional
        ``title`` argument, if specified, is used as the title of the graph.
        The optional ``caption`` option can be used to provide a caption for
        the graph.


Colorized snippets directive
''''''''''''''''''''''''''''

Using reStructuredText markup it is possible to specify Python snippets in a
`doctest block`__. SUch block will be colorized as in epytext `Doctest Blocks`_.

.. __:      http://docutils.sourceforge.net/
            docs/user/rst/quickref.html#bullet-lists

>>> def double(x):
...     return x * 2
...
>>> print double(8)
16

Doctest block are mostly useful to be run as a part of automatized test suite
using the doctest_ module. If the Python prompt gets in your way when you try
to copy and paste and you are not interested in self-testing docstrings, the
``python`` directive will let you obtain a simple block of colorized text:

.. _doctest: http://docs.python.org/lib/module-doctest.html

.. list-table::
   :header-rows: 1

   * -  Docstring Input
     -  Rendered Output

   * -  ::

            .. python::

                def fib(n):
                    """Print a Fibonacci series."""
                    a, b = 0, 1
                    while b < n:
                        print b,
                        a, b = b, a+b

     -  .. python::

            def fib(n):
                """Print a Fibonacci series."""
                a, b = 0, 1
                while b < n:
                    print b,
                    a, b = b, a+b


External API links
''''''''''''''''''

Epydoc can be used to create hyperlinks from your package documentation towards
objects defined in the API of other packages. Such links are similar to
ordinary `documentation crossreference links`_, but it is required to configure
Epydoc setting up a new `interpreted text role`_, binding it to an external API.

To create a new role, the command line option ``--external-api=``\ *NAME* must
be used. This option introduces a new interpreted text role called ``NAME``,
which can be used to refer to objects defined in an external API.

You can alternatively use a configuration file for this and all the other
options: see the `sample configuration file`_ for a comprehensive example.

For example, if your program needs to programmatically use the Epydoc package
itself, your docstrings may refer to functions described by Epydoc API::

    If you want to print a value, you can use
    the :epydoc:`apidoc.pp_apidoc()` function.

When you will generate the API documentation for such program, you will
need the option ``--external-api=epydoc`` or you will get parsing errors due
to the unknown role.

Of course this doesn't help to really create cross references: the
``--external-api`` option suffices to stop Epydoc complaining about unknown
roles, but the text is simply rendered in a monotype font and no link is
created.

What Epydoc requires to create external API links is a mapping from the names
of the objects exposed by the API and the URL where such objects are actually
described. Such mapping must be provided as a text file, with an object name
and its URL on each line, separated by a ``tab`` character. For example the
Epydoc API documentation may be represented by a file names ``api-objects.txt``
containing::

    epydoc                          ->  epydoc-module.html
    epydoc.apidoc                   ->  epydoc.apidoc-module.html
    epydoc.apidoc.UNKNOWN           ->  epydoc.apidoc-module.html#UNKNOWN
    epydoc.apidoc._pp_val           ->  epydoc.apidoc-module.html#_pp_val
    epydoc.apidoc.py_src_filename   ->  epydoc.util-module.html#py_src_filename
    epydoc.apidoc.pp_apidoc         ->  epydoc.apidoc-module.html#pp_apidoc
    epydoc.apidoc._pp_list          ->  epydoc.apidoc-module.html#_pp_list
    ...                                 ...
    ...                                 ...

Epydoc's HTML writer indeed includes such file in its output: see `HTML
Files`_ for details.

You can bind the definition file to the interpreted text role name using
the command line option ``--external-api-file=``\ *NAME:FILENAME*.In the
previous example you can use::

    --external-api-file=epydoc:api-objects.txt

This helps Epydoc to create relative urls: in the previous example the
``apidoc.pp_apidoc()`` label will be linked with the
``epydoc.apidoc-module.html#_pp_val`` URL.

You can specify a new root for the generated links using the last command line
option: ``--external-api-root=``\ *NAME:STRING*. *STRING* will be attached
in front of any URL returned by the *NAME* text role. For example, to let your
program refer to Epydoc API whose documentation is published at
http://epydoc.sourceforge.net/api/ you can use the options::

    --external-api-root=epydoc:http://epydoc.sourceforge.net/api/

this will let your reference :epydoc:`apidoc.pp_apidoc()` point at the
right documentation.

The three options can be used any number of time, effectively allowing to link
towards all the required external packages.


Names resolution
~~~~~~~~~~~~~~~~

When an external API link is to be created, the required name is split along
any separator ('``.``', '``::``', '``->``'). Everything after the first noise
character (for example after an '``(``') is discarded.

The name fragment is looked for in the names defined in the description file:
first an exact match is attempted; if no name exactly matches the required
name, a partial match is attempted: the required name is compared with the
*trailing parts* of the names in the file.

If a single name is found in this lookup, then its URL is returned. If the
name is not found, or if it matches with the trailing part of many defined
names, a warning is raised and the name is rendered as literal text.


Linking from standalone documents
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Epydoc provides the script ``apirst2html.py`` which allows you to use the
previously described interpreted text roles from any reST document. The script
exposes the same interface of the standard Docutils script ``rst2html.py`` but
provides the extra command line options described in `External API links`_.

With such tool you will be able to create hypertextual documentation of your
package with direct links to its API.


Indexed Terms in reStructuredText
'''''''''''''''''''''''''''''''''

Epydoc uses `indexed terms`_ to create a table of terms definitions. Indexed
terms are created using the epytext markup ``X{...}``.

If you want to create indexed terms in reStructuredText modules,
you can use the ``term`` `interpreted text role`_. For example:

.. list-table::
   :header-rows: 1

   * - Docstring Input
     - Rendered Output

   * - .. python::

        def example():
            """
            An :term:`index term` is a term that
            should be included in the index.
            """
            #[...]

     -  An *index term* is a term that should be included in the index.
   
            ============ ==============
                      Index
            ===========================
            index term   *example*
            x intercept  *x_intercept*
            y intercept  *x_intercept*
            ============ ==============


Javadoc
-------

Javadoc_ is a markup language developed by Sun Microsystems for documenting
Java APIs. The epydoc implementation of Javadoc is based on the `Javadoc 1.4.2
reference documentation`__. However, there are likely to be some minor incompatibilities between Sun's implementation and epydoc's. Known incompatibilities include:

* Epydoc does not support the Javadoc block tag ``@serial``.
* Epydoc does not support the following Javadoc inline tags: ``{@docroot}``,
  ``{@inheritdoc}``, ``{@value}``.
* Epydoc adds many field tags that Sun does not include, such as ``@var``,
  ``@type``, and ``@group``.

.. __: http://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/javadoc.html


Javadoc Fields
''''''''''''''

For compatibility with Javadoc, every ``@see`` field is assumed to contain a
single crossreference link, unless its body is quoted, or it starts with an
HTML tag. See the `Javadoc reference manual`__ for more information about how the
``@see`` field is encoded in Javadoc.

.. __: http://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/javadoc.html#@see

Because Javadoc does not mark end of the optional argument, field arguments
must contain exactly one word. Thus, multi-word arguments are not available
in Javadoc. In particular, all group names must be single words.
