Hieronymous Bosch Woodcut of an English pub

Overview

PUB was an early scriptable markup language. It was similar in concept to today's web scripting languages, especially PHP and JavaScript. But, like Microsoft Word, its purpose was to create paginated documents. PUB was the brainchild of Les Earnest of the Stanford Artificial Intelligence Laboratory. Under his direction, I designed the language and implemented the compiler in 1971. It ran on the Digital Equipment Corporation (DEC) PDP-10.

PUB's intended users were computer programmers working at the AI Lab. The brand new ARPANET made it easy to transmit the PUB application, source code, and documents to other research universities, several of which had PDP-10 systems. In the next few years, dozens of Ph.D. candidates around the U.S. chose PUB to format their dissertations. Russ Taylor of Stanford modified the open source to add support for the Information International Inc. FR-80 Microfilm Recorder. Rich Johnsson of Carnegie-Mellon University (CMU) did the same for the Xerox Graphics Printer (XGP), a predecessor to the laser printer.

PUB offered considerable power. But its target audience was small. The software was ridden with quirks that only became apparent after running the compiler and examining the output.

At least two PUB users reacted to these shortcomings by developing a better language. Brian Reid, then at CMU, developed Scribe for nontechnical users. He implemented the first version entirely in PUB. Don Knuth developed TeX for authors of mathematical texts.

The solution I favored was what we would now call a WYSIWYG interactive text editing and page layout system. I felt that, if the effect of any change was immediately apparent, users would feel more in control. I soon left Stanford to pursue my dream at Xerox PARC (1973-80) and Apple Computer (1980-1997).

In 1980, Les Earnest founded Imagen, a pioneering desktop publishing company. He sold it to QMS in 1987.

PUB is all but forgotten. It is not even mentioned in histories of Scribe and TeX. But its reinventions, JavaScript and PHP, have become indispensible in the world of web authoring. As such, history has confirmed what Les postulated at least as early as 1971: built-in markup tags will never be able to handle the variety of formatting effects that authors and publishers require. To achieve effects that a markup language designer could not have anticipated, a powerful scripting language should be provided.

STANFORD ARTIFICIAL INTELLIGENCE PROJECT                  AUGUST 1972
OPERATING NOTE 70




                                 PUB

                        The Document Compiler



                                 by

                            Larry Tesler







ABSTRACT:

PUB  is  an  advanced  text  justifier  and  page  formatter intended
primarily for use by programmers.  It can automatically number pages,
sections, figures,  footnotes, etc.  and can  print their  numbers in
roman numerals as well as  in digit or letter form.  It  can generate
cross references,  tables of contents,  and indexes.  Page  layout is
flexible,  and  allows  multiple  column  output.    Line  formatting
includes tabs, underlining, superscripts, subscripts,  centering, and
justification.   Macros programmed  in a  SAIL-like string-processing
language can generate text to be printed in the document.  The output
of the compiler is  a file which can  be printed on the  terminal, on
the line printer, or on microfilm.





ACKNOWLEDGMENTS:

Les  Earnest  created  the  concept  of  the  Document  Compiler  and
specified most of its capabilities.

Dan  Swinehart  provided  invaluable advice  and  aid  throughout the
development of PUB.

Russ Taylor programmed the FR-80 preprocessor.
      

SAIL was an acronym with two meanings: Stanford Artificial Intelligence Laboratory and Stanford Artificial Intelligence Language. The SAIL language (pdf) was a dialect of Algol-60.

I worked at SAIL, the lab, as a consultant in 1967, and as an employee of Kenneth Colby, M.D., from 1968 to mid-1970.

Around 1968, Jim Warren and I were laying out the Midpeninsula Free University catalog using traditional cut-and-paste methods, i.e., with scissors and glue. I had been involved in computer animation since 1962 when I worked on the Stanford Card Stunt Program. I had used graphic displays since at least 1963 when the LINC came to Stanford. I had recently seen a demo of Doug Engelbart's hypertext system, NLS. It was obvious to me that cut-and-paste would eventually be done using a computer display and something like a mouse. I mentioned this thought to Jim, who knew nothing about computers at the time. He asked to visit SAIL, where I showed him the facility and such toys as Steve Russell's SpaceWar!, the first video game. That visit led to Jim's entry into the computer industry. For me, it reinforced a desire to make interactive page layout a reality.

In 1970, I became disillusioned with the slow pace of artificial intelligence research. I took almost a year off from the industry. When I returned in the spring of 1971, I asked if I could work on something unrelated to AI. Prof. John McCarthy, inventor of LISP and academic leader of the lab, sent me to Les Earnest, the lab's administrative head. Les suggested a few possible projects. The one that interested me the most was his idea for a document compiler for technical manuals. I told Les that I'd rather implement an interactive layout system for a broader audience. He persuaded me that the document compiler should come first. I felt I'd learn useful things, and I needed the job, so I agreed.

Les specified the general approach and most of the features. As I designed and implemented PUB, I naturally put my own spin on it. Once people began using it, features were driven mainly by user feedback.

I released the first version of PUB around September, 1971. The implementation language was SAIL, and the syntax of the scripting language was as SAIL-compatible as I could manage.

Les deserves credit for the strengths of PUB, and I the blame for its quirks.

SAILON-70                        PUB                           Page i


                          TABLE OF CONTENTS
                          ----- -- --------

SECTION                                                          PAGE



1        INTRODUCTION

              1.1       PURPOSE     .  .  .  .  .  .  .  .  .  .  . 1
              1.2       CAPABILITIES   .  .  .  .  .  .  .  .  .  . 1
              1.3       OPERATION   .  .  .  .  .  .  .  .  .  .  . 2
              1.4       COMPILER OUTPUT   .  .  .  .  .  .  .  .  . 4
              1.5       READING THIS MANUAL  .  .  .  .  .  .  .  . 5
              1.6       TUTORIAL FOR BEGINNERS  .  .  .  .  .  .  . 5
              1.7       SAMPLE COMPILATION   .  .  .  .  .  .  .  . 9


2        TEXT CONVENTIONS

              2.1       ILLEGAL CHARACTERS   .  .  .  .  .  .  .   13
              2.2       COMMAND AND TEXT LINES  .  .  .  .  .  .   13
              2.3       PARAGRAPHING   .  .  .  .  .  .  .  .  .   14
              2.4       FILL MODE   .  .  .  .  .  .  .  .  .  .   14
              2.5       JUSTIFICATION  .  .  .  .  .  .  .  .  .   14
              2.6       BREAKING AT BLANK LINES .  .  .  .  .  .   15
              2.7       BREAKING AT TABS  .  .  .  .  .  .  .  .   15
              2.8       BREAKING AT CARRIAGE-RETURNS  .  .  .  .   15
              2.9       NOFILL MODE .  .  .  .  .  .  .  .  .  .   15
              2.10      HORIZONTAL SPACE COMPACTION   .  .  .  .   16
              2.11      VERTICAL GROUPING .  .  .  .  .  .  .  .   17
              2.12      MODE AND SWITCH SETTING COMMANDS .  .  .   17
              2.13      WORD BREAKS .  .  .  .  .  .  .  .  .  .   18
              2.14      CONTROL FUNCTIONS .  .  .  .  .  .  .  .   18
              2.15      CONTROL CHARACTER ACTIVATION  .  .  .  .   21
              2.16      COMPUTED TEXT  .  .  .  .  .  .  .  .  .   23


3        MACROS

              3.1       CALLING A MACRO FROM A COMMAND LINE .  .   25
              3.2       CALLING A MACRO FROM A TEXT LINE .  .  .   25
              3.3       TEMPLATES   .  .  .  .  .  .  .  .  .  .   26
              3.4       MACRO DECLARATION .  .  .  .  .  .  .  .   27
              3.5       MACRO CALLS .  .  .  .  .  .  .  .  .  .   27
              3.6       OMISSIONS   .  .  .  .  .  .  .  .  .  .   28
              3.7       RECURSIVE MACROS  .  .  .  .  .  .  .  .   29
      

About this manual

To navigate the manual, scroll down, or use the links in the table of contents and index. Many, but not all, pages have commentary alongside.

The original PUB manual contained no links. PUB did not support hypertext. Its purpose was to generate printed documents.

The manual was first produced in late 1971. The manual reproduced here is a 1972 revision that included documentation of a few added features, including output to the FR-80.

The character set of the SAIL keyboard and display was not fully supported by the lab's high-speed impact printer. In the hard copy manual, I had to hand print some non-ASCII characters. For this HTML reproduction, I have translated those characters to Unicode. I have also corrected a number of typos in the text and examples.

The cover image is a Hieronymous Bosch woodcut of an English pub. I found the image in 1971 in an off-copyright book in the Stanford Library. It became the cover of the hard copy version of the manual. We had no way to incorporate the image into the digital version.

The digital version of the manual survived thanks to Bruce Baumgart, who laboriously transferred all SAIL backup tapes from the period 1972 to 1990 into a web-based archive. At the time of this writing, February 2005, Bruce is an employee of The Internet Archive, and plans to add the SAIL archive to their holdings.

The manual was, naturally, produced in PUB. We have not yet located the source code, but expect to find it soon.

It took considerable JavaScript and CSS machinations to emulate the behavior of SAIL's line printer in HTML. The manual is best viewed in Microsoft Internet Explorer for Windows, FireFox, or Safari. In older browsers, you may see mispositioned characters as well as numerous backquotes where there ought to be spaces. Even in the recommended browsers, many non-ASCII characters will appear too wide.

Page ii                 TABLE OF CONTENTS                   SAILON-70


4        EXPRESSIONS

              4.1       DATA TYPE   .  .  .  .  .  .  .  .  .  .   30
              4.2       VARIABLES   .  .  .  .  .  .  .  .  .  .   30
              4.3       AUTOMATICALLY DECLARED VARIABLES .  .  .   31
              4.4       SIMPLE EXPRESSIONS   .  .  .  .  .  .  .   32
              4.5       GENERAL EXPRESSIONS  .  .  .  .  .  .  .   33
              4.6       CONSTANTS   .  .  .  .  .  .  .  .  .  .   34


5        STATEMENTS

              5.1       STATEMENT TYPES   .  .  .  .  .  .  .  .   35
              5.2       BLOCK       .  .  .  .  .  .  .  .  .  .   35
              5.3       COMPOUND STATEMENT or CLUMP   .  .  .  .   35
              5.4       ONE PARAGRAPH SCOPE  .  .  .  .  .  .  .   36


