%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Module: ZzTeX Bibliography Facility % % Synopsis: This module provides a new bibliography facility to replace % zzbibtex. It is more flexible so that it can handle numeric, % key, and author/year citations. % % Author: Paul C. Anagnostopoulos % Created: 1 December 2016 % % Copyright 1989--2020 by Paul C. Anagnostopoulos % under The MIT License (opensource.org/licenses/MIT) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initialization % -------------- \def \zbiblioinit {% \if \definedp{\bibliodesign}% \begingroup \bibliodesign \globaldefs = 1 \citestyle = \citestyle \endgroup \fi} % Bibliography Cross-Reference % ------------ --------------- % When tags are loaded, define the name \=zB:tag to contain the % bibliographic info in this format: % folio\zmark key\zmark {author}{year}{full-author} \def \xrefbib #1#2#3#4{% {folio}{key}{{author}{year}{full-author}}{tag} \ifnum \xrefmode=\xrefloadtagmode \if \definedp{\=zB:#4}\zduptag{#4}\fi \withname\gdef{\=zB:#4}{#1\zmark#2\zmark#3}% \fi} % This macro loads the cite cross-reference entries and invokes the % specified macro for each one. \def \mapxrefcites #1{% {\macro} {\let \zmapcitemacro = #1\relax \zxloadcomp{\xrefloadcitemode}}} \def \xrefcite #1#2#3#4{% {page}{}{}{tag} \ifnum \xrefmode=\xrefloadcitemode \zmapcitemacro{#1}{#4}% \fi} % Biblio Block % ------ ----- \defineblock{\biblio}{\endbiblio}{\false}{} %~block biblio % \citestyle = integer % Citation style. % \setflag \indexcites = boolean % If true, index each cite (not implemented). % \setflag \citeself = boolean % If true, \bibitem cites itself (not implemented). %~end \definecount{\citestyle}{-1} \chardef \citebynumber = 0 \chardef \citebykey = 1 \chardef \citebyauthoryear = 2 \def \biblio {% \blockcantbein{\biblio}{\biblio}% \blockmustbein{\biblio}{\list}% \beginblockscope{biblio}% \global\increment \bibliodepth \setflag \citeself = \false %~default soft \processdesign{\biblio}{}% \global\increment \biblionumber} \def \endbiblio {% \endgraf \fakepar % In case biblio is empty. \global\decrement \bibliodepth \endblockscope{biblio}} % Bibliography Items % ------------ ----- \definecount{\zbibitemnumber}{0} \definetoks{\zbibauthor} \definetoks{\zbibyear} \definetoks{\zbibfullauthor} \definetoks{\bibitemtag} % Tag of current \bibitem. %~ The |\bibitem| command is used in a |\biblio| block to start %~ each entry in the bibliography. It takes two arguments; the %~ format of the first argument depends on the citation style. %~ * Cited by number: |\bibitem{}{*tag*}| %~ * Cited by key: |\bibitem{*key*}{*tag*}| %~ * Cited by author/year: |\bibitem{*author*;*year*;*full-author*}{*tag*}| %~ *. %~ In the author/year format, the second semicolon and *full-author* are %~ optional. \def \bibitem #1#2{% {[info]}{tag} \blockmustbein{\bibitem}{\biblio}% \zbibitemnumber = \itemnumber \increment \zbibitemnumber \ifcase \citestyle \edef \zbibkey {\the\zbibitemnumber}% \zbibauthor = {}% \zbibyear = {}% \zbibfullauthor = {}% \or \def \zbibkey {#1}% \zbibauthor = {}% \zbibyear = {}% \zbibfullauthor = {}% \or \def \zbibkey {}% \zparseauthoryear #1;;;\zmark \else \error{invalidcitestyle}{The \string\citestyle parameter is invalid: \the\citestyle}% \fi \bibitemtag = {#2}% \item{\zbibkey}% \if \PDFhyperlinks \PDFmark{T:#2}\fi \if \notp{\emptyargp{#2}}% \edef \znext {% \noexpand\xref{bib}{\noexpand\folio} {\zbibkey} {{\the\zbibauthor}{\the\zbibyear}{\the\zbibfullauthor}} {#2}}% \znext \fi %%% \if \indexcites %%% \edef \znext {\noexpand\xbiblio1{\the\zbibauthor}}% %%% \znext %%% \fi \ignorespaces} \def \zparseauthoryear #1;#2;#3;#4\zmark{% \if \orp{\emptyargp{#1}}{\emptyargp{#2}}% \error{nocitetags}{The author and/or year are missing}% \fi \zbibauthor = {#1}% \zbibyear = {#2}% \zbibfullauthor = {#3}} % Bibliography Citation Page List % ------------ -------- ---- ---- \setflag \zcitexrefsloaded = \false %~ If this macro is specified as the |\endpartext| of a bibliography %~ |\list|, then each entry in the bibliography will include a list %~ of the pages citing that entry. The argument determines whether %~ each page is made into a hyperlinked PDF button. %~ %~ In order for the citation information to be available, the %~ |\xrefcites| document parameter must be set to 1. \def \citepagelist #1{% {button?} \if \notp{\zcitexrefsloaded}% \mapxrefcites{\zbibcitelist}% \global\setflag \zcitexrefsloaded = \true \fi \setflag \zbibfirstpage = \true \def \zbibprevpage {}% \withname\maplistlf {\=citetag:\the\bibitemtag} {\zbibcitepage{##1}{#1}}} \def \zbibcitelist #1#2{% {page}{tag} \if \withname\undefinedp {\=citetag:#2}% \withname\setlist {\=citetag:#2}={}% \fi \withname\appendlf {\=citetag:#2}{#1}} \def \zbibcitepage #1#2{% {page}{button?} \stringeql{\zsamepage}{#1}{\zbibprevpage}% \if \notp{\zsamepage}% \if \notp{\emptydefp{\zbibprevpage}},\space \fi \if #2% \pagebutton{#1}{#1}% \else #1% \fi \def \zbibprevpage {#1}% \fi} % Low-Level Citation Commands % --------- -------- -------- %~ This command produces the key of the bibliography entry specified %~ by the *tag*. The command makes sense only for the numbered or %~ keyed citation styles. \def \citekey #1{% {tag} %^citation \if \eqlp{\citestyle}{\citebyauthoryear}% \warning{badcitekey}{The \noexpand\citekey command doesn't make sense when citing by author/year}% \fi \zcitetaginfo{#1}% \zcitetext{#1}{\zcitekey}% \zxrefcite{\true}{#1}} %%% \if \indexcites \zciteindex{\zcitekey}\fi} %~ This command produces the author of the bibliography entry specified %~ by the *tag*. The command makes sense only for the author/year %~ citation style. \def \citeauthor #1{% {tag} %^citation \if \neqlp{\citestyle}{\citebyauthoryear}% \warning{badciteauthor}{The \noexpand\citeauthor command only makes sense when citing by author/year}% \fi \zcitetaginfo{#1}% \zcitetext{#1}{\zciteauthor}% \zxrefcite{\true}{#1}} %~ This command produces the year of the bibliography entry specified %~ by the *tag*. The command makes sense only for the author/year %~ citation style. \def \citeyear #1{% {tag} %^citation \if \neqlp{\citestyle}{\citebyauthoryear}% \warning{badciteyear}{The \noexpand\citeyear command only makes sense when citing by author/year}% \fi \zcitetaginfo{#1}% \zcitetext{#1}{\zciteyear}% \zxrefcite{\true}{#1}} %~ This command produces the full author of the bibliography entry specified %~ by the *tag*. The command makes sense only for the author/year %~ citation style. \def \citefullauthor #1{% {tag} %^citation \if \neqlp{\citestyle}{\citebyauthoryear}% \warning{badcitefullauthor}{The \noexpand\citefullauthor command only makes sense when citing by author/year}% \fi \zcitetaginfo{#1}% \zcitetext{#1}{\zcitefullauthor}% \zxrefcite{\true}{#1}} \def \zcitetaginfo #1{% {tag} \zcitenoinfo \if \definedp{\=zB:#1}% \expandafterthrice\zcitetaginfoa \name{\=zB:#1}% \else \writelog{ZzTeX citation: undefined tag `#1'.}% \zxwriteinfo{\false}{undef-tag}{#1}{}% \global\increment \zuntagrefs \fi} \def \zcitetaginfoa #1\zmark#2\zmark#3#4#5{% folio\zmark key\zmark % {author}{year}{full-author} \if \eqlp{\citestyle}{\citebyauthoryear}% \def \zciteauthor {#3}% \def \zciteyear {#4}% \def \zcitefullauthor {#5}% \else \def \zcitekey {#2}% \fi} \def \zcitenoinfo {% \def \zcitekey {???}% \def \zciteauthor {???author???}% \def \zciteyear {???}% \def \zcitefullauthor {???full-author???}} \def \zcitetext #1#2{% {tag}{text} \if \DVIWindoinuse \colorspecial{ifview color push rgb .5 .22 .24}\fi \if \PDFhyperlinks \tagbutton{#1}{#2}% \else #2% \fi \if \DVIWindoinuse \colorspecial{ifview color pop}\fi} \def \zxrefcite #1#2{% {defined?}{tag} \ifcase \xrefcites \relax \or \xref{cite}{\folio}{}{}{#2}% \else \customcitexref{#1}{#2}% {boolean}{tag} \fi} %%%\def \zciteindex #1{% {\zcitemacro} %%% \expandafter\xcite\expandafter1\expandafter{#1}} % High-Level Citation Commands % ---------- -------- -------- %~ This high-level citation command produces the key or author/year %~ of the bibliography entry specified by the *tag*. The text %~ is formatted in the style appropriate for a noun in a sentence. %~ There are two formats for the command: %~ * |\citenoun{*tag*}| accepts a tag and produces the key or author/year. %~ * |\citenoun{*tag*;*info*}| accepts a tag and additional %~ information such as a page number or section reference. %~ *. %~ The format of the text produced is controlled by the |\citenounformat|, %~ |\citenouninfoformat|, and |\citepunct| macros in the design file. \def \citenoun #1{% {tag[;info]} %^citation \expandafter\zsetcitepunc \citepunct \zcitetagsinfo #1;;\zmark \def \zcitenounsep {}% \expandafter\zcitenoun \zcitetags,\zmark} \def \zcitenoun #1,#2\zmark {% tag,other-tags\zmark \zcitenounsep \edef \zcitenounsep {\zcitesep}% \if \eqlp{\citestyle}{\citebyauthoryear}% \if \emptydefp{\zciteinfo}% \zciteonetag{\citenounformat}#1!!\zmark \else \citenouninfoformat{\citeauthor{#1}}{\citeyear{#1}}{\zciteinfo}% \fi \else \if \emptydefp{\zciteinfo}% \citenounformat{\citekey{#1}}% \else \citenouninfoformat{\citekey{#1}}{\zciteinfo}% \fi \fi \if \notp{\emptyargp{#2}}\zcitenoun #2\zmark \fi} %~ This high-level citation command produces the key or author/year %~ of the bibliography entry specified by the *tag*. The text %~ is formatted in the style appropriate for a parenthetical %~ citation list. There are two formats for the command: %~ * |\citeparen{*tag-list*}| accepts one or more tags separated %~ by commas and produces a parenthetical list of keys or author/years. %~ * |\citeparen{*tag*;*info*}| accepts a tag and additional %~ information such as a page number or section reference. %~ *. %~ The format of the text produced is controlled by the |\citeparenformat|, %~ |\citepareninfoformat|, and |\citepunct| macros in the design file. \def \citeparen #1{% {tags[;info]} %^citation \expandafter\zsetcitepunc \citepunct \zcitetagsinfo #1;;\zmark \expandafter\zciteparen \zcitetags,\zmark \zcitecfence} \def \zciteparen #1,#2\zmark {% tag,other-tags\zmark \zciteofence \edef \zciteofence {\zcitesep}% \if \eqlp{\citestyle}{\citebyauthoryear}% \if \emptydefp{\zciteinfo}% \zciteonetag{\citeparenformat}#1!!\zmark \else \citepareninfoformat{\citeauthor{#1}}{\citeyear{#1}}{\zciteinfo}% \fi \else \if \emptydefp{\zciteinfo}% \citeparenformat{\citekey{#1}}% \else \citepareninfoformat{\citekey{#1}}{\zciteinfo}% \fi \fi \if \notp{\emptyargp{#2}}\zciteparen #2\zmark \fi} %~ This high-level citation command produces the key or author/year %~ of the bibliography entry specified by the *tag*. The text %~ is formatted in the style appropriate for a citation that is part %~ of a surrounding parenthetical sentence. %~ There are two formats for the command: %~ * |\citeplain{*tag*}| accepts a tag and produces the key or author/year. %~ * |\citeplain{*tag*;*info*}| accepts a tag and additional %~ information such as a page number or section reference. %~ *. %~ The format of the text produced is controlled by the |\citeplainformat| %~ and |\citeplaininfoformat| macros in the design file. \def \citeplain #1{% {tag[;info]} %^citation \zcitetagsinfo #1;;\zmark \expandafter\zciteplain \zcitetags,\zmark} \def \zciteplain #1,#2\zmark {% tag,other-tags\zmark \if \eqlp{\citestyle}{\citebyauthoryear}% \if \emptydefp{\zciteinfo}% \zciteonetag{\citeparenformat}#1!!\zmark \else \citepareninfoformat{\citeauthor{#1}}{\citeyear{#1}}{\zciteinfo}% \fi \else \if \emptydefp{\zciteinfo}% \citeparenformat{\citekey{#1}}% \else \citepareninfoformat{\citekey{#1}}{\zciteinfo}% \fi \fi \if \notp{\emptyargp{#2}}\zciteplain #2\zmark \fi} \def \zsetcitepunc #1#2#3{% \def \zciteofence {#1}% \def \zcitecfence {#2}% \def \zcitesep {#3}} \def \zcitetagsinfo #1;#2;#3\zmark {% {tags[;info]} \if \emptyargp{#1}% \warning{nocitetags}{No bibliography entry tags were specified}% \fi \def \zcitetags {#1}% \def \zciteinfo {#2}} \def \zciteonetag #1#2!#3!#4\zmark {% \if \emptyargp{#2}% \citeyear{#3}% \else #1{\citeauthor{#2}}{\citeyear{#2}}% \fi}