Introduction

Ruff! (Runtime function formatter) is a documentation generation system for programs written in the Tcl programming language. Ruff! is included with Woof! but can be used independently of it. Ruff! uses runtime introspection in conjunction with comment analysis to generate reference manuals for Tcl programs.

In comparison with source code based documentation generators, Ruff! produces documentation that not only requires less effort from the programmer, but is also more complete, more accurate and more maintainable.

Ruff! is covered by a liberal BSD open-source license that permits use for any purpose.

Requirements

Ruff! will run on any system that supports Tcl 8.4 or later. For Tcl 8.4, the dict extension, which is already included with later versions of Tcl, is also required.

Quick Start

To quickly generate HTML documentation for a namespace hierarchy, say ::app, run the following commands from inside your application after all code has been loaded.

package require ruff
::ruff::document_namespaces html ::app -output app.html -recurse true

This will create the documentation for all classes and procs under the ::app namespace tree, in the app.html file.

Documentation through introspection

Tcl provides facilities for deep runtime introspection. Ruff! makes use of these to generate comprehensive documentation with minimal additional effort on the programmer’s part.

  • Ruff! documents namespaces, procedures, TclOO classes, and methods as well as the relationship between these without any additional mark up.

  • Procedure and method documentation includes arguments and defaults. Descriptions are generated from comments written in natural syntax without any additional markup

  • Generated class documentation includes inherited and mixed-in methods so the full interface presented by a class is easily seen.

  • Multiple output formats including HTML and Tcl doctools.

  • Automatic hyper linking between various program elements.

Basic Document Generation

Runtime introspection is primarily through the Tcl info command. Comments within proc and method bodies are also processed at run time and not by analysing source files. Therefore, only comments inside proc and method bodies are visible to Ruff!.

Ruff! requires almost no markup and uses wiki-like free formatting conventions for structured text like lists. A simple proc definition with Ruff! markup would look like this:

proc character_at {str {index 0}} {
       # Fetches the character at the specified position in the string
       # str - string from which character is to be retrieved
       # index - position at which character is to be retrieved
       if {$index < 0} {
           #ruff
           # If the index has a negative value, it is taken as the position
           # from the end of the string.
           ...some code...
           # The above comment about index gets documented by Ruff! because
           # of the #ruff marker even though it appears in the middle of the
           # program body. This comment does not get picked up by Ruff! because it
           # it appears in the middle of the code and has no #ruff marker attached.
       } else {
           ...some code...
       }
   }

Below is the output generated by the Ruff! using the doctools plain text formatter

character_at str ?index?
    str
        string from which character is to be retrieved

    index
        position at which character is to be retrieved (default 0)

Fetches the character at the specified position in the string

If the index has a negative value, it is taken as the position from the
end of the string.

Note the markup is not obtrusive. Refer to the documentation of the distill_body and parse for the exact syntax. The source code for Ruff! itself is the best example of comment formatting conventions for Ruff!. Go to the Ruff! manual and click on the 'Show source' link for a command to view the original source code for the command and the embedded comments.

To generate documentation for a set of commands or classes using Ruff!, it must first be loaded into the same interpreter as those commands and classes.

Documenting a single namespace hierarchy

The simplest use of Ruff! is to generate documentation for a single namespace or namespace hierarchy in HTML format. The command document_namespaces accomplishes this. The following example generates documentation for all classes and procs in the namespace ::some_namespace and its descendents. The output is written to the file some_namespace.html.

package require ruff; # Loads Ruff! into the interpreter
::ruff::document_namespaces html ::some_namespace -output some_namespace.html -recurse true

The above uses the built-in HTML output formatter. External formatters like doctools require another step to be invoked and may themselves have additional options you can use to control the final output. Refer to the documentation for those tools for details.

Documenting multiple namespaces

Documentation of multiple namespaces may take one of two forms:

  • All namespaces may be included in a single documentation file

  • Each namespace may be documented in a separate file

An additional factor is whether the built-in HTML formatter or an external formatter is being used.

If the internal HTML formatter is being used, multiple namespaces can be documented in a single documentation file simply by passing multiple namespaces as a list to the document_namespaces command. If multiple output files are desired, then the command is invoked separately for each namespace. In this case, however, there will be no automatic cross-referencing or navigation menus across namespaces.