6        DECLARATIONS

              6.1       SCOPE       .  .  .  .  .  .  .  .  .  .   37
              6.2       MODE DECLARATIONS .  .  .  .  .  .  .  .   37
              6.3       TABS DECLARATION  .  .  .  .  .  .  .  .   37
              6.4       INDENT DECLARATION   .  .  .  .  .  .  .   38
              6.5       PREFACE DECLARATION  .  .  .  .  .  .  .   39
              6.6       DOUBLE SPACING .  .  .  .  .  .  .  .  .   39
              6.7       AREA DECLARATION  .  .  .  .  .  .  .  .   39
              6.8       MARGIN CONTROL .  .  .  .  .  .  .  .  .   40
              6.9       PLACE DECLARATION .  .  .  .  .  .  .  .   42
              6.10      TEMPORARY AREAS   .  .  .  .  .  .  .  .   42
              6.11      COUNTER DECLARATION  .  .  .  .  .  .  .   43


7        IMPERATIVES

              7.1       ASSIGNMENT STATEMENT .  .  .  .  .  .  .   45
              7.2       CONDITIONAL STATEMENT   .  .  .  .  .  .   45
              7.3       NEXT COUNTER VALUE STATEMENT  .  .  .  .   45
              7.4       NEXT PAGE STATEMENT  .  .  .  .  .  .  .   47
              7.5       HEADINGS AND FOOTINGS   .  .  .  .  .  .   48
              7.6       SECTIONING  .  .  .  .  .  .  .  .  .  .   48
              7.7       COMMAND CHARACTER STATEMENT   .  .  .  .   49
              7.8       PORTION DEMARCATION  .  .  .  .  .  .  .   49
              7.9       SEND STATEMENT .  .  .  .  .  .  .  .  .   50
              7.10      RECEIVE STATEMENT .  .  .  .  .  .  .  .   52
              7.11      REQUIRE STATEMENT .  .  .  .  .  .  .  .   53
              7.12      SKIP STATEMENTS   .  .  .  .  .  .  .  .   53
              7.13      PAGE FRAME STATEMENT .  .  .  .  .  .  .   55
      

Antecedents and contemporaries

PUB was by no means the first computer-based markup language.

In 1963, Jerry Saltzer developed RUNOFF, the first known computer-based system in which an author could insert markup codes into a digital manuscript and run the file through a markup processor to generate a formatted document. Around the same time, inspired by a demo of RUNOFF or a similar program, John Seybold founded a typesetting service bureau, ROCAPPI (1963-70). ROCAPPI is said to have developed powerful editing and layout systems and even a form of generic markup.

RUNOFF spawned Joe Ossanna's troff/nroff (1973), later enhanced by Brian Kernighan, co-developer of Unix and C, and still popular on Unix systems. IBM's SCRIPT, released circa 1967, had a similar syntax to RUNOFF. By 1974, SCRIPT had spawned the PUB-like NSCRIPT and Waterloo Script, as well as the generalized markup language, GML.

Before GML, most markup was specific, e.g., indent the next line 3 spaces. In GML, which was conceived in 1969 and realized in 1971, all markup was general, e.g., make the next line a heading. A document thus prepared could be formatted for different page sizes, different output devices, etc., without altering the markup.

GML was concerned with the syntax of a document type, which it expressed in a standardized form, the document type definition or DTD. The syntactic rules governing a new structural element could be defined in a DTD. Its implementation required recoding of the markup processing application.

PUB, SCRIPT, and other scripted markup languages provided a form of generic markup using macros. In PUB, new elements and new behavior could, in many cases, be defined within the PUB language itself. As stated earlier, Brian Reid's SCRIBE-a complete markup language-was originally implemented in PUB. Similarly, IBM's first version of GML was implemented in SCRIPT.

In 1978, Charles Goldfarb, the principal developer of GML, joined with other advocates of generalized markup to begin work on SGML. SGML has become a widely used language for describing industrial documents. In 1990, Tim Berners-Lee chose SGML as the basis for his World Wide Web hypertext language, HTML. The success of HTML spawned XML, now the favored format for structured data exchange.

Was any feature of PUB without precedent? I do not know enough about the features of similar systems in 1971 to be sure. I am hoping that readers of this manual can help me answer this question.

SAILON-70                 TABLE OF CONTENTS                  Page iii


              7.14      BREAK STATEMENT   .  .  .  .  .  .  .  .   55
              7.15      CONTINUE STATEMENT   .  .  .  .  .  .  .   55
              7.16      DEVICE STATEMENT  .  .  .  .  .  .  .  .   55
              7.17      UNIMPLEMENTED STATEMENTS   .  .  .  .  .   56


8        COMMENTS



9        LABELS AND CROSS-REFERENCES

              9.1       CROSS-REFERENCES  .  .  .  .  .  .  .  .   59
              9.2       LABELS      .  .  .  .  .  .  .  .  .  .   60


10       RESPONSES

              10.1      TEXT RESPONSES .  .  .  .  .  .  .  .  .   63
              10.2      TRANSITION RESPONSES .  .  .  .  .  .  .   64


11       FOOTNOTES




                             APPENDICES
                             ----------


A        THOROUGHLY EXPLAINED EXAMPLES

              A.1       SECTIONING MACROS .  .  .  .  .  .  .  .   68
              A.2       SAMPLE TABLE OF CONTENTS   .  .  .  .  .   69
              A.3       ONE-LEVEL INDEXES .  .  .  .  .  .  .  .   70
              A.4       TWO-LEVEL INDEXES .  .  .  .  .  .  .  .   72
              A.5       KWIC INDEXES   .  .  .  .  .  .  .  .  .   74


         SUBJECT AND COMMAND INDEX  .  .  .  .  .  .  .  .  .  .    I
      

Documents produced using PUB

In the 1970's, PUB gained a following among PDP-10 users at Stanford and other ARPANET-connected universities.The following publications acknowledge the use of PUB in their production:

AL, a programming system for automation by Raphael Finkel, Russel Taylor, Robert Bolles, Richard Paul and Jerome Feldman, SAIL Report AIM-243, Nov. 1974, available from Stanford FTP or the ACM Portal.

Fail by F. H. G. Wright II and R.E. Gorin, SAIL Report AIM-226, Dec. 1975, available from Trailing-Edge.

 

 

 

SAILON-70                        PUB                           Page 1


                              SECTION 1

                            INTRODUCTION




1.1 PURPOSE
    _______

               PUB is a compiler which translates a manuscript into a
                                                    __________
               document.
               ________

               A "manuscript" is an SOS file containing the text of a
               publication interspersed  with control  characters and
               commands.  The function of the compiler is  to arrange
                                              ________
               this text  on formatted pages  under the  direction of
               the control characters and commands.

               Output  is  written  on a  ".DOC"  file  known  as the
               "document".  TYPE, SPOOL  or PRINT it.   Under certain
               conditions, the document can be edited with  TECO (see
               Section 7.16), but it is wiser to make  corrections in
               the manuscript and then rerun the compiler.
               
MANUSCRIPT  DOCUMENT
           COMPILER



1.2 CAPABILITIES
    ____________

               PUB provides the usual capabilities of a  simple text-
               justifier, including:

>Page numbering
>Optional justification to the right margin
>Centering of titles
>Headings and footings
>Control of Spacing and Indentation
>Underlining

               In  addition,   it  features   advanced  documentation
               capabilities, such as:




                              1.1 - 1.2

Terminology

The name PUB was short for PUBlication language.

The PDP-10 operating system was TENEX, later called TOPS-10.

SOS (Son of Stopgap) was a line-oriented text editor. For more information about PUB, SAIL, SOS, and related topics, see Les Earnest's extensive but concise memoire, SAIL Away.

TECO was a character-oriented text editor, originally developed in 1962-63 for the DEC PDP-1. Dan Murphy developed TECO and was one of the developers of TENEX.

The TENEX TYPE command displayed a file on the terminal, which, at SAIL, was a display that every programmer had on his desk-a rare indulgence at the time. The PRINT and SPOOL commands sent a document to the line printer.

"The usual capabilities of a simple text-justifier" refers to preexisting markup processors like RUNOFF.

PHP remark

The advice that "it is wiser to make corrections in the manuscript and then rerun the compiler" would apply today to the HTML output from PHP.

Page 2                      INTRODUCTION                    SAILON-70


>Columnar output
>Footnote placement
>Macros
>Index Generation
>Table of contents generation
>Cross-reference to a variable target
>Automatic numbering of equations, tables, notes, etc
>Superscripts and Subscripts
>Microfilm Output

               The  command  language  is a  dialect  of  SAIL Algol,
               providing the user with:

>Block structure
>Conditional command execution
>Conditional text inclusion
>Arithmetic and String calculations
>Embedded Source Files



1.3 OPERATION
    _________

               The compiler is "two-pass".  The first pass interprets
               the manuscript and outputs several  intermediate files
               with  extensions  ".PUG",  ".PUZ",   and  ".PUI".  The
               second pass is a separate program automatically called
               which  makes one  pass  through the  ".PUI"  files and
               produces the  document.  The  ".PUG" and  ".PUZ" files
               are automatically deleted at the end of Pass One.  The
               ".PUI"  files  are  read  by  Pass  Two,  then deleted
               (unless deletion is waived by a switch setting  -- see
               below).

               The first pass typically requires 40K of core and runs
               at the rate of  15 pages per minute.  The  second pass
               needs 18K  and runs  at 50 pages  per minute.   If the
               system should crash during  Pass Two, and you  wish to
               restart without rerunning Pass One,  R PUB2.  "R PUB2"
               also gives you  an opportunity to specify  a different
               output device than originally requested.

               You may run the document compiler with or without RPG.
               A manuscript file which  is ".PUB" or a  document file
               extension  which  is  ".DOC"  need  not  be mentioned.
               Examples:


                                 1.3

Terminology

Core meant magnetic core memory, the prevalent technology before the invention of semiconductor memory. Even today, Unix systems are said to "dump core" to disk when unable to recover from an error.

40K meant 40x1024 words. A PDP-10 36-bit word could hold five 7-bit ASCII characters or four 9-bit SAIL characters. In units of eight-bit bytes, PUB needed 330K of available memory.

