%D \module %D [ file=t-bib, %D version=2006.08.08, %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 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 \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 A few new shortcuts: \definesystemvariable {pv} % PublicationVariable \definesystemvariable {pb} % PuBlication \definemessageconstant {bib} \definefileconstant {bibextension} {bbl} %D Some user information messages. \startmessages all library: bib title: publications 1: file -- not found, unknown style ignored 2: file -- not found, waiting for bibtex 3: wrote a new auxiliary file \jobname.aux 4: loading database from -- 5: warning: cite argument -- on \the\inputlineno 6: loading formatting style from -- \stopmessages %D Some constants for the multi-lingual interface \startconstants dutch english database: database database artauthor: artauthor artauthor editor: editor editor authoretallimit: authoretallimit authoretallimit artauthoretallimit: artauthoretallimit artauthoretallimit editoretallimit: editoretallimit editoretallimit authoretaldisplay: authoretaldisplay authoretaldisplay artauthoretaldisplay: artauthoretaldisplay artauthoretaldisplay editoretaldisplay: editoretaldisplay editoretaldisplay authoretaltext: authoretaltext authoretaltext artauthoretaltext: artauthoretaltext artauthoretaltext editoretaltext: editoretaltext editoretaltext otherstext: otherstext otherstext andtext: andtext andtext totalnumber: totalnumber totalnumber firstnamesep: firstnamesep firstnamesep vonsep: vonsep vonsep juniorsep: juniorsep juniorsep surnamesep: surnamesep surnamesep lastnamesep: lastnamesep lastnamesep finalnamesep: finalnamesep finalnamesep namesep: namesep namesep pubsep: pubsep pubsep lastpubsep: lastpubsep lastpubsep refcommand: refcommand refcommand samplesize: samplesize samplesize \stopconstants \startvariables dutch english german czech italian romanian french title: titel title titel titul titolo titlu titre short: kort short kurz short short short short cite: cite cite cite cite cite cite cite bbl: bbl bbl bbl bbl bbl bbl bbl bib: bib bib bib bib bib bib bib author: auteur author autor autor autore autor auteur \stopvariables \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 \definelist[pubs] \setuplist[pubs][\c!width=] %D The text string for the publication list header \setupheadtext[en][pubs=References] \setupheadtext[nl][pubs=Literatuur] \setupheadtext[de][pubs=Literatur] \setupheadtext[it][pubs=Bibliografia] \setupheadtext[sl][pubs=Literatura] \setupheadtext[fr][pubs=Bibliographie] %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 \let\@@pbsort \empty \getparameters[\??pb][#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{cont-no}]% \ifx\@@pbdatabase\empty\else \writeauxfile \fi} %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{*first} {\openout \scratchwrite \jobname.aux \write \scratchwrite {\string\citation{*}}% \write \scratchwrite {\string\bibstyle{\bibstyle}}% \write \scratchwrite {\string\bibdata{\@@pbdatabase}}% \closeout\scratchwrite \showmessage\m!bib{3}{}% \installprogram{bibtex \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!bib{6}{bibl-\@@pbalternative}\let\@@pbalternative\empty} {\showmessage\m!bib{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!bib{4}{#1.\f!bibextension}} {\showmessage\m!bib{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. \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\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\insertbiburl#1#2#3% {{\bibdoifelse{\@@pb@biburl}% {\edef\ascii{\@EA\detokenize\@EA{\@@pb@biburl}}% #1\@EA\hyphenatedurl\@EA{\ascii}#2}{#3}}} \def\insertmonth#1#2#3% {\bibdoifelse{\@@pb@month}% {#1\doifnumberelse{\@@pb@month}% {\doifconversiondefinedelse\@@pbmonthconversion {\convertnumber\@@pbmonthconversion{\@@pb@month}}{\@@pb@month}}% {\@@pb@month}#2}{#3}} \let\inserturl \insertbiburl % for backward compat. \let\inserttype\insertbibtype % for backward compat. \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\insertcrossref#1#2#3% {\bibdoifelse{\@@pb@crossref} {#1\@EA\cite\@EA[\@@pb@crossref]#2} {#3}} %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}}} \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 \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 liust has been reordered here, and the meanings %D 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). \def\startpublication{\dosingleempty\dostartpublication} \def\stoppublication {} %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 } % 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}} %D \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} \unless\ifcsname currentlocationrefence\endcsname \let\currentlocationreference\empty \def\dogetreferenceelements#1#2#3#4#5% {\chardef\currentreferencetype=\ifx#1\relax0\else#1\fi\relax \ifnum\currentreferencetype<2 \edef\currentpagereference{#2}% \let \currentdatareference\empty \edef\currentlocationreference{#2}% \ifx\currentpagereference \empty \let\currentfolioreference\folio \else \def \currentpagereference {\referencepagenumber[#2]}% \edef\currentfolioreference{\dosplitofffoliopart[#2]}% \fi \edef\currentrealreference{#3}% \settextreferences#4\end \ifnum0#5<\crossreferencenumber \forwardreferencetrue \else \forwardreferencefalse \fi \else \let \currentlocationreference\empty \edef\currentrealreference {#3}% \def \currentdatareference {#2}% \let \currentfolioreference\folio \settextreferences#4\end \forwardreferencefalse \fi \ifodd\currentreferencetype \realreferencepagefalse \else \docheckrealreferencepage\currentrealreference \ifrealreferencepage \else \docheckrealreferencepage\currentdatareference \fi \fi} \fi \def\filllocalpublist% {\let\dosetfilterlevel\patcheddosetfilterlevel \dosettoclevel\??li{pubs}% \let\dosetfilterlevel\normaldosetfilterlevel \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 \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]% \def\@@pblimitednumber##1{\hbox to \samplewidth{\@@pbnumbercommand{##1}}}% \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 \ifx\@@pbnumbering\v!no \setuplist[pubs][\c!numbercommand=,\c!symbol=\v!none,\c!textcommand=\outdented] \else \setuplist[pubs][\c!numbercommand=\@@pblimitednumber]% \fi \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\docompletepublications[#1]% {%\getparameters[\??pv data][#1]% \begingroup \setuplist[pubs][\c!criterium=\v!previous,#1] \begingroup \loggingall \let\handletextprefix\firstoftwoarguments \edef\headtextpubs{\dogetupsometextprefix\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 \global\let\bibcounter\!!zerocount \inpublisttrue \typesetpubslist \inpublistfalse \endgroup } %D \subsubject{What's in a publication} %D \unexpanded\def\typesetapublication#1% {\doifsomething{#1}{\doglobal\increment\bibcounter \dodolistelement{pubs}{}{\bibcounter}% {\expanded{\reference[\bibrefprefix#1]{\bibcounter}}% \strut \dotypesetapublication{#1}\strut }{}{}}} \def\dotypesetapublication#1% {\bgroup \def\@@currentalternative{data}% \makepbkvalue{#1}% \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 \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]} \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#2#3% {\doifdefinedelse{pbdk-#1} {#2} {\showmessage\m!bib{5}{#1 is unknown}#3}} %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]% \@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=\commalistsize\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 % this can't happen/ \def\currentbibauthor{}% \fi } \def\docurrentbibauthor#1,#2% {\doifemptyelse{#2} {\def\currentbibauthor{#1\bibalternative{otherstext}}} {\edef\currentbibauthor{#1% \ifcase0\bibalternative{authoretallimit}\relax\or \bibalternative{otherstext}\else \bibalternative{andtext}#2\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[bibfoo#1][http://dx.doi.org/#2]\goto{\url[bibfoo#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!bib{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] \preloadbiblist \protect \endinput