%D \module
%D   [       file=bibl-tra,
%D        version=2009.08.13,
%D          title=\CONTEXT\ Publication Module,
%D       subtitle=Publications,
%D         author=Taco Hoekwater,
%D           date=\currentdate,
%D      copyright={Public Domain}]
%C
%C Donated to the public domain.

%D This used to be module \type {t-bib} but due to the number of differences
%D in handling structure between \MKII\ and \MKIV\ we now have \BIBTEX\ support
%D in the kernel. The only patches concerns some namespace issues. Also,
%D constants and variables are now predefined. When the \MKIV\ code is well
%D tested I might backport a couple of adaptions to this \MKII\ variant.

\writestatus{loading}{ConTeXt Bibliography Support / BibTeX}

\definefilesynonym[bib][obsolete]

% here starts t-bib.tex

%D The original was developed independantly by Taco Hoekwater while still working for Kluwer
%D Academic publishers (it still used the dutch interface then). Development continued after
%D he left Kluwer, and in Januari 2005, the then already internationalized file was merged
%D with the core distribution by Hans Hagen.  The current version is once again by Taco.
%D
%D More documentation and additional resources can be found on the contextgarden:
%D \hyphenatedurl{http://wiki.contextgarden.net//Bibliography}.

%D \subject{DONE (dd/mm/yyyy)}
%D
%D \startitemize
%D \item add author definition (and associated system variable) (26/05/2005)
%D \item add finalnamesep support for Oxford comma (17/09/2005)
%D \item add \type{\insert...} for: doi, eprint, howpublished (19/09/2005)
%D \item allow a defaulted \type{\setupcite} (19/11/2005)
%D \item renamed citation type 'number' to 'serial' (19/11/2005)
%D \item better definition of \type{\inverted...author} (19/11/2005)
%D \item don't reset [numbercommand] in \type {\setuppublication} by default (20/11/2005)
%D \item don't disable other \type {\setuppublication} keys if alternative is present (20/11/2005)
%D \item drop \type{\sanitizeaccents} (20/11/2005)
%D \item added \type{\nocite} and \type{\cite[none]} (21/11/2005)
%D \item added headtext for it  (23/11/2005)
%D \item make \type{\cite[url]} and \type{\cite[doi]} interactive (23/11/2005)
%D \item make right-aligned labels in the list work even when autohang=no
%D \item use 'et al.' instead of 'et.al.'. Pointed out by Peter M�nster (30/12/2005)
%D \item added headtext for cz (31/12/2005)
%D \item Keep whitespace after \type{\cite} with single argument (31/12/2005)
%D \item Fix broken \type{\cite{}} support (31/12/2005)
%D \item Use \type{\readfile} inside \type{\usepublications} instead of \type{\readsysfile} (12/01/2006)
%D \item Use \type{\currentbibyear} and \type{\currentbibauthor} instead of \type{\YR} and \type{\AU} (05/02/2006)
%D \item Fix compressed version of authoryear style (05/02/2006)
%D \item Rename the clashing data fields \type{\url} and \type{\type} to \type{\biburl} and \type{\bibtype} (05/02/2006)
%D \item Added two french bibl files from Renaud Aubin (06/02/2006)
%D \item Five new bib class and eight extra bib fields, for IEEEtran (07/02/2006)
%D \item French keyword translation, provided by Renaud (08/02/2006)
%D \item fix underscores in undefined keys (22/02/2006)
%D \item Destroy interactivity in labels of the publication list (13/03/2006)
%D \item fix multi-cite list compression (11/4/2006)
%D \item fix \type{\getcitedata} (11/4/2006)
%D \item magic for chapter bibs (18-25/4/2006)
%D \item language setting (25/4/2006)
%D \item use \type{\hyphenatedurl} for \type{\inserturl} (25/4/2006)
%D \item Add \type{\docitation} to \type{\nocite}(26/4/2006)
%D \item patents can have numbers, added to bst files (26/4/2006)
%D \item \type{\docitation} needs a \type{\iftrialtypesetting} (27/4/2006)
%D \item \type{\filllocalpublist}'s loop is bound by definedness, not resolvedness (27/4/2006)
%D \item \type{\setuppublications[monthconversion=]} added (15/5/2006)
%D \item use \type{\undefinedreference} instead of bare question marks (15/5/2006)
%D \item add grouping around \type{\placepublications} commands (16/5/2006)
%D \item fix a bug in \type{\cite{<item>}} (17/5/2006)
%D \item support \type{\cite[authornum]} (18/5/2006)
%D \item make \type{\cite} unexpandable (20/6/2006)
%D \item allow hyperlinks in author\&year combo's
%D       (cite list compression has to be off) (20/6/2006)
%D \item fix duplicate labels for per-chapter style (20/6/2006)
%D \item allow \type{\setupcite[interaction=(start|stop)]}
%D \item fix the item number in the publication list with 'numbering=yes' (22/6/2006)
%D \item make the default criterium for \type{\placepublications} be \type{previous} (23/6/2006)
%D \item fix \type{\normalauthor} and \type{\normalshortauthor} spacing (29/6/2006)
%D \item do not typeset empty arguments to \type{\typesetapublication} (29/6/2006)
%D \item add \type{symbol=none} to \type{\setuplist} in unnumbered
%D       mode to prevent typesetting of bare numbers (29/6/2006)
%D \item remove two incorrect spaces from bibl-num.tex (1/7/2006)
%D \item reset font styles within \type{\cite}, so that font switches
%D       in \type{left} stay in effect (12/7/2006)
%D \item guard added against loading bbl files multiple times (13/7/2006)
%D \item fix \type{\cite[num]} with compression is on. (14/7/2006)
%D \item test \type{\iflocation} before deciding to use the
%D       interactive version of cite (18/7/2006)
%D \item support \type{\setupcite[authoretallimit=1]} (18/7/2006)
%D \item support use of \type{\cite} within titles and captions by
%D       saveguarding the list item extraction and reference placement
%D       code (19/7/2006)
%D \item support \type{\setuppublicationlist[title=\chapter]} (4/8/2006)
%D \item use the expansion of \type{\headtext{pubs}} (4/8/2006)
%D \item hook added for repeated authors in publication list
%D       \type{\setuppublicationlist[artauthorcommand=\mythreeargscommand]}
%D       (4/8/2006)
%D \item make the bracketed arguments of \type{\artauthor}, \type{\author}
%D        and \type{\editor} (bbl commands) optional (4/8/2006)
%D \item the constants \type{sorttype}, \type{compress} and
%D        \type{autohang} have moved to the core (8/8/2006)
%D \item bibtex is now registered as a program to be run by texexec (8/8/2006)
%D \item fix a bug in \type{\setupcite[authoretallimit=1]} (9/8/2006)
%D \item fix a bug inside citations that prevented lastpubsep from ever being
%D       used due to a volatile \type{\commalistsize} (25/8/2006).
%D \item added the possibility of \type{\placepublications[option=continue]}
%D       (6/9/2006)
%D \item Mojca translated Master's Thesis to Masterarbeit (bibl-apa-de.tex)
%D       (12/9/2006)
%D \item Added \type{\setuppublicationlist[maybeyear=off]} by request from
%D       Thomas Schmitz (15/9/2006)
%D \item Removed some spurious spaces pointed out by willi egger (19/9/2006)
%D \item Add configuration of bibtex executable name (4/11/2006)
%D \item Fix numbering=short and numbering=bib (spotted by Matthias W�chter) (4/11/2006)
%D \item third attempt to get a correct release (5/11/2006)
%D \item fix a few missing dots in bibl-num.tex  (7/12/2006)
%D \item Patch for DOI's by Tobias Burnus (17/4/2007)
%D \item Patch for \type{\insertbiburl} and \type{\insertdoi} for  Tobias Burnus (18/4/2007)
%D \item Added a missing \type{\relax} in \type{\dospecialbibinsert},
%D       that made the space before the {\it et al.} text disappear.  (18/4/2007)
%D \item Attempt to fix percent signs in bbl files. As a side-effect,
%D       this prohibits comments in \tex{startpublication} blocks! (17/4/2008)
%D \item Patch from Matthias W\"achter that allows arbitrary .bst
%D        files to be used with \tex{setupbibtex} (25/9/2008)
%D \item Extended for the new multilingual setups for the Oct 2008 current of ConTeXt (23/10/2008)
%D \item Multilingual setups needed another fix (27/10/2008)
%D \item Two fixes for bibl-apa by Michael Green (27/10/2008)
%D \item Catalan translation of 'References' (10/11/2008)
%D \item 'chapter' -> 'chapitre' in bibl-apa-fr (27/11/2008)
%D \item Run bibtex via os.execute in  mkiv modee (01/12/2008)
%D \item Small correction in bibl-apa's placement of volume
%D       information in articles (05/01/2009)
%D \item Handle multi-author (more than two) cases in \type{\cite}
%D       (02/03/2009)
%D \item Suppress a syntax error in \type{cont-xp} mode. The output is
%D       probably not right, though (02/03/2009)
%D \item Added a \tex{loadmarkfile} at the end, and two new files
%D       from Hans. The \type{t-bib.mkiv} is needed to make the module
%D       work with the new structure code (17/04/2009)
%D \item Added a patch to \type{t-bib.mkiv} from Hans to make the
%D       cross referencing between multiple citations an
%D       bibliographies work (27/04/2009)
%D \item Remove a superfluous \type{\unprotect} in t-bib.mkiv (11/05/2009).
%D \item Patch of incollection in bibl-ams.tex from Xan (08/06/2009).
%D \item Patch of unpublished in bibl-ams.tex from Xan (22/07/2009).
%D \item Modified \type{\bibdogetupsometextprefix} so it works for undefined
%D       language labels, from Hans (13/08/2009).
%D \item Removed some \MKIV\ hacks as well as some things that are in the
%D       core like variables, constants and messages (HH:22/08/2009).
%D \item Added \type{bib} in front of \type {insert} macros and initialize
%D       then later on  (HH:22/08/2009).
%D \item Removed test for type {\currentlocationreference} plus associated
%D       code (HH:22/08/2009).
%D \stopitemize
%D
%D \subject{WISHLIST}
%D
%D \startitemize
%D \item link back from publication list to citation
%D \item export \type {\citation{<cited item>}}
%D \item support mlbibtex
%D \item don't load the whole lot, but filter entries instead
%D \stopitemize

\unprotect

%D Variables, constants and messages are removed as they are now in the
%D multilingual interface modules.

\def\biblistname{pubs} % for compatibility

% \newif\ifeditedbook

%D how to load the references. There is some new stuff here
%D to support Idris' (incorrect :-)) use of projects

% \let\preloadbiblist\relax
%
% \ifx\currentcomponent\v!text
%   % single file
%   \edef\temp{\the\everystarttext}%
%   \ifx\temp\empty
%     % post-starttext
%     \def\preloadbiblist{\dousepublications\jobname }%
%   \else
%     % pre-starttext
%     \appendtoks \dousepublications\jobname \to \everystarttext
%   \fi
%   %
% \else \ifx\currentcomponent\v!project
%   % a project file, have to set up the partial products!
%   \def\startproduct #1 %
%     {\doateverystarttext
%      \dousepublications{#1}%
%      \donextlevel\v!product\currentproduct
%      \doexecutefileonce\doexecutefileonce
%      \donotexecutefile\doexecutefile#1\\}%
%   %
% \else \ifx\currentcomponent\v!product
%   % a product file
%   \def\preloadbiblist{\dousepublications\jobname }%
%   %
% \else
%   % a component? not sure what to do
%   \def\preloadbiblist{\dousepublications\jobname }%
%   %
% \fi \fi \fi

\def\preloadbiblist
  {\globallet\preloadbiblist\relax
   \dousepublications\jobname}

\definelist[pubs]
\setuplist[pubs][\c!width=]

%D \macros{bibdoif,bibdoifnot,bibdoifelse}
%D
%D Here are a few small helpers that are used a lot
%D in all the typesetting commands
%D (\type{\insert...}) we will encounter later.

\long\def\bibdoifelse#1%
  {\@EA\def\@EA\!!stringa\@EA{#1}%
   \ifx\!!stringa\empty
     \expandafter\secondoftwoarguments
   \else
     \expandafter\firstoftwoarguments
   \fi}

\long\def\bibdoifnot#1%
  {\@EA\def\@EA\!!stringa\@EA{#1}%
   \ifx\!!stringa\empty
     \expandafter\firstofoneargument
   \else
     \expandafter\gobbleoneargument
   \fi}

\long\def\bibdoif#1%
  {\@EA\def\@EA\!!stringa\@EA{#1}%
   \ifx\!!stringa\empty
     \expandafter\gobbleoneargument
   \else
     \expandafter\firstofoneargument
   \fi}

%D Bibtex settings separated out

%D No point in writing the aux file if there is no database...

\def\setupbibtex{\dosingleempty\dosetupbibtex}

\def\dosetupbibtex[#1]%
  {\let\@@pbdatabase\empty
   \getparameters[\??pb][\c!sort=\s!default,#1]%
   \expanded{\processaction[\@@pbsort]}
        [      \v!no=>\def\bibstyle{cont-no},
           \v!author=>\def\bibstyle{cont-au},
            \v!title=>\def\bibstyle{cont-ti},
            \v!short=>\def\bibstyle{cont-ab},
          \s!default=>\def\bibstyle{cont-no},
          \s!unknown=>\def\bibstyle{\@@pbsort}]%
   \ifx\@@pbdatabase\empty\else \writeauxfile \fi}

\dosetupbibtex[bibtex=bibtex]

%D \macros{writeauxfile}
%D
%D Unfortunately, \BIBTEX\ is not the best configurable program
%D around. The names of the commands it parses as well as the \type{.aux}
%D extension to the file name are both hardwired.
%D
%D This means \CONTEXT\ has to write a \LATEX-style auxiliary file, yuk!
%D The good news is that it can be rather short. We'll just ask
%D \BIBTEX\ to output the entire database(s) into the \type{bbl} file.
%D
%D The \type{\bibstyle} command controls how the \type{bbl} file will
%D be sorted. The possibilities are:
%D
%D \startitemize[packed]
%D \item by author (+year, title): cont-au.bst
%D \item by title  (+author, year): cont-ti.bst
%D \item by short key as in abbrev.bst: cont-ab.bst
%D \item not sorted at all: cont-no.bst
%D \stopitemize

\def\writeauxfile
  {\doifmode{*\v!first}
    {\openout \scratchwrite \jobname.aux
     \write   \scratchwrite {\string\citation{*}}%
     \write   \scratchwrite {\string\bibstyle{\bibstyle}}%
     \write   \scratchwrite {\string\bibdata{\@@pbdatabase}}%
     \closeout\scratchwrite
     \showmessage\m!publications{3}{}%
     \expanded{\installprogram{\@@pbbibtex\space\jobname}}}}

%D \macros{ifsortbycite,iftypesetall,ifautohang,ifbibcitecompress}
%D
%D The module needs some new \type{\if} statements.

%D Default sort order of the reference list is by citation.

\newif\ifsortbycite        \sortbycitetrue

%D By default, only referenced publications are typeset

\newif\iftypesetall        \typesetallfalse

%D Hanging indentation of the publication list
%D will not adjust itself according to the width of the label.

\newif\ifautohang          \autohangfalse

%D Cite lists are compressed, if possible.

\newif\ifbibcitecompress   \bibcitecompresstrue

\def\setuppublications
  {\dosingleargument\dosetuppublications}

\def\bibleftnumber#1%
  {#1\hfill~}

\def\dosetuppublications[#1]%
  {\getparameters
     [\??pb]
     [\c!alternative=,#1]%
   \doifsomething\@@pbalternative
      {\readsysfile
         {bibl-\@@pbalternative.tex}
         {\showmessage\m!publications{6}{bibl-\@@pbalternative}\let\@@pbalternative\empty}
         {\showmessage\m!publications{1}{bibl-\@@pbalternative}\let\@@pbalternative\empty}}%
  \getparameters
     [\??pb]
     [#1]%
    \processaction
     [\@@pbcriterium]
     [    \v!all=>\typesetalltrue,
      \s!unknown=>\typesetallfalse]%
   \processaction
     [\@@pbautohang]
     [    \v!yes=>\autohangtrue,
      \s!unknown=>\autohangfalse]%
   \processaction
     [\@@pbsorttype]
     [   \v!cite=>\sortbycitetrue,
          \v!bbl=>\sortbycitefalse,
      \s!default=>\sortbycitetrue,
      \s!unknown=>\sortbycitefalse]%
   \processaction
     [\@@pbnumbering]
     [    \v!yes=>\let\@@pbinumbercommand\firstofoneargument,
           \v!no=>\let\@@pbinumbercommand\gobbleoneargument,
        \v!short=>\def\@@pbinumbercommand##1{\getvalue{pbds-\@@pbk}},
          \v!bib=>\def\@@pbinumbercommand##1{\getvalue{pbdn-\@@pbk}},
      \s!unknown=>\let\@@pbinumbercommand\firstofoneargument]%
   \processaction
     [\@@pbrefcommand]
     [\s!default=>\edef\@@citedefault{\@@pbrefcommand},
      \s!unknown=>\edef\@@citedefault{\@@pbrefcommand}]}

% initialize

\def\@@pbrefcommand{num}
\def\@@pbnumbercommand{\bibleftnumber}

%D \macros{usepublications}
%D
%D We need \type{\usereferences} so that it is possible to
%D refer to page and/or appearance number for publications
%D in the other document.

\def\usepublications[#1]%
  {\usereferences[#1]\processcommalist[#1]\dousepublications}

\def\dousepublications#1%
  {\doonlyonce
     {#1.\f!bibextension}
     {\readfile{#1.\f!bibextension}
       {\showmessage\m!publications{4}{#1.\f!bibextension}}
       {\showmessage\m!publications{2}{#1.\f!bibextension}}}}

%D \macros{setuppublicationlist}
%D
%D This will be the first command in (\BIBTEX-generated) \type{bbl}
%D files. `samplesize' is a sample value (in case of \BIBTEX-generated
%D files, this will be the longest `short' key). `totalnumber'
%D is the total number of entries that will follow in this
%D file.

%D Both values are only needed for the label calculation
%D if `autohang' is `true', so by default the command is
%D not even needed, and therefore I saw no need to give
%D it it's own system variable and it just re-uses \type{pb}.

\def\setuppublicationlist
  {\dosingleempty\dosetuppublicationlist}

\def\dosetuppublicationlist[#1]%
  {\getparameters[\??pv data][#1]%
   \setuplist
    [pubs]
    [\c!samplesize={AA99},\c!totalnumber={99},
     \c!alternative=a,\c!interaction=,\c!pagenumber=\v!no,#1]}

\def\setuppublicationlayout[#1]#2%
  {\setvalue{\??pv data#1}{#2\unskip}}

%D \macros{bibalternative}
%D
%D A nice little shorthand that will be used so we don't have to
%D key in the weird \type{\@@pv} parameter names all the time.

\def\bibalternative#1%
  {\getvalue{\??pv\@@currentalternative#1}}

%D \macros{simplebibdef,bibcommandlist}
%D
%D \type{\simplebibdef} defines \type{bib@#1}, which in turn will
%D use one argument that is stored in \type{@@pb@#1}.
%D
%D \type{\simplebibdef} also defines \type{insert#1}, which can be
%D used in the argument of \type{\setuppublicationlayout} to fetch
%D one of the \type{@@pb@} data entries. \type{insert#1} then has
%D three arguments: \type{#1} are commands to be executed before the
%D data, \type{#2} are commands to be executed after the data, and
%D \type{#3} are commands to be executed if the data is not found.

%D \type{\bibcommandlist} is the list of commands that is affected
%D by this approach. Later on, it will be used to do a series
%D of assignments from \type{#1} to \type{bib@#1}: e.g
%D \type{\title} becomes \type{\bib@title} when used within
%D a publication.

\newtoks\initializebibdefinitions % we need to prevent clashes (HH)

% \def\simplebibdef#1% hh: funny expansion ?
%   {\@EA\long\@EA\def\csname bib@#1\endcsname##1%
%      {\setvalue{\??pb @#1}{##1}%
%       \ignorespaces}%
%       \@EA\def\csname insert#1\endcsname##1##2##3%
%         {\@EA\bibdoifelse
%            \@EA{\csname @@pb@#1\endcsname}%
%            {##1\csname @@pb@#1\endcsname##2}%
%            {##3}%
%       }}

\def\simplebibdef#1% hh: funny expansion ?
  {\@EA\long\@EA\def\csname bib@#1\endcsname##1%
     {\setvalue{\??pb @#1}{##1}\ignorespaces}%
   \expandafter \appendtoks
     \expandafter\let\csname insert#1\expandafter\endcsname\csname bibinsert#1\endcsname
   \to \initializebibdefinitions
   \@EA\unexpanded\@EA\def\csname bibinsert#1\endcsname##1##2##3%
     {\@EA\bibdoifelse\@EA{\csname\??pb @#1\endcsname}{##1\csname\??pb @#1\endcsname##2}{##3}}}

\def\bibcommandlist
  {abstract, annotate, arttitle, assignee, bibnumber, bibtype, biburl, chapter, city,
   comment, country, day, dayfiled, doi, edition, eprint, howpublished, isbn, issn,
   issue, journal, keyword, keywords, lastchecked, month, monthfiled, names, nationality,
   note, notes, organization, pages, pubname, pubyear, revision, series, size, thekey,
   title, volume, yearfiled}

\processcommacommand[\bibcommandlist]\simplebibdef

\def\bibinsertdoi#1#2#3%
    {{\bibdoifelse{\@@pb@doi}%
       {\edef\ascii{\@EA\detokenize\@EA{\@@pb@doi}}%
        #1\expanded{\gotoDOI{\@@pb@thekey}{\ascii}}#2}{#3}}}

\def\bibinsertbiburl#1#2#3%
    {{\bibdoifelse{\@@pb@biburl}%
       {\edef\ascii{\@EA\detokenize\@EA{\@@pb@biburl}}%
        #1\expanded{\gotoURL{\@@pb@thekey}{\ascii}}#2}{#3}}}

\def\bibinsertmonth#1#2#3%
  {\bibdoifelse{\@@pb@month}%
    {#1\doifnumberelse{\@@pb@month}%
       {\doifconversiondefinedelse\@@pbmonthconversion
          {\convertnumber\@@pbmonthconversion{\@@pb@month}}{\@@pb@month}}%
       {\@@pb@month}#2}{#3}}

\appendtoks
    \let\inserturl \bibinsertbiburl  % for backward compat.
    \let\inserttype\bibinsertbibtype % for backward compat.
\to\initializebibdefinitions

\def\newbibfield[#1]%
  {\simplebibdef{#1}%
   \edef\bibcommandlist{\bibcommandlist,#1}}

%D \macros{bib@crossref}
%D
%D \type{\crossref} is used in database files to point to another
%D entry. Because of this special situation, it has to be defined
%D separately. Since this command will not be seen until at
%D \type{\placepublications}, it may force extra runs. The same is
%D true for \type{\cite} commands inside of publications.

\def\bib@crossref#1%
  {\setvalue{\??pb @crossref}{#1}\ignorespaces}

\def\bibinsertcrossref#1#2#3%
  {\bibdoifelse{\@@pb@crossref}
     {#1\@EA\cite\@EA[\@@pb@crossref]#2}
     {#3}}

\let\insertcrossref\gobblethreearguments

\appendtoks\let\insertcrossref\bibinsertcrossref\to\initializebibdefinitions

%D \macros{complexbibdef,specialbibinsert}
%D
%D The commands \type{\artauthor}, \type{\author} and
%D \type{\editor} are more complex than the other commands.
%D Their argument lists have this form:
%D
%D \type{\author[junior]{firstnames}[inits]{von}{surname}}
%D
%D (bracketed stuff is optional)
%D
%D And not only that, but there also might be more than one of each of
%D these commands. This is why a special command is needed to insert
%D them, as well as one extra counter for each command.

%D All of these \type{\@EA}'s and \type{\csnames} make this code
%D look far more complex than it really is. For example, the argument
%D \type{author} defines the macro \type{\bib@author} to do two
%D things: increment the counter \type{\author@num} (let's say to 2)
%D and next store it's arguments in the macro \type{\@@pb@author2}.
%D And it defines \type{\insertauthors} to expand into
%D \starttyping
%D \specialbibinsert{author}{\author@num}{<before>}{<after>}{<not>}
%D \stoptyping

\def\docomplexbibdef#1%
   {\def\currentype{#1}%
    \dosingleempty\dodocomplexbibdef}

\def\dodocomplexbibdef[#1]#2%
   {\def\firstarg{#1}\def\secondarg{#2}%
    \dosingleempty\dododocomplexbibdef}

\def\dododocomplexbibdef[#1]#2#3%
  {\@EA\increment\csname \currentype @num\endcsname
      \setevalue{\??pb @\currentype\csname \currentype @num\endcsname}%
        {{\secondarg}{#2}{#3}{#1}{\firstarg}}\ignorespaces}%

% \def\complexbibdef#1%
%   {\@EA\newcounter\csname #1@num\endcsname
%    \@EA\def\csname bib@#1\endcsname{\docomplexbibdef{#1}}%
%    \@EA\def\csname insert#1s\endcsname##1##2##3%
%      {\specialbibinsert{#1}{\csname #1@num\endcsname}{##1}{\unskip ##2}{##3}}}

\def\complexbibdef#1%
  {\@EA\newcounter\csname #1@num\endcsname
   \@EA\def\csname bib@#1\endcsname{\docomplexbibdef{#1}}%
   \expandafter \appendtoks
     \expandafter\let\csname insert#1s\expandafter\endcsname\csname bibinsert#1s\endcsname
   \to \initializebibdefinitions
   \@EA\def\csname bibinsert#1s\endcsname##1##2##3{\specialbibinsert{#1}{\csname #1@num\endcsname}{##1}{\unskip ##2}{##3}}}

\processcommalist[author,artauthor,editor]\complexbibdef

%D Another level of indirection is needed to control the
%D typesetting of all of these arguments.

%D Btw, there is a conflict between `author' and the predefined interface
%D variable `auteur'. The old version is overruled `auteur' is
%D overruled by the systemconstant definition at the top of this file!

\newcount\etallimitcounter
\newcount\etaldisplaycounter
\newcount\todocounter

\def\specialbibinsert#1#2#3#4#5%
  {\bgroup
   \ifnum#2>\zerocount
     \etallimitcounter  =0\bibalternative{#1etallimit}\relax
     \etaldisplaycounter=0\bibalternative{#1etaldisplay}\relax
     \ifnum #2>\etallimitcounter
       \todocounter\etaldisplaycounter
       % just in case ...
	   \ifnum\todocounter>\etallimitcounter
         \todocounter\etallimitcounter
       \fi
     \else
       \todocounter#2\relax
     \fi
     \ifnum\todocounter>\zerocount
       % find the current author list
       \let\templist\empty
       \dorecurse{#2}
          {\toks0=\@EA\@EA\@EA{\csname @@pb@#1\recurselevel\endcsname}%
           \ifx\templist\empty    \edef\templist{\the\toks0}%
           \else        \edef\templist{\templist,\the\toks0}\fi }%
       \doifdefinedelse
          {\??pv data#1\c!command}
          {\doifemptyelsevalue
             {\??pv data#1\c!command}
             {#3\dospecialbibinsert{#1}{\todocounter}{\templist}#4}%
             {#3\getvalue{\??pv data#1\c!command}{#1}{\todocounter}{\templist}#4}}%
          {#3\dospecialbibinsert{#1}{\todocounter}{\templist}#4}%
     \else
       #5%
     \fi
   \else
     #5%
   \fi
   \egroup}

%D This macro does the hard work of inserting a list of people in the
%D output, with proper regard of all the inbetween strings that can
%D arise depending on length of the list of people.

%D \#1 = type
%D \#2 = number of items to be typeset
%D \#3 = commacommand containing authors

\def\dospecialbibinsert#1#2#3%
    {\getcommacommandsize[#3]%
     \scratchcounter 0
     \def\processauthoritem##1%
       {\advance\scratchcounter1
       \ifnum \numexpr\scratchcounter-1\relax<#2\relax
          \getvalue{\??pv data#1}##1%
          \ifnum \scratchcounter=#2\relax
             \ifnum\etallimitcounter<\commalistsize\relax \bibalternative{#1etaltext}\fi
          \else \ifnum\numexpr\scratchcounter+1 = #2\relax
             \ifnum \commalistsize > \plustwo  \bibalternative\c!finalnamesep
             \else                            \bibalternative\c!lastnamesep \fi
          \else
              \bibalternative\c!namesep
          \fi \fi
        \fi}%
     \processcommacommand[#3]\processauthoritem }

%D \macros{invertedauthor,normalauthor,invertedshortauthor,normalshortauthor}
%D
%D Just some commands that can be used in \type{\setuppublicationparameters}
%D If you want to write an extension to the styles, you might
%D as well define some of these commands yourself.
%D
%D The argument list has been reordered here, and the meanings are:
%D
%D {\obeylines\parskip0pt
%D \type{#1} firstnames
%D \type{#2} von
%D \type{#3} surname
%D \type{#4} inits
%D \type{#5} junior
%D }
%D

\def\normalauthor#1#2#3#4#5%
  {\bibdoif{#1}{#1\bibalternative\c!firstnamesep}%
   \bibdoif{#2}{#2\bibalternative\c!vonsep}%
   #3%
   \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}}

\def\normalshortauthor#1#2#3#4#5%
  {\bibdoif{#4}{#4\bibalternative\c!firstnamesep}%
   \bibdoif{#2}{#2\bibalternative\c!vonsep}%
   #3%
   \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}}

\def\invertedauthor#1#2#3#4#5%
  {\bibdoif{#2}{#2\bibalternative\c!vonsep}%
   #3%
   \bibdoif{#5}{\bibalternative\c!juniorsep #5}%
   \bibdoif{#1}{\bibalternative\c!surnamesep #1\unskip}}

\def\invertedshortauthor#1#2#3#4#5%
  {\bibdoif{#2}{#2\bibalternative\c!vonsep}%
   #3%
   \bibdoif{#5}{\bibalternative\c!juniorsep #5}%
   \bibdoif{#4}{\bibalternative\c!surnamesep #4\unskip}}

%D \macros{clearbibitem,clearbibitemtwo,bibitemdefs}
%D
%D These are used in \type{\typesetapublication} to do
%D initializations and cleanups.

\def\clearbibitem#1{\setvalue{\??pb @#1}{}}%

\def\clearbibitemtwo#1%
  {\letvalue{#1@num}\!!zerocount
   \scratchcounter\plusone
   \doloop
     {\doifdefinedelse{\??pb @#1\the\scratchcounter}
        {\letvalue{\??pb @#1\the\scratchcounter}\empty
         \advance\scratchcounter\plusone}%
        {\exitloop}}}

\def\bibitemdefs#1%
   {\@EA\let\@EA\tempa \csname bib@#1\endcsname
    \@EA\let\csname #1\endcsname \tempa }

%D \macros{startpublication}
%D
%D We are coming to the end of this module, to the macros that
%D do typesetting and read the \type{bbl} file.

\newcounter\bibcounter

%D Just a \type{\dosingleempty} is the most friendly
%D of doing this: there need not even be an argument
%D to \type{\startpublication}. Of course, then there
%D is no key either, and it had better be an
%D article (otherwise the layout will be all screwed up).
%D
%D Now prohibits comments, so % can be used for urls

\def\startpublication
  {\edef\bibmodsavedpercent{\the\catcode`\%}%
   \catcode`\%=12
   \dosingleempty\dostartpublication}

\def\stoppublication
  {} % the \catcode of % is reset below

%D Only specifying the key in the argument is also
%D legal. In storing this stuff into macros, some trickery with
%D token registers is needed to fix the expansion problems. Even so,
%D this appears to not always be 100\% safe, so people are
%D urgently advised to use \ETEX\ instead of traditional \TEX.
%D
%D In \ETEX, all expansion problems are conviniently solved by
%D the primitive \type{\protected}. To put that another way:
%D
%D It's not a bug in this module if it does not appear in \ETEX!

\long\def\dostartpublication[#1]#2\stoppublication%
  {\increment\bibcounter
   \bgroup
   \doifassignmentelse{#1}%
     {\getparameters[\??pb][k=,t=article,n=,s=,a=,y=,o=,u=,#1]}%
     {\getparameters[\??pb][k=#1,t=article,n=,s=,a=,y=,o=,u=]}%
   \@EA\toks\@EA2\@EA{\@@pba}%
   \@EA\toks\@EA4\@EA{\@@pbs}%
   \toks0={\ignorespaces #2}%
   \setxvalue{pbdk-\@@pbk}{\@@pbk}
   \setxvalue{pbda-\@@pbk}{\the\toks2}
   \setxvalue{pbdy-\@@pbk}{\@@pby}
   \setxvalue{pbds-\@@pbk}{\the\toks4}
   \setxvalue{pbdn-\@@pbk}{\@@pbn}
   \setxvalue{pbdt-\@@pbk}{\@@pbt}
   \setxvalue{pbdo-\@@pbk}{\@@pbo}
   \setxvalue{pbdu-\@@pbk}{\@@pbu}
   \setxvalue{pbdd-\@@pbk}{\the\toks0}
   \xdef\allrefs{\allrefs,\@@pbk}%
   \egroup
   \catcode`\%=\bibmodsavedpercent\relax }

% intialization of the order-list:

\let\allrefs\empty

%D The next macro is needed because the number command of the
%D publist sometimes needs to fetch something from the current
%D item (like the 'short' key). For this, the ID of the current
%D item is passed in the implict parameter \type{\@@pbk}

\def\makepbkvalue#1{\def\@@pbk{#1}}

\newif\ifinpublist

% from Hans

\def\ignoresectionconversion
  {\let\@@sectionconversion\secondoftwoarguments}

\let\normaldosetfilterlevel\dosetfilterlevel

\def\patcheddosetfilterlevel#1#2% beware: this one is \let
  {\bgroup
   \ignoresectionconversion
   \edef\askedlevel{#1}%
   \edef\askedfilter{#2}%
%   \message{ASKD: \meaning\askedlevel}%
%   \message{PREV: \meaning\v!previous}%
   \ifx\askedlevel\v!current
     \dosetcurrentlevel\askedlevel
   \else\ifx\askedlevel\v!previous
     \dosetpreviouslevel\askedlevel
   \else\ifx\askedlevel\v!all
     \global\chardef\alltoclevels\plusone
   \else\ifx\askedlevel\v!text
     \global\chardef\alltoclevels\plusone
   \else
     \edef\byaskedlevel{\csname\??by\askedlevel\endcsname}%
     \ifx\byaskedlevel\v!text
       \dosettextlevel\askedlevel
     \else
       \dosetotherlevel\askedlevel
     \fi
   \fi\fi\fi\fi
   % experiment
   \ifx\askedfilter\empty \else
     \xdef\currentlevel{\currentlevel\sectionseparator\askedfilter}%
   \fi
   \egroup}

\def\filllocalpublist%
  {\doifdefinedelse{\alltoclevels}
    {\let\dosetfilterlevel\patcheddosetfilterlevel
     \dosettoclevel\??li{pubs}%
     \let\dosetfilterlevel\normaldosetfilterlevel }%
    {\dosettoclevel\??li{pubs}}%
   \global\let\glocalpublist\empty
   \doloop
     {\doifdefinedelse
        {\r!cross cite-\jobname-\recurselevel}
        {\doifreferencefoundelse
           {cite-\jobname-\recurselevel}
           {\@EA\doifreglevelelse\@EA[\currentlocationreference]
              {\@EA\doglobal\@EA\addtocommalist\@EA
                {\currenttextreference}\glocalpublist}{}}
           {}}%
        {\exitloop}}%
    \let\localpublist\glocalpublist}

\def\typesetpubslist
  {\dobeginoflist
%    \the\initializebibdefinitions
   \edef\askedlevel{\csname \??li pubs\c!criterium\endcsname}%
   \ifx\askedlevel\v!all
      \def\bibrefprefix{}%
   \else %
      \preparebibrefprefix
   \fi
   \ifsortbycite
     \filllocalpublist
     \iftypesetall
       \let\localallrefs\allrefs
        \processcommacommand[\localpublist]\typesetapublication
        \def\removefromallrefs##1%
           {\removefromcommalist{##1}\localallrefs }%
        \processcommacommand[\localpublist]\removefromallrefs
        \processcommacommand[\localallrefs]\typesetapublication
      \else
        \processcommacommand[\localpublist]\typesetapublication
     \fi
   \else
     \iftypesetall
       \processcommacommand[\allrefs]\typesetapublication
     \else
       %
       \filllocalpublist
       \processcommacommand[\allrefs]\maybetypesetapublication
     \fi
   \fi
   \doendoflist}

\newif\ifinpublist

\def\maybetypesetapublication#1%
  {\global\inpublistfalse
   \def\test{#1}%
   \def\runtest##1%
      {\def\tempa{##1}\ifx \test\tempa \global\inpublisttrue \fi}%
   \processcommacommand[\localpublist]\runtest
   \ifinpublist \typesetapublication{#1}\fi}

\def\initializepubslist
  {\edef\@@pbnumbering{\@@pbnumbering}%
   \ifautohang
     \ifx\@@pbnumbering\v!short
       \setbox\scratchbox\hbox{\@@pbnumbercommand{\getvalue{\??li pubs\c!samplesize}}}%
     \else\iftypesetall
       \setbox\scratchbox\hbox{\@@pbnumbercommand{\getvalue{\??li pubs\c!totalnumber}}}%
     \else
       \setbox\scratchbox\hbox{\@@pbnumbercommand{\numreferred}}%
     \fi\fi
     \edef\samplewidth{\the\wd\scratchbox}%
     \setuplist[pubs][\c!width=\samplewidth,\c!distance=0pt]%
     \ifx\@@pbnumbering\v!short
       \def\@@pblimitednumber##1{\hbox to \samplewidth
           {\@@pbnumbercommand{\getvalue{pbds-\@@pbk}}}}%
     \else \ifx \@@pbnumbering\v!bib
       \def\@@pblimitednumber##1{\hbox to \samplewidth
           {\@@pbnumbercommand{\getvalue{pbdn-\@@pbk}}}}%
     \else
       \def\@@pblimitednumber##1{\hbox to \samplewidth{\@@pbnumbercommand{##1}}}%
     \fi \fi
   \else
     \ifx\@@pbnumbering\v!short
     \doifemptyelse
        {\getvalue{\??li pubs\c!width}}
        {\def\@@pblimitednumber##1{\hbox
            {\@@pbnumbercommand{\getvalue{pbds-\@@pbk}}}}}%
        {\def\@@pblimitednumber##1{\hbox to \getvalue{\??li pubs\c!width}%
            {\@@pbnumbercommand{\getvalue{pbds-\@@pbk}}}}}%
     \else \ifx \@@pbnumbering\v!bib
        \doifemptyelse
          {\getvalue{\??li pubs\c!width}}
          {\def\@@pblimitednumber##1{\hbox
            {\@@pbnumbercommand{\getvalue{pbdn-\@@pbk}}}}}%
          {\def\@@pblimitednumber##1{\hbox to \getvalue{\??li pubs\c!width}%
            {\@@pbnumbercommand{\getvalue{pbdn-\@@pbk}}}}}%
       \else
       \doifemptyelse
          {\getvalue{\??li pubs\c!width}}
          {\def\@@pblimitednumber##1{\hbox{\@@pbnumbercommand{##1}}}}%
          {\def\@@pblimitednumber##1{\hbox to \getvalue{\??li pubs\c!width}{\@@pbnumbercommand{##1}}}}%
        \fi
     \fi
   \fi
   \ifx\@@pbnumbering\v!no
     \setuplist[pubs][\c!numbercommand=,\c!symbol=\v!none,\c!textcommand=\outdented]%
   \else
     \setuplist[pubs][\c!numbercommand=\@@pblimitednumber]%
   \fi
   \doifelsevalue
      {\??pv data\c!maybeyear}{\v!off}{\def\maybeyear##1{}}{\def\maybeyear##1{##1}}%
   \forgetall} % bugfix 2005/03/18

\def\outdented#1% move to supp-box ?
  {\hskip -\hangindent #1}

%D The full list of publications

\def\completepublications
  {\dosingleempty\docompletepublications}

\def\bibdogetupsometextprefix#1#2#3%
  {\ifcsname#2#1#3\endcsname
     \csname#2#1#3\endcsname
   \else\ifcsname\??la#1\c!default\endcsname
     \@EA\ifx\csname\??la#1\c!default\endcsname\empty
       \ifcsname#2#3\endcsname
         \csname#2#3\endcsname
       \else\ifcsname#2\s!en#3\endcsname
         \csname#2\s!en#3\endcsname
       \fi\fi
     \else
       \expandafter\bibdogetupsometextprefix
          \csname\??la#1\c!default\endcsname{#2}{#3}%
     \fi
   \else
     \ifcsname#2#3\endcsname
       \csname#2#3\endcsname
     \else\ifcsname#2\s!en#3\endcsname
       \csname#2\s!en#3\endcsname
     \fi\fi
   \fi\fi}

\def\docompletepublications[#1]%
  {\begingroup
   \setuplist[pubs][\c!criterium=\v!previous,#1]
   \begingroup
   \let\handletextprefix\firstoftwoarguments
   \edef\headtextpubs{\bibdogetupsometextprefix\headlanguage\c!title{pubs}}%
   \doifdefinedelse
      {\??pv data\v!title}
      {\doifemptyelsevalue
          {\??pv data\v!title}
          {\expanded{\systemsuppliedtitle[pubs]{\headtextpubs}}}%
          {\expanded{\getvalue{\??pv data\v!title}{\headtextpubs}}}%
       }%
      {\expanded{\systemsuppliedtitle[pubs]{\headtextpubs}}}%
   \endgroup
   \dodoplacepublications   }

%D And the portion with the entries only.

\def\placepublications
  {\dosingleempty\doplacepublications}

\def\doplacepublications[#1]%
  {%\getparameters[\??pv data][#1]
   \begingroup
   \setuplist[pubs][\c!criterium=\v!previous,#1]%
   \dodoplacepublications }%

\def\dodoplacepublications%
  {\initializepubslist
   \doifelsevalue
      {\??li pubs\c!option}{\v!continue}%
      {}%
      {\global\let\bibcounter\!!zerocount }%
   \inpublisttrue
   \typesetpubslist
   \inpublistfalse
   \endgroup}

%D \subsubject{What's in a publication}

\unexpanded\def\typesetapublication#1%
  {\doifsomething{#1}
     {\doglobal\increment\bibcounter
      \bgroup
      \the\initializebibdefinitions
      \makepbkvalue{#1}%
      \ifgridsnapping
       \snaptogrid\vbox{\dodolistelement{pubs}{}{\bibcounter}%
         {\expanded{\reference[\bibrefprefix#1]{\bibcounter}}%
          \strut \dotypesetapublication{#1}\strut }{}{}}%
     \else
       \dodolistelement{pubs}{}{\bibcounter}%
         {\expanded{\reference[\bibrefprefix#1]{\bibcounter}}%
         \strut \dotypesetapublication{#1}\strut }{}{}%
     \fi
     \egroup}}

\def\dotypesetapublication#1%
  {\bgroup
   \def\@@currentalternative{data}%
   \processcommacommand[\bibcommandlist,crossref]\clearbibitem
   \processcommalist   [artauthor,author,editor]\clearbibitemtwo
   \processcommacommand[\bibcommandlist]\bibitemdefs
   \processcommalist   [artauthor,author,editor,crossref]\bibitemdefs
   \let\biblanguage\empty
   \getvalue{pbdd-#1}%
   \ifcsname pbdt-#1\endcsname \bibalternative{\getvalue{pbdt-#1}}\fi
   \egroup }

%D An afterthought:

\def\maybeyear#1{}

%D An another:

\def\noopsort#1{}

%D This is the result of bibtex's `language' field.

\def\setbiblanguage#1#2{\setvalue{\??pb @lang@#1}{#2}}

\def\lang#1%
   {\def\biblanguage{#1}%
    \ifcsname \??pb @lang@#1\endcsname
        \expanded{\language[\getvalue{\??pb @lang@#1}]}%
     \fi \ignorespaces}

%D \subject{Citations}
%D
%D \macros{cite,bibref}
%D
%D The indirection with \type{\dobibref} allows \LATEX\ style
%D \type{\cite} commands with a braced argument (these might appear
%D in included data from the \type{.bib} file).

% \unexpanded\def\cite
%   {\doifnextcharelse{[}
%      {\dodocite}
%      {\dobibref}}
% \def\dobibref#1%
%   {\docite[#1][]}
% \def\dodocite[#1]%
%   {\startstrictinspectnextcharacter
%    \dodoubleempty\dododocite[#1]}
% \def\dododocite[#1][#2]{%
%    \stopstrictinspectnextcharacter
%    \docite[#1][#2]}

\unexpanded\def\cite
  {\strictdoifnextoptionalelse\dodocite\dobibref}

\def\dobibref#1%
  {\docite[#1][]}

\def\dodocite[#1]%
  {\strictdoifnextoptionalelse{\docite[#1]}{\docite[#1][]}}

\def\docite[#1][#2]%
  {\begingroup
   \setupinteraction[\c!style=]%
   \edef\temp{#2}%
   \ifx\empty\temp   \secondargumentfalse
   \else             \secondargumenttrue   \fi
   \ifsecondargument
     \processcommalist[#2]\docitation
     \doifassignmentelse
       {#1}%
       {\getparameters[LO][\c!alternative=,\c!extras=,#1]%
        \edef\@@currentalternative{\LOalternative}%
	    \ifx\@@currentalternative\empty
          \edef\@@currentalternative{\@@citedefault}%
        \fi
	    \ifx\LOextras\empty
          \setupcite[\@@currentalternative][#1]%
        \else
	      \expandafter\ifx\csname LOright\endcsname \relax
              \edef\LOextras{{\LOextras\bibalternative\c!right}}%
          \else
              \edef\LOextras{{\LOextras\LOright}}%
          \fi
          \expanded{\setupcite[\@@currentalternative][#1,\c!right=\LOextras]}%
        \fi
       }%
       {\def\@@currentalternative{#1}}%
      \expanded{%
         \processaction[\csname @@pv\@@currentalternative \c!compress\endcsname]}
             [    \v!yes=>\bibcitecompresstrue,
                   \v!no=>\bibcitecompressfalse,
              \s!default=>\bibcitecompresstrue,
              \s!unknown=>\bibcitecompresstrue]%
      \getvalue{bib\@@currentalternative ref}[#2]%
   \else
     \processcommalist[#1]\docitation
     \expanded{\processaction[\csname @@pv\@@citedefault \c!compress\endcsname]}
       [    \v!yes=>\bibcitecompresstrue,
             \v!no=>\bibcitecompressfalse,
        \s!default=>\bibcitecompresstrue,
        \s!unknown=>\bibcitecompresstrue]%
     \edef\@@currentalternative{\@@citedefault}%
     \getvalue{bib\@@citedefault ref}[#1]%
   \fi
   \endgroup}

%D \macros{nocite}

\def\nocite[#1]%
  {\processcommalist[#1]\addthisref
   \processcommalist[#1]\docitation }

%D \macros{setupcite}

\def\setupcite{\dodoubleempty\dosetupcite}

\def\dosetupcite[#1][#2]%
  {\ifsecondargument
     \def\dodosetupcite##1{\getparameters[\??pv##1][#2]}%
     \processcommalist[#1]\dodosetupcite
   \else % default case
     \getparameters[\??pv\@@citedefault][#1]%
   \fi }

%D Low-level stuff

\def\getcitedata#1[#2]#3[#4]#5to#6%
  {\bgroup
   \addthisref{#4}%
   \dofetchapublication{#4}%
   \doifdefinedelse{@@pb@bib#2}%
     {\xdef#6{\getvalue{@@pb@bib#2}}}%
     {\xdef#6{\getvalue{@@pb@#2}}}%
   \egroup}

\def\dofetchapublication#1%
  {\makepbkvalue{#1}%
   \processcommacommand[\bibcommandlist,crossref]\clearbibitem
   \processcommalist   [artauthor,author,editor]\clearbibitemtwo
   \processcommacommand[\bibcommandlist]\bibitemdefs
   \processcommalist   [artauthor,author,editor,crossref]\bibitemdefs
   \getvalue{pbdd-#1}}

%D This new version writes a reference out to the tui file for every
%D \type{\cite}. This will allow backlinking.
%D
%D Some special care is needed so that references are not added from
%D weird locations like in the TOC or within a \type{\setbox} command.

\newcounter\citationnumber

\def\docitation#1{%
  \iftrialtypesetting \else
    \ifdoinpututilities\else
      \doglobal\increment\citationnumber
      \expanded{\rawreference{}{cite-\jobname-\citationnumber}{#1}}%
  \fi \fi }

%D \macros{numreferred,doifreferredelse,addthisref,publist}
%D
%D The interesting command here is \type{\addthisref}, which maintains
%D the global list of references.
%D
%D \type{\numreferred} is needed to do automatic calculations on
%D the label width, and \type{\doifreferredelse} will be used
%D to implement \type{criterium=cite}.

\newcounter\numreferred

\long\def\doifreferredelse#1{\doifdefinedelse{pbr-#1}}

\def\addthisref#1%
  {\doifundefinedelse{pbr-#1}
     {\setxvalue{pbr-#1}{\citationnumber}%
      \doglobal\increment\numreferred
      \ifx\publist\empty \gdef\publist{#1}\else\appended\gdef\publist{,#1}\fi}
     {\setxvalue{pbr-#1}{\getvalue{pbr-#1},\citationnumber}}}

\let\publist\empty

%D \macros{doifbibreferencefoundelse}
%D
%D Some macros to fetch the information provided by
%D \type{\startpublication}.

\def\doifbibreferencefoundelse#1%
  {\preloadbiblist
   \doifdefinedelse{pbdk-#1}
     {\firstoftwoarguments}
     {\showmessage\m!publications{5}{#1 is unknown}%
      \secondoftwoarguments}}

%D \macros{ixbibauthoryear,thebibauthors,thebibyears}
%D
%D If compression of \type{\cite}'s argument expansion is on,
%D the macros that deal with authors and years call this internal
%D command to do the actual typesetting.
%D
%D Two entries with same author but with different years may
%D be condensed into ``Author (year1,year2)''. This is about the
%D only optimization that makes sense for the (author,year)
%D style of citations (years within one author have to be unique
%D anyway so no need to test for that, and ``Author1, Author2 (year)''
%D creates more confusion than it does good).
%D
%D In the code below,
%D the macro \type{\thebibauthors} holds the names of the alternative
%D author info fields for the current list. This is a commalist,
%D and \type{\thebibyears} holds the (collection of) year(s) that go with
%D this author (possibly as a nested commalist).
%D
%D There had better be an author for all cases, but there
%D does not have to be year info always. \type{\thebibyears} is
%D pre-initialized because this makes the insertion macros simpler.
%D
%D In `normal' \TeX, of course there are expansion problems again.

\def\ixbibauthoryear#1#2#3#4%
  {\bgroup
   \gdef\ixlastcommand  {#4}%
   \gdef\ixsecondcommand{#3}%
   \gdef\ixfirstcommand {#2}%
   \glet\thebibauthors  \empty
   \glet\thebibyears    \empty
   \getcommalistsize[#1]%
   \ifbibcitecompress
     \dorecurse\commalistsize{\xdef\thebibyears{\thebibyears,}}%
     \processcommalist[#1]\docompressbibauthoryear
   \else
     \processcommalist[#1]\donormalbibauthoryear
   \fi
   \egroup
   \dobibauthoryear}

%D \macros{dodobibauthoryear}
%D
%D This macro only has to make sure that the lists
%D \type{\thebibauthors} and \type{\thebibyears} are printed.

\def\dobibauthoryear
  {\scratchcounter\zerocount
   \getcommacommandsize[\thebibauthors]%
   \edef\authorcount{\commalistsize}%
   \@EA\processcommalist\@EA[\thebibauthors]\dodobibauthoryear}

\def\dodobibauthoryear#1%
  {\advance\scratchcounter\plusone
   \edef\wantednumber{\the\scratchcounter}%
   \getfromcommacommand[\thebibyears][\wantednumber]%
   \@EA\def\@EA\currentbibyear\@EA{\commalistelement}%
   \setcurrentbibauthor{#1}%
   \ifnum\scratchcounter=\plusone
     \ixfirstcommand
   \else\ifnum \scratchcounter=\authorcount\relax
     \ixlastcommand
   \else
     \ixsecondcommand
   \fi\fi}

\def\setcurrentbibauthor#1%
 {\getcommacommandsize[#1]%
  \ifcase\commalistsize
   % anonymous?
   \def\currentbibauthor{}%
  \or
   \def\currentbibauthor{#1}%
  \or
   \expanded{\docurrentbibauthor#1}%
  \else
   \handlemultiplebibauthors{\commalistsize}{#1}%
  \fi }

\newcount\citescratchcounter

\def\handlemultiplebibauthors#1#2%
  {\citescratchcounter 0
   \def\currentbibauthor{}%
   \def\bibprocessauthoritem##1%
       {\advance\citescratchcounter1
        \ifnum \citescratchcounter=#1\relax
           \edef\currentbibauthor{\currentbibauthor##1}%
        \else \ifnum\numexpr\citescratchcounter+1 = #1\relax
             \edef\currentbibauthor{\currentbibauthor ##1\bibalternative{andtext}}%
          \else
             \edef\currentbibauthor{\currentbibauthor ##1\bibalternative{namesep}}%
          \fi
        \fi }%
     \processcommalist[#2]\bibprocessauthoritem }

\setupcite
       [author,authoryear,authoryears]
       [\c!namesep={, }]

%D This discovery of authoretallimit is not the best one,
%D but it will do for now.

\def\docurrentbibauthor#1,#2%
  {\doifemptyelse{#2}
      {\def\currentbibauthor{#1\bibalternative{otherstext}}}
      {\@EA
       \ifx\csname \??pv\@@currentalternative authoretallimit\endcsname\relax
          \edef\currentbibauthor{#1\bibalternative{andtext}#2}%
       \else
          \edef\currentbibauthor{#1%
            \ifcase0\bibalternative{authoretallimit}\relax\or
            \bibalternative{otherstext}\else\bibalternative{andtext}#2\fi}%
       \fi}}

%D This is not the one Hans made for me, because I need a global
%D edef, and the \type{\robustdoifinsetelse} doesn't listen to
%D \type{\doglobal }

\def\robustaddtocommalist#1#2% {item} \cs
  {\robustdoifinsetelse{#1}#2\resetglobal
     {\dodoglobal\xdef#2{\ifx#2\empty\else#2,\fi#1}}}

%D \macros{donormalbibauthoryear}
%D
%D Now we get to the macros that fill the two lists.
%D The `simple' one really is quite simple.

\def\donormalbibauthoryear#1%
  {\addthisref{#1}%
   \def\myauthor{Xxxxxxxxxx}%
   \def\myyear{0000}%
   \doifbibreferencefoundelse{#1}
     {\def\myauthor{{\getvalue{pbda-#1}}}%
      \def\myyear  {\getvalue{pbdy-#1}}}%
     {}%
   \@EA\doglobal\@EA\appendtocommalist\@EA{\myauthor}\thebibauthors
   \@EA\doglobal\@EA\appendtocommalist\@EA{\myyear  }\thebibyears}

%D \macros{docompressbibauthoryear}
%D
%D So much for the easy parts. Nothing at all will be done if
%D the reference is not found or the reference does not contain
%D author data. No questions marks o.s.s. (to be fixed later)

\def\docompressbibauthoryear#1%
  {\addthisref{#1}%
   \def\myauthor{Xxxxxxxxxx}%
   \def\myyear  {0000}%
   \doifbibreferencefoundelse{#1}
     {\xdef\myauthor{\csname pbda-#1\endcsname }%
      \xdef\myyear  {\csname pbdy-#1\endcsname }}
     {}%
    \ifx\myauthor\empty\else
      \checkifmyauthoralreadyexists
      \findmatchingyear
    \fi}

%D two temporary counters. One of these two can possibly be replaced
%D by \type{\scratchcounter}.

\newcount\bibitemcounter
\newcount\bibitemwanted

%D The first portion is simple enough: if this is the very first author
%D it is quite straightforward to add it. \type{\bibitemcounter} and
%D \type{\bibitemwanted} are needed later to insert the year
%D information in the correct item of \type{\thebibyears}

\def\checkifmyauthoralreadyexists
  {\doifemptyelsevalue{thebibauthors}
     {\global\bibitemwanted  \plusone
      \global\bibitemcounter \plusone
      \xdef\thebibauthors{{\myauthor}}}
     {% the next weirdness is because according to \getcommalistsize,
      % the length of \type{[{{},{}}]} is 2.
      \@EA\getcommalistsize\@EA[\thebibauthors,]%
      \global\bibitemcounter\commalistsize
      \global\advance\bibitemcounter\minusone
      \global\bibitemwanted \zerocount
      \processcommacommand[\thebibauthors]\docomparemyauthor}}

%D The outer \type{\ifnum} accomplishes the addition of
%D a new author to \type{\thebibauthors}. The messing about with
%D the two counters is again to make sure that \type{\thebibyears}
%D will be updated correctly.If the author {\it was} found,
%D the counters will stay at their present values and everything
%D will be setup properly to insert the year info.

\def\docomparemyauthor#1%
  {\global\advance\bibitemwanted \plusone
   \def\mytempc{#1}%
%   \message{authors: \myauthor <=>\mytempc \ifx\mytempc\myauthor :Y \else :N
%          \meaning \myauthor, \meaning\mytempc\fi (\the\bibitemwanted = \the\bibitemcounter)}%
   \ifx\mytempc\myauthor
     \quitcommalist
   \else
     \ifnum\bibitemwanted = \bibitemcounter\relax
       \global\advance\bibitemwanted \plusone
       \global\bibitemcounter\bibitemwanted\relax
       \@EA\doglobal\@EA\robustaddtocommalist\@EA{{\myauthor}}\thebibauthors
     \fi
   \fi}

%D This macro should be clear now.

\def\findmatchingyear
  {\edef\wantednumber{\the\bibitemwanted}%
   \getfromcommacommand[\thebibyears][\wantednumber]%
   \ifx\commalistelement\empty
     \edef\myyear{{\myyear}}%
   \else
     \edef\myyear{{\commalistelement, \myyear}}%
   \fi
   \edef\newcommalistelement{\myyear}%
   \doglobal\replaceincommalist \thebibyears \wantednumber}

%D \macros{preparebibrefprefix}
%D
%D The reference list only writes bare references when the criterium
%D is `all'. Otherwise, a prefix is added to make sure that pdfTeX
%D does not encounter duplicate named references. On the generation
%D side, this is not a big problem. \type{\preparebibrefprefix}
%D creates a suitable string to prepend if a prefix is needed.
%D
%D Because this macro is used within \type{\cite } that itself
%D can be used within lists like the table of contents, it needs
%D to save and restore \type{\savedalltoclevels} and
%D \type{\currentlevel} (\type{\dosetfilterlevel} needs to change
%D their values globally).

\def\preparebibrefprefix
   {\chardef\savedalltoclevels \alltoclevels
	\let\savedcurrentlevel\currentlevel
    \let\dosetfilterlevel\patcheddosetfilterlevel
    \dosettoclevel\??li{pubs}%
    \edef\bibrefprefix{\@@sectiontype\currentlevel\sectionseparator}%
    \let\dosetfilterlevel\normaldosetfilterlevel
	\global\let\currentlevel\savedcurrentlevel
    \global\chardef\alltoclevels \savedalltoclevels  }

%D \macros{preparebibreflist}
%D
%D But this optional prefixing is a bit of a problem on the
%D other side. We would like to do \type{\goto{}[article-full]}
%D but can't do it like that, because the actual label may be
%D \type{1:2:0:3:4:article-full]} or so. The problem is solved
%D by building a commalist that looks like this:
%D \starttyping
%D \def\bibreflist%
%D    {1:2:0:3:4:article-full,
%D     1:2:0:3:article-full,
%D     1:2:0:article-full,
%D     1:2:article-full,
%D     1:article-full,
%D     article-full}
%D \stoptyping

\def\preparebibreflist#1%
   {\let\bibreflist\empty
    \def\storeitem##1%
      {\ifx\bibreflist\empty
         \edef\prefix{##1\sectionseparator}%
         \edef\bibreflist{\prefix#1,#1}%
      \else
         \edef\prefix{\prefix##1\sectionseparator}%
         \edef\bibreflist{\prefix#1,\bibreflist}%
      \fi}%
	\expanded{\processseparatedlist[\bibrefprefix][\sectionseparator]}\storeitem }

%D \macros{gotobiblink,inbiblink,atbiblink}
%D
%D The final task is looping over that list until a match is found.

\newif\ifbibreffound

\def\gotobiblink#1[#2]%
   {\bgroup
    \preparebibrefprefix
    \preparebibreflist{#2}%
    \global\bibreffoundfalse
    \def\setuplink##1%
          {\ifbibreffound\else
           \doifreferencefoundelse
               {##1}
               {\global\bibreffoundtrue \goto{#1}[##1]}%
               {}\fi}%
    \processcommacommand[\bibreflist]\setuplink
    \ifbibreffound \else \unknownreference{#2}\fi
    \egroup }

\def\atbiblink[#1]%
   {\bgroup
    \preparebibrefprefix
    \preparebibreflist{#1}%
    \global\bibreffoundfalse
    \def\setuplink##1%
          {\ifbibreffound\else
           \doifreferencefoundelse
               {##1}
               {\global\bibreffoundtrue \at[##1]}%
               {}\fi}%
    \processcommacommand[\bibreflist]\setuplink
    \ifbibreffound \else \unknownreference{#1}\fi
    \egroup }

\def\inbiblink[#1]%
   {\bgroup
    \preparebibrefprefix
    \preparebibreflist{#1}%
    \global\bibreffoundfalse
    \def\setuplink##1%
          {\ifbibreffound\else
           \doifreferencefoundelse
               {##1}
               {\global\bibreffoundtrue \in[##1]}%
               {}\fi}%
    \processcommacommand[\bibreflist]\setuplink
    \ifbibreffound \else \unknownreference{#1}\fi
    \egroup }

%D \macros{bibauthoryearref,bibauthoryearsref,bibauthorref,bibyearref}
%D
%D Now that all the hard work has been done, these are simple.
%D \type{\ixbibauthoryearref} stores the data in the macros
%D \type{\currentbibauthor} and \type{\currentbibyear}.

\def\ifbibinteractionelse%
  {\iflocation
      \edef\test{\bibalternative\c!interaction}%
      \ifx\test\v!stop
        \@EA\@EA\@EA\secondoftwoarguments
      \else
       \@EA\@EA\@EA\firstoftwoarguments
      \fi
    \else
       \@EA\secondoftwoarguments
    \fi
     }

\def\bibmaybeinteractive#1#2%
  {\ifbibcitecompress #2\else
   \ifbibinteractionelse{\gotobiblink{#2}[#1]}{#2}\fi }

\def\bibauthoryearref[#1]%
 {\ixbibauthoryear{#1}%
   {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
      \bibalternative\v!left{\currentbibyear}\bibalternative\v!right}}
   {\bibalternative\c!pubsep
    \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
      \bibalternative\v!left  {\currentbibyear}\bibalternative\v!right}}
   {\bibalternative\c!lastpubsep
    \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
      \bibalternative\v!left {\currentbibyear}\bibalternative\v!right}}}

\def\bibauthoryearsref[#1]%
  {\bibalternative\v!left
   \ixbibauthoryear{#1}
     {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}
     {\bibalternative\c!pubsep
      \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}
     {\bibalternative\c!lastpubsep
      \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}%
   \bibalternative\v!right}

\def\bibauthorref[#1]%
  {\bibalternative\v!left
   \ixbibauthoryear{#1}%
    {\bibmaybeinteractive{#1}{{\currentbibauthor}}}
    {\bibalternative\c!pubsep    \bibmaybeinteractive{#1}{{\currentbibauthor}}}
    {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibauthor}}}%
   \bibalternative\v!right}

\def\bibyearref[#1]%
  {\bibalternative\v!left
   \ixbibauthoryear{#1}%
      {\bibmaybeinteractive{#1}{{\currentbibyear}}}
      {\bibalternative\c!pubsep    \bibmaybeinteractive{#1}{{\currentbibyear}}}
      {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibyear}}}%
   \bibalternative\v!right}

%D ML problems:

%D \macros{bibshortref,bibkeyref,bibpageref,bibtyperef,bibserialref}
%D
%D There is hardly any point in trying to compress these. The only
%D thing that needs to be done is making sure that
%D the separations are inserted correctly. And that is
%D what \type{\refsep} does.

\newif\iffirstref

\def\refsep{\iffirstref\firstreffalse\else\bibalternative\c!pubsep\fi}

\def\bibshortref[#1]%
  {\bibalternative\v!left
   \firstreftrue\processcommalist[#1]\dobibshortref
   \bibalternative\v!right}

\def\dobibshortref#1%
  {\addthisref{#1}\refsep
   \doifbibreferencefoundelse{#1}{\gotobiblink{\getvalue{pbds-#1}}[#1]}
	 {\unknownreference{#1}}}


\def\bibserialref[#1]%
  {\bibalternative\v!left
   \firstreftrue\processcommalist[#1]\dobibserialref
   \bibalternative\v!right}

\def\dobibserialref#1%
  {\addthisref{#1}\refsep
   \doifbibreferencefoundelse{#1}{\gotobiblink{\getvalue{pbdn-#1}}[#1]}
      {\unknownreference{#1}}}

\def\bibkeyref[#1]%
  {\bibalternative\v!left
   \firstreftrue\processcommalist[#1]\dobibkeyref
   \bibalternative\v!right}

\def\dobibkeyref#1%
  {\addthisref{#1}\refsep\gotobiblink{#1}[#1]}

\def\gotoDOI#1#2%
  {\ifbibinteractionelse
     {\useURL[bibfooDoi#1][#2]%
      \useURL[bibfoo#1][http://dx.doi.org/#2]%
      \goto{\url[bibfooDoi#1]}[url(bibfoo#1)]}
     {\hyphenatedurl{#2}}}

\def\bibdoiref[#1]%
  {\bibalternative\v!left
   \firstreftrue\processcommalist[#1]\dobibdoiref
   \bibalternative\v!right}

\def\dobibdoiref#1%
  {\addthisref{#1}\refsep
   \doifbibreferencefoundelse{#1}{\expanded{\gotoDOI{#1}{\getvalue{pbdo-#1}}}}
        {\unknownreference{#1}}}

\def\biburlref[#1]%
  {\bibalternative\v!left
   \firstreftrue\processcommalist[#1]\dobiburlref
   \bibalternative\v!right}

\def\gotoURL#1#2%
   {\ifbibinteractionelse
       {\useURL[bibfoo#1][#2]\goto{\url[bibfoo#1]}[url(bibfoo#1)]}
       {\hyphenatedurl{#2}}}

\def\dobiburlref#1%
  {\addthisref{#1}\refsep
   \doifbibreferencefoundelse{#1}{\expanded{\gotoURL{#1}{\getvalue{pbdu-#1}}}}
      {\unknownreference{#1}}}

\def\bibtyperef[#1]%
  {\bibalternative\v!left
   \firstreftrue\processcommalist[#1]\dobibtyperef
   \bibalternative\v!right}

\def\dobibtyperef#1%
  {\addthisref{#1}\refsep
   \doifbibreferencefoundelse{#1}{\gotobiblink{\getvalue{pbdt-#1}}[#1]}
       {\unknownreference{#1}}}

\def\bibpageref[#1]%
  {\bibalternative\v!left
   \firstreftrue\processcommalist[#1]\dobibpageref
   \bibalternative\v!right}

\def\dobibpageref#1%
  {\addthisref{#1}\refsep
   \ifbibinteractionelse{\atbiblink[#1]}{{\referencingfalse\at[#1]}}}

\def\bibdataref[#1]%
  {\bibalternative\v!left
   \firstreftrue\processcommalist[#1]\dobibdata
   \bibalternative\v!right}

\def\dobibdata#1%
  {\addthisref{#1}\refsep
   \doifbibreferencefoundelse{#1}{\dotypesetapublication{#1}}
       {\unknownreference{#1}}}

\let\bibnoneref\nocite

%D \macros{bibnumref}
%D
%D It makes sense to try and compress the argument list of
%D \type{\bibnumref}. There are two things involved: the actual
%D compression, and a sort routine. The idea is to store the
%D found values in a new commalist called \type{\therefs}.

%D But that is not too straight-forward, because \type{\in} is
%D not expandable,
%D so that the macro \type{\expandrefs} is needed.

\def\expandrefs#1%
   {\bgroup
    \preparebibrefprefix
    \preparebibreflist{#1}%
    \global\bibreffoundfalse
    \def\setuplink##1%
          {\ifbibreffound\else
           \doifreferencefoundelse
               {##1}
               {\global\bibreffoundtrue
                \@EA\doglobal\@EA\addtocommalist\@EA{\reftypet}\therefs }%
               {}\fi}%
    \processcommacommand[\bibreflist]\setuplink
    \ifbibreffound \else \showmessage\m!publications{5}{#1 unknown}%
       \doglobal\addtocommalist{0}\therefs\fi
    \egroup }

%D But at least the actual sorting code is simple (note that sorting
%D a list with exactly one entry fails to return anything, which
%D is why the \type{\ifx} is needed).

\def\bibnumref[#1]%
  {\bibalternative\v!left
   \penalty\!!tenthousand
   \processcommalist[#1]\addthisref
   \firstreftrue
   \ifbibcitecompress
     \glet\therefs\empty
     \processcommalist[#1]\expandrefs
     \sortcommacommand[\therefs]\donumericcompare
     \ifx\empty\sortedcommalist\else
       \let\therefs\sortedcommalist
     \fi
     \compresscommacommandnrs[\therefs]%
     \processcommacommand[\compressedlist]\verysimplebibnumref
   \else
     \processcommalist[#1]\dosimplebibnumref
   \fi
   \bibalternative\v!right}

\def\dosimplebibnumref  #1%
  {\refsep\ifbibinteractionelse
     {\inbiblink[#1]}{{\referencingfalse\inbiblink[#1]}}}

\def\verysimplebibnumref#1{\doverysimplebibnumref#1}

\def\doverysimplebibnumref#1#2%
  {\refsep
   \ifcase#1\relax \unknownreference{#1}\else
     \def\tempa{#2}\ifx\empty\tempa#1\else#1\bibalternative\c!inbetween#2\fi
   \fi}

%D By request from Sanjoy. This makes it easier to implement
%D \type{\citeasnoun}.

\def\bibauthornumref[#1]%
  {\getcommalistsize[#1]%
   \global\bibitemcounter\commalistsize
   \firstreftrue
   \processcommalist[#1]\dobibauthornumref }

\def\dobibauthornumref#1%
  {\addthisref{#1}\refsep
   \doifbibreferencefoundelse{#1}
      {\getvalue{pbda-#1}%
       \bibalternative\c!inbetween
       \bibalternative\v!left
       \ifbibinteractionelse{\inbiblink[#1]}
            {{\referencingfalse\inbiblink[#1]}}%
       \bibalternative\v!right}
      {\unknownreference{#1}}}

%D And some defaults are loaded from bibl-apa:

\setuppublications
  [\v!month\v!conversion=,
   \c!alternative=apa]

\appendtoks
    \preloadbiblist
\to \everystarttext

\protect \endinput
