Go to the first, previous, next, last section, table of contents.


WEB CONCEPTS

The principle concepts of WEB programming are laid out in Knuth's book, the reference to which was given in section INTRODUCTION to @FWEB{}. @FWEB{} follows most conventions introduced by WEB and CWEB, except that the names of some commands have been changed for consistency, symmetry, and/or clarity.

The @FWEB{} processors: @FWEAVE{} and @FTANGLE{}

Following Knuth's original design, @FWEB{} consists of two processors, @FTANGLE{} and @FWEAVE{}. Both operate on a single source file, say `test.web'. @FTANGLE{} produces compilable code, say `test.c', whereas @FWEAVE{} produces a TeX file, `test.tex', that can (in principle) be processed with either TeX or LaTeX. (If a file `test.tex' already exists, @FWEAVE{} will ask for confirmation before overwriting it if it does not think that the file was created by a previous run of @FWEAVE{}.)

The output file produced by @FTANGLE{} is not intended for human eyes (or for editors!); it is for compiling only. All changes to the code should be made to the web file, since changes made directly to the output file would be overwritten the next time the web source is tangled. In an attempt to discourage messing with @FTANGLE{}'s output file, all unnecessary spaces are deliberately removed.

A common way of integrating @FWEB{} into ones program development is to do all compilations through a make file, into which one puts an extra dependency line that explains how to produce the compilable output file from the web source. For example,

test.c: test.web
        ftangle test

test.o: test.c
        gcc -c test test.c

With this approach, one is not so tempted to edit `test.c'.

@FWEB{} development is now based on LaTeX; Plain TeX is no longer supported. For detailed descriptions of the LaTeX support, see section LaTeX support.

The structure of a web

An @FWEB{} source file is structured into sections, which correspond to logical subunits of the code (either a function or a fragment of a function). Each section consists of three parts, each of which is optional: the

  1. TeX part;
  2. definition part; and
  3. code part.

When @FTANGLE{} outputs code, it can combine the code parts of (possibly noncontiguous) sections into larger units called modules, as explained in section Modules.

With the aid of sections, one's possibly huge and logically complex code can be broken down into bite-sized pieces, each one easily comprehensible. Since sections may correspond to only a small part of a function or subroutine, 1000-line main programs (they still exist!) should become a thing of the past.

Since sections can be combined into modules, there is no need for sections that must be physically contiguous in the output file to be contiguous in the source file. This allows for great flexibility in structuring the documentation of the code.

A simple example

A simple example of an @FWEB{} source file consisting of three sections is as follows:

@n/ % Set FWEB language to Fortran, and recognize short // comments.

\Title{example.web} % \Title is an FWEB TeX macro.
\author{J. A. Krommes} % \author is a LaTeX macro.

@* INTRODUCTION. 
This code is intended to illustrate the use of the |write| statement.
It also provides a simple example of the \FWEB\ macro preprocessor.

@m A_CONSTANT 1.2345 // \FWEB\ preprocessor macro definition.

@a
        program main
        call compute
        end

@ The computational routine is pretty boring.
@a
        subroutine compute
        write(*,*) 'Macro value = ', A_CONSTANT
        end

@* \INDEX.

Commands to @FWEB{} are begun by the `@' symbol (see section @FWEB{} COMMANDS). In this example, the first command, `@n', sets the global language to FORTRAN-77. One should always begin one's code with a language-setting command.

In this example, the language command is invoked with an optional argument `/'. That is necessary in FORTRAN in order to tell @FWEB{} to use the short (single-line) comment form beginning with `//', which otherwise conflicts with the concatenation operator. See section `-n/': Recognize short comments [FORTRAN].

For more information about languages, see section LANGUAGES. For a fuller discussion of optional arguments, see section Setting the language.

The `@*' command begins a major or named section (corresponding to LaTeX's \section command); this command is followed by the section name, terminated by a period. (The period is essential; if it is omitted, weird errors may result.) Major sections are entered in an automatically generated Table of Contents. They are also printed at the top of each output page. If the full section name is too long to so print, one can shorten it with an optional argument, as in

@* [INTRO]INTRODUCTION.

The command `@*n' (not illustrated in the above example) begins a major (sub)section of level n, where `@*0' is equivalent to the simple `@*', `@*1' indicates a subsection, and `@*2' indicates a subsubsection. The highest permissible major level is 2 (a subsubsection). Such subsections are also entered in the Table of Contents. For more information, see section Sections in LaTeX.

