% listbib.doc
%
%  2000.5.17: Changed by T.M. Wu
%             Add cbook, carticle, and so on.
%
%
%
% This file was generated by Volker Kuhlmann on 10 Mar 2000
% from the file btxbst.doc version 0.99b by Oren Patashnik
%    [ 3/23/88   (OP)    Version 0.99b for BibTeX 0.99c ]
% with the command "/lib/cpp -P -DUNSRT btxbst.doc listbib.doc".
%
% Then comments at the beginning of the file were edited,
% and the essence of biblist version 1.3 by Joachim Schrod were worked in.
% Oh yes, and some improvements were added too.
%
% To obtain listbib.bst, a fast-load no-comment version for bibtex, run
% listbib.doc through the command
%   sed -e '/^%/d' -e '/^[  ]*$/d'
% or simply install listbib.doc as listbib.bst (recommended).
% On contemporary computers the speed increase is very negligible and the loss
% of documentation weighs much more.
%
% Volker Kuhlmann
%   10, 14, 15, 16 Mar 2000
%

% unsrt style (unsorted numbers)

%
% The ENTRY declaration
%   Like Scribe's (according to pages 231-2 of the April '84 edition),
%   but no fullauthor or editors fields because BibTeX does name handling.
%   The annote field is commented out here because this family doesn't
%   include an annotated bibliography style.  And in addition to the fields
%   listed here, BibTeX has a built-in crossref field, explained later.