In the case where an external formatter is being used, single file output may be generated through the use of the -append option to the document_namespaces command:

::ruff::document_namespaces doctools ::some_namespace -output some_namespace.man
::ruff::document_namespaces doctools ::another_namespace -output some_namespace.man -append true

Both namespace are then documented in the same file. Note that some formatters, like doctools, may not be able to process such a combined file.

If separate output files are desired, separate files can be generated for each namespace. Here the formatter in use has to combine these into a single documentation set. Refer to the documentation for the appropriate formatting tool for information on how to accomplish this.

Advanced Document Generation

In some cases, you might want more control over the content and structure of the documentation. For example, you may want to

  • document a set of commands or classes partitioned based on something other than namespaces

  • document classes and commands in separate reference pages

  • document each class in its own reference page

Such documents may be generated through the use of the document command in combination with one or more of the commands extract, extract_ooclass, extract_proc and extract_namespace. These latter commands extract metainformation about classes and procs in the form of dictionaries. The combined dictionaries can then be passed to the document command to generate the documentation.

Controlling Output Content and Display

In addition to selecting which classes and procedures are included in the generated documentation, it may be desirable to include or exclude certain parts within the class or procedure. For example, documentation for the public API of a module should not include private or internal functions. The following sections describe some of the options commonly supported by Ruff! commands that affect this.

Using -docstrings to include additional documentation

A reference page may need to include additional material, such as an overview, in addition to details about individual procs and classes. This material may be included in the generated document through the use of the -docstrings option as described in the document command.

Using -hidenamespace to hide namespace qualifiers

By default, documentation generated by Ruff! includes namespace qualifiers in all class and proc names. It is possible to have the generated output leave out the namespace qualifers by adding the -hidenamespace NAMESPACE qualifier to the document generation commands. This provides a more visually pleasing output with less noise, but may result in ambiguities in case of names being present in more than one namespace. In particular, some formatters may not cross-link correctly in such cases.

Using -includeprivate to document private procs and methods

By default, private methods and procs are not included in generated documentation. Specifying -includeprivate true to a command causes these to be included. Private methods are methods that are not exported from a class. Private procs are procs whose names begin with an underscore. This is not currently configurable but is likely to be so in the future.

Using -includesource to include source code

The source code for a proc or a class method is not included in the documentation. For internal documentation, it may be convenient to have the source code be visible as part of documentation. Specifying the option -includesource true to a command causes the source code to be included in the documentation. It is intended that in a future release, HTML output formats will show source code in collapsible sections though this is not currently done.

Ruff! Output Formatters

Ruff! can either directly generate HTML documentation using the built-in HTML formatter, or generate formats that can be understood by several existing tools such as ROBODoc, Natural Docs or doctools.

Each option has its advantages and disadvantages.

The internal HTML formatter offers (in the author’s humble opinion) the best cross-linking and navigation support in addition to cosmetic enhancements such as tooltips and optional hiding/display of source code. It is also the simplest to use as no other external tools are required.

The external formatters have the advantage of supporting many more output formats such as PDF, plain text, Latex etc. In additional the generated documentation can be integrated into other larger documentation sets that contain documentation from other sources.

Choice of an output formatter depends on several factors:

  • the end use document format desired - ROBODoc and doctools support several output formats but the Ruff! internal formatter and Natural Docs support only HTML;

  • existing familiarity with a tool - obviously, if you are already familiar with a tool, or want to integrate Ruff! output with other documentation, it makes sense to stick with a tool you know;

  • capabilities of the tool itself - some tools are better than others in some areas such as quality of output generated, automatic cross-linking and indexing, configurability etc.

In general, it is best to try all formatters and pick one that best meets your needs.

Reference Manual

The Ruff! reference manual, generated using Ruff! itself, is available at http://woof.sourceforge.net/ruff.html.

Source Code and Downloads

Ruff! is an open-source project hosted at sourceforge.net as part of the Woof! web framework package. Source code and downloadable packages can be found at http://www.sourceforge.net/projects/woof.

Ruff! Sample Output

Some sample output from Ruff! can be seen at