Why two passes were necessary

There were several reasons that PUB required two passes. Pass 1 generated front matter such as the Table of Contents that Pass 2 had to output before other pages. Pass 1 determined the targets of cross references so that Pass 2 could fill them in.

Pass 1 automatically ran Pass 2, but the user could run Pass 2 separately to generate output for another device.

SAILON-70                   INTRODUCTION                       Page 3


command typed                input file     output file    switches
_______ _____                _____ ____     ______ ____    ________
.COM FOO                     FOO.PUB        FOO.DOC
 ___ ___
.COM FOOBAZ`````````````````BAZ.PUB````````FOO.DOC
 ___ _______
.COM /PUB FOO.OOFBAZ.ZAB````BAZ.ZAB````````FOO.OOF
 ___ ____ _______________
.COM /PUB FOO.OOF            FOO.OOF        FOO.DOC
 ___ ____ _______
.COM FOO(DN)                 FOO.PUB        FOO.DOC        /D /N
 ___ _______
.R PUB
 _ ___
*FOO/D/N                     FOO.PUB        FOO.DOC        /D /N
 _______

               Do not specify more than one input file nor  more than
               one  output file.   Multiple input  files  are handled
               using the REQUIRE statement (see Section 7.11).

               WARNING (RPG users): If in addition to file  X.PUB you
               have a  file X.SAI  (or X.FAI, etc.)  and if  you type
               "COM X",  RPG will  do a  SAIL (or  FAIL) compilation.
               SOLUTION: Type "COM X.PUB".

               FURTHER WARNING (RPG users): If you have a  file X.REL
               which  is  newer than  X.PUB,  then RPG  won't  do any
               compilation.  SOLUTION: Type "COM /COM X.PUB".

               Presently available switches are:

         nS        Change  intra-paragraph  line   spread:  1S=Single
               Space, 2S=Double Space, etc
          B        Big Document  -- allocates  hashed space  for 3000
               identifiers instead of 1000
          H        Huge  Document --  allocates maximum  symbol table
               space (8191)
          D        DEBUG  --  prints  approximate  source  file  line
               numbers alongside the output
          L        Line Printer output planned (Default)
          M        Microfilm  output planned  (produces  FR80 command
               file -- see Section 7.16)
          T        Terminal  output  planned  (may  produce different
               output than /L)
          Y        Yes! Automatically delete ".PUI" files  after Pass
               2 (Default)
          N        No! Don't delete them (thus allowing Pass 2  to be
               re-run with a different DEVICE)
          A        Ask me whether to delete them when it's time.
          Z        Compiler Debug: see compiler (PUB.SAI[2,TES])




                                 1.3

Terminology

REQUIRE was like include in C and other modern languages.

RPG was like Unix's make.

Tables in PUB vs. HTML

PUB had no element equivalent to HTML's table. Instead, it provided two poorly documented methods of generating a table.

To generate a table row by row, the PUB author set tabs stops and inserted tab characters between the cells in each row. That is probably how I made the table on the adjacent page.

To generate a table column by column, the author created a temporary area (Section 6.10) and inserted next column commands between columns.

Using macros, it was possible to invent a personal notation similar to HTML's table. Whether anyone ever bothered, I do not know.

Page 4                      INTRODUCTION                    SAILON-70


1.4 COMPILER OUTPUT
    ________ ______

               During Pass one, whenever  PUB reads a "Page  Mark" or
               Form Feed,  it types out  the manuscript  page number.
               During Pass Two, whenever  PUB writes a Form  Feed, it
               types out  a count  of the number  of output  pages so
               far.

               During Pass  One, PUB also  types out  error messages.
```````````````After each``message, an arrow``() or a``question mark
               (?) is typed  out.  You may  then respond as  in SAIL.
               If you are not  familiar with SAIL, here is  a summary
               of responses:

       <CR>        Continue compiling after this error.
       <LF>        Continue compiling,  and after  subsequent errors,
               continue automatically.
           NOTE: The above two responses are not valid after "?"
E<file><CR>        Edit file <file>.
      E<CR>        (RPG only) Edit the manuscript file.
      S<CR>        Start Over.

               In DEBUG mode (the /D switch), some error messages are
               also output in the right margin of the document.

               Whenever PUB prints a line number in an  error message
               or in the right margin  of the document, it is  of the
               form:
<file id><line no.>/<page no.>[<macro line no.>/<macro page no.>]

               If the line is from the manuscript, then  <file id> is
               empty.  If  it is  from another file  (such as  one of
               those ".PUG" files mentioned above), then <file id> is
               the  first three  letters of  the first  name  of that
               file.

               If the file is  in SOS format, then the  <line no.> is
               always  five  digits,  including  leading   zeroes  if
               necessary.  If it is from a TECO or TVEDIT  file, then
               PUB  generates  line  numbers  1, 2, 3,  etc.  without
               leading zeroes.  If it is from a ".PUG" file, then the
               <line no.>  is  the  line  number/ page  number  of  a
               relevant  line in  your  manuscript or  in  some other
               source file.

               If a  macro was  being expanded,  the line  number and


                                 1.4

Terminology

TVEDIT (1963) was a display-oriented text editor originally developed by Brian Tolliver for the Stanford PDP-1. Pentti Kanerva ported it to the PDP-10 around 1969 and made a number of improvements. It was a little less powerful, but more user-friendly, than EMACS (1974).

Digression

Pentti's version of TVEDIT had an oops command that restored deleted text to the location of the cursor. To move text, the user issued a delete command, repositioned the cursor, and issued an oops command.

That trick gave me the idea of using cut and paste, not only to position blocks of lines from a galley proof onto a page, but also to move text around within a manuscript. I got to implement cut and paste in Gypsy at PARC in 1974.

SAILON-70                   INTRODUCTION                       Page 5


               page number of its definition are noted  within square
               brackets.  The file  that contained the  definition is
               not noted, so if can't find it in your  manuscript, it
               probably came from PUBSTD.DFS, the PUB  standard macro
               file, or from one  of your REQUIRE files  (see Section
               7.11).

               Examples:

02300/10        Manuscript file, page 10, line 2300 (SOS)
IND02300/10/1   INDEX.PUG file, page 1, comes from Manuscript 2300/10
PUB25/1         PUB Standard Macro File, Page 1, Line 25 (TVEDIT)



1.5 READING THIS MANUAL
    _______ ____ ______

               This manual is ordered  such that as soon as  you have
               learned enough of the system to solve  your particular
               problem, you can skip the rest of the manual.  Read at
               least  through  Section  2.3  before  making  any such
               assumption.

               In  describing  the   syntax  of  PUB   commands,  the
               following meta-linguistic symbolism is employed:

      <...>        These  brackets delimit  the name  of  a syntactic
               entity
      [...]        These delimit optional components of the command
    ...|...        This character separates alternatives for the same
               command component

               Cross-references  in  this  document  are   always  to
               subsections.   Subsection numbers  are printed  at the
               bottom of each page.



1.6 TUTORIAL FOR BEGINNERS
    ________ ___ _________

               PUB is a  string processing language.   Characters can
               be  formed into  words, words  into lines,  lines into
               paragraphs,  paragraphs  into  columns,  columns  into
               "areas" (such as the title areas at the top and bottom
               of the page),  areas into pages, pages  into sections,


                              1.5 - 1.6

Page 6                      INTRODUCTION                    SAILON-70


               sections  into  "portions"  (such  as  the   Table  of
               Contents  or  the  Appendices),  and  portions  into a
               document.  The  methods of  bulding larger  units from
               smaller  ones are  flexible and  under control  of the
               programmer.

               The most trivial  use of PUB  is to create  a document
               that is  exactly identical  to the  manuscript, adding
               only  headings  and footings.   PUB  assumes  that the
               format of each output  page is as follows.   The first
               three lines are a Heading area of which only the first
               is usually used.   The next 48  lines (lines 4  to 51)
               are the Text area.  Line 52 is blank and line 53  is a
               Footing area.   The Footing area  is for  page numbers
               and  other reference  information, not  for footnotes.
               (Footnotes are  placed inside  the Text  area, towards
               its bottom).

               The width of each page is assumed to be 69 characters.
               It is assumed  that there is  only one column  of text
               output.  Therefore, the longest an output line  can be
               is 69 characters.

               The  number  of  lines in  each  area,  the  number of
               columns of text, and the number of characters  in each
               column  may be  changed by  declaration.   See Section
               6.7 and  Section 7.13  for details.   If all  you want
               to do is widen the page, e.g., to 75  characters, then
               make the following line the first of the manuscript:
.PAGE FRAME 53 HIGH 75 WIDE

               The "Dot" in column one indicates that this line  is a
               Command Line for PUB to obey and should not be printed
               in  the document.   If  you would  rather  a different
               character in column  one served for this  purpose, see
               Section 2.2.

               PUB assumes  that you want  no headings  and footings.
               It  will leave  the  heading and  footing  areas blank
               unless  you specify  otherwise.  The  simplest  way to
               specify  headings and  footings is  with  the standard
               macros  "EVERY  HEADING" and  "EVERY  FOOTING".  These
               macros can specify a title for the left  edge, center,
               and right  edge of  the heading  area and  the footing
               area.  For example, the macro call:
.EVERY HEADING(PRELIMINARY REPORT,PARACYBERNETIC PHENOMENA,1972)



                                 1.6
      

The Document Object Model (DOM)

PUB did not have a document object model as powerful as that of DHTML. But it did have a hierarchy of elements, at the top of which were portions. Portions were major document divisions like the Table of Contents, the main body of text, and the Index.

Like JavaScript, PUB offered the ability to append text, with or without markup, to elements. PUB offered both a simple and a fancy method of appending to elements.

In the simple method, text without markup (i.e., after markup had been applied) was appended to the current line, lines were appended to the current paragraph, etc., up the hierarchy to the current portion. Today, pure HTML without scripts operates the same way.

In the fancy method, one portion, usually the main body of text, sent text with unapplied markup to another portion. For example, the main body could send an entry to the Table of Contents, Bibliography, or Index. In pass 2, the receiving portion processed the markup as if it had been part of its original source code. In JavaScript today, a similar process applies when a script uses the writeln function to add markup to a related document in a frame.

The PUB compiler had no predefined notion of a table of contents, bibliography, or index. The author could define as many portions as desired, with their format and structure determined by the script and the markup.

