TF Reference Manual

Copyright © 1997, Thinkage Ltd.

TF is a program for formatting text into clearly readable documents. This manual describes TF in a comparatively terse manner.

Input to TF:

TF takes a single file as its input. The lines of this file are either text or TF requests.

Lines containing TF requests are distinguished by beginning with a special ASCII character called the control character. The default control character in TF is the period (.); throughout this manual, we will use the period in our examples. The control character can be changed with the request

.cc C

where C is the new control character, e.g. ".cc $".

TF requests consist of the control character followed by a pair of characters, e.g. ".cc" as shown above. Any arguments for the request must be separated from these first three characters by at least one space or tab character (as "C" was separated from the ".cc" above).

The case of the letters in a request name does NOT matter. Therefore ".CC" is the same as ".cc".

Running TF:

The TSS command to invoke TF has the form

tf in1 in2 ... [>outfile] [options]*

where "in1", "in2", etc. are input files and "outfile" is an optional output file. If ">outfile" is not specified, output will go to the terminal.

Below we list some of the more commonly used options. A complete list of options for TF can be found in "expl tf".

Diversion=filename
specifies the name of the standard diversion file. Supplementary diversion files are specified using
Diversion1=filename
      ...
Diversion9=filename

Diversion files are discussed in the section named "Diversions".

-Warning
suppresses any warning messages TF might issue when possible anomalies arise.
-FormFeed
suppresses form feed characters in TF output. Normally, TF places form feed characters at the start and end of its output, as well as at page breaks.
-PageFormat
creates one long unpaginated stream of output.

Line Filling:

Normally, TF accumulates text from the input file and outputs this text in filled lines. No attention is paid to the lineation in the input file. If necessary, extra blanks will be inserted at random between words on the output line in order to justify lines to the right margin. The "no justify" request

.nj

tells TF to fill output lines as much as possible, but not to bother putting in the extra blanks needed to create a perfect right margin. The "justify" request

.ju

returns TF to its default mode of right justification.

The "no fill" request

.nf

tells TF to stop filling output lines. From this point onward, output lines will follow the lineation of the input file exactly, regardless of whether the lines fall short of the right margin or go beyond it. To return to TF's normal filling mode, use the fill request

.fi

Line Breaks:

Many TF requests cause a line break. This means that TF breaks off the line it is creating, even if the line is only partly filled, and begins working on a new line. For example, a line break of some sort is required at the end of each paragraph so that the last line of the paragraph is broken off and a new line is started for the next paragraph. The break request

.br

causes a line break specifically. Other requests causing implicit breaks are described in later sections.

Page Breaks:

The "break page" request

.bp

tells TF to start a new page, even if the current page is not yet filled. The "even page" request

.ep

tells TF to begin a new page and to give it an even page number. Similarly, the "odd page" request

.op

tells TF to begin a new page and to give it an odd page number. If the next page is not even or odd as requested, TF will issue an extra form-feed character so that there is a blank page filling in the gap.

The request

.pa E

begins a new page and sets the page's number to the value of the numeric expression E. For a description of valid TF expressions, see the section on Number Registers.

The ".sl" (slew) request determines whether formfeed characters (octal 014) are issued when page breaks occur.

.sl 1

indicates that formfeeds should be issued.

.sl 0

indicates that formfeed characters should not be used. These requests can be used to counteract the "+FormFeed" or "-FormFeed" specified on the TF command line.

If "+FormFeed" or ".sl 1" is specified, a formfeed character will be placed at the END of each page of output. One consequence of this is that there is NO formfeed at the very beginning of TF output.

Blanks and Spaces:

Any line beginning with a blank or tab character causes an automatic line break. Trailing blanks on input lines are stripped. New-line characters are normally turned into a blank character, except when they follow a ".", "?", "!", or ":". In these last four cases, the new-line is turned into two blanks; thus sentences that end in the middle of an output line will be followed by two blanks. Because of this effect, we recommend that users begin a new input line every time a sentence is completed -- this allows TF to format sentences uniformly.

Input lines consisting only of a new-line character are ignored in fill mode (i.e. when ".fi" is in effect).

Blank lines may be specified with the space request

.sp N

where N is an unsigned integer indicating how many blank lines are desired. If N is not specified, the default is ".sp 1", one blank line. If you request more blank lines than are left on the current page (i.e. if N is larger than the number of lines left on the page), ".sp" will leave the remainder of the page blank and will start output right at the top of the next page. It will NOT put the surplus blank lines at the top of the next page.

A contiguous block of blank lines may be allocated with the leave request

.lv N

If there are N or more lines available on the current page, TF will leave a blank block of the requested size. If there are fewer than N lines left on the page, TF will fill out the page with text gathered after the ".lv" and will leave N lines blank as soon as a new page is started.

The "line-spacing" request

.ls +N

can be used to set line-spacing; for example, ".ls 2" is double-spacing. The "+" in front of the N indicates that you can use a signed number to set a new line-spacing value relative to the old.

.ls 2
.ls -1

sets line-spacing to 2, then decrements the 2 by 1. The end effect is thus ".ls 1". Single-spacing (".ls 1") is the default setting for ".ls".

Literals:

The request

.li N

indicates that the next N lines of input are to be taken literally, even if they would normally be regarded as TF requests. If N is omitted, 1 is assumed.

".li" is usually used immediately before lines that begin with the control character, e.g.

.li
.sp is the TF space request.

Number Registers:

The "assign number" request

.an R E

assigns the result of the numeric expression E to a number register named R. If E is omitted, the value 1 is assigned to R.

The register name R may be one to 32 characters long, consisting of letters, digits, and the characters "#", "%", and "_" (underscore). The case of letters is ignored in register names, so "A" and "a" refer to the same register.

The register name in the ".an" request may or may not be surrounded by parentheses. In the documentation that follows, parentheses will normally be included, but they are not necessary.

TF maintains a number of pre-defined registers whose names begin with the "%" character. More of these may be added in future, and thus we recommend that users avoid names beginning with "%" to avoid future naming conflicts.

The expression specified in the ".an" request may take one of the following forms.

An unsigned integer.
In this case, the integer is assigned to the register.
A signed integer.
Permitted signs are "+", "-", "*", "/". These indicate addition, subtraction, multiplication, or division of the current value of the register by the specified integer. Division by zero is defined to be zero.
A relational expression.
The relational operators recognized by TF are ">" (greater than), "<" (less than), and "=" (equal to). The result of a relation test is 1 if the relation is true and 0 otherwise. For example,
.an (xx) 5>3

assigns register "(xx)" the value 1.

An "l" or "s" operation.
The "l" operator takes two operands and returns the larger of the two. The "s" operator takes two operands and returns the smaller. For example,
.an (six) 5l6
.an (five) 5s18
A quoted string.
When a quoted string appears in a numeric expression, it will be replaced by a number equal to the number of characters in the string. For example,
.an (four) 'abcd'

assigns (four) the value 4. The quotes used to surround the string should be the quote character as defined in the ".qc" request (see the section below on the Quote Character).

An extended expression with several operators.
The operations described above may be combined as in
.an (how_much) 4+5-6/2>3

Evaluation is strictly left to right, and parentheses may not be used to change the order of evaluation.

