
========
pure-doc
========

:Author: Albert Graef <Dr.Graef@t-online.de>
:License: GPL V3, see the accompanying COPYING file
:Date: |date|

.. |date| date::
.. |RST| replace:: reStructuredText
.. _RST: http://docutils.sourceforge.net/rst.html
.. _docutils: http://docutils.sourceforge.net

pure-doc is a simple utility for literate programming and documenting source
code written in the Pure programming language. It is designed to be used with
the excellent docutils_ tools and the gentle markup format supported by these,
called RST_ a.k.a. "|RST|", usually pronounced "rest".

The basic idea is that you just comment your code as usual, but using RST
markup instead of plain text. In addition, you can also designate literate
programming fragments in your code, which will be translated to RST literal
blocks automatically. You then run pure-doc on your source files to extract
all marked up comments and the literate code blocks. The resulting RST source
can then be processed with the docutils utilities like rst2html.py and
rst2latex.py to create the documentation in a variety of formats.

.. contents::

Installation
============

Just do the customary ``make && sudo make install``. This only needs flex and
a standards-compliant C++ compiler.

Usage
=====

First, see the description of the RST_ format. RST is a very simple markup
format, almost like plain text (in fact, you're looking at RST right now, this
document is written in it!). You can learn enough of it to start marking up
your source in about five minutes.

Second, you'll have to mark up your source comments. pure-doc recognizes
comments in RST format by looking at the first non-empty line of the
comment. A comment (either ``/* ... */`` or a contiguous sequence of ``//``
line comments) is assumed to contain RST format if the first non-empty line
starts with ``:``, ``..`` or ``__``. Other comments are taken to be plain text
and are ignored by pure-doc.

Notes:

* pure-doc makes no other assumption about the contents of marked up comments,
  so you can include whatever you want: titles, section headers, fields,
  admonitions, plain text, whatever. Just make sure that the comment starts
  with one of the special tokens listed above. (You can always put just ``..``
  at the beginning of the comment to force it to be recognized, this will be
  treated as a comment by the docutils tools.)

* Also, pure-doc makes very few assumptions about the source; in fact, any
  source files with a C/C++-like comment and string syntax should work. So you
  could also use it to document your C/C++ programs, or even plain text files
  like this one, as long as they adhere to these standards.

* Indentation in extracted comments is preserved (assuming tabs = 8 spaces
  by default, you can change this with the ``-t`` option).  This is important
  because indentation conveys document structure in RST.

For instance, here is a sample RST-formatted comment::

  /* :Name: ``rand`` - compute random numbers
     :Synopsis: ``rand``
     :Description: Computes a (pseudo) random number. Takes no parameters.
     :Example: Here is how you can call ``rand`` in Pure:
       ::

         > extern int rand();
         > rand;
         1804289383

     :See Also: rand(3) */

This will be rendered as follows:

  :Name: ``rand`` - compute random numbers
  :Synopsis: ``rand``
  :Description: Computes a (pseudo) random number. Takes no parameters.
  :Example: Here is how you can call ``rand`` in Pure:
    ::

      > extern int rand();
      > rand;
      1804289383

  :See Also: rand(3)

Finally, to extract the documentation you run pure-doc on your source files as
follows::

  pure-doc source-files ...

If no input files are specfied then the source is read from standard
input. Otherwise all input files are read and processed in the indicated
order. The output is written to stdout, so that you can directly pipe it into
one of the docutils programs::

  pure-doc source-files ... | rst2html.py

If you prefer to write the output to a file, you can do that as follows::

  pure-doc source-files ... > rst-file

pure-doc also understands the following two options. These must come before
any file arguments.

-h          Print a short help message.
-twidth     Set the tab width to the given number of spaces.

There are no other options. By its design pure-doc is just a plain simple
"docstring scraping" utility with no formatting knowledge of its own. All
actual formatting is handled by the docutils programs which offer plenty of
options to change the appearance of the generated output; please refer to the
docutils_ documentation for details.

If docutils isn't enough for you, then you should consider one of the other
available RST-based documentation frameworks, such as Sphinx_. These provide
even more elaborate formatting options, but are usually somewhat
Python-centric and harder to use. Also, you should take into account that many
Pure users read documentation in a text-based browser while running the
interpreter, so including all the latest html gizmos is not going to do them
much good and might in fact impair readability.

.. _Sphinx: http://sphinx.pocoo.org

Literate Programming
====================

pure-doc also recognizes literate code delimited by comments which, besides
the comment delimiters and whitespace, contain nothing but the special start
and end "tags" ``>>>`` and ``<<<``. Code between these delimiters (including
all comments) is extracted from the source and output as a RST literal code
block.

For instance::

  /* ..

     pure-doc supports literate programming, too. */

  // >>>

  // This is a literate comment.
  /* .. This too! */

  extern int rand();
  rand;

  // <<<

