% listbib.doc % listbib.bst % % This file was generated by Volker Kuhlmann on 10 Mar 2000 % from the file btxbst.doc version 0.99b by Oren Patashnik % [ 3/23/88 (OP) Version 0.99b for BibTeX 0.99c ] % with the command "/lib/cpp -P -DUNSRT btxbst.doc listbib.doc". % % Then comments at the beginning of the file were edited, % and the essence of biblist version 1.3 by Joachim Schrod were worked in. % Oh yes, and some improvements were added too... % % To obtain listbib.bst, a fast-load no-comment version for bibtex, run % listbib.doc through the command % sed -e '/^%/d' -e '/^[ ]*$/d' % or simply install listbib.doc as listbib.bst (recommended). % On contemporary computers the speed increase is very negligible and the loss % of documentation weighs much more. % % Volker Kuhlmann % 10, 14, 15, 16, 19 Mar; 28 Aug 2000 % 19 Mar 2000: % Inheritance check for volume (result of check is still ignored), % month, totalpages, URL % 28 Aug 2000: % Now not printing totalpages and URL if inherited. % If undefined, defining \url which takes 1 arg and expands to its arg. Load % package url instead! % % unsrt style (unsorted numbers) % % The ENTRY declaration % Like Scribe's (according to pages 231-2 of the April '84 edition), % but no fullauthor or editors fields because BibTeX does name handling. % The annote field is commented out here because this family doesn't % include an annotated bibliography style. And in addition to the fields % listed here, BibTeX has a built-in crossref field, explained later. ENTRY % Fields: { address % Usually the address of a publisher or other type of organization. % Put information in this field only if it helps the reader find the % thing---for example you should omit the address of a major % publisher entirely. For a PROCEEDINGS or an INPROCEEDINGS, % however, it's the address of the conference; for those two entry % types, include the publisher's or organization's address, if % necessary, in the publisher or organization field. % annote % Long annotation---for annotated bibliographies (begins sentence). annote % Used by listbib. Not used by the 4 standard styles, and probably % not used by too many other styles either. % Useful for storing comments about bibliographic items which are % not meant to end up in documents. author % Name(s) of author(s), in BibTeX name format. booktitle % Book title when the thing being referenced isn't the whole book. % For book entries, the title field should be used instead. chapter % Chapter (or section or whatever) number. edition % Edition of a book---should be an ordinal (e.g., "Second"). editor % Name(s) of editor(s), in BibTeX name format. % If there is also an author field, then the editor field should be % for the book or collection that the work appears in. howpublished % How something strange has been published (begins sentence). institution % Sponsoring institution of a technical report. isbn issn % The obvious purpose... journal % Journal name (macros are provided for many). key % Alphabetizing, labeling, and cross-referencing key % (needed when an entry has no author or editor). library % Location of the bibliographic item. This is useful for noting where % in a library a book is. This is not meant to be printed in % documents of course. month % Month (macros are provided). note % To help the reader find a reference (begins sentence). number % Number of a journal or technical report, or of a work in a series. organization % Organization sponsoring a conference (or publishing a manual); if % the editor (or author) is empty, and if the organization produces % an awkward label or cross reference, you should put appropriately % condensed organization information in the key field as well. pages % Page number or numbers (use `--' to separate a range, use `+' % to indicate pages following that don't form a simple range). publisher % Publisher name. school % School name (for theses). series % The name of a series or set of books. % An individual book will will also have it's own title. title % The title of the thing you're referred to. totalpages % Total number of pages of the work. % Is this what custom-bib uses it for? type % Type of a Techreport (e.g., "Research Note") to be used instead of % the default "Technical Report"; or, similarly, the type of a % thesis; or of a part of a book. url % The URL of an entry which is an electronic document. % Is this what custom-bib uses it for? volume % The volume number of a journal or multivolume work. year % The year should contain only numerals (technically, it should end % with four numerals, after purification; doesn't a begin sentence). } % % Integer entry variables { num.entry % The cardinal number of the entry in the data base. % Checking for inheritance requires a resort; this number can be used % to restore the original sort order. inherited.note inherited.annote inherited.isbn inherited.issn inherited.library inherited.volume inherited.month inherited.totalpages inherited.url % Flags which, when set, indicate that the respective field is % inherited from another crossref'ed entry. } % % String entry variables { label sort.label } % These three functions pop one or two (integer) arguments from the stack % and push a single one, either 0 or 1. % The 'skip$ in the `and' and `or' functions are used because % the corresponding if$ would be idempotent FUNCTION {not} { { #0 } { #1 } if$ } FUNCTION {and} { 'skip$ { pop$ #0 } if$ } FUNCTION {or} { { pop$ #1 } 'skip$ if$ } % Each entry function starts by calling output.bibitem, to write the % \bibitem and its arguments to the .BBL file. Then the various fields % are formatted and printed by output or output.check. Those functions % handle the writing of separators (commas, periods, \newblock's), % taking care not to do so when they are passed a null string. % Finally, fin.entry is called to add the final period and finish the % entry. % % A bibliographic reference is formatted into a number of `blocks': % in the open format, a block begins on a new line and subsequent % lines of the block are indented. A block may contain more than % one sentence (well, not a grammatical sentence, but something to % be ended with a sentence ending period). The entry functions should % call new.block whenever a block other than the first is about to be % started. They should call new.sentence whenever a new sentence is % to be started. The output functions will ensure that if two % new.sentence's occur without any non-null string being output between % them then there won't be two periods output. Similarly for two % successive new.block's. % % The output routines don't write their argument immediately. % Instead, by convention, that argument is saved on the stack to be % output next time (when we'll know what separator needs to come % after it). Meanwhile, the output routine has to pop the pending % output off the stack, append any needed separator, and write it. % % To tell which separator is needed, we maintain an output.state. % It will be one of these values: % before.all just after the \bibitem % mid.sentence in the middle of a sentence: comma needed % if more sentence is output % after.sentence just after a sentence: period needed % after.block just after a block (and sentence): % period and \newblock needed. % Note: These styles don't use after.sentence % % VAR: output.state : INTEGER -- state variable for output % % The output.nonnull function saves its argument (assumed to be nonnull) % on the stack, and writes the old saved value followed by any needed % separator. The ordering of the tests is decreasing frequency of % occurrence. % % output.nonnull(s) == % BEGIN % s := argument on stack % if output.state = mid.sentence then % write$(pop() * ", ") % -- "pop" isn't a function: just use stack top % else % if output.state = after.block then % write$(add.period$(pop())) % newline$ % write$("\newblock ") % else % if output.state = before.all then % write$(pop()) % else -- output.state should be after.sentence % write$(add.period$(pop()) * " ") % fi % fi % output.state := mid.sentence % fi % push s on stack % END % % The output function calls output.nonnull if its argument is non-empty; % its argument may be a missing field (thus, not necessarily a string) % % output(s) == % BEGIN % if not empty$(s) then output.nonnull(s) % fi % END % % The output.check function is the same as the output function except that, if % necessary, output.check warns the user that the t field shouldn't be empty % (this is because it probably won't be a good reference without the field; % the entry functions try to make the formatting look reasonable even when % such fields are empty). % % output.check(s,t) == % BEGIN % if empty$(s) then % warning$("empty " * t * " in " * cite$) % else output.nonnull(s) % fi % END % % The output.bibitem function writes the \bibitem for the current entry % (the label should already have been set up), and sets up the separator % state for the output functions. And, it leaves a string on the stack % as per the output convention. % % output.bibitem == % BEGIN % newline$ % write$("\bibitem[") % for alphabetic labels, % write$(label) % these three lines % write$("]{") % are used % write$("\bibitem{") % this line for numeric labels % write$(cite$) % write$("}") % push "" on stack % output.state := before.all % END % % The fin.entry function finishes off an entry by adding a period to the % string remaining on the stack. If the state is still before.all % then nothing was produced for this entry, so the result will look bad, % but the user deserves it. (We don't omit the whole entry because the % entry was cited, and a bibitem is needed to define the citation label.) % % fin.entry == % BEGIN % write$(add.period$(pop())) % newline$ % END % % The new.block function prepares for a new block to be output, and % new.sentence prepares for a new sentence. % % new.block == % BEGIN % if output.state <> before.all then % output.state := after.block % fi % END % % new.sentence == % BEGIN % if output.state <> after.block then % if output.state <> before.all then % output.state := after.sentence % fi % fi % END % INTEGERS { output.state before.all mid.sentence after.sentence after.block } FUNCTION {init.state.consts} { #0 'before.all := #1 'mid.sentence := #2 'after.sentence := #3 'after.block := } % the variables s and t are temporary string holders STRINGS { s t } FUNCTION {output.nonnull} { 's := output.state mid.sentence = { ", " * write$ } { output.state after.block = { add.period$ write$ newline$ "\newblock " write$ } { output.state before.all = 'write$ { add.period$ " " * write$ } if$ } if$ mid.sentence 'output.state := } if$ s } FUNCTION {output} { duplicate$ empty$ 'pop$ 'output.nonnull if$ } FUNCTION {output.check} { 't := duplicate$ empty$ { pop$ "empty " t * " in " * cite$ * warning$ } 'output.nonnull if$ } FUNCTION {output.bibitem} { newline$ "\bibitem{" write$ cite$ write$ "}" write$ newline$ "" before.all 'output.state := } % This function finishes all entries. FUNCTION {fin.entry} { add.period$ write$ newline$ } FUNCTION {new.block} { output.state before.all = 'skip$ { after.block 'output.state := } if$ } FUNCTION {new.sentence} { output.state after.block = 'skip$ { output.state before.all = 'skip$ { after.sentence 'output.state := } if$ } if$ } % Sometimes we begin a new block only if the block will be big enough. The % new.block.checka function issues a new.block if its argument is nonempty; % new.block.checkb does the same if either of its TWO arguments is nonempty. FUNCTION {new.block.checka} { empty$ 'skip$ 'new.block if$ } FUNCTION {new.block.checkb} { empty$ swap$ empty$ and 'skip$ 'new.block if$ } % The new.sentence.check functions are analogous. FUNCTION {new.sentence.checka} { empty$ 'skip$ 'new.sentence if$ } FUNCTION {new.sentence.checkb} { empty$ swap$ empty$ and 'skip$ 'new.sentence if$ } % Here are some functions for formatting chunks of an entry. % By convention they either produce a string that can be followed by % a comma or period (using add.period$, so it is OK to end in a period), % or they produce the null string. % % A useful utility is the field.or.null function, which checks if the % argument is the result of pushing a `missing' field (one for which no % assignment was made when the current entry was read in from the database) % or the result of pushing a string having no non-white-space characters. % It returns the null string if so, otherwise it returns the field string. % Its main (but not only) purpose is to guarantee that what's left on the % stack is a string rather than a missing field. % % field.or.null(s) == % BEGIN % if empty$(s) then return "" % else return s % END % % Another helper function is emphasize, which returns the argument emphazised, % if that is non-empty, otherwise it returns the null string. Italic % corrections aren't used, so this function should be used when punctation % will follow the result. % LaTeX's \emph{} will take care of italic correction. % % emphasize(s) == % BEGIN % if empty$(s) then return "" % %else return "{\em " * s * "}" % else return "\emph{" * s * "}" % % The format.names function formats the argument (which should be in % BibTeX name format) into "First Von Last, Junior", separated by commas % and with an "and" before the last (but ending with "et~al." if the last % of multiple authors is "others"). This function's argument should always % contain at least one name. % % VAR: nameptr, namesleft, numnames: INTEGER % pseudoVAR: nameresult: STRING (it's what's accumulated on the stack) % % format.names(s) == % BEGIN % nameptr := 1 % numnames := num.names$(s) % namesleft := numnames % while namesleft > 0 % do % % for full names: % t := format.name$(s, nameptr, "{ff~}{vv~}{ll}{, jj}") % % for abbreviated first names: % t := format.name$(s, nameptr, "{f.~}{vv~}{ll}{, jj}") % if nameptr > 1 then % if namesleft > 1 then nameresult := nameresult * ", " * t % else if numnames > 2 % then nameresult := nameresult * "," % fi % if t = "others" % then nameresult := nameresult * " et~al." % else nameresult := nameresult * " and " * t % fi % fi % else nameresult := t % fi % nameptr := nameptr + 1 % namesleft := namesleft - 1 % od % return nameresult % END % % The format.authors function returns the result of format.names(author) % if the author is present, or else it returns the null string % % format.authors == % BEGIN % if empty$(author) then return "" % else return format.names(author) % fi % END % % Format.editors is like format.authors, but it uses the editor field, % and appends ", editor" or ", editors" % % format.editors == % BEGIN % if empty$(editor) then return "" % else % if num.names$(editor) > 1 then % return format.names(editor) * ", editors" % else % return format.names(editor) * ", editor" % fi % fi % END % % Other formatting functions are similar, so no "comment version" will be % given for them. % % The `pop$' in this function gets rid of the duplicate `empty' value and % the `skip$' returns the duplicate field value FUNCTION {field.or.null} { duplicate$ empty$ { pop$ "" } 'skip$ if$ } FUNCTION {emphasize} { duplicate$ empty$ { pop$ "" } %%{ "{\em " swap$ * "}" * } { "\emph{" swap$ * "}" * } if$ } INTEGERS { nameptr namesleft numnames } FUNCTION {format.names} { 's := #1 'nameptr := s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := nameptr #1 > { namesleft #1 > { ", " * t * } { numnames #2 > { "," * } 'skip$ if$ t "others" = { " et~al." * } { " and " * t * } if$ } if$ } 't if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } FUNCTION {format.authors} { author empty$ { "" } { author format.names } if$ } FUNCTION {format.editors} { editor empty$ { "" } { editor format.names editor num.names$ #1 > { ", editors" * } { ", editor" * } if$ } if$ } % Format note. % Need to introduce this because we check whether it's inherited. FUNCTION {note.output} { inherited.note { } { note output } if$ } % Format totalpages and URL. FUNCTION {format.totalpages} { totalpages empty$ { "" } { "Pages: " totalpages * } if$ } FUNCTION {format.url} { url empty$ { "" } { "URL: \url{" url * "}" * } if$ } FUNCTION {check.bullet} { duplicate$ empty$ 'skip$ { " \ensuremath{\bullet} " * } if$ } FUNCTION {check.par} { duplicate$ empty$ 'skip$ { "\par " * } if$ } FUNCTION {format.totalpages.url} { totalpages missing$ inherited.totalpages or { "" } { format.totalpages } if$ url missing$ inherited.url or { } { check.bullet format.url * } if$ %check.par } FUNCTION {output.totalpages.url} { new.block output newline$ "\annote " write$ write$ %newline$ "\endannote" } % Deal with annote. % This will also output totalpages and URL. FUNCTION {output.annote} { new.block "\annote " output newline$ write$ annote add.period$ write$ newline$ "\endannote" } FUNCTION {annote.output} { format.totalpages.url duplicate$ empty$ 'pop$ { output.totalpages.url } if$ % annote empty$ inherited.annote or 'skip$ { output.annote } if$ } % Formatting + outputting ISBN and ISSN FUNCTION {format.isbn} { isbn empty$ { "" } { new.sentence "ISBN~" isbn * } if$ } FUNCTION {format.issn} { issn empty$ { "" } { new.sentence "ISSN~" issn * } if$ } FUNCTION {isbn.output} { inherited.isbn { "" } { format.isbn } if$ output } FUNCTION {issn.output} { inherited.issn { "" } { format.issn } if$ output } FUNCTION {isbn.issn.output} { %% both isbn and issn, but not both inherited isbn empty$ not issn empty$ not and inherited.isbn inherited.issn and not and { "used both ISBN and ISSN fields in " cite$ * warning$ } 'skip$ if$ isbn.output issn.output } % Formatting library % We need to check and possibly alter the output state to avoid a period % being output after the library part. % In fact, we can't call output (because it can never work in this case), % instead we write to the output buffer ourselves and set the output.state % to something useful. FUNCTION {format.library} { library empty$ { "" } { "\library{" library * "}" * } if$ } FUNCTION {library.output} { % "checking lib out stat" top$ %% debug inherited.library { "" } { format.library } if$ duplicate$ empty$ { output } { "%" * write$ newline$ before.all 'output.state := } if$ } % The format.title function is used for non-book-like titles. % For most styles we convert to lowercase (except for the very first letter, % and except for the first one after a colon (followed by whitespace)), % and hope the user has brace-surrounded words that need to stay capitilized; % for some styles, however, we leave it as it is in the database. FUNCTION {format.title} { title empty$ { "" } % { title "t" change.case$ } 'title if$ } % By default, BibTeX sets the global integer variable global.max$ to the BibTeX % constant glob_str_size, the maximum length of a global string variable. % Analogously, BibTeX sets the global integer variable entry.max$ to % ent_str_size, the maximum length of an entry string variable. % The style designer may change these if necessary (but this is unlikely) % The n.dashify function makes each single `-' in a string a double `--' % if it's not already % % pseudoVAR: pageresult: STRING (it's what's accumulated on the stack) % % n.dashify(s) == % BEGIN % t := s % pageresult := "" % while (not empty$(t)) % do % if (first character of t = "-") % then % if (next character isn't) % then % pageresult := pageresult * "--" % t := t with the "-" removed % else % while (first character of t = "-") % do % pageresult := pageresult * "-" % t := t with the "-" removed % od % fi % else % pageresult := pageresult * the first character % t := t with the first character removed % fi % od % return pageresult % END FUNCTION {n.dashify} { 't := "" { t empty$ not } { t #1 #1 substring$ "-" = { t #1 #2 substring$ "--" = not { "--" * t #2 global.max$ substring$ 't := } { { t #1 #1 substring$ "-" = } { "-" * t #2 global.max$ substring$ 't := } while$ } if$ } { t #1 #1 substring$ * t #2 global.max$ substring$ 't := } if$ } while$ } % The format.date function is for the month and year, but we give a warning if % there's an empty year but the month is there, and we return the empty string % if they're both empty. FUNCTION {format.date} { year empty$ { month empty$ inherited.month or { "" } { "there's a month but no year in " cite$ * warning$ month } if$ } { month empty$ inherited.month or 'year { month " " * year * } if$ } if$ } % The format.btitle is for formatting the title field when it is a book-like % entry---the style used here keeps it in uppers-and-lowers and emphasizes it. FUNCTION {format.btitle} { title emphasize } % For several functions we'll need to connect two strings with a % tie (~) if the second one isn't very long (fewer than 3 characters). % The tie.or.space.connect function does that. It concatenates the two % strings on top of the stack, along with either a tie or space between % them, and puts this concatenation back onto the stack: % % tie.or.space.connect(str1,str2) == % BEGIN % if text.length$(str2) < 3 % then return the concatenation of str1, "~", and str2 % else return the concatenation of str1, " ", and str2 % END FUNCTION {tie.or.space.connect} { duplicate$ text.length$ #3 < { "~" } { " " } if$ swap$ * * } % The either.or.check function complains if both fields of an either-or pair % are nonempty. % % either.or.check(t,s) == % BEGIN % if not empty$(s) then % warning$(can't use both " * t * " fields in " * cite$) % fi % END FUNCTION {either.or.check} { empty$ 'pop$ { "can't use both " swap$ * " fields in " * cite$ * warning$ } if$ } % The format.bvolume function is for formatting the volume and perhaps % series name of a multivolume work. If both a volume and a series field % are there, we assume the series field is the title of the whole multivolume % work (the title field should be the title of the thing being referred to), % and we add an "of |