HomeQuestions?


Producing an Operating System Book: Scribe and troff


James Peterson
Department of Computer Sciences
The University of Texas at Austin
20 July 1983

Introduction

This report describes the chronology of the writing of the book, Operating Systems Concepts, by J. Peterson and A. Silberschatz. I am writing it to try to record the steps that were involved, should anyone want to follow this path again.

As an overview, the book was started in the Fall of 1981. The basic idea had been kicking around for several years, but I had never gotten the energy to actually do it. Avi provided the energy and motivation to start. The gross table of contents was pretty easy to finish, and we each wrote a sample chapter. I wrote Chapter 5 on memory management, and Avi wrote Chapter 10 (which became Chapter 9) on Concurrent Processes.

The sample chapters, plus the table of contents and vitae, were sent to about 15 publishers in late February, 1982. We had an excellent response, with a great deal of interest in the manuscript. After repeated negotiations, we eventually settled with Addison-Wesley, signing on 10 May 1982. Other serious contenders were Computer Science Press, John Wiley & Sons, and Prentice-Hall.

Writing the Book

With the contract negotiations out of our way, we set down to actually write. All during the summer, I wrote. Starting with Chapter 1, and working my way through, chapter after chapter. By the end of the summer, we had only about half of the book finished.

The final content of the book was not finished until December 1982, and even into January 1982. Most of our time in January and February was spent in production and page make-up. The book was finally sent to Addison-Wesley on 16 February 1983.

The book was written by two authors: Peterson and Silberschatz. I wrote most of Chapters 1 to 7, 12 and 14. Avi wrote 8 to 11, and 13. The procedure was to write the text longhand. Carol then typed it into Scribe format. Drafts were produced on the lineprinter and revised by the author until he was satisfied. Then this draft was turned over to the other author who read it for content, presentation, and form. A period of revision then followed until we were both satisfied with the chapter.

During the creation of one chapter, we sometimes found that we wanted to change some other chapter, or reorder the chapters in the book. Content flowed back and forth between Chapter 2 and Chapter 3 and Chapter 7; Chapters 10 and 12 were switched; a new chapter (Chapter 14) was added when we tried to make the bibliography. We argued over the general structure of a chapter: should the bibliographic notes come before or after the exercises? For a significant period of time (from October to January), while Addison-Wesley wanted a table of contents to show its salespeople, we were changing the table of contents every other week (at least).

Most of these changes were possible because we were using a computer-based technology. With the text editors and formatters, it was quite easy to reorder the text and print a new copy. There were problems because of this, such as Addison-Wesley wanting a firm copy of the changing table of contents. Also, the reviews were often out-dated by the time we got them, since they were based on a version of the book that was prehaps a month old. On the other hand, the flexibility, in my opinion, produced a better book. As late as February, I made some major changes in the order of material in Chapter 4; changes which improved the overall flow of the material, making it easier to read.

Production

The initial writing and formatting of the book was done on a DEC-20 using Scribe, a formatting language. The text was entered from a keyboard from a hand-written draft. As it was typed in, commands were added indicating headings, figures, and so on. These commands are indicated by an at-sign (@) followed by a command name. For example, @b[troff] would print the word "troff" in bold face (troff); @section[Production] defines a section with a title "Production". A separate file (.mak) defines how a section should be formatted (amount of space before and after, typeface, size, numbering, and so on). Scribe can take a document and a document definition and produce output for many different output devices.

Scribe provided a good basis for producing the needed drafts of the book. Elaine Rich, who was also doing a book using Scribe (for McGraw-Hill), gave us a copy of her Scribe book document definition. She had got the definition from Jon Bentley who had used it for his book on Writing Efficient Programs (with Prentice-Hall). The definition was mainly set up for the Dover printer (a high quality Xerox printer). Output could also be produced on a line-printer using the report format. Avi persuaded Jeff Ullman, at Stanford, to give us an account on the Score machine with access to their Dover. We printed 3 complete copies on the Dover at various stages of the writing and had these mailed back to us. These helped us see what the book would eventually look like.

