% File asl.bst, version 1.0, March 1, 2000.
% Christos A. Kapoutsis, ckap@math.uoa.gr.
% Copyright 2000 by the Association for Symbolic Logic.
%
% This file carries the usual TEX-file non-warranty for results and
% it can be freely copied and re-distributed provided that IF IT IS
% CHANGED IN THE SLIGHTEST WAY, it must be RENAMED.
%%%====================================================================
%%%=-1== Important notes for the user =================================
%%%====================================================================
% COMMANDS THAT THE TEX USER SHOULD DEFINE
%
% Any LaTeX file that uses this BibTeX style, must have the following
% commands defined:
% 1. The command \bysame, as in (++).
% 2. The command \weaktie, as in (+).
% 3. The \biband, \bibetal commands.
% 4. The \jslname, \bslname commands, see (ynm).
% 5. The \yearmagic command, as in (@). See also (@@), for a
% relevant suggestion.
% 6. The \guysmagic command, as in (&). See also (&&).
% 7. The \guy command, to comply with syntax (**).
% 8. The \TheSortKeyIs command, as in (*).
% 9. The \bibfitem, \bibritem commands, to comply with syntax (!).
% See file asl.cls for examples of such definitions. (Or aslbstx.sty.)
% ASSUMPTIONS
%
% The following two assumptions are made:
%
% 1. No entry is such that the list of author names is immediately
% followed by the year of publication.
% 2. No entry is such that the list of author names is its last
% block.
%
% It is most probable that both these rules hold, since there should
% always be a title, which is positioned right after the name list.
% If they fail, then the \guysmagic & \yearmagic tricks may not work
% properly.
%%%====================================================================
%%%==0== General description ==========================================
%%%====================================================================
% THE BIBLIOGRAPHY STORY
% Read this section for a description of how a bibliography listing is
% created by LaTeX and BibTeX.
%
% Suppose I am preparing a paper in TeX, say `paper.tex', and I want a
% bibliography to be inserted into it. I do four things:
% 1. Prepare one or more bibliography databases, in the special
% format required by BibTeX (see [1],[3]). The names of the
% files that contain these databases should have the extension
% `bib'. Let them be `data1.bib', ..., `dataN.bib'.
% 2. Prepare one bibliography style file, in the special language
% recognized by BibTeX (see [2]). The name of that file should
% have the extension `bst'. Let it be `style.bst'. File `asl.bst'
% is such a file.
% 3. In `paper.tex', insert the command
% \bibliography{data1,..,dataN}
% at the point where the bibliography should appear, and also
% the command
% \bibliographystyle{style}
% anywhere before that.
% 4. In `paper.tex', insert the command
% \cite{name}
% each time I want to refer to an entry of the bibliography named
% `name'. I should also insert the command
% \nocite{name}
% if I want the entry named `name' to appear in the bibliography
% listing, ot the command
% \nocite{*}
% if I want all bibliography entries to appear in the listing.
%
% Then I type
% latex paper (LaTeX first pass)
% and LaTeX reads `paper.tex'. Processing this file, it creates a new
% file named `paper.aux'. In `paper.tex', a command of the form of the
% left column below causes the corresponding command in the right
% column to be printed into `paper.aux'.
% \bibliography{data1,..,dataN} \bibdata{data1,..,dataN}
% \bibliographystyle{style} \bibstyle{style}
% \cite{name} \citation{name} (#)
% \nocite{name} \citation{name}
% \nocite{*} \citation{*}
% This way, after the processing is over, `paper.aux' contains:
% A. The list of the names of all bibliography database files that
% I intend to use (parameters to the \bibdata command). That is,
% `data1.bib',..,`dataN.bib'.
% B. The name of bibliography style that I intend to use (parameter
% to the \bibstyle command). That is, `style.bst'.
% C. The names of the bibliography entries that I want to appear
% in the bibliography listing (parameters to the several
% \citation commands). Let them be `name1',..,`nameN'.
% D. \citation{*} iff I want all the entries of the bibliography
% databases to appear in the bibliography listing.
%
% Then I can type
% bibtex file
% and BibTeX will read `paper.aux', looking for the (#) commands and
% ignoring all other contents of the file. At the end, it has got all
% of the (A), (B), (C), (D) information. So, it executes `style.bst'
% over each one of `data1.bib',..,`dataN.bib', extracting from them
% the entries named `name1',...,`nameN' (or all entries, in case of
% \citation{*}) and printing them into a new file, named `paper.bbl',
% in a special TeX format (a `thebibliography' environment, which is
% just a special `list' environment).
%
% Then I can type
% latex paper (LaTeX second pass)
% and LaTeX first reads `paper.aux', ignoring each of the (#) commands
% (each one of these commands has a "gobbling" definition); the sole
% purpose of these commands is to pass information to BibTeX, not to
% LaTeX. In the sequel, LaTeX reads `paper.tex'. When it reaches the
% \bibliography{data1,..,dataN}
% command, it \input's `paper.bbl' (the file created by BibTeX, a
% `thebibliography' environment) which causes the bibliography listing
% to appear in the `paper.dvi' file.
% [ This \input is actually a command of the form
% \IfFileExists{paper.bbl}
% {\input paper.bbl}
% {\typeout{No file paper.bbl.}}
% and is also executed -with trival effects- during the first
% run of LaTeX. ]
% However, the content of `thebibliography' environment is not a simple
% list of \item's. It is actually a list of \bibitem's. And each one of
% them not only expands to an \item (thus making the list of \bibitem's
% something _more than_ a list of \item's), but also outputs a
% \bibcite{name}{label}
% command to `paper.aux'. This information is intended to pass to the
% next (third) LaTeX run and its meaning is that "the entry named
% `name' should have citation label `label'".
%
% Then I can type
% latex paper (LaTeX third pass)
% and LaTeX first reads again `paper.aux'. Each time a command
% \bibcite{name}{label}
% is read, the TeX control sequence `b@name' is defined to expand to
% `label'. Then, knowinf this new definition, LaTeX reads `paper.tex'.
% And, when the \cite{name} command appears, the `b@name' macro is
% expanded, to give `label' in place.
%
% In short, the whole process consists of the following steps:
% i. First pass of LaTeX.
% Reads .tex.
% Creates .aux, outputing there all information
% needed by BibTeX: \bibstyle,\bibdata,\citation.
% ii. Pass of BibTeX.
% Reads .aux.
% Creates .bbl = a `thebibliography' environment
% = a list of \bibitem's.
% iii. Second pass of LaTeX.
% Reads .aux, ignoring information intended for BibTeX.
% Then reads .tex, inputs .bbl at \bibliography.
% Creates .aux as in first pass; but also: Each \bibitem
% command outputs a \bibcite to .aux.
% iv. Third pass of LaTeX.
% Reads .aux, ignoring iformation intended for BibTeX,
% defining all \b@name macros out of \bibcite's.
% Then reads .tex, replaces \cite{name} with the expansion
% of \b@name, inputs .bbl at bibliography.
% Creates .aux as in second pass.
% WHAT A BIBLIOGRAPHY STYLE FILE (.bst file) DOES
% Read this section for a description of what a bibliography style
% file does (and also what asl.bst does).
%
% A bibliography style file (.bst file) is a program, written in
% BibTeX's special language (see [2],[4]), that describes how the
% bibliography database files (.bib files) that one includes in the
% `\bibliography' LaTeX command are to be processed.
%
% A style doesn't describe everything in how the databases are to be
% read; some things are fixed: in each database BibTeX expects to find
% a sequence of structures of the form (a spaces implies any nonempty
% sequence of blank characters: spaces, carriage returns, tabs etc.):
% @ENTRYTYPE {name, field1 = "value1", ..., fieldN = "valueN" }
% and ignores everything that is not contained in such a structure.
% Naturally, each such structure is intended to describe one entry of
% the database.
%
% Upon this fixed supposition, a style defines the following:
% (A) What entry types there are. The standard styles,
% allow the following 14 entry types:
% article, book, booklet, conference, inbook,
% incollection, inproceedings, manual, masterthesis,
% misc, phdthesis, proceedings, techreport, unpublished.
% The same goes for asl.bst, too.
% (B) What fields may be defined within each entry (any entry
% of an allowed type). The standard styles, allow the following
% 24 fields:
% address, annote, author, booktitle, chapter, crossref,
% edition, editor, howpublished, institution, journal,
% key, month, note, number, organization, pages,
% publisher, school, series, title, type, volume, year.
% In addition to these, asl.bst also allows the following:
% language, hardcite, hardlist, hardsort, hardxtra.
% The first one is just one more attribute of the publication
% that the entry describes. The `hard' ones enhance the
% flexibility of the user in formatting that entry in LaTeX.
% (C) How each one of the finally selected entries will be
% formatted in TeX.
% This special behavior of a style is determined in the following ways:
% (B) is specified by the ENTRY command. For asl.bst, see Section 1B.
% (C) is specified by defining a function whose name is the same with
% the name of the corresponding entry type. For example, to
% specify how the `article' entry type should be handled, one
% just defines a
% FUNCTION {article} { ... }
% that contains all actions to be performed for the processing of
% an entry of this type. (The function can access the value of
% any field of the entry, through the actual name of that field.)
% For asl.bst, see Section 4B.
% (A) is specified implicitly: An entry of type X that appears in the
% database is accepted by the style only if the style contains a
% FUNCTION {X} {...}
% which, by (C), also determines how this entry is formatted.
% (This way, more than the desired entry types are `accepted'.
% For example, asl.bst also accepts an entry of the type `not',
% because there is a function named this way. However, these extra
% entry types trigger only erroneous actions, most probably.)
% THE STUCTURE OF asl.bst
%
% The first task is the declarations: of the entry types (as explained
% by (A)), of the definable fields (as explained in (B)), of all
% variables used in the program (see [2]), and of the macros for month
% abbreviations (see [3]). These are all done in Section 1, Subsections
% 1A, 1B, 1C, and 1D, respectively.
%
% The second task is reading the databases. This is done in Section 5
% (the easiest section, just one command). BibTeX reads all specified
% (via the \bibdata command) databases and constructs the list L of
% all selected (via \citation commands) entries.
%
% The third task is sorting list L. This is done in Section 6.
%
% The fourth task is calculating some extra fields for each entry.
% This is done in Section 7. The extra fields are the following:
% a. same.flag In Subsection 7B. This is either 1 or 0, depending
% on whether the entry follows another entry with the
% same author(s) or not.
% b. xtra.label In Subsection 7C. This is "a","b",... , when the
% entry belongs to a sublist of successive entries
% with the same author(s) & year. Otherwise, it is
% "".
% c. name.label In Subsection 7D. This is a list of one or more
% \guy commands, that contains proper punctuation &
% conjunctors and fully describes the author(s) of
% the entry. See below for what a \guy command does.
% The calculation of each field is done separately and requires one
% or two iterations over list L. It is possible to implement these
% calculations altogether, with only two iterations. Nevertheless,
% such an implementation would be too complicated and only a little
% faster.
%
% The last task is the creation of the .bbl file. This is done in
% Subsection 8.
%
% Section 2 contains several functions of general purpose.
% Section 3 contains the functions that are responsible for the
% output to the .bbl file.
% Section 4 contains all functions that implement the formatting
% of the entry fields (Subsection 4B) and then of the
% entries themselves (Subsection 4C).
% The main reason why these three sections do not come right before
% Section 8 is that all functions of Section 4 must have been declared
% when the READ command of Section 5 is executed. Otherwise, in
% accordance with (A), BibTeX wouldn't know what types of entries are
% acceptable.
% YEAR MAGIC
% Read this section, if you wonder what the \yearmagic command does.
%
% To make the style flexible, we have to allow that the year of an
% entry may appear at its beginning, like:
% Kapoutsis [2020] $\P=\NP$, Kapoutsis \& co, Koufalia.
% This implies that two tasks should be performed:
% 1. Printing the year at the beginning.
% 2. Not printing the year at its normal position, somewhere
% inside the entry.
% The first task can be accomplished through a proper definition of
% the \bib?item commands. This section discusses the trick that
% performs the second task.
%
% The first thought was the following: (i) We change the style so
% that, whenever year-relevant-stuff is to be printed, the string
% \yearmagic{year-relevant-stuff}
% is output instead of the intended string
% year-relevant-stuff
% and (ii) we define the command \yearmagic as
% \def\yearmagic#1{#1} or \def\yearmagic#1{}
% depending on whether we want the year to appear or disappear.
%
% This is fine, except for a problem with punctuation: If the
% year-relevant-stuff appears in an entry like that:
% A. ...Springer-Verlag, \yearmagic{2020}, pp. 20--21,...
% forcing it to disappear will lead to
% A'. ...Springer-Verlag, , pp. 20,...
% which is not what we wanted. Analogously, in the context
% B. ...Springer-Verlag, \yearmagic{1999}.
% the year's disappearence will give
% B'. ...Springer-Verlag, .
% On the contrary, everything is okay in contexts like
% C. ...Springer-Verlag, May\yearmagic{1999}, pp. 20,...
% D. ...Springer-Verlag, May\yearmagic{1999}.
% (that is, when something precedes the year-relevant-stuff in the
% same block), so long as we take care that the \yearmagic will be
% printed immediately after (no spaces) the preceding material and
% that its expansion, if nonempty, will start with a space.
%
% To beat this punctuation problem we change the \yearmagic command
% a bit. We give it one more argument (made first) which is intended
% to be either empty ("") or comma (","). Then, we correct the .bbl
% output so that cases A, B, C, D are printed like that:
% A*. ...Springer-Verlag\yearmagic{,}{1999}, pp. 20,...
% B*. ...Springer-Verlag\yearmagic{,}{1999}.
% C*. ...Springer-Verlag, May\yearmagic{}{1999}, pp. 20,...
% D*. ...Springer-Verlag, May\yearmagic{}{1999}.
% and we define \yearmagic as follows
% (@) \def\yearmagic#1#2{#1 #2} or \def\yearmagic#1#2{}
% depending on whether we want the year to appear or disappear. You
% can check that everything is okay now.
%
% Correcting the way A, B, C, D are printed is done:
% 1. in functions format.vol.year and format.date (the only
% functions that format strings with year-relevant-stuff).
% There it is obvious whether additional material is going to
% precede the year-relevant-stuff, so it is easy to decide
% what the first argument of the \yearmagic command should be.
% 2. in function output.nonnull. There, we check whether the
% block that is currently printed [the (i-1)'th block, in the
% terminology of that function's comments] will be followed by
% a block that contains the \yearmagic command with no preceding
% material. If so, no comma is inserted between the two blocks,
% exactly because the expansion of the \yearmagic command will
% provide this comma (if necessary). Otherwise, the comma is
% normally inserted.
%
% Remember that the style file should define the \yearmagic command
% as in (@). Suggestion: A couple of commands like the following
% (@@) \def\yearappear{\def\yearmagic##1##2{##1 ##2}}
% \def\yeardisappear{\def\yearmagic##1##2{}}
% will make the (dis)appearence of the year as easy as a declaration
% \yearappear or \yeardisappear
% anywhere before the bibliography.
%
% A complicated trick, for a complicated need.
% GUYS MAGIC
% Read this section, if you wonder what the \guysmagic command does.
%
% Apart from the year-relevant-stuff, the list of names (authors or
% editors) in an entry may also have to disappear. To this end:
% 1. The format.authors and format.editors functions were altered so
% that they enclose their return strings in a \guysmagic command.
% 2. The output.nonnull function is altered so that it does not
% append a comma to a \guysmagic block.
% 3. The \guysmagic macro must be defined, as follows
% (&) \def\guysmagic#1{#1,} or \guysmagic#1{}
% depending on whether we want the names to appear or not.
% As in `year magic', it is also possible to define
% (&&) \def\guysappear{\def\guysmagic##1{##1,}}
% \def\guysdisappear{\def\guysmagic##1{}}
% so that (dis)appearence of the names is a matter of simple
% declaration:
% \guysappear or \guysdisappear.
% REFERENCES
%
% [1] `BibTeXing'. Oren Patashnik, 8 February 1988.
% [2] `Designing BibTeX styles'. Oren Patashnik, 8 February 1988.
% [3] Appendix B of `LaTeX: A document preparation system'.
% Leslie Lamport, Addison-Wesley, 1986.
% [4] File btxbst.doc.
%%%====================================================================
%%%==1== Declarations =================================================
%%%====================================================================
%%%==1A. Entry types ==================================================
% According to [1], standard BibTeX style files should accept the
% following 14 different entry types:
% article, book, booklet, conference, inbook, incollection,
% inproceedings, manual, masterthesis, misc, phdthesis,
% proceedings, techreport, and unpublished.
% According to [2], there should also be a default entry type, named
% default.type,
% to handle all other cases. Each of these types is declared merely
% through the presence of a function of the same name, that handles
% the corresponding entries. All these functions can be found below,
% in Section 4C, immediately before the READ command.
%%%==1B. Entry fields =================================================
% According to [1], each entry (of any type) may contain any of the
% following 24 fields:
% address, annote, author, booktitle, chapter, crossref, edition,
% editor, howpublished, institution, journal, key, month, note,
% number, organization, pages, publisher, school, series, title,
% type, volume, year.
% Here, we also allow the following 5 new fields
% language, hardsort, hardxtra, hardcite, hardlist
% The first one is just one more attribute of the publication that the
% entry describes. The `hard' ones are explained below.
ENTRY
{ address
author
booktitle
chapter
edition
editor
howpublished
institution
journal
key
language
month
note
number
organization
pages
publisher
school
series
title
type
volume
year
% Sorting of the bibliography is done (Section 6) with respect to
% the sort.key$ field of the entries. This field is calculated for
% every entry (in function calc.sort.key) out of the values of the
% other entry fields and is also output in the .bbl file as the
% argument of a gobbling command named \TheSortKeyIs. Therefore, by
% inspecting the .bbl file, one can justify the order of the items.
%
% Note that the \TheSortKeyIs command is printed from function
% fin.entry. And its should merely gobble its argument:
% (*) \def\TheSortKeyIs#1{}
%
% To change this ordering of an entry, we use the hardsort field:
% First, we inspect the .bbl file to select the desired new position
% of the entry. Then, we insert into this entry the hardsort field
% and set it to any value between the sort.key$ values of the two
% bibliography items that are adjacent to the desired position. The
% next run of BibTeX will assign this value to the sort.key$ of the
% specific entry, causing it to sort right into the desired position.
hardsort
%
% First read the comments on the xtra.label entry variable below.
%
% Now suppose that two entries X,Y belong to the same author and were
% published in the same year. The automatic mechanism of section 7C
% decides one of them, say X, to have xtra.label "a" and the other
% one, Y, to have xtra.label "b". What happens if you don't like this
% assignment, but you would instead prefer it the other way round?
%
% We solve this problem as follows: We insert into both entries the
% hardxtra field and set it to "b" in X, and to "a" in Y. The next
% run of BibTeX will adopt the desired assignment.
%
% (This is done as follows: From 7C, it is clear that extra label
% "a" is assigned to the first --after sorting-- entry in the list,
% "b" is assigned to the second, etc. Therefore, to impose the
% assignment implied by the values of the hardxtra field, we need
% only force the corresponding ordering. But this we can achieve
% trivially by inserting these values into the sort.key$ strings,
% right after the year. This need only one line of code in function
% calc.sort.key.)
hardxtra
% There is always the possibility that the citation label (that is,
% the label used at the point of citation of the entry in the text)
% is not what we have in mind. In such a case the hardcite field
% should be inserted in the entry and set to the exact label that
% we want to appear at the point of citation.
%
% Analogously, the hardlist field can be used to force a particular
% label to appear next to the entry in the bibliography listing.
%
% Both these fields are just passed as arguments to the \bib?item
% commands, in the output.bibitem function of Section 3.
hardcite
hardlist
}
{ % In a sequence of two or more successive bibliography items that
% belong to the same author(s)/editor(s), all items after the first
% one should not print the explicit author(s)/editor(s) names. They
% should print a symbol (usually a long dash) denoting repetition.
% We suppose that this symbol is produced by the macro \bysame,
% (++) \def\bysame{\hrule width2cm}
% as an example. The same.flag entry variable is intended to be
% -- 0, if the entry should explicitly print the
% author(s)/editor(s) names.
% -- 1, if the entry repeats the author(s)/editor(s)
% names of the previous entry.
% Its value is decided in the iteration of section 7B and used in
% function format.authors of section 4B.
same.flag
% This is a number denoting whether the guys that (may) appear
% in the entry are editor(s) or not, as follows:
% value 0: no guys in the entry, or the guys are authors.
% value 1: one guy in the entry and this is an editor.
% value 2: more than one guy in the entry, all editors.
% Note that `nonauthor editors' are not taken into consideration
% in this calulation. I.e., when the entry has both editors and
% authors, the nofeditors field will be 0.
% The field is:
% a. defined here.
% b. calculated in Section 7E through a separate iteration over
% the list of entries.
% c. printed as the 5th argument of the corresponding \bib?item
% command (in output.bibitem) to the .bbl file.
nofeditors
}
{ % In a sequence of two or more successive bibliography items that
% belong to the same author(s)/editor(s), and were published in the
% same year, tags a,b,c,... should be appended to the years of all
% items. The xtra.label entry variable is intended to be
% -- "", if in this item no tag of this kind has to be appended.
% -- "a","b","c",... if the corresponding tag has to be appended.
% Its value is decided in the iteration of Subsection 7C and output
% as a \bib?item argument in function output.bibitem of Section 3.
xtra.label
% String name.label.one + ... + name.label.ten is intended to be
% a list of the \guy(s) of author(s)/editor(s) of the entry. It is
% computed by function calc.name.label in 7D and output by function
% output.bibitem to the .bbl file as a \bib?item argument.
% There should be only one variable, say name.label, for this string.
% But there are ten of them, because the string tends to be much
% longer than entry.max$ (see section 5.3 of [2]).
name.label.one
name.label.two
name.label.three
name.label.four
name.label.five
name.label.six
name.label.seven
name.label.eight
name.label.nine
name.label.ten
}
%%%==1C. Variables ====================================================
% Scratch variables.
STRINGS { r s t }
% Scratch variables.
INTEGERS { len i }
% Counters. Used by format functions.
INTEGERS { nameptr namesleft numnames }
% Flag. Is set to true when the construction of a bibitem starts
% (in output.bibitem) and is always false after the first block
% of the bibitem is output (in output.nonnull).
INTEGERS { at.bibitem.start }
% Flag. Use in multi.page.check, in 4A.
INTEGERS { multiresult }
% For sections 7B, 7C.
STRINGS { prev.author curr.author }
% For section 7C.
STRINGS { prev.year curr.year next.xtra }
% Index, for section 7D.
INTEGERS {active.nl.part}
%%%==1D. Month abbreviations ==========================================
% According to [3]'s Section 3, there should be the standard
% abbreviations for the names of months.
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"}
%%%====================================================================
%%%==2== General purpose functions ====================================
%%%====================================================================
%%%==2A. Debugging ====================================================
% Commented out, since they are not currently used.
%
% % Prints the top (string) of the stack, without popping it.
% FUNCTION {shows}
% { duplicate$ ":::: `" swap$ * "'" * top$
% }
%
% % Pops and prints the whole stack.
% FUNCTION {showstack}
% {"### STACK #################################################" top$
% stack$
% "### ENDSTACK ##############################################" top$
% }
%%%==2B. Boolean operators ============================================
% Of one numerical argument. Returns 0 [1] if the argument is !=0 [0].
FUNCTION {not}
{ { #0 }
{ #1 }
if$
}
% Of two numerical arguments. Returns 0 [1] if these arguments aren't
% both 1 [are both 1].
FUNCTION {and}
{ 'skip$
{ pop$ #0 }
if$
}
% Of two numerical arguments. Returns 0 [1] if these arguments are
% both 0 [aren't both 0].
FUNCTION {or}
{ { pop$ #1 }
'skip$
if$
}
%%%==2C. Other ========================================================
% Of one string argument. If this is nonempty, returns it intact.
% Otherwise, returns "".
FUNCTION {field.or.null}
{ duplicate$ empty$
{ pop$ "" }
'skip$
if$
}
% Issues a warning. For usage, see some place where it is used.
FUNCTION {either.or.check}
{ empty$
'pop$
{ "can't use both " swap$ * " fields in " * cite$ * warning$ }
if$
}
% Issues a warning. For usage, see some place where it is used.
FUNCTION {missing.warning}
{ "missing " swap$ * " in " * cite$ * warning$
}
%%%====================================================================
%%%==3== Output to .bbl ===============================================
%%%====================================================================
% Writes to the file the top of the stack and a new line character.
FUNCTION {write.line}
{ write$ newline$
}
% Pushes onto the stack the name of the \bibitem-like command that
% should introduce the entry in the `thebibliography' environment,
% in the .bbl file. In every group of successive entries that have
% the same author(s)/editor(s), the first one (same.flag=0) is
% introduced with a "\bibfitem" command, while the rest (same.flag=1)
% are introduced with a "\bibritem" command.
FUNCTION {command.name}
{ same.flag #0 =
{ "\bibfitem" }
{ "\bibritem" }
if$
}
% Of no argument. Writes to the .bbl file the header of the bibitem
% for the current entry. This is how a bibitem construction starts.
% In correlation with function fin.entry that follows, output.bibitem
% should have been called "start.entry" instead.
%
% The intended syntax of the \bibfitem, \bibritem commands is:
% \bib?item 1. {citation key} (cite$)
% 2. {guys-list} (name.label.one,..,ten)
% (!) 3. {year} (year)
% 4. {tag} (xtra.label)
% 5. {`number' of editors} (nofeditors)
% 6. {hardcite} (hardcite)
% 7. {hardlist} (hardlist)
FUNCTION {output.bibitem}
{ newline$
command.name "{" * cite$ * "}" * write.line
"{" name.label.one * write$
name.label.two write$
name.label.three write$
name.label.four write$
name.label.five write$
name.label.six write$
name.label.seven write$
name.label.eight write$
name.label.nine write$
name.label.ten "}" * write.line
"{" year field.or.null * "}" * write$
"{" xtra.label * "}" * write$
"{" nofeditors int.to.str$ * "}" * write.line
"{" hardcite field.or.null * "}" * write$
"{" hardlist field.or.null * "}" * write.line
#1 'at.bibitem.start :=
""
% This last empty string is the first thing that will be written
% the next time write$ is called. Done this way because each
% item is saved on the stack until we find out what punctuation
% should be added after it. Therefore we need an empty first item.
}
% Of one string argument, the last part of a bibitem. It adds the
% proper punctuation and writes it to the .bbl file. It also outputs
% the sort key of the entry. This is how a bibitem construction ends.
FUNCTION {fin.entry}
{ add.period$ write.line
"\TheSortKeyIs{" sort.key$ * "}" * write.line
}
% Of one string argument, which should be a new, non null block of
% the current bibitem. Let it be the i'th block (i=1,2,..).
%
% At the moment the function is called, the element of the stack
% that lies immediately under this argument is a string containing
% the (i-1)'th bibitem block. [If i=1, then the argument of the
% function is the first bibitem block and immediately under it in
% the stack there is an empty string (""), put there by the second
% last line of output.bibitem.]
%
% So, the first line pops the i'th block off the stack, to reveal
% the (i-1)'th one. The last line pushes it back onto the stack.
% Then:
% --If i=1 (if at.bibitem.start=true)
% The (i-1)'th block is "". It is just popped off the stack.
% --If i>1 (if at.bibitem.start=false)
% The function knows that the (i-1)'th block will be followed
% by a nonempty one (the i'th one). Therefore, it can output to
% the .bbl file this (i-1)'th block and also a comma, to separate
% the two consequtive blocks from each other.
% There are two exceptions to the comma insertion:
% 1. When the i'th block is a "\yearmagic{,}{"-starting one
% then the comma will be inserted by the expansion of the
% \yearmagic macro (if necessary).
% 2. When the (i-1)'th block is a "\guysmagic"-starting one,
% then again the comma will be inserted by the macro.
%
% This is how the intermediate steps of a bibitem construction are
% performed. The two `output' functions that follow, call this one.
FUNCTION {output.nonnull}
{ 's :=
at.bibitem.start #1 =
{ pop$
#0 'at.bibitem.start :=
}
{ s #1 #14 substring$ "\yearmagic{,}{" =
{ write$ }
{ 'r :=
r #1 #11 substring$ "\guysmagic{" =
{ r " " * write$ }
{ r ", " * write$ }
if$
}
if$
}
if$
s
}
% Of one string argument. Checks to see if this is empty. If not, it
% calls output.nonnull to write it out.
FUNCTION {output}
{ duplicate$ empty$
'pop$
'output.nonnull
if$
}
% Of two string arguments, a field name (held by t) and its value. If
% the value is nonnull, calls output.nonnull. Otherwise, it gives a
% warning on-screen that the given field is empty.
FUNCTION {output.check}
{ 't :=
duplicate$ empty$
{ pop$ t missing.warning }
'output.nonnull
if$
}
%%%====================================================================
%%%==4== Formatting ===================================================
%%%====================================================================
%%%==4A. General auxiliary functions ==================================
% Of one string argument, e.g., s. Returns "{\em" * s * "}", if s is
% not null. Returns "" if s is null.
FUNCTION {emphasize}
{ duplicate$ empty$
{ pop$ "" }
{ "{\em " swap$ * "}" * }
if$
}
% Of two string arguments, a font name t and a field name s. Returns
% "{" * t * " " * s * "}". For example,
% title "\em" apply.font
% is equivalent to
% title emphasize .
FUNCTION {apply.font}
{ 't :=
duplicate$ empty$
{ pop$ "" }
{ "{" t * " " * swap$ * "}" * }
if$
}
% Used to make sure page ranges get the TeX code (two hyphens) for
% en-dashes.
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$
}
% Of one string argument, which should be the contents of the
% pages field. Decides whether this is a representation of one
% or of many pages (so that p. or pp. is used, see format.pages).
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
}
% Of two string arguments. Connects them with a ~ if the second
% one is less than 3 letters long, otherwise it puts an ordinary
% space. Returns this concatenation.
FUNCTION {tie.or.space.connect}
{ duplicate$ text.length$ #3 <
{ "~" }
{ " " }
if$
swap$ * *
}
% Of one string argument. Returns it augmented by a space
% character. If the argument is empty, simply returns it.
FUNCTION {add.space.if.necessary}
{ duplicate$ "" =
'skip$
{ " " * }
if$
}
% Of one string argument, which must be name. Formats this name as:
% First von Last, Jr.
% (i.e., first name first, no abbreviating to initials).
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" =
{ " \bibetal " * }
{ " \biband{} " * t * }
if$
}
if$
}
't
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
}
% Checks whether a misc entry is completely empty.
FUNCTION {empty.misc.check}
{ author empty$ title empty$ howpublished empty$
month empty$ year empty$ note empty$
and and and and and
key empty$ not and
{ "all relevant fields are empty in " cite$ * warning$ }
'skip$
if$
}
%%%==4B. Formatting of fields =========================================
% language is an extra field. Format as: (<language>)
FUNCTION {format.language}
{ language empty$
{ "" }
{ " (" language * ")" * }
if$
}
FUNCTION {format.authors}
{ author empty$
{ "" }
{ "\guysmagic{"
same.flag #1 =
{"\bysame"}
{ author format.names "\scshape" apply.font }
if$
* "}" *
}
if$
}
FUNCTION {format.editors}
{ editor empty$
{ "" }
{ "\guysmagic{"
editor format.names *
editor num.names$ #1 >
{ " (editors)" }
{ " (editor)" }
if$
* "}" *
}
if$
}
FUNCTION {format.nonauthor.editors}
{ editor empty$
{ "" }
{ editor format.names
editor num.names$ #1 >
{ ", editors" * }
{ ", editor" * }
if$
}
if$
}
FUNCTION {format.title}
{ title empty$
{ "" }
{ title "t" change.case$ emphasize }
if$
}
FUNCTION {format.booktitle}
{ title empty$
{ "" }
{ title "t" change.case$ "\bfseries\itshape" apply.font }
if$
}
% (ynm) If the value of the journal field is either "The Journal
% of Symbolic Logic" or "Journal of Symbolic Logic", it is replaced
% with \jslname. If it is "The Bulletin of Symbolic Logic" or
% "Bulletin of Symbolic Logic", it is replaced with \bslname. Then,
% asl.cls defines these commands so that the correct output is given,
% depending on the publications
FUNCTION {format.journal}
{ journal empty$
{ "journal name" missing.warning "" }
{ journal "The Journal of Symbolic Logic" =
journal "Journal of Symbolic Logic" =
or
{ "{\normalfont \jslname}" }
{ journal "The Bulletin of Symbolic Logic" =
journal "Bulletin of Symbolic Logic" =
or
{ "{\normalfont \bslname}" }
{ journal "\bfseries\itshape" apply.font }
if$
}
if$
}
if$
}
% (+) For the phrase "vol." we don't add a following ~ because
% absolute prohibition of a line break there might be too stringent
% (consider that the volume number might be three or even more
% digits). Instead we use \weaktie.
FUNCTION {format.vol.year}
{ volume empty$
{ "" %'skip$ :here lay the bug!
"," 's := %remember the \yearmagic parameter.
}
{ "vol.\weaktie " volume *
"" 's := %remember the \yearmagic parameter.
}
if$
year empty$
{ "year" missing.warning }
{ "\yearmagic{" * s * "}{(" * year * ")}" * }
if$
}
% Formats the issue number of a journal article.
FUNCTION {format.number}
{ number empty$
{ "" }
{ "no.\weaktie " number * }
if$
}
% Formats miscellaneous dates
FUNCTION {format.date}
{ year empty$
{ month empty$
{ "" }
{ "there's a month but no year in " cite$ * warning$
month
}
if$
}
{ month empty$
{ "\yearmagic{,}{" year * "}" * }
{ month "\yearmagic{}{" * year * "}" * }
if$
}
if$
}
% The volume, series and number information is sort of tricky.
% This code handles it as follows:
% If the series is present, and the volume, but not the number,
% then we do "{\em Book title}, Series Name, vol. 000"
% If the series is present, and the number, but not the volume,
% then we do "{\em Book title}, Series Name, no. 000"
% If the series is present, and both number and volume,
% then we do "{\em Book title}, vol. XX, Series Name, no. 000"
% Finally, if the series is absent,
% then we do "{\em Book title}, vol. XX"
% or "{\em Book title}, no. 000"
% and if both volume and number are present, give a warning message.
FUNCTION {format.bookvolume.series.number}
{ volume empty$
% If the volume is EMPTY:
{ "" % Push the empty string as a placeholder in case everything else
% is empty too.
series empty$
'skip$
{ pop$ series } % if series is not empty put in stack
if$
number empty$
'skip$
{ duplicate$ empty$ % if no preceding material,
'skip$ % do nothing, otherwise
{ ", " * } % add a comma and space to separate.
if$
"no." number tie.or.space.connect * % add the number information
}
if$
}
% If the volume is NOT EMPTY:
{ "vol." volume tie.or.space.connect % vol. XX
number empty$
{ series empty$
'skip$
{ series ", " * swap$ *} % Series Name, vol. XX
if$
}
{ series empty$
{ "can't use both volume and number if series info is missing"
warning$
"in BibTeX entry type `" type$ * "'" * top$
}
{ ", " * series * ", no." * number tie.or.space.connect }
if$
}
if$
}
if$
}
% Used by inproceedings entry types
FUNCTION {format.inproc.title.address.editors}
{ booktitle empty$
{ "" }
{ booktitle "t" change.case$ "\bfseries\itshape" apply.font }
if$
% We add parentheses around the address
% (place where conference was held).
address empty$
'skip$
{ add.space.if.necessary "(" * address * ")" * }
if$
% Likewise we add parentheses around the editors' names.
editor empty$
'skip$
{ add.space.if.necessary "(" * format.nonauthor.editors * ")" * }
if$
}
% Similar to format.inproc... but omits the address. For collections
% that are not proceedings volumes.
FUNCTION {format.incoll.title.editors}
{ booktitle empty$
{ "" }
{ booktitle "t" change.case$ "\bfseries\itshape" apply.font }
if$
% We add parentheses around the editors' names.
editor empty$
'skip$
{ add.space.if.necessary "(" * format.nonauthor.editors * ")" * }
if$
}
% Desired output for format.number.series:
% Lecture Notes in Math., no.~1224
FUNCTION {format.number.series}
{ series empty$
{ number empty$
{ "" }
{ "there's a number but no series in " cite$ * warning$ }
if$
}
{ series
number empty$
'skip$
{ ", no.\weaktie " * number * }
if$
}
if$
}
FUNCTION {format.edition}
{ edition empty$
{ "" }
{ at.bibitem.start #0 =
{ edition "l" change.case$ " ed." * }
{ edition "t" change.case$ " ed." * }
if$
}
if$
}
FUNCTION {format.pages}
{ pages empty$
{ "" }
{ pages multi.page.check
{ "pp.\weaktie " pages n.dashify * }
{ "p.\weaktie " pages * }
if$
}
if$
}
FUNCTION {format.book.pages}
{ format.pages
}
FUNCTION {format.chapter.pages}
{ chapter empty$
'format.pages
{ type empty$
{ "ch.\weaktie " }
{ type "l" change.case$ " " * }
if$
chapter *
pages empty$
'skip$
{ ", " * format.book.pages * }
if$
}
if$
}
FUNCTION {format.thesis.type}
{ type empty$
'skip$
{ pop$
type "t" change.case$
}
if$
"\bfseries\itshape" apply.font
}
FUNCTION {format.tr.number}
{ type empty$
{ "Technical Report" }
'type
if$
number empty$
{ "t" change.case$ }
{ number tie.or.space.connect }
if$
"\bfseries\itshape" apply.font
}
% The format.crossref functions haven't been paid much attention
% at the present time (June 1990) and could probably use some
% work. MJD
FUNCTION {format.article.crossref}
{ key empty$
{ journal empty$
{ "need key or journal for " cite$ * " to crossref " * crossref *
warning$
""
}
{ "In " journal * }
if$
}
{ "In " key * }
if$
" \cite{" * crossref * "}" *
}
FUNCTION {format.crossref.editor}
{ editor #1 "{vv~}{ll}" format.name$
editor num.names$ duplicate$
#2 >
{ pop$ " \bibetal{}" * }
{ #2 <
'skip$
{ editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
{ " \bibetal{}" * }
{ " \biband{} " * editor #2 "{vv~}{ll}" format.name$ * }
if$
}
if$
}
if$
}
FUNCTION {format.book.crossref}
{ volume empty$
{ "empty volume in " cite$ * "'s crossref of " * crossref * warning$
"In "
}
{ "Vol." 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$
"" *
}
{ series * }
if$
}
{ key * }
if$
}
{ format.crossref.editor * }
if$
" \cite{" * crossref * "}" *
}
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 * "\/}" * }
if$
}
{ "In " key * }
if$
}
{ "In " format.crossref.editor * }
if$
" \cite{" * crossref * "}" *
}
%%%==4C. Formatting of entries ========================================
FUNCTION {article}
{ output.bibitem
format.authors "author" output.check
format.title "title" output.check
crossref missing$
{ format.journal output
format.vol.year output
format.number output
format.pages "pages" output.check
}
{ format.article.crossref output.nonnull
format.pages output
}
if$
format.language *
note output
fin.entry
}
FUNCTION {book}
{ output.bibitem
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$
format.booktitle "title" output.check
format.edition output
crossref missing$
{ format.bookvolume.series.number output
publisher "publisher" output.check
address output
}
{ format.book.crossref output.nonnull
}
if$
format.date "year" output.check
format.language *
note output
fin.entry
}
FUNCTION {booklet}
{ output.bibitem
format.authors output
format.title "title" output.check
howpublished output
address output
format.date output
note output
fin.entry
}
FUNCTION {conference}
{ output.bibitem
format.authors "author" output.check
format.title "title" output.check
crossref missing$
{ format.inproc.title.address.editors "booktitle" output.check
format.bookvolume.series.number output
organization output
publisher output
format.date "year" output.check
}
{ format.incoll.inproc.crossref output.nonnull
}
if$
note output
format.book.pages output
format.language *
fin.entry
}
FUNCTION {inbook}
{ output.bibitem
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$
title "title" output.check
crossref missing$
{ format.bookvolume.series.number output
format.chapter.pages "chapter and pages" output.check
format.number.series output
publisher "publisher" output.check
address output
}
{ format.chapter.pages "chapter and pages" output.check
format.book.crossref output.nonnull
}
if$
format.edition output
format.date "year" output.check
format.book.pages output
format.language *
note output
fin.entry
}
FUNCTION {incollection}
{ output.bibitem
format.authors "author" output.check
format.title "title" output.check
crossref missing$
{ format.incoll.title.editors "booktitle" output.check
format.bookvolume.series.number output
publisher "publisher" output.check
address output
format.edition output
format.date "year" output.check
}
{ format.incoll.inproc.crossref output.nonnull
}
if$
note output
format.book.pages output
format.language *
fin.entry
}
FUNCTION {inproceedings}
{ conference
}
FUNCTION {manual}
{ output.bibitem
author empty$
{ organization empty$
'skip$
{ organization output.nonnull
address output
}
if$
}
{ format.authors output.nonnull }
if$
format.title "title" output.check
author empty$
{ organization empty$
{ address output }
'skip$
if$
}
{ organization output
address output
}
if$
format.edition output
format.date output
note output
fin.entry
}
FUNCTION {mastersthesis}
{ output.bibitem
format.authors "author" output.check
format.title "title" output.check
"Master's thesis" format.thesis.type output.nonnull
school "school" output.check
address output
format.date "year" output.check
note output
fin.entry
}
FUNCTION {misc}
{ output.bibitem
format.authors output
format.title output
howpublished output
format.date output
note output
format.book.pages output
fin.entry
empty.misc.check
}
FUNCTION {phdthesis}
{ output.bibitem
format.authors "author" output.check
format.title "title" output.check
"Ph.D. thesis" format.thesis.type output.nonnull
school "school" output.check
address output
format.date "year" output.check
note output
format.book.pages output
fin.entry
}
FUNCTION {proceedings}
{ output.bibitem
editor empty$
{ organization output }
{ format.editors output.nonnull }
if$
format.title "title" output.check
format.bookvolume.series.number output
address empty$
{ editor empty$
'skip$
{ organization output }
if$
publisher output
format.date "year" output.check
}
{ address output.nonnull
editor empty$
'skip$
{ organization output }
if$
publisher output
format.date "year" output.check
}
if$
note output
fin.entry
}
FUNCTION {techreport}
{ output.bibitem
format.authors "author" output.check
format.title "title" output.check
format.tr.number output.nonnull
institution "institution" output.check
address output
format.date "year" output.check
note output
fin.entry
}
FUNCTION {unpublished}
{ output.bibitem
format.authors "author" output.check
format.title "title" output.check
note "note" output.check
format.date output
fin.entry
}
FUNCTION {default.type}
{ misc
}
%%%====================================================================
%%%==5== Input ========================================================
%%%====================================================================
READ
%%%====================================================================
%%%==6== Sort =========================================================
%%%====================================================================
% SORTING
%
% To sort the list of entries, we must first compute the sort.key$
% (this is an entry field, implicitly defined for all entries) by
% executing function "presort" on each entry. Then, based on the
% sort.key$ values, the SORT command can sort the entire list. So,
% the code is
% ITERATE {presort} % Calculate the sort.key$'s.
% SORT % Use the sort.key$'s to sort the list.
% in section 6C.
%
% For each entry, the sort.key$ is calculated as follows:
% -- If the hardsort field was defined in this entry: Then the
% calculation of sort.key$ is easy: simply assign to it the value of
% the hardsort field. This way we can manually control the position
% of any entry in the bibliography list. (For each entry the .bbl file
% will always contain the value of its sort.key$ as an argument to the
% gobbling macro \TheSortKeyIs.)
% -- If the hardsort field was not defined in this entry: Then
% the sort.key$ is the concatenation of a number of `sortify'ed strings
% (see function `sortify' below), with multiple blanks between them.
% [ This makes, e.g., "brinch per" come before "brinch hansen per". ]
% The fields used here are: 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 as:
% 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.
%%%==6A. General purpose functions ====================================
% Of one string argument. Returns in purify$ed and in lower case.
FUNCTION {sortify}
{ purify$
"l" change.case$
}
% Of three arguments, a string w, an integer len, a string s. Returns
% either s or, if the first len letters of s equals w, it returns the
% part of s after w.
FUNCTION {chop.word}
{ 's :=
'len :=
s #1 len substring$ = %compares with w (which is in the stack).
{ s len #1 + global.max$ substring$ }
's
if$
}
% Of one string argument, that should be in BibTeX name format. Returns
% a string containing " "-separated names in the format described
% above.
FUNCTION {sort.format.names}
{ 's :=
#1 'nameptr :=
""
s num.names$ 'numnames :=
numnames 'namesleft :=
{ namesleft #0 > }
{ nameptr #1 >
{ " " * } % Exactly three spaces in the blank string.
'skip$
if$
s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't :=
nameptr numnames = t "others" = and
{ "et al" * }
{ t sortify * }
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
}
% Of one string argument, a title. Returns the string after chopping
% off any "A ", "An ", "The " -prefix, purifying, case lowering and
% to-global.max$ chopping.
FUNCTION {sort.format.title}
{ 't :=
"A " #2
"An " #3
"The " #4 t chop.word
chop.word
chop.word
sortify
#1 global.max$ substring$
}
%%%==6B. Calculation of the sort.key$ =================================
FUNCTION {author.sort}
{ author empty$
{ key empty$
{ "to sort, need author or key in " cite$ * warning$
""
}
{ key sortify }
if$
}
{ author sort.format.names }
if$
}
FUNCTION {author.editor.sort}
{ author empty$
{ editor empty$
{ key empty$
{ "to sort, need author, editor, or key in " cite$ * warning$
""
}
{ key sortify }
if$
}
{ editor sort.format.names }
if$
}
{ author sort.format.names }
if$
}
FUNCTION {author.organization.sort}
{ author empty$
{ organization empty$
{ key empty$
{ "to sort, need author, organization, or key in " cite$ * warning$
""
}
{ key sortify }
if$
}
{ "The " #4 organization chop.word sortify }
if$
}
{ author sort.format.names }
if$
}
FUNCTION {editor.organization.sort}
{ editor empty$
{ organization empty$
{ key empty$
{ "to sort, need editor, organization, or key in " cite$ * warning$
""
}
{ key sortify }
if$
}
{ "The " #4 organization chop.word sortify }
if$
}
{ editor sort.format.names }
if$
}
FUNCTION {calc.sort.key}
{ type$ "book" =
type$ "inbook" =
or
'author.editor.sort
{ type$ "proceedings" =
'editor.organization.sort
{ type$ "manual" =
'author.organization.sort
'author.sort
if$
}
if$
}
if$
" " * % Exactly four spaces in the blank string.
year field.or.null sortify *
hardxtra field.or.null sortify * % Insert the hardxtra field.
" " * % Exactly four spaces in the blank string.
title field.or.null sort.format.title *
#1 entry.max$ substring$
'sort.key$ :=
}
FUNCTION {presort}
{ hardsort missing$
{ calc.sort.key }
{ hardsort 'sort.key$ := }
if$
}
%%%==6C. Sorting ======================================================
ITERATE {presort}
SORT
%%%====================================================================
%%%==7== Calculate ====================================================
%%%====================================================================
%%%==7A. General functions ============================================
% Returns the author, if nonempty, otherwise the editor, if nonempty,
% otherwise the empty string.
FUNCTION {author.editor.null}
{ author empty$
{ editor empty$
{ "" }
'editor
if$
}
'author
if$
}
% Of one string argument. Returns this, if not "". Otherwise, the
% dummy string "abcxyz" is returned.
FUNCTION {string.or.dummy}
{ 's :=
s "" =
{ "abcxyz" }
{ s }
if$
}
%%%==7B. Calculate same.flag ==========================================
% Just prepares the two string variables needed.
FUNCTION {init.calc.same.flag}
{ "abcxyz" 'prev.author :=
"" 'curr.author :=
}
% Calculates the `author' of the current entry into curr.author. Then
% compares this `author' with the one of the previous entry. If they
% are the same, then \bysame should appear in the current entry. The
% flag to mark it is the same.flag entry variable.
FUNCTION {calc.same.flag}
{ author.editor.null 'curr.author :=
curr.author prev.author =
{ #1 'same.flag := }
{ #0 'same.flag :=
curr.author string.or.dummy 'prev.author :=
}
if$
}
EXECUTE {init.calc.same.flag}
ITERATE {calc.same.flag}
%%%==7C. Calculate xtra.label =========================================
% Just initialize the variables.
FUNCTION {init.calc.xtra.label}
{ "abcxyz" 'prev.author :=
"abcxyz" 'prev.year :=
"" 'curr.author :=
"" 'curr.year :=
"a" 'next.xtra :=
}
FUNCTION {calc.xtra.label.fore}
{ author.editor.null 'curr.author :=
year field.or.null 'curr.year :=
curr.author prev.author =
curr.year prev.year =
and
{ next.xtra chr.to.int$ #1 + int.to.chr$ 'next.xtra :=
next.xtra 'xtra.label :=
}
{ "a" 'next.xtra :=
"" 'xtra.label :=
curr.author string.or.dummy 'prev.author :=
curr.year string.or.dummy 'prev.year :=
}
if$
}
FUNCTION {calc.xtra.label.back}
{ "b" next.xtra =
{ "a" 'xtra.label := }
'skip$
if$
xtra.label 'next.xtra :=
}
EXECUTE {init.calc.xtra.label}
ITERATE {calc.xtra.label.fore}
EXECUTE {init.calc.xtra.label}
REVERSE {calc.xtra.label.back}
%%%==7D. Calculate name.label =========================================
% Sets all name.label parts to the empty string. No part is active.
FUNCTION {nl.init}
{ "" 'name.label.one :=
"" 'name.label.two :=
"" 'name.label.three :=
"" 'name.label.four :=
"" 'name.label.five :=
"" 'name.label.six :=
"" 'name.label.seven :=
"" 'name.label.eight :=
"" 'name.label.nine :=
"" 'name.label.ten :=
#0 'active.nl.part :=
}
% Of one string argument, t. Appends it to the currently active
% part of name.label.
FUNCTION {nl.stick}
{ 't :=
#1 active.nl.part = { name.label.one t * 'name.label.one := }
{ #2 active.nl.part = { name.label.two t * 'name.label.two := }
{ #3 active.nl.part = { name.label.three t * 'name.label.three := }
{ #4 active.nl.part = { name.label.four t * 'name.label.four := }
{ #5 active.nl.part = { name.label.five t * 'name.label.five := }
{ #6 active.nl.part = { name.label.six t * 'name.label.six := }
{ #7 active.nl.part = { name.label.seven t * 'name.label.seven := }
{ #8 active.nl.part = { name.label.eight t * 'name.label.eight := }
{ #9 active.nl.part = { name.label.nine t * 'name.label.nine := }
{ #10 active.nl.part = { name.label.ten t * 'name.label.ten := }
{ "looong name label in " cite$ * warning$ }
if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$
}
% Of one string argument, t. Appends it to the next part of the
% name.label, which is made active.
FUNCTION {nl.append}
{ active.nl.part #1 + 'active.nl.part :=
nl.stick
}
% Of two arguments: a string r (a list of names in BibTeX format) and
% an integer i (>0). Returns a string containing the \guy command that
% corresponds to the i'th name in r. Format of \guy is
% (**) \guy{first name initials}{first}{von}{last}{junior}
FUNCTION {format.guy}
{ 'i :=
'r :=
"\guy{"
r i "{f.}" format.name$ * "}{" *
r i "{ff}" format.name$ * "}{" *
r i "{vv}" format.name$ * "}{" *
r i "{ll}" format.name$ * "}{" *
r i "{jj}" format.name$ * "}" *
}
% Of one string argument, a list of names in BibTeX format. Computes a
% string containing the corresponding list of \guy's, with the proper
% punctuation and conjunctor. The string is stored in name.label.one,
% name.label.two, name.label.three through the nl.append function. In
% simple notation:
%
% FUNCTION make.name.label(s)
% { numnames := num.names$(s)
% namesleft := numnames
% nameptr := 1
% nl.init
% while$(namesleft > 0)
% { if (nameptr = 1)
% nl.append( format.guy(s,nameptr) )
% else
% if (namesleft = 1)
% if (format.name$(s,nameptr,"{ff }{vv }{ll}{ jj}") = "others")
% nl.stick( " et~al." )
% else
% { nl.stick( (numnames > 2 ? ", and ":" and ") )
% nl.append( format.guy(s,nameptr) )
% }
% else
% { nl.stick( ", " )
% nl.append( format.guy(s,nameptr) )
% }
% nameptr := nameptr + 1
% namesleft := namesleft - 1
% }
% }
%
FUNCTION {make.name.label}
{ 's :=
s num.names$ 'numnames :=
numnames 'namesleft :=
#1 'nameptr :=
nl.init
{ namesleft #0 > }
{ nameptr #1 =
{ s nameptr format.guy nl.append }
{ namesleft #1 =
{ s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" =
{ " et~al." nl.stick }
{ numnames #2 >
{ ", and " }
{ " and " }
if$
nl.stick
s nameptr format.guy nl.append
}
if$
}
{ ", " nl.stick
s nameptr format.guy nl.append
}
if$
}
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
}
% Calculates the name.label out of authors/editors. In simple notation:
% name.label := author!=empty ? make.name.label(author):
% editor!=empty ? make.name.label(editor): ""
FUNCTION {calc.name.label}
{ author empty$
{ editor empty$
{ ""
"no names at all in " cite$ * warning$
}
{ editor }
if$
}
{ author }
if$
make.name.label
}
ITERATE {calc.name.label}
%%%==7E. Calculate nofeditors =========================================
% Extracts the number of editors that appear in the editor field of
% the entry and saves it into nofeditors. It may be called by
% calc.nofeditors; only if the editor field should be consulted.
FUNCTION {extract.nofeditors}
{ editor empty$
{ #0 'nofeditors := }
{ editor num.names$ #1 >
{ #2 'nofeditors := }
{ #1 'nofeditors := }
if$
}
if$
}
% Calculates the nofeditors field. This is like that:
% if [ (type$ = "book" or "inbook") and (author is empty) ]
% or [ (type$ = "inproceedings") and (editor in nonempty) ]
% then nofeditors := `number' of names in the editor field
% else nofeditors := 0.
% where `number' of names = 0, if the editor field is empty / 1, if
% exactly one name in the editor field/ 2, if more than 2 names in
% the editor field.
% IMPORTANT: The condition for the if command should be true iff
% the format.editors function will be called for the entry.
FUNCTION {calc.nofeditors}
{ type$ "book" =
type$ "inbook" =
or
author empty$
and
type$ "proceedings" =
editor empty$ not
and
or
{ extract.nofeditors }
{ #0 'nofeditors := }
if$
}
ITERATE {calc.nofeditors}
%%%====================================================================
%%%==8== Output =======================================================
%%%====================================================================
%%%==8A. Functions ====================================================
FUNCTION {begin.bib}
{ preamble$ empty$
'skip$
{ preamble$ write.line
newline$ newline$
}
if$
"\begin{thebibliography}{}" write.line
}
FUNCTION {end.bib}
{ newline$
"\end{thebibliography}" write.line
}
%%%==8B. The actual output ============================================
EXECUTE {begin.bib}
ITERATE {call.type$}
EXECUTE {end.bib}