% 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: () 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}