ENTRY
% Fields:
  { address
%       Usually the address of a publisher or other type of organization.
%       Put information in this field only if it helps the reader find the
%       thing---for example you should omit the address of a major
%       publisher entirely.  For a PROCEEDINGS or an INPROCEEDINGS,
%       however, it's the address of the conference; for those two entry
%       types, include the publisher's or organization's address, if
%       necessary, in the publisher or organization field.
%    annote
%       Long annotation---for annotated bibliographies (begins sentence).
    annote
%           Used by listbib. Not used by the 4 standard styles, and probably
%           not used by too many other styles either.
%           Useful for storing comments about bibliographic items which are
%           not meant to end up in documents.
    author
%       Name(s) of author(s), in BibTeX name format.
    booktitle
%       Book title when the thing being referenced isn't the whole book.
%       For book entries, the title field should be used instead.
    chapter
%       Chapter (or section or whatever) number.
    edition
%       Edition of a book---should be an ordinal (e.g., "Second").
    editor
%       Name(s) of editor(s), in BibTeX name format.
%       If there is also an author field, then the editor field should be
%       for the book or collection that the work appears in.
    howpublished
%        How something strange has been published (begins sentence).
    institution
%       Sponsoring institution of a technical report.
    isbn
    issn
%           The obvious purpose...
    journal
%       Journal name (macros are provided for many).
    key
%       Alphabetizing, labeling, and cross-referencing key
%       (needed when an entry has no author or editor).
    library
%           Location of the bibliographic item. This is useful for noting where
%           in a library a book is. This is not meant to be printed in
%           documents of course.
    month
%       Month (macros are provided).
    note
%       To help the reader find a reference (begins sentence).
    number
%       Number of a journal or technical report, or of a work in a series.
    organization
%       Organization sponsoring a conference (or publishing a manual); if
%       the editor (or author) is empty, and if the organization produces
%       an awkward label or cross reference, you should put appropriately
%       condensed organization information in the key field as well.
    pages
%       Page number or numbers (use `--' to separate a range, use `+'
%       to indicate pages following that don't form a simple range).
    publisher
%       Publisher name.
    school
%       School name (for theses).
    series
%       The name of a series or set of books.
%       An individual book will will also have it's own title.
    title
%       The title of the thing you're referred to.
    type
%       Type of a Techreport (e.g., "Research Note") to be used instead of
%       the default "Technical Report"; or, similarly, the type of a
%       thesis; or of a part of a book.
    volume
%       The volume number of a journal or multivolume work.
    year
%       The year should contain only numerals (technically, it should end
%       with four numerals, after purification; doesn't a begin sentence).
  }
%
% Integer entry variables
  {
    num.entry
%       The cardinal number of the entry in the data base.
%       Checking for inheritance requires a resort; this number can be used
%       to restore the original sort order.
    inherited.note
    inherited.annote
    inherited.isbn
    inherited.issn
    inherited.library
%       Flags which, when set, indicate that the respective field is
%       inherited from another crossref'ed entry.
  }
%
% String entry variables
  {
    label
    sort.label
  }


% These three functions pop one or two (integer) arguments from the stack
% and push a single one, either 0 or 1.
% The 'skip$ in the `and' and `or' functions are used because
% the corresponding if$ would be idempotent

FUNCTION {not}
{   { #0 }
    { #1 }
  if$
}

FUNCTION {and}
{   'skip$
    { pop$ #0 }
  if$
}

FUNCTION {or}
{   { pop$ #1 }
    'skip$
  if$
}

% Each entry function starts by calling output.bibitem, to write the
% \bibitem and its arguments to the .BBL file.  Then the various fields
% are formatted and printed by output or output.check.  Those functions
% handle the writing of separators (commas, periods, \newblock's),
% taking care not to do so when they are passed a null string.
% Finally, fin.entry is called to add the final period and finish the
% entry.
%
% A bibliographic reference is formatted into a number of `blocks':
% in the open format, a block begins on a new line and subsequent
% lines of the block are indented.  A block may contain more than
% one sentence (well, not a grammatical sentence, but something to
% be ended with a sentence ending period).  The entry functions should
% call new.block whenever a block other than the first is about to be
% started.  They should call new.sentence whenever a new sentence is
% to be started.  The output functions will ensure that if two
% new.sentence's occur without any non-null string being output between
% them then there won't be two periods output.  Similarly for two
% successive new.block's.
%
% The output routines don't write their argument immediately.
% Instead, by convention, that argument is saved on the stack to be
% output next time (when we'll know what separator needs to come
% after it).  Meanwhile, the output routine has to pop the pending
% output off the stack, append any needed separator, and write it.
%
% To tell which separator is needed, we maintain an output.state.
% It will be one of these values:
%   before.all      just after the \bibitem
%   mid.sentence        in the middle of a sentence: comma needed
%                   if more sentence is output
%   after.sentence      just after a sentence: period needed
%   after.block     just after a block (and sentence):
%                   period and \newblock needed.
% Note: These styles don't use after.sentence
%
% VAR: output.state : INTEGER       -- state variable for output
%
% The output.nonnull function saves its argument (assumed to be nonnull)
% on the stack, and writes the old saved value followed by any needed
% separator.  The ordering of the tests is decreasing frequency of
% occurrence.
%
% output.nonnull(s) ==
%  BEGIN
%   s := argument on stack
%   if output.state = mid.sentence then
%       write$(pop() * ", ")
%         -- "pop" isn't a function: just use stack top
%   else
%       if output.state = after.block then
%       write$(add.period$(pop()))
%       newline$
%       write$("\newblock ")
%       else
%       if output.state = before.all then
%           write$(pop())
%       else        -- output.state should be after.sentence
%           write$(add.period$(pop()) * " ")
%       fi
%       fi
%       output.state := mid.sentence
%   fi
%   push s on stack
%  END
%
% The output function calls output.nonnull if its argument is non-empty;
% its argument may be a missing field (thus, not necessarily a string)
%
% output(s) ==
%  BEGIN
%   if not empty$(s) then output.nonnull(s)
%   fi
%  END
%
% The output.check function is the same as the output function except that, if
% necessary, output.check warns the user that the t field shouldn't be empty
% (this is because it probably won't be a good reference without the field;
% the entry functions try to make the formatting look reasonable even when
% such fields are empty).
%
% output.check(s,t) ==
%  BEGIN
%   if empty$(s) then
%       warning$("empty " * t * " in " * cite$)
%   else output.nonnull(s)
%   fi
%  END
%
% The output.bibitem function writes the \bibitem for the current entry
% (the label should already have been set up), and sets up the separator
% state for the output functions.  And, it leaves a string on the stack
% as per the output convention.
%
% output.bibitem ==
%  BEGIN
%   newline$
%   write$("\bibitem[") % for alphabetic labels,
%   write$(label)       % these three lines
%   write$("]{")        % are used
%   write$("\bibitem{")     % this line for numeric labels
%   write$(cite$)
%   write$("}")
%   push "" on stack
%   output.state := before.all
%  END
%
% The fin.entry function finishes off an entry by adding a period to the
% string remaining on the stack.  If the state is still before.all
% then nothing was produced for this entry, so the result will look bad,
% but the user deserves it. (We don't omit the whole entry because the
% entry was cited, and a bibitem is needed to define the citation label.)
%
% fin.entry ==
%  BEGIN
%   write$(add.period$(pop()))
%   newline$
%  END
%
% The new.block function prepares for a new block to be output, and
% new.sentence prepares for a new sentence.
%
% new.block ==
%  BEGIN
%   if output.state <> before.all then
%       output.state := after.block
%   fi
%  END
%
% new.sentence ==
%  BEGIN
%   if output.state <> after.block then
%       if output.state <> before.all then
%       output.state :=  after.sentence
%       fi
%   fi
%  END
%

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

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

% the variables s and t are temporary string holders

STRINGS { s t }

FUNCTION {output.nonnull}
{ 's :=
  output.state mid.sentence =
    { ", " * write$ }
    { output.state after.block =
    { add.period$ write$
      newline$
      "\newblock " write$
    }
    { output.state before.all =
        'write$
        { add.period$ " " * write$ }
      if$
    }
      if$
      mid.sentence 'output.state :=
    }
  if$
  s
}

FUNCTION {output}
{ duplicate$ empty$
    'pop$
    'output.nonnull
  if$
}

FUNCTION {output.check}
{ 't :=
  duplicate$ empty$
    { pop$ "empty " t * " in " * cite$ * warning$ }
    'output.nonnull
  if$
}

FUNCTION {output.bibitem}
{ newline$

  "\bibitem{" write$

  cite$ write$
  "}" write$
  newline$
  ""
  before.all 'output.state :=
}

% This function finishes all entries.

FUNCTION {fin.entry}
{ add.period$
  write$
  newline$
}

FUNCTION {new.block}
{ output.state before.all =
    'skip$
    { after.block 'output.state := }
  if$
}

FUNCTION {new.sentence}
{ output.state after.block =
    'skip$
    { output.state before.all =
    'skip$
    { after.sentence 'output.state := }
      if$
    }
  if$
}

% Sometimes we begin a new block only if the block will be big enough.  The
% new.block.checka function issues a new.block if its argument is nonempty;
% new.block.checkb does the same if either of its TWO arguments is nonempty.

FUNCTION {new.block.checka}
{ empty$
    'skip$
    'new.block
  if$
}

FUNCTION {new.block.checkb}
{ empty$
  swap$ empty$
  and
    'skip$
    'new.block
  if$
}

% The new.sentence.check functions are analogous.

FUNCTION {new.sentence.checka}
{ empty$
    'skip$
    'new.sentence
  if$
}

FUNCTION {new.sentence.checkb}
{ empty$
  swap$ empty$
  and
    'skip$
    'new.sentence
  if$
}

% Here are some functions for formatting chunks of an entry.
% By convention they either produce a string that can be followed by
% a comma or period (using add.period$, so it is OK to end in a period),
% or they produce the null string.
%
% A useful utility is the field.or.null function, which checks if the
% argument is the result of pushing a `missing' field (one for which no
% assignment was made when the current entry was read in from the database)
% or the result of pushing a string having no non-white-space characters.
% It returns the null string if so, otherwise it returns the field string.
% Its main (but not only) purpose is to guarantee that what's left on the
% stack is a string rather than a missing field.
%
% field.or.null(s) ==
%  BEGIN
%   if empty$(s) then return ""
%   else return s
%  END
%
% Another helper function is emphasize, which returns the argument emphazised,
% if that is non-empty, otherwise it returns the null string.  Italic
% corrections aren't used, so this function should be used when punctation
% will follow the result.
% LaTeX's \emph{} will take care of italic correction.
%
% emphasize(s) ==
%  BEGIN
%   if empty$(s) then return ""
%   %else return "{\em " * s * "}"
%   else return "\emph{" * s * "}"
%
% The format.names function formats the argument (which should be in
% BibTeX name format) into "First Von Last, Junior", separated by commas
% and with an "and" before the last (but ending with "et~al." if the last
% of multiple authors is "others").  This function's argument should always
% contain at least one name.
%
% VAR: nameptr, namesleft, numnames: INTEGER
% pseudoVAR: nameresult: STRING     (it's what's accumulated on the stack)
%
% format.names(s) ==
%  BEGIN
%   nameptr := 1
%   numnames := num.names$(s)
%   namesleft := numnames
%   while namesleft > 0
%     do
%               % for full names:
%       t := format.name$(s, nameptr, "{ff~}{vv~}{ll}{, jj}")
%               % for abbreviated first names:
%       t := format.name$(s, nameptr, "{f.~}{vv~}{ll}{, jj}")
%       if nameptr > 1 then
%       if namesleft > 1 then nameresult := nameresult * ", " * t
%       else if numnames > 2
%              then nameresult := nameresult * ","
%            fi
%            if t = "others"
%              then nameresult := nameresult * " et~al."
%              else nameresult := nameresult * " and " * t
%            fi
%       fi
%       else nameresult := t
%       fi
%       nameptr := nameptr + 1
%       namesleft := namesleft - 1
%     od
%   return nameresult
%  END
%
% The format.authors function returns the result of format.names(author)
% if the author is present, or else it returns the null string
%
% format.authors ==
%  BEGIN
%   if empty$(author) then return ""
%   else return format.names(author)
%   fi
%  END
%
% Format.editors is like format.authors, but it uses the editor field,
% and appends ", editor" or ", editors"
%
% format.editors ==
%  BEGIN
%   if empty$(editor) then return ""
%   else
%       if num.names$(editor) > 1 then
%       return format.names(editor) * ", editors"
%       else
%       return format.names(editor) * ", editor"
%       fi
%   fi
%  END
%
% Other formatting functions are similar, so no "comment version" will be
% given for them.
%
% The `pop$' in this function gets rid of the duplicate `empty' value and
% the `skip$' returns the duplicate field value

FUNCTION {field.or.null}
{ duplicate$ empty$
    { pop$ "" }
    'skip$
  if$
}

FUNCTION {emphasize}
{ duplicate$ empty$
    { pop$ "" }
    %%{ "{\em " swap$ * "}" * }
    { "\emph{" swap$ * "}" * }
  if$
}

INTEGERS { nameptr namesleft numnames }

FUNCTION {format.names}
{ 's :=
  #1 'nameptr :=
  s num.names$ 'numnames :=
  numnames 'namesleft :=
    { namesleft #0 > }

    { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't :=

      nameptr #1 >
    { namesleft #1 >
        { ", " * t * }
        { numnames #2 >
        { "," * }
        'skip$
          if$
          t "others" =
        { " et~al." * }
        { " and " * t * }
          if$
        }
      if$
    }
    't
      if$
      nameptr #1 + 'nameptr :=
      namesleft #1 - 'namesleft :=
    }
  while$
}

FUNCTION {format.authors}
{ author empty$
    { "" }
    { author format.names }
  if$
}

FUNCTION {format.editors}
{ editor empty$
    { "" }
    { editor format.names
      editor num.names$ #1 >
    { ", editors" * }
    { ", editor" * }
      if$
    }
  if$
}

% Format note.
% Need to introduce this because we check whether it's inherited.

FUNCTION {note.output}
{ inherited.note
    { }
    { note output }
  if$
}

% Deal with annote.

FUNCTION {output.annote}
{ new.block "\annote " output
  newline$ write$
  annote add.period$ write$ newline$
  "\endannote"
}

FUNCTION {annote.output}
{ annote empty$
  inherited.annote
  or
    'skip$
    { output.annote }
  if$
}

% Formatting + outputting ISBN and ISSN

FUNCTION {format.isbn}
{ isbn empty$
    { "" }
    { new.sentence "ISBN~" isbn * }
  if$
}

FUNCTION {format.issn}
{ issn empty$
    { "" }
    { new.sentence "ISSN~" issn * }
  if$
}

FUNCTION {isbn.output}
{ inherited.isbn
    { "" }
    { format.isbn }
  if$
  output
}

FUNCTION {issn.output}
{ inherited.issn
    { "" }
    { format.issn }
  if$
  output
}

FUNCTION {isbn.issn.output}
{ %% both isbn and issn, but not both inherited
  isbn empty$ not
  issn empty$ not
  and
  inherited.isbn
  inherited.issn
  and not and
    { "used both ISBN and ISSN fields in " cite$ * warning$ }
    'skip$
  if$
  isbn.output
  issn.output
}

% Formatting library
% We need to check and possibly alter the output state to avoid a period
% being output after the library part.
% In fact, we can't call output (because it can never work in this case),
% instead we write to the output buffer ourselves and set the output.state
% to something useful.

FUNCTION {format.library}
{ library empty$
    { "" }
    { "\library{" library * "}" * }
  if$
}

FUNCTION {library.output}
{ % "checking lib out stat" top$  %% debug
  inherited.library
    { "" }
    { format.library }
  if$
  duplicate$ empty$
    { output }
    { "%" * write$ newline$
      before.all 'output.state :=
    }
  if$
}

% The format.title function is used for non-book-like titles.
% For most styles we convert to lowercase (except for the very first letter,
% and except for the first one after a colon (followed by whitespace)),
% and hope the user has brace-surrounded words that need to stay capitilized;
% for some styles, however, we leave it as it is in the database.

FUNCTION {format.title}
{ title empty$
    { "" }

%    { title "t" change.case$ }
    'title

  if$
}

% By default, BibTeX sets the global integer variable global.max$ to the BibTeX
% constant glob_str_size, the maximum length of a global string variable.
% Analogously, BibTeX sets the global integer variable entry.max$ to
% ent_str_size, the maximum length of an entry string variable.
% The style designer may change these if necessary (but this is unlikely)

% The n.dashify function makes each single `-' in a string a double `--'
% if it's not already
%
% pseudoVAR: pageresult: STRING     (it's what's accumulated on the stack)
%
% n.dashify(s) ==
%  BEGIN
%   t := s
%   pageresult := ""
%   while (not empty$(t))
%     do
%       if (first character of t = "-")
%         then
%       if (next character isn't)
%         then
%           pageresult := pageresult * "--"
%           t := t with the "-" removed
%         else
%           while (first character of t = "-")
%             do
%           pageresult := pageresult * "-"
%           t := t with the "-" removed
%             od
%       fi
%         else
%       pageresult := pageresult * the first character
%       t := t with the first character removed
%       fi
%     od
%   return pageresult
%  END

FUNCTION {n.dashify}
{ 't :=
  ""
    { t empty$ not }
    { t #1 #1 substring$ "-" =
    { t #1 #2 substring$ "--" = not
        { "--" *
          t #2 global.max$ substring$ 't :=
        }
        {   { t #1 #1 substring$ "-" = }
        { "-" *
          t #2 global.max$ substring$ 't :=
        }
          while$
        }
      if$
    }
    { t #1 #1 substring$ *
      t #2 global.max$ substring$ 't :=
    }
      if$
    }
  while$
}

% The format.date function is for the month and year, but we give a warning if
% there's an empty year but the month is there, and we return the empty string
% if they're both empty.

FUNCTION {format.date}
{ year empty$
    { month empty$
    { "" }
    { "there's a month but no year in " cite$ * warning$
      month
    }
      if$
    }
    { month empty$
    'year
    { month " " * year * }
      if$
    }
  if$
}

% The format.btitle is for formatting the title field when it is a book-like
% entry---the style used here keeps it in uppers-and-lowers and emphasizes it.

FUNCTION {format.btitle}
{ title emphasize
}

% For several functions we'll need to connect two strings with a
% tie (~) if the second one isn't very long (fewer than 3 characters).
% The tie.or.space.connect function does that.  It concatenates the two
% strings on top of the stack, along with either a tie or space between
% them, and puts this concatenation back onto the stack:
%
% tie.or.space.connect(str1,str2) ==
%    BEGIN
%   if text.length$(str2) < 3
%     then return the concatenation of str1, "~", and str2
%     else return the concatenation of str1, " ", and str2
%    END

FUNCTION {tie.or.space.connect}
{ duplicate$ text.length$ #3 <
    { "~" }
    { " " }
  if$
  swap$ * *
}

% The either.or.check function complains if both fields of an either-or pair
% are nonempty.
%
% either.or.check(t,s) ==
%  BEGIN
%   if not empty$(s) then
%       warning$(can't use both " * t * " fields in " * cite$)
%   fi
%  END

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

% The format.bvolume function is for formatting the volume and perhaps
% series name of a multivolume work.  If both a volume and a series field
% are there, we assume the series field is the title of the whole multivolume
% work (the title field should be the title of the thing being referred to),
% and we add an "of <series>".  This function is called in mid-sentence.

FUNCTION {format.bvolume}
{ volume empty$
    { "" }
    { "volume" volume tie.or.space.connect
      series empty$
    'skip$
    { " of " * series emphasize * }
      if$
      "volume and number" number either.or.check
    }
  if$
}

% The format.number.series function is for formatting the series name
% and perhaps number of a work in a series.  This function is similar to
% format.bvolume, although for this one the series must exist (and the
% volume must not exist).  If the number field is empty we output either
% the series field unchanged if it exists or else the null string.
% If both the number and series fields are there we assume the series field
% gives the name of the whole series (the title field should be the title
% of the work being one referred to), and we add an "in <series>".
% We capitilize Number when this function is used at the beginning of a block.

FUNCTION {format.number.series}
{ volume empty$
    { number empty$
    { series field.or.null }
    { output.state mid.sentence =
        { "number" }
        { "Number" }
      if$
      number tie.or.space.connect
      series empty$
        { "there's a number but no series in " cite$ * warning$ }
        { " in " * series * }
      if$
    }
      if$
    }
    { "" }
  if$
}

% The format.edition function appends " edition" to the edition, if present.
% We lowercase the edition (it should be something like "Third"), because
% this doesn't start a sentence.

FUNCTION {format.edition}
{ edition empty$
    { "" }
    { output.state mid.sentence =
    { edition "l" change.case$ " edition" * }
    { edition "t" change.case$ " edition" * }
      if$
    }
  if$
}

% The format.pages function is used for formatting a page range in a book
% (and in rare circumstances, an article).
%
% The multi.page.check function examines the page field for a "-" or "," or "+"
% so that format.pages can use "page" instead of "pages" if none exists.
% Note: global.max$ here means "take the rest of the string"
%
% VAR: multiresult: INTEGER (actually, a boolean)
%
% multi.page.check(s) ==
%  BEGIN
%   t := s
%   multiresult := false
%   while ((not multiresult) and (not empty$(t)))
%     do
%       if (first character of t = "-" or "," or "+")
%         then multiresult := true
%         else t := t with the first character removed
%       fi
%     od
%   return multiresult
%  END

INTEGERS { multiresult }

FUNCTION {multi.page.check}
{ 't :=
  #0 'multiresult :=
    { multiresult not
      t empty$ not
      and
    }
    { t #1 #1 substring$
      duplicate$ "-" =
      swap$ duplicate$ "," =
      swap$ "+" =
      or or
    { #1 'multiresult := }
    { t #2 global.max$ substring$ 't := }
      if$
    }
  while$
  multiresult
}

% This function doesn't begin a sentence so "pages" isn't capitalized.
% Other functions that use this should keep that in mind.

FUNCTION {format.pages}
{ pages empty$
    { "" }
    { pages multi.page.check
    { "pages" pages n.dashify tie.or.space.connect }
    { "page" pages tie.or.space.connect }
      if$
    }
  if$
}

% The format.vol.num.pages function is for the volume, number, and page range
% of a journal article.  We use the format:  vol(number):pages, with some
% variations for empty fields.  This doesn't begin a sentence.

FUNCTION {format.vol.num.pages}
{ volume field.or.null
  number empty$
    'skip$
    { "(" number * ")" * *
      volume empty$
    { "there's a number but no volume in " cite$ * warning$ }
    'skip$
      if$
    }
  if$
  pages empty$
    'skip$
    { duplicate$ empty$
    { pop$ format.pages }
    { ":" * pages n.dashify * }
      if$
    }
  if$
}


% The format.chapter.pages, if the chapter is present, puts whatever is in the
% type field (or else "chapter" if type is empty) in front of a chapter number.
% It then appends the pages, if present.  This doesn't begin a sentence.

FUNCTION {format.chapter.pages}
{ chapter empty$
    'format.pages
    { type empty$
    { "chapter" }
    { type "l" change.case$ }
      if$
      chapter tie.or.space.connect
      pages empty$
    'skip$
    { ", " * format.pages * }
      if$
    }
  if$
}

% The format.in.ed.booktitle function is used for starting out a sentence
% that begins "In <booktitle>", putting an editor before the title if one
% exists.

FUNCTION {format.in.ed.booktitle}
{ booktitle empty$
    { "" }
    { editor empty$
    { "In " booktitle emphasize * }
    { "In " format.editors * ", " * booktitle emphasize * }
      if$
    }
  if$
}

% The function empty.misc.check complains if all six fields are empty, and
% if there's been no sorting or alphabetic-label complaint.

FUNCTION {empty.misc.check}
{ author empty$ title empty$ howpublished empty$
  month empty$ year empty$ note empty$
  and and and and and



    { "all relevant fields are empty in " cite$ * warning$ }
    'skip$
  if$
}

% The function format.thesis.type returns either the (case-changed) type field,
% if it is defined, or else the default string already on the stack
% (like "Master's thesis" or "PhD thesis").

FUNCTION {format.thesis.type}
{ type empty$
    'skip$
    { pop$
      type "t" change.case$
    }
  if$
}

% The function format.tr.number makes a string starting with "Technical Report"
% (or type, if that field is defined), followed by the number if there is one;
% it returns the starting part (with a case change) even if there is no number.
% This is used at the beginning of a sentence.

FUNCTION {format.tr.number}
{ type empty$
    { "Technical Report" }
    'type
  if$
  number empty$
    { "t" change.case$ }
    { number tie.or.space.connect }
  if$
}

% Now come the cross-referencing functions (these are invoked because
% one entry in the database file(s) cross-references another, by giving
% the other entry's database key in a `crossref' field).  This feature
% allows one or more titled things that are part of a larger titled
% thing to cross-reference the larger thing.  These styles allow for
% five posibilities: (1) an ARTICLE may cross-reference an ARTICLE;
% (2) a BOOK, (3) INBOOK, or (4) INCOLLECTION may cross-reference a BOOK;
% or (5) an INPROCEEDINGS may cross-reference a PROCEEDINGS.
% Each of these is explained in more detail later.
%
% An ARTICLE entry type may cross reference another ARTICLE (this is
% intended for when an entire journal is devoted to a single topic---
% but since there is no JOURNAL entry type, the journal, too, should be
% classified as an ARTICLE but without the author and title fields).
% This will result in two warning messages for the journal's entry
% if it's included in the reference list, but such is life.
%
% format.article.crossref ==
%  BEGIN
%   if empty$(key) then
%       if empty$(journal) then
%       warning$("need key or journal for " * cite$ *
%                       " to crossref " * crossref)
%       return(" \cite{" * crossref * "}")
%       else
%       return("In " * emphazise.correct (journal) *
%                       " \cite{" * crossref * "}")
%       fi
%   else
%       return("In " * key * " \cite{" * crossref * "}")
%   fi
%  END
%
% The other cross-referencing functions are similar, so no "comment version"
% will be given for them.

FUNCTION {format.article.crossref}
{ key empty$
    { journal empty$
    { "need key or journal for " cite$ * " to crossref " * crossref *
      warning$
      ""
    }
    %{ "In {\em " journal * "\/}" * }
    { "In " journal emphasize * }
      if$
    }
    { "In " key * }
  if$
  " \cite{" * crossref * "}" *
}

% We use just the last names of editors for a cross reference: either
% "editor", or "editor1 and editor2", or "editor1 et~al." depending on
% whether there are one, or two, or more than two editors.

FUNCTION {format.crossref.editor}
{ editor #1 "{vv~}{ll}" format.name$
  editor num.names$ duplicate$
  #2 >
    { pop$ " et~al." * }
    { #2 <
    'skip$
    { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
        { " et~al." * }
        { " and " * editor #2 "{vv~}{ll}" format.name$ * }
      if$
    }
      if$
    }
  if$
}

% A BOOK (or INBOOK) entry type (assumed to be for a single volume in a
% multivolume work) may cross reference another BOOK (the entire multivolume).
% Usually there will be an editor, in which case we use that to construct the
% cross reference; otherwise we use a nonempty key field or else the series
% field (since the series gives the title of the multivolume work).

FUNCTION {format.book.crossref}
{ volume empty$
    { % We have a problem here: this function is called from both book and
      % inbook when there is a crossref. While it makes sense to warn about an
      % empty volume for a book which crossreferences another book (e.g. when
      % it is volume N of a multivolume work), this does not hold for inbook.
      % An inbook is a part of a book; a volume doesn't make sense (even
      % less warning about one).
      % Solution: disable warning for inbook.   [VK Mar 2000]
      %"empty volume in " cite$ * "'s crossref of " * crossref * warning$
      type$ "inbook" =
        'skip$
    { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ }
      if$
      "In "
    }
    { "Volume" volume tie.or.space.connect
      " of " *
    }
  if$
  editor empty$
  editor field.or.null author field.or.null =
  or
    { key empty$
    { series empty$
        { "need editor, key, or series for " cite$ * " to crossref " *
          crossref * warning$
          "" *
        }
        %{ "{\em " * series * "\/}" * }
        { series emphasize * }
      if$
    }
    { key * }
      if$
    }
    { format.crossref.editor * }
  if$
  " \cite{" * crossref * "}" *
}

% An INCOLLECTION entry type may cross reference a BOOK (assumed to be the
% collection), or an INPROCEEDINGS may cross reference a PROCEEDINGS.
% Often there will be an editor, in which case we use that to construct
% the cross reference; otherwise we use a nonempty key field or else
% the booktitle field (which gives the cross-referenced work's title).

FUNCTION {format.incoll.inproc.crossref}
{ editor empty$
  editor field.or.null author field.or.null =
  or
    { key empty$
    { booktitle empty$
        { "need editor, key, or booktitle for " cite$ * " to crossref " *
          crossref * warning$
          ""
        }
        %{ "In {\em " booktitle * "\/}" * }
        { "In " booktitle emphasize * }
      if$
    }
    { "In " key * }
      if$
    }
    { "In " format.crossref.editor * }
  if$
  " \cite{" * crossref * "}" *
}

% Now we define the type functions for all entry types that may appear
% in the .BIB file---e.g., functions like `article' and `book'.  These
% are the routines that actually generate the .BBL-file output for
% the entry.  These must all precede the READ command.  In addition, the
% style designer should have a function `default.type' for unknown types.
% Note: The fields (within each list) are listed in order of appearance,
% except as described for an `inbook' or a `proceedings'.
%
% The article function is for an article in a journal.  An article may
% CROSSREF another article.
%   Required fields: author, title, journal, year
%   Optional fields: volume, number, pages, month, note
%   Also optional: library, issn, annote
%
% article ==
%  BEGIN
%   output.bibitem
%   output.check(format.authors,"author")
%   new.block
%   output.check(format.title,"title")
%   new.block
%   if missing$(crossref) then
%       output.check(emphasize(journal),"journal")
%       output(format.vol.num.pages)
%       output.check(format.date,"year")
%       else
%       output.nonnull(format.article.crossref)
%       output(format.pages)
%   fi
%   new.block
%   output(note)
%   fin.entry
%  END
%
% The book function is for a whole book.  A book may CROSSREF another book.
%   Required fields: author or editor, title, publisher, year
%   Optional fields: volume or number, series, address, edition, month,
%           note
%   Also optional: library, isbn, issn, annote
%
% book ==
%  BEGIN
%   if empty$(author) then output.check(format.editors,"author and editor")
%   else    output.check(format.authors,"author")
%       if missing$(crossref) then
%           either.or.check("author and editor",editor)
%       fi
%   fi
%   new.block
%   output.check(format.btitle,"title")
%   if missing$(crossref) then
%       output(format.bvolume)
%       new.block
%       output(format.number.series)
%       new.sentence
%       output.check(publisher,"publisher")
%       output(address)
%       else
%       new.block
%       output.nonnull(format.book.crossref)
%   fi
%   output(format.edition)
%   output.check(format.date,"year")
%   new.block
%   output(note)
%   fin.entry
%  END
%
% The other entry functions are all quite similar, so no "comment version"
% will be given for them.

FUNCTION {article}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  crossref missing$
    { journal emphasize "journal" output.check
      format.vol.num.pages output
      format.date "year" output.check
    }
    { format.article.crossref output.nonnull
      format.pages output
    }
  if$
  issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {carticle}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  crossref missing$
    { journal emphasize "journal" output.check
      format.vol.num.pages output
      format.date "year" output.check
    }
    { format.article.crossref output.nonnull
      format.pages output
    }
  if$
  issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {book}
{ output.bibitem
  library.output
  new.sentence
  author empty$
    { format.editors "author and editor" output.check }
    { format.authors output.nonnull
      crossref missing$
    { "author and editor" editor either.or.check }
    'skip$
      if$
    }
  if$
  new.block
  format.btitle "title" output.check
  crossref missing$
    { format.bvolume output
      new.block
      format.number.series output
      new.sentence
      publisher "publisher" output.check
      address output
    }
    { new.block
      format.book.crossref output.nonnull
    }
  if$
  format.edition output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cbook}
{ output.bibitem
  library.output
  new.sentence
  author empty$
    { format.editors "author and editor" output.check }
    { format.authors output.nonnull
      crossref missing$
    { "author and editor" editor either.or.check }
    'skip$
      if$
    }
  if$
  new.block
  format.btitle "title" output.check
  crossref missing$
    { format.bvolume output
      new.block
      format.number.series output
      new.sentence
      publisher "publisher" output.check
      address output
    }
    { new.block
      format.book.crossref output.nonnull
    }
  if$
  format.edition output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% A booklet is a bound thing without a publisher or sponsoring institution.
%   Required: title
%   Optional: author, howpublished, address, month, year, note
%   Also optional: library, isbn, issn, annote

FUNCTION {booklet}
{ output.bibitem
  library.output
  new.sentence
  format.authors output
  new.block
  format.title "title" output.check
  howpublished address new.block.checkb
  howpublished output
  address output
  format.date output
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cbooklet}
{ output.bibitem
  library.output
  new.sentence
  format.authors output
  new.block
  format.title "title" output.check
  howpublished address new.block.checkb
  howpublished output
  address output
  format.date output
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% For the conference entry type, see inproceedings.

% An inbook is a piece of a book: either a chapter and/or a page range.
% It may CROSSREF a book.  If there's no volume field, the type field
% will come before number and series.
%   Required: author or editor, title, chapter and/or pages, publisher,year
%   Optional: volume or number, series, type, address, edition, month, note
%   Also optional: library, isbn, issn, annote

FUNCTION {inbook}
{ output.bibitem
  library.output
  new.sentence
  author empty$
    { format.editors "author and editor" output.check }
    { format.authors output.nonnull
      crossref missing$
    { "author and editor" editor either.or.check }
    'skip$
      if$
    }
  if$
  new.block
  format.btitle "title" output.check
  crossref missing$
    { format.bvolume output
      format.chapter.pages "chapter and pages" output.check
      new.block
      format.number.series output
      new.sentence
      publisher "publisher" output.check
      address output
    }
    { format.chapter.pages "chapter and pages" output.check
      new.block
      format.book.crossref output.nonnull
    }
  if$
  format.edition output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cinbook}
{ output.bibitem
  library.output
  new.sentence
  author empty$
    { format.editors "author and editor" output.check }
    { format.authors output.nonnull
      crossref missing$
    { "author and editor" editor either.or.check }
    'skip$
      if$
    }
  if$
  new.block
  format.btitle "title" output.check
  crossref missing$
    { format.bvolume output
      format.chapter.pages "chapter and pages" output.check
      new.block
      format.number.series output
      new.sentence
      publisher "publisher" output.check
      address output
    }
    { format.chapter.pages "chapter and pages" output.check
      new.block
      format.book.crossref output.nonnull
    }
  if$
  format.edition output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% An incollection is like inbook, but where there is a separate title
% for the referenced thing (and perhaps an editor for the whole).
% An incollection may CROSSREF a book.
%   Required: author, title, booktitle, publisher, year
%   Optional: editor, volume or number, series, type, chapter, pages,
%           address, edition, month, note
%   Also optional: library, isbn, issn, annote

FUNCTION {incollection}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  crossref missing$
    { format.in.ed.booktitle "booktitle" output.check
      format.bvolume output
      format.number.series output
      format.chapter.pages output
      new.sentence
      publisher "publisher" output.check
      address output
      format.edition output
      format.date "year" output.check
    }
    { format.incoll.inproc.crossref output.nonnull
      format.chapter.pages output
    }
  if$
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cincollection}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  crossref missing$
    { format.in.ed.booktitle "booktitle" output.check
      format.bvolume output
      format.number.series output
      format.chapter.pages output
      new.sentence
      publisher "publisher" output.check
      address output
      format.edition output
      format.date "year" output.check
    }
    { format.incoll.inproc.crossref output.nonnull
      format.chapter.pages output
    }
  if$
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% An inproceedings is an article in a conference proceedings, and it may
% CROSSREF a proceedings.  If there's no address field, the month (& year)
% will appear just before note.
%   Required: author, title, booktitle, year
%   Optional: editor, volume or number, series, pages, address, month,
%           organization, publisher, note
%   Also optional: library, isbn, issn, annote

FUNCTION {inproceedings}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  crossref missing$
    { format.in.ed.booktitle "booktitle" output.check
      format.bvolume output
      format.number.series output
      format.pages output
      address empty$
    { organization publisher new.sentence.checkb
      organization output
      publisher output
      format.date "year" output.check
    }
    { address output.nonnull
      format.date "year" output.check
      new.sentence
      organization output
      publisher output
    }
      if$
    }
    { format.incoll.inproc.crossref output.nonnull
      format.pages output
    }
  if$
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cinproceedings}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  crossref missing$
    { format.in.ed.booktitle "booktitle" output.check
      format.bvolume output
      format.number.series output
      format.pages output
      address empty$
    { organization publisher new.sentence.checkb
      organization output
      publisher output
      format.date "year" output.check
    }
    { address output.nonnull
      format.date "year" output.check
      new.sentence
      organization output
      publisher output
    }
      if$
    }
    { format.incoll.inproc.crossref output.nonnull
      format.pages output
    }
  if$
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% The conference function is included for Scribe compatibility.

FUNCTION {conference} { inproceedings }

FUNCTION {cconference} { cinproceedings }

% A manual is technical documentation.
%   Required: title
%   Optional: author, organization, address, edition, month, year, note
%   Also optional: library, isbn, issn, annote

FUNCTION {manual}
{ output.bibitem
  library.output
  new.sentence
  author empty$
    { organization empty$
    'skip$
    { organization output.nonnull
      address output
    }
      if$
    }
    { format.authors output.nonnull }
  if$
  new.block
  format.btitle "title" output.check
  author empty$
    { organization empty$
    { address new.block.checka
      address output
    }
    'skip$
      if$
    }
    { organization address new.block.checkb
      organization output
      address output
    }
  if$
  format.edition output
  format.date output
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cmanual}
{ output.bibitem
  library.output
  new.sentence
  author empty$
    { organization empty$
    'skip$
    { organization output.nonnull
      address output
    }
      if$
    }
    { format.authors output.nonnull }
  if$
  new.block
  format.btitle "title" output.check
  author empty$
    { organization empty$
    { address new.block.checka
      address output
    }
    'skip$
      if$
    }
    { organization address new.block.checkb
      organization output
      address output
    }
  if$
  format.edition output
  format.date output
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% A mastersthesis is a Master's thesis.
%   Required: author, title, school, year
%   Optional: type, address, month, note
%   Also optional: library, isbn, issn, annote

FUNCTION {mastersthesis}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  "Master's thesis" format.thesis.type output.nonnull
  school "school" output.check
  address output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cmastersthesis}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  "Master's thesis" format.thesis.type output.nonnull
  school "school" output.check
  address output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% A misc is something that doesn't fit elsewhere.
%   Required: at least one of the `optional' fields
%   Optional: author, title, howpublished, month, year, note
%   Also optional: library, isbn, issn, annote

FUNCTION {misc}
{ output.bibitem
  library.output
  new.sentence
  format.authors output
  title howpublished new.block.checkb
  format.title output
  howpublished new.block.checka
  howpublished output
  format.date output
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
  empty.misc.check
}

FUNCTION {cmisc}
{ output.bibitem
  library.output
  new.sentence
  format.authors output
  title howpublished new.block.checkb
  format.title output
  howpublished new.block.checka
  howpublished output
  format.date output
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
  empty.misc.check
}

% A phdthesis is like a mastersthesis.
%   Required: author, title, school, year
%   Optional: type, address, month, note
%   Also optional: library, isbn, issn, annote

FUNCTION {phdthesis}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.btitle "title" output.check
  new.block
  "PhD thesis" format.thesis.type output.nonnull
  school "school" output.check
  address output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cphdthesis}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.btitle "title" output.check
  new.block
  "PhD thesis" format.thesis.type output.nonnull
  school "school" output.check
  address output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% A proceedings is a conference proceedings.
% If there is an organization but no editor field, the organization will
% appear as the first optional field (we try to make the first block nonempty);
% if there's no address field, the month (& year) will appear just before note.
%   Required: title, year
%   Optional: editor, volume or number, series, address, month,
%           organization, publisher, note
%   Also optional: library, isbn, issn, annote

FUNCTION {proceedings}
{ output.bibitem
  library.output
  new.sentence
  editor empty$
    { organization output }
    { format.editors output.nonnull }
  if$
  new.block
  format.btitle "title" output.check
  format.bvolume output
  format.number.series output
  address empty$
    { editor empty$
    { publisher new.sentence.checka }
    { organization publisher new.sentence.checkb
      organization output
    }
      if$
      publisher output
      format.date "year" output.check
    }
    { address output.nonnull
      format.date "year" output.check
      new.sentence
      editor empty$
    'skip$
    { organization output }
      if$
      publisher output
    }
  if$
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {cproceedings}
{ output.bibitem
  library.output
  new.sentence
  editor empty$
    { organization output }
    { format.editors output.nonnull }
  if$
  new.block
  format.btitle "title" output.check
  format.bvolume output
  format.number.series output
  address empty$
    { editor empty$
    { publisher new.sentence.checka }
    { organization publisher new.sentence.checkb
      organization output
    }
      if$
      publisher output
      format.date "year" output.check
    }
    { address output.nonnull
      format.date "year" output.check
      new.sentence
      editor empty$
    'skip$
    { organization output }
      if$
      publisher output
    }
  if$
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% A techreport is a technical report.
%   Required: author, title, institution, year
%   Optional: type, number, address, month, note
%   Also optional: library, isbn, issn, annote

FUNCTION {techreport}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  format.tr.number output.nonnull
  institution "institution" output.check
  address output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

FUNCTION {ctechreport}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  format.tr.number output.nonnull
  institution "institution" output.check
  address output
  format.date "year" output.check
  isbn.issn.output
  new.block
  note.output
  annote.output
  fin.entry
}

% An unpublished is something that hasn't been published.
%   Required: author, title, note
%   Optional: month, year
%   Also optional: library, annote

FUNCTION {unpublished}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  note "note" output.check
  format.date output
  annote.output
  fin.entry
}

FUNCTION {cunpublished}
{ output.bibitem
  library.output
  new.sentence
  format.authors "author" output.check
  new.block
  format.title "title" output.check
  new.block
  note "note" output.check
  format.date output
  annote.output
  fin.entry
}

% We use entry type `misc' for an unknown type; BibTeX gives a warning.

FUNCTION {default.type} { misc }

% Here are macros for common things that may vary from style to style.
% Users are encouraged to use these macros.
%
% Months are either written out in full or abbreviated



MACRO {jan} {"January"}

MACRO {feb} {"February"}

MACRO {mar} {"March"}

MACRO {apr} {"April"}

MACRO {may} {"May"}

MACRO {jun} {"June"}

MACRO {jul} {"July"}

MACRO {aug} {"August"}

MACRO {sep} {"September"}

MACRO {oct} {"October"}

MACRO {nov} {"November"}

MACRO {dec} {"December"}



% Journals are either written out in full or abbreviated;
% the abbreviations are like those found in ACM publications.
%
% To get a completely different set of abbreviations, it may be best to make
% a separate .bib file with nothing but those abbreviations; users could then
% include that file name as the first argument to the \bibliography command



MACRO {acmcs} {"ACM Computing Surveys"}

MACRO {acta} {"Acta Informatica"}

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

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

MACRO {ibmsj} {"IBM Systems Journal"}

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

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

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

MACRO {ipl} {"Information Processing Letters"}

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

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

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

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

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

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

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

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

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

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

MACRO {tcs} {"Theoretical Computer Science"}



% Now we read in the .BIB entries.

READ

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% The following part tries to establish whether fields in entries which
%% crossreference another entry are inherited from that entry or not.
%% Unfortunately BibTeX does not make that information available.
%% The basic assumption is that if the fields are identical, they are
%% assumed to be inherited.
%% By Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
%% with help from Oren Patashnik.
%% 15, 16, 17 March 2000
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Display some debugging output (sort output on column 2 and check)
INTEGERS { debug.inheritance }
FUNCTION {debug.inheritance.disable} { #0 'debug.inheritance := }
FUNCTION {debug.inheritance.enable} { #1 'debug.inheritance := }
EXECUTE {debug.inheritance.disable}% do not uncomment this!
%% uncomment if desired:
%EXECUTE {debug.inheritance.enable}

% We need a global string variable to hold field values between entries.
% One per field checked for inheritance, plus cite.
% Really, we should also save a flag "missing" for each field, but we
% won't bother for now.
STRINGS {
    inh.cite
    inh.note
    inh.annote
    inh.isbn
    inh.issn
    inh.library
}

% Adds leading "0" to integers to fill up a field width. Was there a printf$ ...
% pop: integer;  push: string
FUNCTION {fillint3.to.str}%  (field width = 3)
{
  duplicate$ #100 <
    {
      duplicate$ #10 <
        { "00" }
        { "0" }
      if$
    }
    { "" }
  if$
  swap$ int.to.str$ *
}
% Field width = 5, i.e. works up to 99 999 (= 10^6 - 1)
FUNCTION {fillint.to.str}
{
  duplicate$ #10000 <
    { duplicate$ #1000 <
        { duplicate$ #100 <
            { duplicate$ #10 <
                { "0000" }
                { "000" }
              if$
            }
            { "00" }
          if$
        }
        { "0" }
      if$
    }
    { "" }
  if$
  swap$ int.to.str$ *
}

FUNCTION {zero.inherited}
{
  #0 'inherited.note :=
  #0 'inherited.annote :=
  #0 'inherited.isbn :=
  #0 'inherited.issn :=
  #0 'inherited.library :=
}

FUNCTION {debug.entry.dump.head}
{ debug.inheritance
    { "*** Dumping data base entries ... ***" top$ }
    'skip$
  if$
}

% This is for debugging.  Dumps an entry with its cardinal number.
FUNCTION {debug.entry.dump}
{ debug.inheritance
    { "entry " num.entry fillint.to.str * " > " * cite$ * top$ }
    'skip$
  if$
}

% First, we number all entries through.
% Later in the process of establishing field inheritance, we need to sort
% all entries. Saving a cardinal entry number allows us to restore the
% original order.
% While we're at it, we also initialise the flags variables.

INTEGERS { i }

FUNCTION {number.entries.init}
{ #1 'i :=
}

FUNCTION {number.entries}
{
  i 'num.entry :=
  i #1 + 'i :=
  %zero.inherited
}

EXECUTE {number.entries.init}
ITERATE {number.entries}

EXECUTE {debug.entry.dump.head}  ITERATE {debug.entry.dump}  %% debug

% Sort all entries such that the crossreferenced entry is first, then all
% entries crossreferencing it are immediately following.
% Entries which neither crossreference nor are crossreferenced are somewhere
% in between.

%{ crossref #127 int.to.chr$ * } % the DEL character is ignored by SORT
% tilde is the highest character we get; it's also illegal in cite keys
FUNCTION {generate.crossref.sortkeys}
{
  crossref missing$
    { cite$ }
    { crossref "~" * }
  if$
  'sort.key$ :=
  %% debug:
  %"entry " num.entry fillint.to.str * " sort key: '" * sort.key$ * "'" * top$
}

ITERATE {generate.crossref.sortkeys}
SORT

%EXECUTE {debug.entry.dump.head}  ITERATE {debug.entry.dump}  %% debug

% Now go through and check for equal fields in consecutive entries.
%   For each no-crossref entry: save fields
%   For each crossref entry: any fields equal to a saved one is assumed
%     to be inherited.

% Print current values of inherited.* . For debugging.
FUNCTION {debug.inheritance.dump}
{ debug.inheritance
    {
      "entry " num.entry fillint.to.str * " inh:" *
      " note " inherited.note int.to.str$ * *
      ", annote " inherited.annote int.to.str$ * *
      ", isbn " inherited.isbn int.to.str$ * *
      ", issn " inherited.issn int.to.str$ * *
      ", library " inherited.library int.to.str$ * *
      top$
    }
    'skip$
  if$
}

% save possibly inherited fields in global variables
% It is an error to save a missing field in a string variable, so we save
% an empty string instead.
FUNCTION {inheritance.save.fields}
{
  zero.inherited  % this entry has no crossref - therefore no inherited fields
  cite$ 'inh.cite :=
  note missing$
    { "" } { note } if$
    'inh.note :=
  annote missing$
    { "" } { annote } if$
    'inh.annote :=
  isbn missing$
    { "" } { isbn } if$
    'inh.isbn :=
  issn missing$
    { "" } { issn } if$
    'inh.issn :=
  library missing$
    { "" } { library } if$
    'inh.library :=
}

% Check for each non-missing field whether it is equal to the saved one.
% Because we don't have any "field missing" information from the
% crossreferenced entry, a field which is given in the corssreferencing
% entry but is empty will be incorrectly detected as inherited if it is
% missing in the crossreferenced entry.
% Currently empty fields are not printed anyway, so we don't need to worry.
FUNCTION {check.inheritance.fields}
{
  note missing$
    { #0 } { note inh.note = } if$
    'inherited.note :=
  annote missing$
    { #0 } { annote inh.annote = } if$
    'inherited.annote :=
  isbn missing$
    { #0 } { isbn inh.isbn = } if$
    'inherited.isbn :=
  issn missing$
    { #0 } { issn inh.issn = } if$
    'inherited.issn :=
  library missing$
    { #0 } { library inh.library = } if$
    'inherited.library :=
}

INTEGERS { check.inh.inited }

FUNCTION {check.inheritance.init}
{ #0 'check.inh.inited :=
}

FUNCTION {check.inheritance}
{ check.inh.inited #0 =
    { #1 'check.inh.inited :=
      inheritance.save.fields
    }
    { crossref missing$
        { inheritance.save.fields }
        { crossref inh.cite =
            { check.inheritance.fields }
            { zero.inherited
          "crossreferencing entry {" cite$ * "} out of order" *
          " ****** contact listbib author ******" * warning$ }
          if$
        }
      if$
    }
  if$
  %debug.inheritance.dump  %% debug
}

EXECUTE {check.inheritance.init}
ITERATE {check.inheritance}

% Finally, restore original entry order

FUNCTION {generate.num.entry.sortkeys}
{
  num.entry fillint.to.str 'sort.key$ :=
}

ITERATE {generate.num.entry.sortkeys}
SORT

%EXECUTE {debug.entry.dump.head} ITERATE {debug.entry.dump}  %% debug
ITERATE {debug.inheritance.dump}  %% debug

%% End of part checking for inherited fields.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% The sortify function converts to lower case after purify$ing; it's
% used in sorting and in computing alphabetic labels after sorting
%
% The chop.word(w,len,s) function returns either s or, if the first len
% letters of s equals w (this comparison is done in the third line of the
% function's definition), it returns that part of s after w.





% This long comment applies only to alphabetic labels
%
% The format.lab.names function makes a short label by using the initials of
% the von and Last parts of the names (but if there are more than four names,
% (i.e., people) it truncates after three and adds a superscripted "+";
% it also adds such a "+" if the last of multiple authors is "others").
% If there is only one name, and its von and Last parts combined have just
% a single name-token ("Knuth" has a single token, "Brinch Hansen" has two),
% we take the first three letters of the last name.  The boolean
% et.al.char.used tells whether we've used a superscripted "+", so that we
% know whether to include a LaTeX macro for it.
%
% format.lab.names(s) ==
%  BEGIN
%   numnames := num.names$(s)
%   if numnames > 1 then
%       if numnames > 4 then
%       namesleft := 3
%       else
%       namesleft := numnames
%       nameptr := 1
%       nameresult := ""
%       while namesleft > 0
%         do
%       if (name_ptr = numnames) and
%            format.name$(s, nameptr, "{ff }{vv }{ll}{ jj}") = "others"
%          then nameresult := nameresult * "{\etalchar{+}}"
%           et.al.char.used := true
%          else nameresult := nameresult *
%               format.name$(s, nameptr, "{v{}}{l{}}")
%       nameptr := nameptr + 1
%       namesleft := namesleft - 1
%         od
%       if numnames > 4 then
%       nameresult := nameresult * "{\etalchar{+}}"
%       et.al.char.used := true
%   else
%       t := format.name$(s, 1, "{v{}}{l{}}")
%       if text.length$(t) < 2 then % there's just one name-token
%       nameresult := text.prefix$(format.name$(s,1,"{ll}"),3)
%       else
%       nameresult := t
%       fi
%   fi
%   return nameresult
%  END
%
% Exactly what fields we look at in constructing the primary part of the label
% depends on the entry type; this selectivity (as opposed to, say, always
% looking at author, then editor, then key) helps ensure that "ignored" fields,
% as described in the LaTeX book, really are ignored.  Note that MISC is part
% of the deepest `else' clause in the nested part of calc.label; thus, any
% unrecognized entry type in the database is handled correctly.
%
% There is one auxiliary function for each of the four different sequences of
% fields we use.  The first of these functions looks at the author field, and
% then, if necessary, the key field.  The other three functions, which might
% look at two fields and the key field, are similar, except that the key field
% takes precedence over the organization field (for labels---not for sorting).
%
% The calc.label function calculates the preliminary label of an entry, which
% is formed by taking three letters of information from the author or editor or
% key or organization field (depending on the entry type and on what's empty,
% but ignoring a leading "The " in the organization), and appending the last
% two characters (digits) of the year. It is an error if the appropriate fields
% among author, editor, organization, and key are missing, and we use
% the first three letters of the cite$ in desperation when this happens.
% The resulting label has the year part, but not the name part, purify$ed
% (purify$ing the year allows some sorting shenanigans by the user).
%
% This function also calculates the version of the label to be used in sorting.
%
% The final label may need a trailing 'a', 'b', etc., to distinguish it from
% otherwise identical labels, but we can't calculated those "extra.label"s
% until after sorting.
%
% calc.label ==
%  BEGIN
%   if type$ = "book" or "inbook" then
%       author.editor.key.label
%   else if type$ = "proceedings" then
%       editor.key.organization.label
%   else if type$ = "manual" then
%       author.key.organization.label
%   else
%       author.key.label
%   fi fi fi
%   label := label * substring$(purify$(field.or.null(year)), -1, 2)
%       % assuming we will also sort, we calculate a sort.label
%   sort.label := sortify(label), but use the last four, not two, digits
%  END



% When sorting, we compute the sortkey by executing "presort" on each entry.
% The presort key contains a number of "sortify"ed strings, concatenated
% with multiple blanks between them.  This makes things like "brinch  per"
% come before "brinch hansen  per".
%
% The fields used here are: the sort.label for alphabetic labels (as set by
% calc.label), followed by the author names (or editor names or organization
% (with a leading "The " removed) or key field, depending on entry type and on
% what's empty), followed by year, followed by the first bit of the title
% (chopping off a leading "The ", "A ", or "An ").
% Names are formatted: Von Last First Junior.
% The names within a part will be separated by a single blank
% (such as "brinch hansen"), two will separate the name parts themselves
% (except the von and last), three will separate the names,
% four will separate the names from year (and from label, if alphabetic),
% and four will separate year from title.
%
% The sort.format.names function takes an argument that should be in
% BibTeX name format, and returns a string containing "   "-separated
% names in the format described above.  The function is almost the same
% as format.names.



% This long comment applies only to alphabetic labels, when sorted
%
% Now comes the final computation for alphabetic labels, putting in the 'a's
% and 'b's and so forth if required.  This involves two passes: a forward
% pass to put in the 'b's, 'c's and so on, and a backwards pass
% to put in the 'a's (we don't want to put in 'a's unless we know there
% are 'b's).
% We have to keep track of the longest (in width$ terms) label, for use
% by the "thebibliography" environment.
%
% VAR: longest.label, last.sort.label, next.extra: string
%      longest.label.width, last.extra.num: integer
%
% initialize.longest.label ==
%  BEGIN
%   longest.label := ""
%   last.sort.label := int.to.chr$(0)
%   next.extra := ""
%   longest.label.width := 0
%   last.extra.num := 0
%  END
%
% forward.pass ==
%  BEGIN
%   if last.sort.label = sort.label then
%       last.extra.num := last.extra.num + 1
%       extra.label := int.to.chr$(last.extra.num)
%   else
%       last.extra.num := chr.to.int$("a")
%       extra.label := ""
%       last.sort.label := sort.label
%   fi
%  END
%
% reverse.pass ==
%  BEGIN
%   if next.extra = "b" then
%       extra.label := "a"
%   fi
%   label := label * extra.label
%   if width$(label) > longest.label.width then
%       longest.label := label
%       longest.label.width := width$(label)
%   fi
%   next.extra := extra.label
%  END



% Now comes the computation for numeric labels.
% We use either the sorted order or original order.
% We still have to keep track of the longest (in width$ terms) label, for use
% by the "thebibliography" environment.

STRINGS { longest.label }

INTEGERS { number.label longest.label.width }

FUNCTION {initialize.longest.label}
{ "" 'longest.label :=
  #1 'number.label :=
  #0 'longest.label.width :=
}

FUNCTION {longest.label.pass}
{ 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$
}

EXECUTE {initialize.longest.label}

ITERATE {longest.label.pass}



% Now we're ready to start writing the .BBL file.
% We begin, if necessary, with a LaTeX macro for unnamed names in an alphabetic
% label; next comes stuff from the `preamble' command in the database files.
% Then we give an incantation containing the command
%     \begin{thebibliography}{...}
% where the `...' is the longest label.
%
% We also call init.state.consts, for use by the output routines.

FUNCTION {begin.bib}

{ preamble$ empty$

    'skip$
    { preamble$ write$ newline$ }
  if$
  "\begin{thebibliography}{"  longest.label  * "}" * write$ newline$
}

EXECUTE {begin.bib}

EXECUTE {init.state.consts}

% Now we produce the output for all the entries

ITERATE {call.type$}

% Finally, we finish up by writing the `\end{thebibliography}' command.

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

EXECUTE {end.bib}
