|
OverviewPUB 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 manualTo 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 contemporariesPUB 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 PUBIn 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 |
TerminologyThe 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 remarkThe 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 |
TerminologyCore 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 necessaryThere 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 FOO←BAZ`````````````````BAZ.PUB````````FOO.DOC ___ _______ .COM /PUB FOO.OOF←BAZ.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 |
TerminologyREQUIRE was like include in C and other modern languages. RPG was like Unix's make. Tables in PUB vs. HTMLPUB 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 |
TerminologyTVEDIT (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).
|
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. RUNOFFInstead 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 conventionThe 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. RUNOFFRUNOFF 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. CSSIndent 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 charactersThe 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 |
TerminologyTerms I coined like crown, vest, and hem never caught on. Paragraph breaksRUNOFF and PUB: .break
HTML: <br>
FILL modeRUNOFF and PUB: .FILL
Lines of text up to a negating command such as: .NOFILL DHTML: <div style="text-align: left;">
Lines of text </div> JustificationRUNOFF: .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. HTMLWhite space interpretation differed significantly from HTML. NOFILL modeRUNOFF 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 modeRUNOFF: .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 modePUB: .SUPERIMPOSE 2
X ~ 7 X . - DHTML: <pre>
X ~ 7 <div style="position:relative; top:-1.2em;"> X . - </div> </pre> COMPACT and RETAIN modesThere 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. HTMLGrouping and many other features of PUB were concerned with pagination, a non-concept in HTML. Naming inconsistencies in PUBThe 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.
Elements and TagsLike 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 (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 LEFTTo 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 TABThe 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 CenterMicrosoft 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%">
|
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). ``````````∞x∞y∞z...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````````x↑j&↓i````y`````````↑_&y↓[i+j]&↑[ 2] i i+j 2 x````````x↓i↑2`````SUM```````↓[ t]&[SUM] i t i2 ∃````````↓x&∃``````x`````````x↑i↑2 x 2 . i t````````↑.&t``````x`````````x↑[i↑2] 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., X↑i&↓[j,k] You could define the following macro: .MACRO XIJK ⊂"X↑i&↓[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: {"X↑i&↓[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) ⊂"X↑i&↓[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 "Y↑t&↓[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 i←i+1" but``you can't say``"IF X THEN``BEGIN ELSE ```````````````i←i+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 |