Page layout in PUB vs. RUNOFF

Instead of PUB's page frame, RUNOFF had distinct line length and paper length commands.

In RUNOFF, the header command took one argument. Alignment was determined by a separate heading mode command. The page command and its partner, paging mode, controlled the printing of page numbers. PUB combined and generalized these facilities.

The dot convention

The dot convention originated in RUNOFF. Successors such as SCRIPT, GML, and troff followed suit. Commands had to start on a new line.

PUB supported both command lines that began with a dot and intra-line switching between command mode and text mode, in a similar fashion to PHP today.

TeX (1978) and SGML (1986) dropped the dot convention completely, and allowed markup to appear anywhere.

SAILON-70                   INTRODUCTION                       Page 7


               will print  on the  top line of  every page  the three
               titles shown.

               To make the top  line of every page display  the title
               "PRELIMINARY REPORT" on the left and the  current date
               on the right, use:
.EVERY HEADING(PRELIMINARY REPORT, ,{DATE})

               The  consecutive commas  indicate that  the  center is
               empty.   The  curly  brackets  around  the  word  DATE
               specify that  DATE is  not a title  to be  printed but
               rather a variable to be evaluated.

               To make the number of each page appear  bottom center,
               use:
.EVERY FOOTING(,{PAGE},)

               To learn about fancier headings and footings, you will
               have to read most of this document, especially Section
               7.5 and Section 10.2.

               PUB will  number your pages  1, 2, 3, etc.  unless you
               declare otherwise.   To learn  how, see  Section 6.11.
               A new page  of output will be  started for one  of two
               reasons: the previous page is full, or a page-changing
               command  is executed.   The most  common page-changing
               command is:
.NEXT PAGE

               This always starts  a new page,  even if one  was just
               started and nothing is on it yet.  To start a new page
               only if there is something on the current page, use:
.SKIP TO COLUMN 1

               To leave a few blank lines in the document, use:
.GROUP SKIP 10

               The SKIP command is described in Section 7.12.

               PUB processes text a  paragraph at a time.   The usual
               way  to  indicate  the  end  of  a  paragraph  in your
               manuscript is by a blank line (that is, just a  CR and
               LF).   Oher  ways  are  discussed  elsewhere  in  this
               manual, beginning at Section 2.3.

               Usually, PUB packs a paragraph as tightly  as possible
               by  filling  up  each output  line  with  words before


                                 1.6
      

More about page layout in PUB vs. RUNOFF

RUNOFF supported header text but not footer text. PUB symmetrically supported both.

The RUNOFF equivalent to next page was begin page. I adopted next x as a uniform way to start a new element at any level of the hierarchy.

Unlike RUNOFF, PUB supported multiple columns per page. But the word column in the skip to column command referred to character position, i.e., distance from the left margin.

One application of the group skip command was to leave space for a hand-pasted illustration.

Page 8                      INTRODUCTION                    SAILON-70


               beginning a new line.  This is called "filling".  Then
               PUB inserts extra spaces between words to  eliminate a
               ragged right edge from the paragraph.  This  is called
               "justifying".

               PUB  will  not  indent the  first  line  of paragraphs
               unless an  indent command  appears in  the manuscript,
               e.g.:
.INDENT 6

               To learn more  about indentation and  related matters,
               see Section 6.4 through Section 6.7.

               PUB assumes you would like your text lines  filled out
               and justified.  You  can selectively exempt  blocks of
               your manuscript from this fate.  Each such  block must
               be delimited by  ".BEGIN" and ".END".   After "BEGIN",
               specify a formatting mode to persist for  the duration
               of the block.  Examples:

Fill, but don't Justify    Don't even fill   Copy verbatim
_____ ___ _____ _______    _____ ____ ____   ____ ________
.BEGIN NOJUST              .BEGIN NOFILL     .BEGIN VERBATIM
   ...                        ...               ...
.END                       .END              .END

               In  "NOJUST"  mode,  lines  will  be  filled  but  not
               justified.   In  "NOFILL" and  "VERBATIM"  modes, they
               will  not  even  be  filled.   The  difference between
               NOFILL and  VERBATIM is that  VERBATIM is  both faster
               and dumber.  It is faster because it copies  the lines
               of the manuscript  to the document without  looking at
               them, except to see if  there is a dot in  column one.
               It  is  dumber  because  it  does  not  recognize text
               control characters  that PUB normally  recognizes, and
               it does  not reformat in  any way.  Thus,  VERBATIM is
               used to  copy blocks of  manuscript that  are arlready
               formatted perfectly.

               Filling allows  the manuscript to  be quite  ragged, a
               great  convenience   in  editing.   Short   lines  are
               lengthened and long  lines are shortened.   Be careful
               in NOFILL or VERBATIM mode that no manuscript  line is
               longer than 69 characters (or whatever limit  you have
               declared), or  some of  it will be  lost and  an error
               message given.



                                 1.6

Paragraph styles in PUB vs. RUNOFF and vs. CSS

Indent was lifted directly from RUNOFF. The CSS equivalent is the text-indent attribute.

Adjust, nojust, fill and nofill were also lifted from RUNOFF. The corresponding attribute in CSS is text-align.

Verbatim's effect was less like HTML's pre than its deprecated xmp.

SAILON-70                   INTRODUCTION                       Page 9


1.7 SAMPLE COMPILATION
    ______ ___________

               You now  know enough to  use PUB for  simple purposes.
               The next three pages show a sample manuscript  and the
               document that PUB produced from it.











































                                 1.7

Page 10                     INTRODUCTION                    SAILON-70


.EVERY HEADING(DAN MATION,PARACYBERNETIC PHENOMENA,{DATE})
.EVERY FOOTING(,{PAGE},)
.INDENT 6
.BEGIN VERBATIM
.GROUP SKIP 20
                        PARACYBERNETIC PHENOMENA


                             BY DAN MATION
.END
.NEXT PAGE
It has been observed that the Sigma 3 in Horsetown, Mass. and the
CDC 6600 in Liverless, Cal. tend to have parity errors at the same
time.  When records were compared by
Miss Minnie Messer, Director of the Horsetown Chamber of Commerce
Computation Facility,
and Mr. Solomon Crunch of Liverless Hospital's Organ-Transplant
Inventory Project, it was shown that
the correlation of parity error occurrences was 0.8, with a
probability of random coincidence of <.00000001.

Miss Messer and Mr. Crunch revealed these discoveries at the
Universal Users Union meeting in Cranchville, Tenn. after they
arrived two hours late for Mr. Crunch's scheduled talk there.
They said that in the excitement of discovery
the meeting slipped their minds.

This report has motivated this author to undertake
a wider survey to determine if similar
phenomena have occurred elsewhere.  The author has
solicited Miss Messer's assistance in this survey,
but without the cooperation of the entire computing community,
it is unlikely that sufficient
data
can be collected.  Therefore, we request that interested
parties tabulate the exact times of occurrence of parity
errors on their computer during the 7 day period
1200 April 18 to 1200 April 25 and send it to:
.BEGIN NOFILL

        Paracybernetic Society
        c/o Dan Mation
        Boise Institute of Technology
        Boise, Idaho
.END
Results of the study will be presented at the next UUU meeting
in December.
      

DAN MATION            PARACYBERNETIC PHENOMENA        January 15,1972






















                        PARACYBERNETIC PHENOMENA


                             BY DAN MATION

























                                  1
      

DAN MATION            PARACYBERNETIC PHENOMENA        January 15,1972


      It has been observed that  the Sigma 3 in Horsetown,  Mass. and
the CDC  6600 in Liverless,  Cal. tend to  have parity errors  at the
same  time.   When  records  were  compared  by  Miss  Minnie Messer,
Director of the  Horsetown Chamber of Commerce  Computation Facility,
and  Mr.  Solomon  Crunch  of  Liverless  Hospital's Organ-Transplant
Inventory Project, it was shown that the correlation of  parity error
occurrences  was 0.8,  with a  probability of  random  coincidence of
<.00000001.

      Miss Messer  and Mr. Crunch  revealed these discoveries  at the
Universal  Users  Union  meeting  in  Cranchville,  Tenn.  after they
arrived two hours late  for Mr. Crunch's scheduled talk  there.  They
said that in  the excitement of  discovery the meeting  slipped their
minds.

      This  report has  motivated this  author to  undertake  a wider
survey  to determine  if similar  phenomena have  occurred elsewhere.
The author has solicited Miss Messer's assistance in this survey, but
without  the cooperation  of the  entire computing  community,  it is
unlikely  that  sufficient  data  can  be  collected.   Therefore, we
request  that  interested   parties  tabulate  the  exact   times  of
occurrence of parity errors on their computer during the 7 day period
1200 April 18 to 1200 April 25 and send it to:

              Paracybernetic Society
              c/o Dan Mation
              Boise Institute of Technology
              Boise, Idaho

      Results of the study will be presented at the next  UUU meeting
in December.


















                                  2
      

SAILON-70                        PUB                          Page 13


                              SECTION 2

                          TEXT CONVENTIONS




2.1 ILLEGAL CHARACTERS
    _______ __________

               If the following  characters occur in  the manuscript,
               they may cause problems:

       '177        Rubout
       '175        Altmode
        '13        Vertical Tab

               These characters are ignored in the manuscript:

         '0        Null
        '14        Form Feed  (except after  LF, where  it is  a page
               mark)

               A  manuscript   prepared  using   SOS  or   TVEDIT  is
               legitimate  if  it has  no  vertical tabs.   If  it is
               prepared using TECO, be  sure as well that  every line
               ends with CR LF.

               Tabs are expanded to the appropriate number of spaces,
               as in the line editor.



2.2 COMMAND AND TEXT LINES
    _______ ___ ____ _____

               Every line with a  dot (".") in column 1  is processed
               as a command line.  Every other line is processed as a
                    _______ ____
               text line.
               ____ ____
               If you would prefer a different character to introduce
               command lines, e.g., $, use the command:
COMMAND CHARACTER "$" ;






                              2.1 - 2.2

Special characters

The single quote character in SAIL and in PUB introduced an octal number.

Page 14                   TEXT CONVENTIONS                  SAILON-70