You may not put blanks in between the terms of an expression. For example,

.an X 4+5

is correct but

.an X 4 + 5

will not work properly.

The value of a number register may be used by means of an insertion character. The insertion character is established by means of the request

.ic C

where C is the desired insertion character, e.g. ".ic ^". Once this has been done, a construct consisting of the insertion character followed by the register name in parentheses will be replaced by the current value of the register. For example,

.ic ^
.an (xx) 5
Five is equal to ^(xx).

results in the line

Five is equal to 5.

Similarly,

.sp ^(xx)

becomes ".sp 5".

Note that enclosing parentheses are required with a register name when it is used in an insertion construct, even though the parentheses are optional in the ".an" request where the register was defined.

TF allows several different formats for outputting number registers. When a special format has been assigned to "(reg)", TF will print the contents of "(reg)" in that format whenever it sees "^(reg)". Possible formats are shown below.

1     0,1,2,3,4,...,10,11,12,...
01    00,01,02,03,...,09,10,11,12,...
i     0,i,ii,iii,iv,...
I     0,I,II,III,IV,...
a     0,a,b,c,d,...,z,aa,bb,cc,...
A     0,A,B,C,D,...,Z,AA,BB,CC,...
o     0th,1st,2nd,3rd,4th,...
O     0TH,1ST,2ND,3RD,4TH,...
z1     0, 1, 2, 3,...,10,11,12,...

There are also formats 001, 0001, etc. to specify minimum output widths for integers. The formats "z1", "zz1", "zzz1", and so on also specify minimum output widths for integers; in this case however, the numbers will be padded out to the required width with leading blanks instead of zeroes. Thus TF recognizes requests for minimum-width formats, upper or lower case roman numerals, and upper or lower case "theatre seating" format. To assign a given format to a number register, use

.af R F

where R is the register name (optionally in parentheses), and F is the format in which the number 1 should print (shown on the left in the table above). Thus

.af (rom) i

indicates that (rom) should be displayed in lower case roman numerals. All number registers begin with a format of 1.

Number registers may become negative, in which case they will be displayed with the usual minus sign in front.

Special Number Registers:

TF initializes and maintains several special number registers automatically. These are listed below.

%
is the current page number.
#
is the current output line number.
(year)
is the last two digits of the current year.
(mon)
is the number of the current month. January is 1, December is 12.
(day)
is the current day of the month.
(hour), (min), (sec)
give the hour, minute, and second that TF began processing the current input file. These numbers are given with respect to a 24-hour digital clock.
(%in)
gives the current indentation value. For example, ".in 5" means that (%in) will have the value 5.
(%po)
gives the current page offset (as set by the ".po" request).
(%ll)
is the current line length.
(%pw)
is the current page width.
(%pl)
is the current page length.
(%ls)
is the current line spacing. For example, (%ls) will equal 2 if you are currently double-spacing.
(%m1), (%m2), (%m3), (%m4)
give the current sizes of the four page margins.

More about the Insertion Character:

If an insertion character appears in input but is not followed by a register name, the insertion character disappears and the following character is taken literally, regardless of any special meaning it might have been given for TF processing. In particular, TWO insertion characters (e.g. ^^) result in one insertion character actually appearing: the first insertion character disappears and the second is taken literally.

The request

.ic

clears the special meaning of the current insertion character.

Text Registers and Macros:

Just as number registers contain numbers, text registers in TF contain text. To assign text to a register, you begin with an assign text request

.at R

where R satisfies the same requirements as number register names (so that it may be enclosed in parentheses if desired). The name of a text register cannot be the same as the name of another text register or a number register that has already been defined.

The lines that follow the ".at" are assigned to R until a line of the form

.en R

is encountered.

A text register may hold a virtually unlimited number of characters. It should be noted however that the contents of text registers are kept in memory when being defined and used; thus having many large registers active will tend to slow down response time.

There are two general uses for text registers. The first use is similar to the use of number registers; if ^ is the insertion character, the construct "^(text_reg)" is replaced by the textual contents of "(text_reg)" wherever it appears in input. As a simple example of how this might be handy, consider an operations document that refers several times to a particular administrative position. Since the person occupying this position is subject to change, the TF source might define

.at (admin)
R.Montague
.en (admin)

at the beginning of the input file and then use "^(admin)" to refer to this person throughout the body of the document. When the administrator changes, it is only necessary to change the text register definition, e.g.

.at (admin)
J.Capulet
.en (admin)

Running the document through TF again will change all the names appropriately. In this way, a single change fixes things all through the document.

The second use of text registers is in defining macros. When TF encounters a line beginning with the control character immediately followed by a text register name (without parentheses), the contents of the text register are inserted in place of the line. For example, here's a standard paragraph macro:

.at (stp)
.sq
.ne 3
.in 0
.ti +5
.en (stp)

Once this macro definition has been given, the line

.stp

will be replaced by the set of TF requests that have been assigned to the text register (stp). In this way, a single line that resembles a TF command may stand for a large number of TF commands and text lines too.

It is important to make one special note about the way TF collects the lines of a text register. When TF encounters a line in the ".at" text which begins with the control character (usually "."), TF converts that character into a special internal character that indicates the line is a request or macro call. The result is that even if you change the control character later on in the input, TF will know which of the lines stored in a text register are requests or macro calls. Thus changing the control character does not affect the performance of previously defined macros.

When a macro is called during TF processing, it may be passed parameters. For example, suppose we have defined a text register named (mac). The line

.mac 3 5

is a call to (mac) containing a first parameter of three and a second parameter of five. Parameters must be separated by one or more tabs or spaces.

In order for a macro to make use of parameters, a parameter character must be established. This is done with the request

.pc C

where C is the character that will be used inside macro definitions to indicate parameters. If we define

.pc #

then constructs of the form #1, #2, #3, and so on will refer to the first parameter, the second parameter, the third parameter and so on, wherever they appear inside a macro definition. For example, suppose we defined (mac) as

.at (mac)
.sp #1
.an (two_parm) #2
.en (mac)

Then the ".mac 3 5" call we showed above would be replaced by the requests

.sp 3
.an (two_parm) 5

To repeat, the constructs #1, #2, ... are specified inside the macro when it is DEFINED. When the macro is CALLED, TF will replace these constructs with the parameters specified on the calling line.

If #N appears in a macro definition and less than N arguments are specified when the macro is called, the #N construct will be replaced with a null string.

The request

.pc

turns off the special meaning of the current parameter character. This can be done safely any time after all macros have been defined. The parameter character must be defined at the time that the macro is defined, but it does not have to stay in effect afterwards. In particular, the parameter character does not have to be defined at the time that the macro is invoked.

Note that TF ruthlessly suppresses new-line characters wherever possible when defining a text register or macro. In particular, TF always throws away extraneous new-lines which appear at the end of the register definition. For example, if the register (admin) is defined as above, the construct

^(admin)'s office

would be expanded to

J.Capulet's office

If the new-line had not been discarded, the result would have been

J.Capulet 's office

with a space between the name and the apostrophe (since the new-line would have caused a word break).

Generally speaking, users need not worry about this feature when defining macros. However, it has at least one side effect that must be guarded against. The last line of the macro definition cannot be empty. For example,

