%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{}} (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{}} %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 %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}{}{}{} %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