2.3 PARAGRAPHING
    ____________

               The  text  is   processed  in  logical   units  called
               "paragraphs".   A  paragraph  is  the  accumulation of
               words from one or  more text lines, terminated  by the
               occurrence of a paragraph break.
                               _________ _____
               A paragraph break can  be caused by the  command BREAK
                 _________ _____
               as well as by several other commands.  In  addition, a
               paragraph break can be caused by signals in the text.

               Paragraphing conventions can  be varied by the  use of
               various mode and switch settings.



2.4 FILL MODE
    ____ ____

               In FILL mode, the  compiler puts as many words  as can
               fit on each output line before beginning a new line --
               each line is "filled" with words.

               For convenience of  exposition, names have  been given
               to the  parts of  the output  paragraph in  FILL mode.
               The first line  is called the  crown, and the  rest of
                                              _____
               the lines are called the vest.  It is common to indent
                                        ____
               the  crown and  not  the vest,  or vice  versa,  or to
               indent them different  amounts.  The last line  of the
               vest is called the hem.  While the other lines  of the
                                  ___
               paragraph  can be  subject to  justification,  the hem
               line is never justified.



2.5 JUSTIFICATION
    _____________

               In FILL mode, whether or not output lines are
               justified to the right margin is determined by the
               setting of the "ADJUST-NOJUST" switch; but the hem
               line is never justified in any case.






                              2.3 - 2.5

Terminology

Terms I coined like crown, vest, and hem never caught on.

Paragraph breaks

RUNOFF and PUB:

.break

HTML:

<br>

FILL mode

RUNOFF and PUB:

.FILL
Lines of text up to a negating command such as:
.NOFILL

DHTML:

<div style="text-align: left;">
Lines of text
</div>

Justification

RUNOFF:

.ADJUST
Lines of text up to a negating command such as:
.NOFILL

PUB:

.ADJUST
Lines of text up to a negating command such as:
.NOJUST

DHTML:

<div style="text-align: justify;">
Lines of text
</div>

 

SAILON-70                 TEXT CONVENTIONS                    Page 15


2.6 BREAKING AT BLANK LINES
    ________ __ _____ _____

               In FILL mode,  a BREAK is  caused by every  blank line
               (just CR-LF).  Redundant  blank lines have  no effect.
               To disable this response, see Section 10.1.



2.7 BREAKING AT TABS
    ________ __ ____

               Tabs are converted to an appropriate number  of spaces
               by  PUB.   If  you  would like  a  single  tab  at the
               beginning of a text  line to cause a  paragraph break,
               put this command at the beginning of your manuscript:
.TABBREAK

               This  makes text  lines  that are  indented  exactly 8
               spaces  cause  a  break.   Since  an  initial  TAB  is
               converted  to  8  spaces,  it  will  also  break.  The
               inverse of TABBREAK is TABSPACE.



2.8 BREAKING AT CARRIAGE-RETURNS
    ________ __ ________________

               In  FILL mode,  PUB usually  converts  every carriage-
               return at the end of a text line to a space.  If it is
               at the  end of a  sentence, it converts  the carriage-
               return to two spaces.  If you would rather  that every
               carriage-return ending a text line caused  a paragraph
               break, use this command:
.CRBREAK

               The inverse of CRBREAK is CRSPACE.



2.9 NOFILL MODE
    ______ ____

               In  NOFILL mode,  one input  line produces  one output
               line, even if it falls far short of the  right margin;
               if  the line  is too  long, characters  will  be lost.
               Every  carriage-return ending  a text  line  in NOFILL


                              2.6 - 2.9

White space in PUB vs. HTML

White space interpretation differed significantly from HTML.

NOFILL mode

RUNOFF and PUB:

.NOFILL
Lines of text up to a negating command such as:
.FILL

HTML approximation:

<pre>
Lines of text
</pre>

Page 16                   TEXT CONVENTIONS                  SAILON-70


               mode causes a  paragraph break.  The  commands ADJUST,
               CRSPACE, and TABBREAK do not affect this mode.

               NOFILL  mode  has  several  variations,  which  differ
               mainly in the final treatment of the output line:

               NOFILL: (Standard variation) No special treatment.

         CENTER: Center the output line between the margins.

                      FLUSH RIGHT: Shove it against the right margin.

FLUSH LEFT: Shove it against the left margin.

JUSTJUST:    Justify    it    by    the    insertion    of    spaces.

VERBATIM: Copy text lines to output exactly as written,
                 without changing
```indentations.``Ignore all control characters {α[#]&β\-.
            Dot in column 1   still signals a command line.
        This mode speeds text processing
                                 when no formatting is needed.

               SUPERIMPOSE  [n]:  Suppress the  LF  after  each line,
               except every n'th line.
<  < !    ~ % 7 Z
|  > ? /   . \ - -



2.10 HORIZONTAL SPACE COMPACTION
     __________ _____ __________

               In COMPACT  mode, redundant spaces  in the  input line
               are discarded.        In      RETAIN  mode,       they
               are           retained.

               More precisely, in COMPACT mode, a sequence of  two or
               more spaces is reduced to one space, except at the end
               of a sentence, where it is only reduced to two spaces,
               and at the beginning of a text line, where  all spaces
               are discarded.  Of  course, spaces may  be re-inserted
               during justification.






                                2.10

CENTER mode

RUNOFF:

.CENTER
One line of text to center
.CENTER
Another line of text to center

PUB:

.CENTER
Lines of text up to a negating command such as:
.FILL

HTML:

<center>
Lines of text
</center>

DHTML:

<div style="text-align: center;">
Lines of text
</div>

SUPERIMPOSE mode

PUB:

.SUPERIMPOSE 2
X ~ 7
X . -

DHTML:

<pre>
X ~ 7
<div style="position:relative; top:-1.2em;">
X . -
</div>
</pre>

COMPACT and RETAIN modes

There is no exact equivalent in other markup languages of which I am aware.

SAILON-70                 TEXT CONVENTIONS                    Page 17


2.11 VERTICAL GROUPING
     ________ ________

               In GROUP mode, all  output lines are forced  to appear
               in an unbroken column.  Its inverse is APART mode.  If
               the bottom of the output page is encountered  while in
               GROUP mode, the whole group is moved to the top of the
               next column or page.

               It is  unwise to use  GROUP mode for  more than  a few
               lines  that  must  appear  undivided  in  the  output.
               Example:

.GROUP
EQUATION 6
  m = vt
.APART
               This would prevent "Equation 6" from appearing  at the
               bottom  of one  page and  "m = vt" at  the top  of the
               next.



2.12 MODE AND SWITCH SETTING COMMANDS
     ____ ___ ______ _______ ________

               The  commands that  select the  paragraphing  mode are
               FILL,  NOFILL,   CENTER,  FLUSH  RIGHT,   FLUSH  LEFT,
               JUSTJUST,  VERBATIM,  and  SUPERIMPOSE  [n],  where  n
               [optional] is any "SAIL" expression.

               The  commands  ADJUST  and  NOJUST  set  the FILL-mode
               justification  switch.   TABBREAK,  TABSPACE, CRBREAK,
               and CRSPACE control  the reaction to initial  tabs and
               to carriage-returns in FILL mode.

               The  commands  RETAIN  and  COMPACT,  GROUP  and APART
               select the space compaction and column grouping modes.

               At the  outset of compilation,  the settings  in force
               are:
.FILL    ADJUST    TABSPACE  CRSPACE   RETAIN    APART

               WARNING:  Switching  to  NOFILL  or  to  any   of  its
               variations  automatically  switches  to  RETAIN  mode.
               This  can be  overridden by  following the  command by
               COMPACT.


                             2.11 - 2.12

Pagination in PUB vs. HTML

Grouping and many other features of PUB were concerned with pagination, a non-concept in HTML.

Naming inconsistencies in PUB

The group/apart pairing was one example of inconsistent naming that made PUB hard to learn. In my original design, all open/close pairs were consistently named, e.g., GROUP and NOGROUP. Paul Heckel paid me a visit one day in 1971 to inform me that someone had hired him to develop software whose functionality was between that of RUNOFF and PUB. He begged me to make my command suite a superset of his. I foolishly succumbed to the pressure.

Ironically, Paul's project was canceled before I completed PUB. If he had informed me, I could have restored parsimony.

Digression

Years later, Paul wrote a book on friendly software design, which I endorsed. More irony.

Elements and Tags

Like RUNOFF and GML, and unlike SGML and HTML, PUB had no uniform tag syntax with which to bracket elements.

Page 18                   TEXT CONVENTIONS                  SAILON-70


2.13 WORD BREAKS
     ____ ______

               The compiler  processes the  input paragraph  in units
               called  words.   A  "word"  is  roughly  defined  as a
                       _____
               sequence  of  consecutive  visible  characters.   More
               precisely, the compiler concatenates characters into a
               word until the occurrence of a word break.
                                              ____ _____
               A  word  break is  normally  signalled by  any  of the
               following in a text line:

>A space (or a sequence of spaces)
>A carriage-return (the end of an input line)
>The control character β, if activated (as well as some others)

               Word breaks serve two functions.

               (1) FILLING:  In generating  an output  paragraph, the
               compiler puts as  many words as  can fit on  each line
               before beginning a new line.  The paragraph  will only
               be divided for this purpose at word breaks.

               (2) JUSTIFYING:  During  justification,  extra  spaces
               will only be inserted at word breaks.



2.14 CONTROL FUNCTIONS
     _______ _________

               Several control  functions can  be invoked  by control
               characters in the text line.  The user can  choose the
               characters he  wishes to  serve these  functions.  For
               simplicity  of exposition,  a suggested  character has
               been designated for each function.

               The following control functions are available.  If the
               description  states: "BLA  mode only",  then  in other
               modes, the character is treated no differently than an
               alphanumeric.

``````````β````````Cause a word βreak.

``````````α````````Pretend the``next character is``αlphanumeric (this
               lets you slip in control characters);

``````````#````````Same as α <space>; sneaks spaces into words.

                             2.13 - 2.14

Special characters in PUB

α in PUB served the same purpose as backslash ( \ ) in many modern languages. It escaped the next character.

# was like &nbsp; (non-breaking space) in HTML.

PUB's reliance on non-ASCII SAIL characters like β as language delimiters was a barrier to widespread adoption.

SAILON-70                 TEXT CONVENTIONS                    Page 19


          . ! ?    FILL mode  only, and  only at the  end of  a word:
               marks the end of a sentence. This means:

                   (1) If followed by two or more  spaces, COMPACTion
               only reduces the spaces to two instead of one.
                   (2) If followed by a carriage-return, replaces the
               CR by two spaces instead of one.

          -        FILL mode only, and  not the first character  of a
               word: a hyphen.  This means:

                   (1) If at  the end  of a  line, prevents  the word
               break that usually occurs there.
                   (2) Otherwise, permits the word to be broken after
               the hyphen in case it overfills the output line.

          \        TAB.  Insert spaces up to the next tab stop set by
               the TABS command (see Section 6.3).

``````````+n``````MOVE RIGHT.``Leave n spaces in the output line.

``````````-n``````MOVE``LEFT```n characters.``Create``new characters
               (these due to Jerry Agin): ~ ~ O O ~
