Rubyweb - a literate programming system for Ruby

Author: Hugh Sasse <hgs@dmu.ac.uk>

Contents

Introduction | Philosophy and Aims | Examples | Options | Directives | Code and Distribution

Introduction

On 2 Mar 2000 I wrote in [ruby-talk:01683] that I wanted a means of putting information into a document which is kept with the code, but such that it comes out in a different order, because the reader may need it in a different order from the interpreter. Toshiro Kuwabara did not accept this for incorporation into RDtool because it did not fit with his goals.

I decided to write the tool anyway, and do it in such a way that it would interoperate with RDtool. I did not want to replicate the functionality of RDtool because I don't want to create a competitor. Rubyweb solves a different problem, and may be usable with other text files.

Philosophy and Aims

Various places, such as Literate Programming -- Propaganda and Tools and The Literate Programming Library, refer to Donald E. Knuth's ideas that computer programs should be written for humans to understand. One of the main features of this is that a "document" may need several different types of information in it, and depending on the uses to which this information is put, the information may need to appear in various different sequences.

Ruby already supports embedded documentation through the use of
=begin
...
=end
blocks, and Rubyweb uses this feature to process blocks bounded by
=begin rubyweb
...
=end rubyweb
in a special way. Text not bounded by these will be passed to the Ruby interpreter as usual.

Within these blocks one can define named chunks, which one may group into streams. These chunks and streams may then be output to the standard output, a file, or possibly a pipe, as required. Thus one stream may be for internal documentation of a program (how it works, why it uses certain algorithms, etc) and another stream may be external documentation (how to use the program), for example. Although it was planned to have the streams consist of chunks, I saw no reason to prevent streams from containing other streams, and similarly chunks may contain chunks, or even streams. The concepts are at present interchangeable.

One creates a stream with:
=begin_stream name
...
=end_stream name
and similarly on creates a chunk with:
=begin_chunk name
...
=end_chunk name

To make use of a chunk, you use the =use_chunk directive.
=use_chunk name
To make use of a stream, you use the =use_stream directive.
=use_stream name

Once the document has been constructed it can bea passed to rubyweb.rb to be processed. For example you may wish to display a stream with the --display_stream or -ds option or display a chunk with the --display_chunk or -dc option. Similarly you can pass the stream on to a pipe or out to a file. Directives exist to do this from the file itself. You can use the --help or -h option to find out about the options, which are detailed below.

Examples

example1.web is an example of a rubyweb document, as is the program itself.

Options

Rubyweb $Revision: 1.4 $
usage: rubyweb.rb options filenames
options:
    -a
    --allow_all
                allow all output and piping
                from =output_*, =pipe_* and =display_*
                commands in the files.
    -ad
    --allow_display
                allow output from all =display_* commands
                in files.  Default is to allow this.
    -ao
    --allow_output
                allow output from all =output_* commands
                in files.  Default is to suppress this.
    -ap
    --allow_pipe
                allow output from all =pipe_* commands
                in files.  Default is to suppress this.
    -dc chunk
    --display_chunk chunk
		print chunk on standard output
    -ds stream
    --display_stream stream
		print stream on standard output
    
    -h
    --help
		display this message
    -l
    -list_all
		list all chunks and streams
    -lc
    -list_chunks
		list all chunks
    -ls
    -list_streams
		list all streams
    -oc chunk filename
    --output_chunk chunk filename
		output chunk to filename

    -os stream filename
    --output_stream stream filename
		output stream to filename
    
    -pc chunk command
    --pipe_chunk chunk command
		pipe chunk to command

    -ps stream command
    --pipe_stream stream command
		pipe stream to command

    -s
    --suppress_all
                suppress all output and piping
                from =output_*, =pipe_* and =display_*
                commands in the files.
    -sd
    --suppress_display
                suppress output from all =display_* commands
                in files.  Default is to allow this.
    -so
    --suppress_output
                suppress output from all =output_* commands
                in files.  Default is to suppress this.
    -sp
    --suppress_pipe
                suppress output from all =pipe_* commands
                in files.  Default is to suppress this.
    -v
    --version
		Show version number and exit.

Directives

Embedded in the rubyweb files, these control how the structure is built and processed. All of them appear on a line on their own, with no leading whitespace.

=begin rubyweb
Starts each section to be processed by rubyweb. May also be written =begin_rubyweb
=end rubyweb
ends each section to be processed by rubyweb. May also be written =end_rubyweb
=begin_chunk name_of_chunk
Starts a new chunk
=end_chunk name_of_chunk
ends a chunk
=begin_stream name_of_stream
Starts a new stream
=end_stream name_of_stream
ends a stream
=use_chunk name_of_chunk
Embed the text of name_of_chunk at this point in the file.
=use_stream name_of_stream
Embed the text of name_of_stream at this point in the file.
=include_code
This instructs rubyweb to ignore the next =end rubyweb directive, and include the code as if it were part of the documentation
=include name_of_file
This instructs rubyweb to read in the given file at this point.
=display_chunk name_of_chunk
Instructs rubyweb to add this chunk to the list of chunks to display. This is equivalent to the -dc option.
=display_stream name_of_stream
Instructs rubyweb to add this stream to the list of streams to display. This is equivalent to the -ds option.
=output_chunk name_of_chunk filename
Instructs rubyweb to send this chunk to the given file. This is equivalent to the -oc option.
=output_stream name_of_stream filename
Instructs rubyweb to send this stream to the given file. This is equivalent to the -os option.
=pipe_chunk name_of_chunk command
Instructs rubyweb to pipe this chunk to the given command. This is equivalent to the -pc option.
=pipe_stream name_of_stream command
Instructs rubyweb to pipe this stream to the given command. This is equivalent to the -ps option.

Code and Distribution

The files may be had from here: rubyweb.rb, example1.web, example.inc,

The code may be copied under the same terms as Ruby itself. It is supplied without warranty. Corrections and enhancements will be gratefully received.

Created on 28-SEP-2000 by Hugh Sasse

Last Modified on 29-SEP-2000 by Hugh Sasse

$Id: index.html,v 1.4 2000-09-29 18:56:23+01 hgs Exp hgs $