Around Thanksgiving, the Department got an Imagen printer and Scribe support for it. While the Imagen lacks the resolution and font selection of the Dover, it is a good approximation, allowing multi-font and multi-size output characters. This was almost perfect timing since the Stanford Score machine went away at about this time (it was turned off to be replaced by a bigger computer but was down for several weeks as a result).

With the arrival of the Imagen, we started to look at the problem of book design. Addison-Wesley provided us with the basic page layout. Feeling that we needed to know more than this, I looked back at the book designs that had been done by Academic Press and Prentice-Hall for my earlier books and derived a list of design questions. A lengthy phone call to Addison-Wesley settled most of these questions.

The book design was then used to completely revise the Scribe document definition to implement the book design. Parts of the design could only be approximated in Scribe, especially those parts which would require buffering (like centering each program section as a whole). The resulting Scribe document definition is shown is Appendix I.

This Scribe document allowed us to generate Imagen copies which looked almost exactly like the final product. We could see what the book would look like. To finish the production process, however, we needed to get the book typeset. While the draft output allowed us to work on the content and basic form of the book, it was not good enough for the final copy. Our only typesetting facility was on a Unix system. I had used troff for my Petri net book. Thus, we decided to translate our Scribe into troff and use troff to drive the phototypesetter.

troff is a different formatting program, using the same idea (text with embedded formatting commands), but an entirely different syntax and set of commands. A troff command is indicated by a period in column one followed by a two character command name. One important advantage of troff however is that a user can define his own commands (called macros). Thus, we could translate a Scribe command like @section[Production] into a troff macro command like .H1 "Production", and then write a macro to define H1 to act just like a Scribe section heading (or rather, in our case, just like our document design wanted a section heading).

The conversion from Scribe to troff could have been done by a special translation program. However, after talking to Brian Reid at ACM in Dallas, I decided to try to get Scribe to translate its input into troff. This required defining a troff logical device (troff.dev) and a new document type (troff.mak) (See Appendix II). Bugs in the Scribe system prevented me from doing it completely or correctly, but I could get close enough that two post-processing programs and use of the editor would do it.

The basic strategy was to redefine each Scribe command to generate, not the final formatted text, but simply a troff macro call. There were two major difficulties. First, I could not get Scribe to generate line breaks where needed. Remember that troff commands are indicated by a period in column 1. Thus, when I wanted to output a command, I had to go to a new line. Also, for many troff commands I want to go to a new line after the command. Scribe both would not go to the next line when desired and would go to a new line when it was not desired. To correct this, I used the vertical bar to indicate where a line break was needed. A post-processing program then replaced the vertical bar by a line break, and deleted multiple sequential line breaks. An exclamation mark was similar to a vertical bar, but signalled that a verbatim format was being entered, and multiple sequential line breaks should not be deleted, but simply copied.

The other problem with Scribe was with text components with subcomponents, such as a list. Lists should generate first a list begin (.xB), then a sequence of list items (.xI), and finally a list end (.xE). Scribe for some reason, would generate the first .xI command before the .xB. It also would generate two or three paragraph commands (.PP) rather than just one, and so on. A post-processing program was written which would look for two commands in a row and could interchange them, delete the first, delete the second, or leave them alone. A table of the sequencing problems was generated, and used to drive this program.

A final problem with Scribe was that it would create a line break at inappropriate places. It appeared that it would break after a word and before parentheses, periods, commas, and other punctuation at times. These were corrected by hand, although not always successfully.

The Scribe translation produced a troff file which assumed a set of macros implementing the book design. The macros are given in Appendix III. These macros were based upon a similar set written for my Petri net book. Each chapter was translated and post-processed. Then it was ftp-ed across the Arpa-net to a PDP-11/70 (the NGP). Here we ran it through troff to get device-independent output (dvi form). I wrote a program to take dvi input and produce a line-printer approximation of the typesetter output, with vertical spacing (especially) indicated. This allowed us to determine where page breaks were occurring.