`````````````````````````````````````````` ( - | V.

``````````n```````TAB.``Insert``spaces up to``but not``including the
               n'th character  position from  the left  margin (flush
```````````````left is n=1). ``Both kinds of``TAB (\ and``n) inhibit
               insertion of all justification spaces to their left.

```````````````````For n``and``+n, n``may be any``"SAIL" expression
               enclosed  in parentheses.   In  the case  of  a single
               letter variable or a one-digit number, the parentheses
```````````````may``be omitted. ``RESTRICTION...``(<expression>) may
               not appear as the last thing on a text line.

``````````````````Right Flush. ``If a``\ or n``occurs later``in the
               line, slide  the text that  is between here  and there
               flush  against  the  column  designated  by  the  tab.
               Otherwise,    slide the rest of this paragraph against
                          the right margin, inhibiting justification.

``````````````````Center.``If a``\ or n``occurs later in``the line,
               center the text that is between here and there halfway
               between the current  column and the  column designated
               by  the  tab.  Otherwise,  center  the  following text
               between the margins, inhibiting justification.



                                2.14

MOVE LEFT

To achieve:

^. rest of line

PUB:

^∂-1. rest of line

DHTML, if you know the width of the font:

<pre>
^<span style="position:relative;
left:-6pt;">. rest of line</span>
</pre>

MOVE RIGHT and TAB

The equivalents in DHTML are relative and absolute horizontal positioning with positive values of left.

PUB, where the value of VAR is in character units:

∂(VAR) rest of line

PHP, where the value of $var is in pixel units:

<pre>
<span style="position:absolute;
left:<?php echo $var ?>px;"> rest of line</span>
</pre>

Flush and Center

Microsoft Word has left, center, right, and decimal tabs. Centered text is centered around a center tab. PUB had only one kind of tab. Centered text was centered between two consecutive tabs.

PUB:

Left words←Center words→Right words

HTML:

<table width="100%">
  <tr>
    <td align="left">Left words</td>
    <td align="center">Center words</td>
    <td align="right">Right words</td>
  </tr>
</table>

 

Page 20                   TEXT CONVENTIONS                  SAILON-70


``````````x```````Repeat.```x' is``any character. If x``precedes \,
```````````````+, n, , or ,``then use the character x``instead of
               spaces  as filler  to the  left of  the  affected text
```````````````(i.e., .\ puts ..... up to the tab column).

``````````xyz...Use the repeating string xyzxyz... as filler.

``````````_..._``Underline.```In the``text between``brackets, every
                                __ ___  ____ _______  _________ _____
               visible character is underlined. "_" is only a control
               _______ _________ __ ___________
```````````````character when``paired with "".```If you``want spaces
               underlined    as    well    in    a    title,   simply
               replace each space by an underbar.
               _________________________________
``````````````````nderline```one```word.````The````following```word
                                                                 ____
               (consisting of letters and digits only) is underlined.

``````````π````````πrint a weird character.``The line printer and FR-
               80 have these but your terminal doesn't.

                                   To get.............Write
                                   __ ___             _____
```````````````````````````````````(center dot) ``````π.
`````````````````````````````````γ``(gamma)````````````πG or πg
`````````````````````````````````δ``(apple delta)``````π
```````````````````````````````````(integral)`````````π~ (tilde)
`````````````````````````````````±``(πlus-minus)```````π-
```````````````````````````````````(circle plus)``````π+

          {        Switch to Command  Processing.  To return  to text
               processing, use }.  See Section 2.16.

``````````x```````Subscript.``The text x is````````````````(an extra
                                             lowered a line
               line  is  reserved  for  it).   x  may  be  any single
               character except "[" or  "_", or may be a  sequence of
               characters bracketed between [...] .  A subscript must
               appear all on one line.

``````````x```````Superscript.``Analogous to Subscript, except x may
               also  be  the  single  character  "_".   Collectively,
               superscripts
                            and            are called somescripts.
                                                      ___________
                                subscripts
                   These may  combine and  nest in  interesting ways.
               Super/subscripts may not nest more deeply than 4.

          x&y      Align.  "&" is only considered a control character
               if it is the first character following a somescript x.


                                2.14
To be continued [after 13 Feb 2005]...

SAILON-70                 TEXT CONVENTIONS                    Page 21


               Its effect  is to align  the leftmost characters  of x
               and  y  by  backspacing after  printing  x  and before
               printing y, and  to align the rightmost  characters by
               forward spacing to  the end of the  longer of x  and y
               when  done.  x  must be  a somescript.   y may  be any
```````````````single character``except "[", "",``or "", or``may be
               another  somescript,  or   may  be  any   sequence  of
               characters enclosed between [...] .  Examples:

To get...Write     To get....Write
__ ___   _____     __ ___    _____
 j                 _ 2
x````````xj&i````y`````````_&y[i+j]&[ 2]
 i                  i+j

  2
x````````xi2`````SUM```````[ t]&[SUM]
 i                  t

                    i2
````````x&``````x`````````xi2
x

                     2
.                   i
t````````.&t``````x`````````x[i2]



2.15 CONTROL CHARACTER ACTIVATION
     _______ _________ __________

               At  the  outset  of  compilation,  the   only  control
               characters  recognized are  the punctuators  ".", "!",
               and "?"  when they appear  at the end  of a  word, and
               hyphen ("-") when it appears in the middle of  a word.
               NOTE: Not even  "{" is recognized unless  you activate
               it.  However, "}" is permanently active, because it is
               not  a text  control  character but  really  a command
               language delimiter.

               To turn  on any control  function using  its suggested
```````````````character ("α" for example), use the command:
.TURN ON "α"

               To  activate the  control function  using  a different
```````````````character, such as "%" or "β", write:


                                2.15

Page 22                   TEXT CONVENTIONS                  SAILON-70


.TURN ON "%" FOR "α"
.TURN ON "β" FOR "α"
               To  de-activate a  control character,  such as  "?" or
               "%", use:

.TURN OFF "?"
.TURN OFF "%"

               One TURN command  may have several  operands separated
               by commas:
.TURN ON "%" FOR "α", "@" FOR "", "", "\"
.TURN ON "", "", "[", "]", "_", "&"

               The latter may be abbreviated:
.TURN ON "[]_&"

               There  is a  subtle problem  that arises  when control
               characters have been turned on inside a macro  and the
               macro wants to turn off only the ones that  weren't on
```````````````previously. ``If``it``has``done``a ``TURN ON "",``for
```````````````example,``it can``not undo``it with``TURN OFF "", for
               that would  always TURN it OFF  whether or not  it was
               originally on.   There are  two ways  to do  it right.
               One is to use  block structure (see Section  5.2), but
               sometimes  this  is impossible,  because  blocks cause
               paragraph breaks.  The other way is to use the command
               TURN ON|OFF  without  arguments.   Its  effect  is  to
               cancel  the previous  TURN ON|OFF that  had arguments,
               was  in  the  current  block,  and  has  not  yet been
               cancelled.

               For purposes of smooth exposition, in the rest of this
               manual it is assumed  that you have turned on  all the
               control   functions   and  used   all   the  suggested
               characters for them.  Remember, though, that  only the
               punctuators   are   turned  on   unless   you  command
               otherwise!

               It  is  recommended   that  you  don't  turn   on  any
               characters  except  in  short  blocks  where  you know
               you'll remember they're  on.  Ideal places  are inside
               macro bodies (See Section 3.1).







                                2.15
      

SAILON-70                 TEXT CONVENTIONS                    Page 23


2.16 COMPUTED TEXT
     ________ ____

               The  control  character  "{"  will  switch  to command
               processing right in the  middle of a text  line.  This
               allows the execution of any PUB commands without first
               causing either a paragraph break or a word  break.  If
               you want a word break before the {, force it  by means
```````````````of a β or a space.

               The command  most commonly executed  after "{"  is the
               Computed Text Command.   A variable, a constant,  or a
               ________ ____ _______
               parenthesized  expression  occurring  in  isolation is
               _____________
               evaluated and its string value is then scanned  by the
               text scanner as text.  Example:

A = {A}, and B = _{(2+2)}_.

```````````````If``the value``of A``was the``string "3",``this would
               output:

A = 3, and B = 4.
    _          _
               Caution: If  a {...} construct  extends onto  a second
               input  line, be  sure to  begin the  continuation line
               with a "." -- or you won't be in the command scanner!

               Caution: A string constant following the word BEGIN is
               considered a block name, as in SAIL, and  not computed
               text.  If you  put computed text after  BEGIN, precede
               it by a semicolon.

               Note that a "}" (which  can not be TURNed ON  and OFF)
               switches to text processing from command processing at
               any time.   This allows  a Short Text  Line to  be put
                                          _____ ____  ____
               right into a command line:
.NOFILL }I am a short text line.{BREAK FILL

               which is the compact equivalent of:

.NOFILL
I am a short text line.
.FILL

               To  summarize,  there  are  two  ways  to  switch from
               command to text processing:



                                2.16

Page 24                   TEXT CONVENTIONS                  SAILON-70


>New line without "." in column 1
>}
               and two ways to switch from text processing to command
               processing:

>New line with "." in column 1
>{










































                                2.16
      

SAILON-70                        PUB                          Page 25


                              SECTION 3

                               MACROS




3.1 CALLING A MACRO FROM A COMMAND LINE
    _______ _ _____ ____ _ _______ ____

               It  is  common  to  repeat  an  identical  sequence of
               commands many times in a manuscript, e.g.,
.FILL ADJUST COMPACT TURN ON "{αβ"

               You could define the following macro:
.MACRO FAC  FILL ADJUST COMPACT TURN ON "{αβ" 

               and  then  whenever   you  want  the   whole  sequence
               executed, write simply:
.FAC

```````````````The``body of``the macro``enclosed between`` and`` is
               substituted  for  its  name and  then  scanned  by the
               command scanner.

               A macro may also have arguments:
.MACRO T(CHR)  NOFILL TURN ON "CHR" 

               which when called by:
.T(α)

               expands to:
. NOFILL TURN ON "α"



3.2 CALLING A MACRO FROM A TEXT LINE
    _______ _ _____ ____ _ ____ ____

               It is  also common  to repeat  an awkward  sequence of
               control characters many times in the manuscript, e.g.,
Xi&[j,k]

               You could define the following macro:
.MACRO XIJK "Xi&[j,k]"

               but to call it you must get to the command scanner:
{XIJK}

                              3.1 - 3.2

Page 26                        MACROS                       SAILON-70


               When  the  body  is  substituted  for  the  name, this
               becomes a string constant inside curly brackets:
{"Xi&[j,k]"}

               so it  is considered computed  text and is  scanned by
               the text scanner, producing the output:

 i
X
 j,k

               Again, parameters can be used:
.MACRO S(X,I,J,K) "Xi&[j,k]"

               If called by {X(i,j,k)} this would expand to  the same
               as above, but called by
{S(Y,t,t1,URG)}

```````````````it would expand to "Yt&[t1,URG]" which would output:
 t
Y
 t1,URG

               Some macros are  declared for you in  an automatically
               loaded  file  PUBSTD.DFS  (see  Section  7.5).   Other
               useful macros are  declared in a file  PUBMAC.DFS that
               you can REQUIRE (see Section 7.11) to be  loaded; they
               are described in PUBMAC.TES[UP,DOC].



3.3 TEMPLATES
    _________

               A  "template" occurs  as a  part of  several commands,
               including  the  macro declaration,  and  requires some
               explanation.  Its purpose is to store away a  piece of
               program for later, instead of immediate, execution.
        Syntax:
 <piece of program> 

               The <piece  of program>  may include  other templates,
               and may  span several  lines.  However,  several rules
               should be followed:

               (1) The  template should  begin and  end on  a command
               line.


                                 3.3

SAILON-70                      MACROS                         Page 27


```````````````(2) Every  or unpaired`` or  must be preceded``by a
```````````````.

               (3)  People  who  change  COMMAND  CHARACTER  in  mid-
               manuscript,  note:  the  character  beginning  command
               lines within the template  must be the one  current at
               the time  of declaration --  not the one  current when
               you invoke it later.



3.4 MACRO DECLARATION
    _____ ___________
        Syntax:
MACRO <name> [<formal parameters>] [;] <template>

               The <name> may be one or two identifiers.  The <formal
               parameters> if present, are in the following form:
(``[ε]<identifier>``, ...``)

```````````````Each parameter preceded by ε is a value parameter, and
                                                 _____
               when called, the actual parameter that  corresponds is
```````````````εvaluated``and``the``value``is``substituted``for``each
               occurrence in the <template> of the <id>.  Every other
               parameter  is  a  literal  parameter,  and  the actual
                                 _______
               parameter is substituted unevaluated.  Example:
.MACRO PLUG IN(X, εY)  "X --- Y" 

               If called by: {PLUG IN(Peter Pauper, V)} where V  is a
               variable whose current value is "Henrietta", the macro
               expands to: {"Peter Pauper --- Henrietta"}



3.5 MACRO CALLS
    _____ _____

               A macro can be called from anywhere in a  command line
               as well as  inside curly brackets  on a text  line.  A
               value  parameter  must  be  a  "SAIL"  expression (see
               Section 4.1), while  a literal parameter may  take any
               of three forms (form 2 is recommended):

          (1) A string enclosed in  "..." in which every "  inside is
                represented by "" . It must appear all on one line.

          (2) A string enclosed in  |...| in which no |  appears.  It
                may span several command lines.

                              3.4 - 3.5

Page 28                        MACROS                       SAILON-70


          (3) A string  not beginning with "  or | and  containing no
                comma or  right parenthesis.  It  must appear  all on
                one line.  Leading spaces are ignored.

               Thus, all the folowing are equivalent:

PLUG IN ("Peter Pauper", V)
PLUG IN (|Peter Pauper|, V)
PLUG IN ( Peter Pauper, V)
"Peter Pauper --- Henrietta"



3.6 OMISSIONS
    _________

               Any actual parameter may be omitted; its value is then
               NULL.  Furthermore, if  all parameters that  follow it
               are  also omitted,  all their  terminal commas  may be
               omitted.

               In a macro call --  but not in a macro  declaration --
               the parentheses around  the actual parameter  list may
               be omitted (both -- not just one).  However, care must
               be taken  if this is  done.  In particular,  the comma
               that follows  each parameter must  appear on  the same
               line  as  the  parameter.   Also,  the  third  form of
               literal  parameter   may  not   contain  any   of  the
               following:
,``)``]``;``}````CR

               This  convention  is  useful  for  macros  to generate
               section headings; a typical call is:
.SEC SPECIAL FEATURES

               which is equivalent to:
.SEC(|SPECIAL FEATURES|)

               and  would presumably  go to  a new  page,  update the
               section number, print  the heading centered,  and send
               it to the Table of Contents for inclusion  there.  How
               to do all this will unfold gradually.







                                 3.6

SAILON-70                      MACROS                         Page 29


3.7 RECURSIVE MACROS
    _________ ______

               If  a macro  is declared  "RECURSIVE MACRO  ...", then
               when  its  call  occurs   in  the  FALSE  part   of  a
               conditional,   the  compiler   processes   the  actual
               parameters  as usual,  but does  not expand  the macro
               body.  Instead, the whole call is replaced by NULL.

               For macros  not declared  RECURSIVE, their  bodies are
               expanded  even in  the  FALSE part  of  a conditional.
               This  prevents  syntactic anomalies,  but  attempts at
               recursion will create infinite looping.

               Recursive macro hackers: If you call a RECURSIVE macro
               after a conditional statement, an empty statement must
               intervene:
.IF A<0 THEN B ELSE C ; ; RECMAC(...) ;































                                 3.7

Page 30                          PUB                        SAILON-70


                              SECTION 4

                             EXPRESSIONS




4.1 DATA TYPE
    ____ ____

               PUB has only one data type: String.  A string consists
                                           ______
               of zero or more ASCII characters.

               Strings may participate in arithmetic operations.  The
               string "764" is automatically converted to the integer
               764 for this purpose.  The result of the  operation is
               similarly converted back to a string.  Because of this
               convention,  the  data  type  Integer  exists  for all
                                             _______
               practical purposes.



4.2 VARIABLES
    _________

               Variables may be declared by the command:
.VARIABLE A, BETA, C

               This would make A, BETA, and C local to  the innermost
               block   in  which   the  declaration   occurred.   The
               variables are of course type String.

               Any  variable that  is  assigned but  not  declared is
               automatically Global.
                             ______
               All declared  variables  are initialized to  NULL, the
               string of length zero.

               The name  of a variable  is an identifier.   The first
                                              __________
               character  of an  identifier  should be  a  letter The
               letter may be followed  by letters, digits, _,  and !.
               The identifier is  terminated by any  other character,
               including CR.  Before  looking up an identifer  in its
               symbol table,  PUB changes all  lower case  letters to
               upper case and changes _ to !.

               In syntactic  descriptions in  this manual,  <id> will


                              4.1 - 4.2

SAILON-70                    EXPRESSIONS                      Page 31


               denote any identifier, and <v> will denote  a variable
               in particular.



4.3 AUTOMATICALLY DECLARED VARIABLES
    _____________ ________ _________

               Some variables are  automatically declared for  you by
               the compiler, in a block outside your outermost block.
               A few of these are read-only -- it is not  possible to
               assign them a value by an assignment statement.

       CHAR        (read-only)  The  number  of  characters   so  far
               printed  on  the  current  output  line,  not counting
               justification   spaces.    This   is    sometimes   an
               overestimate.
       LINE        (read-only) Value  is zero  if the  current output
               column is empty.  Otherwise, the sequential  number of
               the last line output.
     COLUMN        (read-only) Value is  zero if the current  page is
               empty.  Otherwise  the sequential  number of  the last
               column in which output went.
      CHARS        (read-only)  The  number  of  character  positions
               remaining to be filled on the current output line.
      LINES        (read-only) The  number of unused  lines remaining
               in the current output column.
    COLUMNS        (read-only) The number of unused columns remaining
               in the current page.
    TOPLINE        (read-only)  The  line number  on  this  page that
               starts the current area.  (see Section 6.7).
    FILLING        (read-only) FALSE ("0") if in a NOFILL mode.  TRUE
               if in FILL mode -- "1" if ADJUST, "-1" if NOJUST.
       NULL        (read-only) The empty string ("").
       TRUE        (read-only) "-1"
      FALSE        (read-only) "0"
     SPREAD        The intra-paragraph output line spacing.  SPREAD=1

               is single  spacing, SPREAD=2  is double  spacing, etc.

               Its initial value  is 1 unless otherwise  specified in

               the (nS) CUSP option.
    INDENT1, INDENT2, INDENT3    Control  paragraph  indentation (see
               Section 6.4).
      LMARG, RMARG   The left and right margins (see Section 6.8).
       DATE        Today's  date,  in  the   form  October 16, 1848 .


                                 4.3

Page 32                      EXPRESSIONS                    SAILON-70


               Initialized from the system  DATE UUO just before your
               manuscript is  compiled.  Also  available individually
               are  MONTH, DAY,  and YEAR.   To fully  capitalize the
```````````````month or date, use the  operator described in Section
```````````````4.4 (e.g., MONTH).
       TIME        The  time  your  compilation  began,  in  the form
               16:47 .
       FILE        The first  name of  your manuscript  file.  Useful
               for headings.
       PAGE        The  current page  number, initially  NULL.  Don't
               declare this LOCAL!
     _SKIP_        (read-only)  May  be  set  by   extreme  substring
               operators  (see SAIL  manual, 9-43).   To  examine the
               left and right halves, examine _SKIPL_ and _SKIPR_.
    FOOTSEP        Before the first footnote (if any) in each column,
               a blank line is usually left. This is  because FOOTSEP
               is initially  NULL.  If you  assign it  another value,
               then that string will be printed instead.