.at (xxxx)
.mg
.en (xxxx)

will not work. The blank line, which is an argument for ".mg", will be discarded by TF as an extraneous line. To make the sort of definition given above, one would have to put a

.zz

or similar "no-op" after the blank line, so that the new-line is not discarded.

Register Expansion:

We have shown how parameters are supplied when text registers are invoked as macros. Parameters may also be supplied when text registers are inserted in text. This is done with a construct of the form

^(reg_name arg1 arg2 arg3... )

where "^" is the insertion character, "reg_name" is the name of the text register, and "arg1" and so on are the arguments. These calls may be nested as in

^(reg1 ^^(reg2 ^^^^(reg3)))

Note that multiple insertion characters usually have to be used so that insertion happens during expansion, not as soon as the line is read.

Note that the same technique may be used for invoking TF requests. For example, the following two lines are equivalent.

.af (reg) 01
^(af (reg) 01)

This is generally only useful when a request is being passed to a macro as an argument, e.g.

^(reg1 ^^(request))

Requests and macros may be invoked anywhere in text using a similar construct. For example,

text^(br)text

executes a ".br" break between the two pieces of text. Similarly,

.at (example)
.in 10
Hello there.
.en (example)
This is an ^(example) example.

results in

This is an
          Hello there. example.

In rare cases, subtle differences may be found between the ".macro" and "^(macro)" constructs for expanding a macro. The most common cause of this difference is the use of ".li" within the macro. When ".li" precedes a line, the line is not taken as a TF command (macro or request); however, "^(reg)" constructs ARE expanded within the line. Therefore

.li
.reg

puts the string ".reg" in the output while

.li
^(reg)

puts the expanded contents of (reg) into the input stream and then applies the ".li" to the first line of the expanded contents.

To give another example of this difference, consider the following.

.ic ^
.pc #
.at (test)
.li
#1
.en (test)

If we define

.at (reg)
.ti 5
.en (reg)

then

.test This_is_all_^(reg)_on_one_line.
    is expanded to
This_is_all_.ti 5_on_one_line.

The ".li" in the definition of test suppresses the execution of the ".ti 5" request when "(reg)" is expanded as the argument of ".test". However, if we define

.at (reg)
^^(ti 5)
.en (reg)

we have

.test This_is_^(reg)_on_two_lines.
      producing
This_is_
     _on_two_lines.

When the argument of ".test" is expanded, ".li" does not affect the "^(ti 5)" that ends up in the middle of it. Therefore the temporary indentation takes place at the point it appears.

This subtlety will almost never be important in normal TF usage.

Special Text Registers:

TF maintains the following special text registers.

(%amon)
is the name of the current month, e.g. "January".
(%wday)
is the name of the current weekday, e.g. "Thursday".
(%tf)
is the current version of TF.

The Quote Character:

The request

.qc C

establishes a character C as a quote character. A quote character is useful when passing a macro an argument that contains blank characters. For example, suppose the ".head" macro is used to create a section heading in the document and suppose that ".head" takes a single argument to serve as the heading. If the heading were "Preliminary Facts", you might type

.head Preliminary Facts

Just looking at this though, there appear to be TWO arguments: #1 is "Preliminary" and #2 is "Facts". The two are grouped together by enclosing them in quote characters, as in

.qc '
.head 'Preliminary Facts'

The two words are now treated as one item.

The request

.qc

turns off the special meaning of the current quote character.

Undefined Registers:

When TF encounters a construct of the form

.name ...

where "name" is not the name of a valid register or TF request, a warning will be issued and the line will be taken literally. Thus ".name" will be printed as part of your output.

When TF encounters a construct of the form "^(name ...)" and "name" is not the name of a valid register or request, a warning will again be issued. However, the construct will NOT be taken literally as before; instead, it will be replaced by the character "0". This occurs primarily for historical reasons; the feature may disappear in later releases of TF. For more on undefined registers, see the section called "Ifs and Ignores".

Pushing and Popping Registers:

The request

.sa R

will save the current value of register R on an internal stack. This is useful when you intend to redefine the value of R but don't want to lose the old value. Once you have saved the old value with ".sa", you may redefine R freely with ".at". To recover the old value, use the request

.zt R

This will discard the current value of R and will restore the most recently saved value.

It is perfectly legitimate to use ".sa" to save a register that is not currently defined. When you use ".zt" to restore this, the register will be undefined again. Similarly, if you simply use ".zt" on a register name without saving the register first, the effect is to delete the register (i.e. make it undefined).

Because ".sa" saves register values on a stack, several values may be saved, then restored one by one.

Titles:

TF allows you to define heading titles and footing titles to be put at the top and bottom of output pages. The general form of a title T is

'field1'field2'field3'

Note that "field1" and "field3" may be enclosed in any non-alphanumeric character desired; however, the same character must be used for both fields. When a title of this form is specified in a heading or footing request, "field1" will be positioned on the far left of the page, "field2" will be centered, and "field3" will be positioned on the far right of the page. Therefore a title of the form

'P.Parker'Webs I Have Known'E.S.U. Chem Dept.'

would be expanded to

P.Parker         Webs I Have Known          E.S.U. Chem Dept.

Any of the three fields in a title may be null. If "field1" or "field3" are to be left blank, the enclosing quote characters must still be included, as in

''Title''

When the character "%" appears in a title, it will be replaced by the current page number. Other number or text registers may be inserted in the title using the standard "^(reg_name)" construction.

The following requests take a title of form T as an argument.

.he N T
This defines a heading title that will be put at the top of each page above the actual text of the document. The N is an integer between one and ten (inclusive) indicating which heading line is being defined. TF allows 10 headings; they are printed with heading #1 highest and heading #10 lowest. If N is omitted, 1 is assumed (so ".he T" defines a one-line heading).
.eh N T
This is the same as ".he" except that it defines headings for even-numbered pages only.
.oh N T
This is the same as ".he" except that it defines headings for odd-numbered pages only.
.fo N T
This defines a footing title, to appear below the actual text of the document. Up to 10 footings may be specified for a page. They are printed with footing #1 lowest and footing #10 highest on the page. If N is omitted, 1 is assumed.
.ef N T
This is the same as ".fo" except that it defines footings for even-numbered pages only.
.of N T
This is the same as ".fo" except that it defines footings for odd-numbered pages only.
.fs T
This defines a "footnote separator". A more detailed explanation will be given in the section on Footnotes.

If no heading or footing requests are specified, a blank title is used.

Margins:

There are two margins at the top of the page. "m1" is the blank area above the first heading line. "m2" is the area below this, containing the headings and whatever space is desired between the headings and the body of the text. By default, TF sets

.m1 4
.m2 2

The ".m1" and ".m2" requests may be used to adjust these margins. If "m2" is N with N < 10, headings N+1 to 10 will NOT appear on the page.

There are another two margins at the bottom of the page. "m4" is the blank area below the lowest footing line. "m3" is the area between "m4" and the "squeeze margin" at the bottom of the body of the text (for a description of the squeeze margin, see the section on the Squeeze Request). Margin "m3" contains the footing titles and whatever space is desired between the text and the footings. By default, TF sets

.m3 1
.m4 4

