% control.bst % This is a control program for BiBTeX % It produces the bibliography file. % With modifications, it will produce any format of references! % % To try control.bst, just specify this as your bibliography style % in your LaTeX document. % % The program now includes bibitem calls like % \bibitem[Arnott1972]{Arnott1972} % so that the output can be read by LaTeX. % The method to remove the label on the entries is % from jmb.sty: % % % Use parens instead of brackets for \cite, and no label in the bibliography: % \def\@cite#1#2{(#1\if@tempswa , #2\fi)} % \def\@biblabel#1{} % % author: % Tom Schneider % (301) 846-5598 fax % email: toms@alum.mit.edu STRINGS { version } FUNCTION {version.identifier} % identify the version of the program { "version = 1.17 of control.bst 1996 September 9" duplicate$ write$ newline$ warning$ } ENTRY % declare variables that have a value for each entry on the list { address author booktitle chapter edition editor howpublished institution journal key month note number organization pages publisher school series title type volume year comment } { countingnumber % number assigned to the entry } {label extra.label sort.label } INTEGERS { dotitle } % toggle switch for doinng titles STRINGS { longest.label } INTEGERS { number.label longest.label.width field.there} STRINGS { s t theentryname} STRINGS { last.label next.extra } INTEGERS { last.extra.num } INTEGERS { numbercount } % count the number of each entry % field.there: % a field is presumed to be there initially % 0 means field is not there % 1 means field is there % *********************************************************** % convenient boolean functions FUNCTION {not} { { #0 } { #1 } if$ } FUNCTION {and} { 'skip$ { pop$ #0 } if$ } FUNCTION {or} { { pop$ #1 } 'skip$ if$ } % *********************************************************** FUNCTION {initialize.longest.label} % initialize the variables for the longest.label.pass function { "" 'longest.label := #1 'number.label := #0 'longest.label.width := } FUNCTION {longest.label.pass} % determine the longest label in the references { number.label int.to.str$ 'label := number.label #1 + 'number.label := label width$ longest.label.width > { label 'longest.label := label width$ 'longest.label.width := } 'skip$ if$ } % *********************************************************** % These routines do sorting of the entries and % add labels to the year to make entries unique FUNCTION {initialize.extra.label.stuff} { #0 int.to.chr$ 'last.label := "" 'next.extra := #0 'last.extra.num := % set numbering #0 'numbercount := } FUNCTION {sortify} { purify$ "l" change.case$ } FUNCTION {bib.sort.order} % Generate the sort.key$ variables for sorting. % The sorting is first on the sort.label (ie, author's name), followed % by the year then the title. If there is no year, the cite$ is used. { % " " * % tack on some space % original apa command was to use the year or an empty string: % year field.or.null sortify % % Replace that with the use of the cite$, when there is no year: % don't use year % "" write$ % year duplicate$ empty$ % {pop$ cite$} % debug: "pop cite" write$ % 'skip$ % if$ % % * " " * % tack on some space % * % attach them together % * % use cite$ instead!! sort.label % this is based on the author name cite$ * % attach them together % note: if there is no year, then the cite$ will override the sorting % on the title. Oh well. Title sorting is sorta (ha ha) awful. #1 entry.max$ substring$ 'sort.key$ := % The following line helps debug the program. It shows what the sort.key$ is. "% sort.key:" sort.key$ * write$ newline$ } FUNCTION {show.bib.sort.order} % show the bib, assign them numbers { numbercount #1 + 'numbercount := numbercount 'countingnumber := "% " countingnumber int.to.str$ " " * * write$ "% sort.key, sorted:" sort.key$ * write$ newline$ % debug:zzzqqq } FUNCTION {forward.pass} % pass through the references forward { %"\\ label=" label "//" * * write$ newline$ % display the label %"\\last.label=" last.label "//" * * write$ newline$ % display the label last.label label = % if the label repeats the previous label... { % then increment the extra number label "" = % make sure the label isn't empty though! {} { last.extra.num #1 + 'last.extra.num := % and convert it to a label last.extra.num int.to.chr$ 'extra.label := %"forward.pass" warning$ %last.label warning$ %label warning$ } if$ } { % else set things up for the next entry "a" chr.to.int$ 'last.extra.num := % However, if the year was missing, tack on an extra "a". year empty$ {"a" 'extra.label :=} {"" 'extra.label :=} if$ % "" 'extra.label := % the original method was not to do anything label 'last.label := % capture this label for next time } if$ %"\\extra.label = " extra.label "//" * * write$ newline$ % display the label } FUNCTION {reverse.pass} % pass through the references backwards % add extra characters to the end of the label string { %"{{" label "}}" * * write$ newline$ % display the label next.extra "b" = % original logic: { "a" 'extra.label := } 'skip$ if$ % next.extra "b" = { "next.extra was = b" write$ newline$} 'skip$ if$ % new as of 1989 Oct 18 % { "a" 'extra.label := } % { % Put on an "a" at the end of the label if the year is missing. % year empty$ % { "a" 'extra.label := } % %{ label "a" * 'label := } % 'skip$ % otherwise leave it alone (orignial method) % if$ } % if$ % label extra.label * 'label := % ORIGINAL LABEL METHOD % stick {\em } around extra.label if it's not empty extra.label "" = 'skip$ { label "{\em{" extra.label "}}" * * * 'label :=} if$ extra.label 'next.extra := %"{{" label "}}" * * write$ newline$ % display the label } % *********************************************************** FUNCTION {begin.bib} { % begin the output file newline$ preamble$ empty$ 'skip$ { preamble$ write$ newline$ } if$ "\begin{thebibliography}{" longest.label * "}" * write$ newline$ newline$ } FUNCTION {end.bib} { % end the output file "\end{thebibliography}" write$ newline$ } % *********************************************************** FUNCTION{comma} { ", " write$ } FUNCTION{comma.newline} { % if there was a previous field, field.there will be > 1 % and so we write the comma and newline. field.there {comma newline$} {#1 'field.there :=} % reset if$ } FUNCTION{period} { ". " write$ } FUNCTION{leftparenthesis} { "(" write$ } FUNCTION{rightparenthesis} { ") " write$ } % *********************************************************** % *********************************************************** % This function produces bibliography labels like % (Schneider et al., 1996) INTEGERS { nameptr namesleft numnames } FUNCTION {do.year} % product a year with an extra label on the end if needed. { year empty$ { "empty year in " cite$ ", using label: " extra.label * * * warning$ write$ % " (" extra.label * ")" * % UNemphasized label " ({\em{" extra.label * "}})" * % emphasized label { label "{\em{" extra.label "}}" * * * 'label :=} } { extra.label "" = { % skip the label if it isn't there " (" year ")" * * % emphasized label } { " (" year * "{\em{" extra.label "}}" ")" * * * * % emphasized label } if$ } if$ } % *********************************************************** % *********************************************************** % *********************************************************** FUNCTION {format.lab.names} % format the author names % There are three apalike cases: one person (Jones), % two (Jones and de~Bruijn), and more (Jones et~al.). % This function was taken from jmb (ie from apalike). { 's := s #1 "{vv~}{ll}" format.name$ s num.names$ duplicate$ #2 > { pop$ " {\em et~al.}" * } { #2 < 'skip$ { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = { " {\em et~al.}" * } { " \& " * s #2 "{vv~}{ll}" format.name$ * } % note new use of & rather than `and'. if$ } if$ } if$ } % *********************************************************** % *********************************************************** % The following functions produce bibliography style FUNCTION{startentry} { % start the entry 'theentryname := % pick up the entry name % write the bibitem out in JMB format % write the part of the bibitem to go into the paper "% " countingnumber int.to.str$ * write$ newline$ "\bibitem[" write$ author format.lab.names write$ do.year write$ "]" write$ newline$ % write the part of the bibitem that identifies the citation "{" write$ cite$ write$ "}" write$ newline$ % write the start of the entry "@" theentryname "{" * * write$ #1 'field.there := } FUNCTION{endentry} { % end the entry "}" write$ newline$ newline$ } FUNCTION{makekey} { cite$ write$ } % *********************************************************** FUNCTION{makeauthor} { author missing$ { #0 'field.there := } { #1 'field.there := "author = " quote$ * write$ author write$ quote$ write$ } if$ } FUNCTION{maketitle} { title missing$ { #0 'field.there := } { #1 'field.there := "title = " quote$ * write$ title write$ quote$ write$ } if$ } FUNCTION{makejournal} { journal missing$ { #0 'field.there := } { #1 'field.there := "journal = " quote$ * write$ journal write$ quote$ write$ } if$ } FUNCTION{makevolume} { volume missing$ { #0 'field.there := } { #1 'field.there := "volume = " quote$ * write$ volume write$ quote$ write$ } if$ } FUNCTION{makepages} { pages missing$ { #0 'field.there := } { #1 'field.there := "pages = " quote$ * write$ pages write$ quote$ write$ } if$ } FUNCTION{makeyear} { year missing$ { #0 'field.there := } { #1 'field.there := "year = " quote$ * write$ year write$ quote$ write$ } if$ } FUNCTION{makepublisher} { publisher missing$ { #0 'field.there := } { #1 'field.there := "publisher = " quote$ * write$ publisher write$ quote$ write$ } if$ } FUNCTION{makeaddress} { address missing$ { #0 'field.there := } { #1 'field.there := "address = " quote$ * write$ address write$ quote$ write$ } if$ } FUNCTION{makeeditor} { editor missing$ { #0 'field.there := } { #1 'field.there := "editor = " quote$ * write$ editor write$ quote$ write$ } if$ } FUNCTION{makecomment} { comment missing$ { #0 'field.there := } { #1 'field.there := "comment = " quote$ * write$ comment write$ quote$ write$ } if$ } FUNCTION{makenote} { note missing$ { #0 'field.there := } { #1 'field.there := "note = " quote$ * write$ note write$ quote$ write$ } if$ } FUNCTION{makebooktitle} { booktitle missing$ { #0 'field.there := } { #1 'field.there := "booktitle = " quote$ * write$ booktitle write$ quote$ write$ } if$ } FUNCTION{makeschool} { school missing$ { #0 'field.there := } { #1 'field.there := "school = " quote$ * write$ school write$ quote$ write$ } if$ } % *********************************************************** % style defined functions FUNCTION{article} { "article" startentry makekey comma.newline makeauthor comma.newline maketitle comma.newline makejournal comma.newline makevolume comma.newline makepages comma.newline makenote comma.newline makecomment comma.newline makeyear endentry } FUNCTION{book} { "book" startentry makekey comma.newline makeauthor comma.newline maketitle comma.newline makepublisher comma.newline makeaddress comma.newline makenote comma.newline makecomment comma.newline makeyear endentry } FUNCTION{inproceedings} { "inproceedings" startentry makekey comma.newline makeauthor comma.newline maketitle comma.newline makepages comma.newline makeeditor comma.newline makebooktitle comma.newline makepublisher comma.newline makeaddress comma.newline makenote comma.newline makecomment comma.newline makeyear endentry } FUNCTION{phdthesis} { "phdthesis" startentry makekey comma.newline makeauthor comma.newline maketitle comma.newline makeschool comma.newline makenote comma.newline makecomment comma.newline makeyear endentry } FUNCTION{misc} { "misc" startentry makekey comma.newline makeauthor comma.newline maketitle comma.newline makepages comma.newline makeeditor comma.newline makebooktitle comma.newline makepublisher comma.newline makeaddress comma.newline makenote comma.newline makecomment comma.newline makeyear endentry } FUNCTION{unpublished} { "unpublished" startentry makekey comma.newline makeauthor comma.newline maketitle comma.newline makepages comma.newline makeeditor comma.newline makebooktitle comma.newline makepublisher comma.newline makeaddress comma.newline makenote comma.newline makecomment comma.newline makeyear endentry } % *********************************************************** % *********************************************************** FUNCTION {Do.An.Entry} % This routine replaces the standard % ITERATE { call.type$ } % so that one can figure out where a problem comes from! { "Now processing: " type$ " " cite$ * * * warning$ call.type$ } READ EXECUTE {version.identifier} %EXECUTE {initialize.longest.label} %ITERATE {longest.label.pass} EXECUTE {initialize.extra.label.stuff} % initialize variables ITERATE {bib.sort.order} % set up the sorting keys SORT % by sort.label, year, title---giving final bibliography order ITERATE {show.bib.sort.order} % Having sorted NOW we apply the extra letters at the end! ITERATE {forward.pass} REVERSE {reverse.pass} EXECUTE {begin.bib} %ITERATE { call.type$ } ITERATE { Do.An.Entry } EXECUTE {end.bib}