A package for footnote-style bibliographical references

Federico Garcia

                      feg8@pitt.edu

2002/12/25

1 Introduction

The basic bibliography styles of L^{A}TEX 2ε and BibTEX, with labels between [ and ], are very foreign to the common uses of humanities-writing. In recent times, the category of bibliographical styles known as ‘author-date’ seem to be gaining acceptance and becoming the most usual way to refer to a final list of references and have been successfully implemented in L^{A}TEX and BibTEX, for example in packages such as achicago and harvard.

But certain disciplines—I have in mind musicology—still use, almost exclusively, the ‘old way’ of footnote-referencing, above all in journal articles, which do not have a final list of ‘References’ to which any key can refer. Author-year styles have the significant drawback that the labels interfere with the reading; and, as Susan King and Oren Patashnik point out in their ‘Editorial note’ in the apalike.bst file, the main reason to use them (that changes to the bibliography does not mean “changing numbers in both references and text”) is rendered weakest by computerized typography. As far as I know, the ‘footnote category’ of bibliographical styles has not been particularly addressed by package-writers. This is what opcit intends to do.

Actually, there is a package intended to place the bibliography as footnotes, namely footbib.^{1} In this package, the labels appear as superscripts—^{[1]}—and the information about the source is appended to the bottom of the page. It is not, however, really a footnote, for their numbering is independent, and if other footnotes (not reference-ones) appear, they appear separated from the referenceones. In this way, the whole approach is a kind of ‘hybrid’ between label-oriented and footnote-oriented bibliographical styles.

The system I provide with opcit makes the references footnotes in every sense. On the other hand, as is usual in this kind of style, it keeps track of what sources have already been cited, in order to avoid multiple copies of the same, potencially long, footnote. So it makes automatic use of usual (and beautiful) conventions such as Op. Cit.—which fives the package its name—and Idem, or allows the user to set ‘hereafters’ to repeatedly refer to the same publication.

1By Eric Domenjoud, 1995.

What I regret most about this package is that I was not able to make it ‘bst-independent,’ i.e., able to run with any BibTEX style that the user could want to use. (This, for example, is one of the good things about footbib.) The main reason why this was not possible is that bst files are designed to print the information in a list, not as footnotes, inserting, for example, periods instead of commas, and giving the author names with last-name first.

Since I do not want to fix the BibTEX style to use with opcit (and, OK, also because of lack of time), I have made one with support for just four kinds of entry (the ones I have needed and tested): ARTICLE, BOOK, INCOLLECTION, and MISC. In this documentation I will try to make clear what is needed for new entries to be appended by the users.^{2} Eventually, I will add more of them, as well as implement the cross-referencing mechanisms.

2 Use

\cite The user keeps citing bibliographical references with \cite. Thus, \cite{texbook} will produce the footnote ‘^{3}’. The optional argument has the usual meaning, so

\cite[p.~100]{taruskin} creates ‘^{4}’.

Note that opcit adds a period at the end of the footnotes; however, if the user adds it (for example, in \cite[Introduction.]{gellner}), it will refrain from adding it: ‘^{5}’. It will also avoid it after ‘?’ or ‘!’; in general, after any character with a \sfcode equal to the one of the period. (I am afraid this is lost in \frenchspacing and similar situations, where opcit has no way to ‘see’ the period, and will always add one.)

Warning! I have no clue as to why, but there is a problem when the optional argument to \cite starts with two identical symbols (which is unfortunately very often in expressions such as \cite[pp.~10ff.]!). A \relax should be put between them (\cite[p\relax p~10.ff]) to ensure proper behavior.

A \cite command can also occur within the argument of a \footnote. In that case, the information on the source is added to the text of the footnote, with no period added.^{6}

A later citation of the TEXbook through \cite{texbook} will not render the whole footnote text again, but rather ‘^{7}’. The author name has been reduced to the last-name, and the rest of the information is replaced by ‘Op. cit.’ Again, the period is appropriately handled: no period is added to the one at the end of this expression. But in the case of \cite[p.~101]{taruskin}, it is added: ‘^{8}’.

2Changing, as usual, the name of the file.

3Donald E. Knuth, The TEXbook (Reading, Mass.: Addison Wesley, 1986).

4Richard Taruskin, Defining Russia musically: Historical and Hermeneutical Essays (Princeton: Princeton University Press, 1997), p. 100.

5Ernest Gellner, Thought and change (Chicago: University of Chicago Press, 1964), introduction.

6This is because it is assumed that the user will always ‘close’ the footnote with a final period.

Issuing here \cite{martinb}, which produces Jesús Martín-Barbero, Communication, culture, and hegemony: From media to mediations (London: SAGE Publications, 1993), I do not want opcit to add a period.

7Knuth, Op. cit.

A similar feature is that of ‘Idem.’ If a reference is cited twice or more times consecutively, the second footnote (and after) will contain only ‘Idem,’ followed by the optional argument, if any (and by a period if necessary). Thus, a further citation of Taruskin’s book here, through \cite{taruskin}, renders ‘^{9}’.