The ".m3" and ".m4" requests may be used to adjust these margins. If "m3" is N with N < 10, footings N+1 to 10 will NOT appear on the page.

Top and bottom margins are taken relative to the length of the output page. The "paper length" request

.pl N

establishes a physical paper length of N lines. The default paper length is 66 lines, the standard length of paper on a high-speed printer. Specifying a paper length of 0 will result in no page breaks being issued except by specific paging commands (e.g. ".bp").

The right margin is determined by the current line length. This is set by the ".ll" request; by default, TF sets

.ll 60

The left margin may be moved by using the ".po" (page offset) request. For example,

.po 5

moves the entire page five spaces to the right. The line length stays the same but the entire line is shifted. The left margin may also be changed using indentation requests; these are discussed in a later section.

The arguments for ".po", ".ll", ".pl", ".m1", ".m2", ".m3", and ".m4" may be any valid numeric expression. In particular, the arguments may be signed numbers representing a change in a margin relative to the current setting. For example,

.m3 -1

decrements the current setting of "m3" by one.

Indentation:

The indentation request has the form

.in E

where E is a valid numeric expression. For example,

.in 10

tells TF to indent all lines by 10 spaces, while

.in +5

increments the current indentation by five spaces.

The effect of indentation is to shorten the output line by moving in the left hand margin. This is different from a page offset because a page offset shifts output lines as a whole.

The "temporary indent" request

.ti E

is similar to ".in" but it only indents one line of output. Thus the request

.ti +5

might be used to indent the first line of a paragraph five spaces beyond the current indentation setting. Subsequent lines will be flush with the left hand margin as set by the ".in" request.

A second form of the ".ti" request is

.ti E N

Again, E is an expression giving a temporary indentation for the next line of output. The second argument indicates that the first N characters of that line should not undergo fill processing, i.e. they should be left "as is".

The "center" request

.ce N

centers the next N text input lines in the middle of the page. For example,

.nf
.ce 2
Both of these lines
will be centered.

produces

                                Both of these lines
                                  will be centered.

If the integer N is not specified for ".ce", 1 is assumed. If a second ".ce" request is encountered before N lines of input have been centered, the number on the second ".ce" overrides the number on the first. For example, in

.ce 999
This will be centered.
This will be too.
.ce 0
This will not be centered.

the 0 will override the 999 and no subsequent lines will be centered. This technique is useful when you have to center a large number of lines but don't want to count exactly how many.

If a ".ce" and ".ti" are issued one after the other, without any intervening text, the next line of text will be temporarily indented from the position it would have if it was centered.

The Need Request:

The need request

.ne N

indicates that there must be space for at least N lines on the current page. If this much space isn't available, TF will finish off whatever part of a line it has already filled and will then begin a new page.

".ne" calculates the space needs on the basis of the current line spacing. Thus ".ne 3" asks for three lines if TF is currently single-spacing, but six lines if it is double-spacing.

The Squeeze Request:

The squeeze request

.sq

is used to squeeze a line onto the current page in order to avoid a widow. It does this by maintaining a "squeeze margin" below the body of the text between the text and the standard margin "m3". The size of this margin is determined by the size of the line-spacing set by ".ls". When ".sq" is found in text, TF generates a line break. If there is no room for the resulting (partial) output line to be put in the main body of the text, the line will be placed in the squeeze margin. Thus for example, putting a ".sq" at the end of each paragraph ensures that the last line of the paragraph appears on the current page (possibly in the squeeze margin) instead of dangling at the top of the next page.

Line Numbers:

TF includes a facility that will automatically create line numbers on the left side of output text. For these numbers to be printed, ".po" must be used to specify a suitable page offset (".po 4" is usually sufficient).

The line numbering facility is controlled by the ".ln" request. This has the format

.ln E

where E is a standard numerical expression whose result is 0, 1, or 2. ".ln 1" tells TF to number output lines beginning at 1 at the top of each page. ".ln 2" tells TF to number output lines beginning at 1 where the request is specified and continuing sequentially from there. ".ln 0" stops line-numbering.

The line numbers generated by ".ln" are NOT put on blank lines, titles, or footnotes.

A warning is issued if the ".ln" expression is not 0, 1, or 2.

Footnotes:

Text for footnotes is enclosed by the requests ".fn L" and ".en L", e.g.

.fn (sample)
This is a footnote.
.en (sample)

As shown above, the symbol L stands for a label. A label may be null or it may be a name satisfying the same restrictions as register names. (In particular, it may be enclosed in parentheses.) In the example above, the label name was "(sample)".

The lines contained by the ".fn" and ".en" are formatted normally, but the result is not output until the bottom of the current page is reached.

The footnote environment is completely independent from the environment of the main body of the text. For example, setting a particular indentation for a footnote has no effect on indentation in the main body of the text. Separate settings are maintained for the following requests (and their synonyms or antonyms).

.bf         .ce         .fi
.in         .ju         .ll
.ls         .mg         .ta
.ti         .ul

Normally, footnotes are separated from the bottom of text by a blank line. A different footnote separator may be set by the request,

.fs T

where T is a standard title.

Problems may arise in situations where a footnote becomes longer than a normal output page. If the number of lines in a footnote comes to exceed the number of lines per page, the following actions are taken. First of all, TF causes a page break in the main body of the text so that the footnote will start on a new page. It then outputs whatever portion of the footnote has already been processed and continues outputting until the end of the footnote has been reached. The main body of the text will then continue following the end of the footnote.

If pagination is not turned on (i.e. ".pl 0" has been specified), TF will collect a maximum of 10K (10,840) characters for the footnote. If this maximum is exceeded, a warning is issued and subsequent characters for the footnote are discarded.

Tables:

In the same way that footnotes are processed separately from the main text, TF provides facilities for separate processing of tables. The beginning of a table is indicated by the request

.tt L

where L is a valid label (this request causes an automatic line break). The end of the table is indicated with ".en L", e.g.

.tt (tab1)
   <table stuff>
.en (tab1)

The requests and text lines enclosed by the ".tt" and the ".en" are processed separately from the main text. Once this processing is finished, TF will determine if the processed table will fit on what is left of the current page. If it will fit, the table is output immediately and TF will continue with normal processing. If the table will not fit in its entirety, TF will fill the remainder of the current page using the input that appears AFTER the ".en L"; the fully processed table will then be placed at the top of the page as soon as a new page is begun.

As with footnotes, the environment inside a table is independent of the environment in the main body of the text.

If the number of lines in a table is found to exceed the number of lines per output page, TF will follow the same procedure it uses for handling over-long footnotes. There is a page break to end the current page and the table begins at the top of the next page. If the document is not being paginated, a table may have a maximum of 10K characters. If this maximum is exceeded, a warning is issued and surplus characters are discarded.

If a footnote is issued inside a table, a warning is printed and the footnote is completely discarded. Similarly if you attempt to place a table inside a footnote, a warning will be issued and the table will be discarded.

By default, TF will hold onto more than one table at a time. This can cause TF to grow significantly in memory requirements as it attempts to keep several tables in memory simultaneously. Specifying

.tb 0

avoids excessive memory requirements by instructing TF to hold a maximum of one table at a time. In a situation where TF encounters a ".tt" request when it already has a formatted table waiting to be placed at the top of the next page, ".tb 0" causes TF to break off the current page (as with ".bp"), output the table that is being held, and then begin collecting the new table. The request

