Introduction

Welcome to the RWEB package. RWEB is several things:

  • it is a library providing the tools to do literate programming in Ruby;

  • it is a utility to permit self-tangling (executable) literate Ruby programs;

  • it is a set of external utilities to do tangling and weaving of literate Ruby programs in the more traditional form you see based on Knuth’s WEB;

  • it is a framework for customizing the weaving process to enable any back-end the user desires to use for generating documentation.

The RWEB package can be retrieved from its Rubyforge project page.

This release

This release of RWEB handles both plain text and XHTML for weaving and has the beginnings of a framework for user-supplied plug-ins in the planning pipeline. It is very much a usable system, however, with the XHTML output in particular being well-suited to blogging. The files of note are:

lib/rweb.rb

This is the library file that does the heavy lifting for the package. It needs to be required (“require ‘rweb’”) and it exposes in return the module RWEB. The module exposes two functions: tangle and weave. Everything else in the module is private utility functions.

bin/rtangle and bin/rweave

These scripts are self-tangling RWEB documents in plain text format (rtangle) and XHTML format (rweave) which tangle and weave respectively RWEB documents and generate appropriate output.

COPYING

The license under which this program is released. Read it. Know your rights (and wrongs).

User’s Guide

RWEB is a very simple format for writing literate programs inspired by Donald Knuth’s WEB program. An RWEB file has the following structure:

  • Self-tangling boilerplate

  • Directives

  • Documentation and code chunks in alternation

Self-tangling boilerplate

For sheer convenience it is difficult to beat the ability to directly execute RWEB documents instead of having to manually “tangle” the document into executable code. The key to doing this is attaching some boilerplate Ruby code to the head of an RWEB document and writing the program underneath this. The boilerplate should look something like this:

#! /usr/bin/ruby -w
require 'rubygems'
require 'rweb'
eval RWEB.tangle(DATA)
__END__

All this code does is require the libraries needed to execute itself (this assumes here that rweb has been installed as a gem), call RWEB.tangle with the special DATA variable and then terminate itself with the __END__ directive. The DATA object contains all of the text after the __END__ directive which, in this case, is our RWEB document. The returned string is then evaluated as per usual Ruby methods.

Directives

Instead of using command line options and confusing the interaction between the self-tangling boilerplate and the underlying program, RWEB controls the generation of documentation (not code!) with a block of directives. Directives have the following syntax:

{keys => value}

Currently only two keys are supported:

  • style

  • title

The style key reflects the documentation style used in the underlying RWEB document. As of this version the style can only accept the values Plain and XHTML. Future releases will implement other styles (most notably Bluecloth/Markdown) and will provide tools for user-extended styles to be included in the mix. (The beginnings of this framework is already in place.)

XHTML processing provides optional syntax highlighting automatically. If the syntax library is available the weaving functionality uses it seamlessly behind the scenes. If it is not available for use, the Ruby code blocks are passed through unaltered.

The title key is simply text used while generating the documentation and code which provides a title to the work. If left unset, it defaults to Untitled.

Code chunks

After the directives block (if present) is passed, RWEB begins in documentation mode. Any text in documentation segments is taken verbatim by the processor and passed on without alteration to the style processors later when weaving. A documentation segment ends with the beginning of a code segment.

Starting a code chunk

A code segment is identified by the use of this tag:

<< name {

The name is optional and may consist of any printable characters including whitespace. Any leading or trailing whitespace, however, is stripped before the name is used internally. This tag opens a named chunk of code when first encountered and copies all text between it and the closing tag into it. If a chunk is named several times, subsequent openings just add text to the existing chunk, thus allowing a chunk to be divided up for purposes of explanation.

Ending a code chunk

A chunk is closed with the following tag:

}>>

Note that chunk tags (both opening and closing) must begin in the left-most column with no whitespace nor other characters in front. There must be nothing but whitespace at the end of them as well. RWEB is not a general-purpose templating system. It is a literate programming tool only.

Code chunk references

Within a code chunk, another code chunk may be referenced by the following tag:

{<<name>>}

A code chunk reference may only have whitespace ahead of it and behind it. (Again RWEB is not a templating system.) Any whitespace in front of it is replicated for each line of the named chunk, thus allowing the output code to be readable. Any attempt to put something other than whitespace in front or behind the chunk reference is a runtime error.

Note that code chunk references are completely ignored in documentation segments.

Mainline code chunk

The name of a code chunk is optional. Any code chunks without a name form the special mainline code chunk that is used as the base chunk from which all other chunks are expanded. As with any chunk, the mainline chunk can be opened and closed repeatedly with each re-opening causing more text to be appended to it. There must be a mainline chunk in each RWEB document.

Examples of use

The utilities in ./bin as well as the test cases in ./tests should give ideas on how RWEB documents are structured and used. Too, some examples are provided in the ./docs directory both of RWEB documents as well as of weaved output.