up to date 

PUB Manual


Project Description

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 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>] ; ... 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>] ; ... 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 overflow, an error message by the last PAGE FRAME is issued. Statement (see Section 7.13). If the CHARS clause of the AREA An area has one column unless declaration should be omitted an IN..COLUMNS clause is (as it is in the predeclared included, e.g., areas), then the full width of the Page Frame is assumed. .AREA LISTING LINES 30 TO Similarly, if the LINES clause . 50 IN 2 COLUMNS 7 APART should be omitted, full page height is assumed. Either how WIDE each column is or how far APART they are can An area is assumed to be a TEXT be specified. AREA unless "TITLE AREA" is stated explicitly. The only Associated with each area are a difference between a TEXT AREA left and right margin, located and a TITLE AREA is the action initially at the left and right taken when so many lines are edges of each column. How they written in it that it can be moved inward and back overflows. In the case of a out is explained in Section TEXT AREA overflow, all areas 6.8. are "closed", the whole page is written out, and a new page is The bottom line of a TEXT AREA is not used except to print the last line of a paragraph. This convention prevents the appearance of "widows" at the top of a page. 6.8 MARGIN CONTROL ______ _______ Syntax: NARROW <se> [ ,<e>] <paragraphs and statements> WIDEN NARROW and WIDEN cause paragraph breaks. NARROW L,R moves the left and right margins of the current PLACE area inward L and R, respectively. Their initial positions are determined by the AREA declaration. L and R may be negative. If either is omitted, it is 6.8 SAILON-70 DECLARATIONS Page 41 assumed 0. The matching WIDEN restores the margins to their former positions. Alternatively, you can have: WIDEN <se> [ ,<e>] <paragraphs and statements> NARROW which moves the margins outward. Both kinds can nest. These commands change the automatically declared variables LMARG and RMARG (the Left and Right Margins). They can also be changed directly by assignment statements; such changes are local to the current block and to the current NARROW-WIDEN nest of the current PLACE area. Upon exit from a block, if the margin positions are different than they were at the beginning, then they are restored and instead of the usual Break, END causes a CONTINUE (See Section 7.15), which treats the next line as a vest instead of a crown line. Every paragraph is output in the following format: | ---------------------------------------- | | | | | | | | (P blank lines) | | | ← A-1 →| | | | | | |←- I1 -→The crown line of the paragraph.| | | | |←----- I2 ----→a vest line .............|← I3 →| | |← L →| another vest line .......| |← R →| | | the hem line. | | | | ---------------------------------------- | ↑ ↑ ↑ ↑ A Left-margin Right-margin B The format suggested by the diagram above may be achieved by the following declarations: .AREA TEXT CHARS A TO B ; .NARROW L, R ; .FILL ; PREFACE P ; INDENT I1, I2, I3 ; The automatically declared variable CHAR and all tab stops count characters from the left margin; they may at times be negative. It is possible to produce output past the right margin by setting tab stops out there. 6.8 Page 42 DECLARATIONS SAILON-70 6.9 PLACE DECLARATION _____ ___________ Syntax: PLACE <area id> This breaks and switches output to the named area. This may be done many times on the same page; output to each area always picks up where it left off. If a column of the current Place Area overflows, output continues at the top of the next column. When the last column overflows, either a new page is begun (if a TEXT AREA overflowed) or an error message is given (if a TITLE AREA overfowed). 6.10 TEMPORARY AREAS _________ _____ This section is complicated. Only read it if you need to create temporary areas within a page. To do this, you need to know where you're up to on the page so far. If there's not enough room for the new area, you will want to go to a new page. Then a temporary area (local to a block) should be declared, and text placed in it. Finally, you may need to find out where you're up to on the page again before you exit that block, skip over the temporary area, and resume regular output. A more convenient way to handle this may be available in a future version of PUB in the form of a BOX FRAME declaration. In the meantime, you should be able to get by as follows. To determine the top line on the whole page that the current PLACE area uses, look at TOPLINE. Within that area, lines are numbered starting from 1 -- but if TOPLINE is 6 that means "line 1" of the area is really the 6'th line on the page. We can distinguish P-lines (numbered relative to the whole page) from A-lines (numbered local to the area); A-line 1 might be P-line 6. To determine the column number and A-line number of the last line output in this area, look at COLUMN and 6.9 - 6.10 SAILON-70 DECLARATIONS Page 43 LINE. To determine how many empty columns remain in this area, look at COLUMNS; for how many empty lines remain in this column, look at LINES. Note that LINE+LINES can be less than the full height of the area, because a few lines at the bottom may be occupied by footnotes. To declare a two-column area 10 lines high for a table starting just below the last output line, write: .IF LINES < 10 THEN NEXT PAGE ; .BEGIN .AREA AXE LINES TOPLINE+LINE TO TOPLINE+LINE+9 IN 2 COLUMNS 5 APART .PLACE AXE