As the example demonstrates, the name of the very last section, which should be starred, should be `\INDEX'. Note the backslash; `\INDEX' is a TeX macro. This command tells @FWEAVE{} to write out the index in a special two-column format. By default, `\INDEX' expands to `INDEX', but this name can be overridden by the style-file parameter `index.name' (see section index.???). For more discussion of @FWEB{}'s indexing facilities, see section @FWEB{}'s INDEX..

Minor (unnamed) sections are begun by @ASP{} ("at-space"); these have no associated names and are not entered into the Table of Contents. A newline counts as a space.

The TeX part

All sections begin with (optional) TeX commentary. That can just be straight text; to input that, no knowledge of TeX is required. It can also include mathematical exposition or any of the other advanced features offered by TeX.

Whenever @FWEB{} is in TeX mode, one can temporarily shift into code mode by enclosing the code within vertical bars. That code is typeset just like code in the code part (see below), except that newlines are replaced by spaces. Thus, one can say things like

Consider the C code fragment `|@c for(i=0; i<10; i++){}|', which ...

(If the global language were C instead of FORTRAN, the `@c' inside the vertical bars would not be necessary.) The ability to switch back and forth between text mode and code mode at will allows for a very convenient and flexible style of exposition.

The definition part

The TeX part is followed by an optional definition part. The beginning of the definition part is signaled by the appearance of any one of the commands `@d', `@f', `@m', `@v', or `@W' (explained later). In the previous example, the first section has a definition part consisting of one @FWEB{} macro definition (`@m'); the second section has no definition part. For more information, see section MACROS and PREPROCESSING.

(Failure to appreciate how easy it is to shift from part to part can get one into trouble. For example, don't write documentation such as `Consider the @m command', because the `@m' will inadvertently terminate the documentation part and begin the definition part. What one needs to do here is to use the literal `@', as in `@@m'.)

The code part

An unnamed code part is begun by `@a'. A named code part is begun by the appearance of a module name, such as `@<Global variables@>', followed by an equals sign; see section Modules. Within the code part, one can place any sequence of code or code fragments (they need not be complete subroutines) that are valid for the current language. (Setting the language is described in section LANGUAGES.) The code part is terminated by the next appearance of `@*' or @ASP{} (which signal the beginning of a new section), or by the end of file.

The limbo section