.tb 1

returns TF to its normal "multi-table" mode.

Underlining and Boldface:

The "underline" request

.ul N

will underline the words of the next N input lines when they are placed in output text. Punctuation appearing on those input lines will NOT be underlined. If N is not specified, 1 is assumed. If a second ".ul" request is encountered before N lines of input have been underlined, the number on the second ".ul" overrides the number on the first. For example, in

.ul 999
This is underlined.
This is too.
.ul 0
This is not.

the 0 in the second request replaces the 999 from the first, so that no more lines are underlined. This technique is useful when a large number of items must be underlined.

The "bold face" request

.bf N

bold faces the words of the next N input lines when they are placed in output text. This is done by overstriking the characters of the words three times. Punctuation is bold-faced as well as the words. If N is not specified, 1 is assumed. If a second ".bf" request is encountered before N lines of input have been bold-faced, the number on the second ".bf" overrides the number on the first.

It is strongly recommended that ".ul" and ".bf" be used for underlining and bold-facing rather than doing it with backspacing and so on.

Translation:

Before a character is output, it undergoes translation processing. Normally, characters are simply translated into themselves; however, it is possible to direct TF to perform different translations with the request

.tr ABCDEF...

In this form, character A will be translated to B, C will be translated to D, and so on. For example,

.tr #

causes "#" to be translated into a space just before it is output. This is therefore an unfillable space, since it is treated as a "#" before output, not a separation between words.

ASCII control characters may not be translated. To put an end to the translation of a single character C, just type ".tr CC". The command

.tr

re-initializes the translation tables to their original state, so that all characters are translated into themselves.

The request

.ib C

is also a type of translation request. It indicates that the character "C" is an "input blank" and should be converted into a space character immediately upon input. Again, this is treated as an unfillable blank; where the character C appears in the input there will always be exactly one blank upon output.

In most instances, there will be no difference between the effects of

.ib C

and

.tr C

The difference is only apparent in situations where text does not go through normal output processing. For example, the ".ze" request sends a message directly to the terminal as the input is being processed by TF.

.tr #
.ze Hello#there

would print

Hello#there

on the terminal because the text does not undergo the usual translation on output.

.ib #
.ze Hello#there

prints

Hello there

on the terminal because the "#" is converted to a blank immediately upon input.

Hyphenation:

The hyphenation mode of TF determines how aggressively TF will attempt to hyphenate words when filling out a line. This mode is set by the request

.hy N

where N is 0, 1, 2, or 3.

.hy 0
implies no hyphenation.
.hy 1
allows hyphenation at hyphens typed in input and at hyphenation characters.
.hy 2
allows hyphenation before certain suffixes.
.hy 3
allows hyphenation between certain pairs of letters. Thus this results in "maximum hyphenation".

The default is ".hy 2".

The hyphenation character is established by the request

.hc C

where C stands for the desired hyphenation character. When an input word contains one or more hyphenation characters, it indicates that TF should only hyphenate the word at the indicated spots. For example,

.hc \
chrono\synclastic infun\di\bulum

uses the character "\" to indicate the positions where TF may hyphenate if necessary. The command

.hc

turns off the special meaning of the current hyphenation character.

Tabulation:

The ASCII tab character is normally used in tabulation. However, the request

.tc C

can be used to establish another character C as an additional tab character.

Any input line that contains one or more tab characters undergoes tab processing. Tab characters are used to separate fields for tabbing. Everything that appears before the first tab character in the line is regarded as field #0 and is positioned flush with the left margin (as determined by the current setting of ".po" and ".in"). Field #1 is whatever appears between the first tab character and the second, field #2 is between the second and the third, and so on.

The way in which fields #1 and up are positioned on the output line is determined by the ".ta" request. The arguments for ".ta" are either integers or letters. The numbers determine column positions; an unsigned integer determines an absolute column position and a signed integer determines a position relative to the previous position. Thus "8 16" and "8 +8" are equivalent.

The letters used as arguments for ".ta" determine how each field is positioned relative to the specified columns. There must be a letter for every field except field #0. The following letters are recognized.

L
indicates that the field should be left-aligned to the column number closest to the LEFT of the L.
R
indicates that the field should be right-aligned to the column number closest to the RIGHT of the R.
C
indicates that the field should be centered between the column numbers closest to the LEFT and the RIGHT of the C.

Note that letters are matched with the numbers closest to them; it is not necessary to have a number immediately adjacent to a letter. Therefore

.ta 10 L C R 60

defines the position of three fields: field #1 is left-aligned to column 10, field #2 is centered between 10 and 60, and field 3 is right-aligned to column 60. In a ".ta" request, there must be one or more spaces between numbers and the "L", "C", or "R" indicating how fields should be positioned.

If the first item after the ".ta" is a letter, TF will automatically place a 1 before it; if the last item on the line is a letter, TF will automatically place the current line length at the end of the line. For example, in

.ll 65
.ta L R

the "L" becomes "1 L" and the "R" becomes "R 65".

The arguments for ".ta" may be specified on the same line as the request as shown above, or they may be given on the line immediately following. In this latter case, the specification line consists only of spaces and the letters L, C, and R. An L shows the left-most column of a field that should be left-aligned; a C shows the center column of a field that should be centered; and an R shows the right-most column of a field that should be right-aligned. The first letter on the line is used for field #1, the next for field #2, and so on. For example,

.ta
       l         l    c            r

defines four fields; the first two are left-aligned to the indicated columns, the next is centered, and the last is right-aligned.

If the size and positioning of the various fields causes some fields to overlap, overstriking of characters will occur.

Field #0 may be omitted simply by starting the input line with a tab character. Other fields may be omitted simply by specifying two tab characters with nothing between them.

Tab settings continue to be in effect until they are reset by a new ".ta" request.

If a line contains more tab characters than are accounted for under the current tab settings, the excess tabs will be turned into spaces and be considered part of the last field on the line. A warning message will be issued unless "-Warning" was specified on the TF command line.

Note that the tab positions specified in connection with ".ta" are relative to the page offset and the current indentation setting.

The request

.tc

turns off the special meaning of the additional tab character.

Merge Patterns:

After an output line has been formatted but before translation of characters takes place, the line is merged with any merge patterns that have been established. Such a pattern can be established with the command

.mg N

where N is an unsigned integer. The line immediately following the ".mg" request is established as pattern #N. If N is not specified, 1 is assumed.

The merging of output lines and merge pattern adopts the following procedure. Any blank characters on the output line are replaced by the corresponding characters in merge pattern #1. Any remaining blanks are replaced by the corresponding characters in merge pattern #2 and so on until TF runs out of blanks or merge patterns.

The position of a merge pattern is permanently fixed by the settings of ".po", ".in", and ".ll" that were in effect at the time of the ".mg" request.

Merge patterns containing ASCII control characters are apt to give unexpected results.

Ifs and Ignores:

The ".if" request is handy for conditional processing. It has the form

.if E L

