% 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
%  NCI/FCRDC Bldg 469. Room 144
%  P.O. Box B
%  Frederick, MD  21702-1201
%  (301) 846-5581 (-5532 for messages)
%  (301) 846-5598 fax
%  email: toms@ncifcrf.gov

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}\