Added format.month to move the day before the month
[latex-mlastyle.git] / mlastyle.bst
1 % $Id: mlastyle.bst,v 1.20 2005-02-09 03:53:11 tpope Exp $
2 % BibTeX bibliography style `mlastyle'
3 % Based on BibTeX standard bibliography style `plain'
4         % version 0.99a for BibTeX versions 0.99a or later, LaTeX version 2.09.
5         % Copyright (C) 2003 Tim Pope, all rights reserved.
6         % Copying of this file is authorized only if either
7         % (1) you make absolutely no changes to your copy, including name, or
8         % (2) if you do make changes, you name it something other than
9         % btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst.
10         % This restriction helps ensure that all standard styles are identical.
11         % The file mlastyle.dvi has the documentation for this style.
12
13 ENTRY
14   { address
15     author
16     booktitle
17     chapter
18     edition
19     editor
20     howpublished
21     institution
22     journal
23     key
24     month
25     note
26     number
27     organization
28     pages
29     publisher
30     school
31     series
32     title
33     type
34     volume
35     year
36     % New fields
37     url
38     urldate
39     accessdate
40     urlpath
41     database
42     version
43     % eid isbn issn doi
44   }
45   { author.duplicate author.shared }
46   { label }
47
48 INTEGERS { output.state before.all mid.phrase mid.sentence after.sentence after.block author.different author.last author.flast citealp.used url.used }
49
50 STRINGS { s t u empty.title }
51
52 % Rearranged such that true values require capital letters
53 FUNCTION {init.consts}
54 { #-1 'mid.phrase :=
55   #0 'mid.sentence :=
56   #1 'before.all :=
57   #2 'after.sentence :=
58   #3 'after.block :=
59
60   #0 'author.different :=
61   #1 'author.last :=
62   #2 'author.flast :=
63   %#3 'author.firstlast :=
64
65   #0 'citealp.used :=
66   #0 'url.used :=
67   " \ \ \ \ \unskip\unskip\unskip\unskip\unskip " 'empty.title :=
68   "" 'empty.title :=
69 }
70
71 % I do this a lot
72 FUNCTION {duplicate}
73 {
74   duplicate$
75   "duplicate should be duplicate$" warning$
76 }
77
78 FUNCTION {not}
79 {   { #0 }
80     { #1 }
81   if$
82 }
83
84 FUNCTION {and}
85 {   'skip$
86     { pop$ #0 }
87   if$
88 }
89
90 FUNCTION {or}
91 {   { pop$ #1 }
92     'skip$
93   if$
94 }
95
96 INTEGERS {chars i j}
97
98 % text.length$ does not include braces
99 % This function is probably a bad idea
100 FUNCTION {num.chars}
101 {
102   #0 'chars :=
103     { duplicate$ duplicate$ #1 chars substring$ = not }
104     { duplicate$ duplicate$ text.length$ swap$ #1 chars
105     substring$ text.length$ - chars + #1 + 'chars := }
106   while$
107     { duplicate$ duplicate$ #1 chars #1 - substring$ = }
108     { chars #1 - 'chars := }
109   while$
110   pop$ chars
111 }
112
113 % Puts the period inside any quotes
114 FUNCTION {do.period}
115 {
116   duplicate$ #-1 #2 substring$ "''" =
117     { #2 'i :=
118         { duplicate$ #-1 i - #11 substring$ "'\thinspace" = }
119         { i #11 + 'i := }
120       while$
121       duplicate$ #-1 i - global.max$ substring$
122       add.period$ swap$ #-1 i substring$ *
123     }
124     {
125       duplicate$ #-1 #3 substring$ "''}" =
126         { #3 'i :=
127             { duplicate$ #-1 i - #11 substring$ "'\thinspace" = }
128             { i #11 + 'i := }
129           while$
130           duplicate$ #-1 i - global.max$ substring$
131           add.period$ swap$ #-1 i substring$ *
132         }
133         { add.period$ }
134       if$
135     }
136   if$
137 }
138
139 FUNCTION {do.space}
140 { duplicate$ duplicate$ do.period =
141     { "\ " * }
142     { " " * }
143   if$
144 }
145
146 % Switched to do.period and added mid.phrase
147 FUNCTION {output.nonnull}
148 { 's :=
149   output.state mid.sentence =
150     { ", " * write$ }
151     { output.state after.block =
152         { do.period write$
153           newline$
154           "\newblock " write$
155         }
156         { output.state before.all =
157             'write$
158             { output.state mid.phrase =
159                 { do.space write$ }
160                 { do.period " " * write$ }
161               if$
162             }
163           if$
164         }
165       if$
166       mid.sentence 'output.state :=
167     }
168   if$
169   s
170 }
171
172 FUNCTION {output}
173 { duplicate$ empty$
174     'pop$
175     'output.nonnull
176   if$
177 }
178
179 FUNCTION {output.check}
180 { 't :=
181   duplicate$ empty$
182     { pop$ "empty " t * " in " * cite$ * warning$ }
183     'output.nonnull
184   if$
185 }
186
187 % Switched to do.period
188 FUNCTION {fin.entry}
189 { do.period
190   write$
191   newline$
192 }
193
194 FUNCTION {new.block}
195 { output.state before.all =
196     'skip$
197     { after.block 'output.state := }
198   if$
199 }
200
201 FUNCTION {new.sentence}
202 { output.state after.block =
203     'skip$
204     { output.state before.all =
205         'skip$
206         { after.sentence 'output.state := }
207       if$
208     }
209   if$
210 }
211
212 FUNCTION {continue.sentence}
213 { output.state after.block =
214     'skip$
215     { output.state before.all =
216         'skip$
217         { mid.phrase 'output.state := }
218       if$
219     }
220   if$
221 }
222
223 FUNCTION {new.block.checka}
224 { empty$
225     'skip$
226     'new.block
227   if$
228 }
229
230 FUNCTION {new.block.checkb}
231 { empty$
232   swap$ empty$
233   and
234     'skip$
235     'new.block
236   if$
237 }
238
239 FUNCTION {new.sentence.checka}
240 { empty$
241     'skip$
242     'new.sentence
243   if$
244 }
245
246 FUNCTION {new.sentence.checkb}
247 { empty$
248   swap$ empty$
249   and
250     'skip$
251     'new.sentence
252   if$
253 }
254
255 FUNCTION {field.or.null}
256 { duplicate$ empty$
257     { pop$ "" }
258     'skip$
259   if$
260 }
261
262 FUNCTION {sortify}
263 { purify$
264   "l" change.case$
265 }
266
267 FUNCTION {emphasize}
268 { duplicate$ empty$
269     { pop$ "" }
270     { "\emph{" swap$ * "}" * }
271   if$
272 }
273
274 FUNCTION {enquote}
275 { duplicate$ empty$
276     { pop$ "" }
277     {
278       #1 'i :=
279       #0 'j :=
280         { duplicate$ i #1 substring$ "" = not }
281         { duplicate$ duplicate$ i #1 substring$ quote$ =
282           swap$ i #1 - #1 substring$ "\" = not and %"
283             { duplicate$ #1 i #1 - substring$ swap$
284               i #1 + global.max$ substring$
285               j
286                 { swap$ duplicate$ #-1 #1 substring$ "'" =
287                     { swap$ "\thinspace'" }
288                     { swap$ "'" }
289                   if$
290                    #0 'j :=
291                 }
292                 { duplicate$ #1 #1 substring$ "`" =
293                     { "`\thinspace" }
294                     { "`" }
295                   if$
296                 #1 'j :=
297                 }
298               if$
299               swap$ * *
300             }
301             'skip$
302           if$
303           i #1 + 'i :=
304         }
305       while$
306       j #1 =
307         { "odd number of quotation marks in " cite$ * warning$ }
308         'skip$
309       if$
310       duplicate$ #1 #1 substring$ "`" =
311         { "``\thinspace" swap$ * }
312         { "``" swap$ *}
313       if$
314       duplicate$ #-1 #1 substring$ "'" =
315         { "\thinspace''" * }
316         { "''" *}
317       if$
318     }
319   if$
320 }
321
322 FUNCTION {selective.emphasize}
323 { field.or.null duplicate$ sortify 's :=
324   s #1 #8 substring$ duplicate$ "rev. of " = swap$ "rev.~of " = or
325   s #1 #9 substring$ "rev.\ of " = or
326   s "home page" = or
327   s "america online" = or
328     'skip$
329     'emphasize
330   if$
331 }
332
333 FUNCTION {selective.enquote}
334 { field.or.null duplicate$ sortify 's :=
335   s #1 #8 substring$ duplicate$ "rev. of " = swap$ "rev.~of " = or
336   s #1 #9 substring$ "rev.\ of " = or
337   s "introduction" = or
338   s "preface" = or
339   s "forward" = or
340   s "afterward" = or
341   s "home page" = or
342     'skip$
343     'enquote
344   if$
345 }
346
347 INTEGERS { nameptr namesleft numnames }
348
349 FUNCTION {format.names.custom}
350 { 'u :=
351   's :=
352   #1 'nameptr :=
353   s num.names$ 'numnames :=
354   numnames 'namesleft :=
355     { namesleft #0 > }
356     { s nameptr u format.name$ 't :=
357       nameptr #1 >
358         { namesleft #1 >
359             { ", " * t * }
360             { numnames #2 >
361                 { "," * }
362                 'skip$
363               if$
364               t "others" =
365                 { " et~al." * }
366                 { " and " * t * }
367               if$
368             }
369           if$
370         }
371         't
372       if$
373       nameptr #1 + 'nameptr :=
374       namesleft #1 - 'namesleft :=
375     }
376   while$
377 }
378
379 FUNCTION {format.names}
380 { "{ff~}{vv~}{ll}{, jj}" format.names.custom }
381
382 % Changed first author to last name first
383 FUNCTION {format.names.beginning}
384 { 's :=
385   #1 'nameptr :=
386   s num.names$ 'numnames :=
387   numnames 'namesleft :=
388     { namesleft #0 > }
389     { nameptr #1 =
390         { s nameptr "{vv~}{ll}{, ff}{, jj}" format.name$
391           duplicate$ #1 #1 substring$ duplicate$ "{" =
392             'skip$
393             { "u" change.case$ }
394           if$
395           swap$ #2 global.max$ substring$ * 't :=
396         }
397         { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := }
398       if$
399       nameptr #1 >
400         { namesleft #1 >
401             { ", " * t * }
402             { numnames #2 >
403                 { "," * }
404                 'skip$
405               if$
406               t "others" =
407                 { " et~al." * }
408                 { " and " * t * }
409               if$
410             }
411           if$
412         }
413         't
414       if$
415       nameptr #1 + 'nameptr :=
416       namesleft #1 - 'namesleft :=
417     }
418   while$
419 }
420
421 % Added check for duplicate authors
422 FUNCTION {format.authors}
423 { author empty$
424     { "" }
425     { author.duplicate #1 =
426         { "-{}-{}-" }
427         { author format.names.beginning }
428       if$
429     }
430   if$
431 }
432
433 % Changed to MLA editor abbreviations
434 % author.duplicate also applies
435 FUNCTION {format.editors}
436 { editor empty$
437     { "" }
438     { author empty$ author.duplicate #1 = and
439         { "-{}-{}-" }
440         { editor format.names.beginning }
441       if$
442       editor num.names$ #1 >
443         { ", eds." * }
444         { ", ed." * }
445       if$
446     }
447   if$
448 }
449
450 FUNCTION {format.editors.mid}
451 { editor empty$
452     { "" }
453     {
454       editor num.names$ #1 >
455         { "Eds.\ " }
456         { "Ed.\ " }
457       if$
458       editor format.names *
459     }
460   if$
461 }
462
463 % Formats the address and publisher
464 FUNCTION {format.publisher}
465 { address empty$
466     { publisher }
467     { address ": " * publisher * }
468   if$
469 }
470
471 % Changed to preserve case and use quotes
472 FUNCTION {format.title}
473 { title selective.enquote
474 }
475
476 FUNCTION {n.dashify}
477 { 't :=
478   ""
479     { t empty$ not }
480     { t #1 #1 substring$ "-" =
481         { t #1 #2 substring$ "--" = not
482             { "--" *
483               t #2 global.max$ substring$ 't :=
484             }
485             {   { t #1 #1 substring$ "-" = }
486                 { "-" *
487                   t #2 global.max$ substring$ 't :=
488                 }
489               while$
490             }
491           if$
492         }
493         { t #1 #1 substring$ *
494           t #2 global.max$ substring$ 't :=
495         }
496       if$
497     }
498   while$
499 }
500
501 FUNCTION {format.year}
502 { year empty$
503     { "" }
504     { year n.dashify
505       duplicate$ duplicate$ num.chars #10 =
506       swap$ #5 #2 substring$ "--" = and
507         { duplicate$ duplicate$ #1 #2 substring$ swap$ #7 #2 substring$ =
508             { duplicate$ #1 #6 substring$ swap$ #9 #2 substring$ * }
509             {}
510           if$
511         }
512         {}
513       if$
514     }
515   if$
516 }
517
518 FUNCTION {format.month}
519 {
520   month #-1 #1 substring$ chr.to.int$ duplicate$ #47 > swap$ #58 < and
521     { 
522       month #-2 #1 substring$ chr.to.int$ duplicate$ #47 > swap$ #58 < and
523         { #2 'i := }
524         { #1 'i := }
525       if$
526       month #-2 i - #2 substring$ "\ " =
527         { month #0 i - i substring$
528           month #-2 i - #2 substring$
529           month #-3 i - global.max$ i - #2 - substring$
530           * *
531         }
532         {
533           month #-1 i - #1 substring$ duplicate$ " " = swap$ "~" = or
534             { month #0 i - i substring$
535               month #-1 i - #1 substring$
536               month #-2 i - global.max$ i - #1 - substring$
537               * *
538             }
539             { month }
540           if$
541         }
542       if$
543     }
544     { month }
545   if$
546 }
547
548 FUNCTION {format.date}
549 { year empty$
550     { month empty$
551         { "" }
552         { "there's a month but no year in " cite$ * warning$
553           format.month
554         }
555       if$
556     }
557     { month empty$
558         'format.year
559         { format.month do.space format.year * }
560       if$
561     }
562   if$
563 }
564
565 %INTEGERS {xx}
566 FUNCTION {format.btitle}
567 { title selective.emphasize
568 }
569
570 FUNCTION {tie.or.space.connect}
571 { duplicate$ text.length$ #3 <
572     { "~" swap$ * * }
573     { swap$ do.space swap$ * }
574   if$
575 }
576
577 FUNCTION {either.or.check}
578 { empty$
579     'pop$
580     { "can't use both " swap$ * " fields in " * cite$ * warning$ }
581   if$
582 }
583
584 FUNCTION {abbreviate}
585 { duplicate$ sortify 's := 't :=
586   ""
587   "10th" "tenth" "9th" "ninth" "8th" "eighth" "7th" "seventh" "6th" "sixth"
588   "5th" "fifth" "4th" "fourth" "3rd" "third" "2nd" "second" "1st" "first"
589   "Rev." "revised" "Abr." "abridged"
590   {duplicate$ empty$ { pop$ #0 }{ #1 } if$ }{ s = { 't := }{ pop$ } if$ }
591   while$
592   t
593 }
594
595 FUNCTION {format.bvolume.or.num.series}
596 { volume empty$
597     { number empty$
598         { series field.or.null }
599         { 
600           series empty$
601             { number "there's a number but no series in " cite$ * warning$ }
602             { series
603           %output.state mid.sentence =
604             %{ " Sers." * }
605             %{ "Sers." * }
606           %if$
607           number tie.or.space.connect
608           }
609           if$
610         }
611       if$
612     }
613     { "Vol." volume tie.or.space.connect
614       series empty$
615         'skip$
616         { " of " * series selective.emphasize * add.period$ }
617       if$
618       number empty$
619         'skip$
620         { number * " vols." * }
621       if$
622       %"volume and number" number either.or.check
623     }
624   if$
625 }
626
627 % Changed edition to MLA abbreviation
628 FUNCTION {format.edition}
629 { edition empty$
630     { version empty$
631         { "" }
632         { "Vers.~" version *}
633       if$
634     }
635     { edition abbreviate
636       duplicate$ sortify "revised" =
637         { pop$ "Rev." }
638         'skip$
639       if$
640       duplicate$ sortify "abridged" =
641         { pop$ "Abr." }
642         'skip$
643       if$
644       do.space "ed." *
645       "edition and version" version either.or.check
646     }
647   if$
648 }
649
650 INTEGERS { multiresult }
651
652 FUNCTION {multi.page.check}
653 { 't :=
654   #0 'multiresult :=
655     { multiresult not
656       t empty$ not
657       and
658     }
659     { t #1 #1 substring$
660       duplicate$ "-" =
661       swap$ duplicate$ "," =
662       swap$ "+" =
663       or or
664         { #1 'multiresult := }
665         { t #2 global.max$ substring$ 't := }
666       if$
667     }
668   while$
669   multiresult
670 }
671
672 FUNCTION {format.pages}
673 { pages empty$
674     { "" }
675     {
676 % j is positive if pages contains a comma
677 % (not fully implemented)
678       #0 'j :=
679       pages n.dashify duplicate$ 't :=
680         { duplicate$ empty$ not }
681         {
682           duplicate$ #1 #1 substring$ duplicate$
683           "{" =
684             { j #1 + 'j := }
685             'skip$
686           if$
687           "}" =
688             { j #1 - 'j := }
689             'skip$
690           if$
691           duplicate$ #1 #2 substring$ ", " =
692             { j j #0 = + 'j := }
693             'skip$
694           if$
695           #2 global.max$ substring$
696         }
697       while$
698         { t empty$ not }
699         { t #1 #2 substring$ "--" = j not and
700             { t #3 global.max$ substring$ 't :=
701               duplicate$ num.chars 'i :=
702               "--" *
703               i t num.chars =
704                 {   { i #2 > }
705                     { duplicate$ #1 i #2 - substring$
706                       t #1 i #2 - substring$ =
707                         { t i #1 - global.max$ substring$ * "" 't :=  #2 'i := }
708                         { i #1 - 'i := }
709                       if$
710                     }
711                   while$
712                 }
713                 'skip$
714               if$
715             }
716             { t #1 #1 substring$ duplicate$ "," = swap$ "-" = or j and
717                 { "+" * "" 't := }
718                 { t #1 #1 substring$ *
719                   t #2 global.max$ substring$ 't :=
720                 }
721               if$
722             }
723           if$
724         }
725       while$
726     }
727   if$
728 }
729
730 FUNCTION {format.vol.num.year.pages}
731 { volume empty$
732     { number empty$
733         'skip$
734         { number n.dashify
735           "there's a number but no volume in " cite$ * warning$ }
736       if$
737       format.date
738     }
739     { volume
740       number empty$
741         'skip$
742         { "." * number n.dashify * }
743       if$
744       " (" * format.date * ")" *
745     }
746   if$
747   edition empty$
748     'skip$
749     { ", " * format.edition * }
750   if$
751   type field.or.null sortify duplicate$ "sec." = swap$ "section" = or
752     { chapter empty$
753           { "section type requires chapter in " cite$ warning$ }
754           { ", sec." chapter n.dashify tie.or.space.connect }
755         if$
756       }
757     'skip$
758   if$
759   type field.or.null sortify "review" = chapter empty$ not and
760     { ", sec." chapter n.dashify tie.or.space.connect }
761     'skip$
762   if$
763   pages empty$
764     'skip$
765     { ": " * format.pages * }
766   if$
767 }
768
769 % chapter might be useful if type is set to "pars."
770 FUNCTION {format.chapter.pages}
771 { chapter empty$
772   type field.or.null sortify duplicate$ "def." = swap$ "definition" = or
773   or
774     'format.pages
775     { type empty$
776         { "chapter ignored in " cite$ * warning$ }
777         { type "t" change.case$
778           chapter n.dashify tie.or.space.connect
779           pages empty$
780             'skip$
781             { ", " * }
782           if$
783         }
784       if$
785       format.pages *
786     }
787   if$
788 }
789
790 FUNCTION {empty.misc.check}
791 { author empty$ title empty$ howpublished empty$
792   month empty$ year empty$ note empty$
793   and and and and and
794   key empty$ not and
795     { "all relevant fields are empty in " cite$ * warning$ }
796     'skip$
797   if$
798 }
799
800 FUNCTION {format.thesis.type}
801 { type empty$
802     'skip$
803     { pop$
804       type "t" change.case$
805     }
806   if$
807 }
808
809 FUNCTION {format.tr.number}
810 { type empty$
811     { "Technical Report" }
812     'type
813   if$
814   number empty$
815     { "t" change.case$ }
816     { number tie.or.space.connect }
817   if$
818 }
819
820 FUNCTION {format.urldate}
821 { database empty$
822     'skip$
823     { database selective.emphasize output.nonnull new.block }
824   if$
825   urldate missing$
826   { accessdate empty$
827       { cite$ " has no urldate field" * warning$
828         "\theurldate{}"
829       }
830       { "accessdate in " cite$ * " is depreciated; use urldate instead" *
831         warning$ accessdate
832       }
833     if$
834   }
835   { urldate }
836   if$
837 }
838 FUNCTION {output.url}
839 {
840   url empty$
841     { urlpath empty$ 
842         'skip$
843         { format.urldate output }
844       if$
845     }
846     { format.urldate
847       " $<$\url{" * url * "}$>$" *
848       output.nonnull
849     }
850   if$
851   urlpath empty$
852     'skip$
853     { "Path: " urlpath * output.nonnull }
854   if$
855 }
856
857 FUNCTION {format.crossref}
858 {
859   pages empty$ { "\citealp" } { "\citealp[" format.chapter.pages * "]" * } if$
860   "{" * crossref * "}" *
861 }
862
863
864 FUNCTION {cite.title}
865 { title empty$ journal empty$ not and
866     { key empty$ { journal }{ key } if$ selective.emphasize }
867     { title empty$ key empty$ and
868         { "empty title and key in " cite$ * warning$ "" }
869         { key empty$ {title}{key} if$
870           type$ "book" =
871           type$ "booklet" =
872           type$ "inbook" =
873           type$ "manual" =
874           type$ "phdthesis" =
875           type$ "proceedings" =
876           or or or or or
877             { selective.emphasize }
878             { type$ "article" =
879               %type$ "booklet" =
880               type$ "incollection" =
881               type$ "inproceedings" =
882               type$ "mastersthesis" =
883               type$ "misc" =
884               type$ "techreport" =
885               type$ "unpublished" =
886               or or or or or or
887                 { selective.enquote }
888                 {}
889               if$
890             }
891           if$
892         }
893       if$
894     }
895   if$
896 }
897
898 FUNCTION {cite.label}
899 {
900   %author empty$
901   %  { editor empty$ { organization field.or.null 'a := }{ editor 'a :=} if$}
902   %  { author 'a := }
903   %if$
904   %abbr empty$ {
905   author empty$
906     { editor empty$
907         { "" }
908         { editor }
909       if$
910     }
911     { author }
912   if$
913   duplicate$ empty$
914     { cite.title *
915     "(" * empty.title * ")" * }
916     { duplicate$
917       author.shared author.different =
918         { "{vv~}{ll}" format.names.custom 's := }
919         { author.shared author.last =
920             { "{f.~}{vv~}{ll}{, jj}" format.names.custom 's := }
921             { author.shared author.flast =
922                 { "{ff~}{vv~}{ll}{, jj}" format.names.custom 's := }
923                 { "{vv~}{ll}" format.names.custom ", " *
924                   cite.title * 's := "WTF" warning$ }
925               if$
926             }
927           if$
928         }
929       if$
930       s
931       "(" * empty.title *
932       author.duplicate { cite.title * }{} if$
933       "){" * swap$ "{ff~}{vv~}{ll}{, jj}" format.names.custom * "}" *
934     }
935   if$
936       %}
937       %if$
938     %}
939     %{}% abbr }
940  % if$
941 }
942
943 % TODO
944 FUNCTION {output.bibitem}
945 { newline$
946   "\bibitem[" write$
947   cite.label write$
948   "]{" write$
949   cite$ write$
950   "}" write$
951   newline$
952   ""
953   before.all 'output.state :=
954 }
955
956 FUNCTION {article}
957 { output.bibitem
958   format.authors "author" output.check
959   new.block
960   format.title "title" output.check
961   new.block
962   crossref missing$
963     { type empty$
964         'skip$
965         { type sortify "review" =
966             { "Rev.\ of " booktitle selective.emphasize * 
967             "booktitle" output.check new.block
968             }
969             { "Ignoring invalid type in " cite$ warning$ }
970           if$
971         }
972       if$
973       journal selective.emphasize "journal" output.check
974       continue.sentence
975       address empty$
976         'skip$
977         { "[" address * "]" * output
978           continue.sentence
979         }
980       if$
981       series empty$
982         'skip$
983         { series sortify
984           duplicate$ "new" =
985             { "ns" }
986             { duplicate$ "old" =
987                 { "os" }
988                 { series abbreviate do.space "ser." * "l" change.case$ }
989               if$
990             }
991           if$
992           output.nonnull
993           continue.sentence
994         }
995       if$
996       format.vol.num.year.pages output
997     }
998     { format.crossref output.nonnull
999       %format.pages output
1000     }
1001   if$
1002   new.block
1003   output.url
1004   new.block
1005   note output
1006   fin.entry
1007 }
1008
1009 FUNCTION {book}
1010 { output.bibitem
1011   author empty$
1012     { format.editors "author and editor" output.check }
1013     { format.authors output.nonnull }
1014   if$
1015   new.block
1016   format.btitle "title" output.check
1017   new.block
1018   crossref missing$
1019     { author empty$ 'skip$ { format.editors.mid output new.block } if$
1020       format.edition output
1021       new.sentence
1022       format.bvolume.or.num.series output
1023       new.block
1024       format.publisher "publisher" output.check
1025       format.date "year" output.check
1026     }
1027     {% format.date "year" output
1028       new.block
1029       format.crossref output.nonnull
1030     }
1031   if$
1032   new.block
1033   output.url
1034   new.block
1035   note output
1036   fin.entry
1037 }
1038
1039 FUNCTION {booklet}
1040 { output.bibitem
1041   format.authors output
1042   new.block
1043   format.btitle "title" output.check
1044   howpublished address new.block.checkb
1045   howpublished output
1046   address output
1047   format.date output
1048   new.block
1049   note output
1050   fin.entry
1051 }
1052
1053 FUNCTION {inbook}
1054 { output.bibitem
1055   author empty$
1056     { format.editors "author and editor" output.check }
1057     { format.authors output.nonnull }
1058   if$
1059   new.block
1060   format.btitle "title" output.check
1061   new.block
1062   crossref missing$
1063     { author empty$ 'skip$ { format.editors.mid output new.block } if$
1064       format.edition output
1065       new.sentence
1066       format.bvolume.or.num.series output
1067       new.block
1068       format.publisher "publisher" output.check
1069       format.date "year" output.check
1070       new.sentence
1071       format.chapter.pages "chapter and pages" output.check
1072       %address output
1073     }
1074     {
1075       new.block
1076       format.crossref output.nonnull
1077     }
1078   if$
1079   new.block
1080   output.url
1081   note output
1082   fin.entry
1083 }
1084
1085 FUNCTION {incollection}
1086 { output.bibitem
1087   format.authors "author" output.check
1088   chapter empty$
1089     { new.block type output }
1090     'skip$
1091   if$
1092   new.block
1093   format.title "title" output.check
1094   type field.or.null sortify duplicate$ "definition" = swap$ "def." = or
1095     { new.block "Def.~" chapter field.or.null * "chapter" output.check } 
1096     'skip$
1097   if$
1098   new.block
1099   crossref missing$
1100     { 
1101       booktitle selective.emphasize "booktitle" output.check
1102       new.block
1103       format.editors.mid "editor" output.check
1104       new.block
1105       format.edition output
1106       new.sentence
1107       format.bvolume.or.num.series output
1108       new.block
1109       format.publisher "publisher" output.check
1110       %address output
1111       format.date "year" output.check
1112       new.block
1113       format.chapter.pages output
1114     }
1115     { format.crossref output.nonnull
1116       %format.chapter.pages output
1117     }
1118   if$
1119   new.block
1120   output.url
1121   new.block
1122   note output
1123   fin.entry
1124 }
1125
1126 FUNCTION {inproceedings}
1127 { output.bibitem
1128   format.authors "author" output.check
1129   new.block
1130   format.title "title" output.check
1131   new.block
1132   crossref missing$
1133     {
1134       booktitle "booktitle" output.check
1135       new.sentence
1136       format.editors.mid output
1137       new.block
1138       format.edition output
1139       new.sentence
1140       format.bvolume.or.num.series output
1141       new.block
1142       format.edition output
1143       new.sentence
1144       format.publisher output
1145       format.date "year" output.check
1146       %address empty$
1147         %{ organization publisher new.sentence.checkb
1148          % organization output
1149          % publisher output
1150          % format.date "year" output.check
1151         %}
1152         %{ address output.nonnull
1153          % format.date "year" output.check
1154          % new.sentence
1155          % organization output
1156          % publisher output
1157         %}
1158       %if$
1159       new.sentence
1160       format.pages output
1161     }
1162     { format.crossref output.nonnull
1163     }
1164   if$
1165   new.block
1166   output.url
1167   new.block
1168   note output
1169   fin.entry
1170 }
1171
1172 FUNCTION {conference} { inproceedings }
1173
1174 FUNCTION {manual}
1175 { output.bibitem
1176   author empty$
1177     { organization empty$
1178         'skip$
1179         { organization output.nonnull
1180           address output
1181         }
1182       if$
1183     }
1184     { format.authors output.nonnull }
1185   if$
1186   new.block
1187   format.btitle "title" output.check
1188   new.block
1189   format.edition output
1190   new.sentence
1191   author empty$
1192     { organization empty$
1193         { address new.block.checka
1194           address output
1195         }
1196         'skip$
1197       if$
1198     }
1199     { organization address new.block.checkb
1200       organization output
1201       address output
1202     }
1203   if$
1204   format.date output
1205   new.block
1206   output.url
1207   new.block
1208   note output
1209   fin.entry
1210 }
1211
1212 FUNCTION {mastersthesis}
1213 { output.bibitem
1214   format.authors "author" output.check
1215   new.block
1216   format.title "title" output.check
1217   new.block
1218   "Diss." format.thesis.type output.nonnull
1219   new.block
1220   school "school" output.check
1221   address output
1222   format.date "year" output.check
1223   new.block
1224   output.url
1225   new.block
1226   note output
1227   fin.entry
1228 }
1229
1230 FUNCTION {misc}
1231 { output.bibitem
1232   format.authors output
1233   title howpublished new.block.checkb
1234   format.title output
1235   new.block
1236   %howpublished new.block.checka
1237   howpublished output
1238   format.date output
1239   new.block
1240   output.url
1241   new.block
1242   note output
1243   fin.entry
1244   empty.misc.check
1245 }
1246
1247 FUNCTION {phdthesis}
1248 { output.bibitem
1249   format.authors "author" output.check
1250   new.block
1251   format.btitle "title" output.check
1252   new.block
1253   "Diss." format.thesis.type output.nonnull
1254   new.block
1255   school "school" output.check
1256   address output
1257   format.date "year" output.check
1258   new.block
1259   output.url
1260   new.block
1261   note output
1262   fin.entry
1263 }
1264
1265 FUNCTION {proceedings}
1266 { output.bibitem
1267   editor empty$
1268     { organization output }
1269     { format.editors output.nonnull }
1270   if$
1271   new.block
1272   format.btitle "title" output.check
1273   new.block
1274   format.bvolume.or.num.series output
1275   address empty$
1276     { editor empty$
1277         { publisher new.sentence.checka }
1278         { organization publisher new.sentence.checkb
1279           organization output
1280         }
1281       if$
1282       publisher output
1283       format.date "year" output.check
1284     }
1285     { address output.nonnull
1286       format.date "year" output.check
1287       new.sentence
1288       editor empty$
1289         'skip$
1290         { organization output }
1291       if$
1292       publisher output
1293     }
1294   if$
1295   new.block
1296   output.url
1297   new.block
1298   note output
1299   fin.entry
1300 }
1301
1302 FUNCTION {techreport}
1303 { output.bibitem
1304   format.authors "author" output.check
1305   new.block
1306   format.title "title" output.check
1307   new.block
1308   format.tr.number output.nonnull
1309   new.block
1310   institution "institution" output.check
1311   address output
1312   format.date "year" output.check
1313   new.block
1314   note output
1315   fin.entry
1316 }
1317
1318 FUNCTION {unpublished}
1319 { output.bibitem
1320   format.authors "author" output.check
1321   new.block
1322   format.title "title" output.check
1323   new.block
1324   output.url
1325   new.block
1326   note "note" output.check
1327   format.date output
1328   fin.entry
1329 }
1330
1331 FUNCTION {default.type} { misc }
1332
1333 MACRO {jan} {"Jan."}
1334
1335 MACRO {feb} {"Feb."}
1336
1337 MACRO {mar} {"Mar."}
1338
1339 MACRO {apr} {"Apr."}
1340
1341 MACRO {may} {"May"}
1342
1343 MACRO {jun} {"June"}
1344
1345 MACRO {jul} {"July"}
1346
1347 MACRO {aug} {"Aug."}
1348
1349 MACRO {sep} {"Sept."}
1350
1351 MACRO {oct} {"Oct."}
1352
1353 MACRO {nov} {"Nov."}
1354
1355 MACRO {dec} {"Dec."}
1356
1357 % Currently left in to help with compatibility
1358
1359 MACRO {acmcs} {"ACM Computing Surveys"}
1360
1361 MACRO {acta} {"Acta Informatica"}
1362
1363 MACRO {cacm} {"Communications of the ACM"}
1364
1365 MACRO {ibmjrd} {"IBM Journal of Research and Development"}
1366
1367 MACRO {ibmsj} {"IBM Systems Journal"}
1368
1369 MACRO {ieeese} {"IEEE Transactions on Software Engineering"}
1370
1371 MACRO {ieeetc} {"IEEE Transactions on Computers"}
1372
1373 MACRO {ieeetcad}
1374  {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}
1375
1376 MACRO {ipl} {"Information Processing Letters"}
1377
1378 MACRO {jacm} {"Journal of the ACM"}
1379
1380 MACRO {jcss} {"Journal of Computer and System Sciences"}
1381
1382 MACRO {scp} {"Science of Computer Programming"}
1383
1384 MACRO {sicomp} {"SIAM Journal on Computing"}
1385
1386 MACRO {tocs} {"ACM Transactions on Computer Systems"}
1387
1388 MACRO {tods} {"ACM Transactions on Database Systems"}
1389
1390 MACRO {tog} {"ACM Transactions on Graphics"}
1391
1392 MACRO {toms} {"ACM Transactions on Mathematical Software"}
1393
1394 MACRO {toois} {"ACM Transactions on Office Information Systems"}
1395
1396 MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"}
1397
1398 MACRO {tcs} {"Theoretical Computer Science"}
1399
1400 READ
1401
1402 INTEGERS { len }
1403
1404 FUNCTION {chop.word}
1405 { 's :=
1406   'len :=
1407   s #1 len substring$ =
1408     { s len #1 + global.max$ substring$ }
1409     's
1410   if$
1411 }
1412
1413 FUNCTION {sort.format.names}
1414 { 's :=
1415   #1 'nameptr :=
1416   ""
1417   s num.names$ 'numnames :=
1418   numnames 'namesleft :=
1419     { namesleft #0 > }
1420     { nameptr #1 >
1421         { "   " * }
1422         'skip$
1423       if$
1424       s nameptr "{vv{ } }{ll{ }}{  ff{ }}{  jj{ }}" format.name$ 't :=
1425       nameptr numnames = t "others" = and
1426         { "et al" * }
1427         { t sortify * }
1428       if$
1429       nameptr #1 + 'nameptr :=
1430       namesleft #1 - 'namesleft :=
1431     }
1432   while$
1433 }
1434
1435 FUNCTION {sort.format.title}
1436 { 't :=
1437   "A " #2
1438     "An " #3
1439       "The " #4
1440         "Rev. of " #8
1441           "Rev.~of " #8
1442             "Rev.\ of " #9
1443             t chop.word
1444           chop.word
1445         chop.word
1446       chop.word
1447     chop.word
1448   chop.word
1449   sortify
1450   #1 global.max$ substring$
1451 }
1452
1453 FUNCTION {author.sort}
1454 { author empty$
1455     { key empty$
1456         { "to sort, need author or key in " cite$ * warning$
1457           ""
1458         }
1459         { key sortify }
1460       if$
1461     }
1462     { author sort.format.names }
1463   if$
1464 }
1465
1466 FUNCTION {author.editor.sort}
1467 { author empty$
1468     { editor empty$
1469         { key empty$
1470             { "to sort, need author, editor, or key in " cite$ * warning$
1471               ""
1472             }
1473             { key sortify }
1474           if$
1475         }
1476         { editor sort.format.names }
1477       if$
1478     }
1479     { author sort.format.names }
1480   if$
1481 }
1482
1483 FUNCTION {author.organization.sort}
1484 { author empty$
1485     { organization empty$
1486         { key empty$
1487             { "to sort, need author, organization, or key in " cite$ * warning$
1488               ""
1489             }
1490             { key sortify }
1491           if$
1492         }
1493         { "The " #4 organization chop.word sortify }
1494       if$
1495     }
1496     { author sort.format.names }
1497   if$
1498 }
1499
1500 FUNCTION {editor.organization.sort}
1501 { editor empty$
1502     { organization empty$
1503         { key empty$
1504             { "to sort, need editor, organization, or key in " cite$ * warning$
1505               ""
1506             }
1507             { key sortify }
1508           if$
1509         }
1510         { "The " #4 organization chop.word sortify }
1511       if$
1512     }
1513     { editor sort.format.names }
1514   if$
1515 }
1516
1517 FUNCTION {presort}
1518 { type$ "book" =
1519   type$ "inbook" =
1520   or
1521     'author.editor.sort
1522     { type$ "proceedings" =
1523         'editor.organization.sort
1524         { type$ "manual" =
1525             'author.organization.sort
1526             'author.sort
1527           if$
1528         }
1529       if$
1530     }
1531   if$
1532   duplicate$ empty$ 'skip$ { "    " * } if$
1533   key empty$
1534     { title field.or.null sort.format.title * "    " * booktitle field.or.null sort.format.title * }
1535     { key sortify * }
1536   if$
1537   "    "
1538   *
1539   year field.or.null sortify
1540   *
1541   #1 entry.max$ substring$
1542   'sort.key$ :=
1543 }
1544
1545 ITERATE {presort}
1546
1547 SORT
1548
1549 STRINGS {a b}
1550
1551 FUNCTION {init.vars}
1552 { #0 int.to.chr$ 'a :=
1553   #0 int.to.chr$ 'b :=
1554   #0 'i :=
1555   #0 'j :=
1556 }
1557
1558 % Function name is not strictly accurate
1559 FUNCTION {forward.author.dup.check}
1560 {
1561   url empty$ urlpath empty$ urldate empty$ and and
1562     'skip$
1563     { url.used #1 + 'url.used := }
1564   if$
1565   crossref empty$ 'skip$ { citealp.used #1 + 'citealp.used := } if$
1566   author empty$
1567     { editor empty$ { organization field.or.null 'a := }{ editor 'a :=} if$}
1568     { author 'a := }
1569   if$
1570   %'a :=
1571   a empty$
1572     'skip$
1573     { b "{ff~}{vv~}{ll}{, jj}" format.names.custom purify$
1574       a "{ff~}{vv~}{ll}{, jj}" format.names.custom purify$ =
1575         { #1 'author.duplicate := }
1576         { #0 'author.duplicate := }
1577       if$
1578       a 'b :=
1579     }
1580   if$
1581 }
1582
1583 FUNCTION {forward.author.share.check}
1584 %
1585 % Pass through all entries, comparing current author to last one.
1586 %
1587 { author.duplicate author empty$ or
1588   { author.duplicate { i 'author.shared := }{} if$}
1589   { b "{f.~}{vv~}{ll}{, jj}" format.names.custom purify$
1590     author field.or.null "{f.~}{vv~}{ll}{, jj}" format.names.custom purify$ =
1591     { author.flast 'author.shared := }
1592     { b "{vv~}{ll}" format.names.custom purify$
1593       author field.or.null "{vv~}{ll}" format.names.custom purify$ =
1594       { author.last 'author.shared := }
1595       { author.different 'author.shared := }
1596       if$
1597     }
1598     if$
1599     author.shared 'i :=
1600     author field.or.null 'b :=
1601   }
1602   if$
1603 }
1604
1605 FUNCTION {reverse.author}
1606
1607   author.duplicate
1608   { author.shared i <
1609       { i 'author.shared := }
1610       {}
1611     if$
1612   }
1613   { author.shared i <
1614       { author.shared i 'author.shared := 'i := }
1615       { author.shared 'i := }
1616     if$
1617   }
1618   if$
1619   j #1 = author.duplicate not and { #2 'author.duplicate := } {} if$
1620   author.duplicate 'j :=
1621 }
1622
1623 EXECUTE {init.consts}
1624
1625 EXECUTE {init.vars}
1626 ITERATE {forward.author.dup.check}
1627
1628 EXECUTE {init.vars}
1629 ITERATE {forward.author.share.check}
1630
1631 EXECUTE {init.vars}
1632 REVERSE {reverse.author}
1633
1634 %INTEGERS { number.label longest.label.width }
1635
1636 %FUNCTION {initialize.longest.label}
1637 %{ "" 'longest.label :=
1638 %  #1 'number.label :=
1639 %  #0 'longest.label.width :=
1640 %}
1641
1642 %FUNCTION {longest.label.pass}
1643 %{ number.label int.to.str$ 'label :=
1644 %  number.label #1 + 'number.label :=
1645 %  label width$ longest.label.width >
1646 %    { label 'longest.label :=
1647 %      label width$ 'longest.label.width :=
1648 %    }
1649 %    'skip$
1650 %  if$
1651 %}
1652
1653 %EXECUTE {initialize.longest.label}
1654
1655 %ITERATE {longest.label.pass}
1656
1657 FUNCTION {begin.bib}
1658 {
1659   citealp.used
1660     { "\expandafter\ifx\csname citealp\endcsname\relax\let\citealp\cite\fi"
1661       write$ newline$
1662     }
1663     'skip$
1664   if$
1665   url.used
1666     { "\providecommand\url[1]{\texttt{#1}}"
1667       write$ newline$
1668       "\providecommand\theurldate{\today}"
1669       write$ newline$
1670     }
1671     'skip$
1672   if$
1673   preamble$ empty$
1674     'skip$
1675     { preamble$ write$ newline$ }
1676   if$
1677   "\begin{thebibliography}{\rule{.5in}{0pt}}" write$ newline$
1678 }
1679
1680 EXECUTE {begin.bib}
1681
1682 ITERATE {call.type$}
1683
1684 FUNCTION {end.bib}
1685 { newline$
1686   "\end{thebibliography}" write$ newline$
1687 }
1688
1689 EXECUTE {end.bib}