.END .GROUP SKIP 10 Adding TOPLINE in the AREA declaration is necessary because it expects P-line numbers. 6.11 COUNTER DECLARATION _______ ___________ Syntax: COUNT <id> [INLINE] [FROM <e>] [TO <e>] [BY <e>] [IN <counter id>] [PRINTING <e>|<template>] This is PUB's excuse for a FOR statement. The user can declare certain identifiers to be counters, and ________ arrange them in hierarchies. A counter is anything you want numbered sequentially. Typical counters are SECTION, APPENDIX, SUBSECTION, PAGE, FOOTNOTE, EQUATION, TABLE, FIGURE, NOTE, and REFERENCE. A common hierarchy is: SECTION / \ SUBSECTION PAGE | FOOTNOTE The declarations for this hierarchy might be: .COUNT SECTION FROM 1 TO 9 .COUNT SUBSECTION FROM 1 TO 99 IN SECTION .COUNT PAGE FROM 1 TO 99 IN SECTION .COUNT FOOTNOTE INLINE FROM 1 TO 9 IN PAGE 6.11 Page 44 DECLARATIONS SAILON-70 The "IN" clause specifies the hierarchial parent counter; it must have been previously declared. The range of each counter is specified by the FROM, TO, and BY clauses; if omitted, FROM 1, TO 18, and BY 1 are assumed. The counter need not ever attain the TO-value; it is just an upper limit used to determine the maximum number of characters needed to print the counter in case it is referred to in a Forward Cross- Reference (see Section 9.1). The INLINE option suppresses a BREAK which is otherwise automatically generated before each stepping of the counter. The PRINTING clause is explained in Section 7.3. 6.11 SAILON-70 PUB Page 45 SECTION 7 IMPERATIVES The commands in this section are non-declarative. That means that their scope is not limited by block structure. an occasional exception to this rule is the assignment statement; when the assigned variable is SPREAD, LMARG, RMARG, INDENT1, INDENT2, or INDENT3, then the change is local to the current block. 7.1 ASSIGNMENT STATEMENT __________ _________ Syntax: ← Example: .SPREAD ← T ← r - 4 ; Assignment statements don't break. 7.2 CONDITIONAL STATEMENT ___________ _________ Syntax: IF <e> THEN ELSE Example: .IF ODD PAGE OR LINES < 10 THEN START this text line .END ELSE START that text line .END "IF", "THEN", and "ELSE" don't break. 7.3 NEXT COUNTER VALUE STATEMENT ____ _______ _____ _________ Syntax: NEXT <counter id> 7.1 - 7.3 Page 46 IMPERATIVES SAILON-70 This breaks (unless INLINE appeared in the designated counter's COUNT declaration), and the counter is stepped to its next value. The first time it is called, the counter's value is initialized. Every COUNT declaration automatically declares two variables with special properties, and initializes them to NULL. The first variable has the same name as the <counter id>, e.g., "SUBSECTION", and its value is always the decimal integer value of the counter. The other variable's name is constructed by appending an "!" to the <counter id>, e.g., "SUBSECTION!". The two variables are called the counting or "C-value" and the printing or "P-value", respectively. The precise effect of the statement "NEXT U" in terms of these variables is as follows. (1) If U=NULL, then U is set to the FROM value of the COUNT declaration; otherwise, U is incremented by the BY value of the COUNT declaration. (2) The P-value is computed under control of the PRINTING clause of the COUNT declaration (just how will be explained shortly). In addition, the P-value is assigned to the variable "!" as a convenient abbreviation. (3) If the counter has hierarchically subordinate counters, all their C-values and P-values are set to NULL; thus, when you say NEXT SECTION, SECTION becomes a new number while SUBSECTION, PAGE, and FOOTNOTE become NULL (assuming the hierarchy of the recent example). Exception: If "PAGE" was one of the subordinate counters, after it is cleared it is immediately initialized. The computation of the P-value depends on the PRINTING clause of the COUNT declaration. There are three cases. Case One The PRINTING clause is omitted. P-value is the same as the ____ ___ C-value. Case Two PRINTING <template>. After each C-value is computed, the ____ ___ expression inside the template is evaluated, and the result is the P-value. Thus, the template should contain an expression which involves the C-value. Examples: 7.3 SAILON-70 IMPERATIVES Page 47 .COUNT FOOTNOTE TO 9 IN PAGE PRINTING ⊂"*********"[1 TO FOOTNOTE]⊃ ; When FOOTNOTE=1, this sets FOOTNOTE!=*; when FOOTNOTE=5, this sets FOOTNOTE!=*****. .COUNT SUBSECTION IN SECTION PRINTING ⊂SECTION! & "." & SUBSECTION⊃ ; When SECTION!=4 and SUBSECTION is counted to 7, SUBSECTION! becomes 4.7 . Case ThreePRINTING <e>. The expression is evaluated only once, at ____ _____ declaration time, and its value serves as a pattern for conversion of the C-value to the P-value. For example, the pattern "(i)" will produce P-values such as (iv) and (xlii), and the pattern "!-A" will produce P-values such as 6-A and 33-L. The pattern should evaluate to a string of the form: <prefix> [ ! <middle> ] <format> <suffix> where <prefix>, <middle>, and <suffix> may be empty, and <format> must be 1, a, A, i, or I. This is roughly equivalent to the template: ⊂& ! && CONVERT(,) &⊃ Here's what happens. The P-value becomes this pattern after substituting the parent counter's P-value for "!" (if present) and after converting the C-value to the specified format and substituting it for <format>. Before explaining formats, let's give a simple example: .COUNT SUBSECTION IN SECTION PRINTING "!.1" ; Here, <prefix> and <suffix> are empty and <middle> is ".". Format "1" is no-conversion, so the C-value is substituted unchanged for the "1". The P-value of SECTION is substituted for the "!". Say SECTION! is 6 and SUBSECTION is stepped to 4; then SUBSECTION! becomes 6.4 . The various <format> conversions are: 1 No conversion I Upper case Roman, i.e., 59 → LIX i Lower case Roman A Capital letters A,...Z,AA,BB,...ZZ,AAA,... a Little letters 7.4 NEXT PAGE STATEMENT ____ ____ _________ This variety of Next Statement has special properties. Before stepping the PAGE counter, it "closes" and 7.4 Page 48 IMPERATIVES SAILON-70 outputs all the areas on the current page and sets up a fresh page frame. Conversely, when a page is closed due to text area overflow or "SKIP TO COLUMN 1", etc., the page counter is automatically stepped before the new page is opened, as if the command NEXT PAGE had been given. 7.5 HEADINGS AND FOOTINGS ________ ___ ________ As soon as the first line is ready to be placed in a page, the page is "opened". There are fancy ways you can create fancy headings and footings at that or at other times (see Section 10.2). For simple cases, the following command (which is actually a call to a built-in macro) is provided. Syntax: .EVEN|ODD|EVERY HEADING|FOOTING ( <text>, <text>, <text> ) On left-facing (EVEN), on right-facing (ODD), or on all pages (EVERY); on the top line (HEADING) or the bottom line (FOOTING); the three <text>s will be printed at the left edge, the center, and the right edge of the page, respectively. A <text> may not contain quote ("). Example: .ODD HEADING({DATE}, MACHINES THAT WONDER, {SUBSECTION!}) This would cause to print on the top line of every right-facing page something like: July 14, 1789 MACHINES THAT WONDER VII.iii 7.6 SECTIONING __________ The correct way to start every new section on a new page is: .NEXT PAGE ; NEXT SECTION ; If the order of these were reversed and if SECTION were the parent of PAGE, then NEXT SECTION would change PAGE's value before the old page got written out. 7.5 - 7.6 SAILON-70 IMPERATIVES Page 49 7.7 COMMAND CHARACTER STATEMENT _______ _________ _________ Syntax: COMMAND CHARACTER <qc>|<v> ; The parameter must evaluate to a single character string. That character subsequently assumes the function of dot in column 1. Since this command is not a declaration, its scope is global; i.e, it is not affected by block nesting. Don't omit the semicolon! 7.8 PORTION DEMARCATION _______ ___________ Syntax: PORTION <id> The manuscript may be (ought to be) divided into Portions, such as TITLEPAGE, CONTENTS, THESIS, ________ APPENDICES, NOTES, INDEX, and BIBLIOGRAPHY. Precede each portion by a Portion Demarcation, e.g., .PORTION NOTES The compiler will assure that each portion starts on a fresh page and ends with a paragraph break. In general, the order of appearance of the portions in the manuscript becomes their order of appearance in the document. However, this is not always convenient. For example, the entries for PORTION CONTENTS are usually generated during the processing of the other portions (see Section 7.9); therefore, PORTION _______ CONTENTS must appear at the end of the manuscript. To ________ ____ ______ __ ___ ___ __ ___ __________ show where you would like its output to be inserted in the document, use the statement: .INSERT <id>, ... which is sort of a "forward portion demarcation". Example: 7.7 - 7.8 Page 50 IMPERATIVES SAILON-70 .PORTION TITLEPAGE ... .INSERT CONTENTS . COMMENT This is where the table of contents should be printed; .PORTION THESIS .COUNT PAGE ; COMMENT Before NEXT SECTION starts a new page; .NEXT SECTION ... .PORTION INDEX ... .COUNT PAGE PRINTING "i"; COMMENT Before PORTION starts new page; .PORTION CONTENTS . COMMENT This is where the table of contents is defined ; ... 7.9 SEND STATEMENT ____ _________ Syntax: SEND <portion id> [;] <template> With every portion is associated a file called its generated file. A generated file is in manuscript _________ ____ __________ format. The idea is that you can avoid manual preparation of certain portions of your manuscript (such as the table of contents and the index) by making PUB prepare them mechanically. The generated file of a portion may remain empty, or may be written on during the processing of portions that appear earlier in the manuscript. For example, the generated files for PORTION CONTENTS and PORTION INDEX are usually generated during the processing of earlier portions. The SEND statement writes a template onto the end of the generated file for the named portion. The portion must appear later in the manuscript. Before sending the template, the compiler substitutes for every occurrence of: { <v> } the (unquoted) value of the variable <v>. Thus, if S=6 and PAGE=26, then the statement: 7.9 SAILON-70 IMPERATIVES Page 51 .SEND CONTENTS ⊂ Section {S} -- Findings ∞.→ {PAGE} ⊃ ; would send the following data to the file associated with PORTION CONTENTS (CRLF shown here for clarity): <CRLF> Section 6 -- Findings ∞.→ 26 . If a similar SEND were performed at the beginning of every section and subsection of the manuscript, then by the time the compiler reached PORTION CONTENTS, its generated file would be in perfect manuscript format, e.g.: Section 1 -- Introduction ∞.→ 1 . Section 2 -- Remarks ∞.→ 6 . (etcetera) Section 6 -- Extraneous Factors ∞.→ 26 . (etcetera) Section 413 -- Conclusions ∞.→ 864 . The empty command lines are of course harmless; their inclusion was caused by the method of conforming with one of the rules of writing templates: a template must end on a command line. Of course, a template alternatively could end with a text line terminated by "{". The subtleties of generated files are discussed in the Appendices to this manual. If you would rather postpone becoming an expert on the technique, you can still obtain a table of contents and index by the use of someone else's macros. These macros (STANDARD FRONT and STANDARD BACK) are stored in file PUBMAC.DFS[1,3] and described in file PUBMAC.TES[UP,DOC]. 7.9 Page 52 IMPERATIVES SAILON-70 7.10 RECEIVE STATEMENT _______ _________ Syntax: RECEIVE [<qc>|<v>] This statement substitutes the generated file of the current portion for the statement and causes the compiler to compile it. Thus, PORTION CONTENTS typically consists of a few mode setting commands, a title, and then the statement "RECEIVE". If the optional parameter is present, it should evaluate to a string of one or two characters, say "L" or "LR". The presence of the parameter causes the generated file to be alphabetized before it is compiled. Entries in the file should be in the form: <0 or more characters> L <Key> [R <0 or more characters>] PUB will alphabetize the entries by the <Key>s using the ASCII collating sequence, except lower case letters and "_" are ranked with the corresponding upper case letters and "!". Then it will read the alphabetized file, including the L and R characters. WARNING: The characters L and R must be chosen carefully. They may not occur in the generated file in any role except as key delimiters. Furthermore, the characters "[", "]", "@" may not be used. It is legal for L and R to be the same character. If your index is very large, PUB may exhaust SAIL string space trying to alphabetize it. The error message "STRING SPACE EXHAUSTED" will be typed out. Unfortunately, the only way to get more string space is to REEenter the program and go through the ALLOC ritual (see SAIL manual 14-22). The original allocation is presently 4000 words; try 7000 or 10000. To generate a simple index, use SEND statements such as: .SEND INDEX ; ⊂ βKeyword ∞.→ {PAGE} ⊃ ; and the RECEIVE statement: .RECEIVE "β∞" 7.10 SAILON-70 IMPERATIVES Page 53 The file generated will be quite funny-looking, but will result in the document: ... Keyshmurd ......................... 9 Keyword .......................... 15 ... Rather than all those hideous dots, it is suggested that the number immediately follow or precede the word. To learn how to create two-level and KWIC indexes, see Appendix A.3. 7.11 REQUIRE STATEMENT _______ _________ Syntax: REQUIRE <qc>|<v> SOURCE_FILE The parameter must evaluate to a file name, e.g., "BRAIN.BAZ[H,AHA]". The file must be in manuscript format. It will be substituted for the REQUIRE statement and compiled. If the last line of the file is a text line, PUB will still be scanning for text when it resumes the original file, so don't put a semicolon after the REQUIRE statement -- put a CR. REQUIREd files may REQUIRE other files. You will run out of channels if the number of open SOURCE_FILEs, generated files (extension ".PUG") and pass one output files (extension ".PUI") exceeds 15. 7.12 SKIP STATEMENTS ____ __________ Syntax: [GROUP] SKIP [<se>] SKIP TO LINE <e> SKIP TO COLUMN <e> 7.11 - 7.12 Page 54 IMPERATIVES SAILON-70 SKIP N breaks and leaves N blank lines in the document. If N is omitted, SKIP 1 is assumed. Note that N must be a simple expression -- no assignment or conditional expression is allowed unless it is parenthesized. Blank lines that would appear at the top of any column are automatically suppressed; if you want to force them to appear (say, to leave space for a drawing), use GROUP SKIP. If you are going to run off the same document with different values of SPREAD (i.e., sometimes single space and sometimes double space), you should write all your KIP statements with this factor taken into account, e.g., SKIP 2*SPREAD-1 . SKIP TO LINE N outputs blank lines up to but not including the N'th line (A-line) in the current column of output text, unless the N'th line has already been passed, in which case it goes to the N'th line in the next column. The most common use of this statement is SKIP TO LINE 1, which assures you are at the top of a clean column. SKIP TO COLUMN N outputs blank lines until it reaches the top of the N'th column of this or the next page. If the compiler is already at the top of the N'th column, this statement does nothing. The most common use is SKIP TO COLUMN 1, which goes to a new page unless a new page has just been begun. (To go to a new page regardless, use "NEXT PAGE" -- See Section 7.3). 7.12 SAILON-70 IMPERATIVES Page 55 7.13 PAGE FRAME STATEMENT ____ _____ _________ Syntax: PAGE FRAME <e> HIGH <e> WIDE This statement causes a break, goes to a new page, and sets up its size as specified (number of lines, number of characters). No output can appear outside the bounds set by this statement. Area declarations normally follow it. 7.14 BREAK STATEMENT _____ _________ Syntax: BREAK If a paragraph has been started, BREAK terminates it. Breaks are implicitly caused by many other commands and conditions. 7.15 CONTINUE STATEMENT ________ _________ Syntax: CONTINUE Sometimes you would like to insert an indented quotation or equation in the middle of a paragraph of prose. After the quotation, a paragraph break is necessary to terminate it. Unfortunately, the break also causes the next output line to be treated as a crown line (in FILL mode). If you would rather continue the interrupted paragraph than start a new one, use the command CONTINUE. It breaks, but causes the next paragraph to have no crown, as long as no regular breaks intervene. 7.16 DEVICE STATEMENT ______ _________ Syntax: DEVICE LPT|MIC|TTY 7.13 - 7.16 Page 56 IMPERATIVES SAILON-70 This statement is equivalent to setting the /L, /M, or /T switch when starting up PUB. It has no effect on Pass One output. However, Pass Two reacts to the switch setting as follows. DEVICE MIC makes the document file be in FR-80 command format. Pass Two will output two temporary files with extension ".RPG" and automatically run a program called "TXTF80", written by Russ Taylor, which generates the document file. Simply copy this file to a tape and bring it to the FR-80 operator at Lockheed. DEVICE LPT and DEVICE TTY produce identical output unless the page frame is higher than 53 lines. In that case, DEVICE LPT uses strange control characters instead of line feeds to inhibit page-ejection. DEVICE TTY assures that only line feeds are issued. Files produced under DEVICE TTY can be edited with TECO. Hardly any document file can be edited with SOS or TVEDIT, which don't like CR's without LF's (used for underlining and superimposing). 7.17 UNIMPLEMENTED STATEMENTS _____________ __________ The following commands have not been implemented, but ought to be, so their names are reserved words: CASE statement -- SAIL-style ALIGN statement -- it would align output to side-by-side areas PACK statement -- it would align the bottoms of parallel columns BOX FRAME STATEMENT -- to insert a table in a corner of the page LOCK statement -- to protect lines from being moved by a BOX FRAME SHOW statement -- to output to the console during compilation NOPRINT mode -- would suppress output PRINT mode -- would renew output LDX output will soon be available. This will require a few new commands and automatically declared variables, probably the following: 7.17 Glossary The LDX was Long Distance Xerography, a xerographic facsimile system. The print end was turned into a computer peripheral called the Xerox Graphics Printer (XGP). At the time this manual was written, we knew the machine was coming but did not know its new name. SAILON-70 IMPERATIVES Page 57 DEVICE LDX FONT <font-name> ON <file-name> -- would declare a font RASTER <e> UNITS PER INCH -- to specify raster density BELOW,ABOVE,ONLEFT,ONRIGHT -- like LINES,LINE,CHAR,CHARS CHARACTER <name> <font-name> <coordinates> -- define character 7.17 Page 58 PUB SAILON-70 SECTION 8 COMMENTS There are two ways to get comments into a command line -- not in the middle of an identifier or constant, however. Syntax: COMMENT anything but semicolon ; This one is probably familiar. The other one is: << anything but two greater-than-signs in a row >> Comments may extend over several command lines. If you leave out the terminator, you'll lose everything up to the next text line. Comments have no effect on the document. Why would you want them? Maybe you could write English comments on a French manuscript to help you find your way around. Or maybe you've got complicated macros that need explanation. Or you left out a bunch of text and want to leave a reminder in the manuscript. Don't ask me why -- I just implemented them. To get a comment into a text line, use curly brackets around a regular comment {<< Like this >>}. Continuation lines must be command lines. SAILON-70 PUB Page 59 SECTION 9 LABELS AND CROSS-REFERENCES 9.1 CROSS-REFERENCES ________________ A cross-reference is like computed text in that it causes characters to be processed by the text scanner, and in that it normally appears between curly brackets in the midst of a text line. First there will be an example, and then an explanation. ... invented by Owsley (See {"Page!" PURE}) ... This might produce output such as: ... invented by Owsley (See Page 3-7) ... The identifier PURE is called a label and must be _____ defined once and only once in the manuscript, either before or after the cross-reference. Every label has a value, much like a variable, but the value is assigned only once, at the place the label is defined. Several cross-reference statements may reference the same label. Labels willbe explained further in Section 9.2. There is a major problem in handling forward- references in a text-justifier. The justifier must know how many characters there will be in the value before it can decide where to break off the output line and how many spaces to insert during justification. PUB solves this problem by two slightly awkward hacks. One hack is that you must state or imply an upper limit on the number of characters, so it can leave enough room for it and not break off the line too soon. The other hack is that PUB has two passes. In the second pass, the actual values are substituted, and only then are lines justified. To "state or imply" the upper limit, you have a choice of three forms of cross-reference. Form 1: [ <e> ] <label id> _ _ 9.1 Page 60 LABELS AND CROSS-REFERENCES SAILON-70 Those are really square brackets!!!! Write them in the manuscript, really! The expression evaluates to a number which is the maximum number of characters, and the value printed is the value of the label <label id>. If this is a backward reference (unless to the current page), the number is ignored, so you can say just: {[] <label id>}. You can't just say the label name. Form 2: <counter id>[!] <label id> Those square brackets mean the "!" is optional -- don't write them in the manuscript! This form means that the value of the label will be the C-value (if there is no "!") or P-value (if there is an "!") of the counter <counter id>. PUB can compute the upper limit at declaration time by looking at the TO clause of the counter's COUNT declaration and at the PRINTING clause, so you don't have to state it. In case the PRINTING clause used a template, the upper limit is determined by a not quite foolproof heuristic: suitably large numbers are substituted temporarily for the C-value of the counter, for both values of its parent, and for !, and the expression is evaluated. Form 3: "<counter id>[!]" <label id> This is identical to form 2, except before sending the value of the label to the text scanner, it sends the string (without the "!") and a space. Thus, the following are exactly equivalent: ... See Section {Section! X} ... ... See {"Section!" X} ... The macro used for cross-references in this manual was: .MACRO YON(LBL) ⊂ "Section " ; SUBSECTION! LBL ⊃ which was called like this: ...lots of useless words (See {yon someplace}). Lots more ...... 9.2 LABELS ______ The syntax of <label definition> and <label definer> are defined (::=) as: Syntax: 9.2 SAILON-70 LABELS AND CROSS-REFERENCES Page 61 <label definition> ::= <label id> : <label definer> <label definer> ::= [NEXT] <counter id>[!] | <e> | <text line> Here is an example of each kind of <label definer>: .INTRO: NEXT SECTION .LAPLACE: IF ODD PAGE THEN PAGE ELSE PAGE+1 .EXPLANATION: This is the line that is labelled by the label "EXPLANATION". The first kind of definer makes the value of the label be the current C-value (if there is no "!") or P-value (if there is an "!") of the named counter. If NEXT is present, the counter is stepped before the assignment is made. The second kind makes the value of the label be the value of the expression. The third kind makes it be the value of PAGE! for the page that the <text line> begins on. The first and third kinds of definer both cause a consistency check between all forward-references to this label that mention a counter name and the counter named here. The second kind does not cause a consistency check. CAUTION: There is no consistency check on backward-references. There is no check when a cross-reference specifies a P-value (or C-value) that the label definition also specifies a P-value (or C-value). So if the output is incorrect, check for such inconsistencies yourself. A label must always be on a command line, or inside curly brackets on a text line. If the /D switch was used to obtain debugging information, then the label will be printed on the right side of the document. There is a slight ambiguity if your <label definer> involves PAGE (or PAGE!). If you use the first or third kind of definer, the evaluation is deferred until the next text line is output, i.e., until the next paragraph break or overflowed FILL line. Thus, you may think of a PAGE label as labelling the following text line; even if a new page is begun before that line is output, the label value will be the page on which that line appears. On the other hand, if you use the second kind of definer (i.e., an 9.2 Page 62 LABELS AND CROSS-REFERENCES SAILON-70 expression involving PAGE or PAGE!), the value used will be the current one at the time of evaluation -- even if the following text line doesn't get output until the next page. Note that L:NEXT PAGE will go to a new page and then assign L a value when the first line is output to that page. If the page is blank, the assignment is deferred another page. All this kludgery is to insure that if you say: See {"Page" X} there will really be something to see! Be sure to position the label just before the text line you want them to see. ______ 9.2 SAILON-70 PUB Page 63 SECTION 10 RESPONSES 10.1 TEXT RESPONSES ____ _________ A Text Response enables you to detect certain conditions in the text, and to call macro-like subroutines without using {...}. Presently, four conditions can be responded to: (1) Page Mark or Form Feed (2) Blank Text Line (3) Indented Text Line (4) Presence of a one-to-five character signal Syntax: AT <condition> [;] <template> When the condition is detected, the characters causing it are replaced by: { <template> } which is immediately executed. To dis-declare a response exit the block in which it was declared, or use a null template: AT [;] ⊂⊃ The various <condition>s available are as follows: AT PAGEMARK responds to an SOS page mark or a TECO __ ________ <CR LF FF>. A typical use is: .AT PAGEMARK ⊂SKIP TO COLUMN 1⊃ AT NULL responds to a blank text line. There is a __ ____ predeclared response for this: .AT NULL ⊂IF FILLING THEN BREAK ELSE SKIP 1⊃ This is the only reason that blank lines break in FILL mode. You can redeclare it to treat them otherwise. If you want them ignored, write: .AT NULL ⊂IF NOT FILLING THEN SKIP 1⊃ 10.1 Page 64 RESPONSES SAILON-70 AT N, where N is a positive integer N, responds to __ _ each text line indented exactly N spaces. For example, the standard macro TABBREAK declares: .AT 8 ⊂IF FILLING THEN BREAK ELSE " "⊃ AT S, where S is a string beginning with a non- __ _ alphanumeric character, responds to the occurrence of that string (up to 5 characters long) appearing uninterrupted in a text line. This one <condition> can be followed by a formal parameter list of up to five arguments, e.g.: .AT "%%" A "$" B "%" C "$" ⊂ SEND INDEX ⊂ }A B-C{BREAK ⊃ ⊃ Each parameter name is followed by a string containing a single character called its delimiter. When the _________ signal (in the example, %%) is spotted in a text line, the compiler continues to scan for actual parameters, terminating each scan at the appropriate delimiter. An actual parameter may span several text lines, but each carriage-return is converted to a space if this happens. No parameters may be omitted. None are evaluated -- they are all literal. 10.2 TRANSITION RESPONSES __________ _________ A transition response permits the specification of an action to be taken at the beginning or end of any counter or at the opening or closing of any area. Syntax: BEFORE|AFTER <counter id>|<area id> [;] <template> Here is how this response fits into the NEXT <counter> algorithm. To execute NEXT SECTION, PUB performs six steps: 1) If SECTION≠ NULL then do AFTER SECTION response (if any) 2) Step SECTION using FROM and BY values 3) Compute SECTION! using PRINTING clause, and assign it to ! 4) Do BEFORE SECTION response (if any) 5) For each sub-counter of SECTION, and each of their sub-counters: a) If C-value≠ NULL: AFTER sub-counter response (if any) b) Clear sub-counter C-value and P-value to NULL c) If it is PAGE, initialize PAGE and PAGE! 6) Re-assign SECTION! to ! (steps 4 and 5 may have changed it) 10.2 SAILON-70 RESPONSES Page 65 The END of the block in which any counter is declared (except PAGE) also causes Step 1 to occur. The most useful transition responses are BEFORE PAGE and AFTER PAGE. The BEFORE PAGE template is executed not immediately after NEXT PAGE is executed, but a little later, when the first line of output is ready to be put on the new page. BEFORE <area id> responses are similarly deferred until the first output is ready for the named area. The AFTER PAGE template is executed just before the page is written out -- it had better not place into a text area that is already full! One transition response is pre-declared for you: BEFORE PAGE ⊂ STANDARD TITLES ⊃ STANDARD TITLES is a pre-declared macro that prints the headings and footings set up by EVERY HEADING and its friends. You can of course redeclare this response. Every transition response template is automatically a block. It is surrounded by BEGIN !?@3 ... END !?@3 or something of that sort (which you will occasionally spot in error messages). It is usually necessary to declare all the mode settings and formats you want to be in force inside the <template>. Consider the case of BEFORE PAGE. At the time that a page happens to overflow, it is entirely possible that the compiler is in the midst of a FILL block with INDENT 10,20, all control characters off, and the NOFILL PREFACE set to 2. However, the headings and footings should be processed in NOFILL mode with preface 0, no indentation, and several control characters activated. You might declare: .BEFORE PAGE ⊂ NOFILL ; INDENT 0 ; PREFACE 0 ; TURN ON "{←→" .PLACE HEADING {DATE}←AUTOMATIC VETERINARIAN→{SECTION!} ←{SUBTITLE!} .PLACE FOOTING {IF ODD PAGE THEN "→"}{PAGE!} ⊃ 10.2 Page 66 PUB SAILON-70 SECTION 11 FOOTNOTES Every column of every area has two portions, the calf ____ and the foot. During preparation of the calf, ____ paragraphs can be sent to the foot. A column is considered full when the sum of the lines in the calf and the foot exceeds the height of the area. You can not declare Portion FOOT nor do a RECEIVE for it. The compiler automatically declares a FOOT for each area you declare, and does a RECEIVE for it after each line is placed in the calf. Your only foothold is the command "SEND FOOT". Example: .COUNT FOOTNOTE INLINE IN PAGE PRINTING "(i)" .AT "$$" ENTRY "*" ⊂ NEXT FOOTNOTE ; ! ; .SEND FOOT ⊂ TURN ON "{" PREFACE 1 SPREAD←1 INDENT 0,0 {!} ENTRY .BREAK ⊃ ⊃ * An example of the use of the "$$" signal response is: ...have been shown $$Abelwitz has obtained similar results in his experiments with hippopotami.*. which will print in the calf: ...have been shown (iv). and in the foot: (iv) Abelwitz has obtained similar results in his experiments with hippopotami. There is an implicit BEGIN FILL ; ... END around footnotes. - - - - - - - - - - - - - - - - - - - - - - - - - *) Thanks are due to Profs. G.I. Wish and O.U. Kidd of Steady State University for this example. Page 68 PUB SAILON-70 APPENDIX A THOROUGHLY EXPLAINED EXAMPLES A.1 SECTIONING MACROS __________ ______ At the beginning of each section, it is customary to perform the following ritual: <<1>> Begin a fresh page <<2>> Count up the section number <<3>> Print the section number and name <<4>> Skip a few lines <<5>> Send the section number, name, and page number to the CONTENTS See the document PUBMAC.TES[UP,DOC] for a description of the macros STANDARD FRONT and STANDARD BACK, which do all these things for you. If you want to define your own macros, read on. A macro to perform all the steps listed above <<commented for reference>> is: .MACRO SEC(NAME) .<<1>> NEXT PAGE .<<2>> NEXT SECTION .<<3>> ONCE CENTER ↓_SECTION {!}_↓ -- ↓_NAME_↓ .<<4>> SKIP 3 .<<5>> SEND CONTENTS ⊂ {!}\\NAME→{PAGE!}{⊃⊃ A sample call on this macro is: .SEC SPECIAL FEATURES At the beginning of each subsection, a similar macro can be called. The one below prints the subsection name on a line by itself but prints the subsection number at the beginning of the first line of the first paragraph of the subsection. It makes sure that there are enough lines for all this to be contiguous; if not, it first goes to a new page. Finally, it allows the macro call to specify a label to be used in cross- references to this subsection. A.1 SAILON-70 THOROUGHLY EXPLAINED EXAMPLES Page 69 .MACRO SS(NAME, LABEL) ⊂ .IF LINES < 10 THEN NEXT PAGE .SKIP 2 .LABEL NEXT SUBSECTION .ONCE NOFILL NAME .SEND CONTENTS ⊂ \{!}\\NAME→{PAGE!}{⊃⊃ {SUBSECTION!}. {⊃ The second argument is optional. If present, it must include a colon at the end: .SS MISCELLANEOUS FEATURES,MISC: which would define the label MISC and output something like this: MISCELLANEOUS FEATURES 33-7. This is the first line of the paragraph that follows. A.2 SAMPLE TABLE OF CONTENTS ______ _____ __ ________ The following CONTENTS portion expects a file generated by the SENDs in the SEC and SS macros shown above. .PORTION CONTENTS .NOFILL .TABS 12, 20, 30 .SKIP 2 .RECEIVE and might output: A.2 Page 70 THOROUGHLY EXPLAINED EXAMPLES SAILON-70 SECTION Subsection PAGE _______ __________ ____ 1 INTRODUCTION 3 1-1 PURPOSE 3 1-2 APPROACH 3 2 BACKGROUND 11 2-1 HISTORY 11 2-2 SIMILAR WORK 13 2-3 STATE-OF-THE-ART 19 Notice that nearly all formatting is accomplished in the SEND template. Long titles will not be handled by the portion declared above. Instead, FILL mode must be used. The following declarations are approximately what was used to produce the table of contents of this manual. .PORTION CONTENTS .FILL CRBREAK NOJUST .INDENT 0, 35, 10 .TABS 10, 15, 25 .SKIP 2 .RECEIVE A.3 ONE-LEVEL INDEXES _________ _______ There is presently no way to have a phrase indexed automatically every time it occurs. PUB now requires that you mark each phrase to be indexed at every occurrence that you wish to be referenced. The AT <signal characters> response is particularly useful for this purpose. Choose a character or a pair of characters that will never appear in the text of your manuscript; for example "%<". This will be your signal that the next phrase is to be indexed. Then choose a character that will never appear in such a phrase; for example, ">". This will be your end-of-phrase delimiter. Suppose you would like the phrase "Simple variables" to be indexed. Find each occurrence of this phrase in your manuscript and surround it by your chosen characters: Nothing warms the heart like %<simple variables>. We A.3 SAILON-70 THOROUGHLY EXPLAINED EXAMPLES Page 71 Your favorite text editor may be of some help in this task; however, watch out for a phrase that is broken across two lines: the editor will miss it if your search string is too stringent. Suppose you would like your index to look something like this: signed constants 8.0 significant digits 10.3, 10.7 signs 2.4, 3.7 simple variables 8.1, 20.8, 20.11 Now you need to declare a signal response (see Section 10.1) at the beginning of your manuscript: .AT "%<" PHRASE ">" ⊂ }PHRASE{ .SEND INDEX ⊂ }∧{PAGE!}∨{⊃⊃ This will respond to each occurrence in the text of the signal "%<". The characters that follow this signal, up to but not including the next ">", will be substituted in the body of the template for every occurrence of the word PHRASE. Then the body of the template will be surrounded by "{...}" and embedded in the text, replacing all characters from and including "%<" to and including ">". The effect in the example above would be: Nothing warms the heart like {}simple variables{} .SEND INDEX ⊂ }∧{PAGE!}∨{⊃. We SEND causes the current PAGE! to be substituted in the SEND template. Thus, the characters sent to the generated file will be: }∧2.6∨{ In the generated file, each index entry is signalled by the character pair "∧<, followed by the phrase, followed by ">", followed by the page number and "∨". You may of course choose your own delimiters. They will be recognized by the following signal response that appears in PORTION INDEX: A.3 Page 72 THOROUGHLY EXPLAINED EXAMPLES SAILON-70 .PORTION INDEX .NOFILL .LETTER ← PHR ← NULL .AT "∧<" PHRASE ">" PGNO "∨" ⊂ .IF "PHRASE" = PHR THEN START },#PGNO{ END .ELSE START COMMENT NEW PHRASE, GO TO A NEW LINE ; . IF ↑LETTER = ↑"PHRASE"[1] THEN BREAK . ELSE SKIP 1 ; PHRASE##PGNO{ . PHR ← "PHRASE" ; LETTER ← "PHRASE"[1] ; . END ⊃ ; COMMENT END SIGNAL RESPONSE ; .RECEIVE "<>" ; COMMENT ALPHABETIZE BEFORE READING ; RECEIVE will alphabetize the entries. The "AT" signal response will analyze each entry and make a couple of checks before outputting it: (1) If the phrase is the same as the one just printed, it simply appends the page number of the new entry to the last line printed. For example, if the alphabetized file contained: ...∧2.4∨{}∧3.7∨... then the index would include: Signs 2.4, 3.7 (2) Else, if the first letter of this and the previous phrase are the same, it goes to the next line; else, it skips a line. Thus, between the A's (and a's) and the B's (and b's) there will be a blank line. Then, it prints both the phrase and the page number. A.4 TWO-LEVEL INDEXES _________ _______ A "two-level index" divides some phrases into two parts: a "generic" part and a "specific" part, e.g.: compilers, Algol 13, 15 Fortran 18 LISP 22 SAIL 15 computers, analog 29 digital 10, 64, 80 consoles 16, 25 A.4 SAILON-70 THOROUGHLY EXPLAINED EXAMPLES Page 73 In the phrase "Fortran compilers", "Fortran" is the specific part and "compilers" is the generic part. This time we will approach the problem analytically instead of synthetically. There are two kinds of entries: one part and two part If two entries have the same generic part (e.g., "computers"), then the generic part should print only once. As PORTION INDEX receives each entry, it must compare it with the preceding entry. Say that the generic part of the preceding entry was WASL and the specific part was WASR (WASL was thus printed on the Left and WASR on the Right). The generic part of the current entry is L and the specific part is R. If WASL and L are different, a whole new generic entry is to be printed. Otherwise, if WASR and R are different, a new specific entry is to be printed. Otherwise, a new page number is to be added to the last entry printed. As an extra feature in this index, we will not print the same page number twice on the same line, i.e., twice in a row. Thus, an additional variable, WASP, will be needed to remember the page number last printed. Furthermore, if the entry has no specific part (see "consoles" in the above example), the page numbers will be printed on the same line as the generic part. The PORTION INDEX that follows assumes that the generated file has entries of the form: "<" generic-part "/" specific-part ">" page-number "%" where the specific-part can be empty. A.4 Page 74 THOROUGHLY EXPLAINED EXAMPLES SAILON-70 .PORTION INDEX .WASL ← WASR ← WASP ← NULL ; .NOFILL ; TABS 6 ; .AT "<" L "/" R ">" PGNO "%" ⊂ . IF ↑WASL[1] ≠ ↑"L"[1] THEN SKIP 1 ; <<1ST LETTER DIFFERENT>> . IF WASL ≠ "L" THEN . START "NEW GENERIC" BREAK ; L{IF "R"≠ NULL THEN START "WITH SPECIFIC PART" }, \R##{ END "WITH SPECIFIC PART" ; }PGNO{ . END "NEW GENERIC" . ELSE IF WASR ≠ "R" THEN . START "NEW SPECIFIC" BREAK ; \R##PGNO{ END "NEW SPECIFIC" . ELSE IF WASP ≠ "PGNO" THEN START },PGNO{ END . ⊃ ; .RECEIVE "<>" ; To create the generated file for PORTION INDEX requires a signal response such as: .AT "%<" SPECIFIC "/" GENERIC ">" ⊂ . IF "SPECIFIC"≠ NULL THEN START }SPECIFIC { END ; . }GENERIC{ ; comment print SPECIFIC and GENERIC in the text ; . SEND INDEX ⊂ }{PAGE!}%{⊃ ; . ⊃ ; Every phrase to be sent to the index should be bracketed as follows where it appears in the manuscript: that there are more %<Algol/compilers> than Algol users ... the world's leading expert on %</consoles>. A.5 KWIC INDEXES ____ _______ This one is easy. The desired output is: writers of compilers often balk 16 _________ The XYZ compilers 35 _________ certain Algol compilers 8 _________ compilers I've known 41 _________ IBM computer 72 ________ uses of the computer in government 64 ________ At the end of the manuscript: A.5 SAILON-70 THOROUGHLY EXPLAINED EXAMPLES Page 75 .PORTION KWIC .NOFILL TABS 30 .AT "<" KEY "/" PRE "/" POST ">" PGNO "%" ⊂ →PRE\#↓_KEY_↓#POST→PGNO ⊃ .RECEIVE "<>" At the beginning: .AT "%<" PRE "≤" KEY "≥" POST ">" ⊂ .}PREβKEYβPOST{ .SEND KWIC ⊂ . }<KEY/{ . "PRE"[∞-25 TO ∞] }/{ . "POST"[1 TO 30-LENGTH("KEY")] }>{ . PAGE! }%{ . ⊃ ; ⊃ ; Each phrase to be indexed is bracketed as follows: It is said that % at The last %> we bought was A.5 SAILON-70 PUB Page I SUBJECT AND COMMAND INDEX (References are to Page numbers) _SKIP_ 32 BREAKING AT CARRIAGE-RETURNS 15 BREAKING AT TABS 15 ! 46 BY 46 <dc> 34 C-value 46 <e> 33 CALLING A MACRO FROM A COMMAND <id> 30 LINE 25 <oc> 34 CALLING A MACRO FROM A TEXT LINE <qc> 34 25 35 CAPABILITIES 1 <se> 33 carriage-return 15, 64 <v> 31 CASE 56 CENTER 16, 19 ABOVE 57 channels 53 ADJUST 14 CHAR 31, 41 AFTER 64 CHARACTER 57 ALIGN 56 CHARS 31 alphabetize 52 collating sequence 52 APART 17 COLUMN 31 APPENDICES 49 COLUMNS 31, 40 APPENDIX 43 COMMAND AND TEXT LINES 13 AREA DECLARATION 39 COMMAND CHARACTER STATEMENT 49 arithmetic 30 command line 13 ASCII 34, 52 Command Processing 20, 24 Assignment expressions 33 COMMENTS 58 assignment statement 45 COMPACT 16 AT N 64 COMPILER OUTPUT 4 AT NULL 63 COMPOUND STATEMENT or CLUMP 35 AT PAGEMARK 63 COMPUTED TEXT 23 AT S 64 conditional expressions 33 AUTOMATICALLY DECLARED VARIABLES CONDITIONAL STATEMENT 45 31 CONSTANTS 34 CONTENTS 49, 50, 69 BEFORE 64 CONTINUE 41 BEFORE PAGE 65 CONTINUE STATEMENT 55 BEGIN 35 CONTROL CHARACTER ACTIVATION 21 BELOW 57 control characters 18 BIBLIOGRAPHY 49 CONTROL FUNCTIONS 18 BLOCK 35 COUNT 43, 46 block structure 35, 45 COUNTER DECLARATION 43 BOX FRAME STATEMENT 56 CRBREAK 15 BREAK STATEMENT 55 CROSS-REFERENCES 59 BREAKING AT BLANK LINES 15 crown 14 Page II INDEX SAILON-70 CRSPACE 15 GENERAL EXPRESSIONS 33 generated file 50, 52 DATA TYPE 30 Global 30 DATE 31 GROUP 17 decimal 34 GROUP SKIP 54 declaration 35 DECLARATIONS 37 HEADING 39 declarative 35 HEADINGS AND FOOTINGS 48 DEVICE LDX 57 hem 14 DEVICE LPT 56 hierarchy 43 DEVICE MIC 56 HORIZONTAL SPACE COMPACTION 16 DEVICE STATEMENT 55 hyphen 19 DEVICE TTY 56 document 1 IF 45 dot in column 1 49 ILLEGAL CHARACTERS 13 DOUBLE SPACE 39 imperative 35 DOUBLE SPACING 39 IMPERATIVES 45 INDENT DECLARATION 38 edit 56 INDENT1 31, 38, 45 ELSE 45 INDENT2 31, 38, 45 END 35 INDENT3 31, 38, 45 EQUATION 43 INDEX 49, 50, 52, 70 error messages 4 INLINE 46 EVERY HEADING 65 INSERT 49 EXPRESSIONS 30 integer 30 INTRODUCTION 1 FALSE 31 FIGURE 43 JUSTIFICATION 14, 18, 59 FILE 32 justifying 8 FILL MODE 14 JUSTJUST 16 filling 8, 31, 63 FLUSH LEFT 16 KWIC INDEXES 74 FLUSH RIGHT 16 FONT 57 LABELS 60 FOOTING 39 LABELS AND CROSS-REFERENCES 59 FOOTNOTE 43 LDX 56 FOOTNOTES 66 LINE 31 FOOTSEP 32 LINES 31 Forward Cross-Reference 44 LMARG 31, 45 forward-references 59 local 30 FR-80 56 LOCK 56 FROM 46 MACRO CALLS 27 SAILON-70 INDEX Page III MACRO DECLARATION 27 PUBSTD.DFS 26 MACROS 25 PUG 2 manuscript 1 PUI 2 MARGIN CONTROL 40 PURPOSE 1 MODE AND SWITCH SETTING COMMANDS PUZ 2 17 MODE DECLARATIONS 37 quotes 34 NARROW 40 RASTER 57 NEXT COUNTER VALUE STATEMENT 45 READING THIS MANUAL 5 NEXT PAGE STATEMENT 47 RECEIVE STATEMENT 52 NOFILL 8, 16 RECURSIVE MACROS 29 NOFILL MODE 15 REFERENCE 43 NOJUST 8, 14 REQUIRE STATEMENT 53 NOPRINT 56 reserved words 33 NULL 30, 31 RESPONSES 63 RETAIN 16 octal 34 Right Flush 19 OMISSIONS 28 RMARG 31, 45 ONCE 36 Roman 47 ONE PARAGRAPH SCOPE 36 RPG 2 ONE-LEVEL INDEXES 70 ONLEFT 57 SAMPLE COMPILATION 9 ONRIGHT 57 SAMPLE TABLE OF CONTENTS 69 OPERATION 2 scope 35, 36, 37 output past the right margin 41 SECTION 43 SECTIONING 48 P-value 46 SECTIONING MACROS 68 PACK 56 SEND STATEMENT 50 PAGE 32, 43 SHOW 56 PAGE FRAME STATEMENT 55 SIMPLE EXPRESSIONS 32 PAGEMARK 63 SINGLE SPACE 39 Paracybernetic Society 12 SKIP N 54 paragraph break 14, 37 SKIP STATEMENTS 53 PARAGRAPHING 14 SKIP TO COLUMN N 54 PLACE DECLARATION 42 SKIP TO LINE N 54 PORTION DEMARCATION 49 SPREAD 31, 39, 45 PREFACE DECLARATION 39 STANDARD BACK 51 PRINT 56 STANDARD FRONT 51 PRINTING 46, 60 STANDARD TITLES 65 PUB2 2 START 35 PUBMAC.DFS 26, 51 STATEMENT TYPES 35 PUBMAC.TES 51 STATEMENTS 35 Page IV INDEX SAILON-70 string 34 VERBATIM 8 STRING SPACE EXHAUSTED 52 VERTICAL GROUPING 17 Strings 30 vest 14 Subscript 20 SUBSECTION 43 WIDEN 40 substring 33 widows 40 SUPERIMPOSE [n] 16 WORD BREAKS 18 Superscript 20 switches 3 syntax of PUB commands 5 TAB 19, 41 TABBREAK 15 TABLE 43 table of contents 50 TABS DECLARATION 37 TABSPACE 15 TEMPLATES 26 TEMPORARY AREAS 42 TEXT 39 TEXT AREA 40 TEXT CONVENTIONS 13 text line 13 text processing 23 TEXT RESPONSES 63 THEN 45 THOROUGHLY EXPLAINED EXAMPLES 68 TIME 32 TITLE AREA 40 TITLEPAGE 49 TOPLINE 31 TRANSITION RESPONSES 64 TRIPLE SPACE 39 TRUE 31 TURN OFF 22 TURN ON 21 TUTORIAL FOR BEGINNERS 5 TWO-LEVEL INDEXES 72 Underline 20 UNIMPLEMENTED STATEMENTS 56 VARIABLES 30


Creator:Bilal Ahmed Shirwani
Admin:Bilal Ahmed Shirwani


algorithm, children, client, collection, compiler, cryptography, education, exercise, fileformat, learning, meta, monticello, moose, multimedia, persistency, pharo, protocol, research, seaside, server, squeak, teaching, testing, ui, xml


Code commited to this repository will be automatically under MIT license.


location: 'http://www.squeaksource.com/BilalAhmedShirwani'
user: ''
password: ''



Global:Read And Write


Registered:16 February 2022 2:24:13.486627 pm
Total Releases:0
Total Versions:0
Total Downloads:0
XHTML | CSS | RSS23 June 2024