4.4 SIMPLE EXPRESSIONS
    ______ ___________

               Most of the  SAIL <string expression> syntax  has been
               implemented.   Exceptions:  function  designators (but
               there are macro calls); exponentiation; LDB, ILDB, and
               LOP; shifts and masks; LEAP operators.

```````````````PUB``has``three``unary``operators``of``its ``own:``""
               capitalizes its argument (only lower case  letters and
               underbar are affected).   EVEN and ODD  are predicates
               which  tell  whether the  low  order bit  of  the last
               character of  a string  is off or  on.  They  are used
               primarily to distinguish left and right facing pages:
.IF ODD PAGE THEN etc.

               All the  available operators are  listed in  the table
               below.  If operator  op1 is listed above  operator op2
               then op1 is performed before op2.









                                 4.4

SAILON-70                    EXPRESSIONS                      Page 33


(        )
[        ]
+ -``````ABS ``````LENGTH````````(this + and - are unary)
*        DIV  /    MOD       &
+ ``-````EQV``````XOR```````````(this + and - are binary)
MAX      MIN
EVEN     ODD
>``<``=````LEQ``````GEQ```````NEQ
````````NOT
````````AND
````````OR

               The identifiers OR,  LEQ, etc. are not  reserved words
               except   in  context.    (The  same   holds   for  all
               identifiers in the language except command names.)

               Both  division operators  (/, DIV)  are  equivalent --
               they yield the truncated integer.

```````````````= and ``compare strings character-by-character;``<, >,
               etc. compare integers algebraically.

               If  neither   TO  nor  FOR   occurs  in   a  substring
               specification, FOR 1 is assumed.  Note that:

7654[] = 4
76 & 54 = 7654



4.5 GENERAL EXPRESSIONS
    _______ ___________

               Assignment expressions and conditional expressions are
               allowed.  If used alone to compute text,  enclose them
               in  parentheses,  otherwise  they  will  look  to  the
               compiler  like  assignment  statements  or conditional
                                           __________
               statements, and  the text  processor won't  scan their
               __________
               values.

               In syntactic descriptions,  <e> will denote  a general
               expression  --  simple,  assignment,  or  conditional,
               while <se> will denote a strictly simple expression.






                                 4.5

Page 34                      EXPRESSIONS                    SAILON-70


4.6 CONSTANTS
    _________

               PUB  recognizes  three  forms  of  constants:  quoted,
               decimal, and  octal.  WARNING:  CR will  terminate any
               form, so  don't continue  a quoted  constant on  a new
               line.

               A quoted constant  (<qc>) is a sequence  of characters
               surrounded by quotes  ("...").  To include a  quote in
               the represented string,  write two quotes ("")  in the
               constant.

               A  decimal constant  (<dc>) is  a sequence  of decimal
               digits.

               An octal constant (<oc>) is an apostrophe (') followed
               by a sequence of octal digits.  The value of the octal
               number is  taken modulo  200  and  converted to  a one
                                           8
               character ASCII string.  The following octal codes are
               illegal: '0, '11-'15, '175, '177.



























                                 4.6

SAILON-70                        PUB                          Page 35


                              SECTION 5

                             STATEMENTS




5.1 STATEMENT TYPES
    _________ _____

               Syntactically,   any  command   can  be   a  statement
               (abbreviated  <s>  in  this  manual).   There  are two
               categories of commands: declarative and imperative.  A
               declaration  is   limited  in   its  scope   by  block
               ___________
               structure, while an imperative isn't.
                                   __________


5.2 BLOCK
    _____
        Syntax:
BEGIN [<qc>] <s> ; ... END [<qc>]

               The optional block name  [<qc>] should be the  same in
               both  places.   Mismatches will  be  flagged.  Missing
               END's are calamitous to say the least!

               Note  that declarations  don't  have to  be  the first
               thing in the block.  The scope of a declaration is the
               remainder of the innermost block in which it occurs.

               Both BEGIN and  END cause a paragraph  break.  Neither
               produces output, not even a blank line.

               The semicolons  between statements  may be  omitted as
               long as no ambiguity is presented thereby.



5.3 COMPOUND STATEMENT or CLUMP
    ________ _________ __ _____
        Syntax:
START [<qc>] <s> ; ... END [<qc>]

               Declarations are  not local to  clumps, and  START and
               END never break.  Thus:
.IF TRUE THEN START FILL ; ADJUST END ;


                              5.1 - 5.3

Page 36                      STATEMENTS                     SAILON-70


               sets the  modes FILL  and ADJUST  and leaves  them set
               after END.  If BEGIN  had been used instead  of START,
               the scope  of the  modes would  have extended  only to
               END.



5.4 ONE PARAGRAPH SCOPE
    ___ _________ _____
        Syntax:
ONCE

               The command ONCE breaks and begins a local scope which
               is  implicitly  terminated  by  the  end  of  the next
               paragraph.  There must not be an END provided to match
                                      ___
               it.   If a  BEGIN  is encountered  before  a paragraph
               breaks, then everything that has been declared  in the
               ONCE's scope  is donated to  the scope of  the BEGIN's
               block and the ONCE is forgotten.  Examples:

.ONCE FLUSH RIGHT
George
               is equivalent to:

.BEGIN FLUSH RIGHT
George
.END
               and

.ONCE FILL
.BEGIN NOJUST
Harry
.END
               is equivalent to:

.BEGIN FILL NOJUST
Harry
.END

               You  will find  the ONCE  construct useful  in writing
               macros  and  in  formatting  odd  paragraphs  here and
               there.  Note that ONCE is a complete statement, unlike
               BEGIN, which  introduces a  statement that  extends to
               the matching END.  Thus,  you can say "IF X  THEN ONCE
```````````````ELSE ii+1" but``you can't say``"IF X THEN``BEGIN ELSE
```````````````ii+1".



                                 5.4

SAILON-70                        PUB                          Page 37


                              SECTION 6

                            DECLARATIONS




6.1 SCOPE
    _____

               (For the third time:) A declaration is in  force until
               the occurrence of  an overriding declaration  or until
               the end  of the innermost  block in which  it occurred
               (see Section 5.2 through Section 5.4).



6.2 MODE DECLARATIONS
    ____ ____________

               Most of these have already been described.   Some mode
               declarations  cause paragraph  breaks and  some don't.
               The ones that first Break are: FILL, all  the NOFILLs,
               ADJUST, NOJUST, GROUP, and APART.  The ones that don't
               are: CRBREAK, CRSPACE, COMPACT and  RETAIN.



6.3 TABS DECLARATION
    ____ ___________
        Syntax:
TABS <e>, ...

               The  expressions  are  sorted  in  algebraic ascending
               order  and  duplicates  are  eliminated.   These  then
               become the tab stops for the \ control  character.  If
               you tab when the  target is already passed,  no spaces
               are  inserted, but  justification to  the left  of the
               current  position  in  the  output  line  is inhibited
               anyway.   Tab  distances are  measured  from  the left
               margin.








                              6.1 - 6.3

Page 38                     DECLARATIONS                    SAILON-70


6.4 INDENT DECLARATION
    ______ ___________
        Syntax:
INDENT [<e>] [ ,<e>] [,<e>]

               This command can change the values of three parameters
               that control  paragraph format: INDENT1,  INDENT2, and
               INDENT3.   They  can  also  be  changed   directly  by
               assignment statements.  Every  change is local  to the
               current block.

                    INDENT1  and INDENT2  specify indentation
                         from the left margin.

                    INDENT1 specifies the value of  the crown
                                                        _____
                         indentation, which affects  only the
                         ___________
                         first line of output paragraphs.

                    INDENT2 specifies  the value of  the vest
                                                         ____
                         indentation, which affects non-first
                         ___________
                         lines in FILL mode.

                    In  NOFILL,  SUPERIMPOSE,   and  JUSTJUST
                         modes,  INDENT1  is   observed,  and
                         INDENT2 is  ignored.  Old  PUB users
                         note: this is a change from previous
                         conventions.

                    INDENT3  specifies  indentation  from the
                         right  margin in  FILL mode.   It is
                         ignored in NOFILL modes, and in text
                         affected  by the  control characters
`````````````````````````"", "", and "".

                    Lines  in VERBATIM,  FLUSH  LEFT, CENTER,
                         and  FLUSH  RIGHT  modes  are  never
                         indented.

                    If   any   argument   is   omitted,   the
                         corresponding    parameter   remains
                         unchanged.








                                 6.4

SAILON-70                   DECLARATIONS                      Page 39


6.5 PREFACE DECLARATION
    _______ ___________
        Syntax:
PREFACE <e>



               PREFACE  N will  cause  every output  paragraph  to be
               preceded by  an implicit SKIP  N.  There  are actually
               two Preface  numbers maintained --  one for  FILL mode
               and one for NOFILL modes.  The one you change  by this
               command depends on the current mode.



               Initially,  the  FILL  Preface  is  1  and  the NOFILL
               Preface is 0.

               You may want to vary the Prefaces according to SPREAD,
               e.g., PREFACE 1+SPREAD .



6.6 DOUBLE SPACING
    ______ _______
        Syntax:
SINGLE SPACE
DOUBLE SPACE
TRIPLE SPACE

               These are standard macros that set SPREAD to 1, 2, and
               3, respectively.  At the end of the current block, the
               old value  is restored.   SPREAD controls  the spacing
               between lines within a paragraph.



6.7 AREA DECLARATION
    ____ ___________
        Syntax:
[TEXT|TITLE] AREA <id> [LINE[s] <e> [TO <e>]] [CHAR[S] <e> [TO <e>]]
         [IN <e> COLUMNS <e> WIDE|APART]

               Each  page  is  divided  into  Areas  into  which  the
                                              _____
               compiler will place  output text.  The  areas HEADING,
               TEXT, and FOOTING are pre-declared for you as follows:
                                     ____________


                              6.5 - 6.7

Page 40                     DECLARATIONS                    SAILON-70


.AREA TEXT LINES 4 TO 51 ;
.TITLE AREA HEADING LINES 1 TO 3 ;
.TITLE AREA FOOTING LINE 53 ;

Each area  is a  rectangle that       begun.  In the case of  a TITLE
must lie within the  bounds set       AREA overf