where E is an expression and L is a label. If E is non-zero (true), the lines that follow the ".if" will be processed normally. However, if E is zero (false), TF will ignore all input until it encounters an ".en L" where the label L matches the label in the ".if" (unless it finds an ".el L" first -- see below). Thus TF will only pay attention to the lines between the ".if" and the ".en" if the given expression is non-zero. For example,

.if ^(mon)=1 (jan)
JANUARY
.en (jan)
.if ^(mon)=2 (feb)
FEBRUARY
.en (feb)
  ...
.if ^(mon)=12 (dec)
DECEMBER
.en (dec)

uses the current month number to return an upper case name of the month.

".if" requests can be nested provided that no two of the "ifs" have the same label. Thus we might write

.if ^(mon)=1 (jan)
.if ^(day)=1 (jan1)
Happy New Year!!!
.en (jan1)
.en (jan)

The ".el" (else) request may be used in connection with ".if" to create an IF-THEN-ELSE construct. The request has the form

.el L

where L is a label matching the ".if" with which the else is associated. For example,

.if ^(mon)=1 (jan)
This is January!
.el (jan)
This is not January!!
.en (jan)

results in "This is January!" if (mon) is 1 and otherwise gives "This is not January!!". Constructs using ".if" and ".el" may be nested if desired.

The ".id" (If Defined) request has the form

.id R L 

If the register R is defined, TF will process everything down to the next ".en L". If R has not yet been defined, TF will skip the text that follows the ".id". The ".el" request may be used with ".id" in the same way that it is used with ".if". For example, in

.id (reg) (label)
   AAAAAAA
.el (label)
   BBBBBBB
.en (label)

the region AAAAAAA will be executed if "reg" has been defined in a ".at" or ".an" requst and the region BBBBBBB will be executed if "reg" has not been defined.

".if" and ".id" requests may be freely intermingled, provided that no two have the same label.

The request

.ig L

causes TF to ignore all requests and input text until it encounters an ".en" request with a matching label L. If we were to write the previous example using ".ig" we might say

.ig (^(mon))
.en (1)
JANUARY
.ig (0)
.en (2)
FEBRUARY
.ig (0)
  ...
.en (12)
DECEMBER
.en (0)

Diversions:

The ".di" request signifies the beginning of input for the standard diversion. It has the form

.di L

where L is a standard label. If the "Diversion=file" option was specified on the TF command line, input lines following the ".di" will be written to the specified file until an ".en L" is encountered. If the option was not specified, the lines between the ".di" and ".en" are simply discarded.

The only processing that TF performs on lines diverted to the diversion file is the replacement of "^(reg_name)" constructs with the contents of the appropriate number or text register. Otherwise, the lines are copied exactly as they appear.

In addition to the standard diversion, TF allows you to have nine subsidiary diversions. The diversion files are specified using the options

Diversion1=file
Diversion2=file
    ...
Diversion9=file

on the command line. Material for each of these diversions is introduced with the request

.dn N L

in the input file, where N indicates the number of the diversion file that should receive this material. The end of such diversion material is indicated with ".en L".

If a ".dn" request refers to a diversion N, but the command line contained no corresponding "DiversionN" option, the diversion material will normally go to the standard diversion. However, a subsidiary diversion file can be named inside the TF source file by using the "file attach" request.

.fa N filename

tells TF to use the named file for diversion N. The request

.cl N

closes the file associated with diversion N.

Note that diversion files attached with ".fa" are placed on a stack. Thus

.fa 1 file1
.fa 1 file2
.cl 1

attaches "file1" as diversion 1, then attaches "file2" as diversion 1 to replace "file1". When "file2" is closed by the ".cl" request, "file1" returns to serve as diversion 1.

Traps

In some formatting applications, it is useful to be able to "spring a trap" upon reaching a particular line on the page. As an artificial example, you may want to leave blank the bottom half of every page in a report so that readers have space to write comments. The request

.tp N R

sets a trap at line N (where N is a valid numeric expression). R is the name of a text register or macro. When TF advances to line N on the page (i.e. as soon as it has finished line N-1), the contents of R will be inserted in the input stream. Thus if R is a macro it will be executed; if R simply contains text, the text will be formatted and will appear beginning on the line in question. TF always uses the current value of the register R; thus if R is redefined between the time the trap is set and the time the trap goes off, TF will use the newest definition. If R does not exist at the time the trap goes off, no action will be taken.