Page make-up required checking for widows and orphans, placing figures in the right places and adjusting the length of facing pages to be the same length. This process took several weeks in January and February. Finally, we could ship the resulting files from the NGP to the TSP system with its phototypesetter. It took about 10 days to typeset the book. About 20% of the book had to be typeset twice, to correct errors.

We have reset 53 pages (about 10% of the book) to correct errors for the second printing. Of these 53 pages, only 6 of them are a result of problems with the typesetting process. Generally, these were places where Scribe split an end-of-sentence period onto a new line where troff assumed it to be a command. Most of the remaining errors were incorrect capitalization, wrong use of a or an, small misspellings (if instead of of or is) or verb-noun number disagreement. About 10 of the changed pages were the result of content changes.

Costs

The costs resulting from our book production were:

Copy Editor $ 633.18
Secretary 6,514.00
Phototypesetting 1,028.93
Mailing 256.79
Reduction Copies 15.07
Computer Costs 6,335.17
---------
Total14,783.14

It is not clear how this would compare with a more traditional production process, both in terms of costs to the authors, or in terms of overall costs of production (author and publisher). Normally the copy editting and photo-typesetting costs would be borne by the publisher, and I suspect that half of the computer costs were related to the page make-up and typesetting process. Thus our costs for doing the page proofs directly, rather than leaving that to the publisher were probably about $5K. (It should be pointed out that these costs were most likely heavily subsidized by the University and would be much larger if done commercially.)

Scribe Book Definition
@Marker(Make,aw,imprint10,impress) @fontfamily[book]

@comment{ Define basic physical properties of pages } @Style(
LeftMargin 0.75 inches,
linewidth 28 picas,
TopMargin 1.125 inches,
BottomMargin 2.875 inches,
WidowAction force,
DoubleSided,
bindingmargin 0 picas)

@comment{ Define basic text body format } @define(bodystyle,
font bodyfont,
facecode r,
size 10,
spacing 12 points,
indent 18 points,
spread 0,
Hyphenation on,
Justification,
Spaces Compact)