This will be rendered as follows:

  pure-doc supports literate programming, too.

  ::

    // This is a literate comment.
    /* .. This too! */

    extern int rand();
    rand;

Try it now! You can scrape all the sample "documentation" from this file and
format it as html, as follows::

  pure-doc README | rst2html.py --no-doc-title --no-doc-info > test.html

As already mentioned, this document itself is also in RST format, so you can
also do the following to get nicely formatted documentation::

  rst2html.py README pure-doc.html

(You can also just type ``make html`` to get this.)

Hyperlink Targets and Index Generation
======================================

To supplement the normal hyperlink target processing by the docutils tools,
pure-doc recognizes explicit hyperlink targets of the form::

  .. _target:

pure-doc automatically creates raw html targets (``<a name=...>``) for
those. This works around the docutils name mangling (which is undesirable if
you're indexing, say, function names). It also resolves a quirk with w3m which
doesn't pick up all ``id`` attributes in the docutils-generated html source.

In addition, you can also have pure-doc generate an index from all explicit
targets. To these ends, just add the following special directive at the place
where you want the index to appear::

  .. makeindex::

The directive will be replaced with a bullet list of references to all targets
collected *up to that point*, sorted alphabetically. This also resets the list
of collected targets, so that you can have multiple smaller indices in your
document instead of one big one.

.. note::

   docutils doesn't allow multiple explicit targets with the same name, so you
   should take that into consideration when devising your index terms.

It goes without saying that this facility is rather simplistic, and can't
compete with a carefully hand-made index. But we decided to toss it in because
docutils currently doesn't provide an automatic index facility of its own, and
the simple kind of index generated with pure-doc is certainly better than
having no index at all. (An alternative to pure-doc's indexing facility would
be to introduce a special RST "text role" for indexing purposes and use a
custom utility to process this kind of markup. But at present this is beyond
pure-doc's scope, so you're on your own if you take that route.)

Generating Documentation
========================

If you're generating some library documentation for which you have to process
a bigger collection of source files, then it is often convenient to have a few
Makefile rules to automatize the process. To these ends, simply add rules
similar to the following to your Makefile::

  # The sources. Order matters here. The generated documentation will have the
  # comments from each source file in the indicated order.
  sources = foo.pure bar.pure

  # The basename of the documentation files to be generated.
  target = foo

  .PHONY: html tex pdf

  html: $(target).html
  tex: $(target).tex
  pdf: $(target).pdf

  $(target).txt: $(sources)
          pure-doc $(sources) > $@

  # This requires that you have docutils installed.

  %.html: %.txt
          rst2html.py $< $@

  %.tex: %.txt
          rst2latex.py $< $@

  # This also requires that you have TeX installed.

  %.pdf: %.tex
          pdflatex $<
          rm -f *.aux *.log *.out

  clean:
          rm -f *.html *.tex *.pdf

(This assumes GNU make. If you use some other make utility then you will have
to adapt the pattern rules accordingly.)

Now you can just type ``make`` or ``make html`` to generate the documentation
in html format, and ``make tex`` or ``make pdf`` to generate the other
formats. The ``clean`` target removes the generated files.

Installing Documentation
========================

Now that you generated the documentation for your Pure library, you might want
to make the Pure interpreter know about it, so that you can read your
documentation with the ``help`` command of the interpreter. This isn't
difficult either. You just install the html files on the Pure library
path. The following Makefile rule automatizes this process. Add this to the
Makefile in the previous section::

  # Try to guess the installation prefix (this needs GNU make):
  prefix = $(patsubst %/bin/pure,%,$(shell which pure 2>/dev/null))
  ifeq ($(strip $(prefix)),)
  # Fall back to /usr/local.
  prefix = /usr/local
  endif

  libdir = $(prefix)/lib
  datadir = $(libdir)/pure

  install:
          test -d "$(DESTDIR)$(datadir)" || mkdir -p "$(DESTDIR)$(datadir)"
          cp $(target).html "$(DESTDIR)$(datadir)"

After a ``make install`` your documentation should now end up in the Pure
library directory, and you can read it in the Pure interpreter using a
command like the following::

  > help foo#

For a concrete example, you can find all this and more in pure-doc's own
Makefile. In fact, after installation this document ends up as pure-doc.html
in the Pure library directory, so that you can read it with::

  > help pure-doc#

Note the hash character. This tells the ``help`` command that this is an
auxiliary documentation file, rather than a function name to be looked up in
the Pure Library Manual. You can also look up a specific section in the
pure-doc manual as follows::

  > help pure-doc#literate-programming

Please also refer to the `Pure Manual`_ for more information on how to use the
interpreter's online help.

.. _Pure Manual: pure.html