If more than one trap is specified for a particular line, the traps will be executed in the order in which they were set. If a trap is sprung in the middle of a table (that began with ".tt"), or a footnote, or blank space created with ".sp" (e.g. ".sp 6), or multiple spacing (e.g. triple spacing with ".ls 3"), the trap is placed on a list of "pending" traps and will be executed as soon as the table, footnote, or blank space is finished.

The line number N can be negative. In this case, it is taken as an offset above the bottom of the page (i.e. above the squeeze margin).

The ".nt" request returns the line number of the next trap on the page. Most users will find it convenient to use this in the "^(nt)" form. For example,

.if ^(nt)-1=^(#) ...

checks to see if the current line number (#) is the one before the next trap. If there are no traps set for the remainder of the current page, ".nt" returns a -1.

Traps are set for a particular line number. If a trap is set when the output on the current page has already passed that line number, the trap will not go off until the next page. If a trap sets a trap, the new trap will not go off until the next time the appropriate line number is reached. If a trap is set for a line number that does not exist on the page (i.e. the page length is too short), the trap will never go off. Heading and footing lines do not spring traps.

There are two ways to turn off a trap once it has been set. The request

.td N

turns off all traps that were set for line N. The request

.te 0

disables all trap processing. In other words, any traps that are set will not go off; they are simply ignored. To enable trap processing again, use

.te 1

There are still a few problems with trapping in the current version of TF. If setting off a trap creates more than a page of output, the trap will be sprung when the output reaches the specified line on the next page and presumably another page of output will be generated. This process will eventually lead to the error "input nesting level too deep". Another problem is that TF currently makes no distinction between trapping line 0 and trapping line 1. Lastly, the register given to ".tp" must be a true register, not a built-in TF request. If the name given is a TF request, a warning will be issued and the trap will be ignored.

In the current version of TF, the ".ne" request does not pay attention to traps. Therefore if ".ne" causes a page break because there isn't enough space left on the current page, any traps that remain for the current page will NOT be sprung.

Source Switching

The TF command accepts only one input file. However, if that input file contains a request of the form

.so filename

TF will attempt to access the specified file. If this is possible, TF will switch to taking its input from this second file; when it reaches the end of this second file, it will return to the first file and resume collection of input with the line immediately following the ".so". Files that appear in an ".so" request may themselves contain ".so" requests. Such source file requests may be nested almost indefinitely, even recursively.

A file named in an ".so" request may be temporary or permanent. Accessing files follows the standard conventions.

Files accessed by ".so" will be removed from the AFT once they have been used, unless they were in the AFT before TF began processing (e.g. temporary files).

Notes

Notes that are not part of the actual body of the document may be specified with the "note" request. This has the form

.no <note>

where <note> is the desired note, e.g.

.no This is just a comment.

The note will be placed to the right of the right margin in the output. The distance between the margin and the notes is set to one space by default; to change this, type

.nd N

where N is the number of spaces that should separate the two.

Notes that are too long to fit on the paper will be folded. The default paper width is 120 characters; this can be changed to N characters with the request

.pw N

Debugging Features

The command

.uf

causes TF to underline the first character of each line of input. This helps to show what happens to input lines as they are filled out for output. To turn off this feature, specify

.nu

The request

.pr E

causes TF to print the names of all requests it executes. These are printed beginning in column E; however, if the result of E is less than the current line length, the requests are NOT printed.

.pr 0

turns off this feature.

The request

.ps E

prints sequence numbers beginning in column E. These sequence numbers indicate line numbers in the file that is currently being read. E must be greater than the current line length and less than the column set for ".pr". The sequence numbers given refer to the input line that contained the last word on the output line. The request

.ps 0

turns off this feature.

Preparing Output for Special Terminals

TF includes several features designed to facilitate the preparation of output that will be printed on terminals with special capabilities. The majority of users probably will not be concerned with such features and therefore may want to skip this section.

When preparing output for terminals capable of proportional spacing, the user must first define the size of each output character. This is done with the ".dc" (Define Character) request. The simplest form of this request is

.dc C N

where C is a character and N is a number giving the width of the character in centipoints. (A centipoint is a small unit of width; 720 centipoints equal one "m", the standard width of a character, 1/10th of an inch.) To indicate that the width is given in centipoints, the letter "p" should immediately follow the number. For example,

.dc a 640p

tells TF that a lower case "a" has a width of 640 centipoints on the device for which the output is being prepared. The character whose width is being declared may be enclosed in quote characters; for example,

.qc '
.dc ' ' 250p

declares the size of a blank character to be 250 centipoints.

The second form of ".dc" allows you to associate an arbitrary length string with a single ASCII character whose octal value is in the range from 240 to 777 inclusive. In the examples that follow, we will use the notation "\nnn" to denote the ASCII character whose octal value is "nnn". This is how you would enter such a character if you were using the FRED text editor to prepare your TF input file.

The general form for associating an ASCII character with a string is

.dc \nnn N 'string'

where "\nnn" is the ASCII character, 'string' is the string being associated with the character, and N the width that should be allowed for 'string', measured in centipoints. For example,

.dc \240 0p '\033[7m'

associates the string '\033[7m' with the single ASCII character \240. This is the sort of string that might be used to set terminal characteristics for a terminal satisfying the current ANSI standards. Since the string performs no real output, the output width given is zero. From this point onward, the character \240 will be replaced in the output by the given string, much as ".tr" causes one character to be replaced by another.

When preparing output for devices with proportional spacing, it is often useful to be able to specify escape sequences which can be used to obtain padding of different sizes. Suppose, for example, that a given escape sequence creates padding that is 250 centipoints wide. Then

.dc \241 250p 'escape sequence'
.db \241

assigns the escape sequence to the single ASCII character \241 and then uses the ".db" (Define Blank) request to inform TF that the given sequence may be transmitted to obtain 250 centipoints of padding. TF allows up to 140 pad strings to be defined. This permits the user to define pad strings of varying lengths so that TF may generate appropriate widths of padding.

As a final note on proportional spacing, it is often convenient to use centipoints as units of width for more than just characters. For example, one may wish to specify an indentation in centipoints. The following requests will accept numerical arguments given in centipoints.

.in     .ll     .nd     .ps     .ta
.po     .ti     .dc     .pr

Note that centipoint measures must always be suffixed by a "p", e.g.

.in 4000p

If the "p" does not appear, TF assumes that the width is given in "standard" character widths or "m" units (1 m is 720 centipoints, 1/10th of an inch).

If for some reason TF cannot pad to exactly the correct centipoint value (e.g. it has not been given sufficiently small pad characters), it will choose a smaller padding value as close to the correct value as possible.

Many terminals support different fonts in their printing. For example, there may be an escape sequence that automatically causes the terminal to bold face or underline its display. There are a number of requests that allow TF to make use of such capabilities when bold facing or underlining (instead of resorting to its usual technique of back-spacing and overstriking or underscoring).

The "Terminal bold Face" request

.tf \nnn

indicates that the given ASCII character has already been associated (via ".dc") with an escape sequence that causes the output device to bold face. For example,

.dc \300 0p '\033[1m'
.tf \300

might be used for ANSI standard terminals like the Ann Arbor Ambassador. When TF encounters the ".bf" request to put output in bold face, it will use the given escape sequence to put the terminal into bold face mode. Similarly,

.tu \nnn

indicates that the given ASCII character is associated with an escape sequence that causes the output device to underline.

.tl \nnn

indicates that the given ASCII character is associated with an escape sequence that causes the output device to underline and bold face.

.tn \nnn

indicates that the given ASCII character is associated with an escape sequence that causes the output device to return to its normal output state.

All four of ".tf", ".tl", ".tu", and ".tn" must be specified in order for TF to use the escape sequences for any one of them.

The most convenient way to use TF's special terminal capabilities is to prepare a number of source files, each of which contains requests that describe a particular terminal. For example, suppose that file "/a" contains ".dc" and other requests pertinent to terminal type A, while file "/b" contains similar requests pertaining to terminal type B. Suppose further that file "/in" contains general TF input that does not contain any special terminal-handling requests. Then the command line

tf /a /in >outa

prepares output for terminal A while

tf /b /in >outb

prepares output for terminal B. If the actual input does not contain terminal-specific requests, it is an easy task to prepare output for different terminal types simply by starting things off with a standardized terminal description file.

Miscellaneous Requests

.cs C
This sets a case escape character. This is used in connection with the ".uc" and ".lc" requests.
.lc
This tells TF to lower case all alphabetic characters in the text lines that follow the request. TF will put all letters into lower case except those preceded by the case escape character set by ".cs". Letters preceded by the case escape character will be output in upper case. This is useful when typing input from a single case terminal.
.uc
This tells TF to upper case all alphabetic characters in the text lines that follow the request. TF will put all letters into upper case except those preceded by the case escape character set by ".cs". Letters preceded by the case escape character will be output in lower case.
.nc
This tells TF to stop converting the case of alphabetic characters. In other words, it marks the end of the effect of a previous ".lc" or ".uc".
.np N
This instructs TF not to print any output for the next N pages. Formatting continues, but nothing is written into the output file.
.ns N
This tells TF not to fill the first N characters of the next input line. This is one way to ensure that certain character strings are not broken up due to the filling action.
.sk E
This evaluates E and tells TF to set the page number to this result the next time a page break occurs. ".sk" is similar to ".pa E", but ".sk" doesn't cause a page break.
.st
When TF is sending output to a terminal, it will pause when an ".st" is encountered. To have the output continue, the user should type a carriage return.
.sy COMM
The ".sy" request sends everything that follows it as a command to TSS, e.g.
.sy echo "I am starting Chapter 2."
.ze COMMENT
The ".ze" command sends everything that follows it as a message to the STDERR output unit. (STDERR is the output unit where TF prints its error and warning messages. Under TSS, this is the terminal; in batch, it is the execution report.)
 
.ze I am starting Chapter 2.

has the same effect as the previous ".sy" command, but will execute much more quickly.

.zz COMMENT
The ".zz" request simply causes the rest of the request line to be ignored. Thus ".zz" can be used to include comments in your TF input, e.g.
.zz The calling sequence for the next macro is
.zz     .macro A B
.zz where A is an integer and B is ...
   ... and so on ...
.at (macro)
   ... macro definition ...
.en (macro)
.ff N
Normally, a form feed on the line printer positions the output at the third line of the page. TF can compensate for this by deleting lines from "m1" in output pages that begin with form feeds. The ".ff" request allows you to set TF's correction factor by specifying that a form feed leaves the printer page at line N. Since TF is designed to handle output to the line printer properly, ".ff" is only necessary when using some other printing device.

The TF Library:

A number of useful source files are stored in the TF library. These can be accessed by putting a

.so file

in the input file. For more details, see "expl tf lib".

Historical Features:

The following items are part of the current version of TF for compatibility with TF's predecessor, ROFF. They may be deleted in future versions of TF and therefore should not be used in new TF source files.

.ar
is equivalent to ".af % 1".
.ro
is equivalent to ".af % i".
.ds
is equivalent to ".ls 2".
.ss
is equivalent to ".ls 1".
.pn
is equivalent to ".np 0".
.n0
is equivalent to ".ln 0".
.n1
is equivalent to ".ln 1".
.n2
is equivalent to ".ln 2".
.ix
is equivalent to ".di".
.nx
is equivalent to ".dn".

Acknowledgements:

TF is based on the ROFF text formatter created by Bell Laboratories. TF was written by J.C.Winterton with the assistance of P.J.Fraser, W.C.W.Ince, and other interested parties.

APPENDIX A: Summary of TF Requests

In the descriptions that follow, R signifies a valid register name (optionally enclosed in parentheses), C signifies a character, T indicates a heading or footing line, L is an end label (either null or having the form of a register name), N represents an unsigned integer, and E is a valid numeric expression.

REQUEST LINE  DEFAULT        MEANING
        BREAK
.ab      yes          abort TF processing
.af R F   no    F=1   assign format to register R,
                      F=i,I,a,A,o,O,z1,zz1,1,01,...
.an R E   no    E=1   assign number to register R, R=/%
.at R     no          assign text to register R until .en R
.bf N     no     1    next N lines set in boldface
.bp      yes          begin page
.br      yes          break
.cc C     no    C=.   control character is C
.ce N    yes          center next N text lines, break on
                      each
.cl N     no          close diversion file N
.cs C     no          set the case escape character to C
.db C     no          informs TF that C may be used as a
                      padding character for proportional
                      spacing output
.dc C N S no          gives the width of character C in
                      proportional spacing output; if a
                      string S is given, C in input is
                      replaced by S in output
                      if end of footnote
.ep      yes          begin an even page
.fa N P   no          attach (open) file with pathname P
                      for diversion file N
.ff N     no    N=2   set line number of top of form
.fi      yes    yes   fill output lines
.fn L     no          divert text to footnotes until .en L
.fo N T   no  T=''''  Nth even/odd foot titles are T,
                      1<=N<=10
.fs T     no  T=''''  footnote separator is T
.hc C     no          hyphenation character is C
.he N T   no  T=''''  Nth even/odd head titles are T,
                      1<=N<=10
.hy N     no    N=3   hyphenation mode is N, 0<=n<=3
.ib C     no          converts C to a blank on input
.ic C     no          insertion character is C
.id R L   no          if R is defined, include following
                      lines; else ignore to .en L
.if E L   no          if E is non-zero, include following
                      lines; else ignore to .en L
.ig L     no          ignore all input until .en L
.in E     no    E=0   indent left margin E spaces
.ju      yes    yes   justify right margin of filled lines
.lc       no          lower case all following input
.ll E     no   E=60   line length is E including indent
.ln E     no          control line-numbering of output
.ls E    yes    E=1   line spacing is E
.lv N     no          leave N consecutive blank lines; wait
                      until next page if necessary
.m1 E     no    E=4   margin above head 1 is E lines
.m2 E     no    E=2   margin below and including heads is E
.m3 E     no    E=1   margin above and including feet is E
.m4 E     no    E=4   margin below foot 1 is E lines
.mg N     no   empty  next line sets merge pattern N,
                      1<=N<=10
.nc       no          cancel ".lc" or ".uc"
.nd N     no    N=1   distance between right margin and
                      notes
.ne N     no          need room for N output lines with
                      present spacing, do .bp if necessary
.nf      yes    no    nofill, break on each input line
.nj      yes    no    no right margin justification
.no       no          rest of line is note
.np N     no    no    no printing of output for next N pages
.ns N     no          first N characters of next line are
                      not filled
.nt       no    -1    returns line number of next trap on
                      page
.nu       no    yes   no first character underlining
.of N T   no  T=''''  Nth odd page foot title is T,
                      1<=N<=10
.oh N T   no  T=''''  Nth odd page head title is T,
                      1<=N<=10
.op      yes          begin an odd page
.pa E    yes    E=1   begin page with page number E
.pc C     no          parameter character is C
.pl E    yes   E=66   paper length is E lines
.po E     no    E=0   page offset is E, i.e. move all output
                      E spaces right
.pr E     no    E=0   print requests indented E, don't print
                      if E <= line length
.ps E     no    E=0   print sequence numbers of input lines
                      indented E (E for .pr > E for .ps)
.pw       no   120    set paper width
.qc       no          quote character for macro arg
                      delimiter
.sa R     no          save current value of R on stack
.sk E     no          skip at next new page to page number E
.sl n     no          control formfeeds
                      pathname P
.sp N    yes          insert N extra spacing lines
.sq      yes          squeeze line onto current page
.st      yes          pause now
.sy COMM  no          execute TSS system command COMM
.ta       no    all   tabs set by this line or next
.tb       no      1   table break: if non-zero, hold as many
                      tables as possible
.tc C     no          extra tab character is C
.td N     no          delete all traps for line N
.te N     no    N=1   N=0 disables trap processing; N=1
                      enables trap processing
.tf C     no          C corresponds to escape sequence for
                      bold facing on output device
.ti E N  yes          temporary indent, for one line only
                      second argument functions as .ns
                      request
.tl C     no          C corresponds to escape sequence for
                      underlining and bold facing on output
                      device
.tn C     no          C corresponds to escape sequence for
                      normal display on output device
.tp N R   no          when line N is reached, trap goes off
                      and executes register R
.tr CD... no          translate C into D on output
.tt L    yes          divert text to table until .en L
.tu C     no          C corresponds to escape sequence for
                      underlining on output device
.uc       no          upper case all following input
.uf       no    no    underline first character of each
                      input text line
.ul N     no          underline alphanumerics in next N
                      input text lines
.ze MSG   no          send message MSG to STDERR
.zt R     no          restore most recently saved value
                      for R
.zz COMMENT           line contains a comment; ignore it

The following principles hold when arguments are omitted. When an N or E field is omitted, a value of 1 is used. When a T field is omitted, an empty title is used. Omitting the C field for ".cc", ".hc", ".ic", ".pc", ".cs", ".qc", or ".tc", turns off the special meaning of any character previously given in such a request.

The current version of TF supports the following obsolete requests:

 .ar  .ds  .ix  .n0  .n1  .n2  .nx  .pn  .ro  .ss

All of these have been superseded by new requests, and thereforemay be deleted in future versions of TF.