%%% ==================================================================== %%% @LaTeX-doc-source-file{ %%% filename = "amsrefs.dtx", %%% version = "2.03", %%% date = "2007/10/22", %%% time = "10:22:13 EDT", %%% author = "Michael J Downes and David M. Jones", %%% address = "American Mathematical Society, %%% Publications Technical Group, %%% PO Box 6248, %%% Providence, RI 02940, %%% USA", %%% email = "tech-support@ams.org", %%% URL = "http://www.ams.org/", %%% abstract = "A LaTeX package that permits bibliography style %%% to be controlled completely from the LaTeX side %%% instead of being determined chiefly by the BibTeX %%% style file.", %%% copyright = "Copyright 2001, 2004, 2006, 2007 American %%% Mathematical Society.", %%% license = "Unlimited copying and redistribution of this file %%% are permitted as long as this file is not %%% modified. Modifications, and distribution of %%% modified versions, are permitted, but only if %%% the resulting file is renamed.", %%% checksum = "57935 8186 25806 247374", %%% docstring = "The checksum field, produced by Robert Solovay's %%% checksum utility, gives CRC-16 checksum, lines, %%% words, and characters.", %%% } %%% ==================================================================== %%% % \iffalse %<*driver> \NeedsTeXFormat{LaTeX2e} \documentclass[draft,oneside]{amsdtx} \setcounter{secnumdepth}{3} \setcounter{tocdepth}{3} \DoNotIndex{\bib,\BibSpec,\@apply,\citesel,\cite@cj,\cite} \DoNotIndex{\IfOption,\add@toks@,\@emptytoks,\@temptokenb} \makeatletter \DeclareRobustCommand{\fld}{\category@index{field}} \DeclareRobustCommand{\btype}{\category@index{entry type}} \DeclareRobustCommand{\attr}{\category@index{attribute}} \makeatother %\OnlyDescription \usepackage{amsrefs} \usepackage{multicol} \providecommand{\lat}[1]{\protect\LaTeX{}} \DeclareTextSymbol{\lbracechar}{OT1}{123} \DeclareTextSymbolDefault{\lbracechar}{OT1} \DeclareTextSymbol{\rbracechar}{OT1}{125} \DeclareTextSymbolDefault{\rbracechar}{OT1} \newcommand{\rdag}{{\normalfont\dag}} \providecommand{\embrace}[1]{% \begingroup \ntt\lbracechar#1\rbracechar\endgroup} % One mandatory argument: cnm; two: cnmm; one optional and one % mandatory: cnom; throwing in a star: cnsom; and so on. \providecommand{\cnbreak}{\penalty999\hskip0pt\relax} \providecommand{\cnm}[2]{\cn{#1}\cnbreak\embrace{#2}} \providecommand{\cnmm}[3]{\cn{#1}\cnbreak\embrace{#2}\cnbreak\embrace{#3}} \providecommand{\cnom}[1]{\cn{#1}\cnbreak\ommitude} \providecommand{\ommitude}[2][]{{\ntt[#1]}\cnbreak\embrace{#2}} \providecommand{\cnmsm}[4]{% \cn{#1}\cnbreak\embrace{#2}\cnbreak *\embrace{#4}} \newcommand{\rpack}[1]{\pkg{amsrefs} package} \newcommand{\MacroArgs}{% \par \medskip \noindent\emph{Arguments}: \par} \newcommand{\macroarg}[2]{ \texttt{\arg{#1} <- }\emph{#2}\unkern\texttt{.}\par} \newenvironment{bug}{% \quote \emph{Known bug:}} {\endquote} % non-stupid hline: support for adding some space below \newcommand{\nshline}{\hline\omit\\} \newcommand{\SeveralOptions}[1]{% \vbox{\def\\{\unskip,\egroup\hbox\bgroup\ignorespaces}% \hbox{\strut#1}}} % Make this a self-contained document without separate .bbl file. \newcommand{\PrintBibliography}{% \begin{bibsection}\begin{biblist}\raggedright \bib{Jones2004}{article}{ author={Jones, David M.}, title={User's Guide to the \pkg{amsrefs} Package}, note={distributed with the \pkg{amsrefs} code} } \bib{SOS99}{book}{ author={Swanson, Ellen}, author={O'Sean, Arlene}, author={Schleyer, Antoinette}, title={Mathematics into Type}, edition={updated}, year={1999}, publisher={American Mathematical Society}, } \end{biblist}\end{bibsection} } \makeatletter \def\nametest#1{% \par \begingroup \let\EmptyNameWarning\relax \vdef\@tempa{#1}% {\tt author=\embrace\@tempa}: \name@split#1,,,\@nil G=\@showname{given} S=\@showname{surname} J=\@showname{jr}% \endgroup } \def\@showname#1{% {\ntt\lbracechar}% {\tt\@xp\macrotext\csname bib'#1\endcsname}% {\ntt\rbracechar} } \def\initialtest#1{% \par \begingroup \vdef\@tempa{#1}% {\tt author=\embrace\@tempa}: \name@split#1,,,\@nil I={\ntt\lbracechar}\csname bib'initials\endcsname{\ntt\rbracechar}% \endgroup } \makeatother \CodelineIndex \begin{document} \title{The \pkg{amsrefs} package} \author{Michael Downes and David M. Jones\\American Mathematical Society} \date{Version \fileversion, \filedate} \hDocInput{amsrefs.dtx} \PrintIndex \end{document} % % \fi % % \MakeShortVerb{\|} % % \maketitle % % \tableofcontents % % \section{Introduction} % % The \rpack/ is a \lat/ package for bibliographies that provides an % archival data format similar to the format of \bibtex/ database % files, but adapted to make direct processing by \lat/ easier. The % package can be used either in conjunction with \bibtex/ or as a % replacement for \bibtex/. % % This document is written for anyone who wants to implement a new % bibliography style for \pkg{amsrefs} or who is just curious about % how the package is implemented. % The reader should be familiar with the contents of the ``User's % Guide to the \pkg{amsrefs} Package''~\cite{Jones2004} % (\fn{amsrdoc.tex}). % % For the publisher or implementor, the chief advantages of the % \rpack/ are as follows: % \begin{description} % % \item[Preservation of structure] % % The internal structural information of the bibliography entries is not % lost when they are imported from the database file into the \lat/ % document. This takes on its greatest significance when archiving % documents in \lat/ form or transmitting them to another user (such as a % publisher). % % \item[Deferred formatting] % % This means that the style of the bibliography can be readily changed % without reimporting everything from the original database(s). % % \item[Setup requires only \lat/ knowledge] % % All bibliography setup can be done in \lat/; learning another % programming language (such as the one used in \bibtex/ \fn{bst} % files) is unnecessary. % % \end{description} % % \section{Package options} % % In addition to the options documented in the user's guide, there % are a few additional options that were omitted either because % they are obsolete or deprecated options included only for % backwards compatability or because they are still considered % experimental and not yet ready for widespread use. % % \begin{description} % % \item[?] % % Informational option. This causes \pkg{amsrefs} to % display a pointer to the User's Guide on the terminal an in the % log file. (In previous versions, it displayed much more % material, including a summary of package options.) % % \item[traditional-quotes, logical-quotes] % % With the \textit{traditional quotes} option % (default), quotation marks produced by \cn{bibquotes} % (\secref{misc-cmds}) fall outside of other punctuation, ``like % this,'' whereas with the \textit{logical quotes} option the order % is reversed, ``like this''. % % \end{description} % % \section{More about the \cn{bib} command}\label{bib-command} % % \subsection{Field names for the \cn{bib} command} % % In addition to the fields discussed in the user's guide, the % following fields are used internally: % \begin{description} % % \item[fulljournal] % % Used internally by \cn{DefineJournal}. % % \item[name] % % Used internally by the \btype{name} bibliography type and % \cn{DefineName}. % % \item[transition] % % A dummy field used inside \cs{BibSpec}s when we want to force an % action unconditionally. % % \end{description} % % The following fields are included for backwards compatibility: % \begin{description} % % \item[institution, school] % % These are provided as aliases for \fld{organization} for % compatibility with \BibTeX. % % \item[place] % % A synonym for \fld{address}. In earlier versions of % \pkg{amsrefs}, \fld{place} was preferred and \fld{address} was % considered as an alias for \fld{place}. However, this seemed % like a gratuitous incompatibility with \BibTeX\ to me, so I have % reinstated \fld{address} as the primary field and \fld{place} is % now an undocumented alias. % % \end{description} % % The following fields are reserved for future use: % \begin{description} % % \item[doi] Digital Object Identifier % % \item[setup] % % This is a special field that can be used to give arbitrary % commands to be executed at the beginning of the current \cn{bib} % entry, after all the fields have been read. The idea is that one % can alter the formatting of an individual entry through this % field, to handle special cases. % % This is fully implemented, but I've been unable to think of any % good examples of its use; so, I've decided to suppress it until % such an example comes to light. % % \item[url] Universal Resource Locator. % % \end{description} % % \subsection{Bibliography entry types} % % The following additional entry types (or, really, pseudo-entry % types) are used internally by \pkg{amsrefs}: % \begin{description} % % \item[collection.article] % % \item[proceedings.article] % % \item[partial] % % \item[conference] % % \item[innerbook] % % \item[name] % % \item[nameLE] % % \item[nameBE] % % \item[nameinverted] % % \item[publisher] % % \end{description} % % The following are currently undocumented aliases for various of % the standard types: % \begin{description} % % \item[miscellaneous] % % \item[periodical] % % \end{description} % % \section{Customizing the bibliography style}\label{other-styles} % % If you use the \rpack/ as is, the bibliography style you get is the % kind of style customarily seen in AMS publications. The recommended % way to get a different bibliography style is to write a \lat/ % package which loads the \rpack/ with \cn{RequirePackage} and % then makes the desired changes by using suitable \cn{BibSpec} % commands as explained below. Thus, the general form of the custom % package will be % \begin{verbatim} % \ProvidesPackage{xyzbib}[2002/11/06 v1.28] % % \RequirePackage{amsrefs}\relax % % \BibSpec{article}{ % ... % } % % \BibSpec{book}{ % ... % } %\end{verbatim} % % The interior formatting within entries is specified by \cn{BibSpec} % commands, one for each entry type. To illustrate, let's look at an % example style specification for entries of type \btype{article}: % \begin{verbatim} % \BibSpec{article}{% % +{}{\PrintAuthors} {author} % +{,}{ \textit} {title} % +{,}{ } {journal} % +{}{ \textbf} {volume} % +{}{ \parenthesize} {date} % +{,}{ } {pages} % +{,}{ } {note} % +{.}{} {transition} % +{}{ } {review} % } %\end{verbatim} % % It should be pretty obvious that each line specifies the formatting % for a particular field. After reading the data for a particular % \cn{bib} command, \lat/ steps through the style specification and % for each % field listed, prints the field with the given formatting \emph{if % and only if the field has a nonempty value}. The \verb'+' character % at the beginning of each field specification must be followed by three % arguments: the punctuation to be added if the field is nonempty; % space and/or other material to be added after the punctuation; and % the field name. It is permissible for the second part to end with a % command that takes an argument, such as \cn{textbf}, in which case % it will receive the field's value as its argument. By defining a % suitable command and using it here you can place material after the % field contents as well as before; \cn{parenthesize} is an example % of this. % % The reason that the punctuation and the following space are specified % separately is that between them there is a crucial boundary for line % breaks. If you put a \cn{linebreak} command at the end of a field value, % the break point will actually be carried onward to a suitable point after % the next bit of punctuation (whose actual value may vary depending on % which of the following fields is the first to turn up with a nonempty % value). % % The meaning of the \cn{parenthesize} command, supplied by % \pkg{amsrefs}, should be obvious. The meaning of the \cn{PrintAuthors} % command is a different story. But I don't think it is all that hard to % understand. If we have two or more author names which were given % separately, % and we need to combine them into a conventional name list using commas % and the word \qq{and}, then it would be nice if we had a command which % could take a list of names and Do The Right Thing. And that is just % what \cn{PrintAuthors} is. % % The \pkg{rkeyval} package allows keys to be defined as additive: if the % key occurs more than once, each successive value will be concatenated to % the previous value, along with a prefix. The setup done by % \pkg{amsrefs} for the \fld{author} field is % \begin{verbatim} % \DefineAdditiveKey{bib}{author}{\name} %\end{verbatim} % This means that if two names are given, as in % \begin{verbatim} % author={Bertram, A.}, % author={Wentworth, R.}, %\end{verbatim} % then the final value of the \fld{author} field seen when \lat/ % processes the style specification will be % \begin{verbatim} % \name{Bertram, A.}\name{Wentworth, R.} %\end{verbatim} % % The \fld{transition} field in our \cn{BibSpec} example is a dummy % field to be % used when punctuation or other material must be added at a certain point % in the bibliography without regard to the emptiness or non-emptiness of % the fields after it. The \fld{transition} field always tests as non-empty % but has no printed content. So when you use it you always get the % indicated punctuation and space at the indicated point in the list of % fields. If it were the last thing in this \cn{BibSpec} example, it could % serve just to put in the final period that is always wanted. But in AMS % bibliographies, if a \emph{Mathematical Reviews} reference is given, it is % conventionally printed \emph{after} the final period. Using the % \fld{transition} field as shown here ensures that the final period will % be always printed, even when the \fld{review} field is empty. % % \section{Miscellaneous commands provided by the \pkg{amsrefs} % package}\label{misc-cmds} % % Most of the following commands are helper commands for use in % \cn{BibSpec} statements. The others are intended for use in bibliography % data. % \begin{description} % % \item[\cn{parenthesize}]\SpecialUsageIndex{\parenthesize} % This command adds parentheses around its % argument. It is useful in \cn{BibSpec} statements because there is no % special provision for adding material after the field value. % % \item[\cn{bibquotes}]\SpecialUsageIndex{\bibquotes} % This command is much like \cn{parenthesize} but % it adds quotes around its argument and it has one other important % difference: there are special arrangements to print the closing quote % \emph{after} a following comma or similar punctuation (unless the % \pkg{amsrefs} package is invoked with the \opt{logical-quotes} option, % in which case \cn{bibquotes} puts the closing quote immediately after % the quoted material). % % \item[\cn{voltext}]\SpecialUsageIndex{\voltext} % This is used to format volume numbers. By default, it precedes % the volume number by ``vol.'' % % \item[\cn{issuetext}]\SpecialUsageIndex{\issuetext} % This is used to format issue numbers. By default, it precedes % the volume number by ``no.'' % % \item[\cn{editiontext}]\SpecialUsageIndex{\editiontext} % This command produces ``ed.''\ following an % edition number. See \cn{PrintEdition} for more information. % % \item[\cn{DashPages}]\SpecialUsageIndex{\DashPages} % This command is similar in spirit to % \cn{voltext} but more complicated in its implementation. It takes % one argument which is expected to contain one or more page numbers % or a range of page numbers. The argument is printed with a prefix % of \qq{p.} if it seems to be a single page number, otherwise with a % prefix of \qq{pp.}. % % \item[\cn{tsup}, \cn{tsub}, \cn{tprime}]\SpecialUsageIndex{\tsup} % \SpecialUsageIndex{\tsub}\SpecialUsageIndex{\prime} % These are for text subscripts % and superscripts, with \cn{tprime} producing a superscript prime % symbol. Unlike the standard \cn{textsuperscript} and % \cn{textsubscript} functions provided by \lat/, these do not use % math mode at all.\footnote{There is one drawback: If you don't % want to get the prime symbol for \cn{tprime} from the \fnt{cmsy} % font, you will need to redefine \cn{tprime} in some suitable % way.} % % \item[\cn{nopunct}]\SpecialUsageIndex{\nopunct} % This command causes following punctuation to be omitted if it is % added with the internal function \cs{@addpunct}. % % \item[\cn{PrintPrimary}]\SpecialUsageIndex{\PrintPrimary} % This is a relatively complicated function that determines the % ``primary'' contributors for an entry and formats them, or % replaces them by \cn{sameauthors} if appropriate. It should be % used when an entry type might have editors or translators instead % of authors. It prefers authors over editors and editors over % translators and generates a warning if there are no primary % contributors. % % \item[\cn{PrintAuthors}]\SpecialUsageIndex{\PrintAuthors} % This is used to format the list of authors as the primary % contributors for an entry type. % % \item[\cn{PrintEditorsA}]\SpecialUsageIndex{\PrintEditorsA} % This is similar to \cn{PrintAuthors} but adds |(ed.)| or |(eds.)| % following the editors. % % \item[\cn{PrintEditorsB}]\SpecialUsageIndex{\PrintEditorsB} % This is similar to \cn{PrintEditorsA} but puts parentheses around % the entire list of editors. It's used by, for example, the % \btype{article} type to print the editors of a % \btype{proceedings} or \btype{collection}. % % \item[\cn{PrintEditorsC}]\SpecialUsageIndex{\PrintEditorsC} % Similar to \cn{PrintEditorsA} but precedes the editors by % |Edited by|. It's used when the editors should be treated as % subsidiary contributors, rather than the primary contributor. % % \item[\cn{PrintTranslatorsA}]\SpecialUsageIndex{\PrintTranslatorsA} % This is similar to \cn{PrintEditorsA} but adds |(trans.)| % following the translators. % % \item[\cn{PrintTranslatorsB}]\SpecialUsageIndex{\PrintTranslatorsB} % This is similar to \cn{PrintEditorsB}. It's not currently used, % but is provided for symmetry. % % \item[\cn{PrintTranslatorsC}]\SpecialUsageIndex{\PrintTranslatorsC} % Similar to \cn{PrintEditorsC} but precedes the translators by % |Translated by|. % % \item[\cn{sameauthors}]\SpecialUsageIndex{\sameauthors} % This is a function of one argument. If you use % the default set of \cn{BibSpec}s from the \pkg{amsrefs}, % \cn{sameauthors} is applied to the author name for a given \cn{bib} % command if it matches exactly the author name of the preceding % \cn{bib} command. Change the definition of \cn{sameauthors} if you % don't want to get a bysame dash. % % \item[\cn{bysame}]\SpecialUsageIndex{\bysame} % This is a horizontal rule of length 3~em. The default % definition of \cn{sameauthors} prints \cn{bysame} instead of the % author names. % % \item[\cn{Plural}, \cn{SingularPlural}]\SpecialUsageIndex{\Plural} % \SpecialUsageIndex{\SingularPlural} % These are helper functions % that allow you to conditionally % print singular or plural forms such as \verb'(ed.)' or \verb'(eds.)' % depending on the number of names in the current name list. % The definition of \cn{PrintEditorsA} reads, in part, % \begin{verbatim} % ... (ed\Plural{s}.) ... %\end{verbatim} % % \item[\cn{PrintReviews}]\SpecialUsageIndex{\PrintReviews} % This is similar to \cn{AuthorList} but is used for % printing (possibly multiple) MR numbers given in the \fld{review} % field. % % \item[\cn{BibField}]\SpecialUsageIndex{\BibField} % This is for more complicated programming tasks such % as may be necessary for some \cn{BibSpec}s. It takes one % argument, a field name, and yields the contents of that field for % the current \cn{bib} entry. % % \item[\cn{IfEmptyBibField}]\SpecialUsageIndex{\IfEmptyBibField} % If one writes % \begin{verbatim} % \IfEmptyBibField{isbn}{A}{B} %\end{verbatim} % then the commands in A will be executed if the \fld{isbn} field is empty, % otherwise the commands in B. % % \item[\cn{PrintEdition}]\SpecialUsageIndex{\PrintEdition} % If a bibliography entry has % \begin{verbatim} % edition={2} %\end{verbatim} % and the \cn{BibSpec} used \cn{PrintEdition} to handle this field, then the % edition information will be printed as \qq{2nd ed.}\mdash that is, the % number is converted to cardinal form and \qq{ed.} is added (taken from % \cn{editiontext}). % % \item[\cn{CardinalNumeric}]\SpecialUsageIndex{\CardinalNumeric} % This provides the conversion to cardinal % number form used by \cn{PrintEdition}. % % \item[\cn{PrintDate}, \cn{PrintYear}]\SpecialUsageIndex{\PrintDate} % \SpecialUsageIndex{\PrintYear} % These functions convert a date in % canonical form (ISO 8601) to the form required by the current % bibliography style. You can get your preferred date form by % redefining these functions or by changing your \cn{BibSpec} statements % to use another function of your own devising. The original definition % of \cn{PrintDate} adds parentheses (as for the year of a journal article % in normal AMS style), whereas the \cn{PrintYear} function simply % prints the year without any additional material (as for a book's year % of publication in normal AMS style). % % \item[\cn{mdash}, \cn{ndash}]\SpecialUsageIndex{\mdash} % \SpecialUsageIndex{\ndash} % These are short forms for \cn{textemdash} % and \cn{textendash}, recommended instead of the more usual \verb'---' % and \verb'--' notation. From the \pkg{textcmds} package. % % \item[et cetera \dots] [mjd,2002-01-03] See the \fn{.dtx} files for % further possibilities that I have not managed to get properly % documented yet! % \end{description} % % \StopEventually{\PrintBibliography} % \iffalse % \clearpage % \typeout{@@@ That was the last page of the OnlyDescription} % \fi % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Implementation} % % \subsection{Overview} % % It will be a while yet before we get to any actual code. First we % need to understand what the code needs to accomplish in order to % provide the user interface described above in a way that is as % compatible as possible with existing \lat/ mechanisms. % % \subsubsection{Normal \lat/ processing of cites} % % \paragraph{First \lat/ pass} % % Various commands are written to the \fn{.aux} file that are % mostly used by \bibtex/. % \begin{enumerate} % \item A \cnm{cite}{moo} command writes one line to the \fn{.aux} file: % \cnm{citation}{moo}. This indicates to \bibtex/ that it should % include `moo' in the list of cited items to be searched for. % The \cn{cite} command also checks to see if \cs{b@moo} contains % the corresponding citation label, but since this is the first % pass, the label won't be known yet, so \lat/ emits an `Undefined % citation' warning and prints a placeholder (i.e., \textbf{???}) % instead of the citation label. % % \item A \cnm{bibliographystyle}{har} command writes one line to the % \fn{.aux} file: \cnm{bibstyle}{har}. This indicates to \bibtex/ that it % should use \fn{har.bst} to determine the style for sorting and % formatting the bibliography items. % % \item A \cnm{bibliography}{hij,klm,...} command writes one line to the % \fn{.aux} file: \cnm{bibdata}{hij,klm,...}. This indicates to \bibtex/ % that it should look in \fn{hij.bib}, \fn{klm.bib}, \dots\ for % bibliographic data. The \cn{bibliography} also tries to input % the \fn{.bbl} file, but on the first pass it won't exist % yet. % % \end{enumerate} % % On the first pass all \cn{cite}'s normally are reported as % undefined because the \fn{.bbl} file has not yet been created. % % \paragraph{\bibtex/ pass} % % For a document named \fn{xyz.tex}, the command \verb'bibtex xyz' is % used to invoke \bibtex/. It looks in \fn{xyz.aux} to find the % citation information written there by \lat/. For each \cn{citation} line, % \bibtex/ searches for a corresponding entry in the specified % \fn{.bib} files and formats it. The entire list is then sorted in % whatever way dictated by the bibliography style, and written out to % the file \fn{xyz.bbl}. This normally produces entries that look % something like: % \begin{verbatim} % \bibitem{BGL} P. Busch, M. Grabowski and P. J. Lahti: % {\it Operational Quantum Physics.} % Springer Verlag, New York (1995). %\end{verbatim} % % \paragraph{Second \lat/ pass} % % Now the \fn{.bbl} file exists and contains some \cn{bibitem} % commands. At \cnm{begin}{document}, \lat/ reads the \fn{.aux} file, % hoping to find some \cn{bibcite} commands, but it will not find % them until the next time around. \cn{citation}, \cn{bibstyle}, and % \cn{bibdata} commands in the \fn{.aux} file are simply ignored by \lat/. % Then \lat/ proceeds to typeset the body of the document. % \begin{enumerate} % \item Instances of \cn{cite} still print question marks. % % \item The \cn{bibliography} command causes \lat/ to input \fn{xyz.bbl} % and typeset its contents. % % \item A \cnm{bibitem}{moo} command writes one line to the % \fn{.aux} file: \cnmm{bibcite}{moo}{9}, where 9 is the current item % number. % % \item A \cnom{bibitem}[Moody]{moo} command writes one line to the % \fn{.aux} file: \cnmm{bibcite}{moo}{Moody}, using the supplied label % instead of a number. % % \end{enumerate} % % \paragraph{Third \lat/ pass} % % Now the \fn{.aux} file contains some \cn{bibcite} commands. Once again, % \lat/ reads the \fn{.aux} file when it reaches \cnm{begin}{document}. % \begin{enumerate} % % \item A \cnmm{bibcite}{moo}{Moody} causes \lat/ to define \cs{b@moo} % with `Moody' as the replacement text. % % \item If two \cn{bibcite} commands have the same citation key, \lat/ % gives a warning message. This happens at \cnm{begin}{document}, % during the reading of the \fn{.aux} file. % % \item Instances of \cn{cite} in the body of the document will print % the appropriate labels obtained from the \fn{.aux} file. % % \item If there are any \cn{cite} commands for which the \fn{.aux} file did % not have a \cn{bibcite} command, \lat/ will give an `Undefined % citation' warning. This often happens if the \fn{.aux} file is incomplete % due to a \TeX{} error on the preceding pass. % \end{enumerate} % % \subsection{How cites are processed by \pkg{amsrefs}} % % In order to support its additional features (e.g., author-year % citations and the \opt{backrefs} option), the \rpack/ stores additional % information for each cite in the macro \cs{b@whatever}. Instead of % simply using the defined or undefined status of this macro to % trigger the standard warnings, we add some boolean flags to allow % us to discriminate more finely what the current situation is. % \begin{itemize} % \item Each time an item is cited in the body of the document, a % \texttt{backref} entry is added to the info of that item. The % \texttt{backref} info % is the current page and section location. Section location is a bit % hard to get right without better support from the document class. % So we provide a hook to allow it to work better when the support is % there. % % \item When a cite occurs, if the info is undefined then a warning is % issued and the info structure is created. A \cs{citation} command % and a \cs{citedest} command (providing backref info) are written to % the \fn{.aux} file. Because the backref info includes page number, it has % to be a non-immediate write. % % An undefined info structure would normally happen only on a first % pass when no \fn{.aux} file exists, or when a new cite is added. % I.e., when the corresponding \cs{citation} command is not yet % present in the \fn{.aux} file. % % \item When a citation command occurs in the \fn{.aux} file, it initializes % the info structure if necessary, setting the ``bib-info-present'' % flag to 0. % % \item When a \cs{citedest} command occurs in the \fn{.aux} file, it % initializes the info structure if necessary---but this shouldn't % happen: if the corresponding \cs{citation} command did not already % get processed, then something is wrong. So normally, the % \cs{citedest} command merely needs to add its backref info to the % existing info structure. % % \item When a \cs{bibcite} command occurs in the \fn{.aux} file, it will % normally find that \cs{b@whatever} is already defined, if the % bibliography occurs after all the \cn{cite} commands. What it must % do is fill in the appropriate blank slots in the info structure % set up by a previous \cs{citation} command. % % \item The \fn{.aux} file is actually processed two times, once at the % beginning of the document and once at the end. In the latter case, % \cs{bibcite} should give a warning if the backref-list is empty, % since that means there were no \cn{cite} commands for the given % key. % % \item When processing the bibliography: The \cn{bib} command needs to % check if it is using a key that is already used by another \cn{bib} % command. % \end{itemize} % % We therefore have % \begin{verbatim} % \b@xyz -> \citesel 00{label}{year}{backref-list} %\end{verbatim} % where the first~0 is replaced by~1 if there has already been another % citation for the same key earlier in the document (some citation % styles use abbreviated forms for all instances after the first), % and the second~0 is replaced by~1 if the same key was already % used by an earlier \cn{bib} command. % % Because the backref-list often includes page number information, it % cannot be built on the fly as we go along; instead we have to write % the information to the \fn{.aux} file and read it in at the beginning of % the next run. % % If there was no \cs{bibcite} in the \fn{.aux} file for a given key, then % the info is % \begin{verbatim} % \b@xyz -> \citesel 00{}{}{backref-list} %\end{verbatim} % If there was neither \cs{citation} nor \cs{bibcite} in the \fn{.aux} file % for a given key, then the \cn{cite} command should find that % \ncn{b@xyz} is undefined. % % If the author-year option is in effect, the \qq{label} contains % the author last names instead of a label: % \begin{verbatim} % \b@xyz -> \citesel 00{\name{Smith}\name{Jones}}{...}{...} %\end{verbatim} % Full name information is included in the data because some citation % styles give full names at the first citation and abbreviated forms % for subsequent instances. % % \subsection{Data structures} % % The result of scanning the key/value pairs of a \cn{bib} command is % an assignment statement for \cs{rsk@toks}. (Cf.\@ the \pkg{rkeyval} % package.) For example, consider the entry % \begin{verbatim} % \bib{miller83}{article}{ % author={Miller, G.}, % title={Eine Bemerkung zur Darstellung von Polynomen \"{u}ber % Verb\"{a}nden}*{language={german}}, % journal={J. Math. Sent.}, % volume={10}, % year={1983}, % pages={26\ndash 30}, % } %\end{verbatim} % The scanned result is to assign % \begin{verbatim} % \global\rsk@toks{% % \set:bib'author{Miller, G.}{}% % \set:bib'title{Eine Bemerkung zur Darstellung von Polynomen % \"{u}ber Verb\"{a}nden}{language={german}}% % \set:bib'journal{J. Math. Sent.}{}% % \set:bib'volume{10}{}% % \set:bib'year{1983}{}% % \set:bib'pages{26\ndash 30}{}% % } %\end{verbatim} % The code in the last arg of \cn{RestrictedSetKeys} then invokes % \cs{bib@exec} to do something with the value of \cs{rsk@toks}. % \begin{verbatim} % \bib@exec{miller83}{\the\rsk@toks}{\setbib@article}{} %\end{verbatim} % % \subsection{Preliminaries} % % \begin{macrocode} %<*pkg> % \end{macrocode} % % Standard declaration of package name and date. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesPackage{amsrefs}[2007/10/22 v2.03] % \end{macrocode} % % \begin{macro}{\amsrefs@warning@nl} % \begin{macrocode} \def\amsrefs@warning@nl{\PackageWarningNoLine{amsrefs}} % \end{macrocode} % \end{macro} % % Backward handling for beta and jpa options. % \begin{macrocode} \@ifpackagewith{amsrefs}{beta}{% \amsrefs@warning@nl{The beta option is obsolete}% }{} \@ifpackagewith{amsrefs}{jpa}{% \amsrefs@warning@nl{The jpa option is obsolete}% }{} % \end{macrocode} % % \begin{macrocode} \IfFileExists{url.sty}{% \RequirePackage{url}\relax \@gobble }{% \@firstofone } { \DeclareRobustCommand{\url}[1]{% \def\@tempa{#1}% \texttt{\@urlsetup $\expandafter\strip@prefix\meaning\@tempa$}% }% \def\@urlsetup{% \check@mathfonts \textfont\@ne\the\font \textfont\z@\the\font \@apply\@urlfix{\do\+\do\=\do\:\do\-\do\.\do\,\do\;}% \@apply\@urlbreak{\do\&\do\/\do\?}% }% \def\@urlbreak#1{% \mathcode`#1="8000 \begingroup \lccode`\~=`#1 \lowercase{\endgroup \edef~}% {\mathchar\number`#1\penalty\hyphenpenalty}% }% \def\@urlfix#1{% \mathcode`#1=`#1\relax }% } % \end{macrocode} % % \begin{macrocode} \@ifundefined{NormalCatcodes}{\RequirePackage{pcatcode}\relax}{} \PushCatcodes\NormalCatcodes % \end{macrocode} % % \begin{macrocode} %% WARNING WARNING WARNING: Catcode of apostrophe ' is letter %% throughout this file. \catcode`\'=11 % letter % \end{macrocode} % % \subsection{Utilities} % % Some of these useful functions are also found in AMS % document classes. % % \begin{macro}{\after@deleting@token} % Similar in concept to \cs{afterassignment}, except it deletes the % next token in the stream before putting its argument % back into the input. Useful for skipping past tokens during % parsing. % \begin{macrocode} \def\after@deleting@token#1{% \afterassignment#1% \let\@let@token= % Don't delete this space! } % \end{macrocode} % \end{macro} % % \begin{macro}{\@ifempty} % \begin{macro}{\@ifnotempty} % Some frequently used tests for empty arguments. Note that an % argument consisting entirely of spaces (e.g., % \verb*|\@ifempty{ }|) counts as empty. % \begin{macrocode} \long\def\@ifempty#1{\@xifempty#1@@..\@nil} \long\def\@xifempty#1#2@#3#4#5\@nil{% \ifx#3#4\@xp\@firstoftwo\else\@xp\@secondoftwo\fi } \long\def\@ifnotempty#1{\@ifempty{#1}{}} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\macrotext} % \begin{macrocode} \def\macrotext{\expandafter\strip@prefix\meaning} % \end{macrocode} % \end{macro} % % \begin{macro}{\vdef} % ``Verbatim'' def. % \begin{macrocode} \def\vdef#1#2{% \def#1{#2}% \edef#1{\macrotext#1}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\auto@protect} % Sometimes it's convenient to render a given control sequence % unexpandable for a time. \cs{auto@protect} provides a way to do % that.\footnote{There really should be a special name for macros % that, like \cs{auto@protect}, take a control sequence as an % argument and redefine that control sequence in order to achieve % some special effect. Pending happier inspiration, I'm % going to call them ``wrapper'' macros.\index{wrapper macros, % definition}} % % An earlier version of this code read simply |\let#1\relax| but % that had the disadvantage of making all \cs{auto@protect}ed % macros compare equal via \cs{ifx}. This version allows macros to % keep their identities under comparisons. % \begin{macrocode} \def\auto@protect#1{\def#1{\@nx#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\g@undef} % Globally undefine a control sequence. % \begin{macrocode} \def\g@undef#1{\global\let#1\relax} % \end{macrocode} % \end{macro} % % \begin{macro}{\@concat} % Concatenate onto the end of a token list. Expands everything. % \begin{macrocode} \def\@concat#1#2{\edef#1{#1#2}} % \end{macrocode} % \end{macro} % % \begin{macro}{\add@toks@} % This saves a few tokens of main memory and a lot of typing. % \begin{macrocode} \def\add@toks@{\addto@hook\toks@} % \end{macrocode} % \end{macro} % % \begin{macro}{\@lappend} % Append an element to a \cs{do}-delimited list. As long as the % element to be appended (|#2|) is a single token, nothing is % expanded. If it contains multiple tokens, all tokens after the % first will be expanded. % \begin{macrocode} \def\@lappend#1#2{% \begingroup \def\do{\@nx\do\@nx}% \edef\@tempa{\def\@nx#1{#1\do#2}}% \@xp\endgroup \@tempa } % \end{macrocode} % \end{macro} % % \begin{macro}{\@apply} % Apply a macro to each element of a \cs{do}-delimited list. % \begin{macrocode} \def\@apply#1#2{% \let\do#1% #2% } % \end{macrocode} % \end{macro} % % \begin{macro}{\get@numberof} % This is a generic macro for counting the number of elements in a % \lat/-style list. % The first argument is a \cs{count} register that will receive the % final count; the second argument is the control sequence that % separates elements of the list, and the third argument is the % list itself. So, for example, % \begin{verbatim} % \get@numberof\@tempcnta\do\dospecials %\end{verbatim} % would count the number of special characters in \cs{dospecials} % and store the number in \cs{@tempcnta}. % \begin{macrocode} \def\get@numberof#1#2#3{% \begingroup \def#2{\advance\@tempcnta\@ne \@gobble}% \@tempcnta\z@ #3\relax \edef\@tempb{#1=\the\@tempcnta\relax}% \@xp\endgroup \@tempb } % \end{macrocode} % \end{macro} % % \begin{macro}{\safe@set} % This is a quick and dirty way of extracting an integer prefix % from a string and assigning it to a counter. If the string does % not begin with an integer, the counter receives the value~0. The % suffix after the integer prefix is discarded. (But bad things % will happen if the string contains the token \cs{@nil}.) % \begin{macrocode} \def\safe@set#1#2{% \afterassignment\@nilgobble #1=0#2\relax\@nil } % \end{macrocode} % \end{macro} % % \begin{macro}{\@chomp} % Vaguely reminiscent of Perl's \texttt{chomp} function, which removes % a substring from the end of a variable, but ours works with % tokens (more-or-less) and takes the substring to be removed as % its second argument. Note the use of \cs{@empty} to anchor the % chomped substring to the end of the string. Note also that the % second argument will be fully expanded during the chomping. % \begin{macrocode} \def\@chomp#1#2{% \begingroup \toks@\@emptytoks \def\@chomper##1##2#2\@empty##3\@nil{% \ifx\@let@token\bgroup \toks@{{##1}##2}% \else \toks@{##1##2}% \fi }% \@xp\chomp@ #1\@empty#2\@empty\@nil \edef\@tempa{\def\@nx#1\@xp{\the\toks@}}% \@xp\endgroup \@tempa } % \end{macrocode} % \end{macro} % % \begin{macro}{\chomp@} % Before passing control to \cs{@chomper}, we peek ahead at the % next token in the stream. That way, if the next token is an open % brace, we know we need to surround \cs{@chomper}'s first argument % with braces. Unfortunately, this might still remove braces from % the second argument, but I think that's ok for our purposes. % \begin{macrocode} \def\chomp@{% \futurelet\@let@token \@chomper } % \end{macrocode} % \end{macro} % % \begin{macro}{\amsrefs@warning} % \begin{macrocode} \def\amsrefs@warning{\PackageWarning{amsrefs}} % \end{macrocode} % \end{macro} % % \begin{macro}{\amsrefs@error} % \begin{macrocode} \def\amsrefs@error{\PackageError{amsrefs}} % \end{macrocode} % \end{macro} % % \begin{macro}{\MessageBreakNS} % This suppresses the leading space in \cs{on@line} in error and % warning messages. % \begin{macrocode} \def\MessageBreakNS{\MessageBreak\romannumeral`\^^@} % \end{macrocode} % \end{macro} % % \begin{macro}{\@addpunct} % The \cs{@addpunct} function is defined by AMS document classes and % the \pkg{amsgen} package. But if we find it undefined we had better % define it. % \begin{macrocode} \@ifundefined{@addpunct}{% \def\@addpunct#1{% \relax\ifhmode \ifnum\spacefactor>\@m \else#1\fi \fi } \def\frenchspacing{% \sfcode`\.1006 \sfcode`\?1005 \sfcode`\!1004 \sfcode`\:1003 \sfcode`\;1002 \sfcode`\,1001\relax } }{} % \end{macrocode} % \end{macro} % % \begin{macro}{\nopunct} % Omit any following punctuation that would normally be inserted by % \cs{@addpunct}. % \begin{macrocode} \providecommand{\nopunct}{\spacefactor \@nopunctsfcode} % \end{macrocode} % \end{macro} % % \begin{macro}{\@nopunctsfcode} % \begin{macrocode} \def\@nopunctsfcode{1007 } % \end{macrocode} % \end{macro} % % \subsection{Declaring package options} % % We call the \pkg{ifoption} package to facilitate some option tests. % \begin{macrocode} \RequirePackage{ifoption}[2000/02/15] % \end{macrocode} % % The \opt{sorted} option is a no-op and is no longer documented. % I'm only leaving it here for backwards compatibility. % \begin{macrocode} \DeclareExclusiveOptions{sorted,citation-order} % \end{macrocode} % The \opt{alphabetic} option corresponds to the standard \bst{alpha} % biblio style with labels like Knu66 (three letters from name plus % two digits of year). Maybe should provide an alias LllYY for this % option. Numeric is the default since it is commoner in AMS % publications. % \begin{macrocode} \DeclareExclusiveOptions{alphabetic,shortalphabetic,author-year,numeric} % \end{macrocode} % % \begin{option}{y2k} % \begin{macrocode} \DeclareBooleanOption{y2k} % \end{macrocode} % \end{option} % % \begin{option}{nobysame} % \begin{macrocode} \DeclareBooleanOption{nobysame} % \end{macrocode} % \end{option} % % The standard \bst{abbrv} bibliography style uses abbreviations for % month names and journal names, and first names of people are % abbreviated to their initials. Since the second test bibliography % that I tested with had unabbreviated month names but abbreviated % journal names, perhaps it is a good idea to let these choices be % specified separately. % \begin{macrocode} \DeclareBooleanOption{short-journals} % \end{macrocode} % \begin{macrocode} \DeclareBooleanOption{short-publishers} % \end{macrocode} % The \opt{short-journals} and \opt{short-publishers} options only % affect journal and publisher names that are defined with % \cn{DefineJournal} and \cn{DefinePublisher} commands. % \begin{macrocode} \DeclareBooleanOption{short-months} % \end{macrocode} % % \begin{macrocode} \DeclareBooleanOption{initials} % \end{macrocode} % Nevertheless, it's to be expected that the preceding four options % would typically be used together, so we provide a short-hand for % requesting them all. % \begin{macrocode} \DeclareOption{abbrev}{% \@pass@ptions \@currext {initials,short-months,short-journals,short-publishers}% \@currname } % \end{macrocode} % % In the bibliography, if a title or something is enclosed in quotes, % should the closing quotes go inside the punctuation (logical % position) rather than outside (traditional)? These options give you % a choice. % \begin{macrocode} \DeclareExclusiveOptions{traditional-quotes,logical-quotes} % \end{macrocode} % % A sequence of cites will be sorted and ranges of length three or % greater will be compressed if these options so indicate. Note % that the \opt{non-sorted-cites} option automatically disables % compression. This is probably a feature. % \begin{macrocode} \DeclareExclusiveOptions{sorted-cites,non-sorted-cites} \DeclareExclusiveOptions{non-compressed-cites,compressed-cites} % \end{macrocode} % % In the bibliography, print page numbers showing where each % entry was cited. % \begin{macrocode} \DeclareBooleanOption{backrefs} % \end{macrocode} % % Option for giving information about the available options: % \begin{macrocode} \DeclareBooleanOption{?} % \end{macrocode} % % This option means to forgo loading of the \pkg{textcmds} and % \pkg{mathscinet} packages. % \begin{macrocode} \DeclareBooleanOption{lite} % \end{macrocode} % % This option can be used by later releases as a sign that fall-back % adaptations need to be done. % \begin{macrocode} \DeclareBooleanOption{beta} % \end{macrocode} % % \begin{macrocode} \DeclareBooleanOption{bibtex-style} % \end{macrocode} % % \begin{macrocode} \DeclareBooleanOption{msc-links} % \end{macrocode} % % \begin{macrocode} \ExecuteOptions{numeric,traditional-quotes,sorted-cites,compressed-cites} \ProcessOptions\relax \ProcessExclusiveOptions % \end{macrocode} % % \begin{macrocode} \IfOption{backrefs}{% \IfFileExists{backref.sty}{% \RequirePackage{backref}[1999/05/30] }{% \amsrefs@warning@nl{The backrefs option cannot be used^^J% unless the backref package is also installed.^^J% (backref is part of the hyperref package)}% }% }{} \IfOption{msc-links}{% \IfFileExists{hyperref.sty}{% \RequirePackage{hyperref}[1999/07/08] }{ \amsrefs@warning@nl{The msc-links option cannot be used^^J% unless the hyperref package is installed}% }% }{} % \end{macrocode} % % \subsubsection{The \opt{?} option} % % \begin{macrocode} \IfOption{?}{% \typeout{^^J% Documentation for the amsrefs package is found in amsrdoc.dvi^^J% (or .pdf or .tex). ^^J% }% }{}% % \end{macrocode} % % \subsection{Loading auxiliary packages} % Now, if these other packages make use of the \pkg{pcatcode} package % like they should, then we don't need to make any fuss here about % the special catcode of \texttt{'}. Just load the packages. % \begin{macrocode} \RequirePackage{rkeyval}[2001/12/22] % \end{macrocode} % % \subsubsection{The \opt{lite} option} % % In my opinion, this is misguided, since \pkg{amsrefs} shouldn't % be loading these packages to begin with. But it's too late to % change it now. % % \begin{macrocode} \IfOption{lite}{% True? Then don't load the next two packages. }{% False? OK, let's load them: \RequirePackage{textcmds}[2001/12/14] \RequirePackage{mathscinet}[2002/01/01] } % \end{macrocode} % % \subsection{Key-value setup} % % \begin{macro}{\BibField} % This provides easy access to individual fields for user-defined % formatting functions. % \begin{macrocode} \newcommand{\BibField}[1]{\csname bib'#1\endcsname} % \end{macrocode} % \end{macro} % % \begin{macro}{\IfEmptyBibField} % A convenient partial application of \cn{rkvIfEmpty}. % \begin{macrocode} \newcommand{\IfEmptyBibField}{\rkvIfEmpty{bib}} % \end{macrocode} % \end{macro} % % \subsubsection{Standard field names (the \texttt{bib} group)} % % And here are the predefined key names. You could always add some % more if you needed them. Only worry is about compatibility if you % want to share your data with other people. % % \begin{macro}{\fld@elt} % \begin{macro}{\name} % We want the list macros used above to be unexpandable except when % special processing is done. (It's not clear to me there's any % real benefit to using these instead of just using \cn{do}.---dmj) % \begin{macrocode} \let\fld@elt=? \let\name=? % \end{macrocode} % \end{macro} % \end{macro} % % First the fields that could be repeated more than once in a single % entry. Maybe publisher should be allowed to repeat also, for % co-published works. But then need to worry about the address % handling. % \begin{macrocode} \DefineAdditiveKey{bib}{author}{\name} \DefineAdditiveKey{bib}{editor}{\name} \DefineAdditiveKey{bib}{translator}{\name} \DefineAdditiveKey{bib}{contribution}{\fld@elt} \DefineAdditiveKey{bib}{isbn}{\fld@elt} \DefineAdditiveKey{bib}{issn}{\fld@elt} \DefineAdditiveKey{bib}{review}{\fld@elt} \DefineAdditiveKey{bib}{partial}{\fld@elt} % \end{macrocode} % % \begin{macrocode} \DefineSimpleKey{bib}{address} \DefineSimpleKey{bib}{book} \DefineSimpleKey{bib}{booktitle} \DefineSimpleKey{bib}{conference} %\DefineSimpleKey{bib}{contributor} \DefineSimpleKey{bib}{copula} \DefineSimpleKey{bib}{date} \DefineSimpleKey{bib}{doi} \DefineSimpleKey{bib}{edition} \DefineSimpleKey{bib}{eprint} \DefineSimpleKey{bib}{fulljournal} \DefineSimpleKey{bib}{hyphenation} \DefineSimpleKey{bib}{institution} \DefineSimpleKey{bib}{journal} \DefineSimpleKey{bib}{label} \DefineSimpleKey{bib}{language} \DefineSimpleKey{bib}{name} \DefineSimpleKey{bib}{note} \DefineSimpleKey{bib}{number} \DefineSimpleKey{bib}{organization} \DefineSimpleKey{bib}{pages} \DefineSimpleKey{bib}{part} \DefineSimpleKey{bib}{place} \DefineSimpleKey{bib}{publisher} \DefineSimpleKey{bib}{reprint} \DefineSimpleKey{bib}{school} \DefineSimpleKey{bib}{series} \DefineSimpleKey{bib}{setup} \DefineSimpleKey{bib}{status} \DefineSimpleKey{bib}{subtitle} \DefineSimpleKey{bib}{title} \DefineSimpleKey{bib}{translation} \DefineSimpleKey{bib}{type} \DefineSimpleKey{bib}{url} \DefineSimpleKey{bib}{volume} \DefineSimpleKey{bib}{xref} \DefineSimpleKey{bib}{year} % \end{macrocode} % The \fld{transition} key is used when we want to insert punctuation % or other material at a given point in the sequence % unconditionally. The key appears to have a non-empty value to % \cn{IfEmptyBibField}, but its value (expansion) is empty. % \begin{macrocode} \DefineDummyKey{bib}{transition} % \end{macrocode} % % \subsubsection{Auxiliary properties (the \texttt{prop} group)} % % \begin{macrocode} \DefineSimpleKey{prop}{inverted} \DefineSimpleKey{prop}{language} % \end{macrocode} % % \subsection{Bibliography type specifications} % % \begin{macro}{\BibSpec} % Accumulate specification material in \cs{toks@}, then define % \cs{setbib@TYPE} from it. % \begin{macrocode} \newcommand{\BibSpec}[2]{% \toks@\@emptytoks \@ifnotempty{#2}{% % \end{macrocode} % The \cs{@ifnextchar} removes an optional |+| at the beginning of % a specification. From then on, each time \cs{bibspec@scan} is % invoked, it expects to find four arguments. The four % \cs{@empty}s appended to the specification (|#2|) below ensure % that this is so. % \begin{macrocode} \@ifnextchar{+}{\@xp\bibspec@scan\@gobble}{\bibspec@scan}% #2\@empty\@empty\@empty\@empty }% \@xp\edef\csname setbib@#1\endcsname{\the\toks@}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\bibspec@scan} % The \cs{bibspec@scan} function scans one field specification % from the second arg of \cn{BibSpec}. Each field specification has % the form % \begin{verbatim} % +{punctuation}{prelim material}{field name} %\end{verbatim} % Note however that because the initial |+| is stripped off by % \cs{BibSpec} (see above), the actual order that \cs{bibspec@scan} % reads the field specification is % \begin{verbatim} % #1={punctuation} #2={prelim material} #3={field name} #4=+ %\end{verbatim} % where the fourth argument is actually expected to be either the % |+| from the following specification, or one of the special % \cs{@empty} tokens inserted by \cs{BibSpec}. If it is neither of % these special values, it means we have a malformed specification; % so, we issue an error and then try to pick up where we left off. % \begin{macrocode} \def\bibspec@scan#1#2#3#4{% \add@toks@{\bib@append{#1}{#2}}% \edef\@tempa{% \toks@{\the\toks@ \@xp\@nx\csname bib'#3\endcsname}% }% \@tempa \ifx\@empty#4% \@xp\@gobble % end the recursion \else \ifx +#4\else\bibspec@scan@error\fi \fi \bibspec@scan } % \end{macrocode} % \end{macro} % % \begin{macro}{\bibspec@scan@error} % \begin{macrocode} \def\bibspec@scan@error{\amsrefs@error{Bad BibSpec: Expected '+'}} % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@append} % The function \cs{bib@append} prints the value of a field, together % with associated punctuation and font changes, unless the value is % empty. Arg 1 is punctuation (that may need to be swapped with a % preceding line break), arg 2 gives the space to be added after the % punctuation, and possibly a function to be applied to the contents % of arg 3, which is % a macro containing the field % value. So if we have \cn{moo} and \cn{bib'pages}, from % \verb'pages={21\ndash 44}', then we want to arrange to call % \begin{verbatim} % \moo{21\ndash 44} %\end{verbatim} % We don't want to simply call \cs{moo}\cs{bib'bar} because that makes % it rather difficult for \cs{moo} to look at the contents of % \cs{bib@bar}. % \begin{macrocode} \def\bib@append#1#2#3{% \ifx\@empty#3% \else % \end{macrocode} % \begin{bug} % Need better error message here. % \end{bug} % \begin{macrocode} \ifx\relax#3% \errmessage{#3=\relax}% \else \begingroup \series@index\m@ne \def\current@bibfield{#3}% \@ifempty{#1}{% \@temptokena{\ifnum\lastkern=\@ne\ignorespaces\fi #2}% }{% \@temptokena{\SwapBreak{#1}#2}% }% \toks@\@xp{#3}% \edef\@tempa{\the\@temptokena{\the\toks@}}% \rkvIfAdditive#3{}{% \get@current@properties \select@auxlanguage }% \@tempa \endgroup \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\select@auxlanguage} % \begin{macrocode} \def\select@auxlanguage{% \ifx\prop'language\@empty \else \@xp\selectlanguage\@xp{\prop'language}% \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\erase@field} % There are some fields that can appear in more than one place in a % reference, depending on context. For example, if a book has an % editor but no author, the editor appears at the beginning of the % entry, but if the book has both an editor and an author, the % editor appears at the end of the entry. A simple way to handle % this is to ``erase'' the \fld{editor} field after printing it, % which is what \cs{erase@field} is for. % % The obvious definition of \cs{erase@field} is % \begin{verbatim} % \def\erase@field#1{\global\let#1\@empty} %\end{verbatim} % but that doesn't work because the top-level value of % \pkg{rkeyval} fields isn't \cs{@empty}; instead, it contains a % setter function used by \cs{RestrictedSetKeys} when processing a % key-value list (see \cs{rkv@DSAK}, \cs{rsk@set@a} and % \cs{rsk@set@b}). % % On the other hand, rewriting the field locally won't work % either, since \cs{erase@field} will typically be executed inside % the group established by \cs{bib@append}. Instead, we want to % rewrite the value right after \cs{bib@append}'s group ends. One % way to do this would be to keep a list of fields to be erased and % have \cs{bib@append} iterate over the list after its % \ncn{endgroup}. % % However, as long as the call to \cs{erase@field} % is never nested within any deeper groups, it's simpler just to % use \cs{aftergroup}, which is what we'll do (``Sufficient unto % the day is the evil thereof'' and all that). % \begin{macrocode} \def\erase@field#1{% \aftergroup\let\aftergroup#1\aftergroup\@empty } % \end{macrocode} % \end{macro} % % \begin{macro}{\get@current@properties} % This retrieves the auxiliary properties for the current field % value, as defined by \cs{current@bibfield} and % \cs{series@index}. % \begin{macrocode} \def\get@current@properties{% \begingroup \@xp\get@nth@property\@xp\@tempa\current@bibfield\series@index \edef\@tempa{% \@nx\RestrictedSetKeys{}{prop}{% \def\@nx\@tempa{\@nx\prop@reset \@nx\the\@nx\rsk@toks}% }{\@tempa}% }% \@tempa \@xp\endgroup \@tempa } % \end{macrocode} % \end{macro} % % \begin{macro}{\BibSpecAlias} % This is a \cs{def} rather than a \cs{let} because using \cs{let} % would make \cn{BibSpecAlias} statements order-sensitive in a way % that seems frequently to be a stumbling block to unwary package % writers. But then we should probably do at least the simplest % kind of infinite loop check. % \begin{macrocode} \newcommand{\BibSpecAlias}[2]{% \@xp\def\@xp\@tempa\@xp{\csname setbib@#1\@xp\endcsname}% \@xp\ifx\csname setbib@#2\endcsname\@tempa \amsrefs@error{% Mirror alias #1->#2 not allowed (infinite loop)}\@ehc \else \@xp\def\csname setbib@#1\@xp\endcsname \@xp{\csname setbib@#2\endcsname}% \fi } % \end{macrocode} % \end{macro} % % \subsection{The standard bibliography types} % % \begin{macrocode} \BibSpec{article}{% +{} {\PrintAuthors} {author} +{,} { \textit} {title} +{.} { } {part} +{:} { \textit} {subtitle} +{,} { \PrintContributions} {contribution} +{.} { \PrintPartials} {partial} +{,} { } {journal} +{} { \textbf} {volume} % \end{macrocode} % The date form is tricky depending on presence or absence of DOI. % \begin{macrocode} +{} { \PrintDatePV} {date} +{,} { \issuetext} {number} +{,} { \eprintpages} {pages} +{,} { } {status} +{,} { \PrintDOI} {doi} +{,} { available at \eprint} {eprint} +{} { \parenthesize} {language} +{} { \PrintTranslation} {translation} +{;} { \PrintReprint} {reprint} +{.} { } {note} +{.} {} {transition} +{} {\SentenceSpace \PrintReviews} {review} } \BibSpec{partial}{% +{} {} {part} +{:} { \textit} {subtitle} +{,} { \PrintContributions} {contribution} +{,} { } {journal} +{} { \textbf} {volume} +{} { \PrintDatePV} {date} +{,} { \issuetext} {number} +{,} { \eprintpages} {pages} } \BibSpec{contribution}{% +{} {} {type} +{} { by \PrintNameList} {author} } \BibSpec{book}{% +{} {\PrintPrimary} {transition} +{,} { \textit} {title} +{.} { } {part} +{:} { \textit} {subtitle} +{,} { \PrintEdition} {edition} +{} { \PrintEditorsB} {editor} +{,} { \PrintTranslatorsC} {translator} +{,} { \PrintContributions} {contribution} +{,} { } {series} +{,} { \voltext} {volume} +{,} { } {publisher} +{,} { } {organization} +{,} { } {address} +{,} { \PrintDateB} {date} +{,} { } {status} +{} { \parenthesize} {language} +{} { \PrintTranslation} {translation} +{;} { \PrintReprint} {reprint} +{.} { } {note} +{.} {} {transition} +{} {\SentenceSpace \PrintReviews} {review} } \BibSpec{collection.article}{% +{} {\PrintAuthors} {author} +{,} { \textit} {title} +{.} { } {part} +{:} { \textit} {subtitle} +{,} { \PrintContributions} {contribution} +{,} { \PrintConference} {conference} +{} {\PrintBook} {book} +{,} { } {booktitle} +{,} { \PrintDateB} {date} +{,} { pp.~} {pages} +{,} { } {status} +{,} { \PrintDOI} {doi} +{,} { available at \eprint} {eprint} +{} { \parenthesize} {language} +{} { \PrintTranslation} {translation} +{;} { \PrintReprint} {reprint} +{.} { } {note} +{.} {} {transition} +{} {\SentenceSpace \PrintReviews} {review} } \BibSpec{conference}{% +{} {} {title} +{} {\PrintConferenceDetails} {transition} } \BibSpec{innerbook}{% +{,} { } {title} +{.} { } {part} +{:} { } {subtitle} +{,} { \PrintEdition} {edition} +{} { \PrintEditorsB} {editor} +{,} { \PrintTranslatorsC} {translator} +{,} { \PrintContributions} {contribution} +{,} { } {series} +{,} { \voltext} {volume} +{,} { } {publisher} +{,} { } {organization} +{,} { } {address} +{,} { \PrintDateB} {date} +{.} { } {note} } \BibSpec{report}{% +{} {\PrintPrimary} {transition} +{,} { \textit} {title} +{.} { } {part} +{:} { \textit} {subtitle} +{,} { \PrintEdition} {edition} +{,} { \PrintContributions} {contribution} +{,} { Technical Report } {number} +{,} { } {series} +{,} { } {organization} +{,} { } {address} +{,} { \PrintDateB} {date} +{,} { \eprint} {eprint} +{,} { } {status} +{} { \parenthesize} {language} +{} { \PrintTranslation} {translation} +{;} { \PrintReprint} {reprint} +{.} { } {note} +{.} {} {transition} +{} {\SentenceSpace \PrintReviews} {review} } \BibSpec{thesis}{% +{} {\PrintAuthors} {author} +{,} { \textit} {title} +{:} { \textit} {subtitle} +{,} { \PrintThesisType} {type} +{,} { } {organization} +{,} { } {address} +{,} { \PrintDateB} {date} +{,} { \eprint} {eprint} +{,} { } {status} +{} { \parenthesize} {language} +{} { \PrintTranslation} {translation} +{;} { \PrintReprint} {reprint} +{.} { } {note} +{.} {} {transition} +{} {\SentenceSpace \PrintReviews} {review} } % \end{macrocode} % % \begin{macrocode} \BibSpecAlias{periodical}{book} \BibSpecAlias{collection}{book} \BibSpecAlias{proceedings}{book} \BibSpecAlias{manual}{book} \BibSpecAlias{miscellaneous}{book} \BibSpecAlias{misc}{miscellaneous} \BibSpecAlias{unpublished}{book} \BibSpecAlias{proceedings.article}{collection.article} \BibSpecAlias{techreport}{report} % \end{macrocode} % % \begin{macro}{\setbib@incollection} % \begin{macrocode} \edef\setbib@incollection{% \@xp\@nx\csname setbib@collection.article\endcsname } % \end{macrocode} % \end{macro} % % \begin{macro}{\setbib@inproceedings} % \begin{macrocode} \edef\setbib@inproceedings{% \@xp\@nx\csname setbib@collection.article\endcsname } % \end{macrocode} % \end{macro} % % Some more entry types for implementing abbreviations. % \begin{macrocode} \BibSpec{name}{% +{} {\PrintAuthors} {name} } \BibSpec{publisher}{% +{,} { } {publisher} +{,} { } {address} } % \end{macrocode} % % \subsection{The \env{biblist} environment} % % The \env{biblist} environment can be used with a section or chapter % heading. % % Use a standard \lat/ counter for numbering bibliography items. % \begin{macrocode} \newcounter{bib} % \end{macrocode} % % \begin{environment}{biblist} % \begin{macrocode} \newenvironment{biblist}{% \setcounter{bib}\z@ \@biblist }{% \@endbiblist } % \end{macrocode} % \end{environment} % % \begin{environment}{biblist*} % \begin{macrocode} \newenvironment{biblist*}{% \@biblist }{% \@endbiblist } % \end{macrocode} % \end{environment} % % \begin{macro}{\@biblist} % \begin{macrocode} \newcommand\@biblist[1][]{% \stepcounter{bib@env} \normalfont \footnotesize \labelsep .5em\relax \list{\BibLabel}{% \restore@labelwidth \@maxlabelwidth\z@ \@nmbrlisttrue \def\@listctr{bib}% \let\makelabel\bib@mklab #1\relax }% \sloppy % \end{macrocode} % Discourage page breaks within bibliography entries and disable them % completely for entries that are less than four lines long. % \begin{macrocode} \interlinepenalty\@m \clubpenalty\@M \widowpenalty\clubpenalty \frenchspacing \ResetCapSFCodes } % \end{macrocode} % \end{macro} % % \begin{macro}{\@endbiblist} % Change error for empty list (no items) to warning, to allow authors % to leave their bibliography temporarily empty during writing: % \begin{macrocode} \def\@endbiblist{% \save@labelwidth \def\@noitemerr{\@latex@warning{Empty bibliography list}}% \endlist } % \end{macrocode} % \end{macro} % % \begin{macro}{\@maxlabelwidth} % \begin{macrocode} \newdimen\@maxlabelwidth % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@mklab} % \begin{macrocode} \def\bib@mklab#1{% \settowidth\@tempdima{#1}% \ifdim \@tempdima > \@maxlabelwidth \global\@maxlabelwidth\@tempdima \fi #1\hfil } % \end{macrocode} % \end{macro} % % \begin{macrocode} \newcounter{bib@env} % \end{macrocode} % % \begin{macro}{\save@labelwidth} % \begin{macrocode} \def\save@labelwidth{% \if@filesw \immediate\write\@auxout{% \string\newlabel{[bibenv:\the\c@bib@env]}{\the\@maxlabelwidth}% }% \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\restore@labelwidth} % \begin{macrocode} \def\restore@labelwidth{% \@xp\ifx \csname r@[bibenv:\the\c@bib@env]\endcsname \relax \resetbiblist{00}% \else \@xp\labelwidth\csname r@[bibenv:\the\c@bib@env]\endcsname \leftmargin\labelwidth \advance\leftmargin\labelsep \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\ResetCapSFCodes} % Presumably this is here because there has been a problem in the % past with packages that change the \cs{catcode}s of capital % letters. % \begin{macrocode} \providecommand{\ResetCapSFCodes}{% \count@=`\A \def\@tempa{% \sfcode\count@=\@m \advance\count@\@ne \ifnum\count@>`\Z\relax \expandafter\@gobble \fi \@tempa }% \@tempa } % \end{macrocode} % \end{macro} % % \begin{macro}{\CurrentBib} % In case this is undefined sometimes. % \begin{macrocode} \def\CurrentBib{??} % \end{macrocode} % \end{macro} % % \begin{macro}{\BibLabel} % \begin{macrocode} \newcommand{\BibLabel}{% [\hyper@anchorstart{cite.\CurrentBib}\relax\thebib\hyper@anchorend]% } % \end{macrocode} % \end{macro} % % \begin{macro}{\resetbiblist} % \begin{macrocode} \newcommand{\resetbiblist}[1]{% \settowidth\labelwidth{\def\thebib{#1}\BibLabel}% \leftmargin\labelwidth \ifdim\labelwidth=\z@ \leftmargin=1em \itemindent=-\leftmargin \else \advance\leftmargin\labelsep \fi } % \end{macrocode} % \end{macro} % % \subsection{Processing bibliography entries} % % There are several things one might want to do when a \cn{bib} entry % is encountered: % \begin{enumerate} % % \item Format and print it. This corresponds to the direct entry % of bibliography items as described in section~2.1 of the users's % guide. % % \item Copy it into a \fn{.bbl} file. This corresponds to the use % of \cn{bibselect} and an external \fn{.ltb} database as described % in section~2.2 of the user's guide. % % \item Store the full information in memory. This is done by % \cn{bib*}. % % \end{enumerate} % % \begin{macro}{\bib} % Here is where the rubber hits the road. % \begin{macrocode} \newcommand{\bib}{% \begingroup \@ifstar{% \@tempswatrue \let\@bibdef\star@bibdef \BibItem }{% \@tempswafalse \BibItem }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\BibItem} % \MacroArgs % \macroarg{1}{citekey} % \macroarg{2}{bibtype} % \begin{macrocode} \newcommand{\BibItem}[2]{% \def\@tempa{#1}% \edef\@tempb{% \@nx\@bibdef\@xp\@nx\csname setbib@#2\endcsname{#2}% {\macrotext\@tempa}% }% \@tempb } % \end{macrocode} % \end{macro} % % \begin{macro}{\@bibdef} % \cs{@bibdef} is a pointer to the procedure that should be handed % the entry's key-value pairs. It has one of four values: % \begin{enumerate} % % \item \cs{star@bibdef} % % \item \cs{normal@bibdef} % % \item \cs{copy@bibdef} % % \item \cs{selective@bibdef} % % \end{enumerate} % \MacroArgs % \macroarg{1}{\cs{setbib@}bibtype} % \macroarg{2}{bibtype} % \macroarg{3}{citekey} % \begin{macrocode} \AtBeginDocument{\let\@bibdef\normal@bibdef} % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@exec} % And \cs{bib@exec} is a pointer to the procedure that % \cs{normal@bibdef} will invoke to process the key-value pairs % after they've been parsed. It has one % of these values: % \begin{enumerate} % % \item \cs{bib@store} % % \item \cs{bib@print} % % \end{enumerate} % \MacroArgs % \macroarg{1}{citekey} % \macroarg{2}{\cs{the}\cs{rsk@toks}} % \macroarg{3}{\cs{setbib@}bibtype} % \begin{macrocode} \AtBeginDocument{\let\bib@exec\bib@print} % \end{macrocode} % \end{macro} % % \subsubsection{\cs{@bibdef} Implementations} % % \begin{macro}{\normal@bibdef} % \MacroArgs % \macroarg{1}{\cs{setbib@}bibtype} % \macroarg{2}{bibtype} % \macroarg{3}{citekey} % \begin{macrocode} \def\normal@bibdef#1#2#3{% % \end{macrocode} % \cs{CurrentBibType} is used by \pkg{export-bibtex}, but there % might be a better way to handle it. (dmj) % \begin{macrocode} \def\CurrentBibType{#2}% \ifx\relax#1% \amsrefs@error{Undefined entry type: #2}\@ehc \let#1\setbib@misc \fi \RestrictedSetKeys{}{bib}% {\bib@exec{#3}{\the\rsk@toks}{#1}\endgroup}% } \let\@bibdef\normal@bibdef % \end{macrocode} % \end{macro} % % \begin{macro}{\star@bibdef} % \MacroArgs % \macroarg{1}{\cs{setbib@}bibtype} % \macroarg{2}{bibtype} % \macroarg{3}{citekey} % \begin{macrocode} \def\star@bibdef{% \let\bib@exec\bib@store \normal@bibdef } % \end{macrocode} % \end{macro} % % \begin{macro}{\copy@bibdef} % This is a variation that copies everything into the \fn{.bbl} % file. Used by \cn{bibselect*} and \cn{bib*} inside \fn{.ltb} % files. % \begin{macrocode} \def\copy@bibdef{% \if@tempswa \@xp\defer@bibdef \else \@xp\copy@bibdef@a \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\copy@bibdef@a} % \begin{macrocode} \def\copy@bibdef@a#1#2#3#4{% \@open@bbl@file \process@xrefs{#4}% \bbl@write{% \string\bib\if@tempswa*\fi{#3}{#2}\string{\iffalse}\fi }% % \end{macrocode} % Since we're supplying our own definition of \cs{rsk@set}, we % don't actually need the group argument, so we leave it out to % save a few tokens. % \begin{macrocode} \RestrictedSetKeys{\global\let\rsk@set\bbl@copy}\@empty {\bbl@write{\iffalse{\fi\string}^^J}% \endgroup}{#4}% } % \end{macrocode} % \end{macro} % % \begin{macrocode} \catcode`\:=11 \def\modify@xref@fields{% \let\set:bib'author\output@xref@a \let\set:bib'editor\output@xref@a \let\set:bib'translator\output@xref@a \let\set:bib'journal\output@xref@a \let\set:bib'publisher\output@xref@a \def\set:bib'xref##1##2{\output@xref@{##1}\@empty}% \def\set:bib'book##1##2{\output@inner@xref@{##1}\@empty}% \let\set:bib'conference\set:bib'book \let\set:bib'partial\set:bib'book \let\set:bib'reprint\set:bib'book \let\set:bib'translation\set:bib'book } \catcode`\:=12 \def\process@xrefs#1{% \begingroup \RestrictedSetKeys{\modify@xref@fields}{bib}{\the\rsk@toks}{#1}% \endgroup } \def\output@xref@a#1#2{% \def\@tempa{#1}% \lowercase{\def\@tempb{#1}}% \ifx\@tempa\@tempb \output@xref@{#1}% \fi } \def\output@xref@#1{% \@ifnotempty{#1}{% \@ifundefined{bi@#1}{}{% \begingroup \let\star@bibdef\copy@bibdef@a \csname bi@#1\endcsname \endgroup }% \@xp\g@undef\csname bi@#1\endcsname }% } \def\output@inner@xref@#1{% \in@={#1}% \ifin@\else \output@xref@{#1}% \fi } % \end{macrocode} % % \begin{macro}{\bbl@copy} % \begin{macrocode} \def\bbl@copy#1\endcsname#2{% \begingroup \def\@tempa{#1}% \toks@{{#2}}% \star@{\bbl@copy@a}{}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\bbl@copy@a} % \begin{macrocode} \def\bbl@copy@a#1{% \@ifnotempty{#1}{% \add@toks@{*{#1}}% }% \bbl@write{ \space\@tempa=\the\toks@,}% \endgroup \rsk@resume } % \end{macrocode} % \end{macro} % % \begin{macro}{\selective@bibdef} % This is a variation that ignores anything not having a known % citation key. Used by \cn{bibselect}. % % \MacroArgs % \macroarg{1}{\cs{setbib@}bibtype} % \macroarg{2}{bibtype} % \macroarg{3}{citekey} % \begin{macrocode} \def\selective@bibdef#1#2#3{% \@xp\selbibdef@a\csname b@#3\endcsname{#1}{#2}{#3}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\selbibdef@a} % \begin{macrocode} \def\selbibdef@a#1{% \def\@tempa{\endgroup\@gobblefour}% \ifx\relax#1\else \@xp\selbibdef@b#1\@nil \fi \@tempa } % \end{macrocode} % \end{macro} % % \begin{macro}{\selbibdef@b} % \begin{macrocode} \def\selbibdef@b#1#2#3\@nil{% \ifx 1#2\let\@tempa\copy@bibdef\fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\defer@bibdef} % This is a variation that ignores anything not having a known % citation key. Used by \cn{bibselect}. % % \MacroArgs % \macroarg{1}{\cs{setbib@}bibtype} % \macroarg{2}{bibtype} % \macroarg{3}{citekey} % \macroarg{4}{key-val pairs} % \begin{macrocode} \def\defer@bibdef#1#2#3#4{% \@xp\gdef\csname bi@#3\endcsname{% \bib*{#3}{#2}{#4}% }% \@xp\addto@defer@list \csname bi@#3\endcsname \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\bibdefer@list} % \begin{macrocode} \let\bibdefer@list\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\addto@defer@list} % \begin{macrocode} \def\addto@defer@list#1{% \begingroup \def\do{\@nx\do\@nx}% \xdef\bibdefer@list{\bibdefer@list\do#1}% \endgroup } % \end{macrocode} % \end{macro} % % \subsubsection{\cs{bib@exec} Implementations} % % \begin{macro}{\bib@store} % This is the easy one. It just stores the entire set of key-value % pairs in \cs{bi@}\emph{citekey}. % \begin{macrocode} \def\bib@store#1{% \afterassignment\@gobble \@xp\xdef\csname bi@#1\endcsname } % \end{macrocode} % \end{macro} % % \begin{macro}{\numeric@refs} % \begin{macrocode} \def\numeric@refs{00} % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@print} % \MacroArgs % \macroarg{1}{citekey} % \macroarg{2}{\cs{the}\cs{rsk@toks}} % \macroarg{3}{\cs{setbib@}bibtype} % \begin{macrocode} \def\bib@print#1#2#3{% \bib@start{#1}% \let\setbib@@#3% #2\relax % execute definitions locally \bib@resolve@xrefs \bib@field@patches \bib@selectlanguage \generate@label \bib'setup \bib@cite{#1}% \kern\@ne sp \ifx\setbib@@\setbib@article \ifx\bib'booktitle\@empty \ifx\bib'book\@empty \ifx\bib'conference\@empty \else \let\setbib@@\setbib@incollection \fi \else \let\setbib@@\setbib@incollection \fi \else \let\setbib@@\setbib@incollection \fi \fi \setbib@@ \bib@end } % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@print@inner} % Note that the order of the arguments is reversed with respect to % \cs{bib@print}. Maybe that isn't such a great idea. % \MacroArgs % \macroarg{1}{\cs{setbib@}bibtype} % \macroarg{2}{\cs{the}\cs{rsk@toks}} % \begin{macrocode} \def\bib@print@inner#1#2{% \begingroup #2\relax % execute definitions locally \bib@resolve@xrefs \bib@field@patches \bib'setup #1% \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\current@citekey} % \begin{macrocode} \let\current@citekey\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\prev@citekey} % \begin{macrocode} \let\prev@citekey\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@start} % There used to be more to it. % \begin{macrocode} \def\bib@start#1{% \begingroup \def\current@citekey{#1}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@end} % Instead of being handled by \cs{bib@end}, ending punctuation is % normally handled via the \fld{transition} field (q.v.) % \begin{macrocode} \def\bib@end{% \relax \@xp\PrintBackRefs\@xp{\CurrentBib}% \par \save@primary \global\let\prev@citekey\current@citekey \endgroup } % \end{macrocode} % \end{macro} % % \subsubsection{Resolving cross-references} % % \begin{macro}{\bib@resolve@xrefs} % \begin{macrocode} \def\bib@resolve@xrefs{% \xref@check@c\bib'xref \xref@check@a\bib'author \xref@check@a\bib'editor \xref@check@a\bib'translator \xref@check@b\bib'journal \xref@check@b\bib'publisher } % \end{macrocode} % \end{macro} % % \begin{macro}{\xref@check@a} % Resolve a contributor (typically a \cn{DefineName}) alias. % Requires rebuilding the list. % \begin{macrocode} \def\xref@check@a#1{% \ifx\@empty#1\relax \else \begingroup \toks@\@emptytoks \@temptokenb\@emptytoks \series@index\z@ \def\name{\xref@check@aa#1}% #1\relax \edef\@tempa{% \def\@nx#1{\the\toks@}% \the\@temptokenb }% \@xp\endgroup \@tempa \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\xref@check@aa} % \begin{macrocode} \def\xref@check@aa#1#2{% \advance\series@index\@ne \def\@tempa{#2}% \lowercase{\def\@tempb{#2}}% \ifx\@tempa\@tempb \ifx\@tempa\@empty \add@toks@{\name{}}% \else \@ifundefined{bi@#2}{% \BibAbbrevWarning{#2}% \add@toks@{\name{#2}}% }{% \xref@check@ab#1{#2}% }% \fi \else \add@toks@{\name{#2}}% \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\xref@check@ab} % \begin{macrocode} \def\xref@check@ab#1#2{% \csname bi@#2\endcsname \ifx\@empty\bib'name \@temptokena{#2}% \else \@temptokena\@xp{\bib'name}% \get@property\@tempa\bib'name \edef\@tempa{% \@nx\addto@hook\@temptokenb{% \@nx\reset@nth@property\@nx#1\the\series@index{\@tempa}% }% }% \@tempa \fi \edef\@tempa{\@nx\add@toks@{\@nx\name{\the\@temptokena}}}% \@tempa } % \end{macrocode} % \end{macro} % % \begin{macro}{\xref@check@b} % Resolve a \fld{journal} or \fld{publisher} alias (typically a % \cn{DefinePublisher} or \cn{DefineJournal} alias). % \begin{macrocode} \def\xref@check@b#1{% \ifx\@empty#1% \else \toks@\@xp{#1}% \edef\@tempb{\lowercase{\def\@nx\@tempa{\the\toks@}}}% \@tempb \ifx\@tempa#1\relax % all lowercase \@ifundefined{bi@#1}{% \BibAbbrevWarning{#1}% }{% % \end{macrocode} % We pass control to \cs{xref@check@c} here to handle inheritance % of multiple fields properly. This means some of the checking % we've just done gets done again, but I can live with that. % \begin{macrocode} \let#1\@empty \xref@check@c\@tempa }% \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\xref@check@c} % Resolve an \fld{xref} field. % \begin{macrocode} \def\xref@check@c#1{% \ifx#1\@empty \else \begingroup \@apply\auto@protect\amsrefs@textsymbols \@apply\auto@protect\amsrefs@textaccents \let\DSK@def\xref@add@toks \let\DSK@append\xref@append \toks@\@emptytoks \let\bib@reset\@empty % \end{macrocode} % The \cs{@for} here is just a fancy way of expanding \arg{1}. (Or % is it?) % \begin{macrocode} \@for\xref@ID:=#1\do{% \@ifundefined{bi@\xref@ID}{% \XRefWarning{\xref@ID}% }{% \csname bi@\xref@ID\endcsname }% }% \edef\@tempa{\endgroup\the\toks@}% \@tempa \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\xref@add@toks} % If any title occurs in an \fld{xref}ed item, assume that it is a book % title. This might not always be the best assumption? Let's see how % it goes though. [mjd,2001-12-11] % % \MacroArgs % \macroarg{1}{\cs{bib'}field} % \macroarg{2}{value} % \begin{macrocode} \def\xref@add@toks#1#2#3{% \ifx#1\@empty \edef\@tempa{% \@nx\add@toks@{\@xp\@nx\csname\rkv@setter#1\endcsname{#2}{#3}}% }% \@tempa \else \in@\bib'title{#1}% \ifin@ \ifx\bib'booktitle\@empty \edef\@tempa{% \@nx\add@toks@{% \@xp\@nx\csname set:bib'booktitle\endcsname }% }% \@tempa \add@toks@{{#2}{#3}}% \fi \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macrocode} \def\xref@append#1#2#3#4{% \edef\@tempa{% \@nx\add@toks@{\@xp\@nx\csname\rkv@setter#2\endcsname{#3}{#4}}% }% \@tempa } % \end{macrocode} % % \begin{macro}{\BibAbbrevWarning} % \begin{macrocode} \def\BibAbbrevWarning#1{\amsrefs@warning{Abbreviation '#1' undefined}} % \end{macrocode} % \end{macro} % % \begin{macro}{\XrefWarning} % \begin{macrocode} \def\XRefWarning#1{\amsrefs@warning{Xref '#1' undefined}} % \end{macrocode} % \end{macro} % % \subsubsection{Bib field preprocessing} % % \begin{macro}{\current@primary} % \begin{macrocode} \let\current@primary\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\previous@primary} % \begin{macrocode} \let\previous@primary\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\save@primary} % \begin{macrocode} \IfOption{nobysame}{% \let\save@primary\@empty }{% \def\save@primary{% \global\let\previous@primary\current@primary }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@field@patches} % Depending on your point of view, this macro either puts the % bibitem into a canonical form or, alternatively, it fudges the % data to fit our model. Either way, it simplifies formatting the % bibliography. % \begin{macrocode} \def\bib@field@patches{% \ifx\bib'author\@empty \ifx\bib'editor\@empty \let\current@primary\bib'translator \let\print@primary\PrintTranslatorsA \else \let\current@primary\bib'editor \let\print@primary\PrintEditorsA \fi \else \let\current@primary\bib'author \let\print@primary\PrintAuthors \fi \ifx\bib'address\@empty \let\bib'address\bib'place \fi \ifx\bib'organization\@empty \ifx\bib'institution\@empty \let\bib'organization\bib'school \else \let\bib'organization\bib'institution \fi \fi \ifx\bib'date\@empty \ifx\bib'year\@empty \let\bib@year\bib'status \else \bib@parsedate\bib'year \fi \else \bib@parsedate\bib'date \fi % \end{macrocode} % Example~21 on page~74 of \emph{Mathematics into % Type}~\cite{SOS99} seems to indicate that when the year serves as % the volume number, the date should be suppressed. If so, this is % where that is done. % \begin{macrocode} \def\@tempa{year}% \ifx\bib'volume\@tempa \let\bib'volume\bib@year \let\bib'date\@empty \fi % \end{macrocode} % Some journals have ``numbers'' but no ``volumes''. AMS house % style is to treat the number as volume. % \begin{macrocode} \ifx\setbib@@\setbib@article \ifx\bib'volume\@empty \ifx\bib'number\@empty\else \let\bib'volume\bib'number \let\bib'number\@empty \fi \fi \fi % \end{macrocode} % \cs{bib'language} is used for producing the printed rendition of % the language. \cs{bib@language} needs to be in the form required by % \cn{selectlanguage}. % \begin{macrocode} \bib@language@fixup } % \end{macrocode} % \end{macro} % % \subsubsection{Date setup} % % \begin{macro}{\bib@year} % \begin{macrocode} \let\bib@year\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@month} % \begin{macrocode} \let\bib@month\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@day} % \begin{macrocode} \let\bib@day\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@parsedate} % Parse an ISO 8601 date into its year, month and day components, % but without actually verifying that any of the components are % numeric. Hmmm. % \begin{macrocode} \def\bib@parsedate#1{% \@xp\bib@parsedate@a#1---\@nil } % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@parsedate@a} % \begin{macrocode} \def\bib@parsedate@a#1-#2-#3-#4\@nil{% \def\bib@year{#1}% \def\bib@month{#2}% \def\bib@day{#3}% % \end{macrocode} % The rest of this macro tries to rewrite \cs{bib'date} into a % normalized form. I'm not sure if this is a good idea. % \begin{macrocode} \ifx\@empty\bib@day \ifx\@empty\bib@month \let\bib'date\bib@year \else \def\bib'date{#1-#2}% \fi \else \def\bib'date{#1-#2-#3}% \fi } % \end{macrocode} % \end{macro} % % \subsubsection{Language setup} % % \begin{macro}{\bib@language@fixup} % \begin{macrocode} \def\bib@language@fixup{% \ifx\bib'hyphenation\@empty \ifx\bib'language\@empty \let\bib@language\biblanguagedefault \else \let\bib@language\bib'language \fi \else \let\bib@language\bib'hyphenation \fi \def\@tempa##1 ##2\@nil{\lowercase{\def\bib@language{##1}}}% % \end{macrocode} % The mysterious \cs{@firstofone} here is to preserve the space % before the \cs{@nil}. % \begin{macrocode} \@firstofone{\@xp\@tempa\bib@language} \@nil } % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@selectlanguage} % For \cn{bib} purposes we are interested mainly in testing whether % the hyphenation patterns are the same. So we use an % if-same-patterns test (by which \pkg{babel}'s `english' and % `american' compare as equal) rather than an if-same-language test. % Also, the way that the \cn{selectlanguage} command checks to see % whether a language has been properly defined for babel use is to % see if \cs{dateLANGUAGE} is defined. And if we tried to select an % undefined language, the result would be a \lat/ error. % \begin{macrocode} \def\bib@selectlanguage{% \@ifsame@patterns{\languagename}{\bib@language}{}{% \@ifundefined{date\bib@language}{}{% \@xp\selectlanguage\@xp{\bib@language}% }% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\@ifsame@patterns} % \begin{macrocode} \def\@ifsame@patterns#1#2{% \@xp\@ifsamepat\csname l@#1\@xp\endcsname\csname l@#2\endcsname } % \end{macrocode} % \end{macro} % % \begin{macro}{\@ifsamepat} % \begin{macrocode} \def\@ifsamepat#1#2{% \ifnum \ifx\relax#1\m@ne\else#1\fi = \ifx\relax#2\m@ne\else#2\fi \@xp\@firstoftwo \else \@xp\@secondoftwo \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\languagename} % \begin{macro}{\biblanguageEnglish} % \begin{macro}{\biblanguagedefault} % \begin{macro}{\bib@language} % \begin{macrocode} \providecommand{\languagename}{english} \def\biblanguageEnglish{english} \let\biblanguagedefault\biblanguageEnglish \let\bib@language\@empty % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \subsubsection{Citation label setup} % % \begin{macro}{\generate@label} % \begin{macrocode} \let\generate@label\relax % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@label} % \begin{macrocode} \def\cite@label{\@currentlabel} % \end{macrocode} % \end{macro} % % \begin{macro}{\alpha@label} % \begin{macrocode} \let\alpha@label\relax % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@cite} % When \cs{bib@cite} is called, author name and year are available % in \cs{bib@author} and \cs{bib@year}. % \MacroArgs % \macroarg{1}{citekey} % \begin{macrocode} \def\bib@cite#1{% \def\CurrentBib{#1}% \alpha@label % modify \thebib if necessary \item\leavevmode \SK@\SK@@label{#1}% \@xp\bib@cite@a\csname b@#1\endcsname \bibcite@write{#1}% } % \end{macrocode} % \end{macro} % % \begin{macrocode} \def\bib@cite@a#1{% \ifx\relax#1% \begingroup \auto@protect\etaltext \protected@edef\@tempa{% \gdef\@nx#1{% \@nx\citesel 01{\cite@label}{\bib@label@year}{}% }% }% \@xp\endgroup \@tempa \else \@xp\bib@cite@check\@xp#1#1\@empty\@empty\@empty\@empty\@empty \fi } % \end{macrocode} % % \begin{macro}{\bib@cite@check} % For the citation key we want to check if it is already defined. But % there is a slight problem. There is already one control % sequence in use for each bibliography entry, to store the label or % the author/year information needed by \cn{cite}. If we introduce % another control sequence to check whether a particular cite is % multiply defined, then we double the number of control sequences % used. For a large bibliography in a book this is fairly serious. % This is addressed by using a \cs{citesel} function. % % \MacroArgs % \macroarg{1}{\cs{b@}citekey} % \macroarg{2}{\cs{citesel}} % \macroarg{3}{cited?} % \macroarg{4}{used?} % \macroarg{5}{label} % \macroarg{6}{year} % \macroarg{7}{backrefs} % \begin{macrocode} \def\bib@cite@check#1#2#3#4#5#6#7{% \ifx 1#4\relax \DuplicateBibKeyWarning \else % \end{macrocode} % This has gotten \emph{way} out of hand. % \begin{macrocode} \begingroup \auto@protect\etaltext \@apply\auto@protect\amsrefs@textsymbols \@apply\auto@protect\amsrefs@textaccents \@tempswafalse \in@\CitePrintUndefined{#5}% \ifin@ \let\@tempa\@empty \else \def\@tempa{#5}% \fi \ifx\@tempa\@empty \else \@xp\ifx\@xp\@currentlabel\cite@label \edef\@tempb{\cite@label}% \else \let\@tempb\cite@label \fi \ifx\@tempa\@tempb \def\@tempa{#6}% \ifx\@tempa\bib@label@year \else \@tempswatrue \fi \else \@tempswatrue \fi \fi \if@tempswa \@ifempty{#6}{% \def\@tempa{#5}% \let\@tempb\cite@label }{% \def\@tempa{#5, #6}% \def\@tempb{\cite@label, \bib@label@year}% }% \amsrefs@warning{Citation label for \extr@cite#1 is changing from `\@tempa ' to `\@tempb '}% \fi \protected@edef\@tempa{% \gdef\@nx#1{% \@nx\citesel #31{\cite@label}{\bib@label@year}{#7}% }% }% \@xp\endgroup \@tempa \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@label@year} % \begin{macrocode} \let\bib@label@year\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\DuplicateBibKeyWarning} % \begin{macrocode} \def\DuplicateBibKeyWarning{% \amsrefs@warning{% Duplicate \protect\bib\space key `\CurrentBib ' detected\MessageBreakNS}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\bibcite@write} % \begin{macrocode} \def\bibcite@write#1{% \if@filesw \begingroup \let\citesel\citesel@write \csname b@#1\endcsname \endgroup \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\citesel@write} % \begin{macrocode} \def\citesel@write#1#2#3#4#5{% \toks@{{#3}{#4}}% \immediate\write\@auxout{\string\bibcite{\CurrentBib}{\the\toks@}}% } % \end{macrocode} % \end{macro} % % Because duplicate bibs are caught immediately, we don't need % \cs{bibcite} to run \cs{@testdef}. % \begin{macrocode} \AtEndDocument{\let\bibcite\@gobbletwo} % \end{macrocode} % % \subsubsection{Printing the bibliography} % % \begin{macro}{\bibname} % \begin{macrocode} \providecommand{\bibname}{Bibliography} % \end{macrocode} % \end{macro} % % \begin{macro}{\refname} % \begin{macrocode} \providecommand{\refname}{References} % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@div@mark} % The AMS document classes automatically take care of the page % marks for \cn{section*} and \cn{chapter*}, but for the standard % classes, we need to make sure that \cn{@mkboth} gets invoked. % \begin{macrocode} \let\bib@div@mark\@gobble % \end{macrocode} % This is verbose, but probably safer than any alternative. % \begin{macrocode} \@ifclassloaded{amsbook}{}{% \@ifclassloaded{amsart}{}{% \@ifclassloaded{amsproc}{}{% \def\bib@div@mark#1{% \@mkboth{\MakeUppercase{#1}}{\MakeUppercase{#1}}% }% }% }% } % \end{macrocode} % \end{macro} % % \begin{environment}{bibchapter} % We need to take a little extra trouble here to pre-expand the % \cn{bibname}. % \begin{macrocode} \newenvironment{bibchapter}[1][\bibname]{% \begingroup \protected@edef\@{% \endgroup \protect\chapter*{#1}% \protect\bib@div@mark{#1}% }% \@ }{\par} % \end{macrocode} % \end{environment} % % \begin{environment}{bibsection} % And here to pre-expand the \cn{refname}. % \begin{macrocode} \newenvironment{bibsection}[1][\refname]{% \begingroup \protected@edef\@{% \endgroup \protect\section*{#1}% \protect\bib@div@mark{#1}% }% \@ }{\par} % \end{macrocode} % \end{environment} % % \begin{environment}{bibdiv} % Here we try to guess whether this is a book-like document or an % article-like document. % \begin{macrocode} \@ifundefined{chapter}{% \newenvironment{bibdiv}{\bibsection}{\endbibsection} }{% \newenvironment{bibdiv}{\bibchapter}{\endbibchapter} } % \end{macrocode} % \end{environment} % % This is what the standard \cls{book} class has for the bibliography % title: % \begin{verbatim} % \newenvironment{thebibliography}[1] % {\chapter*{\bibname % \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}}% % \list{\@biblabel{\@arabic\c@enumiv}}% %\end{verbatim} % % \begin{environment}{thebibliography} % \begin{macrocode} \renewenvironment{thebibliography}[1]{% \bibdiv \biblist[\resetbiblist{#1}]% }{% \endbiblist \endbibdiv } % \end{macrocode} % \end{environment} % % \subsection{Name, journal and publisher abbreviations} % % The commands \cn{DefineName}, \cn{DefinePublisher}, and % \cn{DefineJournal} are provided to make abbreviations a little % easier. % % \begin{macro}{\DefineName} % \begin{macrocode} \newcommand{\DefineName}[2]{% \bib*{#1}{name}{name={#2}}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\DefineJournal} % \begin{macrocode} \newcommand{\DefineJournal}[4]{% \bib*{#1}{periodical}{ issn={#2}, journal={#4} }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\DefinePublisher} % Note that an explicit \fld{address} field in a \cn{bib} entry will % override the \fld{address} supplied as part of a % \cn{DefinePublisher}. % \begin{macrocode} \newcommand{\DefinePublisher}[4]{% \bib*{#1}{publisher}{% publisher={#3}, address={#4} }% } % \end{macrocode} % \end{macro} % % \subsection{Processing \fn{.ltb} files} % % If you have a file that contains \pkg{amsrefs}-style % \cn{bib} entries, you can use it as a database and extract items % from it for use in another document. In typical relatively simple % scenarios, the extraction can be done by \lat/ itself on the first % pass, so that citations in the text will be successfully resolved % on the second pass (possibly even the first, depending on what kind % of bibliography sorting is used). % % \begin{macro}{\bibselect} % \begin{macrocode} \newcommand{\bibselect}{% \@ifstar{% \let\@bibdef\copy@bibdef \BibSelect }{% \let\@bibdef\selective@bibdef \BibSelect }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\BibSelect} % \begin{macrocode} \newcommand{\BibSelect}[2][\bblname]{% \if@filesw \typeout{Trying to create bbl file `#1.bbl' ...}% \def\bibselect@msg{% \typeout{ ... rats. Unable to create bbl file.}% }% \let\@open@bbl@file\OpenBBLFile \@for\@tempa:=#2\do{\ReadBibData{\@tempa}}% \fi \@close@bbl@file \@apply\g@undef\bibdefer@list \global\let\bibdefer@list\@empty % \end{macrocode} % Now read the \fn{.bbl} file we just created. % \begin{macrocode} \let\@bibdef\normal@bibdef \@input@{#1.bbl}% \let\BibSelect\MultipleBibSelectWarning } % \end{macrocode} % \end{macro} % % \begin{macro}{\MultipleBibSelectWarning} % \begin{macrocode} \newcommand\MultipleBibSelectWarning[2][]{% \amsrefs@warning{% Multiple \string\bibselect 's found (only one \string\bibselect\space per biblist environment is allowed)% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\bblname} % \begin{macrocode} \def\bblname{\jobname} % \end{macrocode} % \end{macro} % % \begin{macro}{\bib@dbfile} % \begin{macrocode} \newread\bib@dbfile % \end{macrocode} % \end{macro} % % \begin{macro}{\ReadBibData} % \begin{macrocode} \newcommand{\ReadBibData}[1]{% \IfFileExists{#1.ltb}{% \openin\bib@dbfile=\@filef@und \relax }{% \IfFileExists{#1.ltx}{% \openin\bib@dbfile=\@filef@und \relax }{% \IfFileExists{#1.tex}{% \openin\bib@dbfile=\@filef@und \relax }{% \begingroup \NoBibDBFile{#1}% \let\ReadBibData@a\endgroup }% }% }% \ReadBibData@a } % \end{macrocode} % \end{macro} % % \begin{macro}{\NoBibDBFile} % \begin{macrocode} \def\NoBibDBFile#1{% \amsrefs@warning{No data file #1.ltb (.ltx, .tex) found}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\ReadBibData@a} % \begin{macrocode} \def\ReadBibData@a{% \ProvidesFile{\@filef@und}\relax \begingroup \let\star@bibdef\defer@bibdef \ReadBibLoop \endgroup \closein\bib@dbfile } % \end{macrocode} % \end{macro} % % \begin{macro}{\ReadBibLoop} % \begin{macrocode} \def\ReadBibLoop{% \ifeof\bib@dbfile \@xp\@gobble \else \read\bib@dbfile to\CurLine % \end{macrocode} % The \cs{@empty} is in case \cs{CurLine} is empty. % \begin{macrocode} \@xp\ReadBibLoop@a\CurLine\@empty\@nil \fi \ReadBibLoop } % \end{macrocode} % \end{macro} % % \begin{macro}{\ReadBibLoop@e} % This traps top-level \cn{bib} commands. Note that: % \begin{itemize} % % \item % If \cs{CurLine} doesn't contain a complete \cn{bib} entry, the % code chokes. % % \item % I \cn{bib} is not the very first non-space token in a line, it % will not be recognized. % % \end{itemize} % % \begin{macrocode} \long\def\ReadBibLoop@a#1#2\@nil{% \ifx\bib#1% \CurLine % just exec it \else % \end{macrocode} % We're not done yet. The line may contain something like % \cn{DefineName}, so we need to expand the first macro in the line % and see if it starts with \cn{bib}. But first we check to make % sure that the token we're about to expand isn't \cn{endinput}. % \begin{macrocode} \ifx\endinput#1% \let\ReadBibLoop\@empty \else % \end{macrocode} % And this \cs{@empty} is for the admittedly unlikely case that % \cs{CurLine} isn't empty, but its expansion is. % \begin{macrocode} \@xp\ReadBibLoop@b#1#2\@empty\@nil \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\ReadBibLoop@b} % \begin{macrocode} \long\def\ReadBibLoop@b#1#2\@nil{% \ifx\bib#1% \CurLine % just exec it \fi } % \end{macrocode} % \end{macro} % % \begin{macrocode} \let\bbl@out=\relax \let\bbl@write\@gobble \let\@open@bbl@file\relax \let\@close@bbl@file\relax % \end{macrocode} % % \begin{macro}{\OpenBBLFile} % \begin{macrocode} \def\OpenBBLFile{% \if@filesw % Just use the next unused output stream \count@\count17 \advance\count@\@ne \ifnum\count@<\sixt@@n \global\chardef\bbl@out=\count@ \immediate\openout\bbl@out=\bblname.bbl\relax \global\let\@close@bbl@file\CloseBBLFile \gdef\bbl@write{\immediate\write\bbl@out}% \else \ch@ck\count@\sixt@@n\write \fi \fi \global\let\@open@bbl@file\relax } % \end{macrocode} % \end{macro} % % \begin{macro}{\CloseBBLFile} % \begin{macrocode} \def\CloseBBLFile{% \immediate\closeout\bbl@out\relax \global\let\@close@bbl@file\relax \global\let\bbl@write\@gobble \global\let\bbl@out\relax } % \end{macrocode} % \end{macro} % % \subsection{Citation processing} % % \subsubsection{The \cs{citesel} structure} % % The information used by \cn{cite} for key \texttt{moo} is stored in % \cs{b@moo} in the form % \begin{verbatim} % \citesel{status1}{status2}{label}{year}{backref-info} %\end{verbatim}% % % The first status flag is~1 if this key has already been cited % earlier in the same document; 0~otherwise. This is used in some % bibliography schemes to print a full list of author names for the first % citation and an abbreviated author list for subsequent citations. % % The second status flag is~1 if this key has already been used by a % define-cite command (such as \cn{bib}); 0~otherwise. This makes it % possible to issue a warning message as soon as the conflict is seen, % on the first \lat/ run, instead of on a subsequent run during the % processing of the \fn{.aux} file. % % When an author/year citation scheme is in use, args 3 and~4 hold % respectively author names and year. Otherwise arg~3 simply holds % a cite label and arg~4 is empty. % % And finally, arg~5 holds a list of backref pointers indicating the % locations in the document where this entry has been cited. % % \begin{macro}{\citesel@update} % \begin{macrocode} \def\citesel@update#1#2#3#4#5#6{% \gdef#6{\citesel 1#2{#3}{#4}{#5}}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\citesel@number} % \begin{macrocode} \def\citesel@number#1#2#3#4#5{#3} % \end{macrocode} % \end{macro} % % \begin{macro}{\citesel@year} % \begin{macrocode} \def\citesel@year#1#2#3#4#5{#4} % \end{macrocode} % \end{macro} % % \begin{macro}{\citesel} % \begin{macrocode} \let\citesel\citesel@number % \end{macrocode} % \end{macro} % % \subsubsection{The basic \cn{cite} command} % % Here is the difference between the various optional forms of % \cn{cite}: % \begin{verbatim} % \cite{xyz} -> \cite@a\citesel{xyz}{} % -> \cite@bc\b@xyz\citesel{} % % \cite{xyz}*{blub} -> \cite@a\citesel{xyz}{blub} % -> \cite@bc\b@xyz\citesel{blub} % % \cite[blub]{xyz} -> \cite@a\citesel{xyz}{blub} % -> \cite@bc\b@xyz\citesel{blub} %\end{verbatim} % % Canceling the old \lat/ definition of \verb*'\cite ' prevents % certain problems that could arise with the \pkg{showkeys} package. % \begin{macrocode} \expandafter\let\csname cite \endcsname\relax % \end{macrocode} % % \begin{macro}{\cite} % Need to handle the standard [...] option for compatibility's sake. % \begin{macrocode} \renewcommand{\cite}[2][]{% \if\cite@single#2,\@gobble \else\MultipleCiteKeyWarning{#2}{#1}\fi \@ifempty{#1}{% \cites@o{#2}% }{% \ObsoleteCiteOptionWarning \cites@a{*{#1}}{#2}% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\MultipleCiteKeyWarning} % \begin{macrocode} \def\MultipleCiteKeyWarning#1#2{% \amsrefs@warning{% Use of \string\cites\space is recommended instead of % \string\cite\space\MessageBreak for multiple cites '#1'}% \@ifnotempty{#2}{% \amsrefs@warning{Star option requires \string\citelist\space here}% }% \global\let\MultipleCiteKeyWarning\@gobbletwo } % \end{macrocode} % \end{macro} % % \begin{macro}{\ObsoleteCiteOptionWarning} % \begin{macrocode} \def\ObsoleteCiteOptionWarning{% \amsrefs@warning{% The form \string\cite{...}*{...} is recommended\MessageBreak instead of \string\cite[...]{...}}% \global\let\ObsoleteCiteOptionWarning\@empty } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@single} % \begin{macrocode} \edef\cite@single#1,#2{\iffalse{\fi\iffalse{\fi\string}#2.\string}} % \end{macrocode} % \end{macro} % % \begin{macro}{\cites@o} % \begin{macrocode} \def\cites@o#1{\star@{\cites@oo{#1}}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\cites@oo} % \begin{macrocode} \def\cites@oo#1#2{\@ifempty{#2}{\cites@a{}{#1}}{\cites@a{*{#2}}{#1}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\cites@a} % \begin{macrocode} \def\cites@a#1#2{% \begingroup \toks@{\endgroup \cites@b{#1}}% \vdef\@tempa{#2}% \edef\@tempa{% \the\toks@ \@firstofone{\@xp\zap@space\@tempa} \@empty }% \@tempa,\@empty \edef\@tempa{\endgroup\@nx\citelist{\the\toks@}}% \@tempa } % \end{macrocode} % \end{macro} % % \begin{macro}{\cites@b} % \begin{macrocode} \def\cites@b#1#2,#3{% \begingroup \toks@{\InnerCite{#2}#1}% \ifx\@empty#3\@xp\@gobble\fi \cites@c#3% } % \end{macrocode} % \end{macro} % % \begin{macro}{\cites@c} % \begin{macrocode} \def\cites@c#1,#2{% \add@toks@{\InnerCite{#1}}% \ifx\@empty#2\@xp\@gobble\fi \cites@c#2% } % \end{macrocode} % \end{macro} % % \begin{macro}{\citeleft} % \begin{macro}{\citeright} % \begin{macro}{\citemid} % \begin{macro}{\citepunct} % These variables are named to follow the precedent set by % Arseneau's \pkg{cite} package. \cs{citemid} is used to separate a % citation label from additional information such as \qq{Theorem % 4.9}. \cs{citepunct} is used to separate multiple cites, unless % one of the cites has additional associated information, in which % case \cs{CiteAltPunct} is used. % \begin{macrocode} \def\citeleft{[} \def\citeright{]} % \end{macrocode} % \begin{macrocode} \def\citemid{,\penalty9999 \space} \def\citepunct{,\penalty9999 \hskip.13em plus.1em minus.05em\relax} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\citeAltPunct} % When a citation list contains one or more citations with optional % arguments, we replace \cs{citemid} by \cs{CiteAltPunct}. % \begin{macrocode} \def\citeAltPunct{;\ } % \end{macrocode} % \end{macro} % % \begin{macro}{\citeform} % This is used for formatting the citation label. It can be used, % for example, to bolden the labels (as in \cls{amsbook} and % \cls{amsproc}) or to do more elaborate things such as convert the % numbers to roman numerals. By default, it's just a no-op. % % Note that currently there is no corresponding macro for changing % the formatting of \cn{cite}'s optional argument. This is % probably a bug. % \begin{macrocode} \providecommand{\citeform}{\@firstofone} % \end{macrocode} % \end{macro} % % \begin{macro}{\citelist} % The \cs{@citelist} indirection turns out to be helpful in % implementing the \cs{ocites} command for the \opt{author-year} % option. % \begin{macrocode} \DeclareRobustCommand{\citelist}{\@citelist} % \end{macrocode} % \end{macro} % % \begin{macro}{\@citelist} % \begin{macrocode} \def\@citelist#1{% \leavevmode \begingroup \@citestyle \citeleft\nopunct % suppress first \citepunct \cite@begingroup \in@*{#1}% \ifin@ \let\citepunct\citeAltPunct \fi \let\cite@endgroup\@empty \cites@init \def\citeleft{\@addpunct{\citepunct}}% \let\citeright\ignorespaces \def\cite{\InnerCite}% \process@citelist{#1}% \endgroup \citeright \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\@citestyle} % Reset the font to an upright, medium font (e.g. \fnt{cmr}), per % AMS style. Also set $\cs{mathsurround} = 0\,\mathrm{pt}$ just in % case there are subscripts in the cite numbers (from % \cn{etalchar}, for example). % \begin{macrocode} \providecommand{\@citestyle}{\m@th\upshape\mdseries} % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@begingroup} % Grouping that encloses an entire cite block (a single cite or a % list of cites). % \begin{macrocode} \def\cite@begingroup{\begingroup\let\cite@begingroup\relax} % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@endgroup} % \begin{macrocode} \let\cite@endgroup\endgroup % \end{macrocode} % \end{macro} % % \begin{macro}{\cites@init} % This needs to be called at the beginning of a list of cites to % reset a few things. % \begin{macrocode} \def\cites@init{% \gdef\prev@names{???}% \let\cites@init\@empty } % \end{macrocode} % \end{macro} % % \begin{macro}{\InnerCite} % \begin{macrocode} \newcommand{\InnerCite}[1]{\star@{\cite@a\citesel{#1}}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@a} % The job of \cs{cite@a} is to convert the cite key to all catcode-12 % characters and remove any spaces it might contain before passing % it on to \cs{cite@b}. % % \MacroArgs % \macroarg{1}{\cs{CITESEL}} % \macroarg{2}{citekey} % \begin{macrocode} \def\cite@a#1#2{% \BackCite{#2}% \cite@begingroup \cites@init \let\citesel#1\relax \ifx\citesel\citesel@author \let\citeleft\@empty \let\citeright\@empty \fi \begingroup \toks@{\endgroup \cite@b}% \vdef\@tempa{#2}% \edef\@tempa{% \the\toks@{\@firstofone{\@xp\zap@space\@tempa} \@empty}% }% \@tempa } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@b} % \MacroArgs % \macroarg{1}{citekey} % \macroarg{2}{star-optional-arg} % \begin{macrocode} \def\cite@b#1#2{% \@xp\cite@bc\csname b@#1\@xp\endcsname {#1}{#2}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@bc} % If it's uninitialized, plug in an empty cite structure. % \cs{cite@bc} should be executed only once for a given instance of a % cite key. All further processing should go through \cs{cite@cj}. % \begin{macrocode} \def\cite@bc#1#2{% \ifx#1\@@undefined \global\let#1\relax \fi \ifx#1\relax \global\let#1\empty@cite \fi \@xp\cite@nobib@test#1{}{}{}{}\@nil#1% \cite@cj#1% } % \end{macrocode} % \end{macro} % % \begin{macro}{\empty@cite} % \begin{macrocode} \def\empty@cite{\citesel 00{}{}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@nobib@test} % If arg 4 is empty, it means there wasn't any \cn{bib} command that % defined a valid label. % % \MacroArgs % \macroarg{1}{\cs{citesel}} % \macroarg{2}{cited?} % \macroarg{3}{used?} % \macroarg{4}{label} % \macroarg{5}{backrefs} % \macroarg{6}{\cs{b@}citekey} % \begin{macrocode} \def\cite@nobib@test#1#2#3#4#5\@nil#6{% \@ifempty{#4}{% \G@refundefinedtrue \UndefinedCiteWarning#6% \xdef#6{\@nx\citesel #2#3{% \@nx\CitePrintUndefined{\extr@cite#6}}{}{}}% }{}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\UndefinedCiteWarning} % This is a copy of the standard warning from \cs{@citex}. % \begin{macrocode} \def\UndefinedCiteWarning#1{% \@latex@warning{% Citation `\extr@cite#1' on page \thepage\space undefined}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\CitePrintUndefined} % \begin{macrocode} \DeclareRobustCommand{\CitePrintUndefined}[1]{% \begingroup\fontshape{n}\fontseries\mddefault \ttfamily ?#1\endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\CPU@normal} % This has to be a \cs{let}, not a \cs{def}. % \begin{macrocode} \let\CPU@normal\CitePrintUndefined % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@cj} % \MacroArgs % \macroarg{1}{\cs{b@}citekey} % \macroarg{2}{star-optional-arg} % \begin{macrocode} \def\cite@cj#1#2{% \leavevmode \begingroup \cite@cb#1% write info to aux file \ar@SK@cite#1% \@citeleft \ar@hyperlink{#1}% \@ifnotempty{#2}{\citemid{#2}}% \citeright \endgroup \ignorespaces % ignore spaces inside \citelist \cite@endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\@citeleft} % The following definition provides some indirection that helps to % deal with author-year object cites. % \begin{macrocode} \def\@citeleft{\citeleft} % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@cb} % \begin{macrocode} \def\cite@cb#1{% \if@filesw \immediate\write\@auxout{\string\citation{\extr@cite#1}}% \fi % \end{macrocode} % Define \cs{citesel} to make \cs{b@whatever} update itself. % \begin{macrocode} \begingroup \let\citesel\citesel@update #1#1% \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\extr@cite} % Extract \emph{citekey} from \cs{b@}\emph{citekey}. % \begin{macrocode} \def\extr@cite{\@xp\@gobblethree\string} % \end{macrocode} % \end{macro} % % \subsubsection{Fancier \cn{cite} commands} % % \begin{macro}{\cites} % A list of simple cites. Make it robust in case used inside a figure % caption. (But then also, by the way, listoffigures should provide % special handling.) % \begin{macrocode} \DeclareRobustCommand{\cites}{\cites@a{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\citen} % This is just to keep the showkeys package from clobbering the wrong % part of our definition of \cn{cite}: % \begin{macrocode} \providecommand{\citen}{\ocite} % \end{macrocode} % \end{macro} % % \begin{macro}{\ycite} % \cn{cite} gets redefined inside of \cn{citelist}, so we need to % \cs{def} \cn{ycite} here instead of just \cs{let}ting everything % to \cn{cite}. % \begin{macrocode} \def\ycite{\cite} % \end{macrocode} % \end{macro} % % \begin{macro}{\ycites} % \begin{macrocode} \let\ycites\cites % \end{macrocode} % \end{macro} % % \begin{macro}{\ocite} % \begin{macrocode} \let\ocite\ycite % \end{macrocode} % \end{macro} % % \begin{macro}{\ocites} % \begin{macrocode} \let\ocites\cites % \end{macrocode} % \end{macro} % % \begin{macro}{\fullcite} % \begin{macrocode} \let\fullcite\cite % \end{macrocode} % \end{macro} % % \begin{macro}{\fullocite} % \begin{macrocode} \let\fullocite\ocite % \end{macrocode} % \end{macro} % % \begin{macro}{\citeauthor} % \begin{macrocode} \let\citeauthor\ycite % \end{macrocode} % \end{macro} % % \begin{macro}{\citeauthory} % \begin{macrocode} \let\citeauthory\ycite % \end{macrocode} % \end{macro} % % \subsubsection{The \cn{nocite} command} % % \begin{macro}{\nocite} % \begin{macrocode} \renewcommand{\nocite}[1]{\othercites{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\othercites} % \begin{macrocode} \newcommand{\othercites}[1]{% \cite@begingroup \let\BackCite\@gobble \let\cite@endgroup\@empty \def\citelist{\othercitelist}% \cites{#1}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\othercitelist} % \begin{macrocode} \newcommand{\othercitelist}[1]{% \cite@begingroup \let\cite@endgroup\@empty \cites@init \let\citeleft\relax \let\citeright\ignorespaces \def\InnerCite{\OtherCite}% \def\cite@cj ##1##2{% \begingroup \@xp\citesel##1% \cite@cb ##1% \endgroup % \end{macrocode} % If we detect |\nocite{*}|, we globally alias % \cs{selective@bibdef} to \cs{copy@bibdef} so that all succeeding % \cn{bibselect} commands act like \cn{bibselect*}. % \begin{macrocode} \@xp\ifx\csname b@*\endcsname ##1% \global\let\selective@bibdef\copy@bibdef \fi \ignorespaces \cite@endgroup }% #1\relax \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\OtherCite} % \begin{macrocode} \def\OtherCite#1{\cite@a\citesel@other{#1}{}{}} % \end{macrocode} % \end{macro} % % \begin{macro}{\citesel@other} % \begin{macrocode} \def\citesel@other#1#2#3#4#5#6{} % \end{macrocode} % \end{macro} % % \begin{macro}{\b@*} % This provides a dummy definition to keep things like |\nocite{*}| % from generating an error message. % \begin{macrocode} \@namedef{b@*}{\citesel 11{*}{*}{*}} % \end{macrocode} % \end{macro} % % \subsubsection{Citation sorting} % % \begin{macro}{\process@citelist@sorted} % \begin{macrocode} \def\process@citelist@sorted#1{% \ifx\citesel\citesel@number \cite@sorted@s #1\cite@sorted@e \else \NonNumericCiteWarning \process@citelist@unsorted{#1}% \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\NonNumericCiteWarning} % \begin{macrocode} \def\NonNumericCiteWarning{% \amsrefs@warning{% Unable to confirm that cite keys are numeric: not sorting% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\process@citelist@unsorted} % \begin{macrocode} \def\process@citelist@unsorted#1{% \ignorespaces#1\relax } % \end{macrocode} % \end{macro} % % \begin{macro}{\process@citelist} % By default, citation lists will be sorted. % \begin{macrocode} \let\process@citelist\process@citelist@sorted % \end{macrocode} % \end{macro} % % \begin{macro}{\CPU@sort} % By defining this as \TeX's maxint, undefined cites migrate to the % end of a sorted list. % \begin{macrocode} \def\CPU@sort#1{2147483647} % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@sorted@s} % Here's where we prepare to sort the citations and (optionally) % compress ranges. % \begin{macrocode} \def\cite@sorted@s{% \begingroup \let\CitePrintUndefined\CPU@sort \let\cite@cjs\cite@cj \let\cite@cj\cite@compress \begingroup \toks@\@emptytoks \let\cite@cj\cite@sort \ignorespaces } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@sorted@e} % \begin{macrocode} \def\cite@sorted@e{% \@xp\endgroup \the\toks@ \cite@dash \prev@cite \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@sort} % This is essentially an insertion sort. I think. % % \MacroArgs % \macroarg{1}{\cs{b@}citekey} % \macroarg{2}{optional arg} % \begin{macrocode} \def\cite@sort#1#2{% \safe@set\@tempcnta#1% highest number so far \toks@{\cite@cj#1{#2}}% \@temptokena\toks@ \let\cite@cj\cite@sort@a \ignorespaces } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@sort@a} % \begin{macrocode} \def\cite@sort@a#1#2{% \safe@set\@tempcntb#1% \ifnum\@tempcntb > \@tempcnta \add@toks@{\cite@cj#1{#2}}% \@tempcnta\@tempcntb \else \let\cite@cj\cite@sort@b \toks@\@emptytoks \def\@tempb{\add@toks@{\cite@cj#1{#2}}}% \the\@temptokena \@tempb \let\cite@cj\cite@sort@a \fi \@temptokena\toks@ \ignorespaces } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@sort@b} % \begin{macrocode} \def\cite@sort@b#1#2{% \safe@set\count@#1% \ifnum\@tempcntb < \count@ \@tempb \let\@tempb\@empty \fi \add@toks@{\cite@cj#1{#2}}% \ignorespaces } % \end{macrocode} % \end{macro} % % \subsubsection{Range compression} % % When the time comes to apply compression, we have at our disposal a % list of internal cite calls that looks like this: % \begin{verbatim} % \cite@cj\b@aaa{opta}\cite@cj\b@bbb{optb}...\cite@cj\b@zzz{optz} %\end{verbatim} % where % \[ \ncn{b@aaa} < \ncn{b@bbb} < \cdots < \ncn{b@zzz} \] % and the \texttt{opt} arguments are possibly null. % To print the citations while collapsing sequences of 3 or more % contiguous numbers into ranges of the form $n$--$m$, we bind % \cs{cite@cj} to a suitably clever function and then execute the % list. In the absence of optional arguments, here's the algorithm: % % \begin{enumerate} % \item[Begin.] % Enter state~0. This is done by \cs{cite@sorted@s}. % \item[State 0.] %^^A This is the initial state. % The current citation is the beginning % of a range (possibly a singleton range). Print it. Then, set % $\mathit{prevnum} := \mathit{number}$ and enter state~1. % % \item[State 1.] % The current citation might be the second element of a range. % \begin{enumerate} % \item[Case a)] % $\mathit{number} = \mathit{prevnum} + 1$. Then the current % item is definitely the second element of a range. It might be % the last element of the range, but we won't know until we examine % the following citation. So, save the current citation in % \cs{prev@cite}, set $\mathit{prevnum} := \mathit{number}$, and go % to state~2. % % \item[Case b)] % $\mathit{number} \ne \mathit{prevnum} + 1$. The current citation % is the beginning of a new range. Print it, set % $\mathit{prevnum} := \mathit{number}$ and remain in state~1. % (This is essentially identical to stage~0.) % % \end{enumerate} % % \item[State 2.]\leavevmode % The current citation might be the third (or later) element of a % range. % \begin{enumerate} % \item[Case a)] % $\mathit{number} = \mathit{prevnum} + 1$. The current element is % definitely part of a range. It might be the last % element of the range, but again we won't know until we examine % the following citation. Save the current citation % in \cs{prev@cite} and set $\mathit{prevnum} := \mathit{number}$. % Remain in state~2. % % \item[Case b)] % $\mathit{number} \ne \mathit{prevnum} + 1$. The previous % citation was the end of a range and the current citation is the % beginning of a new range. Print a dash followed by % \cs{prev@cite}, then set $\mathit{prevnum} := \mathit{number}$ % and enter state~1. % % \end{enumerate} % % \item[End.] If \cs{prev@cite} is not empty, print it, preceded by a % dash if we were in the middle of a range. (This is done by % \cs{cite@sorted@e}.) % % \end{enumerate} % % The presence of optional arguments complicates things % somewhat, since a citation with an optional argument should never % participate in range compression. In other words, when we come % across an optional argument, we should finish off the preceding % range, print the current citation, and then return to the initial % state. More precisely, here are the actions taken in each state % when there is an optional argument: % % \begin{enumerate} % % \item[State 0.] % Print the current citation and remain in state~0. % % \item[State 1.] % Print the current citation and return to state~0. % % \item[State 2.] % Print a dash followed by \cs{prev@cite}. Then print the current % citation and return to state~0. % % \end{enumerate} % % \begin{macro}{\prev@cite} % \begin{macrocode} \let\prev@cite\@empty % \end{macrocode} % \end{macro} % % \begin{macro}{\prev@cite@cb} % There's one further complication: Even though we're suppressing % some of the citation numbers, we need to make sure that each % citation is recorded in the \fn{.aux} file. So, in case~2a, % before we overwrite \cs{prev@cite}, we first invoke % \cs{prev@cite@cb} to record the previous citation (if any). % \begin{macrocode} \def\prev@cite@cb{% \ifx\@prev@cite\@empty \else \begingroup \def\cite@print##1##2{% \cite@cb##1% }% \prev@cite \endgroup \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@print} % \begin{macrocode} \def\cite@print#1#2{% \begingroup \let\CitePrintUndefined\CPU@normal \cite@cjs#1{#2}% \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\cite@dash} % Ok, I lied. There was more than one further complication. % Suppose that when we hit the end of the list, we're in state~2. % We need to know whether to output a dash or a comma. (For % ex