bibl-tra.mkxl /size: 54 Kb    last modification: 2023-12-21 09:44
1%D \module
2%D   [       file=bibl-tra,
3%D        version=2009.08.22,
4%D          title=\CONTEXT\ Publication Module,
5%D       subtitle=Publications,
6%D         author=Taco Hoekwater,
7%D           date=\currentdate,
8%D      copyright={Public Domain}]
9%C
10%C Donated to the public domain.
11
12%D This is really obsolete in \LMTX. For now I keep it but it will either go
13%D away. The code is not upgraded, we only deal with macro protection. I will
14%D only update the bits that annoy me in grepping for possible optimizations.
15
16% % % % watch out ... bibl-tra-new.mkiv is work in progress % % % %
17
18% % % % mlbibtex also supports context and we can run that instead of bibtex % % % %
19
20%D This module has been adapted to \MKIV\ by Hans Hagen so if things go wrong, he is
21%D to blame. The changes concern references and lists but teh rendering itself is
22%D unchanged. Future versions might provide variants as we have plans for an
23%D upgrade.
24%D
25%D We use a still somewhat experimental extension to the list mechanism. Eventually
26%D the bibtex module will use the bibl loader and access the data by means of lpath
27%D expressions. In that case we don't need to process the bibliography but still
28%D need to track usage as done here.
29%D
30%D A bit ongoing: make more local macros prefixed with bib, i.e. the bib namespace
31%D is reserved.
32
33%D Todo: commandhandler
34
35\writestatus{loading}{ConTeXt Bibliography Support / BibTeX}
36
37\definefilesynonym[bib][obsolete]
38
39\registerctxluafile{bibl-tra}{}
40
41%D The original was developed independantly by Taco Hoekwater while still working
42%D for Kluwer Academic publishers (it still used the dutch interface then).
43%D Development continued after he left Kluwer, and in Januari 2005, the then already
44%D internationalized file was merged with the core distribution by Hans Hagen. The
45%D current version is once again by Taco.
46%D
47%D More documentation and additional resources can be found on the contextgarden:
48%D \hyphenatedurl {http://wiki.contextgarden.net//Bibliography}.
49
50%D \subject{DONE (dd/mm/yyyy)}
51%D
52%D \startitemize
53%D \item add author definition (and associated system variable) (26/05/2005)
54%D \item add finalnamesep support for Oxford comma (17/09/2005)
55%D \item add \type{\insert...} for: doi, eprint, howpublished (19/09/2005)
56%D \item allow a defaulted \type{\setupcite} (19/11/2005)
57%D \item renamed citation type 'number' to 'serial' (19/11/2005)
58%D \item better definition of \type{\inverted...author} (19/11/2005)
59%D \item don't reset [numbercommand] in \type {\setuppublication} by default (20/11/2005)
60%D \item don't disable other \type {\setuppublication} keys if alternative is present (20/11/2005)
61%D \item drop \type{\sanitizeaccents} (20/11/2005)
62%D \item added \type{\nocite} and \type{\cite[none]} (21/11/2005)
63%D \item added headtext for it  (23/11/2005)
64%D \item make \type{\cite[url]} and \type{\cite[doi]} interactive (23/11/2005)
65%D \item make right-aligned labels in the list work even when autohang=no
66%D \item use 'et al.' instead of 'et.al.'. Pointed out by Peter M\"unster (30/12/2005)
67%D \item added headtext for cz (31/12/2005)
68%D \item Keep whitespace after \type{\cite} with single argument (31/12/2005)
69%D \item Fix broken \type{\cite{}} support (31/12/2005)
70%D \item Use \type{\readfile} inside \type{\usepublications} instead of \type{\readsysfile} (12/01/2006)
71%D \item Use \type{\currentbibyear} and \type{\currentbibauthor} instead of \type{\YR} and \type{\AU} (05/02/2006)
72%D \item Fix compressed version of authoryear style (05/02/2006)
73%D \item Rename the clashing data fields \type{\url} and \type{\type} to \type{\biburl} and \type{\bibtype} (05/02/2006)
74%D \item Added two french bibl files from Renaud Aubin (06/02/2006)
75%D \item Five new bib class and eight extra bib fields, for IEEEtran (07/02/2006)
76%D \item French keyword translation, provided by Renaud (08/02/2006)
77%D \item fix underscores in undefined keys (22/02/2006)
78%D \item Destroy interactivity in labels of the publication list (13/03/2006)
79%D \item fix multi-cite list compression (11/4/2006)
80%D \item fix \type{\getcitedata} (11/4/2006)
81%D \item magic for chapter bibs (18-25/4/2006)
82%D \item language setting (25/4/2006)
83%D \item use \type{\hyphenatedurl} for \type{\inserturl} (25/4/2006)
84%D \item Add \type{\docitation} to \type{\nocite}(26/4/2006)
85%D \item patents can have numbers, added to bst files (26/4/2006)
86%D \item \type{\docitation} needs a \type{\iftrialtypesetting} (27/4/2006)
87%D \item \type{\filllocalpublist}'s loop is bound by definedness, not resolvedness (27/4/2006)
88%D \item \type{\setuppublications[monthconversion=]} added (15/5/2006)
89%D \item use \type{\undefinedreference} instead of bare question marks (15/5/2006)
90%D \item add grouping around \type{\placepublications} commands (16/5/2006)
91%D \item fix a bug in \type{\cite{<item>}} (17/5/2006)
92%D \item support \type{\cite[authornum]} (18/5/2006)
93%D \item make \type{\cite} unexpandable (20/6/2006)
94%D \item allow hyperlinks in author\&year combo's
95%D       (cite list compression has to be off) (20/6/2006)
96%D \item fix duplicate labels for per-chapter style (20/6/2006)
97%D \item allow \type{\setupcite[interaction=(start|stop)]}
98%D \item fix the item number in the publication list with 'numbering=yes' (22/6/2006)
99%D \item make the default criterium for \type{\placepublications} be \type{previous} (23/6/2006)
100%D \item fix \type{\normalauthor} and \type{\normalshortauthor} spacing (29/6/2006)
101%D \item do not typeset empty arguments to \type{\typesetapublication} (29/6/2006)
102%D \item add \type{symbol=none} to \type{\setuplist} in unnumbered
103%D       mode to prevent typesetting of bare numbers (29/6/2006)
104%D \item remove two incorrect spaces from bibl-num.tex (1/7/2006)
105%D \item reset font styles within \type{\cite}, so that font switches
106%D       in \type{left} stay in effect (12/7/2006)
107%D \item guard added against loading bbl files multiple times (13/7/2006)
108%D \item fix \type{\cite[num]} with compression is on. (14/7/2006)
109%D \item test \type{\iflocation} before deciding to use the
110%D       interactive version of cite (18/7/2006)
111%D \item support \type{\setupcite[authoretallimit=1]} (18/7/2006)
112%D \item support use of \type{\cite} within titles and captions by
113%D       saveguarding the list item extraction and reference placement
114%D       code (19/7/2006)
115%D \item support \type{\setuppublicationlist[title=\chapter]} (4/8/2006)
116%D \item use the expansion of \type{\headtext{pubs}} (4/8/2006)
117%D \item hook added for repeated authors in publication list
118%D       \type{\setuppublicationlist[artauthorcommand=\mythreeargscommand]}
119%D       (4/8/2006)
120%D \item make the bracketed arguments of \type{\artauthor}, \type{\author}
121%D        and \type{\editor} (bbl commands) optional (4/8/2006)
122%D \item the constants \type{sorttype}, \type{compress} and
123%D        \type{autohang} have moved to the core (8/8/2006)
124%D \item bibtex is now registered as a program to be run by texexec (8/8/2006)
125%D \item fix a bug in \type{\setupcite[authoretallimit=1]} (9/8/2006)
126%D \item fix a bug inside citations that prevented lastpubsep from ever being
127%D       used due to a volatile \type{\commalistsize} (25/8/2006).
128%D \item added the possibility of \type{\placepublications[option=continue]}
129%D       (6/9/2006)
130%D \item Mojca translated Master's Thesis to Masterarbeit (bibl-apa-de.tex)
131%D       (12/9/2006)
132%D \item Added \type{\setuppublicationlist[maybeyear=off]} by request from
133%D       Thomas Schmitz (15/9/2006)
134%D \item Removed some spurious spaces pointed out by willi egger (19/9/2006)
135%D \item Add configuration of bibtex executable name (4/11/2006)
136%D \item Fix numbering=short and numbering=bib (spotted by Matthias W\"achter) (4/11/2006)
137%D \item third attempt to get a correct release (5/11/2006)
138%D \item fix a few missing dots in bibl-num.tex  (7/12/2006)
139%D \item Patch for DOI's by Tobias Burnus (17/4/2007)
140%D \item Patch for \type{\insertbiburl} and \type{\insertdoi} for  Tobias Burnus (18/4/2007)
141%D \item Added a missing \type{\relax} in \type{\dospecialbibinsert},
142%D       that made the space before the {\it et al.} text disappear.  (18/4/2007)
143%D \item Attempt to fix percent signs in bbl files. As a side-effect,
144%D       this prohibits comments in \tex{startpublication} blocks! (17/4/2008)
145%D \item Patch from Matthias W\"achter that allows arbitrary .bst
146%D        files to be used with \tex{setupbibtex} (25/9/2008)
147%D \item Extended for the new multilingual setups for the Oct 2008 current of ConTeXt (23/10/2008)
148%D \item Multilingual setups needed another fix (27/10/2008)
149%D \item Two fixes for bibl-apa by Michael Green (27/10/2008)
150%D \item Catalan translation of 'References' (10/11/2008)
151%D \item 'chapter' -> 'chapitre' in bibl-apa-fr (27/11/2008)
152%D \item Run bibtex via os.execute in  mkiv modee (01/12/2008)
153%D \item Small correction in bibl-apa's placement of volume
154%D       information in articles (05/01/2009)
155%D \item Handle multi-author (more than two) cases in \type{\cite}
156%D       (02/03/2009)
157%D \item Suppress a syntax error in \type{cont-xp} mode. The output is
158%D       probably not right, though (02/03/2009)
159%D \item Added a \tex{loadmarkfile} at the end, and two new files
160%D       from Hans. The \type{t-bib.mkiv} is needed to make the module
161%D       work with the new structure code (17/04/2009)
162%D \item Added a patch to \type{t-bib.mkiv} from Hans to make the
163%D       cross referencing between multiple citations an
164%D       bibliographies work (27/04/2009)
165%D \item Remove a superfluous \type{\unprotect} in t-bib.mkiv (11/05/2009).
166%D \item Patch of incollection in bibl-ams.tex from Xan (08/06/2009).
167%D \item Patch of unpublished in bibl-ams.tex from Xan (22/07/2009).
168%D \item Modified \type{\bibdogetupsometextprefix} so it works for undefined
169%D       language labels, from Hans (13/08/2009).
170%D \item Adapt referencing and list insertion to \MKIV. Update some code
171%D       to the latest \CONTEXT. Change some names in order to avoid conflicts
172%D       with existing core names (like \type {\insertpages}).
173%D \item All constants, variables, message etc.\ are now in the core.
174%D \item Added key: \type {method} (when \type {global}, previous shown entries are
175%D       not shown again, when \type {local} they are repeated).
176%D \stopitemize
177%D
178%D \subject{WISHLIST}
179%D
180%D \startitemize
181%D \item link back from publication list to citation
182%D \item export \type {\citation{<cited item>}}
183%D \item support mlbibtex
184%D \item don't load the whole lot, but filter entries instead
185%D \item 9 vs 10, 19 vs 20 ... prevent extra runs when only subtle changes in wd of reference
186%D \stopitemize
187
188\unprotect
189
190\def\biblistname{pubs} % for compatibility
191
192\definelist
193  [pubs]
194
195\setuplist
196  [pubs]
197  [\c!state=\v!start,
198   \c!criterium=\@@pbcriterium,
199   \c!headnumber=\v!always, % needed as we provide our own and need to force
200   \c!width=]
201
202\installstructurelistprocessor{pubs:userdata}%
203  {\ctxlua{bibtex.hacks.add(structures.lists.uservalue("\currentlist",\currentlistindex,"bibref"),\currentlistindex)}}
204
205\ifdefined\bibtexblock   \else \newinteger\bibtexblock   \fi \bibtexblock\plusone
206\ifdefined\bibtexcounter \else \newinteger\bibtexcounter \fi
207
208%D \macros{bibdoif,bibdoifnot,bibdoifelse}
209%D
210%D Here are a few small helpers that are used a lot in all the typesetting commands
211%D (\type{\bibinsert...}) we will encounter later.
212
213\protected\def\bibdoifelse#1%
214  {\expandafter\def\expandafter\!!stringa\expandafter{#1}%
215   \ifempty\!!stringa
216     \expandafter\secondoftwoarguments
217   \else
218     \expandafter\firstoftwoarguments
219   \fi}
220
221\protected\def\bibdoifnot#1%
222  {\expandafter\def\expandafter\!!stringa\expandafter{#1}%
223   \ifempty\!!stringa
224     \expandafter\firstofoneargument
225   \else
226     \expandafter\gobbleoneargument
227   \fi}
228
229\protected\def\bibdoif#1%
230  {\expandafter\def\expandafter\!!stringa\expandafter{#1}%
231   \ifempty\!!stringa
232     \expandafter\gobbleoneargument
233   \else
234     \expandafter\firstofoneargument
235   \fi}
236
237%D Unfortunately, \BIBTEX\ is not the best configurable program around. The names of
238%D the commands it parses as well as the \type {.aux} extension to the file name are
239%D both hardwired.
240%D
241%D This means \CONTEXT\ has to write a \LATEX-style auxiliary file, yuk! The good
242%D news is that it can be rather short. We'll just ask \BIBTEX\ to output the entire
243%D database(s) into the \type {bbl} file.
244%D
245%D The \type {\bibstyle} command controls how the \type {bbl} file will be sorted.
246%D The possibilities are:
247%D
248%D \startitemize[packed]
249%D \item by author (+year, title): cont-au.bst
250%D \item by title  (+author, year): cont-ti.bst
251%D \item by short key as in abbrev.bst: cont-ab.bst
252%D \item not sorted at all: cont-no.bst
253%D \stopitemize
254
255\newtoks\everysetupbibtex
256
257\protected\def\setupbibtex
258  {\dosingleempty\dosetupbibtex}
259
260\protected\def\dosetupbibtex[#1]%
261  {\lettonothing\@@pbdatabase
262   \getparameters[\??pb][#1]%
263   \the\everysetupbibtex}
264
265\protected\def\installbibtexsorter#1#2%
266  {\setvalue{\??pb:\c!sort:#1}{#2}}
267
268\installbibtexsorter\v!no     {no}
269\installbibtexsorter\v!author {au}
270\installbibtexsorter\v!title  {ti}
271\installbibtexsorter\v!short  {ab}
272\installbibtexsorter\empty    {no}
273\installbibtexsorter\s!default{no}
274
275\def\thebibtexsorter{\executeifdefined{\??pb:\c!sort:\@@pbsort}\@@pbsort}
276
277\appendtoks
278   \ifempty\@@pbdatabase\else
279     \doifmode{*\v!first}{\ctxlua{bibtex.hacks.process { style="\thebibtexsorter", database="\@@pbdatabase" }}}%
280   \fi
281\to \everysetupbibtex
282
283\setupbibtex
284  [\c!sorttype=\v!cite,
285   \c!sort=no]
286
287%D \macros{iftypesetall,ifbibcitecompress}
288%D
289%D The module needs some new \type{\if} statements.
290
291\newtoks\everysetuppublications
292
293\protected\def\setuppublications
294  {\dosingleargument\dosetuppublications}
295
296\protected\def\dosetuppublications[#1]%
297  {\getparameters[\??pb][\c!alternative=,#1]%
298   \doifsomething\@@pbalternative
299     {\readsysfile{bibl-\@@pbalternative.tex}
300        {\showmessage\m!publications{6}{bibl-\@@pbalternative}}
301        {\showmessage\m!publications{1}{bibl-\@@pbalternative}}%
302      \lettonothing\@@pbalternative}%
303   \let\setuppublicationlayout\normalsetuppublicationlayout % overloaded in bibl-num ... vadjust needs to be done with option
304   \getparameters[\??pb][#1]% as bibl-* can have set things back
305   \the\everysetuppublications
306   \ignorespaces}
307
308%D We can omit already shown references (\v!global) or use fresh lists each time
309%D (\v!local).
310
311\setnewconstant\bibtexoncemode\plusone % 0=disable, 1=local, 2=global
312
313\appendtoks
314  \doifelse\@@pbmethod\v!local
315    {\bibtexoncemode\plusone}%
316    {\bibtexoncemode\plustwo}%
317\to \everysetuppublications
318
319%D Cite lists are compressed, if possible. This is set later on.
320
321\newif\ifbibcitecompress\bibcitecompresstrue
322
323\def\@@pbinumbercommand{\executeifdefined{\??pb:\c!numbercommand:\@@pbnumbering}\firstofoneargument}
324
325\setvalue{\??pb:\c!numbercommand:\v!yes  }#1{#1}%
326\setvalue{\??pb:\c!numbercommand:\v!no   }#1{}
327\setvalue{\??pb:\c!numbercommand:\v!short}#1{\bibgetvars\currentpublicationkey}
328\setvalue{\??pb:\c!numbercommand:\v!bib  }#1{\bibgetvarn\currentpublicationkey}
329
330% to be tested
331%
332% \setvalue{\??pb:\c!numbercommand:\v!short}{\bibgetvars\currentpublicationkey\firstofoneargument}
333% \setvalue{\??pb:\c!numbercommand:\v!bib  }{\bibgetvarn\currentpublicationkey\firstofoneargument}
334
335\appendtoks
336  \processaction
337    [\@@pbrefcommand]
338    [\s!default=>\edef\@@citedefault{\@@pbrefcommand},
339     \s!unknown=>\edef\@@citedefault{\@@pbrefcommand}]%
340\to \everysetuppublications
341
342\protected\def\bibleftnumber#1{#1\hfill~}
343
344%D \macros{usepublications}
345%D
346%D After discussing it with Thomas Schmitz it became clear that using external
347%D references makes no sense as one needs to refer to it in special ways and because
348%D similar numbers can be confusing. So, for the moment this is not supported in
349%D \MKIV. (So no: see reference [3-5,9] in "some other document")
350
351\protected\def\usepublications[#1]%
352  {\processcommalist[#1]\dousepublications}
353
354\protected\def\dousepublications#1%
355  {\doonlyonce{#1.\f!bibextension}{\dodousepublications{#1}}}
356
357\pushoverloadmode
358
359\protected\def\dodousepublications#1% brr, this par stuff
360  {\enforced\let\par\ignorespaces
361   \ifhmode\kern\zeropoint\fi
362   \pushcatcodetable
363   \setcatcodetable\ctxcatcodes
364   \readfile{#1.\f!bibextension}
365     {\showmessage\m!publications{4}{#1.\f!bibextension}}
366     {\showmessage\m!publications{2}{#1.\f!bibextension}}%
367   \popcatcodetable
368   \ifhmode\removeunwantedspaces\fi
369   \enforced\let\par\normalpar}
370
371\popoverloadmode
372
373%D \macros{setuppublicationlist}
374%D
375%D This will be the first command in (\BIBTEX-generated) \type {bbl} files. \quote
376%D {samplesize} is a sample value (in case of \BIBTEX|-|generated files, this will
377%D be the longest \quote {short} key). Here \quote {totalnumber} is the total number
378%D of entries that will follow in this file.
379%D
380%D Both values are only needed for the label calculation if \quote {autohang} is
381%D \quote {true}, so by default the command is not even needed, and therefore I saw
382%D no need to give it it's own system variable and it just re-uses \type {pb}.
383
384\def\publicationlistparameter#1{\csname\??pv:l:#1\endcsname}
385
386\protected\def\setuppublicationlist
387  {\dosingleempty\dosetuppublicationlist}
388
389\protected\def\dosetuppublicationlist[#1]%
390  {\getparameters[\??pv:l:][#1]%
391   \setuplist[pubs][\c!samplesize={AA99},\c!alternative=a,\c!interaction=,\c!pagenumber=\v!no,#1,\c!command=]}
392
393\protected\def\setuppublicationlayout[#1]#2%
394  {\setvalue{\??pv:l:#1}{#2}}
395
396\let\normalsetuppublicationlayout\setuppublicationlayout
397
398\setuppublicationlist
399  [\c!title=,
400   \c!command=\dospecialbibinsert,
401   \c!maybeyear=\v!on]
402
403%D \macros{bibalternative}
404%D
405%D A nice little shorthand that will be used so we don't have to key in the weird
406%D \type {\@@pv} parameter names all the time.
407
408\def\bibalternative#1%
409  {\csname\??pv\@@currentalternative#1\endcsname}
410
411%D \macros{simplebibdef,bibcommandlist}
412%D
413%D \type {\simplebibdef} defines \type {bib@#1}, which in turn will use one argument
414%D that is stored in \type {@@pb@#1}.
415%D
416%D \type {\simplebibdef} also defines \type {bibinsert#1}, which can be used in the
417%D argument of \type {\setuppublicationlayout} to fetch one of the \type {@@pb@}
418%D data entries. \type {bibinsert#1} then has three arguments: \type {#1} are
419%D commands to be executed before the data, \type {#2} are commands to be executed
420%D after the data, and \type {#3} are commands to be executed if the data is not
421%D found.
422%D
423%D \type {\bibcommandlist} is the list of commands that is affected by this
424%D approach. Later on, it will be used to do a series of assignments from \type {#1}
425%D to \type {bib@#1}: e.g \type {\title} becomes \type {\bib@title} when used within
426%D a publication.
427
428\newtoks\initializebibdefinitions % we need to prevent clashes
429
430\protected\def\simplebibdef#1% hh: funny expansion ?
431  {\expandafter\def\csname bib@#1\endcsname##1%
432     {\setvalue{\??pb @#1}{##1}\ignorespaces}%
433   \expandafter \appendtoks
434     \expandafter\let\csname insert#1\expandafter\endcsname\csname bibinsert#1\endcsname
435   \to \initializebibdefinitions
436   \expandafter\protected\expandafter\def\csname bibinsert#1\endcsname##1##2##3%
437     {\expandafter\bibdoifelse\expandafter{\csname\??pb @#1\endcsname}{##1\csname\??pb @#1\endcsname##2}{##3}}}
438
439\def\bibcommandlist
440  {abstract, annotate, arttitle, assignee, bibnumber, bibtype, biburl, chapter, city,
441   comment, country, day, dayfiled, doi, edition, eprint, howpublished, isbn, issn,
442   issue, journal, keyword, keywords, lastchecked, month, monthfiled, names, nationality,
443   note, notes, organization, pages, pubname, pubyear, revision, series, size, thekey,
444   title, volume, yearfiled}
445
446\processcommacommand[\bibcommandlist]\simplebibdef
447
448\protected\def\bibinsertdoi#1#2#3% let's see how this fails
449  {\bibdoifelse{\@@pb@doi}{#1\normalexpanded{\bibgotoDOI{\@@pb@thekey}{\@@pb@doi}}#2}{#3}}
450
451\protected\def\bibinsertbiburl#1#2#3% let's see how this fails
452  {\bibdoifelse{\@@pb@biburl}{#1\normalexpanded{\bibgotoURL{\@@pb@thekey}{\@@pb@biburl}}#2}{#3}}
453
454\protected\def\bibinsertmonth#1#2#3%
455  {\bibdoifelse\@@pb@month
456     {#1\doifelsenumber\@@pb@month
457       {\doifelseconversiondefined\@@pbmonthconversion
458          {\convertnumber\@@pbmonthconversion\@@pb@month}{\@@pb@month}}%
459          {\@@pb@month}#2}%
460     {#3}}
461
462\appendtoks
463    \let\inserturl \bibinsertbiburl  % for backward compat.
464    \let\inserttype\bibinsertbibtype % for backward compat.
465\to\initializebibdefinitions
466
467\protected\def\newbibfield[#1]%
468  {\simplebibdef{#1}%
469   \edef\bibcommandlist{\bibcommandlist,#1}}
470
471%D \macros{complexbibdef,specialbibinsert}
472%D
473%D The commands \type {\artauthor}, \type {\author} and \type {\editor} are more
474%D complex than the other commands. Their argument lists have this form:
475%D
476%D \type{\author[junior]{firstnames}[inits]{von}{surname}}
477%D
478%D (bracketed stuff is optional)
479%D
480%D And not only that, but there also might be more than one of each of these
481%D commands. This is why a special command is needed to insert them, as well as one
482%D extra counter for each command.
483
484% todo: instead of \getvalue {bla@num} in specs we should do \bibentrynum {bla} so
485% that we can create a better namespace
486
487%D All of these \type {\expandafter}'s and \type {\csnames} make this code look far
488%D more complex than it really is. For example, the argument \type {author} defines
489%D the macro \type {\bib@author} to do two things: increment the counter \type
490%D {\author@num} (let's say to 2) and next store it's arguments in the macro \type
491%D {\@@pb@author2}. And it defines \type {\bibinsertauthors} to expand into
492%D
493%D \starttyping
494%D \specialbibinsert{author}{\author@num}{<before>}{<after>}{<not>}
495%D \stoptyping
496
497\protected\def\docomplexbibdef#1%
498  {\dodoubleempty\dodocomplexbibdef[#1]}
499
500\protected\def\dodocomplexbibdef[#1][#2]#3%
501  {\doquadrupleempty\dododocomplexbibdef[#1][#2][#3]}
502
503\protected\def\dododocomplexbibdef[#1][#2][#3][#4]#5#6%
504  {\expandafter\increment\csname#1@num\endcsname % todo: bib in name
505   \setevalue{\??pb @#1\csname#1@num\endcsname}{{#3}{#5}{#6}{#4}{#2}}\ignorespaces}
506
507\protected\def\complexbibdef#1%
508  {\expandafter\newcounter\csname #1@num\endcsname
509   \expandafter\def\csname bib@#1\endcsname{\docomplexbibdef{#1}}%
510   \expandafter \appendtoks
511     \expandafter\let\csname insert#1s\expandafter\endcsname\csname bibinsert#1s\endcsname
512   \to \initializebibdefinitions
513   \expandafter\def\csname bibinsert#1s\endcsname##1##2##3{\specialbibinsert{#1}{\csname #1@num\endcsname}{##1}{\unskip ##2}{##3}}}
514
515\processcommalist[author,artauthor,editor]\complexbibdef
516
517%D Another level of indirection is needed to control the typesetting of all of these
518%D arguments.
519
520\newinteger\etallimitcounter
521\newinteger\etaldisplaycounter
522\newinteger\todocounter
523
524\protected\def\specialbibinsert#1#2#3#4#5%
525  {\bgroup
526   \ifnum#2>\zerocount
527     \etallimitcounter  =0\bibalternative{#1etallimit}\relax
528     \etaldisplaycounter=0\bibalternative{#1etaldisplay}\relax
529     \ifnum #2>\etallimitcounter
530       \todocounter\etaldisplaycounter
531       % just in case ...
532	   \ifnum\todocounter>\etallimitcounter
533         \todocounter\etallimitcounter
534       \fi
535     \else
536       \todocounter#2\relax
537     \fi
538     \ifnum\todocounter>\zerocount
539       % find the current author list
540       \lettonothing\templist
541       \dorecurse{#2}
542         {\scratchtoks\doubleexpandafter{\csname\??pb @#1\recurselevel\endcsname}%
543          \edef\templist{\ifempty\templist\else\templist,\fi\the\scratchtoks}}%
544       #3\publicationlistparameter\c!command{#1}{\todocounter}{\templist}#4\relax
545     \else
546       #5%
547     \fi
548   \else
549     #5%
550   \fi
551   \egroup}
552
553%D This macro does the hard work of inserting a list of people in the output, with
554%D proper regard of all the inbetween strings that can arise depending on length of
555%D the list of people.
556
557%D \#1 = type
558%D \#2 = number of items to be typeset
559%D \#3 = commacommand containing authors
560
561\protected\def\doprocessauthoritem#1#2#3%
562  {\advanceby\scratchcounter\plusone
563   \ifnum\numexpr\scratchcounter-\plusone\relax<#2\relax
564     \publicationlistparameter{#1}#3%
565     \ifnum\scratchcounter=#2\relax
566       \ifnum\etallimitcounter<\commalistsize\relax
567         \bibalternative{#1etaltext}%
568       \fi
569     \orelse\ifnum\numexpr\scratchcounter+\plusone\relax=#2\relax
570        \ifnum\commalistsize>\plustwo
571          \bibalternative\c!finalnamesep
572        \else
573          \bibalternative\c!lastnamesep
574        \fi
575     \else
576       \bibalternative\c!namesep
577     \fi
578   \fi}
579
580\protected\def\dospecialbibinsert#1#2#3%
581  {\getcommacommandsize[#3]%
582   \scratchcounter\zerocount
583   \processcommacommand[#3]{\doprocessauthoritem{#1}{#2}}}
584
585%D \macros{invertedauthor,normalauthor,invertedshortauthor,normalshortauthor}
586%D
587%D Just some commands that can be used in \type {\setuppublicationparameters}
588%D If you want to write an extension to the styles, you might as well define
589%D some of these commands yourself.
590%D
591%D The argument list has been reordered here, and the meanings are:
592%D
593%D \startlines
594%D \type{#1} firstnames
595%D \type{#2} von
596%D \type{#3} surname
597%D \type{#4} inits
598%D \type{#5} junior
599%D \stoplines
600
601\protected\def\normalauthor#1#2#3#4#5%
602  {\bibdoif{#1}{#1\bibalternative\c!firstnamesep}%
603   \bibdoif{#2}{#2\bibalternative\c!vonsep}%
604   #3%
605   \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}}
606
607\protected\def\normalshortauthor#1#2#3#4#5%
608  {\bibdoif{#4}{#4\bibalternative\c!firstnamesep}%
609   \bibdoif{#2}{#2\bibalternative\c!vonsep}%
610   #3%
611   \bibdoif{#5}{\bibalternative\c!surnamesep#5\unskip}}
612
613\protected\def\invertedauthor#1#2#3#4#5%
614  {\bibdoif{#2}{#2\bibalternative\c!vonsep}%
615   #3%
616   \bibdoif{#5}{\bibalternative\c!juniorsep#5}%
617   \bibdoif{#1}{\bibalternative\c!surnamesep#1\unskip}}
618
619\protected\def\invertedshortauthor#1#2#3#4#5%
620  {\bibdoif{#2}{#2\bibalternative\c!vonsep}%
621   #3%
622   \bibdoif{#5}{\bibalternative\c!juniorsep#5}%
623   \bibdoif{#4}{\bibalternative\c!surnamesep#4\unskip}}
624
625%D \macros{clearbibitem,clearbibitemtwo,bibitemdefs}
626%D
627%D These are used in \type {\typesetapublication} to do initializations and
628%D cleanups.
629
630\protected\def\clearbibitem#1{\setvalue{\??pb @#1}{}}%
631
632\protected\def\clearbibitemtwo#1% is this reset really needed? after all we reset the counter and we are local
633  {%\dofastrecurse\plusone{\csname#1@num\endcsname}\plusone{\expandafter\let\csname\??pb @#1\recurselevel\undefined}%
634   \letvalue{#1@num}\!!zerocount}
635
636\protected\def\bibitemdefs#1%
637  {\expandafter\let\csname#1\expandafter\endcsname\csname bib@#1\endcsname}
638
639\protected\def\presetbibvariables % make a fast resetter (toks)
640  {\processcommacommand[\bibcommandlist,crossref]\clearbibitem
641   \processcommalist   [artauthor,author,editor]\clearbibitemtwo
642   \processcommacommand[\bibcommandlist]\bibitemdefs
643   \processcommalist   [artauthor,author,editor,crossref]\bibitemdefs}
644
645%D \macros{startpublication}
646%D
647%D We are coming to the end of this module, to the macros that do typesetting and
648%D read the \type {bbl} file.
649%D
650%D Just a \type {\dosingleempty} is the most friendly of doing this: there need not
651%D even be an argument to \type {\startpublication}. Of course, then there is no key
652%D either, and it had better be an article (otherwise the layout will be all screwed
653%D up).
654%D
655%D Only specifying the key in the argument is also legal. In storing this stuff into
656%D macros, some trickery with token registers is needed to fix the expansion
657%D problems. Even so, this appears to not always be 100\% safe, so people are
658%D urgently advised to use \ETEX\ instead of traditional \TEX.
659%D
660%D In \ETEX, all expansion problems are conveniently solved by the primitive \type
661%D {\protected}. To put that another way:
662%D
663%D It's not a bug in this module if it does not appear in \ETEX!
664%D
665%D Now prohibits comments, so % can be used for urls
666
667\pushoverloadmode
668
669\overloaded \protected\def\startpublication
670  {\dosingleempty\dostartpublication}
671
672\overloaded\let\stoppublication\relax
673
674\popoverloadmode
675
676%D This is rather memory hungry; some day i will rewrite this so that we use the
677%D database instead.
678
679%D \macros{doifbibreferencefoundelse}
680%D
681%D Some macros to fetch the information provided by \type {\startpublication}.
682%D
683%D We can consider a faster variant in the bbl file; we can also consider storing
684%D the keys in lua (and then do more in lua) and use calls to fetch the variables.
685
686% hm, we can store at the lua end ...
687
688\protected\def\dostartpublication[#1]%
689  {\begingroup
690   \doifelseassignment{#1}%
691     {\getparameters[\??pb][k=\s!unknown,t=article,n=,s=,a=,y=,o=,u=,#1]}%
692     {\getparameters[\??pb][k=#1,t=article,n=,s=,a=,y=,o=,u=]}%
693   \ctxlua{bibtex.hacks.register(\!!bs\@@pbk\!!es,\!!bs\@@pbs\!!es)}%
694   \catcode\commentasciicode\othercatcode
695   \dodostartpublication}
696
697\protected\def\dodostartpublication#1\stoppublication
698  {\setxvalue{pbd:\@@pbk}##1{\noexpand\ifcase##1\noexpand\or
699     \@@pbk\noexpand\or
700     \@@pba\noexpand\or
701     \@@pby\noexpand\or
702     \@@pbs\noexpand\or
703     \@@pbn\noexpand\or
704     \@@pbt\noexpand\or
705     \@@pbo\noexpand\or
706     \@@pbu\noexpand\or
707     \normalunexpanded{#1}\noexpand\fi}%
708   \endgroup
709   \ignorespaces}
710
711\def\bibgetvark#1{\csname pbd:#1\endcsname\plusone  }
712\def\bibgetvara#1{\csname pbd:#1\endcsname\plustwo  }
713\def\bibgetvary#1{\csname pbd:#1\endcsname\plusthree}
714\def\bibgetvars#1{\csname pbd:#1\endcsname\plusfour }
715\def\bibgetvarn#1{\csname pbd:#1\endcsname\plusfive }
716\def\bibgetvart#1{\csname pbd:#1\endcsname\plussix  }
717\def\bibgetvaro#1{\csname pbd:#1\endcsname\plusseven}
718\def\bibgetvaru#1{\csname pbd:#1\endcsname\pluseight}
719\def\bibgetvard#1{\csname pbd:#1\endcsname\plusnine }
720
721\protected\def\doifelsebibreferencefound#1%
722  {\preloadbiblist
723   \doifelsedefined{pbd:#1}
724     \firstoftwoarguments
725     {\showmessage\m!publications{5}{#1,\the\inputlineno}\secondoftwoarguments}}
726
727\let\doifbibreferencefoundelse\doifelsebibreferencefound
728
729%D \macros{bib@crossref}
730%D
731%D \type {\crossref} is used in database files to point to another entry. Because of
732%D this special situation, it has to be defined separately. Since this command will
733%D not be seen until at \type {\placepublications}, it may force extra runs. The
734%D same is true for \type {\cite} commands inside of publications.
735
736% used in bib self
737
738\protected\def\bib@crossref#1% called via \csname \endcsname
739  {\setvalue{\??pb @crossref}{#1}\ignorespaces}
740
741\protected\def\bibinsertcrossref#1#2#3%
742  {\bibdoifelse\@@pb@crossref{#1\cite[\@@pb@crossref]#2}{#3}}
743
744\let\insertcrossref\gobblethreearguments
745
746\appendtoks\let\insertcrossref\bibinsertcrossref\to\initializebibdefinitions
747
748%D The next macro is needed because the number command of the publist sometimes
749%D needs to fetch something from the current item (like the 'short' key). For this,
750%D the ID of the current item is passed in the implict parameter \type
751%D {\currentpublicationkey}.
752
753\protected\def\doprocessbibtexentry#1{\typesetapublication{#1}}
754
755\protected\def\typesetpubslist
756  {\begingroup
757   \startpacked[\v!blank]%
758   \preloadbiblist
759   % \the\initializebibdefinitions % COMMENTED
760   \edef\currentlist{pubs}%
761   \ctxlua{bibtex.hacks.reset(\number\bibtexoncemode)}%
762   \doifelse{\listparameter\c!criterium}\v!all
763     {\showmessage\m!publications{7}{}%
764      \ctxlua{bibtex.hacks.filterall()}}
765     {\doif{\listparameter\c!criterium}\v!cite
766        {\setuplist[pubs][\c!criterium=\v!here]}%
767      \strc_lists_place_current
768        {pubs}%
769        {\listparameter\c!criterium}%
770        {}%
771        {\listparameter\c!extras}%
772        {\listparameter\c!order}}%
773        {}%
774   \ctxlua{bibtex.hacks.flush("\@@pbsorttype")}%
775   \stoppacked
776   \endgroup}
777
778\newif\ifinpublist
779
780\protected\def\initializepubslist
781  {\def\currentlist{pubs}%
782   \edef\@@pbnumbering{\@@pbnumbering}%
783   \doifelse\@@pbautohang\v!yes
784     {\ifx\@@pbnumbering\v!short
785        \setbox\scratchbox\hbox{\@@pbnumbercommand{\listparameter\c!samplesize}}%
786      \else
787        \doifelse{\listparameter\c!criterium}\v!all
788          {\setbox\scratchbox\hbox{\@@pbnumbercommand{\ctxlua{tex.write{bibtex.hacks.nofregistered()}}}}}
789          {\determinelistcharacteristics[pubs]%
790           \setbox\scratchbox\hbox{\@@pbnumbercommand{\structurelistsize}}}%
791      \fi
792      \edef\publistnumberbox{\hbox to \the\wd\scratchbox}%
793      \normalexpanded{\setuplist[pubs][\c!width=\the\wd\scratchbox,\c!distance=\zeropoint]}%
794      \ifx\@@pbnumbering\v!short
795        \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvars\currentpublicationkey}}}%
796      \orelse\ifx\@@pbnumbering\v!bib
797        \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvarn\currentpublicationkey}}}%
798      \else
799        \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{##1}}}%
800      \fi}
801     {\doifelsenothing{\listparameter\c!width}
802        {\let \publistnumberbox \hbox}
803        {\edef\publistnumberbox{\hbox to \listparameter\c!width}}%
804      \ifx\@@pbnumbering\v!short
805        \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvars\currentpublicationkey}}}%
806      \orelse\ifx\@@pbnumbering\v!bib
807        \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{\bibgetvarn\currentpublicationkey}}}%
808      \else
809        \def\@@pblimitednumber##1{\publistnumberbox{\@@pbnumbercommand{##1}}}%
810      \fi}%
811   \ifx\@@pbnumbering\v!no
812     \setuplist[pubs][\c!numbercommand=,\c!symbol=\v!none,\c!textcommand=\outdented]%
813   \else
814     \setuplist[pubs][\c!numbercommand=\@@pblimitednumber]%
815   \fi
816   \doifelse{\publicationlistparameter\c!maybeyear}{\v!off}{\def\maybeyear##1{}}{\def\maybeyear##1{##1}}%
817   \forgetall}
818
819%D The full list of publications
820
821\protected\def\completepublications
822  {\dosingleempty\docompletepublications}
823
824\protected\def\docompletepublications[#1]%
825  {\begingroup
826   \setuplist[pubs][#1]%
827   \edef\currentbibtexsessiontitle{\publicationlistparameter\c!title}%
828   \ifempty\currentbibtexsessiontitle
829     \normalexpanded{\startnamedsection[\v!chapter][\c!reference=pubs,\c!title={\headtext{pubs}}]}%
830   \else
831     \normalexpanded{\startnamedsection[\v!chapter][\c!reference=pubs,\c!title={\currentbibtexsessiontitle}]}%
832   \fi
833   \dodoplacepublications
834   \stopnamedsection
835   \endgroup}
836
837%D And the portion with the entries only.
838
839\def\bibrefprefix{\number\bibtexblock:}
840
841\protected\def\placepublications
842  {\dosingleempty\doplacepublications}
843
844\protected\def\doplacepublications[#1]%
845  {\begingroup
846   \setuplist[pubs][#1]%
847   \dodoplacepublications
848   \endgroup}
849
850\protected\def\dodoplacepublications
851  {\determinelistcharacteristics[pubs]%
852   \initializepubslist
853   \doifnot{\namedlistparameter{pubs}\c!option}\v!continue
854     {\global\bibtexcounter\zerocount}%
855   \inpublisttrue
856   \typesetpubslist
857   \inpublistfalse
858   \global\advanceby\bibtexblock\plusone}
859
860%D \subsubject{What's in a publication}
861%D
862%D Watch out: here all means all publications in database, so use text when you want
863%D text only.
864
865\protected\def\typesetapublication#1%
866  {\doifsomething{#1}
867     {\doifelse{\namedlistparameter{pubs}\c!criterium}\v!all
868        {\doplacepublicationindeed{#1}}%
869        {\ctxlua{bibtex.hacks.doifalreadyplaced("#1")}
870           {}
871           {\doplacepublicationindeed{#1}}}%
872      }}
873
874%D For the moment we don't access the data directly but we will do that later when
875%D we get away from storing the data and only deal with references.
876
877% we'll define proper handlers later
878
879\protected\def\doplacepublicationindeed#1%
880  {\doifelsebibreferencefound{#1}
881     {\global\advanceby\bibtexcounter\plusone
882      \def\currentpublicationkey{#1}%
883      \ctxlua{bibtex.hacks.registerplaced("#1")}%
884      \def\currentlist{pubs}%
885      \edef\currentlistentrynumber{\number\bibtexcounter}%
886      \let\currentlistentrytitle\bibtexpubtext
887      \lettonothing\currentlistentrypagenumber
888      \strc_lists_apply_renderingsetup}
889     {}} % invalid
890
891\protected\def\bibtexpubtext
892  {\normalexpanded{\reference[\bibrefprefix\currentpublicationkey]{\number\bibtexcounter}}%
893   \strut\dotypesetapublication\currentpublicationkey\strut}
894
895\protected\def\dotypesetapublication#1%
896  {\bgroup
897   \the\initializebibdefinitions % NEW
898   \def\@@currentalternative{:l:}%
899   \presetbibvariables
900   \lettonothing\biblanguage
901   \ignorespaces
902   \bibgetvard{#1}%
903   \removeunwantedspaces
904   \ignorespaces
905   \bibalternative{\bibgetvart{#1}}%
906   \removeunwantedspaces
907   \egroup}
908
909%D An few afterthoughts:
910
911\let\maybeyear\gobbleoneargument
912\let\noopsort \gobbleoneargument
913
914%D This is the result of bibtex's `language' field.
915
916\protected\def\setbiblanguage#1#2{\setvalue{\??pb\s!language#1}{#2}}
917
918\protected\def\lang#1%
919   {\edef\biblanguage{#1}%
920    \ifcsname\??pb\s!language#1\endcsname
921      \language[\getvalue{\??pb\s!language#1}]%
922    \fi
923    \ignorespaces}
924
925%D \subject{Citations}
926
927%D \macros{cite,bibref}
928%D
929%D The indirection with \type {\dobibref} allows \LATEX\ style \type {\cite}
930%D commands with a braced argument (these might appear in included data from the
931%D \type {.bib} file).
932
933\pushoverloadmode
934
935\protected\def\cite
936  {\strictdoifelsenextoptional\dodocite\dobibref}
937
938\popoverloadmode
939
940\protected\def\dobibref#1%
941  {\docite[#1][]}
942
943\protected\def\dodocite[#1]%
944  {\strictdoifelsenextoptional{\docite[#1]}{\docite[#1][]}}
945
946\protected\def\docite[#1][#2]%
947  {\begingroup
948   \doifelsesomething{#2}
949     {\dowhatevercite{#1}{#2}}%
950     {\donumberedcite{#1}}%
951   \endgroup}
952
953\protected\def\dowhatevercite#1#2%
954  {\processcommalist[#2]\docitation
955   \setupinteraction[\c!style=]%
956   \doifelseassignment
957     {#1}%
958     {\getparameters[LO][\c!alternative=,\c!extras=,#1]%
959      \edef\@@currentalternative{\LOalternative}%
960      \ifempty\@@currentalternative
961        \edef\@@currentalternative{\@@citedefault}%
962      \fi
963      \ifempty\LOextras
964        \setupcite[\@@currentalternative][#1]%
965      \else
966        \expandafter\ifrelax\csname\??pv\@@currentalternative\c!right\endcsname
967          % avoids tail recursion
968          \expandafter\lettonothing\csname\??pv\@@currentalternative\c!right\endcsname
969        \fi
970        \expandafter\ifrelax\csname LOright\endcsname
971          \edef\LOextras{{\LOextras\bibalternative\c!right}}%
972        \else
973          \edef\LOextras{{\LOextras\LOright}}%
974        \fi
975        \normalexpanded{\setupcite[\@@currentalternative][#1,\c!right=\LOextras]}%
976      \fi}%
977     {\def\@@currentalternative{#1}}%
978   \doifelsevalue{@@pv\@@currentalternative\c!compress}\v!no\bibcitecompressfalse\bibcitecompresstrue
979   \getvalue{bib\@@currentalternative ref}[#2]}
980
981\protected\def\donumberedcite#1%
982  {\processcommalist[#1]\docitation
983   \setupinteraction[\c!style=]%
984   \edef\@@currentalternative{\@@citedefault}%
985   \doifelsevalue{@@pv\@@currentalternative\c!compress}\v!no\bibcitecompressfalse\bibcitecompresstrue
986   \getvalue{bib\@@citedefault ref}[#1]}
987
988%D \macros{nocite}
989
990\pushoverloadmode
991
992\protected\def\nocite[#1]%
993  {\processcommalist[#1]\docitation}
994
995\popoverloadmode
996
997%D \macros{setupcite}
998
999\permanent\tolerant\protected\def\setupcite[#1]#*[#2]%
1000  {\ifparameter#2\or
1001     \def\dodosetupcite##1{\getparameters[\??pv##1][#2]}%
1002     \processcommalist[#1]\dodosetupcite
1003   \else % default case
1004     \getparameters[\??pv\@@citedefault][#1]%
1005   \fi}
1006
1007%D Low-level stuff
1008
1009\protected\def\getcitedata#1[#2]#*[#3]#*to#4%
1010  {\bgroup
1011   \dofetchapublication{#3}%
1012   \doifelsedefined{\??pb @bib#2}%
1013     {\xdef#4{\getvalue{\??pb @bib#2}}}%
1014     {\xdef#4{\getvalue{\??pb @#2}}}%
1015   \egroup}
1016
1017\protected\def\dofetchapublication#1%
1018  {\def\currentpublicationkey{#1}%
1019   \presetbibvariables
1020   \ignorespaces\bibgetvard{#1}}
1021
1022\protected\def\docitation#1%
1023  {\iftrialtypesetting \else
1024     \normalexpanded{\writedatatolist[pubs][bibref=#1]}%
1025   \fi}
1026
1027\let\addthisref\gobbleoneargument % keep this for compatibility
1028
1029%D \macros{ixbibauthoryear,thebibauthors,thebibyears}
1030%D
1031%D If compression of \type {\cite}'s argument expansion is on, the macros that deal
1032%D with authors and years call this internal command to do the actual typesetting.
1033%D
1034%D Two entries with same author but with different years may be condensed into
1035%D ``Author (year1,year2)''. This is about the only optimization that makes sense
1036%D for the (author,year) style of citations (years within one author have to be
1037%D unique anyway so no need to test for that, and ``Author1, Author2 (year)''
1038%D creates more confusion than it does good).
1039%D
1040%D In the code below, the macro \type {\thebibauthors} holds the names of the
1041%D alternative author info fields for the current list. This is a commalist, and
1042%D \type {\thebibyears} holds the (collection of) year(s) that go with this author
1043%D (possibly as a nested commalist).
1044%D
1045%D There had better be an author for all cases, but there does not have to be year
1046%D info always. \type{\thebibyears} is pre|-|initialized because this makes the
1047%D insertion macros simpler.
1048%D
1049%D In normal \TEX, of course there are expansion problems again.
1050
1051%D Delegate this to \LUA.
1052
1053% \let         \ixlastcommand \relax
1054% \let         \ixsecondcomman\relax
1055% \let         \ixfirstcommand\relax
1056% \lettonothing\thebibauthors
1057% \lettonothing\thebibyears
1058% \let         \authorcount   \!!zerocount
1059
1060\lettonothing\currentbibauthor
1061
1062\protected\def\ixbibauthoryear#1#2#3#4%
1063  {\bgroup
1064   \gdef\ixlastcommand{#4}%
1065   \gdef\ixsecondcommand{#3}%
1066   \gdef\ixfirstcommand{#2}%
1067   \glettonothing\thebibauthors
1068   \glettonothing\thebibyears
1069   \getcommalistsize[#1]%
1070   \ifbibcitecompress
1071     \dorecurse\commalistsize{\xdef\thebibyears{\thebibyears,}}%
1072     \processcommalist[#1]\docompressbibauthoryear
1073   \else
1074     \processcommalist[#1]\donormalbibauthoryear
1075   \fi
1076   \egroup
1077   \dobibauthoryear}
1078
1079%D \macros{dodobibauthoryear}
1080%D
1081%D This macro only has to make sure that the lists \type {\thebibauthors} and \type
1082%D {\thebibyears} are printed.
1083
1084\protected\def\dobibauthoryear
1085  {\scratchcounter\zerocount
1086   \getcommacommandsize[\thebibauthors]%
1087   \edef\authorcount{\commalistsize}%
1088   \expandafter\processcommalist\expandafter[\thebibauthors]\dodobibauthoryear}
1089
1090\protected\def\dodobibauthoryear#1%
1091  {\advanceby\scratchcounter\plusone
1092   \edef\wantednumber{\the\scratchcounter}%
1093   \getfromcommacommand[\thebibyears][\wantednumber]%
1094   \expandafter\def\expandafter\currentbibyear\expandafter{\commalistelement}%
1095   \setcurrentbibauthor{#1}%
1096   \ifnum\scratchcounter=\plusone
1097     \ixfirstcommand
1098   \orelse\ifnum \scratchcounter=\authorcount\relax
1099     \ixlastcommand
1100   \else
1101     \ixsecondcommand
1102   \fi}
1103
1104\protected\def\setcurrentbibauthor#1% sensitive for empty entries but I don't want to touch this
1105  {\getcommacommandsize[#1]%
1106   \ifcase\commalistsize
1107    % anonymous?
1108     \lettonothing\currentbibauthor
1109   \or
1110     \def\currentbibauthor{#1}%
1111   \or
1112     \normalexpanded{\docurrentbibauthor#1}%
1113   \else
1114     \handlemultiplebibauthors{\commalistsize}{#1}%
1115   \fi}
1116
1117\newinteger\citescratchcounter
1118
1119\protected\def\handlemultiplebibauthors#1#2%
1120  {\citescratchcounter\zerocount
1121   \lettonothing\currentbibauthor
1122   \protected\def\bibprocessauthoritem##1%
1123     {\advanceby\citescratchcounter\plusone
1124      \ifnum \citescratchcounter=#1\relax
1125        \edef\currentbibauthor{\currentbibauthor##1}%
1126      \orelse\ifnum\numexpr\citescratchcounter+\plusone\relax=#1\relax
1127        \edef\currentbibauthor{\currentbibauthor##1\bibalternative{andtext}}%
1128      \else
1129        \edef\currentbibauthor{\currentbibauthor##1\bibalternative{namesep}}%
1130      \fi}%
1131     \processcommalist[#2]\bibprocessauthoritem}
1132
1133\setupcite
1134  [author,authoryear,authoryears]
1135  [\c!namesep={, }]
1136
1137%D This discovery of authoretallimit is not the best one,
1138%D but it will do for now.
1139
1140\protected\def\docurrentbibauthor#1,#2%
1141  {\doifelseempty{#2}
1142     {\def\currentbibauthor{#1\bibalternative{otherstext}}}
1143     {\expandafter\ifrelax\csname\??pv\@@currentalternative authoretallimit\endcsname
1144        \edef\currentbibauthor{#1\bibalternative{andtext}#2}%
1145      \else
1146        \edef\currentbibauthor{#1%
1147        \ifcase0\bibalternative{authoretallimit}\relax\or
1148        \bibalternative{otherstext}\else\bibalternative{andtext}#2\fi}%
1149      \fi}}
1150
1151%D This is not the one Hans made for me, because I need a global edef, and the \type
1152%D {\robustdoifinsetelse} doesn't listen to \type {\doglobal}.
1153
1154\pushoverloadmode
1155
1156%     \protected\def\robustaddtocommalist#1#2% {item} \cs
1157%       {\robustdoifelseinset{#1}#2\resetglobal
1158%          {\dodoglobal\xdef#2{\ifempty#2\else#2,\fi#1}}}
1159
1160    \protected\def\robustaddtocommalist#1#2% {item} \cs
1161      {\robustdoifelseinset{#1}#2\donothing{\xdef#2{\ifempty#2\else#2,\fi#1}}}
1162
1163\popoverloadmode
1164
1165%D \macros{donormalbibauthoryear}
1166%D
1167%D Now we get to the macros that fill the two lists. The \quote {simple} one really
1168%D is quite simple.
1169
1170\protected\def\donormalbibauthoryear#1%
1171  {\def\myauthor{Xxxxxxxxxx}%
1172   \def\myyear{0000}%
1173   \doifelsebibreferencefound{#1}
1174     {\def\myauthor{{\bibgetvara{#1}}}%
1175      \def\myyear  {\bibgetvary{#1}}}%
1176     {}%
1177   \expandafter\doglobal\expandafter\appendtocommalist\expandafter{\myauthor}\thebibauthors
1178   \expandafter\doglobal\expandafter\appendtocommalist\expandafter{\myyear  }\thebibyears}
1179
1180%D \macros{docompressbibauthoryear}
1181%D
1182%D So much for the easy parts. Nothing at all will be done if the reference is not
1183%D found or the reference does not contain author data. No questions marks o.s.s.
1184%D (to be fixed later).
1185
1186\protected\def\docompressbibauthoryear#1%
1187  {\def\myauthor{Xxxxxxxxxx}%
1188   \def\myyear  {0000}%
1189   \doifelsebibreferencefound{#1}
1190     {\xdef\myauthor{\bibgetvara{#1}}%
1191      \xdef\myyear  {\bibgetvary{#1}}}
1192     {}%
1193    \ifempty\myauthor\else
1194      \checkifmyauthoralreadyexists
1195      \findmatchingyear
1196    \fi}
1197
1198%D Two temporary counters. One of these two can possibly be replaced by \type
1199%D {\scratchcounter}.
1200
1201\newinteger\bibitemcounter
1202\newinteger\bibitemwanted
1203
1204%D The first portion is simple enough: if this is the very first author it is quite
1205%D straightforward to add it. \type {\bibitemcounter} and \type {\bibitemwanted} are
1206%D needed later to insert the year information in the correct item of \type
1207%D {\thebibyears}.
1208
1209\protected\def\checkifmyauthoralreadyexists
1210  {\doifelseemptyvalue{thebibauthors}
1211     {\global\bibitemwanted \plusone
1212      \global\bibitemcounter\plusone
1213      \xdef\thebibauthors{{\myauthor}}}
1214     {% the next weirdness is because according to \getcommalistsize,
1215      % the length of \type{[{{},{}}]} is 2.
1216      \expandafter\getcommalistsize\expandafter[\thebibauthors,]%
1217      \global\bibitemcounter\numexpr\commalistsize+\minusone\relax
1218      \global\bibitemwanted \zerocount
1219      \processcommacommand[\thebibauthors]\docomparemyauthor}}
1220
1221%D The outer \type {\ifnum} accomplishes the addition of a new author to \type
1222%D {\thebibauthors}. The messing about with the two counters is again to make sure
1223%D that \type {\thebibyears} will be updated correctly.If the author {\it was}
1224%D found, the counters will stay at their present values and everything will be
1225%D setup properly to insert the year info.
1226
1227\protected\def\docomparemyauthor#1%
1228  {\global\advanceby\bibitemwanted \plusone
1229   \def\mytempc{#1}%
1230   \ifx\mytempc\myauthor
1231     \quitcommalist
1232   \orelse\ifnum\bibitemwanted=\bibitemcounter\relax
1233     \global\advanceby\bibitemwanted \plusone
1234     \global\bibitemcounter\bibitemwanted\relax
1235     \expandafter\doglobal\expandafter\robustaddtocommalist\expandafter{{\myauthor}}\thebibauthors
1236   \fi}
1237
1238%D This macro should be clear now.
1239
1240\protected\def\findmatchingyear
1241  {\edef\wantednumber{\the\bibitemwanted}%
1242   \getfromcommacommand[\thebibyears][\wantednumber]%
1243   \ifempty\commalistelement
1244     \edef\myyear{{\myyear}}%
1245   \else
1246     \edef\myyear{{\commalistelement,\myyear}}%
1247   \fi
1248   \edef\newcommalistelement{\myyear}%
1249   \doglobal\replaceincommalist \thebibyears \wantednumber}
1250
1251%D \macros{gotobiblink,inbiblink,atbiblink}
1252%D
1253%D The final task is looping over that list until a match is found.
1254
1255%D Beware, we can have cites without reference match.
1256
1257\protected\def\gotobiblink#1[#2]{\doifelsereferencefound{\bibrefprefix#2}{\goto{#1}[\bibrefprefix#2]}{#1}}
1258\protected\def\atbiblink    [#1]{\doifelsereferencefound{\bibrefprefix#1}{\at[\bibrefprefix#1]}{#1}}
1259\protected\def\inbiblink    [#1]{\doifelsereferencefound{\bibrefprefix#1}{\normalexpanded{\goto{\currentreferencetext}}[\bibrefprefix#1]}{#1}}
1260
1261%D \macros{bibauthoryearref,bibauthoryearsref,bibauthorref,bibyearref}
1262%D
1263%D Now that all the hard work has been done, these are simple. \type
1264%D {\ixbibauthoryearref} stores the data in the macros \type {\currentbibauthor} and
1265%D \type {\currentbibyear}.
1266
1267\protected\def\doifelsebibinteraction
1268  {\iflocation
1269     \edef\test{\bibalternative\c!interaction}%
1270     \ifx\test\v!stop
1271       \doubleexpandafter\secondoftwoarguments
1272     \else
1273       \doubleexpandafter\firstoftwoarguments
1274     \fi
1275   \else
1276     \expandafter\secondoftwoarguments
1277   \fi}
1278
1279\let\doifbibinteractionelse\doifelsebibinteraction
1280
1281\protected\def\bibmaybeinteractive#1#2%
1282  {\doifelsebibinteraction{\gotobiblink{#2}[#1]}{#2}}
1283
1284\protected\def\bibauthoryearref[#1]%
1285 {\ixbibauthoryear{#1}%
1286    {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
1287     \bibalternative\v!left{\currentbibyear}\bibalternative\v!right}}
1288    {\bibalternative\c!pubsep
1289     \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
1290     \bibalternative\v!left  {\currentbibyear}\bibalternative\v!right}}
1291    {\bibalternative\c!lastpubsep
1292     \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween
1293     \bibalternative\v!left {\currentbibyear}\bibalternative\v!right}}}
1294
1295\protected\def\bibauthoryearsref[#1]%
1296  {\bibalternative\v!left
1297   \ixbibauthoryear{#1}
1298     {\bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}
1299     {\bibalternative\c!pubsep
1300      \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}
1301     {\bibalternative\c!lastpubsep
1302      \bibmaybeinteractive{#1}{{\currentbibauthor}\bibalternative\c!inbetween{\currentbibyear}}}%
1303   \bibalternative\v!right}
1304
1305\protected\def\bibauthorref[#1]%
1306  {\bibalternative\v!left
1307   \ixbibauthoryear{#1}%
1308     {\bibmaybeinteractive{#1}{{\currentbibauthor}}}
1309     {\bibalternative\c!pubsep    \bibmaybeinteractive{#1}{{\currentbibauthor}}}
1310     {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibauthor}}}%
1311   \bibalternative\v!right}
1312
1313\protected\def\bibyearref[#1]%
1314  {\bibalternative\v!left
1315   \ixbibauthoryear{#1}%
1316     {\bibmaybeinteractive{#1}{{\currentbibyear}}}
1317     {\bibalternative\c!pubsep    \bibmaybeinteractive{#1}{{\currentbibyear}}}
1318     {\bibalternative\c!lastpubsep\bibmaybeinteractive{#1}{{\currentbibyear}}}%
1319   \bibalternative\v!right}
1320
1321%D \macros{bibshortref,bibkeyref,bibpageref,bibtyperef,bibserialref}
1322%D
1323%D There is hardly any point in trying to compress these. The only thing that needs
1324%D to be done is making sure that the separations are inserted correctly. And that
1325%D is what \type {\bibinsertrefsep} does.
1326
1327\newconditional\firstbibrefsep
1328
1329\protected\def\bibresetrefsep
1330  {\firstbibrefsep\conditionaltrue}
1331
1332\protected\def\bibinsertrefsep
1333  {\ifconditional\firstbibrefsep
1334     \firstbibrefsep\conditionalfalse
1335   \else
1336     \bibalternative\c!pubsep
1337   \fi}
1338
1339\protected\def\bibshortref[#1]%
1340  {\bibalternative\v!left
1341   \bibresetrefsep\processcommalist[#1]\dobibshortref
1342   \bibalternative\v!right}
1343
1344\protected\def\dobibshortref#1%
1345  {\bibinsertrefsep
1346   \doifelsebibreferencefound{#1}
1347     {\gotobiblink{\bibgetvars{#1}}[#1]}
1348	 {}}
1349
1350\protected\def\bibserialref[#1]%
1351  {\bibalternative\v!left
1352   \bibresetrefsep\processcommalist[#1]\dobibserialref
1353   \bibalternative\v!right}
1354
1355\protected\def\dobibserialref#1%
1356  {\bibinsertrefsep
1357   \doifelsebibreferencefound{#1}
1358     {\gotobiblink{\bibgetvarn{#1}}[#1]}
1359     {}}
1360
1361\protected\def\bibkeyref[#1]%
1362  {\bibalternative\v!left
1363   \bibresetrefsep\processcommalist[#1]\dobibkeyref
1364   \bibalternative\v!right}
1365
1366\protected\def\dobibkeyref#1%
1367  {\bibinsertrefsep
1368   \gotobiblink{#1}[#1]}
1369
1370\protected\def\bibgotoDOI#1#2%
1371  {\doifelsebibinteraction
1372     {\useURL[bibfooDoi#1][#2]%
1373      \useURL[bibfoo#1][http://dx.doi.org/#2]%
1374      \goto{\url[bibfooDoi#1]}[url(bibfoo#1)]}
1375     {\hyphenatedurl{#2}}}
1376
1377\protected\def\bibdoiref[#1]%
1378  {\bibalternative\v!left
1379   \bibresetrefsep\processcommalist[#1]\dobibdoiref
1380   \bibalternative\v!right}
1381
1382\protected\def\dobibdoiref#1%
1383  {\bibinsertrefsep
1384   \doifelsebibreferencefound{#1}
1385     {\normalexpanded{\bibgotoDOI{#1}{\bibgetvaro{#1}}}}
1386     {}}
1387
1388\protected\def\biburlref[#1]%
1389  {\bibalternative\v!left
1390   \bibresetrefsep\processcommalist[#1]\dobiburlref
1391   \bibalternative\v!right}
1392
1393\protected\def\bibgotoURL#1#2%
1394  {\doifelsebibinteraction
1395     {\useURL[bibfoo#1][#2]\goto{\url[bibfoo#1]}[url(bibfoo#1)]}
1396     {\hyphenatedurl{#2}}}
1397
1398\protected\def\dobiburlref#1%
1399  {\bibinsertrefsep
1400   \doifelsebibreferencefound{#1}
1401     {\normalexpanded{\bibgotoURL{#1}{\bibgetvaru{#1}}}}
1402     {}}
1403
1404\protected\def\bibtyperef[#1]%
1405  {\bibalternative\v!left
1406   \bibresetrefsep\processcommalist[#1]\dobibtyperef
1407   \bibalternative\v!right}
1408
1409\protected\def\dobibtyperef#1%
1410  {\bibinsertrefsep
1411   \doifelsebibreferencefound{#1}
1412     {\gotobiblink{\bibgetvart{#1}}[#1]}
1413     {}}
1414
1415\protected\def\bibpageref[#1]%
1416  {\bibalternative\v!left
1417   \bibresetrefsep\processcommalist[#1]\dobibpageref
1418   \bibalternative\v!right}
1419
1420\protected\def\dobibpageref#1%
1421  {\bibinsertrefsep
1422   \doifelsebibinteraction
1423     {\atbiblink[#1]}
1424     {{\referencingfalse\at[#1]}}}
1425
1426\protected\def\bibdataref[#1]%
1427  {\bibalternative\v!left
1428   \bibresetrefsep\processcommalist[#1]\dobibdata
1429   \bibalternative\v!right}
1430
1431\protected\def\dobibdata#1%
1432  {\bibinsertrefsep
1433   \doifelsebibreferencefound{#1}
1434     {\dotypesetapublication{#1}}
1435     {}}
1436
1437\let\bibnoneref\nocite
1438
1439%D \macros{bibnumref}
1440
1441\protected\def\bibnumref[#1]%
1442  {\begingroup
1443   \bibalternative\v!left
1444   \penalty\plustenthousand
1445   \ctxlua{bibtex.hacks.resolve("","\number\bibtexblock","#1")}%
1446   \bibalternative\v!right
1447   \endgroup}
1448
1449\protected\def\dowithbibtexnumrefconnector#1#2%
1450  {\ifnum#1>\plusone
1451     \ifnum#2>\plusone
1452       \ifnum#2=#1\relax
1453         \bibalternative{lastpubsep}%
1454       \else
1455         \bibalternative{pubsep}%
1456       \fi
1457     \fi
1458   \fi}
1459
1460\protected\def\dowithbibtexnumref#1#2#3#4#5% n, i, prefix block ref
1461  {\dowithbibtexnumrefconnector{#1}{#2}%
1462   \def\bibrefprefix{#4:}%
1463   \inbiblink[#5]}
1464
1465\protected\def\dowithbibtexnumrefrange#1#2#3#4#5#6#7% n, i, prefix block ref
1466  {\dowithbibtexnumrefconnector{#1}{#2}%
1467   \def\bibrefprefix{#4:}%
1468   \inbiblink[#5]%
1469   \endash
1470   \def\bibrefprefix{#6:}%
1471   \inbiblink[#7]}
1472
1473%D By request from Sanjoy. This makes it easier to implement \type {\citeasnoun}.
1474
1475\protected\def\bibauthornumref[#1]%
1476  {\getcommalistsize[#1]%
1477   \global\bibitemcounter\commalistsize
1478   \bibresetrefsep
1479   \processcommalist[#1]\dobibauthornumref}
1480
1481\protected\def\dobibauthornumref#1%
1482  {\bibinsertrefsep
1483   \doifelsebibreferencefound{#1}
1484     {\begingroup
1485      \cite[\c!left=,\c!right=,\c!alternative=\v!author][#1]%
1486      \bibalternative\c!inbetween
1487      \cite[num][#1]%
1488      \endgroup}
1489     {}}
1490
1491%D And some defaults are loaded from bibl-apa:
1492
1493\setuppublications
1494  [\c!monthconversion=,
1495   \c!alternative=apa,
1496   \c!method=\v!global,
1497  %\c!criterium=\v!previous,
1498   \c!criterium=\v!cite, % mojca wants this so bother her, not me
1499   \c!refcommand=num,
1500   \c!numbercommand=\bibleftnumber]
1501
1502\protected\def\preloadbiblist
1503  {\glet\preloadbiblist\relax
1504   \dousepublications\jobname}
1505
1506% \appendtoks \preloadbiblist \to \everysetuppublications
1507% \appendtoks \preloadbiblist \to \everystarttext
1508
1509\let\ifbibinteractionelse\doifbibinteractionelse
1510
1511\protect \endinput
1512