The ACM Transactions (acmtrans) bibliography style

Glenn Paulley  Andrew W. Appel  Rebecca L. Davies

David M. Jones

22 August 1995 Version 1.2b β

Contents

1 Introduction

This is the acmtrans BibTEX style, which is based Glenn Paulley’s chicago bibliography style (for further information about the history of this code, please see the comments in chicago.bst). The acmtrans style was hacked by Andrew W. Appel and Rebecca L. Davies of Princeton University, and further modified and reworked by David M. Jones.

This style implements an “author-year” bibliography format, where in-text citations have the general form “[author name(s) year]” and the Reference list is sorted alphabetically by the author or whatever passes for author in the absence of one. The style also supports abbreviated author lists in citations.

This style must be supplemented by some TEX macros to process the citation information generated by acmtrans. The citation information deposited in the bibliography has the following format:

\citeauthoryear{⟨full-author-info⟩}{⟨abbrev-author-info⟩}{⟨year⟩}

The L^{A}TEX style should define something like the following:

    \let\@internalcite\cite
    \def\fullcite{\def\citeauthoryear##1##2##3{##1 ##3}\@internalcite}
    \def\fullciteA{\def\citeauthoryear##1##2##3{##1}\@internalcite}

\begin{matrix}c \\ ◯ \end{matrix}1995, all rights reserved. Copying of this file is authorized only if either (1) you make absolutely no changes to your copy, including name, or (2) if you do make changes, you name it something other than “acmtrans.bst”. There are undoubtably bugs in this style. Please send any bug reports, suggestions for im-

provements, etc., to jacm@theory.lcs.mit.edu.

    \def\shortcite{\def\citeauthoryear##1##2##3{##2 ##3}\@internalcite}
    \def\shortciteA{\def\citeauthoryear##1##2##3{##2}\@internalcite}
    \def\citeyear{\def\citeauthoryear##1##2##3{##3}\@internalcite}

Additional commands to manipulate different components of a citation can be defined so that, for example, you can list author’s names without parentheses if using a citation as a noun or object in a sentence. See the acmart document class for a more complete example.

In order to provide more flexibility for use with both L^{A}TEX 2.09 and L^{A}TEX 2ε, acmtrans uses the following macros for all font changes: \bibsc for small caps \bibemph for italics without an italic correction \bibemphic for italics with an italic correction at the end.

For L^{A}TEX 2ε, the following is appropriate:

    \let\bibsc\textsc
    \let\bibemph\emph
    \let\bibemphic\emph

For L^{A}TEX 2.09, the following should do:

    \newcommand{\bibsc}[1]{{\sc#1}}
    \newcommand{\bibemph}[1]{{\em#1}}
    \newcommand{\bibemphic}[1]{{\em#1\/}}

One further macro, \bibyear, is needed, to format the year. The following definition is used in the acmart class. See the comments before output.year.check below and before \bibyear in acmart for more information.

    \newcommand{\bibyear}[2]{%
       \unskip\quad\ignorespaces#1\unskip
       \if#2. .\quad \else \quad#2 \fi
    }

These TEX macro definitions are found in the acmart document class.

2 Further features of acmtrans

• full names used in citations, but abbreviated citations are available (see above)

• if an entry has a “month”, then the month and year are also printed as part of that bibitem.

• all conjunctions use “and” instead of “&”

• major modification from Chicago Manual of Style (13th ed.) is that only the first author in a reference appears last name first- additional authors appear as J. Q. Public.

• pages are listed as “pp. xx-xx” in all entry types except article entries.

• book, inbook, and manual use “location: publisher” (or organization) for address and publisher. All other types list publishers separately.

• “pp.” are used to identify page numbers for all entry types except articles.

• organization is used as a citation label if neither author nor editor is present (for manuals).

• “et al.” is used for long author and editor lists, or when “others” is used.

3 Modifications and bug fixes from newapa.bst

• added month, year to bib entries if month is present

• fixed bug with In proceedings, added necessary comma after title

• all conjunctions changed to “and” from “&”

• fixed bug with author labels in my.full.label: “et al.” now is generated when “others” is an author name

• major modification from Chicago Manual of Style (13th ed.) is that only the first author in a reference appears last name first—additional authors appear as J. Q. Public.

• pages are listed as “pp. xx-xx” in all entry types except article entries. Unnecessary (IMHO) “()” around page numbers were removed, and page numbers now don’t end with a period.

• created chicago.sty for use with this bibstyle (required).

• fixed bugs in format.vol.num.pages for missing volume, number, and/or pages. Renamed to format.jour.vol.

• fixed bug in formatting booktitles: additional period an error if book has a volume.

• fixed bug: editors usually given redundant period before next clause

  (format.editors.dot) removed.

• added label support for organizations, if both author and editor are missing (from alpha.bst). If organization is too long, then the key field is used for abbreviated citations.

• In proceedings or books of several volumes, no comma was written between the “Volume x” and the page numbers (this was intentional in newapa.bst). Fixed.

• Some journals may not have volumes/numbers, only month/year (eg. IEEE Computer). Fixed bug in article style that assumed volume/number was always present.

4 To-do list

Here are a few of the many things that need to be done to finish this style file. • Figure out what, if any, copyright notice should cover this file.

• Decide what parts of the above documentation to keep. Sort out credit issues.

• Get style rules from ACM and implement them.

• Implement format.proc.publisher and sort out other issues mentioned in connection with inproceedings.

• Sort out format.key business.

• Munge month to standardize month abbreviations when authors fail to use the standard strings.

• Sort out journal abbreviations.

• Make .bbl file look more like what the ACM wants for its automatic conversion programs. (In fact, we could output SGML code directly for them, if they’d tell us what they want.)

• Rewrite macrocode to index BST macros.

5 The docstrip modules

This code uses the following modules:

xref  use crossrefs in the bibliography
driver generate a driver file for the documentation

6 The macros

6.1 The field names and useful utilities

1 ENTRY
2 { address
3  author

 4  booktitle
 5  chapter
 6  edition
 7  editor
 8  howpublished
 9  institution
10  journal
11  key
12  month
13  note
14  number
15  organization
16  pages
17  publisher

In addition to the standard fields, we introduce three new fields, pub-year, pub-month and pub-address. These are for use in proceedings, where the year, month and address fields normally refer to the date and location of the conference rather than the publisher. For compatibility with the standard BibTEX styles, we introduce new fields for the publisher information rather than the conference information, although it would probably be more logical for the existing fields always to refer to the publisher and to introduce new fields for the conference information.

18  pub-year
19  pub-month
20  pub-address
21  school
22  series
23  title
24  type
25  volume
26  year

27 }

28 {}
29 { label.year extra.label sort.year sort.label }

30

31 INTEGERS {
32  output.state
33  before.all
34  mid.sentence
35  after.sentence
36  after.block

37 }

init.state.consts
38 FUNCTION {init.state.consts}
39 { #0 'before.all :=
40 #1 'mid.sentence :=
41 #2 'after.sentence :=
42 #3 'after.block :=

43 }

output.nonnull
44 STRINGS { s t u }

45

46 FUNCTION {output.nonnull}
47 { 's :=
48 output.state mid.sentence =
49  { ", " * write$ }
50  { output.state after.block =
51  { add.period$ write$
52  newline$
53  "\newblock " write$

54 }

55  { output.state before.all =
56  'write$
57  { add.period$ " " * write$ }
58  if$

59 }

60  if$
61  mid.sentence 'output.state :=

62 }

63 if$

64 s 65 }

output.nonnull.colon Use a colon to separate output. Used only for address/publisher combination in book/inbook types, address/institution for manuals, and organization:publisher for proceedings (inproceedings).

66 FUNCTION {output.nonnull.colon}
67 { 's :=
68 output.state mid.sentence =
69  { ": " * write$ }
70  { output.state after.block =
71  { add.period$ write$
72  newline$
73  "\newblock " write$

74 }

75  { output.state before.all =
76  'write$
77  { add.period$ " " * write$ }
78  if$

79 }

80  if$
81  mid.sentence 'output.state :=

82 }

83 if$

84 s 85 }

output

 86 FUNCTION {output}
 87 { duplicate$ empty$
 88  'pop$
 89  'output.nonnull
 90 if$

91 }

output.colon
 92 FUNCTION {output.colon}
 93 { duplicate$ empty$
 94  'pop$
 95  'output.nonnull.colon
 96 if$

97 }

output.check
 98 FUNCTION {output.check}
 99 { 't :=
100 duplicate$ empty$
101  { pop$ "empty " t * " in " * cite$ * warning$ }
102  'output.nonnull
103 if$

104 }

output.check.colon
105 FUNCTION {output.check.colon}
106 { 't :=
107 duplicate$ empty$
108  { pop$ "empty " t * " in " * cite$ * warning$ }
109  'output.nonnull.colon
110 if$

111 }

new.block
112 FUNCTION {new.block}
113 { output.state before.all =
114  'skip$
115  { after.block 'output.state := }
116 if$

117 }

new.sentence
118 FUNCTION {new.sentence}

119 {

120  output.state after.block =
121  'skip$
122  { output.state before.all =
123  'skip$
124  { after.sentence 'output.state := }

125  if$

126 }

127  if$

128 }

output.year.check This is somewhat nasty. We need to put a quad space around the year. Unfortunately, the obvious thing (i.e., putting out “\quad⟨year⟩\quad”) won’t work because the next call to output will add a period after the second \quad. Because of the way BibTEX writes things, it would be difficult to get the \quad in the right place, so instead we cheat by wrapping the year in the macro \bibyear, which is defined in acmart to look ahead one character and, if necessary, move the period before the second quad space.

This should be thought about some more.

129 FUNCTION {output.year.check}
130 { year empty$
131  { "empty year in " cite$ * warning$ }
132  { add.period$ write$
133  " \bibyear{" year * extra.label * "}" *
134  mid.sentence 'output.state :=

135 }

136 if$

137 }

fin.entry
138 FUNCTION {fin.entry}
139 { add.period$
140 write$
141 newline$

142 }

not
143 FUNCTION {not}
144 {   { #0 }
145  { #1 }
146 if$

147 }

and
148 FUNCTION {and}
149 {   'skip$
150  { pop$ #0 }
151 if$

152 }

or
153 FUNCTION {or}
154 {   { pop$ #1 }
155  'skip$
156 if$

157 }

new.block.checka
158 FUNCTION {new.block.checka}
159 { empty$
160  'skip$
161  'new.block
162 if$

163 }

new.block.checkb
164 FUNCTION {new.block.checkb}
165 { empty$
166 swap$ empty$
167 and
168  'skip$
169  'new.block
170 if$

171 }

new.sentence.checka
172 FUNCTION {new.sentence.checka}
173 { empty$
174  'skip$
175  'new.sentence
176 if$

177 }

new.sentence.checkb
178 FUNCTION {new.sentence.checkb}
179 { empty$
180 swap$ empty$
181 and
182  'skip$
183  'new.sentence
184 if$

185 }

field.or.null
186 FUNCTION {field.or.null}
187 { duplicate$ empty$
188  { pop$ "" }
189  'skip$
190 if$

191 }

parenthesize Put parentheses around the top string on the stack.

192 FUNCTION {parenthesize}
193 { duplicate$ empty$
194  { pop$ "" }
195  { " (" swap$ * ")" * }

196 if$

197 }

emphasize Emphasize the top string on the stack.

It’s a shame that we can’t assume people are using L^{A}TEX 2ε, since the \emph command would be much more convenient here. As it is, we have to try to guess whether or not we will need an italic correction, and use either emphasize or emphasize.ic as appropriate. As a partial solution, we use the macros \bibemph and \bibemphic, which should be defined by the style file. For L^{A}TEX 2ε, these can both be equivalent to \emph; for L^{A}TEX 2.09, \bibemphic should add an italic correction and \bibemph should not.

198 FUNCTION {emphasize}
199 { duplicate$ empty$
200  { pop$ "" }
201  { "\bibemph{" swap$ * "}" * }
202 if$

203 }

emphasize.ic Emphasize the top string on the stack, but add a trailing space.

204 FUNCTION {emphasize.ic}
205 { duplicate$ empty$
206  { pop$ "" }
207  { "\bibemphic{" swap$ * "}" * }
208 if$

209 }

emphasize.comma Emphasize the top string on stack, add a trailing comma and space.

Removed superfluous italic correction, moved comma outside of emphasis. [8/15/95—dmj]

210 FUNCTION {emphasize.comma}
211 { duplicate$ empty$
212  { pop$ "" }
213  { emphasize "," * }
214 if$

215 }

smallcaps Put the top string on the stack in small caps.

216 FUNCTION {smallcaps}
217 { duplicate$ empty$
218  { pop$ "" }
219  { "\bibsc{" swap$ * "}" * }
220 if$

221 }

format.names Format bibliographical entries with the last name first. All names are formatted

in this routine.

Changed so that entire author list is surrounded by {\sc and }, instead of surrounding each individual element. Also moved “Junior” part to the very end, so that it appears after the first initial instead of before.

222 INTEGERS { nameptr namesleft numnames }

223

224 FUNCTION {format.names}
225 { 's :=
226 #1 'nameptr :=               % nameptr = 1;
227 s num.names$ 'numnames :=    % numnames = num.name$(s);
228 numnames 'namesleft :=
229  { namesleft #0 > }

230 {

231 %      nameptr #1 =
232 %        {s nameptr "{vv~}{ll}{, f.}{, jj}" format.name$ 't := } {
233  s nameptr "{vv~}{ll}{, f.}{, jj}" format.name$ 't :=
234 %      } if$
235  nameptr #1 >
236  { namesleft #1 >
237  { ", " * t * }
238  { numnames #2 >
239  { "," * }
240  'skip$
241  if$
242  t "others" =
243  { " et~al." * }
244  { " and " * t * } % from Chicago Manual of Style
245  if$

246 }

247  if$

248 } 249 't

250  if$
251  nameptr #1 + 'nameptr :=          % nameptr += 1;
252  namesleft #1 - 'namesleft :=      % namesleft =- 1;

253 }

254 while$

255 }

my.full.label
256 FUNCTION {my.full.label}
257 { 's :=
258 #1 'nameptr :=               % nameptr = 1;
259 s num.names$ 'numnames :=    % numnames = num.name$(s);
260 numnames 'namesleft :=
261  { namesleft #0 > }
262  { s nameptr "{vv~}{ll}" format.name$ 't :=  % get the next name
263  nameptr #1 >
264  { namesleft #1 >
265  { ", " * t * }
266  { numnames #2 >
267  { "," * }
268  'skip$
269  if$

270  t "others" =
271  { " et~al." * }
272  { " and " * t * } % from Chicago Manual of Style
273  if$

274 }

275  if$

276 } 277 't

278  if$
279  nameptr #1 + 'nameptr :=          % nameptr += 1;
280  namesleft #1 - 'namesleft :=      % namesleft =- 1;

281 }

282 while$

283 }

format.names.fml Format names in “familiar” format, with first initial followed by last name. Like

format.names, ALL names are formatted.

Changed so that entire author list is surrounded by {\sc and }, instead of surrounding each individual element.

284 FUNCTION {format.names.fml}
285 { 's :=
286 #1 'nameptr :=               % nameptr = 1;
287 s num.names$ 'numnames :=    % numnames = num.name$(s);
288 numnames 'namesleft :=
289  { namesleft #0 > }
290  { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't :=
291  nameptr #1 >
292  { namesleft #1 >
293  { ", " * t * }
294  { numnames #2 >
295  { "," * }
296  'skip$
297  if$
298  t "others" =
299  { " et~al." * }
300  { " and " * t * }
301  if$

302 }

303  if$

304 } 305 't

306  if$
307  nameptr #1 + 'nameptr :=          % nameptr += 1;
308  namesleft #1 - 'namesleft :=      % namesleft =- 1;

309 }

310 while$

311 }

format.authors

312 FUNCTION {format.authors}
313 { author empty$
314  { "" }
315  { author format.names smallcaps }
316 if$

317 }

format.key
318 FUNCTION {format.key}
319 { empty$
320  { key field.or.null }
321  { "" }
322 if$

323 }

format.editors.fml Format editor names for use in the “in” types: inbook, incollection, inproceedings: first initial, then last names. When editors are the LABEL for an entry, then format.editor is used which lists editors by last name first.

Removed parens around “Ed.” since that seems to be desired by the ACM. [8/18/95—dmj]

324 FUNCTION {format.editors.fml}
325 { editor empty$
326  { "" }
327  { editor format.names.fml
328  editor num.names$ #1 >
329  { ", Eds." * }
330  { ", Ed." * }
331  if$

332 }

333 if$

334 }

format.editors Format editor names for use in labels, last names first.

Removed parens around “Ed.” since that seems to be desired by the ACM. [8/18/95—dmj]

335 FUNCTION {format.editors}
336 { editor empty$
337  { "" }
338  { editor format.names smallcaps
339  editor num.names$ #1 >
340  { ", Eds." * }
341  { ", Ed." * }
342  if$

343 }

344 if$

345 }

format.title
346 FUNCTION {format.title}

347 { title empty$
348  { "" }
349  { title "t" change.case$ }
350 if$

351 }

n.dashify
352 FUNCTION {n.dashify}
353 { 't :=

354 ""

355 { t empty$ not }
356  { t #1 #1 substring$ "-" =
357  { t #1 #2 substring$ "--" = not
358  { "--" *
359  t #2 global.max$ substring$ 't :=

360 }

361  {   { t #1 #1 substring$ "-" = }
362  { "-" *
363  t #2 global.max$ substring$ 't :=

364 }

365  while$

366 }

367  if$

368 }

369  { t #1 #1 substring$ *
370  t #2 global.max$ substring$ 't :=

371 }

372  if$

373 }

374 while$

375 }

format.btitle
376 FUNCTION {format.btitle}
377 { edition empty$
378 { title emphasize }
379 { title empty$

The following branch is somewhat eccentric, but I’ll leave it for now since it’s harmless, and in the current code, format.btitle is always followed by a call to output.check, which will generate a warning message if necessary.

380  { title emphasize }
381  { volume empty$     % gnp - check for volume, then don't need period
382  { title emphasize.ic edition " ed." * parenthesize * "." * }
383  { title emphasize.ic edition " ed." * parenthesize * }
384  if$

385 }

386  if$

387 }

388 if$

format.emphasize.booktitle
390 FUNCTION {format.emphasize.booktitle}
391 { edition empty$
392 { booktitle emphasize.ic }
393 { booktitle empty$

The following branch is also somewhat eccentric, but I’ll leave it for now since it should never be taken in the current code.

394  { booktitle emphasize }
395  { volume empty$  % gnp - extra period an error if book has a volume
396  { booktitle emphasize.ic edition " ed." * parenthesize * "." *}
397  { booktitle emphasize.ic edition " ed." * parenthesize * }
398  if$

399 }

400  if$

401 }

402 if$

403 }

tie.or.space.connect
404 FUNCTION {tie.or.space.connect}
405 { duplicate$ text.length$ #3 <
406  { "~" }
407  { " " }
408 if$
409 swap$ * *

410 }

either.or.check
411 FUNCTION {either.or.check}
412 { empty$
413  'pop$
414  { "can't use both " swap$ * " fields in " * cite$ * warning$ }
415 if$

416 }

format.bvolume
417 FUNCTION {format.bvolume}

418 {

419  series empty$
420  { "" }
421  { series emphasize }
422  if$
423  volume empty$
424  'skip$
425  { " vol." volume tie.or.space.connect * }
426  if$

427 }

429 % FUNCTION {format.bvolume}
430 % { volume empty$
431 %     { "" }
432 %     { "Volume" volume tie.or.space.connect % gnp - changed to mixed case
433 %       series empty$
434 %         'skip$
435 %         { " of " * series emphasize * }
436 %       if$
437 %       "volume and number" number either.or.check

438 % }

439 %   if$

440 % }

format.number.series
441 FUNCTION {format.number.series}

442 {

443  volume empty$
444  { number empty$
445  { series field.or.null }
446  { "Number" number tie.or.space.connect
447  series empty$
448  { "there's a number but no series in " cite$ * warning$ }
449  { " in " * series * }
450  if$

451 }

452  if$

453 }

454  { "" }
455  if$

456 }

multi.page.check
457 INTEGERS { multiresult }

458

459 FUNCTION {multi.page.check}
460 { 't :=
461 #0 'multiresult :=
462  { multiresult not
463  t empty$ not
464  and

465 }

466  { t #1 #1 substring$
467  duplicate$ "-" =
468  swap$ duplicate$ "," =
469  swap$ "+" =
470  or or
471  { #1 'multiresult := }
472  { t #2 global.max$ substring$ 't := }
473  if$

475 while$
476 multiresult

477 }

format.pages gnp - removed ()

478 FUNCTION {format.pages}
479 { pages empty$
480 { "" }

481 {

482 %    pages multi.page.check {
483  "pp.\ " pages n.dashify tie.or.space.connect
484 %       } { "pp.\ " pages tie.or.space.connect }
485 %    if$

486 }

487 if$

488 }

format.jour.vol By Young (and Spencer) GNP - fixed bugs with missing volume, number, and/or

pages Format journal, volume, number, pages for article types.

489 FUNCTION {format.jour.vol}
490 { journal empty$
491  { "no journal in " cite$ * warning$
492  "" }
493  { journal emphasize.ic }
494  if$
495 number empty$
496  { volume empty$
497  { "no number and no volume in " cite$ * warning$
498  "" * }
499  { "~" * volume emphasize * }
500  if$

501 }

502  { volume empty$
503  {"no volume for " cite$ * warning$
504  "~" * number * }
505  { "~" *
506  volume emphasize.comma
507  "~" * number * * }
508  if$
509  month empty$
510  'skip$
511  {month parenthesize *}
512  if$

513 }

514 if$
515 pages empty$
516  {"page numbers missing in " cite$ * warning$

517  "" * } % gnp - place a null string on the stack for output
518  { duplicate$ empty$
519  { pop$ format.pages }
520  { ", " *  pages n.dashify * } % gnp - removed pp. for articles
521  if$

522 }

523 if$

524 }

format.chapter.pages
525 FUNCTION {format.chapter.pages}
526 { chapter empty$
527  'format.pages
528  { type empty$
529  { "Chapter" } % gnp - changed to mixed case
530  { type "t" change.case$ }
531  if$
532  chapter tie.or.space.connect
533  pages empty$
534  {"page numbers missing in " cite$ * warning$}%gnp - added check
535  { ", " * format.pages * }
536  if$

537 }

538 if$

539 }

format.in.ed.booktitle
540 FUNCTION {format.in.ed.booktitle}
541 { booktitle empty$
542 { "" }
543 { editor empty$
544  { "In " format.emphasize.booktitle * }
545  { "In " format.editors.fml * ", " * format.emphasize.booktitle * }
546  if$

547 }

548 if$

549 }

format.thesis.title
550 FUNCTION {format.thesis.title}
551 { title empty$
552  'skip$
553 %   {pop$
554 { { "" }
555  title "t" change.case$

556 }

557 if$

558 }

format.tr.number
559 FUNCTION {format.tr.number}
560 { type empty$
561  { "Technical Report" }
562  'type
563 if$
564 number empty$
565  { "t" change.case$ }
566  { number tie.or.space.connect }
567 if$

568 }

format.crossref Merged format.article.crossref and format.incoll.inproc.crossref into

a single macro, format.crossref, which has proper spacing.

569 ⟨∗xref⟩

570 FUNCTION {format.crossref}

571 {

572  "See \citeN{" crossref * "}" *

573 } 574 ⟨/xref⟩

format.crossref.editor

575 ⟨∗xref⟩

576 FUNCTION {format.crossref.editor}
577 { editor #1 "{vv~}{ll}" format.name$
578 editor num.names$ duplicate$
579 #2 >
580  { pop$ " et~al." * }
581  { #2 <
582  'skip$
583  { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
584  { " et~al." * }
585  { " and " * editor #2 "{vv~}{ll}" format.name$ * }
586  if$

587 }

588  if$

589 }

590 if$

591 } 592 ⟨/xref⟩

format.book.crossref

593 ⟨∗xref⟩

594 FUNCTION {format.book.crossref}
595 { volume empty$
596  { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
597  "In "

598 }

599  { "Volume" volume tie.or.space.connect % gnp - changed to mixed case

600  " of " *

601 }

602 if$
603 editor empty$
604 editor field.or.null author field.or.null =

605 or

606  { key empty$
607  { series empty$
608  { "need editor, key, or series for " cite$ * " to crossref " *
609  crossref * warning$
610  "" *

611 }

612  { series emphasize.ic }
613  if$

614 }

615  { key * }
616  if$

617 }

618  { format.crossref.editor * }
619 if$
620 " \citeN{" * crossref * "}" *

621 } 622 ⟨/xref⟩

format.lab.names Determines “short” names for the abbreviated author information. “Long” labels are created in calc.label, using the routine my.full.label to format author and editor fields.

There are 4 cases for labels (n = 3 in the example):

1. one author: Foo

2. one to n: Foo, Bar and Baz

3. use of “and others”: Foo, Bar et al.

4. more than n: Foo et al.

623 FUNCTION {format.lab.names}
624 { 's :=
625 s num.names$ 'numnames :=
626 numnames #2 >    % change number to number of others allowed before
627  % forcing "et al".
628  { s #1 "{vv~}{ll}" format.name$ " et~al." * }

629 {

630  numnames #1 - 'namesleft :=
631  #2 'nameptr :=
632  s #1 "{vv~}{ll}" format.name$
633  { namesleft #0 > }
634  { nameptr numnames =
635  { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" =
636  { " et~al." * }

637  { " and " * s nameptr "{vv~}{ll}" format.name$ * }
638  if$

639 }

640  { ", " * s nameptr "{vv~}{ll}" format.name$ * }
641  if$
642  nameptr #1 + 'nameptr :=
643  namesleft #1 - 'namesleft :=

644 }

645  while$

646 }

647 if$

648 }

author.key.label
649 FUNCTION {author.key.label}
650 { author empty$
651  { key empty$
652  { "no key, author in " cite$ * warning$
653  cite$ #1 #3 substring$ }
654  'key
655  if$

656 }

657  { author format.lab.names }
658 if$

659 }

editor.key.label
660 FUNCTION {editor.key.label}
661 { editor empty$
662  { key empty$
663  { "no key, editor in " cite$ * warning$
664  cite$ #1 #3 substring$ }
665  'key
666  if$

667 }

668  { editor format.lab.names }
669 if$

670 }

author.key.org.label added - gnp. Provide label formatting by organization if author is null.

671 FUNCTION {author.key.org.label}
672 { author empty$
673  { organization empty$
674  { key empty$
675  { "no key, author or organization in " cite$ * warning$
676  cite$ #1 #3 substring$ }
677  'key
678  if$

679 }

680  'organization
681  if$

682 }

683  { author format.lab.names }
684 if$

685 }

editor.key.org.label added - gnp. Provide label formatting by organization if editor is null.

686 FUNCTION {editor.key.org.label}
687 { editor empty$
688  { organization empty$
689  { key empty$
690  { "no key, editor or organization in " cite$ * warning$
691  cite$ #1 #3 substring$ }
692  'key
693  if$

694 }

695  'organization
696  if$

697 }

698  { editor format.lab.names }
699 if$

700 }

author.editor.key.label
701 FUNCTION {author.editor.key.label}
702 { author empty$
703  { editor empty$
704  { key empty$
705  { "no key, author, or editor in " cite$ * warning$
706  cite$ #1 #3 substring$ }
707  'key
708  if$

709 }

710  { editor format.lab.names }
711  if$

712 }

713  { author format.lab.names }
714 if$

715 }

calc.label GNP: changed. Form label for BibTEX entry. The classification of which fields are used for which type of entry (book, inbook, etc.) are taken from alpha.bst. The change here from newapa is to also include organization as a citation label if author or editor is missing. See also author.organization.sort,

 editor.organization.sort.
716 FUNCTION {calc.label}
717 { type$ "book" =
718 type$ "inbook" =

719 or

720  'author.editor.key.label
721  { type$ "proceedings" =
722  'editor.key.org.label
723  { type$ "manual" =
724  'author.key.org.label
725  'author.key.label
726  if$

727 }

728  if$

729 }

730 if$
731 author empty$  % generate the full label citation information.
732  { editor empty$
733  { organization empty$
734  { "no author, editor, or organization in " cite$ * warning$
735  "??" }
736  'organization
737  if$

738 }

739  { editor my.full.label }
740  if$

741 }

742  { author my.full.label }
743 if$

leave label on the stack, to be popped when required.

744 "}{" * swap$ * "}{" *
745 %  year field.or.null purify$ #-1 #4 substring$ *

save the year for sort processing afterwards (adding a, b, c, etc.)

746 year field.or.null purify$ #-1 #4 substring$
747 'label.year :=

748 }

output.bibitem
749 FUNCTION {output.bibitem}
750 { newline$
751 "\bibitem[\protect\citeauthoryear{" write$
752 calc.label write$
753 sort.year write$
754 "}]{" write$
755 cite$ write$
756 "}" write$
757 newline$

758 ""

759 before.all 'output.state :=

760 }

6.2 The entry types

6.2.1 The article type

article
761 FUNCTION {article}

762 {

763  output.bibitem
764  format.authors "author" output.check

Some but not all types contain the following line. It’s questionable whether it belongs there at all, but if it does, shouldn’t it be in all the types?

765  author format.key output          % added
766  output.year.check                 % added
767  new.block
768  format.title "title" output.check
769  new.block

770 ⟨∗xref⟩

771  crossref missing$

772 { 773 ⟨/xref⟩

774  format.jour.vol output

775 ⟨∗xref⟩ 776 } 777 {

778  format.crossref output.nonnull
779  format.pages output

780 }

781  if$

782 ⟨/xref⟩

783 new.block
784 note output
785 fin.entry

786 }

6.2.2 The book type

book
787 FUNCTION {book}
788 { output.bibitem
789 author empty$
790  { format.editors "author and editor" output.check }
791  { format.authors
792  output.nonnull
793  crossref missing$
794  { "author and editor" editor either.or.check }
795  'skip$
796  if$

797 }

798 if$

799 output.year.check       % added
800 new.block
801 format.btitle "title" output.check

802 ⟨∗xref⟩

803 crossref missing$

804 { 805 ⟨/xref⟩

806  format.bvolume output
807  new.block
808  format.number.series output
809  new.sentence
810  publisher "publisher" output.check
811  address output

812 ⟨∗xref⟩ 813 } 814 {

815  new.block
816  format.book.crossref output.nonnull

817 }

818 if$

819 ⟨/xref⟩

820 new.block
821 note output
822 fin.entry

823 }

6.2.3 The booklet type

booklet
824 FUNCTION {booklet}
825 { output.bibitem
826 format.authors output
827 author format.key output          % added
828 output.year.check                 % added
829 new.block
830 format.title "title" output.check
831 new.block
832 howpublished output
833 address output
834 new.block
835 note output
836 fin.entry

837 }

6.2.4 The inbook type

inbook
838 FUNCTION {inbook}
839 { output.bibitem

840 author empty$
841  { format.editors "author and editor" output.check

842 }

843  { format.authors output.nonnull
844  crossref missing$
845  { "author and editor" editor either.or.check }
846  'skip$
847  if$

848 }

849 if$
850 output.year.check                 % added
851 new.block
852 format.btitle "title" output.check

853 ⟨∗xref⟩

854 crossref missing$

855 { 856 ⟨/xref⟩

857  format.bvolume output
858  format.chapter.pages "chapter and pages" output.check
859  new.block
860  format.number.series output
861  new.sentence
862  publisher "publisher" output.check.colon
863  address output

864 ⟨∗xref⟩ 865 } 866 {

867  format.chapter.pages "chapter and pages" output.check
868  new.block
869  format.book.crossref output.nonnull

870 }

871 if$

872 ⟨/xref⟩

873 new.block
874 note output
875 fin.entry

876 }

 6.2.5 The incollection type
incollection
877 FUNCTION {incollection}
878 { output.bibitem
879 format.authors "author" output.check
880 author format.key output       % added
881 output.year.check              % added
882 new.block
883 format.title "title" output.check
884 new.block

885 ⟨∗xref⟩

886 crossref missing$

887 { 888 ⟨/xref⟩

889  format.in.ed.booktitle "booktitle" output.check
890  format.bvolume output
891  format.number.series output
892  format.chapter.pages output % gnp - was special.output.nonnull
893 %                                 left out comma before page numbers
894  new.sentence
895  address output
896  publisher "publisher" output.check.colon

897 ⟨∗xref⟩ 898 } 899 {

900  format.crossref output.nonnull
901  format.chapter.pages output

902 }

903 if$

904 ⟨/xref⟩

905 new.block
906 note output
907 fin.entry

908 }

 6.2.6 The inproceedings type
format.date
909 FUNCTION {format.date}
910 { year empty$
911  { month empty$
912  { "" }
913  { "there's a month but no year in " cite$ * warning$
914  month

915 }

916  if$

917 }

918  { month empty$
919  'year
920  { month " " * year * }
921  if$

922 }

923 if$

924 }

format.proc.loc.date
925 FUNCTION {format.proc.loc.date}

926 {

927  address field.or.null

928  format.date
929  duplicate$ empty$
930  'pop$
931  { swap$
932  duplicate$ empty$
933  'pop$
934  { ", " * swap$ * }
935  if$

936 }

937  if$
938  parenthesize

939 * 940 }

inproceedings Added format.proc.loc.date to format proceedings location and date. Should

also add something like format.proc.publisher to handle the pub-year, pub-month

and pub-address fields, but should first find out from ACM how such things should be handled. In particular, if year of publication is different from year of conference, which should be used in citation (presumably the year of publication).

A related problem is to decide exactly what the year refers to. In the standard styles, if there is a year but no address, the year is assumed to refer to the date of publication, while if there is an address, the address and date are assumed to refer to the conference. For true compatibility with the standard styles, we should probably preserve this distinction.

941 FUNCTION {inproceedings}

942 {

943 output.bibitem
944 format.authors "author" output.check
945 author format.key output            % added
946 output.year.check                   % added
947 new.block
948 format.title "title" output.check
949 new.block

950 ⟨∗xref⟩

951 crossref missing$

952 { 953 ⟨/xref⟩

954  format.in.ed.booktitle "booktitle" output.check
955  format.bvolume output
956  format.number.series output
957 %      address output
958  format.proc.loc.date %output
959 %      format.pages output
960  new.sentence
961  organization output
962  publisher output %.colon
963  format.pages output

964 ⟨∗xref⟩ 965 }

967  format.crossref output.nonnull
968  format.pages output

969 }

970 if$

971 ⟨/xref⟩

972 new.block
973 note output
974 fin.entry

975 }

6.2.7 The conference type

conference
976 FUNCTION {conference} { inproceedings }

6.2.8 The manual type

manual
977 FUNCTION {manual}
978 { output.bibitem
979 author empty$
980  { editor empty$
981  { organization "organization" output.check
982  organization format.key output }  % if all else fails, use key
983  { format.editors "author and editor" output.check }
984  if$

985 }

986  { format.authors output.nonnull }
987  if$
988 output.year.check                 % added
989 new.block
990 format.btitle "title" output.check
991 organization address new.block.checkb

Reversed the order of “address” and “organization”, added the “:”.

992 address output
993 organization "organization" output.check.colon
994 %  address output
995 %  ":" output
996 %  organization output
997 new.block
998 note output
999 fin.entry

1000 }

 6.2.9 The mastersthesis type
mastersthesis

1001 FUNCTION {mastersthesis}
1002 { output.bibitem
1003 format.authors "author" output.check
1004 author format.key output          % added
1005 output.year.check                 % added
1006 new.block
1007 format.title "title" output.check
1008 new.block
1009 "Master's thesis" format.thesis.title output.nonnull
1010 school "school" output.check
1011 address output
1012 new.block
1013 note output
1014 fin.entry

1015 }

6.2.10 The misc type

misc
1016 FUNCTION {misc}
1017 { output.bibitem
1018 format.authors output
1019 author format.key output            % added
1020 output.year.check                   % added
1021 title howpublished new.block.checkb
1022 format.title output
1023 new.block
1024 howpublished output
1025 new.block
1026 note output
1027 fin.entry

1028 }

6.2.11 The phdthesis type

phdthesis
1029 FUNCTION {phdthesis}
1030 { output.bibitem
1031 format.authors "author" output.check
1032 author format.key output            % added
1033 output.year.check                   % added
1034 new.block
1035 format.btitle "title" output.check
1036 new.block
1037 format.thesis.title "Ph.\ D. thesis" output.nonnull
1038 school "school" output.check
1039 address output
1040 new.block
1041 note output

1042 fin.entry

1043 }

6.2.12 The proceedings type

proceedings
1044 FUNCTION {proceedings}
1045 { output.bibitem
1046 editor empty$
1047  { organization output
1048  organization format.key output } % gnp - changed from
1049  { format.editors output.nonnull }  % author format.key

1050 if$

1051 % author format.key output             % gnp - removed (should be either
1052 %                                        editor or organization
1053 output.year.check                    % added (newapa)
1054 new.block
1055 format.btitle "title" output.check
1056 format.bvolume output
1057 format.number.series output
1058 %  address output
1059  format.proc.loc.date % output
1060 new.sentence
1061 organization output
1062 publisher output.colon
1063 new.block
1064 note output
1065 fin.entry

1066 }

6.2.13 The techreport type

techreport
1067 FUNCTION {techreport}
1068 { output.bibitem
1069 format.authors "author" output.check
1070 author format.key output             % added
1071 output.year.check                    % added
1072 new.block
1073 format.title "title" output.check
1074 new.block
1075 format.tr.number
1076  month empty$
1077  'skip$
1078  { month parenthesize * }

1079 if$

1080 output.nonnull
1081 institution "institution" output.check
1082 address output

1083 new.block
1084 note output
1085 fin.entry

1086 }

6.2.14 The unpublished type

unpublished
1087 FUNCTION {unpublished}
1088 { output.bibitem
1089 format.authors "author" output.check
1090 author format.key output              % added
1091 output.year.check                      % added
1092 new.block
1093 format.title "title" output.check
1094 new.block
1095 note "note" output.check
1096 fin.entry

1097 }

6.2.15 The default.type type

default.type
1098 FUNCTION {default.type} { misc }

6.3 Standard abbreviations

The following abbreviations should all be checked to make sure they correspond to what the ACM wants.

1099 MACRO {jan} {"Jan."}

1100

1101 MACRO {feb} {"Feb."}

1102

1103 MACRO {mar} {"March"}

1104

1105 MACRO {apr} {"April"}

1106

1107 MACRO {may} {"May"}

1108

1109 MACRO {jun} {"June"}

1110

1111 MACRO {jul} {"July"}

1112

1113 MACRO {aug} {"Aug."}

1114

1115 MACRO {sep} {"Sept."}

1116

1117 MACRO {oct} {"Oct."}

1118

1119 MACRO {nov} {"Nov."}

1120

1121 MACRO {dec} {"Dec."}

1122

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

1124

1125 MACRO {acta} {"Acta Informatica"}

1126

1127 MACRO {ai} {"Artificial Intelligence"}

1128

1129 MACRO {cacm} {"Commun. ACM"}

1130

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

1132

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

1134

1135 MACRO {ieeese} {"IEEE Trans. Softw. Eng."}

1136

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

1138

1139 MACRO {ieeetcad}
1140 {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}

1141

1142 MACRO {ipl} {"Inf. Process. Lett."}

1143

1144 MACRO {ic} {"Inf. Comput."}

1145

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

1147

1148 MACRO {jcss} {"J. Comput. Syst. Sci."}

1149

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

1151

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

1153

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

1155

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

1157

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

1159

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

1161

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

1163

1164 MACRO {toplas} {"ACM Trans. on Programm. Lang. Syst."}

1165

1166 MACRO {tcs} {"Theor. Comp. Sci."}

1167

1168 READ

6.4 Sorting the entries

sortify
1169 FUNCTION {sortify}
1170 { purify$
1171 "l" change.case$

1172 }

chop.word
1173 INTEGERS { len }

1174

1175 FUNCTION {chop.word}
1176 { 's :=
1177 'len :=
1178 s #1 len substring$ =
1179  { s len #1 + global.max$ substring$ }

1180 's 1181 if$ 1182 }

sort.format.names
1183 FUNCTION {sort.format.names}
1184 { 's :=
1185 #1 'nameptr :=

1186 ""

1187 s num.names$ 'numnames :=
1188 numnames 'namesleft :=
1189  { namesleft #0 > }
1190  { nameptr #1 >
1191  { "   " * }
1192  'skip$

1193 if$

1194  s nameptr "{vv{ } }{ll{ }}{  f{ }}{  jj{ }}" format.name$ 't :=
1195  nameptr numnames = t "others" = and
1196  { " et~al" * }
1197  { t sortify * }

1198 if$

1199  nameptr #1 + 'nameptr :=
1200  namesleft #1 - 'namesleft :=

1201 }

1202 while$

1203 }

sort.format.title
1204 FUNCTION {sort.format.title}
1205 { 't :=
1206 "A " #2
1207  "An " #3
1208  "The " #4 t chop.word

1209  chop.word
1210 chop.word
1211 sortify
1212 #1 global.max$ substring$

1213 }

author.sort
1214 FUNCTION {author.sort}
1215 { author empty$
1216  { key empty$
1217  { "to sort, need author or key in " cite$ * warning$

1218 "" }

1219  { key sortify }

1220 if$ 1221 }

1222  { author sort.format.names }

1223 if$ 1224 }

editor.sort
1225 FUNCTION {editor.sort}
1226 { editor empty$
1227  { key empty$
1228  { "to sort, need editor or key in " cite$ * warning$

1229 "" 1230 }

1231  { key sortify }

1232 if$ 1233 }

1234  { editor sort.format.names }

1235 if$ 1236 }

author.editor.sort
1237 FUNCTION {author.editor.sort}

1238 {

1239  author empty$
1240  { "missing author in " cite$ * warning$
1241  editor empty$
1242  { key empty$
1243  { "to sort, need author, editor, or key in "
1244  cite$ * warning$

1245 "" 1246 } 1247 {

1248  key sortify

1249 } 1250 if$ 1251 }

1253  editor sort.format.names

1254 } 1255 if$ 1256 } 1257 {

1258  author sort.format.names

1259 } 1260 if$ 1261 }

author.organization.sort added - GNP. Stack author or organization for sorting (from alpha.bst). Unlike alpha.bst, we need entire names, not abbreviations

1262 FUNCTION {author.organization.sort}
1263 { author empty$
1264  { organization empty$
1265  { key empty$
1266  { "to sort, need author, organization, or key in "
1267  cite$ * warning$

1268 "" 1269 }

1270  { key sortify }

1271 if$ 1272 }

1273  { organization sortify }

1274 if$ 1275 }

1276  { author sort.format.names }

1277 if$ 1278 }

editor.organization.sort added - GNP. Stack editor or organization for sorting (from alpha.bst). Unlike alpha.bst, we need entire names, not abbreviations

1279 FUNCTION {editor.organization.sort}
1280 { editor empty$
1281  { organization empty$
1282  { key empty$
1283  { "to sort, need editor, organization, or key in "
1284  cite$ * warning$

1285 "" 1286 }

1287  { key sortify }

1288 if$ 1289 }

1290  { organization sortify }

1291 if$ 1292 }

1293  { editor sort.format.names }

1294 if$ 1295 }

presort Presort creates the bibentry’s label via a call to calc.label, and then sorts the entries based on entry type. Chicago.bst adds support for including organizations as the sort key; the following is stolen from alpha.bst.

1296 FUNCTION {presort}
1297 { calc.label sortify % recalculate bibitem label
1298 year field.or.null purify$ #-1 #4 substring$ * % add year

1299 " " 1300 *

1301 type$ "book" =
1302 type$ "inbook" =

1303 or

1304  'author.editor.sort
1305  { type$ "proceedings" =
1306  'editor.organization.sort
1307  { type$ "manual" =
1308  'author.organization.sort
1309  'author.sort

1310 if$ 1311 } 1312 if$ 1313 } 1314 if$

1315 #1 entry.max$ substring$        % added for newapa
1316 'sort.label :=                  % added for newapa
1317 sort.label                      % added for newapa

1318 * 1319 " " 1320 *

1321 title field.or.null
1322 sort.format.title

1323 *

1324 #1 entry.max$ substring$
1325 'sort.key$ :=

1326 }

1327 ITERATE {presort}

1328

1329 SORT    % by label, year, author/editor, title

1330

init.extra.label.stuff
1331 STRINGS { last.label next.extra }

1332

1333 INTEGERS { last.extra.num }

1334

1335 FUNCTION {init.extra.label.stuff}
1336 { #0 int.to.chr$ 'last.label :=
1337 "" 'next.extra :=
1338 #0 'last.extra.num :=

1339 }

forward.pass Pass through all entries, comparing current entry to last one. Need to concatenate year to the stack (done by calc.label) to determine if two entries are the same

  (see presort)
1340 FUNCTION {forward.pass}
1341 { last.label
1342 calc.label year field.or.null purify$ #-1 #4 substring$ * % add year
1343 #1 entry.max$ substring$ =     % are they equal?
1344  { last.extra.num #1 + 'last.extra.num :=
1345  last.extra.num int.to.chr$ 'extra.label :=

1346 }

1347  { "a" chr.to.int$ 'last.extra.num :=
1348  "" 'extra.label :=
1349  calc.label
1350  year field.or.null purify$ #-1 #4 substring$ * % add year
1351  #1 entry.max$ substring$ 'last.label := % assign to last.label

1352 } 1353 if$ 1354 }

reverse.pass
1355 FUNCTION {reverse.pass}
1356 { next.extra "b" =
1357  { "a" 'extra.label := }
1358  'skip$

1359 if$

1360 label.year extra.label * 'sort.year :=
1361 extra.label 'next.extra :=

1362 }

1363 EXECUTE {init.extra.label.stuff}

1364

1365 ITERATE {forward.pass}

1366

1367 REVERSE {reverse.pass}
bib.sort.order
1368 FUNCTION {bib.sort.order}
1369 { sort.label

1370 " " 1371 *

1372 year field.or.null sortify

1373 * 1374 " " 1375 *

1376 title field.or.null
1377 sort.format.title

1378 *

1379 #1 entry.max$ substring$
1380 'sort.key$ :=

1381 }

1382 ITERATE {bib.sort.order}

1383

1384 SORT % by sort.label, year, title --- giving final bib. order.
begin.bib
1385 FUNCTION {begin.bib}
1386 { preamble$ empty$
1387  'skip$
1388  { preamble$ write$ newline$ }

1389 if$

1390 "\begin{thebibliography}{}" write$ newline$

1391 }

1392 EXECUTE {begin.bib}

1393

1394 EXECUTE {init.state.consts}

1395

1396 ITERATE {call.type$}
end.bib
1397 FUNCTION {end.bib}
1398 { newline$
1399 "\end{thebibliography}" write$ newline$

1400 }

1401 EXECUTE {end.bib}