\opcittext The user can change the expressions ‘Op. Cit.’ and ‘Idem’ by \renewcommand’ing

\idemtext the \opcittext and \idemtext commands, respectively.

\cite* A starred version of \cite is provided, by which the author’s name is omitted from the reference. So we can say that Gellner expanded one of the ideas presented from his mentioned book in a later study.\cite*{gellner2}^{10}

2.1 The ‘herafter’ mechanism

hereafter = "" When two or more works by the same author are \cite’d, the Op. Cit. mechanism is not reliable (there are many ‘oOpera citatæ’). The user should then provide, in the bib file and for all the works of that author, a value for the new entry hereafter. Then, opcit will use the value of this entry in the place of Op. Cit.

For example, if Gellner’s mentioned books had hereafter entries of "T{\&}C"

and "N{\&}N", respectively, the commands \cite{gellner} and \cite{gellner2}

will produce ‘^{11}’ and ‘^{12}’ (of course, from the second time these works are cited on). Note that the strings were emphasized. Still, the starred version \cite* hides the author’s name, and the ‘Idem’ mechanism will apply if any of the works is \cite’d for the second time in a row.

In case no hereafter entry is found, a warning will be issued, and the deliberately unacceptable expression ?Op.?Cit.? substituted.

\hereafter The \hereafter command typesets the hereafter string of the last work \cite’d, so that we can say something like

\footnote{See \cite{gellner}; hereafter I will refer to this text as
\hereafter.}

2.2 The final references list

The command \bibliography has the usual effect of producing a final section (or chapter) for ‘References.’ According to the BibTEX style used, the format of the entries is different in the references list from the footnotes.

Frequently, a document with bibliographical references in footnote style does not include a final references list. However, it is the \bibliography command that tells BibTEX what database file to look at, so opcit needs it to be present. If the final list is not wanted, the user should include this command (and the list) at least once, so that the file opcit.bbl is created, and then comment it out. In this way, opcit will have a file to read, but no reference list will be actually typeset.

8Taruskin, Op. cit., p. 101.

9Idem.

10Nations and Nationalism (Ithaca: Cornell University Press, 1983).

11Gellner: T&C.

12Gellner: N&N.

2.3 Modifying the bibliography style

This distribution of opcit includes a BibTEX style file, opcit.bst, designed to fulfill the package’s conventions. This style is far from being (and from pretending to be) complete. It supports only four generic entry-types:

@ARTICLE
@BOOK
@INCOLLECTION
@MISC

These entries take the usual fields of the plain.bst style, just adding one more, namely hereafter (see section 2.1). Cross-reference, moreover, has been turned off.^{13}

This style has been, in general, sufficient for my own needs (I have made @INBOOK entries as @INCOLLECTION). But I regard it mainly as a model for new, more specific (but also less versatile) bibliography styles that use the features of the package. This section states clearly what is needed from such a style.

If a style is created to work with opcit, the user has to indicate it as an option to the package, with the usual TEX conventions for file names, and with no

extension, for example \usepackage[c:/texmf/bibtex/bst/modopcit]{opcit}.

If no style is specified, opcit.bst will be used.

Many details of formatting differ between a footnote-style and a list-style reference. The most visible one is that in footnotes commas are used when periods are preferred in a list. Also, while in the list address and publisher form a block independent from year, in the footnotes the three things are grouped by parentheses. And so on.

Because of all this, a way has to be available for opcit the package to communicate with the BibTEX-sylte. To properly find out and assign the information of each \bibitem, opcit has to know what exactly is the author’s name, what the last-name (for second and later citations of the same work, in which the first name is omitted), etc.

The convention chosen is that the BibTEX-style writes out every \bibitem in the form

   \bibitem{⟨label⟩}

\biblastnames{⟨last name(s)⟩}⟨… additional declarations… ⟩

   \opcitstart ⟨Name(s)⟩\bibpunctuation \newblock

⟨remaining info⟩\opcitends

As long as this scheme is strictly followed, opcit will run.^{14} Other conventions are needed but not required, for example that instead of periods or commas, the style appends \bibpunctuation commands (this command is converted into commas in the footnotes, into periods in the references list). Similarly, \bibIn will decide if the particle ‘in’ for @INCOLLECTION and similar entries is capitalized or not, and \bibparenthesis does or does not parenthesize its argument according to the situation.

13In part, because a footnote-oriented style does not naturally lend itself to cross reference, for there are no ‘labels’ to refer to.

14This can be easily achieved in the style by suitably modifying the bibstart and fin.entry functions.

\sameauthors If the style substitutes a line for the author(s)’ name(s), opcit needs a way to know the ‘real’ author. This is achieved by the style not typesetting the line by itslef, but rather appending a \sameauthors command, which is defined by opcit as a 23pt-rule for the references list.

Also, opcit requires the style to provide the author’s last name as the argument to the command \biblastnames. Another command of this kind is \hereafter, which gives as its argument the abbreviation that the user chose in the hereafter field. This kind of commands is what is represented by ⟨… additional declarations… ⟩.

\newBibCommand The ‘communication commands’ mentioned are those that I have already im-