The portion of the source file before the first section (i.e., before the first `@*' or @ASP{}) is called in limbo or the limbo section. The only `@' commands that are allowed in limbo (in addition to `@@', which stands for the character `@' and is allowed anywhere) are the language-changing commands, and one of those, such as `@c', should appear. Other text in limbo is ignored by @FTANGLE{} and is copied by @FWEAVE{} to the tex output file. Thus, one can make or issue TeX macro definitions in limbo that override the defaults in @FWEB{}'s macro package `fwebmac.sty'. In the above example, see the \Title command. This is defined in `fwebmac.sty', and basically issues LaTeX's \title command.

(Another way of getting TeX text into the limbo section is by means of the `@l' command; see section `@l': Specify limbo text.)

LaTeX users may need to know that TeX commands in limbo are executed after the `\begin{document}' command (which is issued automatically in `fwebmac.sty'). For more information, see section LaTeX support.

Modules

The code parts of (possibly noncontiguous) sections can be combined into modules. For @FWEAVE{}, this is a logical combination, for purposes of cross-referencing different pieces of the code. But for @FTANGLE{}, the combination is physical; @FTANGLE{}'s output proceeds module by module.

Modules can be named or unnamed. There is exactly one unnamed module. The fundamental operation of @FTANGLE{} is that

@FTANGLE{ outputs the unnamed module}.

That output goes to a compilable file with an extension appropriate to the current language.

The contents of a module, either unnamed or named, consists of a mixture of code and comments. @FTANGLE{} ignores the comments; @FWEAVE{} treats them as TeX text. Within any TeX text, including comments, constructions delimited by `|...|' signify a temporary shift into code mode. (In the present design, one cannot enclose a comment within the vertical bars.)

The unnamed module

The unnamed code module is introduced by the command `@a'. Subsequent uses of `@a' accrete code to the unnamed module. To repeat, the fundamental operation of @FTANGLE{} is that

@FTANGLE{ outputs the unnamed module}.

Thus, there must be at least one `@a' in the source file or @FTANGLE{} will output nothing.

(Why is the command called `@a'? Historically, it was the first letter of the alphabet, as befits its prominent status. However, one can also think of it as "accrete.")

Named modules

Named modules represent logically-connected fragments of code.

A module name is specified by the construction

@< Arbitrary TeX text @>

Leading and trailing white space around the name text is ignored. The name text can include the `|...|' construction, which tells @FWEAVE{} to typeset a code fragment. Thus, module names can be highly explicit--for example,

@< Check that |x >= 0.0|; |abort| if not @>

To define a named module, replace the `@a' that begins the unnamed code part of a section by `@< module name @>='. If one uses this construction with the same name in a later section, the effect is to accrete to the contents of the module. Thus, a named module might ultimately consist of the code from sections 2, 5, and 9, for example.

To use a named module, simply use the name anywhere in a code part; @FTANGLE{} will insert the contents of the module at the point where the name is used. For example,

@c
@ Here's how to use a named module.
@a
for(i=1; i<n; i++)
        @< Inner loop @>@;

@ Here's how to define a named module.  Definitions may occur after use.
@< Inner...@>=
{
a[i] = i;
}

There are several details to notice about the above example. First, @FWEAVE{} considers module names to be simple expressions (such as the single identifier x). In C, expressions are made into complete statements (as is required in the body of a for statement) by appending a semicolon. In this case, a pseudo-semicolon `@;' is appropriate; for more discussion of that, see section `@;': Pseudo-semicolon.

Second, after a name has appeared once in full, it may be abbreviated by a unique prefix followed by three periods, as demonstrated in the above example. By convention, a complete module name cannot be a subset of another. For example, `@<Test@>' and `@<Test of graphics@>' will elicit an error message.

Commonly, the first unnamed section in the code indicates its modular structure. For example, a C code might begin with

@c
@* DEMO.
@a
@<Include files@>@;
@<Typedefs@>@;
@<Function prototypes@>@;
@<Global variables@>@;

Subsequently one can accrete to the above named sections, as often as desired and in any order. This way, definitions of global variables can be introduced anywhere in the web source file as logical and pedagogical exposition dictates, but will be guaranteed to appear at the top of the code. Function prototypes could be handled this way as well; alternatively, they could all be collected into one section, perhaps at the end of the source file. (The above organization still guarantees that they will appear at the beginning of the output.) Functions could be introduced one at a time in subsequent unnamed sections.

Very rarely, one might try the following construction:

@
@a
@< Left side @> = @< Right side @>@;

Here the intent is to construct an assignment statement. However, this will be flagged as an error because @FWEB{} thinks one is trying to define the named module `@<Left side@>', which one shouldn't be doing while in code mode. To make it work, just put the invisible expression `@e' (see section Pseudo (invisible) operators) before the equals sign.

Phases of processing

The @FWEB{} processors perform their work in several distinct phases. (The following is somewhat technical. Scan it, then use it for reference later if necessary.)

The phases of @FTANGLE{}

@FTANGLE{} has two phases. In phase 1, the source file is read; in phase 2, compilable code is written out in the order specified by the web.

More specifically, phase 1

Phase 2

The phases of @FWEAVE{}

@FWEAVE{} has three phases. In phase 1, the source file is read and cross-reference information is collected. In phase 2, the source file is read again, then pretty-printed with some cross-reference information. (For discussion of pretty-printing, see section Pretty-printing.) In phase 3, an automatically-generated Index, List of Modules, and Table of Contents are written.

More specifically, phase 1

Phase 2

Phase 3 writes out cross-reference information. (To eliminate some of that, see section `-x': Eliminate or reduce cross-reference information (@FWEAVE{})..) Specifically, it


Go to the first, previous, next, last section, table of contents.