Reference Developer Tutorial 1 Introduction 2 Macros 3 Typesetting 4 Example 5 Hints 6 Examples 7 Webmaking SEARCH

6.6 Documents That Share Text

FunnelWeb is very useful when preparing multiple documents that must share large slabs of identical text that are being constantly modified.

For example someone preparing two slightly different user manuals for two slightly different audiences might want the manuals to share large slabs of text, while still allowing differences between them. The following example shows how this can be done. The code is cluttered, but this clutter would not be a problem if the lumps of text were moderately large.

    @O@<manual1.txt@>==@{@<M1@>@+@}
    @O@<manual2.txt@>==@{@<M2@>@+@}

    @$@<M1@>+=@{@<T1@>@}
    @$@<M2@>+=@{@<T1@>@}
    @$@<T1@>@M==@{@-
    First lump of text shared by both documents.@+@}

    @$@<M1@>+=@{Text for first document@+@}
    @$@<M2@>+=@{Text for second document@+@}

    @$@<M1@>+=@{@<T2@>@}
    @$@<M2@>+=@{@<T2@>@}
    @$@<T2@>@M==@{@-
    Second lump of text shared by both documents.@+@}

An alternative approach, which might work better in situations where there are many small differences between the two documents rather than a few large ones, is to define a macro with two arguments, one for each product file document. Write the document from top to bottom, but place all stretches that differ between the two documents in a macro call.

    @! Set the definition of @#D to
    @!    @1 to create the shareholders report.
    @!    @2 to create the customers report.
    @$@#D@(@2@)@M==@{@1@}

    @O@<report.txt@>==@{@-
    ANNUAL REPORT TO @#D@(Shareholders@,Customers@)
    =================@#D@(============@,=========@)
    This has been a very good year for The Very Big
    Corporation of America. With your help, we have
    been able to successfully
    @#D@(@"screw the customers
              for every cent they have@"@,
         @"knock the shareholders into
            submission to bring you lower prices@"@).
    With gross earnings approaching six trillion
    dollars, we have been able to
    @#D@(@"increase dividends@"@,
         @"lower prices@"@).
    We expect to have an even better year next year.
    @}

One application where text sharing can be particularly useful is in the preparation of computer documentation containing examples. For example, a book describing a new programming language might be full of examples of small programs written in the language which the user might want to try without having to type them all in. The "default" approach of keeping a copy of the examples in the text of the book and another copy in separate files is cumbersome and error prone, because both files have to be updated whenever an example is changed. A more sophisticated approach is to store each example in a separate file, and then use the "include file" facility of the word processor to include each example in the text. This is a better solution, but suffers from a few drawbacks. First, when editing the book in a word processor, the examples in the book will not be directly accessible or visible. To see an example, the writer would have to open the file containing the example in a separate window. This could become tedious if the text contained many examples, as many texts do. Furthermore, there is a risk that some example files will be included in the wrong place. Second, because the book is dependent on the included files, the book will end up consisting of a directory of a hundred or more files instead of just a few.

An alternative solution is to construct a single FunnelWeb `.fw` file that, when processed, produces both the book file and the example files. This solution assumes that the book consists of a text file containing commands for a typesetter such as TeX.

    @O@<Book.tex@>==@{@#B@}

    @$@#B+=@{@-
    The first step to learning the object oriented
    AdaCgol++ language is to examine a hello world
    program.

    \start{verbatim}
    @<Ex1@>
    \finish{verbatim}
    @}

    @$@<Ex1@>==@{@-
    read iopack@+Enter !World~! !Hello~! ex pr flu X[1]@}
    @O@<Ex1.c@>==@{@<Ex1@>@}

    @$@#B+=@{@-
    To understand the program, think of the execution
    state as a plate of cheese...
    @}

Most of the file will consist of part definitions of the additive macro `@#B`. The definition is "broken" to allow a macro definition, wherever an example appears.

The example above is a little messy because FunnelWeb does not allow macros connected to product files to be called, and it does not have text expressions that write to an product file as well as evaluating to text. Nevertheless, it presents a fairly clean solution to the problem of keeping the example programs in a computing text up to date.

Webmaster Copyright © Ross N. Williams 1992,1999. All rights reserved.