@comment{ define format for table of contents } @Enable(Contents) @Send(Contents "@set(page=0)
@Style(PageNumber<@i>)
@NewPage
@unnumberedchapter(Contents)")

@comment{ headings } @Define(HDX,
LeftMargin 0,
Indent 0,
Fill,
Spaces compact,
Justification Off,
Hyphenation Off,
above 0,
below 0,
Break around,
continue force)

@Define(hdChap,Use HdX,
Font TitleFont5, FaceCode B,
size 20,
Spacing 0 points,
Capitalized,
FlushRight,
PageBreak untilodd,
break around,
continue force)

@define(sink14picas,sink 2.958 inches, break around)

@Define(HdA,Use HdX,
Font TitleFont4, FaceCode B,
size 14,
Spacing 12 points,
Above 18 points,
Below 6 points,
break around,
continue force)

@Define(HdB,Use HdX,
Font TitleFont3,FaceCode B,
Size 12,
Spacing 12 points,
Above 12 points,
Below 6 points,
break around,
continue force)

@Define(HdC,Use HdX,
Font TitleFont2,FaceCode B,
size 10,
Spacing 12 points,
above 12 points,
break around,
continue force)

@Define(TcX,
leftmargin 6 picas,
RightMargin 5 picas,
Fill, Spaces compact,
indent -6 picas,
Above 0,
Below 0,
size 10,
Spacing 12 points,
Spread 0,
Justification off,
Hyphenation Off,
Break)

@Define(Tc0=TcX,
Font TitleFont3, FaceCode R,
Need 4 lines,
size 9)

@Define(Tc1=TcX,
Font TitleFont2, FaceCode B,
Above 12 points,
size 10,
Below 12 points,
Need 4 lines,
spacing 12 points)

@Define(Tc2=TcX,
Font TitleFont2,FaceCode R,
size 10,
spacing 12 points)

@modify(hdg, fixed .625 inches) @define[runninghead,
font smallbodyfont, facecode B,
size 9,
spacing 0,
spaces compact,
justification off,
hyphenation off,
continue,
break around]

@comment{ Chapter, Section, Subsection, and Subsubsection headings }

@Counter(Chapter,
Numbered [@1],
Referenced [@1],
IncrementedBy Use,
Announced,

TitleForm{@begin(HdChap)

@PageHeading(immediate)
@PageFooting(immediate)

@PageHeading(even,
left= "@runninghead[@value<page>@~
@hsp(2 em)@~
Chapter @parm(numbered)@~
@hsp(2 em)@~
@parm(title)@~
]")
@PageHeading(odd,
right="@runninghead[@>Section @ref(section)@~
@hsp(1 em)@~
@title(section)@~
@hsp(2 em)@~
@value(page)
]")

@pagefooting()
@tabclear()@~
@blankspace(2 picas)@~
@Parm(Numbered)@~
@blankspace(2 picas)@~
@parm(Title)@~
@sink14picas()@~
@end(HdChap)},

ContentsForm{@begin(Tc1)
Chapter @parm(Referenced)@~
@hsp(1 em)@~
@parm(Title)@~
@rfstr(@parm(page))
@end(Tc1)} )

@Counter(Section,
Within Chapter,
Numbered [@#@:.@1],
Referenced [@#@:.@1],
IncrementedBy Use,
Announced,

Titleform{@begin[HdA]
@parm[numbered]@~
@hsp[1 en]@~
@parm[title]@~
@end[HdA]}, Contentsform{@begin(Tc2)
@parm(Referenced)@~
@hsp(1 em)@~
@parm(Title)@~
@rfstr(@parm(page))
@end(Tc2)} )

@Counter(SubSection,
Within Section,
Numbered [@#@:.@1],
IncrementedBy Use,
Referenced [@#@:.@1],

Titleform{@begin[HdB]
@parm[numbered]@~
@hsp[1 en]@~
@parm[title]@~
@end[HdB]} )

@Counter(Subsubsection,
Within SubSection,
IncrementedBy Use,

Titleform{@begin[HdC]
@parm[title]@~
@end[HdC]} ) @equate(paragraph=subsubsection)

@Counter(UnnumberedChapter,
numbered [],
referenced [],
Announced,

TitleForm{@begin(HdChap)

@PageHeading(immediate)
@PageFooting(immediate)

@PageHeading(even,
left= "@runninghead[@value<page>@~
@hsp(2 em)@~
@parm(title)@~
]")
@PageHeading(odd,
right="@runninghead[@>@title(section)@~
@hsp(2 em)@~
@value(page)@~
]")

@pagefooting()
@tabclear()
@blankspace(2 picas)@~
@blankspace(2 picas)@~
@parm(Title)@~
@sink14picas()@~
@end(HdChap)},

ContentsForm{@begin(Tc1)
@parm(Title)@~
@rfstr(@parm(page))
@end(Tc1)} )


@Counter(UnnumberedSection,
numbered [],
referenced [],
Within Chapter,
Announced,

Titleform{@begin[HdA]
@parm[title]
@end[HdA]},

Contentsform{@begin(Tc2)
@parm(Title)@~
@rfstr(@parm(page))
@end(Tc2)} )

@equate(prefacesection=unnumberedchapter)

@comment{ Lists, numbered and bullet }

@modify(enumerate,
leftmargin +18 points,
rightmargin 0,
above 12 points,
below 12 points,
spread 6 points,
indent -18 points,
justification on,
hyphenation off)

@define(Aenumerate=enumerate,
Numbered <@a. >,
referenced <@a.>,
leftmargin +18 points,
rightmargin 0,
above 12 points,
below 12 points,
spread 6 points,
indent -18 points,
justification on,
hyphenation off)

@define(1enumerate=enumerate,
Numbered <@1. >,
referenced <@1.>,
leftmargin +18 points,
rightmargin 0,
above 12 points,
below 12 points,
spread 6 points,
indent -18 points,
justification on,
hyphenation off)

@modify(itemize,
leftmargin +18 points,
rightmargin 0,
above 12 points,
below 12 points,
spread 6 points,
indent -18 points,
justification on,
hyphenation off)

@modify(programexample,
facecode R,
above 12 points,
below 12 points,
free,
justification off,
hyphenation off)

@modify(display, centered)

@Counter(FigureCounter, Table "FigureContents",
Within Chapter,
Numbered <Figure@@ @#@:.@1:@@ @@ >,
Referenced "@#@:.@1",
ContentsForm {})

@Define(Figure,Nofill,Spaces Kept,Use R,BlankLines kept,Float,
Above 1,Below 1,
Counter FigureCounter,
NumberLocation LFL)

@Define(FullPageFigure,Use Figure,FloatPage) @Define(CaptionEnv=Center,FaceCode R,Spacing 1) @equate(space=blankspace)

@define(references,
above 12 points,
below 12 points,
spread 6 points,
blanklines break,
break around,
continue off,
unnumbered,
leftmargin +18 points,
indent -18 points,
justification on)

@define (exercises,
above 12 points,
below 12 points,
spread 6 points,
blanklines break,
break around,
continue off,
leftmargin 24 points,
rightmargin 0,
indent -24 points,
within chapter,
numbered <@#@:.@1 >,
numberlocation LFL,
justification on,
hyphenation off)

@comment{ Begin text environment }

@style(pagenumber="@1") @Set(Page=1) @begin(Text,
Use bodystyle)

@PageHeading(Even) @PageHeading(Odd)

Scribe to troff Translation troff.dev file
@Marker(Device,Troff) @Comment{ Convert Scribe to Troff }

@Declare(GenericDevice="troff",
DeviceTitle="Troff Translation File",
FinalName="#.trf")

@Declare(Driver LPT,
Hunits inch,
Hraster 10,
Vunits inch,
Vraster 6)

@Declare(Backspace no,BareCR no,BareLF no) @Declare(PaperLength 200,Paperwidth 254,Scriptpush yes) @Declare(LeftMargin 0,TopMargin 0,BottomMargin 0,LineWidth 254) @Declare(Paged False)

@DefineFont(CharDef,R=<RawFont "ALL">) @DefineFont(UserFont)

@Define(R, TabExport, afterentry [\fR], beforeexit [\fP]) @define(B, TabExport, afterentry [\fB], beforeexit [\fP]) @define(I, TabExport, afterentry [\fI], beforeexit [\fP])

@Define(C,Capitalized,TabExport) @Define(W,HyphenBreak off,Hyphenation Off,Spaces NoBreak,TabExport)

@Equate(G=noop) @Equate(Z=noop) @Equate(A=noop)

@Define(Plus,Hyphenation Off,HyphenBreak Off,
afterentry [\s-2\u], beforeexit [\d\s+2],TabExport) @Define(Minus,Hyphenation Off, Hyphenbreak off,
afterentry [\s-2\d], beforeexit [\u\s+2], TabExport)

@Define(F0, TabExport, afterentry [\f0], beforeexit [\fP]) @Define(F1, TabExport, afterentry [\f1], beforeexit [\fP]) @Define(F2, TabExport, afterentry [\f2], beforeexit [\fP]) @Define(F3, TabExport, afterentry [\f3], beforeexit [\fP]) @Define(F4, TabExport, afterentry [\f4], beforeexit [\fP]) @Define(F5, TabExport, afterentry [\f5], beforeexit [\fP]) @Define(F6, TabExport, afterentry [\f6], beforeexit [\fP]) @Define(F7, TabExport, afterentry [\f7], beforeexit [\fP]) @Define(F8, TabExport, afterentry [\f8], beforeexit [\fP]) @Define(F9, TabExport, afterentry [\f9], beforeexit [\fP])

@Counter(Page,Numbered <@1>,Referenced <@1>,Init 1) @Define(Hdg,Fixed 0,Nofill,
HyphenBreak off, Hyphenation off,
LeftMargin 0,RightMargin 0,
Spread 0,Spacing 1,
Columns 1,ColumnMargin 0,
UnNumbered,Underline off,
Indent 0,Initialize "@TabClear()",
Invisible) @Define(Ftg=Hdg,Fixed 45)

@Define(Text,
facecode R,
spacing 0,
above 0,
below 0,
leftmargin 0,
rightmargin 0,
justification off,
hyphenation off,
hyphenbreak off,
blanklines kept,
break around,
continue off,
indent 0,
spread 1,
numbered <|.PA|>,
numberlocation LFL )

@Define(Multiple,Indent 0,SpecialCase OpenBefore) @Define(Transparent) @Define(Group,Break) @Define(Float,Break,Continue) @Define(Bspace,Break,
Above 0,Below 0,
Group,Nofill,
LeftMargin 0,RightMargin 0) @Define(Bpage,Break,Continue) @Define(Pspace,Break,
Above 0,Below 0,
Group,Nofill,
LeftMargin 0,RightMargin 0)

@newpage[]
troff.mak file
@Marker(Make,troff,troff)

@comment{ Define basic text body format } @define(bodystyle,
break,continue,
justification off,
hyphenation off,
hyphenbreak off,
blanklines kept,
above 0,
below 0,
font chardef,
facecode R,
indent 0,
leftmargin 0,
rightmargin 184,
spacing 0,
spread 1,
numbered [|.PP|],
numberlocation LFL )

@modify (multiple, numbered [|.PP|], numberlocation LFL)

@Define(Center,AfterEntry [|.CB|], afterexit [|.CE|@*],
nofill,leftmargin 0,rightmargin -184,
BlankLines kept)

@Define(Flushright,AfterEntry [|.RB|], afterexit [|.RE|@*],
nofill,leftmargin 0,rightmargin -184,
BlankLines kept)

@Define(Flushleft,AfterEntry [|.LB|], afterexit [|.LE|@*],
nofill,leftmargin 0,rightmargin -184,
BlankLines kept)

@Define(Description, AfterEntry [|.DB|], afterexit [|.DE|@*],
break,continue) @Define(Display, afterentry [|.YB!], afterexit [!.YE|@*],
nofill,leftmargin 0,rightmargin -184,
break,continue)

@Define(Example, afterentry [|.EB!], afterexit [!.EE|@*],
nofill,leftmargin 0,rightmargin -184,
break,continue) @Define(ProgramExample, afterentry [|.PB!], afterexit [!.PE|@*],
nofill,leftmargin 0,rightmargin -184,
break,continue)

@Define(Format, afterentry [|.MB!], afterexit [!.ME|@*],
nofill,leftmargin 0,rightmargin -184,
break,continue) @Define(Quotation, AfterEntry [|.QB|], afterexit [|.QE|@*],
break,continue) @Define(Verbatim, afterentry [|.VB!], afterexit [!.VE|@*],
nofill,leftmargin 0,rightmargin -184,
break,continue) @Define(Verse, AfterEntry [|.SB|], afterexit [|.SE|@*],
blanklines break,
break,continue)

@Define(Heading, AfterEntry [|.HH "], afterexit ["|@*]) @Define(MajorHeading, AfterEntry [|.MH "], afterexit ["|@*]) @Define(SubHeading, AfterEntry [|.SH "], afterexit ["|@*])

@comment{ Chapter, Section, Subsection, and Subsubsection headings }

@Counter(Chapter,
Numbered [@1],
Referenced [@1],
IncrementedBy Use,
Announced,
TitleForm{|.H0 "@parm(numbered)" "@parm(title)" "@value(page)"|@*} )

@Counter(Section,
Within Chapter,
Numbered [@#@:.@1],
Referenced [@#@:.@1],
IncrementedBy Use,
Announced,
TitleForm{|.H1 "@parm(numbered)" "@parm(title)"|@*} )

@Counter(SubSection,
Within Section,
Numbered [@#@:.@1],
IncrementedBy Use,
Referenced [@#@:.@1],
TitleForm{|.H2 "@parm(numbered)" "@parm(title)"|@*} )

@Counter(Subsubsection
Within SubSection,
Numbered [@#@:.@1],
Referenced [@#@:.@1],
IncrementedBy Use,
TitleForm{|.H3 "@parm(numbered)" "@parm(title)"|@*} )

@Counter(UnnumberedChapter,
Announced,
TitleForm{|.U0 "@parm(title)" "@value(page)"|@*} )


@Counter(UnnumberedSection,
Within Chapter,
Announced,
TitleForm{|.U1 "@parm(title)"|@*} )

@equate(prefacesection=unnumberedchapter)

@Define(Itemize, AfterEntry [|.BB|], afterexit [|.BE|@*],
numbered [|.B1|@,|.B2|@,|.B3|],
numberlocation LFL,
BlankLines break,
hyphenation off, hyphenbreak off,
break,continue)

@Define(Enumerate,AfterEntry [|.NB|], afterexit [|.NE|@*],
Numbered [|.N1 "@1."|@,|.N2 "@a."|@,|.N3 "@i."|],
Referenced [@1@,@a@,@i],
Numberlocation LFL,
hyphenation off, hyphenbreak off,
blanklines break,
break,continue)

@Equate(Enumeration=Enumerate,Itemization=Itemize)

@Define(AEnumerate,AfterEntry [|.NB|], afterexit [|.NE|@*],
Numbered [|.N1 "@a."|@,|.N2 "@a."|@,|.N3 "@a."|],
Referenced [@a@,@a@,@a],
Numberlocation LFL,
hyphenation off, hyphenbreak off,
blanklines break,
break,continue)

@Define(1Enumerate,AfterEntry [|.NB|], afterexit [|.NE|@*],
Numbered [|.N1 "@1."|@,|.N2 "@1."|@,|.N3 "@1."|],
Referenced [@1@,@1@,@1],
Numberlocation LFL,
hyphenation off, hyphenbreak off,
blanklines break,
break,continue)

@Define(references,AfterEntry [|.ZB|], afterexit [|.ZE|@*],
numbered [|.ZI|],
numberlocation LFL,
hyphenation off, hyphenbreak off,
BlankLines break,
break,continue)

@Define(Exercises,AfterEntry [|.XB|], afterexit [|.XE|@*],
Within Chapter,
Numbered [|.XI "@#@:.@1"|],
Referenced [@#@:.@1],
Numberlocation LFL,
hyphenation off, hyphenbreak off,
blanklines break,
break,continue)

@Counter(FigureCounter, Table "FigureContents",
Within Chapter,
Numbered [Figure @#@:.@1],
Referenced [@#@:.@1],
TitleForm{.CP "@parm(numbered)" "@parm(title)"},
ContentsForm {})

@Define(Figure, AfterEntry [|.FB|], afterexit [|.FE|@*],
nofill,leftmargin 0,rightmargin -184,
Counter FigureCounter,
NumberLocation LFL,
break)

@Define(FullPageFigure,Use Figure)

@Define(Fnenv, AfterEntry [|.OB|], afterexit [|.OE|@*],
break,continue) @Define(FootSepEnv,Break,SaveBox <FootSep>)

@Style(Notes=Inline)

@define(space, afterentry [@*|.SP ], afterexit [|@*]) @counter(avi, titleform {|'Hd|} )

@comment{ Begin text environment }

@style(pagenumber=[@1]) @Set(Page=1) @begin(Text,
Use bodystyle,
hyphenation off, hyphenbreak off)

troff Macros

troff macro file
HomeComments?