[net.sources] Bib -- a replacement for refer

gary@sri-unix (10/28/82)

The following files are a reference guide for writing macros for the
bib program and a collection of macro packages 
and support files that are used at
Arizona.  The macros only handle the bibliographic aspects and are
intended to be used with some other macro package (me, ms, or your
local favorite).
The support files are explained in the reference guide.

The files must be placed in /usr/lib/bmac as that is where bib expects
them.  The file common should also be placed in this directory.

See other posting for bib source, reference guide, and man pages.

===== refdoc             =====
.de Ex
.sp
.QS
.nf
..
.ce 100
\fBReference File Formats\fP
.ce 0
.sp
.PP
A reference file is simply a file containing any number of reference
items.  Reference items are separated by one or more blank lines.
There are no restrictions placed on the order of items in a file,
although generally users will want to impose some order (such as sorting
items alphabetically) to simplify updates.
.PP
A reference item is simply a collection of field tags and values.
A field tag is a percent sign followed by a single letter.
Currently the following field tags are recognized:
.Ex
.ta 0.5i
A	Author's name
B	Title of book containing item
C	City of publication
D	Date
E	Editor(s) of book containing item
F	Caption
G	Government (NTIS) ordering number
I	Issuer (publisher)
J	Journal name
K	Keys for searching
N	Issue number
O	Other information
P	Page(s) of article
R	Technical report number
S	Series title
T	Title
V	Volume number
W	Where the item can be found locally
.QE
.PP
With the exception of the author field, each field can occur only once
in any reference.  The field information is as long as necessary,
and can extend onto new lines.
Lines that do not begin with a percent sign or a period
are treated as continuations of the previous line.
The order of fields is irrelevant, except that authors
are listed in the order of occurrence.
.PP
Generally a reference will fall into one of several basic categories.
An example of each and a brief comment is given below.  With less
standard references (Archival Sources, Correspondence, Government
Documents, Newspapers) generally some experimentation will be necessary.
.SH
Books
.PP
A book is something with a publisher that isn't a journal article or
a technical report.  Generally books also have authors and titles
and dates of publication (although some don't).  For books not published
by a major publishing house it is also helpful to give a city for the
publisher.  Some government documents also qualify as books, so a book
may have a government ordering number.
.PP
It is conventional that the authors names appear in the reference in
the same form as on the title page of the book.  Note also that
string definitions are provided for most of the major publishing houses
(PRHALL for Prentice-Hall, for example).
.Ex
%A R. E. Griswold
%A J. F. Poage
%A I. P. Polonsky
%T The SNOBOL4 Programming Language
%I PRHALL
%D second edition 1971
.QE
.PP
Sometimes a book (particularly old books) will have no listed publisher.
The reference entry must still have an I field.
.Ex
%A R. Colt Hoare
%T A Tour through the Island of Elba
%I (no listed publisher)
%C London
%D 1814
.QE
.PP
If a reference database contains entries from many people (such
as a departmental-wide database) The W field can be used to indicate
where the referenced item can be found; using the initials of the owner,
for example.
Any entry style can take a W field, since this field is not used in
formating the reference.
.PP
The K field is used to define general subject categories for an entry.
This is useful in locating all entries pertaining to a specific subject
area.
.Ex
%A Dennie Van\e Tassel
%T Program Style, Design, Efficiency,
Debugging and Testing
%I PRHALL
%D 1978
%W tab
%K testing debugging
.QE
.SH
Journal article
.PP
The only requirement for a journal article is that it have a
journal name and a volume number.
Usually journal articles will also have authors, titles, page
numbers, and a date of publication.  They may also have numbers, and,
less frequently, a publisher.  (Generally publishers are only listed for
obscure journals).
.PP
Note that string names (such as CACM for \fICommunications of the ACM\fP
are defined for most major journals.
There are also string names for the months of the year, so that months
can be abbreviated to the first three letters.
Note also in this example the use of the K field to define a short
name (hru) which can be used in searching for the reference.
.Ex
%A M. A. Harrison
%A W. L. Ruzzo
%A J. D. Ullman
%T Protection in Operating Systems
%J CACM
%V 19
%N 8
%P 461-471
%D AUG 1976
%K hru
.QE
.SH
Article in conference proceedings
.PP
An article from a conference is printed as though it were a journal
article and the journal name was the name of the conference.
Note that string names (SOSP) are also defined for the major
conferences (Symposium on Operating System Principles).
.Ex
%A M. Bishop
%A L. Snyder
%T The Transfer of Information and Authority
in a Protection System
%J Proceedings of the 7th SOSP
%P 45-54
%D 1979
.QE
.SH
Article in book
.PP
An article in a book has two titles, the title of the article and the title
of the book.  The first goes into the T field and the second into the B
field.  Similarly the author of the article goes into the A field and the
editor of the book goes into the E field.
.Ex
%A John B. Goodenough
%T A Survey of Program Testing Issues
%B Research Directions in Software Technology
%E Peter Wegner
%I MIT Press
%P 316-340
%D 1979
.QE
.PP
Unlike author fields, which can be repeated, if a work as more than
one editor they are all listed in a single E field.
.Ex
%A R. J. Lipton
%A L. Snyder
%T On Synchronization and Security
%E R. A. DeMillo, D. P. Dobkin, A. K. Jones and R. J. Lipton
%B Foundations of Secure Computation
%P 367-388
%I ACPRESS
%D 1978
.QE
.PP
Sometimes the book is part of a multi-volume series, and hence may
contain a volume field and/or a series name.
.Ex
%A C.A.R. Hoare
%T Procedures and parameters: An axiomatic approach
%B Symposium on semantics of algorithmic languages
%E E. Engeler
%P 102-116
%S Lecture Notes in Mathematics
%V 188
%I Springer-Verlag
%C Berlin-Heidelberg-New York
%D 1971
.QE
.PP
In any reference format, the O field can be used to give additional information.
This is frequently used, for example, for secondary references.
.Ex
%A Girard
%A J-C Rault
%T A Programming Technique for Software Reliability
%B Symposium on Software Reliability
%I IEEE
%C Montvale, New Jersey
%D 1977
%O (Cited in Glib [32])
.QE
.SH
Compilations
.PP
A compilation is the work of several authors gathered together by an editor
into a book.  In fact the reference format is the same as for a book, with
the editor(s) taking the place of the author.
Note the word "editors" has been added to the last author field.
.Ex
%A R. A. DeMillo
%A D. P. Dobkin
%A A. K. Jones
%A R. J. Lipton,\e editors
%T Foundations of Secure Computation
%I ACPRESS
%D 1978
.QE
.SH
Technical Reports
.PP
A technical report must have a report number.  They usually have authors,
titles, dates and an issuing institution (the I field is used for this).
They may also have a city and a government issue number.  Again string
values (UATR for \*(oqUniversity of Arizona Technical Report\*(cq) will
frequently simplify typing references.
.Ex
%A T. A. Budd
%T An APL Complier
%R UATR 81-17
%D 1981
.QE
.PP
If the institution name is not part of the technical report number, then
the institution should be given separately.
.Ex
%A Douglas Baldwin
%A Frederick Sayward
%T Heuristics for Determining Equivalence of Program Mutations
%R Technical Report Number 161
%I Yale University
%D 1979
.QE
.SH
PhD Thesis
.PP
A PhD thesis is listed as if it were a book, and the institution granting
the degree the publisher.
.Ex
%A Martin Brooks
%T Automatic Generation of Test Data for
Recursive Programs Having Simple Errors
%I PhD Thesis, Stanford University
%D 1980
.QE
.PP
Some authors prefer to treat Masters and Bachelor theses similarly, although
most references on style instruct say to treat a masters degree as an
article or as a report .
.Ex
%A A. Snyder
%T A Portable Compiler for the Language C
%R Master's Thesis
%I M.I.T.
%D 1974
.QE
.SH
Miscellaneous
.PP
A miscellaneous object is something that does not fit into any other form.
It can have any of the the following fields; an author, a title, a date,
page numbers, and, most generally, other information (the O field).
.PP
Any reference item can contain an F field, and the corresponding text
will override whatever citation would otherwise be constructed.
.Ex
%F BHS--
%A Timothy A. Budd
%A Robert Hess
%A Frederick G. Sayward
%T User's Guide for the EXPER Mutation Analysis system
%O (Yale university, memo)
.QE
===== bform.open         =====
.ds [ [
.ds ] ]
.ds , ,\|
.ds <. \ \&
.ds <, \ \&
.ds >. .
.ds >, ,
.ds c[ ,\0
.ds n[ \0and\0
.ds m[ , and\0
.\"
.de s[   \" start reference
.nh
.IP [\\*([F]\0  \\n(a[
..
.de e[   \" end reference
.[-
..
.de []   \" start to display collected references
.SH
References
.LP
..
.de ][   \" choose format
.ie !"\\*([J""     .nr t[ 1    \" journal
.el .ie !"\\*([B"" .nr t[ 3    \" article in book
.el .ie !"\\*([R"" .nr t[ 4    \" technical report
.el .ie !"\\*([I"" .nr t[ 2    \" book
.el                .nr t[ 0    \" other
.\\n(t[[
..
.de 0[   \" other
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.br
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.br
.if !~\\*([O~~ \\*([O\c
.if !~\\*([D~~ , \\*([D\c
\&.
.e[
..
.de 1[ \" journal article
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.br
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.br
.ds a[ \\fI\\*([J\\fP
.ie !"\\*([V"" \{\
.       as a[ , \\*([V
.       if !~\\*([N~~ .as a[ (\\*([N)
.       if !~\\*([P~~ .as a[ :\\*([P\}
.el .if !~\\*([P~~ .as a[ , pages \\*([P
.if !~\\*([I~~ .as a[ , \\*([I
.if !~\\*([D~~ .as a[ , \\*([D
\\*(a[.
.br
.if !~\\*([O~~ \\*([O
.e[
..
.de 2[ \" book
.s[
.if !~\\*(.A~.~ .as [A .
.ie !"\\*([A"" \\*([A
.el .if !~\\*([E~~ \{\
.       ie \\n([E \\*([E, editors.
.       el \\*([E, editor.\}
.br
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\fI\\*([T\\fP
.br
.rm a[
.if !~\\*([I~~ .ds a[ \\*([I
.if !~\\*([C~~ \{\
.       if !~\\*(a[~~ .as a[ ,\\0
.       as a[ \\*([C\}
.if !~\\*([D~~ \{\
.       if !~\\*(a[~~ .as a[ ,\\0
.       as a[ \\*([D\}
\\*(a[.
.br
.if !~\\*([G~~ Government ordering number \\*([G.
.br
.if !~\\*([O~~ \\*([O.
.e[
..
.de 3[ \" article in book
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.br
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.br
.if !~\\*([P~~ pp. \\*([P\0\c
in \\fI\\*([B\\fP\c
.if !~\\*([V~~ , Vol \\*([V\c
.if !~\\*([E~~ , ed. \\*([E\c
\&.
.br
.if !~\\*([I~~ \\*([I\c
.if !~\\*([C~~ , \\*([C\c
.if !~\\*([D~~ , \\*([D\c
\&.
.if !~\\*([O~~ \\*([O.
.e[
..
.de 4[ \" report
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.br
.if !~\\*(.T~.~ .as [T .
\\*([T
.br
\\*([R\c
.if !~\\*([G~~ \& (\\*([G)\c
.if !~\\*([I~~ , \\*([I\c
.if !~\\*([C~~ , \\*([C\c
.if !~\\*([D~~ , \\*([D\c
\&.
.br
.if !~\\*([O~~ \\*([O.
.e[
..
.de [-   \" clean up after yourself
.rm [A [B [C [D
.rm [E [F [G
.rm [I [J [K
.rm [N [O [P
.rm [R [T
.rm [V [W
.rm .A .T
..

===== bform.std          =====
.ds [ [
.ds ] ]
.ds , ,\|
.ds <. \ \&
.ds <, \ \&
.ds >. .
.ds >, ,
.ds c[ ,\0
.ds n[ \0and\0
.ds m[ , and\0
.\"
.de s[   \" start reference
.nh
.IP [\\*([F]\0  \\n(a[
..
.de e[   \" end reference
.[-
..
.de []   \" start to display collected references
.SH
References
.LP
..
.de ][   \" choose format
.ie !"\\*([J""     .nr t[ 1    \" journal
.el .ie !"\\*([B"" .nr t[ 3    \" article in book
.el .ie !"\\*([R"" .nr t[ 4    \" technical report
.el .ie !"\\*([I"" .nr t[ 2    \" book
.el                .nr t[ 0    \" other
.\\n(t[[
..
.de 0[   \" other
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.if !~\\*([O~~ \\*([O\c
.if !~\\*([D~~ , \\*([D\c
\&.
.e[
..
.de 1[ \" journal article
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.ds a[ \\fI\\*([J\\fP
.ie !"\\*([V"" \{\
.       as a[ , \\*([V
.       if !~\\*([N~~ .as a[ (\\*([N)
.       if !~\\*([P~~ .as a[ :\\*([P\}
.el .if !~\\*([P~~ .as a[ , pages \\*([P
.if !~\\*([I~~ .as a[ , \\*([I
.if !~\\*([D~~ .as a[ , \\*([D
\\*(a[.
.if !~\\*([O~~ \\*([O
.e[
..
.de 2[ \" book
.s[
.if !~\\*(.A~.~ .as [A .
.ie !"\\*([A"" \\*([A
.el .if !~\\*([E~~ \{\
.       ie \\n([E \\*([E, editors.
.       el \\*([E, editor.\}
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\fI\\*([T\\fP
.rm a[
.if !~\\*([I~~ .ds a[ \\*([I
.if !~\\*([C~~ \{\
.       if !~\\*(a[~~ .as a[ ,\\0
.       as a[ \\*([C\}
.if !~\\*([D~~ \{\
.       if !~\\*(a[~~ .as a[ ,\\0
.       as a[ \\*([D\}
\\*(a[.
.if !~\\*([G~~ Government ordering number \\*([G.
.if !~\\*([O~~ \\*([O.
.e[
..
.de 3[ \" article in book
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.if !~\\*([P~~ pp. \\*([P\0\c
in \\fI\\*([B\\fP\c
.if !~\\*([V~~ , Vol \\*([V\c
.if !~\\*([E~~ , ed. \\*([E\c
\&.
.if !~\\*([I~~ \\*([I\c
.if !~\\*([C~~ , \\*([C\c
.if !~\\*([D~~ , \\*([D\c
\&.
.if !~\\*([O~~ \\*([O.
.e[
..
.de 4[ \" report
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.if !~\\*(.T~.~ .as [T .
\\fI\\*([T\\fP
\\*([R\c
.if !~\\*([G~~ \& (\\*([G)\c
.if !~\\*([I~~ , \\*([I\c
.if !~\\*([C~~ , \\*([C\c
.if !~\\*([D~~ , \\*([D\c
\&.
.if !~\\*([O~~ \\*([O.
.e[
..
.de [-   \" clean up after yourself
.rm [A [B [C [D
.rm [E [F [G
.rm [I [J [K
.rm [N [O [P
.rm [R [T
.rm [V [W
.rm .A .T
..

===== bib.fullnames      =====
# full journal names, and other names
#
# journals
D ACTA Acta Informatica
D BIT B\&IT
D BSTJ Bell System Technical Journal
D CACM Communications of the ACM
D COMP Computer
D COMPJOUR The Computer Journal
D COMPLANG Computer Languages
D COMPSUR ACM Computer Surveys
D I&C Information and Control
D IEEETSE IEEE Transactions on Software Engineering
D IEEETC IEEE Transactions on Computers
D IPL Information Processing Letters
D JACM Journal of the ACM
D JCSS Journal of Computer and System Sciences
D NMATH Numerical Mathematics
D SIAMJC Siam Journal on Computing
D SIAMJNA Siam Journal on Numerical Analysis
D SIGACT S\&IGACT News
D SIGPLAN SI\&GPLAN Notices
D SIGSOFT Software Engineering Notes
D SP&E Software \(em Practice & Experience
D TODS ACM Transactions on Database Systems
D TOMS ACM Transactions on Mathematical Software
D TOPLAS ACM Transactions on Programming Languages and Systems
#
# conferences
#
D POPL ACM Symposium on Principles of Programming Languages
D POPL5 Conference Record of the Fifth POPL
D POPL6 Conference Record of the Sixth POPL
D POPL7 Conference Record of the Seventh POPL
D POPL8 Conference Record of the Eighth POPL
D POPL9 Conference Record of the Ninth POPL
D POPL10 Conference Record of the Tenth POPL
D STOC Annual ACM Symposium on Theory of Computing
D FOCS Annual Symposium on Foundations of Computer Science
D SOSP Symposium on Operating System Principles
D ICSE International Conference on Software Engineering
#
#  publishers
#
D ACPRESS Academic Press
D PRHALL Prentice Hall
D WILEY Wiley
#
# months
#
D JAN January
D FEB February
D MAR March
D APR April
D MAY May
D JUN June
D JUL July
D AUG August
D SEP September
D OCT October
D NOV November
D DEC December
#
#  miscelaneous
#
D UATR University of Arizona Technical Report
D DPCS  Department of Computer Science
D CSDP Computer Science Department
===== bib.open           =====
#
#  open format macros
#  style adapted from "A Handbook for Scholars"
#                     by Mary-Claire van Leunen
#
#  (check for periods following author and titles)
T AT
.so /usr/lib/bmac/bform.open
===== bib.std            =====
#
#  standard format macros
#  style adapted from "A Handbook for Scholars"
#                     by Mary-Claire van Leunen
#
# (detect periods at end of authors, titles)
T AT
.so /usr/lib/bmac/bform.std
===== bmac.hnf           =====
#
#  Hanson Normal Form
#
SAD-2
CA3lD-2
A
I /usr/lib/bmac/bib.fullnames
.ds [ [
.ds ] ]
.ds , ,
.ds <. \ \&
.ds <, \ \&
.ds >. .
.ds >, ,
.ds c[ ,\0
.ds n[ \0and\0
.ds m[ , and\0
.\"
.de s[   \" start reference
.nh
.IP [\\*([F] 2m
.br
..
.de e[   \" end reference
.[-
..
.de []   \" start to display collected references
.SH
References
.LP
..
.de ][   \" choose format
.ie !"\\*([J"" \{\
.    ie !"\\*([V"" .nr t[ 1    \" journal
.    el            .nr t[ 5    \" conference paper
.\}
.el .ie !"\\*([B"" .nr t[ 3    \" article in book
.el .ie !"\\*([R"" .nr t[ 4    \" technical report
.el .ie !"\\*([I"" .nr t[ 2    \" book
.el                .nr t[ 0    \" other
.\\n(t[[
..
.de 0[   \" other
.s[
.if !"\\*([A"" \\*([A.
.if !"\\*([T"" \\*([T.
.if !"\\*([O"" \\*([O\c
.if !"\\*([D"" , \\*([D\c
\&.
.e[
..
.de 1[ \" journal article
.s[
.if !"\\*([A"" \\*([A,
.if !"\\*([T"" \\*([T,
\\fI\\*([J\\fP
\\fI \\*([V\\fP,
.if !"\\*([N"" \\*([N
.if !"\\*([D"" (\\*([D),
.if !"\\*([P"" \\*([P\c
.if !"\\*([I"" , \\*([I\c
\\&.
.if !"\\*([O"" \\*([O.
.e[
..
.de 2[ \" book
.s[
.ie !"\\*([A"" \\*([A,
.el .if !"\\*([E"" \{\
.       ie \\n([E \\*([E, editors,
.       el \\*([E, editor,\}
.if !"\\*([T"" \\fI\\*([T\\fP,
.rm a[
.if !"\\*([I"" .ds a[ \\*([I
.if !"\\*([C"" \{\
.       if !"\\*(a["" .as a[ ,\\0
.       as a[ \\*([C\}
.if !"\\*([D"" \{\
.       if !"\\*(a["" .as a[ ,\\0
.       as a[ \\*([D\}
\\*(a[.
.if !"\\*([G"" Government ordering number \\*([G.
.if !"\\*([O"" \\*([O.
.e[
..
.de 3[ \" article in book
.s[
.if !"\\*([A"" \\*([A.
.if !"\\*([T"" \\*([T.
.if !"\\*([P"" pp. \\*([P\0\c
in \\fI\\*([B\\fP\c
.if !"\\*([V"" , Vol \\*([V\c
.if !"\\*([E"" , ed. \\*([E\c
\&.
.if !"\\*([I"" \\*([I\c
.if !"\\*([C"" , \\*([C\c
.if !"\\*([D"" , \\*([D\c
\&.
.if !"\\*([O"" \\*([O.
.e[
..
.de 4[ \" report
.s[
.if !"\\*([A"" \\*([A,
\\*([T,\\*([R\c
.if !"\\*([G"" \& (\\*([G)\c
.if !"\\*([I"" , \\*([I\c
.if !"\\*([C"" , \\*([C\c
.if !"\\*([D"" , \\*([D\c
\&.
.if !"\\*([O"" \\*([O.
.e[
..
.de [-   \" clean up after yourself
.rm [A [B [C [D
.rm [E [F [G
.rm [I [J [K
.rm [N [O [P
.rm [R [T
.rm [V [W
..


===== bmac.opena         =====
#
#  standard open alphabetic format
#
SAD-2
C2D-2
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.open
# a[ - amount to indent reference
.nr a[ 8
===== bmac.openn         =====
#
#  standard open numeric format
#
SAD-2
C1
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.open
# a[ - amount to indent references
.nr a[ 5
===== bmac.stda          =====
#
#  standard alphabetic format
#
SAD-2
C2D-2
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.std
# a[ - amount to indent reference
.nr a[ 8
===== bmac.stdn          =====
#
#  standard numeric format
#
C1
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.std
# a[ - amount to indent references
.nr a[ 5
===== bmac.stdsn         =====
#
#  standard sorted numeric
#
SAD-2
I /usr/lib/bmac/bmac.stdn
===== bmac.supn          =====
#
#  standard superscripted numeric format
#
C1
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.std
# redefine string for citations
.ds [ \u
.ds ] \d
.ds >.
.ds <. .
.ds >,
.ds <, ,
.nr a[ 5
===== common             =====
and
for
the
an
be
of
in
at
on
by
to
no
as
tr
with
some
about
jan
feb
mar
apr
may
june
jun
july
jul
aug
sep
sept
oct
nov
dec

hawley (11/02/82)

I have seen the macros, and a refdoc file,
but no documentation on how to use the macros with nroff,
and no "bib" program, no man pages.

Are these forthcoming?
If not, would appreciate it if you could mail me a copy.

Mike Hawley
(decvax!yale-comix!hawley)

whm (11/13/82)

A large portion of the net didn't get the source for "bib" the first
time we sent it out.  Due to tremendous demand, here it comes again, in
two separate articles.  Questions about bib should be directed to
arizona!gary.

					Sorry about the redundancy,
					Bill Mitchell
					The U of A

whm (11/13/82)

This is the source and documentation for our local replacement for
refer.  Each file is preceded by a line of equal signs surrounding the
file name.  The file names are important if you want the makefile to
work correctly.  The documentation comes first, followed by the
makefile and the source.

The programs are called bib (the refer replacement), invert (the
program to create the index needed by bib), lookup (a replacement for
lookbib), and listrefs (used to produce a readable version of the
reference list).

Bib produces macro calls.  I have put some sample macro packages in
net.sources (separate posting).  That posting contains documentation on
creating new macro packages that work with bib.

As an aside, invert can be used to create an index to any set of
records.  (A record is a sequence of non-blank lines.  Records are
separated by lines.) Lookup will then select records based on
keywords.  I use it for a phone/address list.

===== bibman:    man page for bib   =====

.TH bib 1 local
.SH NAME
bib - bibliographic formatter
.SH SYNOPSIS
\fBbib\fP [options] ...
.SH DESCRIPTION
\fIBib\fP is a preprocessor for \fInroff\fP or \fItroff\fP(1) that
formats citations and bibliographies.  The input files (standard input
default) are copied to the standard output, except for text between [. and .]
pairs, which are assumed to be keywords for searching a bibliographic database.
If a matching reference is found a citation is generated replacing the text.
References are collected, optionally sorted, and written out at a location
specified by the user.
Citation and reference formats are controlled by the -t option.
.PP
Reference databases are created using the \fIinvert\fP utility.
.PP
The following options are available:
.IP -a 8m
reduce author\*(CQs first names to abbreviations.
.IP -c\fIstr\fP
build citations according to the template \fIstr\fP.  See the reference
format designer\*(CQs guide for more information on templates.
.IP -f
instead of collecting references, dump each
reference immediately following the line on which the citation is placed
(used for footnoted references).
.IP "-p \fIfile\fP"
.ns
.IP  -p\fIfile\fP
instead of searching the file INDEX,
search the indicated reference file before searching the system file.
.IP -r\fInum\fP
reverse the first \fInum\fP author\*(CQs names
.IP -s\fIstr\fP
sort references according to the template \fIstr\fP.
.IP "-t \fItype\fP"
.ns
.IP -t\fItype\fP
use the standard macros and switch settings to generate citations and references
in the indicated style.
.IP -x
print authors last names in Caps-Small Caps style (for example Budd becomes
B\s-2UDD\s+2.  This style is used by certain ACM publications).
.SH FILES
INDEX   inverted index for reference database
.br
/usr/dict/papers/INDEX   default system index
.br
/usr/lib/bmac/bmac.*   formatting macro packages
.br
/usr/tmp/bibr*   scratch file for collecting references
.br
/usr/tmp/bibp*   output of pass1 of bib
.SH SEE ALSO
\fIA UNIX Bibliographic Database Facility\fP, Timothy A. Budd and Gary M. Levin,
University of Arizona Technical Report 82-1, 1982.
.br
invert(1), troff(1)

===== invertman:    man page for invert/lookup   =====

.TH invert/lookup 1 local
.SH NAME
invert, lookup \(em create and access an inverted index
.SH SYNOPSIS
.B invert
[option ... ] file ...
.ns
.PP
.B lookup
[option ... ]
.SH DESCRIPTION
.I Invert
creates an inverted index to one or more files.
.I Lookup
retrieves records from files for which an inverted index exists.
The inverted indices are intended for use with
.IR bib (1).
.PP
.I Invert
creates one inverted index to all of its input files.
Each input file is viewed as a set of records;
each record consists of non-blank lines;
records are separated by blank lines.
.PP
.I Lookup
retrieves records based on its input
.I (stdin).
Each line of input is a retrieval request.
All records that contain all of the keywords in the retrieval request
are sent to
.I stdout.
If there are no matching references,
"No references found." is sent to
.I stdout.
.I Lookup
first searches in the user's private index (default INDEX)
and then, if no references are found,
in the system index (/usr/dict/papers/INDEX).
The system index was produced using
.I invert
with the default options;
in general, the user is advised to use the defaults.
.PP
Keywords are a sequence of non-white space characters
with non-alphanumeric characters removed.
Keywords must be at least two characters and are truncated
(default length is 6).
Some common words are ignored.
Some lines of input are ignored for the purpose of collecting keywords.
.PP
The following options are available for
.I invert:
.IP "-c \fIfile\fP" 8m
.ns
.IP -c\fIfile\fP
File contains common words, one per line.
Common words are not used as keys.
(Default /usr/lib/bmac/common.)
.IP "-k \fIi\fP"
.ns
.IP -k\fIi\fP
Maximum number of keys kept per record. (Default 100)
.IP "-l \fIi\fP"
.ns
.IP -l\fIi\fP
Maximum length of keys. (Default 6)
.IP "-p \fIfile\fP"
.ns
.IP -p\fIfile\fP
File is the name of the private index file (output of
.IR invert ).
(Default is INDEX.)
.IP -%\fIstr\fP
Ignore lines that begin with %x
where x is in
.I str.
(Default is CNOPVX. See
.IR bib (1)
for explanation of field names.)
.PP
.I Lookup
has only the options
.BR c ,
.BR l ,
and
.B  p
with the same meanings as
.I invert.
.SH FILES
INDEX                    inverted index
.br
/usr/tmp/invertxxxxxx    scratch file for invert
.br
/usr/lib/bmac/common     default list of common words
.br
/usr/dict/papers/INDEX   default system index
.SH SEE ALSO
\fIA UNIX Bibliographic Database Facility\fP,
Timothy A. Budd and Gary M. Levin,
University of Arizona Technical Report 82-1, 1982.
.br
bib(1)
.SH DIAGNOSTICS
Messages indicating trouble accessing files are sent on
.I  stderr.
There is an explicit message on
.I stdout
from
.I lookup
if no references are found.
.SH BUGS
No attempt is made to check the compatibility between an index
and the files indexed.
The user must create a new index whenever
the files that are indexed are modified.

===== bibdoc:    how to use bib (see other posting for macros)   =====


.ce 1000
\fBBIB - a program for formatting bibliographies\fP
.ce 0
.PP
\fIBib\fP is a program for collecting and formatting reference lists in
documents.  It is a preprocessor to the nroff/troff typesetting systems,
much like the tbl [.tbl.] and eqn [.eqn.] systems.  \fIBib\fP takes two
inputs: a document to be formatted and a library of references.  Imprecise
citations in the source document are replaced by more conventional
citation strings, the appropriate references are selected from the reference
file, and commands are generated to format both citation and the referenced
item in the bibliography.
.PP
An imprecise citation is simply a list of words surrounded by the characters
\*(oq[\&.\*(cq \*(oq.]\*(cq.  Words (which can be truncated to six letters)
in the imprecise citation are matched against entries in the reference file,
and if an entry is found that matches all words, that reference is used.
For example:
.de 2Q
.sp
.QS
.QS
..
.de 2E
.sp
.QE
.QE
..
.2Q
.PP
In Brooks\*(CQ interesting book [\&. brooks mythical.] various reasons ...
.2E
.PP
Multiple citations are indicated by simply placing a comma in the imprecise
citation:
.2Q
.PP
In [\&.kernig tools, kernig elements.] Kernighan and Plauger have ...
.2E
.PP
Embedded newlines, tabs and extra blanks are ignored within the
imprecise citation.
.PP
Judicious use of the K (keyword) field in references can simplify citations
considerably:
.2Q
.PP
For a description of LR parsing, see [\&.dragon.] by Aho and Ullman.
.2E
.PP
The algorithm used by \fIbib\fP scans the source input in two passes.
In the first pass,
references are collected and the location of citations marked.
In the second pass, these marks are replaced by the appropriate citation,
and the entire list of references is dumped following a call on the macro
\&\*(oq.[]\*(cq.
This macro is left untouched.
Most standard document types will define this macro to cause a break and
start a section titled \*(oqReferences\*(cq.
However, this can be altered by the user to achive any desired typographic
effect.
.PP
An exception to this process is made in those instances where
references are indicated in footnotes.  In this case the macro that
generates the reference is placed immediately after each line in which
the reference is cited.
.PP
Reference files are prepared for \fIbib\fP using the program \fIinvert\fP.
By default \fIinvert\fP places an inverted index for the
reference list in a file called INDEX.  Unless the user specifies an
alternative (see the -p switch described below) this is the first file
searched in attempting to locate a reference.  If the entry is not found
in the user\*(CQs file, a standard system-wide index is searched.  If the
entry is still not found in the system file, a warning message is produced
and a blank citation is generated.
.PP
The format for entries in the reference file is described more fully in
[.reference formats.].  This format is similar to that used by \fIrefer\fP
[.lesk refer.] with the following exceptions:
.IP 1.
An F field, if present, overrides whatever citation string would otherwise
be constructed.
.IP 2.
Certain defined names can be used, and will be expanded differently by
different document styles.  For example, the string CACM is expanded into
\*(oqCommunications of the ACM\*(cq by some document styles, \*(oqComm.
ACM\*(cq by others,
and \*(oqComm. of the Assoc. of Comp. Mach.\*(cq by yet others.
Appendix 1 lists the currently recognized names.
.PP
Since the user\*(CQs index is searched before the system index, if the
user wants to alter a specific entry in the system index (say to change
the name W. E. Howden to William E. Howden, for example) it is a simple
matter to copy the system information into his own library and make
the changes locally.
.PP
Reference files must be run through \fIinvert\fP before they can be
used in \fIbib\fP.
.PP
Citation formats are either determined by explicit switch settings or,
more generally, by using a predefined formatting style.  In the latter form,
usage looks something like:
.sp
.ce
bib -t\fIstyle\fP [files]
.sp
where \fIstyle\fP is a citation style.
Currently the following citation styles are available:
.IP stdn\0\0
(standard numeric) numeric citation.  Reference entries are listed in
citation order.
.IP stdsn
same as stdn, but references are sorted by senior author followed by date.
.IP stda
(standard alphabetic) citations are three letters followed by the last two
digits of the date.  For papers with a single author, the letters are the
first three letters of the authors last name (e.g. Knu).
In papers with two authors the first two letters are from the first author
followed by one letter from the second (e.g. HoU). If three or more
authors are given the first letters from the first three authors are used
(e.g. AHU).
.IP openn
same as stdsn, only using an open reference format (each major entry is on
a new line\u1\d).
.FS
1. The open reference format is adapted from \*(oqA Handbook for Scholars\*(cq,
by Mare-Claire van Leunen, published by Knopf, 1978.
.FE
.IP opena
same as stda, but using an open format.
.IP supn
same as stdn, but using superscripts.
.IP hnf
(Hanson Normal Form)  citations are the first three letters of the senior
authors last name, in lower case, followed by the last two digits of the date.
First names are abbreviated.  References are sorted by senior author
followed by date.
.PP
It is possible to alter slightly the format of standard styles.  For example,
to generate references in standard numeric style, but abbreviate first names,
the following can be used:
.sp
.ce
bib -tstdn -a ...
.PP
If two reference items create the same citation string (this can happen
if two papers authored by the same person in a single year are referred to
in one paper) a disambiguating final letter is added to the citation
(i.e., Knu79 becomes Knu79a and Knu79b).
As noted previously, this can be altered by using the F field.
.PP
For the purposes of sorting by author, the last name is taken to be the last
word of the name field.  This means some care must be taken when names contain
embedded blanks, such as in \*(oqHartley Rogers, Jr.\*(cq
or \*(oqMary-Claire van Leunen\*(cq.
In these cases a concealed space (either \e0 or \e ) should be used, as in
\*(oqHartley Rogers,\e Jr.\*(cq.
.PP
Note that \fIbib\fP knows very little about troff usage or syntax.  This
can sometimes be useful.  For example, to cause an entry to appear in a
reference list without having it explicitly cited in the text the following
construction can be used:
.QS
.nr
.sp
 .di XX
 [\&.imprecise citation.]
 .di
.QE
.PP
It is also possible to embed troff commands within a reference definition.
See \*(oqabbreviations\*(cq in the section \*(oqReference Format Designers
Guide\*(cq for an example of this.
.PP
In some styles (superscripts) periods and commas should precede the
citation while in other styles (brackets) they should follow it.  If
a period or comma immediately precedes a citation, it will be moved to the
appropriate location for the particular reference style being used.
.PP
The following is a complete list of options for bib:
.IP -a 8m
reduce author\*(CQs first names to abbreviations.
.IP -c\fIstr\fP
build citations according to the template \fIstr\fP.  See the reference
format designer\*(CQs guide for more information on templates.
.IP -f
instead of dumping references following the call on \&.[], dump each
reference immediately following the line on which the citation is placed
(used for footnoted references).
.IP "-p \fIfile\fP"
.ns
.IP  -p\fIfile\fP
instead of searching the file INDEX,
search the indicated reference file before searching the system file.
.IP -r\fInum\fP
reverse the first \fInum\fP author\*(CQs names
.IP -s\fIstr\fP
sort references according to the template \fIstr\fP.
.IP "-t \fItype\fP"
.ns
.IP -t\fItype\fP
use the standard macros and switch settings to generate citations and references
in the indicated style.
.IP -x
print authors last names in Caps-Small Caps style (for example Budd becomes
B\s-2UDD\s+2.  This style is used by certain ACM publications).
.SH
Acknowledgements
.PP
The \fIbib\fP program was inspired by the \fIrefer\fP utility written by
M. Lesk.
.[]
.bp
.CH
Reference Format Designers Guide
.PP
This section need only be read by those users who are displeased with the
existing library of reference styles, and who wish to write their own
formatting macro package.
.PP
The information necessary for generating citations and references of a
particular style is contained in a \fIformat file\fP.  A format file
consists of two parts; a sequence of format commands, which are read and
interpreted by bib, and a sequence of text lines (usually troff macro
definitions) which are merely copied to output.
The format file name is always prefixed with the string bmac.
Thus the format file for a standard document type, such as stdn, is found
in /usr/lib/bmac/bmac.stdn.
.PP
When bib encounters a -t switch, the user\*(CQs directory is first searched for
a format file matching the given name, before the system area is examined.
Thus the user can generate his own format style by creating his own format
file.
.PP
There are ten format commands.  Each command is distinguished by a single
letter, which must be the first character on a line.  The ten commands,
and their arguments, are as follows:
.sp
# text
.PP
A line beginning with a sharp sign is a comment, and all remaining text on the
line is ignored.
.sp
A
.PP
The A command indicates that author\*(CQs first names are to be abbreviated.
(See \*(oqabbreviations\*(cq below).
.sp
F
.PP
The F command indicates that references are to be dumped immediately after
a line containing a citation, such as when the references are to be placed
in footnotes.
.sp
S \fItemplate\fP
.PP
The S command indicates references are to be sorted before being dumped.
The comparison used in sorting is based on the \fItemplate\fP.  See
the discussion on sorting (below) for an explanation of templates.
.sp
C \fItemplate\fP
.PP
The \fItemplate\fP is used as a model in constructing citations.
See the discussion below.
.sp
D \fIword definition\fP
.PP
The word-definition pair is placed into a table.
Before each reference is dumped it is examined for the
occurrence of these words.  Any occurrence of a word from this table is replaced
by the definition, which is then rescaned for other words.
Words are limited to being alphanumeric.
.sp
I \fIfilename\fP
.PP
The indicated file is included at the current point.  The included file may
contain other formatting commands.
.sp
R \fInumber\fP
.PP
The first \fInumber\fP author\*(CQs names are reversed on output (i.e. T. A. Budd
becomes Budd, T. A.)
.sp
T \fIstr\fP
.PP
The \fIstr\fP is a list of field names.  Each time a definition string for
a named field is produced, a second string containing just the last character
will also be generated.  See \*(oqTrailing characters\*(cq, below.
.sp
X
.PP
Authors last names are to be printed in Caps/Small Caps
format (i.e., Budd becomes B\s-2UDD\s+2).
.PP
The first line in the format file that does not match a format command
causes that line, and all subsequent lines, to be immediately copied to
the output.
.SH
Sorting
.PP
The sort template is used in comparing two references to generate
the sorted reference list.  The sort template is a sequence of
sort objects.  Each sort object consists of an optional negative sign, followed
by a field character, followed by an optional signed size.  The leading negative
sign, if present, specifies the sort is to be in decreasing order, rather than
increasing.  The field character indicates which field in the reference
is to be compared.  The entire field is used, except in the case of the \*(OQA\*(CQ
field, in which case only the senior authors last name is used.
A positive number following the field character indicates that only the first
n characters are to be examined in the comparison.  The negative value indicates
only the last n characters.  Thus, for example, the template AD-2 indicates
that sorting is to be done by the senior author followed by the last two
characters of the date.
.PP
The sort algorithm is stable, so that two documents which compare equally
will be listed in citation order.
.SH
Citations
.PP
A citation template is similar to a sort template, with the following
exceptions:  The field name \*(oq1\*(cq refers to the number which
represents the position of the reference in the reference list (after sorting).
The field name \*(oq2\*(cq generates a three character sequence; If the
paper being references has only one author, this is the first three characters
of the authors last name.  For two author papers, this is the first two
characters of the senior author, followed by the first character of the second
author.  For papers with three or more authors the first letter of the first
three authors is used.
Finally each object can be followed by either of the letters \*(OQu\*(CQ or
\*(OQl\*(CQ and the field will be printed in all upper or all lower case,
respectively.
.PP
If necessary for disambiguating, the character \*(oq@\*(cq can be used as
a separator between objects in the citation template.  Any text which should
be inserted into the citation uninterpreted should be surrounded by either
{} or <> pairs.
.SH
Citation Formatting
.PP
In the output each citation is surrounded by the strings \e*[ and \e*].
Multiple citations are separated by the string \e*,.
The text portion of a format file should contain troff definitions for
these strings to achieve the appropriate typographic effect.
.PP
Citations that are preceded by either a period or a comma are, in addition,
surrounded by the string values \e*(<. and \e*(>. or \e*(<, and \e*(>,.
Again, troff commands should be given to insure the appropriate values are
produced.
.SH
Reference Formatting
.PP
The particular style used in printing references is decided by macros
passed to the troff processor.  Basically for each reference
\fIbib\fP generates a sequence of string definitions, one for each field in the
reference, followed by a call on the formatting macro.  For example an
entry which in the reference file looks like:
.KS
.nf
%A M. A. Harrison
%A W. L. Ruzzo
%A J. D. Ullman
%T Protection in Operating Systems
%J CACM
%V 19
%N 8
%P 461-471
%D 1976
%K hru
.KE
.PP
Is converted into the following sequence of commands
.KS
.nf
 .[-
 .ds [F 1
 .ds [A M. A. Harrison
 .as [A \e*(c[W. L. Ruzzo
 .as [A \e*(m[J. D. Ullman
 .ds [T Protection in Operating Systems
 .ds [J Communications of the ACM
 .ds [V 19
 .ds [N 8
 .nr [P 1
 .ds [P 461-471
 .ds [D 1976
 .][
.KE
.PP
Note that the commands are preceded by a call on the macro \*(oq.[-\*(cq.
This can be used by the macro routines for initialization, for example to
delete any old string values.  The string [F is the citation value used
in the document.
Note too that the string CACM has been
expanded into \*(oqCommunications of the ACM\*(cq.
.PP
The strings c[, n[ and m[ are used to separate authors.  c[ separates
the initial authors in multi-author documents (it is usually a comma
with some space before and after) n[ separates authors in two author
documents (usually \*(oq and \*(cq) and m[ separates the last two authors
in multi-author documents (either \*(oq and \*(cq or \*(oq, and \*(cq).
.PP
If abbreviation is specified, the string d[ is used to separate initials
in the authors first name.
.PP
The \fIbib\fP system does provide a minimal sort of assistance in
deciding format types.  For example note that the number register [P has
been set of 1, to indicate that the article is on more than one page.
Similarly in documents with editors, the register [E is set to zero if
there is only one editor and one if there is more than one editor.
.SH
Trailing Characters
.PP
There is a problem with fields which end with puncuation characters causing
multiple occurrences of those characters to be printed.  For example, suppose
author fields are terminated with a period, as in T. A. Budd.  If names
are reverse, this could be printed as Budd, T. A..  Even if names are not
reverse, abbreviations, such as in Jr. can cause problems.
.PP
To avoid this problem \fIbib\fP will, if instructed, generate the last
character from a particular field as a separate string.  The string name
is a period followed by the field name.  Macro packages should test this
field before generating punctuation.
.SH
Abbreviations
.PP
The algorithm used to generate abbreviations from first names is fairly
simple: Each word in the first name field which begins with a capital
is reduced to that capital letter followed by a period.
In some cases this may not be sufficient.  For example, suppose you think
Ole-Johan Dahl should be abbreviated \*(oqO-J. Dahl\*(cq.  The only
way to achieve this (short of editing bib output) is to include troff commands
in the reference file which alter the strings produced by bib, as in the following
.QS
 ...
 %A Ole-Johan Dalh
 .ds [A O-J. Dalh
 ...
.QE
.PP
In fact any troff commands can be entered in the middle of a reference
entry, and the commands will be copied uninterpreted to the output.
For example the user may wish to have a switch indicating whether the name
is to be abbreviated or not:
.QS
 ...
 %A Ole-Johan Dalh
 .if \en(i[ .ds [A O-J. Dalh
 ...
.QE
.SH
An Example
.PP
Figure 1 shows the format file for the standard alphabetic format.
The sort command indicates that sorting is to be done by senior author,
followed by the last two digits of the date.  The citation template
indicates that citations will be the three character sequence described
in the section of citations
followed by the last two characters of the date (i.e. AHU79, for
example).
.KS
.nf
#
#  standard alphabetic format
#
SAD-2
C2D-2
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.std
.sp
.ce
\fBFigure 1\fP
.KE
.PP
The two I commands include two files.  The first is a file of definitions
for common strings, such as dates and journal names.  A portion of this
file is shown in figure 2.
Note that a no-op has been inserted into the definition string for the
journal BIT in order to avoid the name being expanded again when the
definition is rescaned.
.PP
The second file is a sequence of troff macros
for formatting the references.  The beginning of this file is shown in figure 3.
.PP
On the basis of some simple rules (the presence or absence of certain fields)
the document is identified as one of five different types, and a call made
on a different macro for each type.  This is shown in figure 4.
.PP
Finally figure 5 shows the macro for one of those different types, in this
case the book formatting macro.
.KS
.nf
# full journal names, and other names
#
# journals
D ACTA Acta Informatica
D BIT B\e&IT
D CACM Communications of the ACM
 ...
#
# months
#
D JAN January
D FEB February
 ...
D DEC December
.sp
.ce
\fBFigure 2\fP
.KE
.KS
.nf
 #
 #  standard end macros
 #
 .ds [ [
 .ds ] ]
 .ds , ,
 .ds >. .
 .ds >, ,
 .ds c[ ,\e0
 .ds n[ \e0and\e0
 .ds m[ , and\e0
   ...
 .de p[   \e" produce reference beginning
 .IP [\e\e$1]\0\0
 ..
 .de []   \e" start displaying collected references
 .SH
 References
 .LP
 ..
.sp
.ce
\fBFigure 3\fP
.KE
.KS
.nf
.sp
 .de ][   \e" choose format
 .ie !"\e\e*([J"" \e{\e
 .    ie !"\e\e*([V"" .nr t[ 1    \e" journal
 .    el            .nr t[ 5    \e" conference paper
 .\e}
 .el .ie !"\e\e*([B"" .nr t[ 3    \e" article in book
 .el .ie !"\e\e*([R"" .nr t[ 4    \e" technical report
 .el .ie !"\e\e*([I"" .nr t[ 2    \e" book
 .el                .nr t[ 0    \e" other
 .\e\en(t[[
 ..
.sp
.ce
\fBFigure 4\fP
.KE
.KS
.nf
.sp
   ...
 .de 2[ \e" book
 .if !"\e\e*([F"" .p[ \e\e*([F
 .if !"\e\e*([A"" \e\e*([A,
 .if !"\e\e*([T"" \e\ef2\e\e*([T,\e\ef1
 \e\e*([I\ec
 .if !"\e\e*([C"" , \e\e*([C\ec
 .if !"\e\e*([D"" \e& (\e\e*([D)\ec
 \e&.
 .if !"\e\e*([G"" Gov't. ordering no. \e\e*([G.
 .if !"\e\e*([O"" \e\e*([O
 .]-
 ..
.sp
.ce
\fBFigure 5\fP
.KE
.rs
.bp
.CH
APPENDIX
.sp
Standard Names
.PP
The following list gives the standard names recognized in most
citation styles.  Various different forms for the output are used
by the different styles.
.sp
.nf
.ta 1i
\fBJournal Names\fP
ACTA	Acta Informatica
BIT	BIT
BSTJ	Bell System Technical Journal
CACM	Communications of the ACM
COMP	Computer
COMPJOUR	The Computer Journal
COMPLANG	Computer Languages
COMPSUR	ACM Computer Surveys
I&C	Information and Control
IEEETSE	IEEE Transactions on Software Engineering
IEEETC	IEEE Transactions on Computers
IPL	Information Processing Letters
JACM	Journal of the ACM
JCSS	Journal of Computer and System Sciences
SIAMJC	Siam Journal on Computing
SIGACT	S\&IGACT News
SIGPLAN	SI\&GPLAN Notices
SIGSOFT	Software Engineering Notes
SP&E	Software \(em Practice & Experience
TODS	ACM Transactions on Database Systems
TOMS	ACM Transactions on Mathematical Software
TOPLAS	ACM Transactions on Programming Languages and Systems
.sp
\fBConferences\fP
POPL	ACM Symposium on Principles of Programming Languages
POPL5	Conference Record of the Fifth POPL
POPL6	Conference Record of the Sixth POPL
POPL7	Conference Record of the Seventh POPL
POPL8	Conference Record of the Eighth POPL
POPL9	Conference Record of the Ninth POPL
POPL10	Conference Record of the Tenth POPL
STOC	Annual ACM Symposium on Theory of Computing
FOCS	Annual Symposium on Foundations of Computer Science
ICSE	International Conference on Software Engineering
SOSP	Symposium on Operating System Principles
.sp
\fBMonths of the year\fP
JAN	January
FEB	February
MAR	March
APR	April
MAY	May
JUN	June
JUL	July
AUG	August
SEP	September
OCT	October
NOV	November
DEC	December
.sp
\fBMisc\fP
CSDP	Computer Science Department
DPCS	Department of Computer Science
UATR	University of Arizona Technical Report

===== makefile     =====

.c.o:
	cc -g -c $*.c

INVo        = invert.o streams.o  makekey.o
LOOKo       = lookup.o locate.o alpha.seek.o streams.o makekey.o
BIBo        = bib.o bibargs.o locate.o alpha.seek.o streams.o makekey.o

invert:  $(INVo)
	cc -g  $(INVo)   -o invert

lookup: $(LOOKo)
	cc -g  $(LOOKo)  -o lookup

bib: $(BIBo)
	cc -g  $(BIBo)  -o bib

listrefs: listrefs.o bibargs.o streams.o makekey.o
	cc -g  -o listrefs listrefs.o bibargs.o streams.o makekey.o

locate.o:       streams.h

invert.o:       streams.h
makekey.o:

alpha.seek.o:   streams.h
streams.o:      streams.h

===== testrefs:    a few simple bibliography entries for testing    =====

%O References having to do with numerical software

%A Webb Miller
%T The Engineering of Numerical Software
%K book
%I (to appear)

%A G.W. Stewart
%T The Economical Storage of Plane Rotations
%J Numer. Math.
%V 25
%P 137-138
%D 1976

%A G.W. Stewart
%T Introduction to Matrix Computations
%I ACPRESS
%D 1973

%A J.J. Dongarra
%A J.R. Bunch
%A C.B. Moler
%A G.W. Stewart
%T LINPACK Users' Guide
%J SIAMJC
%D 1979

%A G.E. Forsythe
%A M.A. Malcolm
%A C.B. Moler
%T Computer Methods for Mathematical Computations
%I PRHALL
%D 1977

%A A.K. Cline
%A C.B. Moler
%A G.W. Stewart
%A J.H. Wilkinson
%T An Estimate of the Condition Number of a Matrix
%J SIAMJNA
%V 16
%D 1979
%P 368-375

%A J.T. Schwartz
%T Fast Probabilistic Algorithms for Verification of Polynomial Identities
%J JACM
%V 27
%N 4
%P 701-717
%D OCT 1980


===== alpha.seek.c =====
#

# include "stdio.h"
# include "ctype.h"
# include "streams.h"
# define  nexttry           ((high+low)/2)

/*  alpha_seek(stream, word, s_size, fold)
        seeks the first line in stream that is at least word.
    assumes that stream is a sorted file of lines.  (last char must be \n)
    if fold, assumes that word is lowercase and folds stream to lowercase.
    s_size = size of stream
    returns 1 if word = line, 0 o.w.
*/
int alpha_seek(stream, word, s_size, fold)
FILE *stream;
char *word;
long int s_size;
int  fold;
{   long int high, low, mid;    /*  point to beginning of a line in stream  */
    int      ans;               /*  line(low) < word <= line(high)          */
    char     line[maxstr];


    /*  initialize low (return if first line >= word)       */
        low= 0L;
        pos(low); getline(stream, line);
        if (fold) foldline(line);
        ans= strcmp(line,word);

        if ( ans >= 0)
        {   pos(low);   return(ans==0); }

    /*  initialize high to "line" after last line           */
        high= s_size;

    mid= nextline(stream, nexttry );
    while (mid < high )
    {   getline(stream,line);
        if (fold) foldline(line);
        if (strcmp(line,word) < 0)    low=  mid;
        else                          high= mid;
        mid= nextline(stream, nexttry );
    }

    /* linear search from low to high   */
        low= nextline(stream,low);
        for(;;)
        {   if (low>=high)      break;

            getline(stream,line);
            if (fold) foldline(line);
            ans=strcmp(line,word);

            if (ans>=0)         break;
            low= ftell(stream);
        }

    pos(low);
    if (low=high)   return(0);
    else            return(ans==0);
}


/*  foldline(p):    change all uppercase to lowercase in string p
*/
foldline(p)
char *p;
{   for (; *p!=NULL;  p++)
    {   if (isupper(*p))    *p = tolower(*p);
    }
}
===== bib.c        =====
/*
   bib - bibliographic formatter
         timothy a. budd, 1/82
         lookup routines supplied by gary levin 2/82
*/
# include <stdio.h>
# include <ctype.h>
# define HUNTSIZE 512                /* maximum size of hunt string */
# define MAXFIELD 250                /* maximum field length */
# define REFSIZE 1024                /* maximum size of reference string */
# define MAXREFS  300                /* maximum number of references */
# define MAXKEY    25                /* maximum keyword size */
# define REFCHAR  002                /* char surrounding references from pass1*/
# define true 1
# define false 0
# define err -1
# define getch(c,fd) (c = getc(fd))
# define echoc(c,ifd,ofd) (getch(c,ifd) == EOF ? c : putc(c,ofd))
# define testc(c,d,ifd,ofd) (getch(c, ifd) == d ? putc(c, ofd) : 0)

/* global variables */
   FILE *rfd;                   /* reference temporary file   */
   char reffile[] = "/usr/tmp/bibrXXXXXX"; /* temporary file */
   long int refspos[MAXREFS];   /* reference seek positions   */
   long int rend = 0;           /* last position in rfd       */
   int numrefs = -1;            /* number of references generated so far */
   FILE *tfd;                   /* output of pass 1 of file(s) */
   char tmpfile[] = "/usr/tmp/bibpXXXXXX"; /* output of pass 1 */
   char common[] = "/usr/lib/bmac/common"; /* common word file */
   char *citestr[MAXREFS];      /* citation strings */
   char citearea[REFSIZE];      /* area for citation strings */
   int  findex = false;         /* can we read the file INDEX ? */

/* global variables in bibargs */
   extern int abbrev, foot, sort, personal, numrev, capsmcap;
   extern char sortstr[], trailstr[], pfile[], citetemplate[];


main(argc, argv)
   int argc;
   char **argv;
{  int i, numfiles, rcomp();
   FILE *fd;
   char *p, *q, name[120];

   /* set variable index */
   rfd = fopen("INDEX", "r");
   if (rfd != NULL) {
      findex = true;
      close(rfd);
      }

   /* open temporaries  */
   mktemp(reffile);
   rfd = fopen(reffile,"w+");
   if (rfd == NULL)
      error("can't open temporary reference file");
   mktemp(tmpfile);
   tfd = fopen(tmpfile,"w");
   if (tfd == NULL)
      error("can't open temporary output file");

    /*
       pass1 - read files, looking for citations
    */

   if (doargs(argc, argv) == 0)
      rdtext(stdin);

   /*
    sort references, making citations
   */

   if (sort)
      qsort(refspos, numrefs+1, sizeof(int), rcomp);
   makecites(citestr, citearea);
   disambiguate();

   /*
   reopen temporaries
   */

   fclose(tfd);
   tfd = fopen(tmpfile,"r");
   if (tfd == NULL)
      error("can't open temporary output file for reading");

   /*
   pass 2 - reread files, replacing references
   */

   pass2(tfd, stdout);

   /*
   clean up
   */

   fclose(tfd);
   fclose(rfd);
   unlink(tmpfile);
   unlink(reffile);
}

/* rdtext - read and process a text file */
   rdtext(fd)
   FILE *fd;
{  int period, comma;
   char c;

   period = comma = false;
   while (getch(c, fd) != EOF)
      switch(c) {
         case '[':
            if (getch(c, fd) == '.') {
               if (period)
                  fputs("\\*(<.", tfd);
               else if (comma)
                  fputs("\\*(<,", tfd);
               rdcite(fd);
               if (period)
                  fputs("\\*(>.", tfd);
               else if (comma)
                  fputs("\\*(>,", tfd);
               comma = period = false;
               }
            else {
               if (period)
                  putc('.', tfd);
               else if (comma)
                  putc(',', tfd);
               putc('[', tfd);
               comma = period = false;
               if (c == '.')
                  period = true;
               else if (c == ',')
                  comma = true;
               else
                  putc(c, tfd);
               }
            break;

         default:
            if (period)
               putc('.', tfd);
            else if (comma)
               putc(',', tfd);
            period = comma = false;
            if (c == '.')
               period = true;
            else if (c == ',')
               comma = true;
            else
               putc(c, tfd);
         }
}

/* rdcite - read citation information */
   rdcite(fd)
   FILE *fd;
{  int period;
   long int n, getref();
   char huntstr[HUNTSIZE], c, info[HUNTSIZE];

   fputs("\\*[", tfd);
   period = false;
   huntstr[0] = 0;
   info[0] = 0;
   while (getch(c, fd) != EOF)
      switch (c) {
         case '\n':
         case '\t':
            if (period)
               addc(huntstr,'.');
            period = false;
            addc(huntstr,' ');
            break;

         case ',':
            if (period)
               addc(huntstr,'.');
            period = false;
            n = getref(huntstr);
            if (n >= 0)
               fprintf(tfd, "%c%d%c%s\\*,", REFCHAR, n, REFCHAR, info);
            else
               fprintf(tfd, "%s\\*,", huntstr);
            huntstr[0] = info[0] = 0;
            break;

         case '.':
            if (period)
               addc(huntstr,'.');
            else
               period = true;
            break;

         case ']':
            if (period) {
               n = getref(huntstr);
               if (n >= 0)
                  fprintf(tfd, "%c%d%c%s", REFCHAR, n, REFCHAR,info);
               else
                  fprintf(tfd, "%s", huntstr);
               fputs("\\*]", tfd);
               return;
               }
            else
               addc(huntstr,']');
            break;

         case '{':
            while (getch(c, fd) != '}')
               if (c == EOF) {
                  fprintf(stderr, "Error: ill formed reference\n");
                  exit(1);
                  }
                else
                  addc(info, c);
            break;

         default:
            if (period)
               addc(huntstr,'.');
            period = false;
            addc(huntstr,c);
         }
   error("end of file reading citation");
}

/* addc - add a character to hunt string */
   addc(huntstr, c)
   char huntstr[HUNTSIZE], c;
{  int  i;

   i = strlen(huntstr);
   if (i > HUNTSIZE)
      error("citation too long");
   huntstr[i] = c;
   huntstr[i+1] = 0;
}

/* getref - get bibliographic reference */
   long int getref(huntstr)
   char huntstr[HUNTSIZE];
{  char ref[REFSIZE], *r, *hunt();
   int  i, match(), getwrd();

   r = hunt(huntstr);
   if (r != NULL) {

      /* see if reference has already been cited */

      for (i = 0; i <= numrefs; i++) {
          rdref(refspos[i], ref);
          if (strcmp(ref, r) == 0) {
             free(r);
             return(refspos[i]);
             }

          }

      /* didn't match any existing reference, create new one */

      numrefs++;
      refspos[numrefs] = rend;
      fseek(rfd, rend, 0);
      i = strlen(r) + 1;
      fwrite(r, 1, i, rfd);
      rend = rend + i;
      free(r);
      return(refspos[numrefs]);
      }
   else {
      fprintf(stderr,"no reference matching %s\n", huntstr);
      return(-1);
      }
}

/* rdref - read text for an already cited reference */
   rdref(i, ref)
   int  i;
   char ref[REFSIZE];
{
   ref[0] = 0;
   fseek(rfd, (long) i, 0);
   fread(ref, 1, REFSIZE, rfd);
}

/* hunt - hunt for reference from either personal or system reference list */
   char *hunt(huntstr)
   char huntstr[];
{  char *fhunt(), *r;

   if (personal) {
      if ((r = fhunt(pfile, huntstr)) != NULL)
         return(r);
      }
   else if (findex) {
      if ((r = fhunt("INDEX", huntstr)) != NULL)
         return(r);
      }
   if ((r = fhunt("/usr/dict/papers/INDEX", huntstr)) != NULL)
      return(r);
   return(NULL);
}

/* fhunt - hunt from a specific file */
   char *fhunt(file, huntstr)
   char file[], huntstr[];
{  char *p, *r, *locate();

   r = locate(huntstr, file, 6, common);

   if (r == NULL)
      return(NULL);  /* error */
   if (*r == 0)
      return(NULL);  /* no match */

   for (p = r; *p; p++)
      if (*p == '\n')
         if (*(p+1) == '\n') { /* end */
            if (*(p+2) != 0)
               fprintf(stderr,"multiple references match %s\n",huntstr);
            *(p+1) = 0;
            break;
            }
         else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */
            *p = ' ';
   return(r);
}

/* rcomp - reference comparison routine for qsort utility */
   int rcomp(ap, bp)
   int *ap, *bp;
{  char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
   char *p, *q, *getfield();
   int  neg, res;

   rdref(*ap, ref1);
   rdref(*bp, ref2);
   for (p = sortstr; *p; p = q) {
      if (*p == '-') {
         p++;
         neg = true;
         }
      else
         neg = false;
      q = getfield(p, field1, ref1);
      if (q == 0)
         res = 1;
      else if (getfield(p, field2, ref2) == 0)
         res = -1;
      else {
         if (*p == 'A') {
            if (isupper(field1[0]))
               field1[0] -= 'A' - 'a';
            if (isupper(field2[0]))
               field2[0] -= 'A' - 'a';
            }
         res = strcmp(field1, field2);
         }
      if (neg)
         res = - res;
      if (res != 0)
         break;
      }
   if (res == 0)
      if (ap < bp)
         res = -1;
      else
         res = 1;
   return(res);
}

/* makecites - make citation strings */
   makecites(citestr, citearea)
   char *citestr[], citearea[];
{  char *cp, ref[REFSIZE], *bldcite();
   int  i;

   cp = citearea;
   for (i = 0; i <= numrefs; i++) {
      rdref(refspos[i], ref);
      citestr[i] = cp;
      cp = bldcite(cp, i, ref);
      }
}

/* bldcite - build citation strings */
   char *bldcite(cp, i, ref)
   char *cp, ref[];
   int  i;
{  char *p, *q, c, *fp, *np, field[REFSIZE], temp[100], *getfield();
   int  j;

   getfield("F", field, ref);
   if (field[0] != 0)
      for (p = field; *p; p++)
         *cp++ = *p;
   else {
      p = citetemplate;
      field[0] = 0;
      while (c = *p++)
         if (isalpha(c)) {
            q = getfield(p-1, field, ref);
            if (q != 0) {
               p = q;
               for (fp = field; *fp; )
                  *cp++ = *fp++;
               }
            }
         else if (c == '1') {
            sprintf(field,"%d",1 + i);
            for (fp = field; *fp; )
               *cp++ = *fp++;
            }
         else if (c == '2') {
            if (getname(1, field, temp, ref)) {
               np = cp;
               fp = field;
               for (j = 1; j <= 3; j++)
                  if (*fp != 0)
                     *cp++ = *fp++;
               if (getname(2, field, temp, ref))
                  np[2] = field[0];
               if (getname(3, field, temp, ref)) {
                  np[1] = np[2];
                  np[2] = field[0];
                  }
               }
            }
         else if (c == '{') {
            while (*p ^= '}')
               if (*p == 0)
                  error("unexpected end of citation template");
               else
                  *cp++ = *p++;
            p++;
            }
         else if (c == '<') {
            while (*p ^= '>')
               if (*p == 0)
                  error("unexpected end of citation template");
               else
                  *cp++ = *p++;
            p++;
            }
         else if (c != '@')
            *cp++ = c;
      }
   *cp++ = 0;   /* leave room for disambiguator */
   *cp++ = 0;
   return(cp);
}

/* getfield - get a single field from reference */
   char *getfield(ptr, field, ref)
   char *ptr, field[], ref[];
{  char *p, *q, temp[100];
   int  n, len, i, getname();

   field[0] = 0;
   if (*ptr == 'A')
      getname(1, field, temp, ref);
   else
      for (p = ref; *p; p++)
         if (*p == '%' && *(p+1) == *ptr) {
            for (p = p + 2; *p == ' '; p++)
               ;
            for (q = field; *p != '\n'; )
               *q++ = *p++;
            *q = 0;
            break;
            }
   n = 0;
   len = strlen(field);
   if (*++ptr == '-') {
      for (ptr++; isdigit(*ptr); ptr++)
         n = 10 * n + (*ptr - '0');
      if (n > len)
         n = 0;
      else
         n = len - n;
      for (i = 0; field[i] = field[i+n]; i++)
         ;
      }
   else if (isdigit(*ptr)) {
      for (; isdigit(*ptr); ptr++)
         n = 10 * n + (*ptr - '0');
      if (n > len)
         n = len;
      field[n] = 0;
      }

   if (*ptr == 'u') {
      ptr++;
      for (p = field; *p; p++)
         if (islower(*p))
            *p = (*p - 'a') + 'A';
      }
   else if (*ptr == 'l') {
      ptr++;
      for (p = field; *p; p++)
         if (isupper(*p))
            *p = (*p - 'A') + 'a';
      }
   return(ptr);
}

/* getname - get name filed  */
   int getname(n, last, first, ref)
   int  n;
   char last[], first[], ref[];
{  char *p;

   for (p = ref; *p; p++)
      if (*p == '%' & *(p+1) == 'A') {
         n--;
         if (n == 0) {
            for (p = p + 2; *p == ' '; p++) ;
            breakname(p, first, last) ;
            return(true);
            }
         }
   return(false);
}

/* disambiguate - add disambiguators */
   disambiguate()
{  int i, j;
   char adstr[2];

   for (i = 0; i < numrefs; i = j) {
      j = i + 1;
      if (strcmp(citestr[i], citestr[j])==0) {
         adstr[0] = 'a'; adstr[1] = 0;
         for (j = i+1; strcmp(citestr[i],citestr[j]) == 0; j++) {
            adstr[0] = 'a' + (j-i);
            strcat(citestr[j], adstr);
            if (j == numrefs)
               break;
            }
         adstr[0] = 'a';
         strcat(citestr[i], adstr);
         }
     }
}

/* pass2 - read pass 1 files entering citation */
   pass2(ifd, ofd)
   FILE *ifd, *ofd;
{
   char c;
   int  i, fn, footrefs[25], dumped;
   long int n;

   fn = -1;
   dumped = foot;
   while (getch(c, ifd) != EOF) {
      while (c == '\n') {
         putc(c, ofd);
         if (foot && fn >= 0) {
            for (i = 0; i <= fn; i++)
                dumpref(footrefs[i], ofd);
            fn = -1;
            }
         if (testc(c, '.', ifd, ofd))
            if (testc(c, '[', ifd, ofd))
               if (testc(c, ']', ifd, ofd)) {
                  while (echoc(c, ifd, ofd) != '\n')
                     ;
                  dumped = true;
                  for (i = 0; i <= numrefs; i++)
                     dumpref(i, ofd);
                  getch(c, ifd);
                  }
         }
      if (c == REFCHAR) {
         n = 0;
         while (isdigit(getch(c, ifd)))
            n = 10 * n + (c - '0');
         for (i = 0; i <= numrefs; i++)
            if (refspos[i] == n) {
               fputs(citestr[i], ofd);
               if (foot) {
                  fn++;
                  footrefs[fn] = n;
                  }
               }
         }
      else if (c != EOF)
         putc(c, ofd);
      }
   if (dumped == false)
      fprintf(stderr,"Warning: references never dumped\n");
}


/* dumpref - dump references */
   dumpref(i, ofd)
   int i;
   FILE *ofd;
{  char ref[REFSIZE], *p, line[REFSIZE], first[40], last[40];
   int numauths, maxauths;

   numauths = 0;
   rdref(refspos[i], ref);
   for (maxauths = 0; getname(maxauths+1, last, first, ref); maxauths++) ;
   fprintf(ofd, ".[-\n");
   fprintf(ofd, ".ds [F %s\n",citestr[i]);
   fseek(rfd, (long) refspos[i], 0);
   while (fgets(line, REFSIZE, rfd) != NULL) {
      if (line[0] == 0)
         break;
      if (line[0] == '.')
         fprintf(ofd,"%s",line);
      else {
         expand(line);
         if (line[0] == '%') {
            for (p = &line[2]; *p == ' '; p++);
            if (line[1] == 'A')
               numauths++;

            doline(line[1], p, numauths, maxauths, ofd);
            }
         }
      }
   fprintf(ofd,".][\n");
}
===== bibargs.c    =====
/*
        read argument strings for bib and listrefs
                                                        */
# include <stdio.h>
# include <ctype.h>
# define true 1
# define false 0
# define err -1
# define LINELENGTH 1024
# define MAXDEFS  500                /* maximum number of defined words */

/* global variables */
   int  abbrev = false;         /* automatically abbreviate names */
   int  sort = false;           /* sort references ? (default no) */
   int  foot = false;           /* footnoted references ? (default endnotes) */
   char sortstr[80] = "1";      /* sorting template */
   char trailstr[80] = "";      /* trailing characters to output */
   char pfile[120];             /* private file name */
   int  personal = false;       /* personal file given ? (default no) */
   char citetemplate[80] = "1"; /* citation template */
   int  numrev = 0;             /* number of authors names to reverse */
   int  capsmcap = false;       /* print names in caps small caps (CACM form) */
   char *words[MAXDEFS];        /* defined words */
   char *defs[MAXDEFS];         /* defined word definitions */
   int  wordtop = -1;           /* top of defined words array */

/* where output goes */
   extern FILE *tfd;

/* doargs */
   int doargs(argc, argv)
   int argc;
   char **argv;
{  int numfiles, i;
   char *p, *q, name[120];
   FILE *fd;

   numfiles = 0;
   for (i = 1; i < argc; i++)
      if (argv[i][0] == '-')
         switch(argv[i][1]) {
            case 'a':  abbrev = true;
                       break;

            case 'f':  foot = true;
                       break;

            case 's':  sort = true;
                       if (argv[i][2])
                          for (p = sortstr,q = &argv[i][2]; *p++ = *q++; );
                       break;

            case 'c':  if (argv[i][2] == 0)
                          error("citation string expected");
                       else
                          for (p = citetemplate,q = &argv[i][2]; *p++ = *q++; );
                       break;

            case 'p':  if (argv[i][2])
                          p = &argv[i][2];
                       else {  /* take next arg */
                          i++;
                          p = argv[i];
                          }
                       strcpy(pfile, p);
                       personal = true;
                       break;

            case 'r':  if (argv[i][2] == 0)
                          numrev = 1000;
                       else
                          numrev = atoi(&argv[i][2]);
                       break;

            case 't':  if (argv[i][2])
                          p = &argv[i][2];
                       else { /* take next arg */
                          i++;
                          p = argv[i];
                          }
                       strcpy(name,"bmac.");
                       strcat(name,p);
                       fd = fopen(name, "r");
                       if (fd == NULL) {
                          strcpy(name,"/usr/lib/bmac/bmac.");
                          strcat(name,p);
                          fd = fopen(name, "r");
                          }
                       if (fd == NULL) {
                          fprintf(stderr,"bmac.%s",p);
                          error(": can't open");
                          }
                       setswitch(fd);
                       break;

            case 'x':  capsmcap = true;
                       break;

            case 0:    rdtext(stdin);
                       numfiles++;
                       break;

            default:   fputs(argv[i], stderr);
                       error(": invalid switch");
            }
      else { /* file name */
         numfiles++;
         fd = fopen(argv[i], "r");
         if (fd == NULL) {
            fputs(argv[i], stderr);
            error(": can't open");
            }
         else {
            rdtext(fd);
            fclose(fd);
            }
         }

   return(numfiles);

}

/* error - report unrecoverable error message */
  error(str)
  char str[];
{
  fputs(str, stderr);
  putc('\n', stderr);
  exit(1);
}

/* tfgets - fgets which trims off newline */
   char *tfgets(line, n, ptr)
   char line[];
   int  n;
   FILE *ptr;
{  char *p;

   p = fgets(line, n, ptr);
   if (p == NULL)
      return(NULL);
   else
      for (p = line; *p; p++)
         if (*p == '\n')
            *p = 0;
   return(line);
}

/* getwrd - place next word from in[i] into out */
int getwrd(in, i, out)
   char in[], out[];
   int i;
{  int j;

   j = 0;
   while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t')
      i++;
   if (in[i])
      while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n')
         out[j++] = in[i++];
   else
      i = 0;    /* signals end of in[i..]   */
   out[j] = 0;
   return (i);
}

/* setswitch - set document switch settings from format file */
   setswitch(fp)
   FILE *fp;
{  char name[80], *p, line[LINELENGTH], word[80];
   int  i, j, getwrd();
   FILE *fp2;

   while (tfgets(line, LINELENGTH, fp) != NULL)
      switch(line[0]) {
         case '#': break;

         case 'A': abbrev = true;
                   break;

         case 'C': for (p = &line[1]; *p == ' '; p++) ;
                   strcpy(citetemplate, p);
                   break;

         case 'D': if ((i = getwrd(line, 1, word)) == 0)
                      error("word expected in definition");
                   for (j = 0; j <= wordtop; j++)
                      if (strcmp(word, words[j]) == 0)
                         break;
                   if (j > wordtop) {
                      if ((j = ++wordtop) > MAXDEFS)
                         error("too many defintions");
                      if ((words[wordtop] = malloc(1 + strlen(word))) == NULL)
                         error("out of definition room");
                      strcpy(words[wordtop],word);
                      }
                   for (p = &line[i]; *p == ' '; p++) ;
                   if ((defs[j] = malloc(1 + strlen(p))) == NULL)
                      error("out of definition room");
                   strcpy(defs[j], p);
                   break;

         case 'F': foot = true;
                   break;

         case 'I': for (p = &line[1]; *p == ' '; p++);
                   fp2 = fopen(p, "r");
                   if (fp2 == NULL) {
                      strcpy(name,"/usr/lib/bmac/");
                      strcat(name,p);
                      fp2 = fopen(name, "r");
                      }
                   if (fp2 == NULL) {
                      fprintf(stderr,"%s",p);
                      error(": can't open");
                      }
                   setswitch(fp2);
                   break;

         case 'R': if (line[1] == 0)
                      numrev = 1000;
                   else
                      numrev = atoi(&line[1]);
                   break;

         case 'S': sort = true;
                   for (p = &line[1]; *p == ' '; p++) ;
                   strcpy(sortstr, p);
                   break;

         case 'T': for (p = &line[1]; *p == ' '; p++) ;
                   strcpy(trailstr, p);
                   break;

         case 'X': capsmcap = true;
                   break;

         default:  fprintf(tfd,"%s\n",line);
                   while (fgets(line, LINELENGTH, fp) != NULL)
                      fputs(line, tfd);
                   return;
         }
   return;
}

/* expand - expand line, replacing defined words */
   expand(line)
   char line[];
{  char line2[LINELENGTH], word[LINELENGTH], *p, *q, *w;
   int  flag, i;

   flag  = true;
   while (flag) {
      flag = false;
      p = line;
      q = line2;
      while (*p) {
         if (isalnum(*p)) {
            for (w = word; *p && isspace(*p) == 0; )
               *w++ = *p++;
            *w = 0;
            for (i = 0; i <= wordtop; i++)
               if (strcmp(word, words[i]) == 0) {
                  strcpy(word, defs[i]);
                  flag = true;
                  break;
                  }
            for (w = word; *w; )
               *q++ = *w++;
            }
         else
            *q++ = *p++;
         }
      *q = 0;
      p = line;
      q = line2;
      while (*p++ = *q++);
      }
}

/* breakname - break a name into first and last name */
   breakname(line, first, last)
   char line[], first[], last[];
{  char *p, *q, *r, *t, *f;

   for (t = line; *t != '\n'; t++);
   for (t--; isspace(*t); t--);

   /* now strip off last name */
   for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--)
      if (q == line)
         break;
   f = q;
   if (q != line)
      q++;

   for (; isspace(*f); f--);

   /* first name is start to f, last name is q to t */

   for (r = first, p = line, f++; p != f; )
      *r++ = *p++;
   *r = 0;
   for (r = last, p = q, t++; q != t; )
      *r++ = *q++;
   *r = 0;
}

/* match - see if string1 is a substring of string2 (case independent)*/
   int match(str1, str2)
   char str1[], str2[];
{  int  i, j;
   char a, b;

   for (i = 0; str2[i]; i++) {
      for (j = 0; str1[j]; j++) {
         if (isupper(a = str2[i+j]))
            a = (a - 'A') + 'a';
         if (isupper(b = str1[j]))
            b = (b - 'A') + 'a';
         if (a != b)
            break;
         }
      if (str1[j] == 0)
         return(true);
      }
   return(false);
}

/* scopy - append a copy of one string to another */
   char *scopy(p, q)
   char *p, *q;
{
   while (*p++ = *q++)
      ;
   return(--p);
}

/* bldname - build a name field */
   bldname(first, last, name, reverse)
   char *first, *last, name[];
   int reverse;
{
   char newfirst[120], newlast[120], *p, *q, *f, *l, *scopy();
   int  flag;

   if (abbrev) {
      p = first;
      q = newfirst;
      flag = false;
      while (*p) {
         while (*p == ' ')
            p++;
         if (*p == 0)
            break;
         if (isupper(*p)) {
            if (flag)
               q = scopy(q, "\\*([d");
            flag = true;
            *q++ = *p;
            *q++ = '.';
            }
         if (*++p == '.')
            p++;
         else while (*p != 0 && ! isspace(*p))
            p++;
         }
      *q = 0;
      f = newfirst;
      }
   else
      f = first;

   if (capsmcap) {
      p = last;
      q = newlast;
      flag = 0;  /* 1 - printing cap, 2 - printing small */
      while (*p)
         if (islower(*p)) {
            if (flag != 2)
               q = scopy(q, "\\s-2");
            flag = 2;
            *q++ = (*p++ - 'a') + 'A';
            }
         else {
            if (flag == 2)
               q = scopy(q,"\\s+2");
            flag = 1;
            *q++ = *p++;
            }
      if (flag == 2)
         q = scopy(q, "\\s+2");
      *q = 0;
      l = newlast;
      }
   else
      l = last;

   if (reverse)
      sprintf(name, "%s, %s\n", l, f);
   else
      sprintf(name, "%s %s\n", f, l);
}

/* doline - actually print out line information */
   doline(c, line, numauths, maxauths, ofd)
   char c, *line;
   int numauths, maxauths;
   FILE *ofd;
{
   char first[LINELENGTH], last[LINELENGTH];

   switch(c) {
      case 'A':
          if (numauths <= numrev || abbrev || capsmcap) {
             breakname(line, first, last);
             bldname(first, last, line, numauths <= numrev);
             }
          if (numauths == 1)
             fprintf(ofd,".ds [A %s",line);
          else if (numauths < maxauths)
             fprintf(ofd,".as [A \\*(c[%s",line);
          else if (maxauths == 2)
             fprintf(ofd,".as [A \\*(n[%s",line);
          else
             fprintf(ofd,".as [A \\*(m[%s",line);
          if (index(trailstr, 'A'))
             fprintf(ofd,".ds .A %c\n",line[strlen(line)-2]);
          break;

       case 'E':
           if (match(" and ", line))
              fprintf(ofd,".nr [E 1\n");
          else
             fprintf(ofd,".nr [E 0\n");
          fprintf(ofd,".ds [E %s",line);
          if (index(trailstr, 'E'))
             fprintf(ofd,".ds .E %c\n",line[strlen(line)-2]);
          break;

       case 'P':
          if (index(line, '-'))
             fprintf(ofd,".nr [P 1\n");
          else
             fprintf(ofd,".nr [P 0\n");
          fprintf(ofd,".ds [P %s",line);
          if (index(trailstr, 'P'))
             fprintf(ofd,".ds .P %c\n",line[strlen(line)-2]);
          break;

       case 'F':
       case 'K': break;

       default:
          fprintf(ofd,".ds [%c %s", c, line);
          if (index(trailstr, c))
             fprintf(ofd,".ds .%c %c\n", c, line[strlen(line)-2]);
          }
}

===== invert.c     =====
#
/*  input:  records of lines, separated by blank lines
    output: key:file1 start/length ... start/length:file2 start/length ...
*/

# include "stdio.h"
# include "streams.h"
# define isnull(x)  (*(x) == NULL)
# define makelow(c) ('A'<=(c) && (c)<='Z' ? (c)-'A'+'a' : c)

int     max_kcnt = 100;     /*  max number of keys                      */
int     max_klen =   6;     /*  max length of keys                      */
char    *ignore =           /*  string of line starts to ignore         */
            "CNOPVX";
char    *common =           /*  name of file of common words            */
            "/usr/lib/bmac/common";
char    *INDEX=             /*  name of output file                     */
            "INDEX";

char    *tmpfile =          /*  name of temporary file                  */
            "/usr/tmp/invertXXXXXX";


char *sort_it =
        "sort -u +0 -1 +1 -2 +2n -3 +3n %s -o %s";
char sortcmd[150];

int     argc;
char    **argv;

main(argcount,arglist)
int argcount;
char **arglist;
{   char            *filename;
    FILE            *input, *output;
    long int        start,length;
    char            word[maxstr];
    int             kcnt;
    char            tag_line[100];

    long int	    records = 0;  /*  number of records read           */
    long int	    keys    = 0;  /*  number of keys read (occurences) */
    long int	    distinct;     /*  number of distinct keys          */
    long int	    shorten();

    argc= argcount-1;
    argv= arglist+1;
    mktemp(tmpfile);
    output= fopen(tmpfile,"w");

    for ( flags() ; argc>0 ; argc--, argv++ ,flags() )
    {   /* open input file              */
            filename=   *argv;
            input=      fopen(filename,"r");
            if (input==NULL)
            {   fprintf(stderr, "invert: error in open of %s\n", filename);
                continue;
            }
            start=      0L;
            length=     0L;

        for(;;) /* each record  */
        {   /* find start of next record (exit if none)     */
                start= nextrecord(input,start+length);
                if (start==EOF)   break;
            records++;
	    kcnt= 0;
            length= recsize(input,start);
            sprintf(tag_line, " %s %D %D\n", filename, start, length);

            while (ftell(input) < start+length && kcnt < max_kcnt)
            {   getword(input,word,ignore);
                makekey(word,max_klen,common);
                if (!isnull(word))
                {   fputs(word,output); fputs(tag_line,output);
                    kcnt++; keys++;
                }
            }
        }
        fclose(input);
    }
    fclose(output);

    sprintf(sortcmd, sort_it, tmpfile, tmpfile);
    system(sortcmd);

    distinct = shorten(tmpfile,INDEX);
    fprintf(stderr, "%D documents   %D distinct keys  %D key occurences\n",
	    records, distinct, keys);
}



/*  Flag    Meaning                             Default
    -ki     Keys per record                     100
    -li     max Length of keys                  6
    -%str   ignore lines that begin with %x     CNOPVX
            where x is in str
            str is a seq of chars
    -cfile  file contains Common words          /usr/src/local/bib/common
            do not use common words as keys
    -pfile  name of output file                 INDEX
*/

# define    operand     (strlen(*argv+2)==0 ? (argv++,argc--,*argv) : *argv+2)

flags()
{   for (; argc>0 && *argv[0]=='-';  argc--,argv++)
    {   switch ((*argv)[1])
        {   case 'k':   max_kcnt= atoi(operand);
                        break;
            case 'l':   max_klen= atoi(operand);
                        break;
            case 'c':   common=  operand;
                        break;
            case '%':   ignore=  *argv+2;
                        break;
            case 'p':   INDEX=  operand;
                        break;
            default:    fprintf(stderr, "unknown flag '%s'\n", *argv);
        }
    }
}


/*  shorten(inf,outf): file "inf" consists of lines of the form:
        key file start length
    sorted by key and file.  replace lines with the same key
    with one line of the form:
        key:file1 start/length ... start/length:file2 start/length ...
    rename as file "outf"
    returns number of lines in output
*/
long shorten(inf,outf)
char *inf, *outf;
{   FILE *in, *out;
    char line[maxstr];
    char key[20],  newkey[20],
         file[20], newfile[20];
    long int start, length;
    long int lines = 0;

    in=  fopen(inf, "r");
    out= fopen(outf, "w");
    if (in==NULL || out==NULL)
    {   fprintf(stderr, "invert: error in opening file for compression\n");
        return(0);
    }

    getline(in,line);
    sscanf(line,"%s%s%D%D", key, file, &start, &length);
    fprintf(out, "%s :%s %D/%D", key, file, start, length);
    for ( getline(in, line) ; !feof(in);  getline(in, line))
    {   sscanf(line,"%s%s%D%D", newkey, newfile, &start, &length);
        if (strcmp(key,newkey)!=0)
        {   strcpy(key, newkey);
            strcpy(file, newfile);
            fprintf(out, "\n%s :%s %D/%D",  key, file, start, length);
	    lines++;
        }
        else if (strcmp(file,newfile)!=0)
        {   strcpy(file,newfile);
            fprintf(out, ":%s %D/%D", file, start, length);
        }
        else
            fprintf(out, " %D/%D", start, length);
    }
    fprintf(out, "\n");
    lines++;

    fclose(in); fclose(out);
    unlink(inf);
    return (lines);
}
===== listrefs.c   =====
/*
        list all documents in ref index file
                                                        */
# include <stdio.h>
# include <ctype.h>
# include "streams.h"
# define MAXLINE 250

FILE *tfd;
int count = 0;

main(argc, argv)
   int argc;
   char **argv;
{
   FILE *ifile;

   tfd = stdout;
   fprintf(tfd,".so /usr/lib/bmac/bform.open\n");
   doargs(argc, argv);
}

/* rdtext - process a file */
   rdtext(ifile)
   FILE *ifile;
{
   long int start, length;
   int  i, numauths, kcnt;
   char word[120];

   start = length = 0L;

   for (;;) {
      start = nextrecord(ifile, start + length);
      if (start == EOF) break;
      length = recsize(ifile, start);

      /* count number of authors */
      numauths = 0;
      for (i = length; i > 0; i--)
         if (getc(ifile) == '%') {
            i--;
            if (getc(ifile) == 'A')
               numauths++;
            }
      fseek(ifile, start, 0);

      dumpref(ifile, stdout, numauths);

     }
}

/* get a line from reference file */
   char refgets(line, ifile)
   char line[];
   FILE *ifile;
{
   char c, *p;

   for (p = line;;) {
      while ((c = getc(ifile)) != '\n')
         if (c == EOF)
            return(EOF);
         else
            *p++ = c;
      c = getc(ifile);
      if (c == '.' || c == '%' || c == '\n') {
         if (c != EOF)
            ungetc(c, ifile);
         break;
         }
      }
   *p++ = '\n';
   *p = 0;
   return(c);
}

/* dump reference */
   dumpref(ifile, ofile, maxauths)
   FILE *ifile, *ofile;
   int maxauths;
{
   char line[250], *p;
   int  numauths;

   fprintf(tfd, ".[-\n");
   fprintf(tfd, ".ds [F %d\n", count++);
   numauths = 0;
   while (refgets(line, ifile) != EOF) {
      if (line[0] == '\n')
         break;
      else if (line[0] == '.')
         fprintf(ofile, "%s\n", line);
      else {
         expand(line);
         if (line[0] == '%') {
            for (p = &line[2]; isspace(*p); p++);
            if (line[1] == 'A')
               numauths++;
            doline(line[1], p, numauths, maxauths, ofile);
            }
         }
      }
   fprintf(tfd, ".][\n");
}
===== locate.c     =====
#

# include   "stdio.h"
# include   "streams.h"
# include   "ctype.h"
# define    maxrefs      200

struct reftype{
    char reffile[20];
    long int start, length;
    };

char *malloc();
char *stripkeys();
int   fetchref();

/*  locate(keys, name, max_klen, common):
        returns a string containing all references pointed to by name
        that contain all keys in keys.  common is name of common word file.
    pointer returned comes from malloc.  use free to return storage
*/
char *locate(keys,name,max_klen,common)
char *keys, *name, *common;
int  max_klen;          /* max key length */
{   static  char oldname[maxstr] = "";  /* oldname is name of stream index */
    static  FILE *index = NULL;
    static  long int i_size;            /* size of index                   */
    static  char oldtext[maxstr];       /* oldtext is suffix of stream text*/
    static  FILE *text = NULL;
    static  int  pathlen;

    int  len;
    char key[maxstr];                   /* refs[i] is a line of index for  */
    struct reftype  refs[maxrefs];      /* all keys up to key              */

    int  refcnt, copied, comp;          /* refcnt = # of refs               */
                                        /* copied = # of refs copied        */
                                        /* comp   = # of refs compared      */
    struct reftype ref;
    char   str[maxstr];
    int    more;

    long int ans;
    int i,j;
    unsigned total;
    char *allrefs, *next;               /* all refs (separated by null line)*/
    char *p;

    /*  open index */
        if  (strcmp(oldname,name)!=0)
        {   if (index) fclose(index);
            if (text) fclose(text);
            strcpy(oldname,name);
            strcpy(oldtext,"");
            /*  determine pathlen   */
                p= rindex(oldname, '/');
                if      (p!=NULL)           pathlen= p-oldname+1;
                else if (oldname[0]==':')   pathlen= 1;
                else                        pathlen= 0;

            index= fopen(oldname,"r");
            if (index==NULL)
            {   fprintf(stderr, "locate: cannot open %s\n", oldname);
                return(NULL);
            }
            else
            {   fseek(index,0L,2);     /*  seeks last newline      */
                i_size= ftell(index);
            }

        }

    /*  load references to first key  */
        keys= stripkeys(keys,key, max_klen, common);
            if (*key==NULL) { fprintf(stderr,"locate: no keys for citation\n");
			      allrefs = malloc(1);
			      if (allrefs==NULL)
	  		      {fprintf(stderr, 
			         "locate: insufficient space for references\n");
			       return(NULL);
			      }
			      *allrefs= NULL;
			      return(allrefs);
                            }
        len= strlen(key);
        strcat(key," ");
        alpha_seek(index, key, i_size, 0);
        key[len]= NULL;                     /*  strip blank off */

        refcnt= 0;
        fscanf(index,"%s ", str);
        if (strcmp(str,key) == 0)
        {   str[0]= NULL;
            while (refcnt < maxrefs && fetchref(index, str, &ref) )
            {   refs[refcnt]= ref;
                refcnt++;
            }
        }

        if (refcnt==maxrefs)
            fprintf(stderr,"locate: first key (%s) matched too many refs\n", key);

    /*  intersect the reference sets for remaining keys with first set */
        while (*keys!=NULL)
        {   keys= stripkeys(keys, key, max_klen, common);
            if (*key==NULL) continue;

            len= strlen(key);
            strcat(key," ");
            alpha_seek(index, key, i_size, 0);
            key[len]= NULL;

            fscanf(index,"%s ", str);
            if (strcmp(str,key) != 0)  refcnt= 0;   /*  no matching refs */

            copied= 0; comp= 0; more= fetchref(index, str, &ref);
            while (comp < refcnt && more)
            {   /*  ans= ref-refs[comp]    */
                    ans= strcmp(ref.reffile, refs[comp].reffile);
                    if (ans==0)     ans= ref.start-refs[comp].start;
                    if (ans==0)     ans= ref.length-refs[comp].length;
                if (ans<0)  more= fetchref(index, str, &ref);
                if (ans==0) { refs[copied]= refs[comp]; comp++; copied++;
                              more= fetchref(index, str, &ref);}
                if (ans>0)  comp++;
            }

            refcnt= copied;
        }

    total= 0;
    for (i=0; i<refcnt; i++)    total += refs[i].length+1;

    allrefs= malloc(total+1);
    if (allrefs==NULL)
    {   fprintf(stderr, "locate: insufficient space for references\n");
        return(NULL);
    }

    /* copy refs into allrefs */
        next= allrefs;
        for (i=0; i<refcnt; i++)
        {   /*  open text */
                if (strcmp(oldtext,refs[i].reffile) != 0)
                {   strcpy(oldtext,refs[i].reffile);
                    strncpy(str, oldname, pathlen);  str[pathlen]= NULL;
                    strcat(str, oldtext);
                    if (text) fclose(text);
                    text= fopen(str, "r");
                    if (text==NULL)
                    {   fprintf(stderr, "locate: cannot open %s\n", str);
                        return(NULL);
                    }
                }
            fseek(text, refs[i].start, 0);
            for (j=0; j<refs[i].length; j++)    *next++ = getc(text);
            *next++ = '\n';
        }
        *next = NULL;
    return(allrefs);
}



/*  stripkeys(line,key,max_klen, common):
        assigns to key the first key in line
        and returns a pointer to the position following the key
*/
char *stripkeys(line,key,max_klen,common)
char *line, *key;
int  max_klen;
char *common;
{   char *p;

    do
    {   while (isspace(*line))   line++;

        p= key;
        while (*line!=NULL && !isspace(*line))
        {   *p++ = *line++;
        }
        *p= NULL;

        makekey(key, max_klen, common);
    }   while (*key==NULL && *line!=NULL);
    return(line);
}

/*  read a reference pair from stream into *ref.  if file not given,
    use oldfile. return 1 if pair found, 0 ow.
*/
int fetchref(stream, oldfile, ref)
FILE *stream;
char *oldfile;
struct reftype *ref;
{   char cntl;

    fscanf(stream, "%c", &cntl);
    if (cntl=='\n') {return (0);}
    if (cntl==':')  fscanf(stream, "%s", oldfile);
    strcpy(ref->reffile, oldfile);
    fscanf(stream, "%D/%D", &ref->start, &ref->length);
    return(1);
}
===== lookup.c     =====
# include "stdio.h"
# include "streams.h"
char *locate();

int     max_klen =   6;     /*  max length of keys                      */
char    *common =           /*  name of file of common words            */
            "/usr/lib/bmac/common";
char    *INDEX=             /*  name of index file                      */
            "INDEX";

# define DEPT_FILE      "/usr/dict/papers/INDEX"

int     argc;
char    **argv;

main(argcount,arglist)
int argcount;
char **arglist;
{   char *refs;
    char keys[maxstr];
    char failed;

    failed= 0;
    argc= argcount-1;
    argv= arglist+1;
    flags();

    while (fgets(keys,maxstr,stdin)!=NULL)
    {   if (!failed)
        {   refs= locate(keys, INDEX, max_klen, common);
            failed= (refs==NULL);
        }
        else    refs= NULL;
        if (refs==NULL || *refs==NULL)
            refs= locate(keys, DEPT_FILE, max_klen, common);
        if (refs==NULL || *refs==NULL)  printf("No references found.\n");
        else                            printf("%s", refs);
        if (refs!=NULL) free(refs);
    }
}

# define    operand     (strlen(*argv+2)==0 ? (argv++,argc--,*argv) : *argv+2)

flags()
{   for (; argc>0 && *argv[0]=='-';  argc--,argv++)
    {   switch ((*argv)[1])
        {   case 'l':   max_klen= atoi(operand);
                        break;
            case 'c':   common=  operand;
                        break;
            case 'p':   INDEX=  operand;
                        break;
            default:    fprintf(stderr, "unknown flag '%s'\n", *argv);
        }
    }
}
===== makekey.c    =====
#

# include "stdio.h"
# include "ctype.h"
# define  maxcomm       300

char    commlist[maxcomm]=   /*  list of strings of common words         */
     "";
int firsttime = 1;

/*  makekey(p,max_klen,common):  compresses *p into a key
        folds upper to lower case.  ignores non-alphanumeric
        drops keys of length <= 1.
        drops words in common (name of file of words, one per line)
            (first call determines common for all later calls)
*/
makekey(p,max_klen,common)
char *p;
int  max_klen;          /* max key length */
char *common;
{   register char *from, *to, *stop;

    if (firsttime) {firsttime= 0; load_comm(common); }

    from= p; to= p; stop= max_klen+p;
    while (*from != NULL  &&  to < stop)
    {   if      (islower(*from))      *to++ = *from++;
        else if (isdigit(*from))      *to++ = *from++;
        else if (isupper(*from))    { *to++ = tolower(*from);  from++; }
        else                          from++;
    }
    *to= NULL;

    if (to<=p+1 ||
        lookup(commlist, p) )  *p= NULL;
}

/*  list is a string of null terminated strings, final string is null.
    p is a null terminated string.
    return 1 if p is a string in list, 0 ow.
*/
int lookup(list,p)
char *list, *p;
{   int len;
    len= strlen(list);
    while (len!=0 && strcmp(list,p)!=0)
    {   list += (len+1);
        len= strlen(list);
    }
    return(len!=0);
}

/*  read file common into commlist
*/
load_comm(common)
char *common;
{   FILE    *commfile;          /*  stream of common words                  */
    char *p, *stop;
    commfile= fopen(common,"r");
    if (commfile==NULL) fprintf(stderr, "cannot open '%s'\n", common);
    else
    {   /* read commfile into commlist  */
            p= commlist;    stop= commlist+maxcomm-1;
            while (p<stop && ((*p= getc(commfile))!=EOF))
            {   if (*p=='\n')   *p= NULL;
                p++;
            }
            if  (*p==EOF)  *p= NULL;
            else
            {   fprintf(stderr, "invert: too many common words\n");
                commlist[0]= NULL;
            }
        fclose(commfile);
    }
}

===== streams.c    =====
#

# include "stdio.h"
# include "streams.h"
# include "ctype.h"

/*  getword(stream,p,ignore):
        read next sequence of nonspaces on current line into *p.
    null if no more words on current line.
    %x (x in ignore) terminates line.
    all words of the form %a are returned as null.
    *p is a null terminated string (char p[maxstr]).
*/
getword(stream,p,ignore)
FILE *stream;
char *p, *ignore;
{   char c;
    char *oldp, *stop;

    oldp= p;
    stop= p+maxstr-1;
    do{ c= getc(stream);
    }   while (isspace(c) && c!='\n');

    while (!isspace(c))
    {   *p= c;
        if (p < stop)  p++;
        c= getc(stream);
    }
    *p= NULL;

    if (oldp[0]=='%')
    {   oldp[0]= NULL;
        if (index(ignore, oldp[1]) != NULL)
            while (c!='\n') c=getc(stream);
    }
}



/*  recsize(stream,start):
    returns length of record beginning at start
    (record ends at blank line or eof)
    assumes and retains stream positioned at start
*/
long int recsize(stream,start)
FILE *stream;
long int start;
{   char c;                 /*  length = # of chars from start to beginning */
    long int length;        /*  of current line.  c in current line.        */
    int nonspaces;          /*  nonspaces = # of nonspaces in current line. */

    nonspaces= 0;
    c= getc(stream);
    length= 0L;

    while ( (c!='\n' || nonspaces!=0) && c!=EOF)
    {   if      (c=='\n')
        {   length= ftell(stream)-start;
            nonspaces= 0;
        }
        else if (!isspace(c))    nonspaces++;

        c= getc(stream);
    }

    pos(start);
    return(length);
}


/*  nextrecord(stream,x): seeks in stream for first non-blank line
        at or after char x in stream. seeks to eof if x is past last record.
        x is the index of a character in the file (not eof).
    returns position in stream.  (returns EOF, if seeks to EOF)
*/
long int nextrecord(stream,x)
FILE *stream;
long int x;
{   long int start;         /*  position of the beginning of the line  */
    char c;                 /*      containing c                       */

    pos(x);
    start= x;
    /*  find start of first non-blank record        */
        for(;;)
        {   c= getc(stream);
            if      (c=='\n')           start= ftell(stream);
            else if (!isspace(c))       break;
        }

    if (feof(stream))   { pos(start);  start= EOF;  }
    else                pos(start);
    return(start);
}

/*  nextline(stream,x): seeks in stream after first newline at or after
        char x in stream. seeks to eof if x is in last line.
        x is the index of a character in the file (not eof).
    returns position in stream
*/
long int nextline(stream,x)
FILE *stream;
long int x;
{   pos(x);
    while (getc(stream)!='\n') ;
    return(ftell(stream));
}


/*  printline(stream): copies stream up to a newline
*/
printline(stream)
FILE *stream;
{   char c;
    while ((c=getc(stream)) != '\n' && c!=EOF)  putchar(c);
    putchar('\n');
}

/*  getline(stream,p):  store in *p next chars in stream up to \n
        advance stream past \n.
    limit of  maxstr-1 chars may be stored at p.
*/
getline(stream,p)
FILE *stream;
char *p;
{   char *stop;
    stop= p+maxstr-1;
    while ( (*p= getc(stream)) != '\n' && *p!=EOF)
        if (p<stop)    p++;
    *p= NULL;
}
===== streams.h    =====
#

long int nextrecord(), recsize(), nextline();

# define  maxstr            256
# define  pos(x)            fseek(stream,x,0)

whm (11/13/82)

The following files are a reference guide for writing macros for the
bib program and a collection of macro packages 
and support files that are used at
Arizona.  The macros only handle the bibliographic aspects and are
intended to be used with some other macro package (me, ms, or your
local favorite).
The support files are explained in the reference guide.

The files must be placed in /usr/lib/bmac as that is where bib expects
them.  The file common should also be placed in this directory.

See other posting for bib source, reference guide, and man pages.

===== refdoc             =====
.de Ex
.sp
.QS
.nf
..
.ce 100
\fBReference File Formats\fP
.ce 0
.sp
.PP
A reference file is simply a file containing any number of reference
items.  Reference items are separated by one or more blank lines.
There are no restrictions placed on the order of items in a file,
although generally users will want to impose some order (such as sorting
items alphabetically) to simplify updates.
.PP
A reference item is simply a collection of field tags and values.
A field tag is a percent sign followed by a single letter.
Currently the following field tags are recognized:
.Ex
.ta 0.5i
A	Author's name
B	Title of book containing item
C	City of publication
D	Date
E	Editor(s) of book containing item
F	Caption
G	Government (NTIS) ordering number
I	Issuer (publisher)
J	Journal name
K	Keys for searching
N	Issue number
O	Other information
P	Page(s) of article
R	Technical report number
S	Series title
T	Title
V	Volume number
W	Where the item can be found locally
.QE
.PP
With the exception of the author field, each field can occur only once
in any reference.  The field information is as long as necessary,
and can extend onto new lines.
Lines that do not begin with a percent sign or a period
are treated as continuations of the previous line.
The order of fields is irrelevant, except that authors
are listed in the order of occurrence.
.PP
Generally a reference will fall into one of several basic categories.
An example of each and a brief comment is given below.  With less
standard references (Archival Sources, Correspondence, Government
Documents, Newspapers) generally some experimentation will be necessary.
.SH
Books
.PP
A book is something with a publisher that isn't a journal article or
a technical report.  Generally books also have authors and titles
and dates of publication (although some don't).  For books not published
by a major publishing house it is also helpful to give a city for the
publisher.  Some government documents also qualify as books, so a book
may have a government ordering number.
.PP
It is conventional that the authors names appear in the reference in
the same form as on the title page of the book.  Note also that
string definitions are provided for most of the major publishing houses
(PRHALL for Prentice-Hall, for example).
.Ex
%A R. E. Griswold
%A J. F. Poage
%A I. P. Polonsky
%T The SNOBOL4 Programming Language
%I PRHALL
%D second edition 1971
.QE
.PP
Sometimes a book (particularly old books) will have no listed publisher.
The reference entry must still have an I field.
.Ex
%A R. Colt Hoare
%T A Tour through the Island of Elba
%I (no listed publisher)
%C London
%D 1814
.QE
.PP
If a reference database contains entries from many people (such
as a departmental-wide database) The W field can be used to indicate
where the referenced item can be found; using the initials of the owner,
for example.
Any entry style can take a W field, since this field is not used in
formating the reference.
.PP
The K field is used to define general subject categories for an entry.
This is useful in locating all entries pertaining to a specific subject
area.
.Ex
%A Dennie Van\e Tassel
%T Program Style, Design, Efficiency,
Debugging and Testing
%I PRHALL
%D 1978
%W tab
%K testing debugging
.QE
.SH
Journal article
.PP
The only requirement for a journal article is that it have a
journal name and a volume number.
Usually journal articles will also have authors, titles, page
numbers, and a date of publication.  They may also have numbers, and,
less frequently, a publisher.  (Generally publishers are only listed for
obscure journals).
.PP
Note that string names (such as CACM for \fICommunications of the ACM\fP
are defined for most major journals.
There are also string names for the months of the year, so that months
can be abbreviated to the first three letters.
Note also in this example the use of the K field to define a short
name (hru) which can be used in searching for the reference.
.Ex
%A M. A. Harrison
%A W. L. Ruzzo
%A J. D. Ullman
%T Protection in Operating Systems
%J CACM
%V 19
%N 8
%P 461-471
%D AUG 1976
%K hru
.QE
.SH
Article in conference proceedings
.PP
An article from a conference is printed as though it were a journal
article and the journal name was the name of the conference.
Note that string names (SOSP) are also defined for the major
conferences (Symposium on Operating System Principles).
.Ex
%A M. Bishop
%A L. Snyder
%T The Transfer of Information and Authority
in a Protection System
%J Proceedings of the 7th SOSP
%P 45-54
%D 1979
.QE
.SH
Article in book
.PP
An article in a book has two titles, the title of the article and the title
of the book.  The first goes into the T field and the second into the B
field.  Similarly the author of the article goes into the A field and the
editor of the book goes into the E field.
.Ex
%A John B. Goodenough
%T A Survey of Program Testing Issues
%B Research Directions in Software Technology
%E Peter Wegner
%I MIT Press
%P 316-340
%D 1979
.QE
.PP
Unlike author fields, which can be repeated, if a work as more than
one editor they are all listed in a single E field.
.Ex
%A R. J. Lipton
%A L. Snyder
%T On Synchronization and Security
%E R. A. DeMillo, D. P. Dobkin, A. K. Jones and R. J. Lipton
%B Foundations of Secure Computation
%P 367-388
%I ACPRESS
%D 1978
.QE
.PP
Sometimes the book is part of a multi-volume series, and hence may
contain a volume field and/or a series name.
.Ex
%A C.A.R. Hoare
%T Procedures and parameters: An axiomatic approach
%B Symposium on semantics of algorithmic languages
%E E. Engeler
%P 102-116
%S Lecture Notes in Mathematics
%V 188
%I Springer-Verlag
%C Berlin-Heidelberg-New York
%D 1971
.QE
.PP
In any reference format, the O field can be used to give additional information.
This is frequently used, for example, for secondary references.
.Ex
%A Girard
%A J-C Rault
%T A Programming Technique for Software Reliability
%B Symposium on Software Reliability
%I IEEE
%C Montvale, New Jersey
%D 1977
%O (Cited in Glib [32])
.QE
.SH
Compilations
.PP
A compilation is the work of several authors gathered together by an editor
into a book.  In fact the reference format is the same as for a book, with
the editor(s) taking the place of the author.
Note the word "editors" has been added to the last author field.
.Ex
%A R. A. DeMillo
%A D. P. Dobkin
%A A. K. Jones
%A R. J. Lipton,\e editors
%T Foundations of Secure Computation
%I ACPRESS
%D 1978
.QE
.SH
Technical Reports
.PP
A technical report must have a report number.  They usually have authors,
titles, dates and an issuing institution (the I field is used for this).
They may also have a city and a government issue number.  Again string
values (UATR for \*(oqUniversity of Arizona Technical Report\*(cq) will
frequently simplify typing references.
.Ex
%A T. A. Budd
%T An APL Complier
%R UATR 81-17
%D 1981
.QE
.PP
If the institution name is not part of the technical report number, then
the institution should be given separately.
.Ex
%A Douglas Baldwin
%A Frederick Sayward
%T Heuristics for Determining Equivalence of Program Mutations
%R Technical Report Number 161
%I Yale University
%D 1979
.QE
.SH
PhD Thesis
.PP
A PhD thesis is listed as if it were a book, and the institution granting
the degree the publisher.
.Ex
%A Martin Brooks
%T Automatic Generation of Test Data for
Recursive Programs Having Simple Errors
%I PhD Thesis, Stanford University
%D 1980
.QE
.PP
Some authors prefer to treat Masters and Bachelor theses similarly, although
most references on style instruct say to treat a masters degree as an
article or as a report.
.Ex
%A A. Snyder
%T A Portable Compiler for the Language C
%R Master's Thesis
%I M.I.T.
%D 1974
.QE
.SH
Miscellaneous
.PP
A miscellaneous object is something that does not fit into any other form.
It can have any of the the following fields; an author, a title, a date,
page numbers, and, most generally, other information (the O field).
.PP
Any reference item can contain an F field, and the corresponding text
will override whatever citation would otherwise be constructed.
.Ex
%F BHS--
%A Timothy A. Budd
%A Robert Hess
%A Frederick G. Sayward
%T User's Guide for the EXPER Mutation Analysis system
%O (Yale university, memo)
.QE
===== bform.open         =====
.ds [ [
.ds ] ]
.ds , ,\|
.ds <. \ \&
.ds <, \ \&
.ds >. .
.ds >, ,
.ds c[ ,\0
.ds n[ \0and\0
.ds m[ , and\0
.\"
.de s[   \" start reference
.nh
.IP [\\*([F]\0  \\n(a[
..
.de e[   \" end reference
.[-
..
.de []   \" start to display collected references
.SH
References
.LP
..
.de ][   \" choose format
.ie !"\\*([J""     .nr t[ 1    \" journal
.el .ie !"\\*([B"" .nr t[ 3    \" article in book
.el .ie !"\\*([R"" .nr t[ 4    \" technical report
.el .ie !"\\*([I"" .nr t[ 2    \" book
.el                .nr t[ 0    \" other
.\\n(t[[
..
.de 0[   \" other
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.br
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.br
.if !~\\*([O~~ \\*([O\c
.if !~\\*([D~~ , \\*([D\c
\&.
.e[
..
.de 1[ \" journal article
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.br
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.br
.ds a[ \\fI\\*([J\\fP
.ie !"\\*([V"" \{\
.       as a[ , \\*([V
.       if !~\\*([N~~ .as a[ (\\*([N)
.       if !~\\*([P~~ .as a[ :\\*([P\}
.el .if !~\\*([P~~ .as a[ , pages \\*([P
.if !~\\*([I~~ .as a[ , \\*([I
.if !~\\*([D~~ .as a[ , \\*([D
\\*(a[.
.br
.if !~\\*([O~~ \\*([O
.e[
..
.de 2[ \" book
.s[
.if !~\\*(.A~.~ .as [A .
.ie !"\\*([A"" \\*([A
.el .if !~\\*([E~~ \{\
.       ie \\n([E \\*([E, editors.
.       el \\*([E, editor.\}
.br
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\fI\\*([T\\fP
.br
.rm a[
.if !~\\*([I~~ .ds a[ \\*([I
.if !~\\*([C~~ \{\
.       if !~\\*(a[~~ .as a[ ,\\0
.       as a[ \\*([C\}
.if !~\\*([D~~ \{\
.       if !~\\*(a[~~ .as a[ ,\\0
.       as a[ \\*([D\}
\\*(a[.
.br
.if !~\\*([G~~ Government ordering number \\*([G.
.br
.if !~\\*([O~~ \\*([O.
.e[
..
.de 3[ \" article in book
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.br
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.br
.if !~\\*([P~~ pp. \\*([P\0\c
in \\fI\\*([B\\fP\c
.if !~\\*([V~~ , Vol \\*([V\c
.if !~\\*([E~~ , ed. \\*([E\c
\&.
.br
.if !~\\*([I~~ \\*([I\c
.if !~\\*([C~~ , \\*([C\c
.if !~\\*([D~~ , \\*([D\c
\&.
.if !~\\*([O~~ \\*([O.
.e[
..
.de 4[ \" report
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.br
.if !~\\*(.T~.~ .as [T .
\\*([T
.br
\\*([R\c
.if !~\\*([G~~ \& (\\*([G)\c
.if !~\\*([I~~ , \\*([I\c
.if !~\\*([C~~ , \\*([C\c
.if !~\\*([D~~ , \\*([D\c
\&.
.br
.if !~\\*([O~~ \\*([O.
.e[
..
.de [-   \" clean up after yourself
.rm [A [B [C [D
.rm [E [F [G
.rm [I [J [K
.rm [N [O [P
.rm [R [T
.rm [V [W
.rm .A .T
..

===== bform.std          =====
.ds [ [
.ds ] ]
.ds , ,\|
.ds <. \ \&
.ds <, \ \&
.ds >. .
.ds >, ,
.ds c[ ,\0
.ds n[ \0and\0
.ds m[ , and\0
.\"
.de s[   \" start reference
.nh
.IP [\\*([F]\0  \\n(a[
..
.de e[   \" end reference
.[-
..
.de []   \" start to display collected references
.SH
References
.LP
..
.de ][   \" choose format
.ie !"\\*([J""     .nr t[ 1    \" journal
.el .ie !"\\*([B"" .nr t[ 3    \" article in book
.el .ie !"\\*([R"" .nr t[ 4    \" technical report
.el .ie !"\\*([I"" .nr t[ 2    \" book
.el                .nr t[ 0    \" other
.\\n(t[[
..
.de 0[   \" other
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.if !~\\*([O~~ \\*([O\c
.if !~\\*([D~~ , \\*([D\c
\&.
.e[
..
.de 1[ \" journal article
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.ds a[ \\fI\\*([J\\fP
.ie !"\\*([V"" \{\
.       as a[ , \\*([V
.       if !~\\*([N~~ .as a[ (\\*([N)
.       if !~\\*([P~~ .as a[ :\\*([P\}
.el .if !~\\*([P~~ .as a[ , pages \\*([P
.if !~\\*([I~~ .as a[ , \\*([I
.if !~\\*([D~~ .as a[ , \\*([D
\\*(a[.
.if !~\\*([O~~ \\*([O
.e[
..
.de 2[ \" book
.s[
.if !~\\*(.A~.~ .as [A .
.ie !"\\*([A"" \\*([A
.el .if !~\\*([E~~ \{\
.       ie \\n([E \\*([E, editors.
.       el \\*([E, editor.\}
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\fI\\*([T\\fP
.rm a[
.if !~\\*([I~~ .ds a[ \\*([I
.if !~\\*([C~~ \{\
.       if !~\\*(a[~~ .as a[ ,\\0
.       as a[ \\*([C\}
.if !~\\*([D~~ \{\
.       if !~\\*(a[~~ .as a[ ,\\0
.       as a[ \\*([D\}
\\*(a[.
.if !~\\*([G~~ Government ordering number \\*([G.
.if !~\\*([O~~ \\*([O.
.e[
..
.de 3[ \" article in book
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.if !~\\*(.T~.~ .as [T .
.if !~\\*([T~~ \\*([T
.if !~\\*([P~~ pp. \\*([P\0\c
in \\fI\\*([B\\fP\c
.if !~\\*([V~~ , Vol \\*([V\c
.if !~\\*([E~~ , ed. \\*([E\c
\&.
.if !~\\*([I~~ \\*([I\c
.if !~\\*([C~~ , \\*([C\c
.if !~\\*([D~~ , \\*([D\c
\&.
.if !~\\*([O~~ \\*([O.
.e[
..
.de 4[ \" report
.s[
.if !~\\*(.A~.~ .as [A .
.if !~\\*([A~~ \\*([A
.if !~\\*(.T~.~ .as [T .
\\fI\\*([T\\fP
\\*([R\c
.if !~\\*([G~~ \& (\\*([G)\c
.if !~\\*([I~~ , \\*([I\c
.if !~\\*([C~~ , \\*([C\c
.if !~\\*([D~~ , \\*([D\c
\&.
.if !~\\*([O~~ \\*([O.
.e[
..
.de [-   \" clean up after yourself
.rm [A [B [C [D
.rm [E [F [G
.rm [I [J [K
.rm [N [O [P
.rm [R [T
.rm [V [W
.rm .A .T
..

===== bib.fullnames      =====
# full journal names, and other names
#
# journals
D ACTA Acta Informatica
D BIT B\&IT
D BSTJ Bell System Technical Journal
D CACM Communications of the ACM
D COMP Computer
D COMPJOUR The Computer Journal
D COMPLANG Computer Languages
D COMPSUR ACM Computer Surveys
D I&C Information and Control
D IEEETSE IEEE Transactions on Software Engineering
D IEEETC IEEE Transactions on Computers
D IPL Information Processing Letters
D JACM Journal of the ACM
D JCSS Journal of Computer and System Sciences
D NMATH Numerical Mathematics
D SIAMJC Siam Journal on Computing
D SIAMJNA Siam Journal on Numerical Analysis
D SIGACT S\&IGACT News
D SIGPLAN SI\&GPLAN Notices
D SIGSOFT Software Engineering Notes
D SP&E Software \(em Practice & Experience
D TODS ACM Transactions on Database Systems
D TOMS ACM Transactions on Mathematical Software
D TOPLAS ACM Transactions on Programming Languages and Systems
#
# conferences
#
D POPL ACM Symposium on Principles of Programming Languages
D POPL5 Conference Record of the Fifth POPL
D POPL6 Conference Record of the Sixth POPL
D POPL7 Conference Record of the Seventh POPL
D POPL8 Conference Record of the Eighth POPL
D POPL9 Conference Record of the Ninth POPL
D POPL10 Conference Record of the Tenth POPL
D STOC Annual ACM Symposium on Theory of Computing
D FOCS Annual Symposium on Foundations of Computer Science
D SOSP Symposium on Operating System Principles
D ICSE International Conference on Software Engineering
#
#  publishers
#
D ACPRESS Academic Press
D PRHALL Prentice Hall
D WILEY Wiley
#
# months
#
D JAN January
D FEB February
D MAR March
D APR April
D MAY May
D JUN June
D JUL July
D AUG August
D SEP September
D OCT October
D NOV November
D DEC December
#
#  miscelaneous
#
D UATR University of Arizona Technical Report
D DPCS  Department of Computer Science
D CSDP Computer Science Department
===== bib.open           =====
#
#  open format macros
#  style adapted from "A Handbook for Scholars"
#                     by Mary-Claire van Leunen
#
#  (check for periods following author and titles)
T AT
.so /usr/lib/bmac/bform.open
===== bib.std            =====
#
#  standard format macros
#  style adapted from "A Handbook for Scholars"
#                     by Mary-Claire van Leunen
#
# (detect periods at end of authors, titles)
T AT
.so /usr/lib/bmac/bform.std
===== bmac.hnf           =====
#
#  Hanson Normal Form
#
SAD-2
CA3lD-2
A
I /usr/lib/bmac/bib.fullnames
.ds [ [
.ds ] ]
.ds , ,
.ds <. \ \&
.ds <, \ \&
.ds >. .
.ds >, ,
.ds c[ ,\0
.ds n[ \0and\0
.ds m[ , and\0
.\"
.de s[   \" start reference
.nh
.IP [\\*([F] 2m
.br
..
.de e[   \" end reference
.[-
..
.de []   \" start to display collected references
.SH
References
.LP
..
.de ][   \" choose format
.ie !"\\*([J"" \{\
.    ie !"\\*([V"" .nr t[ 1    \" journal
.    el            .nr t[ 5    \" conference paper
.\}
.el .ie !"\\*([B"" .nr t[ 3    \" article in book
.el .ie !"\\*([R"" .nr t[ 4    \" technical report
.el .ie !"\\*([I"" .nr t[ 2    \" book
.el                .nr t[ 0    \" other
.\\n(t[[
..
.de 0[   \" other
.s[
.if !"\\*([A"" \\*([A.
.if !"\\*([T"" \\*([T.
.if !"\\*([O"" \\*([O\c
.if !"\\*([D"" , \\*([D\c
\&.
.e[
..
.de 1[ \" journal article
.s[
.if !"\\*([A"" \\*([A,
.if !"\\*([T"" \\*([T,
\\fI\\*([J\\fP
\\fI \\*([V\\fP,
.if !"\\*([N"" \\*([N
.if !"\\*([D"" (\\*([D),
.if !"\\*([P"" \\*([P\c
.if !"\\*([I"" , \\*([I\c
\\&.
.if !"\\*([O"" \\*([O.
.e[
..
.de 2[ \" book
.s[
.ie !"\\*([A"" \\*([A,
.el .if !"\\*([E"" \{\
.       ie \\n([E \\*([E, editors,
.       el \\*([E, editor,\}
.if !"\\*([T"" \\fI\\*([T\\fP,
.rm a[
.if !"\\*([I"" .ds a[ \\*([I
.if !"\\*([C"" \{\
.       if !"\\*(a["" .as a[ ,\\0
.       as a[ \\*([C\}
.if !"\\*([D"" \{\
.       if !"\\*(a["" .as a[ ,\\0
.       as a[ \\*([D\}
\\*(a[.
.if !"\\*([G"" Government ordering number \\*([G.
.if !"\\*([O"" \\*([O.
.e[
..
.de 3[ \" article in book
.s[
.if !"\\*([A"" \\*([A.
.if !"\\*([T"" \\*([T.
.if !"\\*([P"" pp. \\*([P\0\c
in \\fI\\*([B\\fP\c
.if !"\\*([V"" , Vol \\*([V\c
.if !"\\*([E"" , ed. \\*([E\c
\&.
.if !"\\*([I"" \\*([I\c
.if !"\\*([C"" , \\*([C\c
.if !"\\*([D"" , \\*([D\c
\&.
.if !"\\*([O"" \\*([O.
.e[
..
.de 4[ \" report
.s[
.if !"\\*([A"" \\*([A,
\\*([T,\\*([R\c
.if !"\\*([G"" \& (\\*([G)\c
.if !"\\*([I"" , \\*([I\c
.if !"\\*([C"" , \\*([C\c
.if !"\\*([D"" , \\*([D\c
\&.
.if !"\\*([O"" \\*([O.
.e[
..
.de [-   \" clean up after yourself
.rm [A [B [C [D
.rm [E [F [G
.rm [I [J [K
.rm [N [O [P
.rm [R [T
.rm [V [W
..


===== bmac.opena         =====
#
#  standard open alphabetic format
#
SAD-2
C2D-2
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.open
# a[ - amount to indent reference
.nr a[ 8
===== bmac.openn         =====
#
#  standard open numeric format
#
SAD-2
C1
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.open
# a[ - amount to indent references
.nr a[ 5
===== bmac.stda          =====
#
#  standard alphabetic format
#
SAD-2
C2D-2
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.std
# a[ - amount to indent reference
.nr a[ 8
===== bmac.stdn          =====
#
#  standard numeric format
#
C1
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.std
# a[ - amount to indent references
.nr a[ 5
===== bmac.stdsn         =====
#
#  standard sorted numeric
#
SAD-2
I /usr/lib/bmac/bmac.stdn
===== bmac.supn          =====
#
#  standard superscripted numeric format
#
C1
I /usr/lib/bmac/bib.fullnames
I /usr/lib/bmac/bib.std
# redefine string for citations
.ds [ \u
.ds ] \d
.ds >.
.ds <. .
.ds >,
.ds <, ,
.nr a[ 5
===== common             =====
and
for
the
an
be
of
in
at
on
by
to
no
as
tr
with
some
about
jan
feb
mar
apr
may
june
jun
july
jul
aug
sep
sept
oct
nov
dec