plemented in opcit.bst. Others can be created with the macro \newBibCommand{⟨command⟩}{⟨footnote-style⟩{⟨list-style⟩}

   This macro is used in opcit.sty to define \bibpunctuation, \bibIn and

\bibparenthesis. As a complementary example, let’s suppose the style will support videocassettes. The particle ‘videocassette’ is to be appended at the end of the item. In a footnote, it comes after a comma (the current meaning of \bibpunctuation), but in the references list it comes after a period. The command

   \newBibCommand{\videocassette}{(videocassette)}{Videocassette.}

will manage this properly. If a new communication command needs arguments, the [n] part has to be inside the first argument of \newBibCommand (see the definition of \bibparenthesis below, code line 21).

When to issue the \newBibCommand’s? A good place to do it is the style itself, when it appends the \begin{thebibliography} command (usually the begin.bib function). Since \newBibCommand does not typeset anything, it causes no problem either in the preamble nor at the start of the list.

3 Implementation

1 ⟨∗package⟩

 2 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 3 \ProvidesPackage{opcit}[2002/12/25 Footnote references (Federico Garcia)]
 4 \RequirePackage{xspace}
 5 \newcommand{\opcit@bst}{opcit}
 6 \DeclareOption*{\PackageInfo{opcit}{%
 7  `\CurrentOption' used as bibliography style}%
 8  \let\opcit@bst\CurrentOption}
 9 \ProcessOptions

3.1 Basic idea

The basic idea behind the working of opcit is that the bbl file produced by BibTEX is read at the beginning of the document. Each reference item starts in this file with the \bibitem command (used in the thebibliography environment to crete the different items). But when reading the file at the beginning, \bibitem is redefined so that, instead of appending an item to a list, it defines the control sequences that will produce the footnotes.

Thus, for each work \cite’d there will be a set of newly defined control sequences, identified by the label by which the user refers to it in \cite commands. For example, there will be a set for the label texbook used above: the commands

\texbook, \texbook@star, \texbook@author, and so on. These commands (of

whose existence the user does not need to know) contain the actual text to be written in the footnotes.

The \cite command itself is redefined here to execute the appropriate control sequence each time. In this way, \cite{texbook} means basically \footnote{\texbook}. But it also redefines \texbook so that the next time it is used it will expand to ‘Knuth, Op. Cit.’

3.2 The macros

Three conditionals are needed: one to check if there is a bbl file to read from; another to check if \cite occurs inside or outside the argument of \footnote; and one more to check whether the last character was a period. The rule for repeated authors is also set here to 23pt.

10 \newif\ifopcit@bbl\opcit@bblfalse
11 \newif\ifopcit@footnote\opcit@footnotefalse
12 \newif\ifperi@d\peri@dfalse
13 \newlength{\sameauthorsrule}\setlength{\sameauthorsrule}{23pt}

The following section sets up the ‘communication commands.’ Note that the commands that add a punctuation mark do so only if the last character was not period, question, or exclamation marks (all of which have a \sfcode different from other characters). Within the thebibliography environment, however, the period is set to \sfcode of 1000 (as letters), so it is not good for the test. \last@cited is initialized to a value unlikely to occur.

14 \newtoks\opcit@redefs
15 \newcommand{\newBibCommand}[3]{%
16  \newcommand#1{#2}%
17  \opcit@redefs\expandafter{\the\opcit@redefs%
18  \renewcommand#1{#3}}}
19 \newcommand{\opcitstart}{\relax}
20 \newBibCommand{\opcitend}{\relax}{\ifnum\spacefactor=\sfcode`?\else.\fi}
21 \newBibCommand{\bibparenthesis[1]}{ (#1)}{. \newblock #1}
22 \newBibCommand{\bibIn}{in}{In}
23 \newBibCommand{\bibpunctuation}{%
24  \ifnum\spacefactor=\sfcode`.\else,\fi\xspace}{%
25  \ifnum\spacefactor=\sfcode`?\else.\fi\xspace}
26 \newcommand{\sameauthors}{\rule{\sameauthorsrule}{.4pt}}
27 \newBibCommand{\biblastnames[1]}{%
28  \global\@namedef{\@curr@bibitem @authors}{#1}}{\relax}
29 \newBibCommand{\bibhereafter[1]}{%

30  \global\@namedef{\@curr@bibitem @hereafter}{#1}}{\relax}
31 \newcommand{\last@cited}{)OpcitFirst(}
32 \newcommand{\opcittext}{Op.~Cit.}
33 \newcommand{\idemtext}{Idem}

After having set up the communication, the bibliography style is called, and the bbl file is read, if exists. This is done within a group, for thebibliography and \bibitem are redefined (the former as nothing). Recall that, by now, the communication commands have their ‘footnote meaning,’ the first part of their definition (the second part has been stored in \opcit@redefs, to be redeemed later on).

In \bibitem, #1 is the label for the \cite command; #2 is a series of declarations written out to the bbl file by the BibTEX style (one of them, required, is the command \biblastnames, whose argument contains only the last name(s) of the author(s); another is \hereafter, if any). #3 is the full author(s)’ name(s), that appears the first time the work is \cite’d. Finally, #4 is the rest of the information for the entry.

34 \bibliographystyle{\opcit@bst}
35 \bgroup
36  \renewenvironment{thebibliography}[1]{\relax}{\relax}
37  \def\bibitem#1#2\opcitstart #3\bibpunctuation \newblock#4\opcitend{%
38  \ifx#3\sameauthors\else\def\@lastauthors{#3}\fi
39  \global\expandafter\edef\csname#1@author\endcsname{\@lastauthors}%
40  \global\def\@curr@bibitem{#1}%
41  \global\expandafter\def\csname#1\endcsname{\@nameuse{#1@author}, #4}%
42  \global\@namedef{#1@star}{#4}%
43  \bibhereafter{\opcittext}%
44  #2}
45  \InputIfFileExists{\jobname.bbl}{\global\opcit@bbltrue}%
46  {\global\opcit@bblfalse\PackageWarningNoLine{opcit}{%
47  No information found about bibliographical references.}}
48 \egroup

The effect of all this, if \jobname.bbl exists, is that for each entry foo the following commands are defined: \foo@author as ⟨author⟩ (avoiding the rule for a repeated author); \foo, as ‘\foo@author, ⟨info⟩’; and \foo@star as ‘⟨info⟩’. Also, \bibhereafter is applied, so the command \foo@hereafter is defined as \opcittext (=‘Op. Cit.’). If the user provided a value for the hereafter field, the BibTEX style will issue a \bibhereafter command as part of ⟨… additional declarations… ⟩, which will override the one just applied when #2 is executed.

And now for the \cite and \cite* commands. They check if they are in a footnote (note that this requires \interfootnotelinepenalty to be different from \interlinepenalty in the main text); if not, they call a \footnote, and append a period at the end, if necessary. After that, they execute one of the commands defined by \bibitem above. Then they call the redefinition routine \renew@cites, which will redefine those very commands to produce different things the next time the work is \cite’d. They are redefined only if there was a bbl from which those commands were initially defined.

49 \ifopcit@bbl
50 \renewcommand{\cite}{\@ifstar{\opcit@cite@star}{\opcit@cite}}%
51 \newcommand{\opcit@cite}[2][.]{\nocite{#2}%
52  \ifnum\interlinepenalty=\interfootnotelinepenalty\opcit@footnotetrue%
53  \else\opcit@footnotefalse\expandafter\footnote\fi%
54  {\@nameuse{#2}\ifx#1.\check@for@period{\@nameuse{#2}}%
55  \else\check@for@period{#1}%
56  {, #1}\fi%
57  \ifopcit@footnote\peri@dtrue\fi%
58  \ifperi@d\else.\fi}%
59  \renew@cites{#2}}
60 \newcommand{\opcit@cite@star}[2][.]{\nocite{#2}%
61  \ifnum\interlinepenalty=\interfootnotelinepenalty\opcit@footnotetrue%
62  \else\opcit@footnotefalse\expandafter\footnote\fi%
63  {\@nameuse{#2star}\ifx#1.\check@for@period{\@nameuse{#2}}%
64  \else\check@for@period{#1}%
65  {, #1}\fi%
66  \ifopcit@footnote\peri@dtrue\fi%
67  \ifperi@d\else.\fi}%
68  \renew@cites{#2}}
69 \fi

The redefinition routine is in charge of catching two identical \cite’s in a row, to produce Idem (or the current value of \idemtext) in the second. Also, after the first time a work is \cite’d, it redefines its commands to produce only the author(s)’ last name(s) followed by the hereafter (which is either Op. Cit. or the hereafter field in the bib file). After that, \check@for@period is defined.

70 \newcommand{\renew@cites}[1]{%
71  \global\expandafter\edef\csname\last@cited\endcsname{%
72  \@nameuse{\last@cited @authors},%
73  ~{\noexpand\em\@nameuse{\last@cited @hereafter}}}%
74  \global\expandafter\edef\csname\last@cited star\endcsname{%
75  {\noexpand\em\@nameuse{\last@cited @hereafter}}}%
76  \global\def\last@cited{#1}%
77  \global\@namedef{#1}{{\em\idemtext}}%
78  \global\@namedef{#1star}{{\em\@nameuse{#1@hereafter}}}%
79  \global\def\hereafter{\@nameuse{#1@hereafter}}}
80 \def\check@for@period#1{{\normalsfcodes\setbox0\hbox{#1%
81  \ifnum\spacefactor=\sfcode`.\global\peri@dtrue\else%
82  \global\peri@dfalse\fi}}}

Finally, the redefinitions of the communication commands have to be executed before the references list is compiled. thebibliography environment is formatted to produce no labels.

83 \let\opcit@bibliography\bibliography
84 \renewcommand{\bibliography}{\the\opcit@redefs\opcit@bibliography}
85 \newcommand{\thebib@renew}{}
86 \@ifclassloaded{article}{%
87  \renewcommand{\thebib@renew}{\section*{\refname}\@mkboth{\refname}{\refname}}}{%
88  \renewcommand{\thebib@renew}{\chapter*{\bibname}\@mkboth{\bibname}{\bibname}}}%

 89 \renewenvironment{thebibliography}[1]
 90  {\thebib@renew%
 91  \the\opcit@redefs%
 92  \list{}%
 93  {\setlength\labelwidth{\z@}%
 94  \leftmargin\bibindent
 95  \itemindent -\bibindent
 96  \parsep \z@
 97  \@openbib@code
 98  \usecounter{enumiv}%
 99  \let\p@enumiv\@empty
100  \renewcommand\theenumiv{\@arabic\c@enumiv}}%
101  \sloppy
102  \clubpenalty4000
103  \@clubpenalty \clubpenalty
104  \widowpenalty4000%
105  \sfcode`\.\@m}
106  {\def\@noitemerr
107  {\@latex@warning{Empty `thebibliography' environment}}%
108  \endlist}

109 ⟨/package⟩

3.3 The opcit.bst bibliography style

This style was prepared adapting the plain.bst file, crudely simplifying it, and adding new functions for communication commands.

110 ⟨∗bst⟩

111 ENTRY
112 { address
113  author
114  booktitle
115  chapter
116  edition
117  editor
118  howpublished
119  institution
120  journal
121  key
122  month
123  note
124  number
125  organization
126  pages
127  publisher
128  school
129  series
130  title
131  type
132  volume

133  year
134  hereafter

135 } 136 {}

137 { label }

138

139 INTEGERS { output.state before.all mid.sentence after.sentence after.block quoted.state }

140

141 STRINGS { s t last.authors }

142

143 FUNCTION {init.state.consts}
144 { #0 'before.all :=
145 #1 'mid.sentence :=
146 #2 'after.sentence :=
147 #3 'after.block :=
148 #0 'quoted.state :=
149 "" 'last.authors :=

150 }

The string last.authors is used to check for works by the same author, to replace the name by the \sameauthors command. In the following section, defining basic functions, the communication commands are implemented.

151 FUNCTION {output.nonnull}
152 { 's :=
153 output.state mid.sentence =
154  { " " * write$ }
155  { output.state after.block =
156  { "\bibpunctuation" *
157  quoted.state #1 =
158  { #2 'quoted.state := }
159  { quoted.state #2 =
160  { "''" * #0 'quoted.state := }
161  'skip$
162  if$

163 }

164  if$
165  write$
166  newline$
167  "\newblock " write$

168 }

169  { output.state before.all =
170  'write$
171  { "\bibpunctuation" * write$ }
172  if$

173 }

174  if$
175  mid.sentence 'output.state :=

176 }

177 if$

178 s

180

181 FUNCTION {output}
182 { duplicate$ empty$
183  'pop$
184  'output.nonnull
185 if$

186 }

187

188 FUNCTION {output.check}
189 { 't :=
190 duplicate$ empty$
191  { pop$ "empty " t * " in " * cite$ * warning$ }
192  'output.nonnull
193 if$

194 }

195 196

197 FUNCTION {fin.entry}
198 { "\opcitend%" * write$
199 newline$

200 }

201

202 FUNCTION {new.block}
203 { output.state before.all =
204  'skip$
205  { after.block 'output.state := }
206 if$

207 }

Then some logical and general-purpose functions:

208 FUNCTION {not}
209 {   { #0 }
210  { #1 }
211 if$

212 }

213

214 FUNCTION {and}
215 {   'skip$
216  { pop$ #0 }
217 if$

218 }

219

220 FUNCTION {or}
221 {   { pop$ #1 }
222  'skip$
223 if$

224 }

225

226 FUNCTION {new.block.checka}

227 { empty$
228  'skip$
229  'new.block
230 if$

231 }

232

233 FUNCTION {new.block.checkb}
234 { empty$
235 swap$ empty$
236 and
237  'skip$
238  'new.block
239 if$

240 }

241

242 FUNCTION {field.or.null}
243 { duplicate$ empty$
244  { pop$ "" }
245  'skip$
246 if$

247 }

248

249 FUNCTION {emphasize}
250 { duplicate$ empty$
251  { pop$ "" }
252  { "{\em " swap$ * "}" * }
253 if$

254 }

The next formatting-functions are very similar (though not quite identical) to

 those in plain.bst:

255

256 INTEGERS { nameptr namesleft numnames }

257

258 FUNCTION {format.names}
259 { 's :=
260 #1 'nameptr :=
261 s num.names$ 'numnames :=
262 numnames 'namesleft :=
263  { namesleft #0 > }
264  { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't :=
265  nameptr #1 >
266  { namesleft #1 >
267  { ", " * t * }
268  { numnames #2 >
269  { "," * }
270  'skip$
271  if$
272  t "others" =
273  { " et~al." * }

274  { " and " * t * }
275  if$

276 }

277  if$

278 } 279 't

280  if$
281  nameptr #1 + 'nameptr :=
282  namesleft #1 - 'namesleft :=

283 }

284 while$

285 }

286

287 FUNCTION {format.authors}
288 { author empty$
289  { ""
290  "" 'last.authors :=

291 }

292  { author last.authors =
293  { "\sameauthors" }
294  { author format.names }
295  if$
296  author 'last.authors :=

297 }

298 if$

299 }

300

301 FUNCTION {format.editors}
302 { editor empty$
303  { "" }
304  { editor format.names }
305 if$

306 }

307

308 FUNCTION {format.editors.ed}
309 { editor empty$
310  { "" }
311  { editor format.names " (ed.)" * }
312 if$

313 }

314

315 FUNCTION {format.title}
316 { title empty$
317  { "" }
318  { title }
319 if$

320 }

321

322 FUNCTION {n.dashify}
323 { 't :=

324 ""

325  { t empty$ not }
326  { t #1 #1 substring$ "-" =
327  { t #1 #2 substring$ "--" = not
328  { "--" *
329  t #2 global.max$ substring$ 't :=

330 }

331  {   { t #1 #1 substring$ "-" = }
332  { "-" *
333  t #2 global.max$ substring$ 't :=

334 }

335  while$

336 }

337  if$

338 }

339  { t #1 #1 substring$ *
340  t #2 global.max$ substring$ 't :=

341 }

342  if$

343 }

344 while$

345 }

346

347 FUNCTION {format.date}
348 { year empty$
349  { month empty$
350  { "" }
351  { "there's a month but no year in " cite$ * warning$
352  month

353 }

354  if$

355 }

356  { month empty$
357  'year
358  { month " " * year * }
359  if$

360 }

361 if$

362 }

363

364 FUNCTION {format.btitle}
365 { title emphasize

366 }

367

368 FUNCTION {tie.or.space.connect}
369 { duplicate$ text.length$ #3 <
370  { "~" }
371  { " " }
372 if$
373 swap$ * *

375

376 FUNCTION {either.or.check}
377 { empty$
378  'pop$
379  { "can't use both " swap$ * " fields in " * cite$ * warning$ }
380 if$

381 }

382

383 FUNCTION {format.bvolume}
384 { volume empty$
385  { "" }
386  { "volume" volume tie.or.space.connect
387  series empty$
388  'skip$
389  { " of " * series emphasize * }
390  if$
391  "volume and number" number either.or.check

392 }

393 if$

394 }

395

396 FUNCTION {format.number.series}
397 { volume empty$
398  { number empty$
399  { series empty$
400  { "" }
401  { ", series " * series * "" }
402  if$ }
403  { output.state mid.sentence =
404  { "number" }
405  { "Number" }
406  if$
407  number tie.or.space.connect
408  series empty$
409  { "there's a number but no series in " cite$ * warning$ }
410  { " in " * series * }
411  if$

412 }

413  if$

414 }

415  { "" }
416 if$

417 }

418

419 FUNCTION {format.edition}
420 { edition empty$
421  { "" }
422  { output.state mid.sentence =
423  { edition "l" change.case$ " edition" * }

424  { edition "t" change.case$ " edition" * }
425  if$

426 }

427 if$

428 }

429

430 INTEGERS { multiresult }

431

432 FUNCTION {multi.page.check}
433 { 't :=
434 #0 'multiresult :=
435  { multiresult not
436  t empty$ not
437  and

438 }

439  { t #1 #1 substring$
440  duplicate$ "-" =
441  swap$ duplicate$ "," =
442  swap$ "+" =
443  or or
444  { #1 'multiresult := }
445  { t #2 global.max$ substring$ 't := }
446  if$

447 }

448 while$
449 multiresult

450 }

451

452 FUNCTION {format.pages}
453 { pages empty$
454  { "" }
455  { pages multi.page.check
456  { "pages" pages n.dashify tie.or.space.connect }
457  { "page" pages tie.or.space.connect }
458  if$

459 }

460 if$

461 }

462

463 FUNCTION {format.vol.num.date.pages}
464 { volume empty$
465  'skip$
466  { volume }
467  if$
468  number empty$
469  'skip$
470  { "/" number * *
471  volume empty$
472  { "there's a number but no volume in " cite$ * warning$ }
473  'skip$

474  if$

475 }

476 if$
477 " (" * format.date * ")" *
478 pages empty$
479  'skip$
480  { duplicate$ empty$
481  { pop$ format.pages }
482  { ": " * pages n.dashify * }
483  if$

484 }

485 if$

486 }

487

488 FUNCTION {format.chapter.pages}
489 { chapter empty$
490  'format.pages
491  { type empty$
492  { "chapter" }
493  { type "l" change.case$ }
494  if$
495  chapter tie.or.space.connect
496  pages empty$
497  'skip$
498  { ", " * format.pages * }
499  if$

500 }

501 if$

502 }

503

504 FUNCTION {format.in.ed.booktitle}
505 { booktitle empty$
506  { "" }
507  { "\bibIn \ " booktitle emphasize *
508  editor empty$
509  'skip$
510  { ", ed.~" * format.editors * }
511  if$

512 }

513 if$

514 }

515

516 FUNCTION {empty.misc.check}
517 { author empty$ title empty$ howpublished empty$
518 month empty$ year empty$ note empty$
519 and and and and and
520 key empty$ not and
521  { "all relevant fields are empty in " cite$ * warning$ }
522  'skip$
523 if$

The next three functions are new. get.lastnames is used to provide the argu-

 ment for the \biblastnames command; make.address.publisher.year group
 those fields as the argument to \bibparenthesis; and format.title.quoted

is used to wrap the quotes for @ARTICLE and @INCOLLECTION titles. The integer quoted.state, there modified, has an effect in the output.nonnull function above.

525 FUNCTION{get.lastnames}
526 { 's :=
527 #1 'nameptr :=
528 s num.names$ 'numnames :=
529 numnames 'namesleft :=
530  { namesleft #0 > }
531  { s nameptr "{vv~}{ll}" format.name$ 't :=
532  nameptr #1 >
533  { namesleft #1 >
534  { ", " * t * }
535  { numnames #2 >
536  { "," * }
537  'skip$
538  if$
539  t "others" =
540  { " et~al." * }
541  { " and " * t * }
542  if$

543 }

544  if$

545 } 546 't

547  if$
548  nameptr #1 + 'nameptr :=
549  namesleft #1 - 'namesleft :=

550 }

551 while$

552 }

553

554 FUNCTION {make.address.publisher.year}
555 {   "\unskip\bibparenthesis{"
556  address empty$
557  'skip$
558  { address * ": " * }
559  if$
560  publisher empty$
561  'skip$
562  { publisher * ", " * }
563  if$
564  format.date * "}" *

565 }

566

567 FUNCTION{format.title.quoted}
568 {  title empty$
569  { "" }
570  { "``" title * }
571  if$
572  #1 'quoted.state :=

573 }

It is the output.bibitem function, which starts each \bibitem, that is in charge of fulfilling almost all the convention for this command (see section 2.3),

 by inserting the key commands \biblastname and \opcitstart (\opcitend is

added by fin.entry, above). The hereafter field is also handled here.

574 FUNCTION {output.bibitem}
575 { newline$
576 "\bibitem{" write$
577 cite$ "}" * write$

578 ""

579 newline$
580 "\biblastnames{" write$
581 author empty$
582  { editor get.lastnames }
583  { author get.lastnames }
584  if$
585 "}" * write$
586 hereafter empty$
587  'skip$
588  { "\bibhereafter{" write$ hereafter "}" * write$ }
589  if$
590 newline$
591 "\opcitstart " write$
592 before.all 'output.state :=
593  #0 'quoted.state :=

594 }

Then the four entry functions. Note that they do not reveal by themselves the opcit conventions.

595 FUNCTION {article}
596 { output.bibitem
597 format.authors "author" output.check
598 new.block
599 format.title.quoted "title" output.check
600 new.block
601 journal emphasize "journal" output.check
602 format.vol.num.date.pages "year" output.check
603 new.block
604 note output
605 fin.entry

606 }

607

608 FUNCTION {book}

609 { output.bibitem
610 author empty$
611  {   format.editors.ed "author and editor" output.check }
612  {   format.authors output.nonnull
613  "author and editor" editor either.or.check

614 }

615 if$
616 new.block
617 format.btitle "title" output.check
618 edition new.block.checka
619 format.edition output
620 format.bvolume output
621 format.number.series output
622 make.address.publisher.year output
623 new.block
624 note output
625 fin.entry

626 }

627

628 FUNCTION {incollection}
629 { output.bibitem
630 format.authors "author" output.check
631 new.block
632 format.title.quoted "title" output.check
633 new.block
634 format.in.ed.booktitle "booktitle" output.check
635 format.bvolume output
636 format.number.series output
637 make.address.publisher.year output
638 format.chapter.pages output
639 new.block
640 note output
641 fin.entry

642 }

643

644 FUNCTION {misc}
645 { output.bibitem
646 format.authors "author" output.check
647 new.block
648 format.title output
649 howpublished new.block.checka
650 howpublished output
651 format.date output
652 new.block
653 note output
654 fin.entry
655 empty.misc.check

656 }

The next has been copied almost verbatim (I am not even sure if all these functions are actually used by the style…)

657

658 FUNCTION {default.type} { misc }

659

660 MACRO {jan} {"January"}

661

662 MACRO {feb} {"February"}

663

664 MACRO {mar} {"March"}

665

666 MACRO {apr} {"April"}

667

668 MACRO {may} {"May"}

669

670 MACRO {jun} {"June"}

671

672 MACRO {jul} {"July"}

673

674 MACRO {aug} {"August"}

675

676 MACRO {sep} {"September"}

677

678 MACRO {oct} {"October"}

679

680 MACRO {nov} {"November"}

681

682 MACRO {dec} {"December"}

683

684 MACRO {acmcs} {"ACM Computing Surveys"}

685

686 MACRO {acta} {"Acta Informatica"}

687

688 MACRO {cacm} {"Communications of the ACM"}

689

690 MACRO {ibmjrd} {"IBM Journal of Research and Development"}

691

692 MACRO {ibmsj} {"IBM Systems Journal"}

693

694 MACRO {ieeese} {"IEEE Transactions on Software Engineering"}

695

696 MACRO {ieeetc} {"IEEE Transactions on Computers"}

697

698 MACRO {ieeetcad}
699 {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}

700

701 MACRO {ipl} {"Information Processing Letters"}

702

703 MACRO {jacm} {"Journal of the ACM"}

705 MACRO {jcss} {"Journal of Computer and System Sciences"}

706

707 MACRO {scp} {"Science of Computer Programming"}

708

709 MACRO {sicomp} {"SIAM Journal on Computing"}

710

711 MACRO {tocs} {"ACM Transactions on Computer Systems"}

712

713 MACRO {tods} {"ACM Transactions on Database Systems"}

714

715 MACRO {tog} {"ACM Transactions on Graphics"}

716

717 MACRO {toms} {"ACM Transactions on Mathematical Software"}

718

719 MACRO {toois} {"ACM Transactions on Office Information Systems"}

720

721 MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"}

722

723 MACRO {tcs} {"Theoretical Computer Science"}

724

725 READ

726

727 FUNCTION {sortify}
728 { purify$
729 "l" change.case$

730 }

731

732 INTEGERS { len }

733

734 FUNCTION {chop.word}
735 { 's :=
736 'len :=
737 s #1 len substring$ =
738  { s len #1 + global.max$ substring$ }

739 's

740 if$

741 }

742

743 FUNCTION {sort.format.names}
744 { 's :=
745 #1 'nameptr :=

746 ""

747 s num.names$ 'numnames :=
748 numnames 'namesleft :=
749  { namesleft #0 > }
750  { nameptr #1 >
751  { "   " * }
752  'skip$
753  if$

754  s nameptr "{vv{ } }{ll{ }}{  ff{ }}{  jj{ }}" format.name$ 't :=
755  nameptr numnames = t "others" = and
756  { "et al" * }
757  { t sortify * }
758  if$
759  nameptr #1 + 'nameptr :=
760  namesleft #1 - 'namesleft :=

761 }

762 while$

763 }

764

765 FUNCTION {sort.format.title}
766 { 't :=
767 "A " #2
768  "An " #3
769  "The " #4 t chop.word
770  chop.word
771 chop.word
772 sortify
773 #1 global.max$ substring$

774 }

775

776 FUNCTION {author.sort}
777 { author empty$
778  { key empty$
779  { "to sort, need author or key in " cite$ * warning$

780 "" 781 }

782  { key sortify }
783  if$

784 }

785  { author sort.format.names }
786 if$

787 }

788

789 FUNCTION {author.editor.sort}
790 { author empty$
791  { editor empty$
792  { key empty$
793  { "to sort, need author, editor, or key in " cite$ * warning$

794 "" 795 }

796  { key sortify }
797  if$

798 }

799  { editor sort.format.names }
800  if$

801 }

802  { author sort.format.names }
803 if$

805

806 FUNCTION {author.organization.sort}
807 { author empty$
808  { organization empty$
809  { key empty$
810  { "to sort, need author, organization, or key in " cite$ * warning$

811 "" 812 }

813  { key sortify }
814  if$

815 }

816  { "The " #4 organization chop.word sortify }
817  if$

818 }

819  { author sort.format.names }
820 if$

821 }

822

823 FUNCTION {editor.organization.sort}
824 { editor empty$
825  { organization empty$
826  { key empty$
827  { "to sort, need editor, organization, or key in " cite$ * warning$

828 "" 829 }

830  { key sortify }
831  if$

832 }

833  { "The " #4 organization chop.word sortify }
834  if$

835 }

836  { editor sort.format.names }
837 if$

838 }

839

840 FUNCTION {presort}
841 { type$ "book" =
842 type$ "inbook" =

843 or

844  'author.editor.sort
845  { type$ "proceedings" =
846  'editor.organization.sort
847  { type$ "manual" =
848  'author.organization.sort
849  'author.sort
850  if$

851 }

852  if$

853 }

854 if$

855 " " 856 *

857 year field.or.null sortify

858 * 859 " " 860 *

861 title field.or.null
862 sort.format.title

863 *

864 #1 entry.max$ substring$
865 'sort.key$ :=

866 }

By contrast, begin.bib has been heavily lengthened, by adding all the formatting commands. This would be the best place for inserting any \newBibCommand’s.

867 FUNCTION {begin.bib}
868 { preamble$ empty$
869  'skip$
870  { preamble$ write$ newline$ }
871 if$
872 "\begin{thebibliography}{}"   write$ newline$

873 }

Finally, the ‘executive functions:’

874 ITERATE {presort}

875

876 SORT

877

878 EXECUTE {begin.bib}

879

880 EXECUTE {init.state.consts}

881

882 ITERATE {call.type$}

883

884 FUNCTION {end.bib}
885 { newline$
886 "\end{thebibliography}" write$ newline$

887 }

888

889 EXECUTE {end.bib}

890 ⟨/bst⟩