diff options
Diffstat (limited to 'macros/latex-dev/required/latex-lab/latex-lab-bib.dtx')
-rw-r--r-- | macros/latex-dev/required/latex-lab/latex-lab-bib.dtx | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-bib.dtx b/macros/latex-dev/required/latex-lab/latex-lab-bib.dtx new file mode 100644 index 0000000000..20332d1c9e --- /dev/null +++ b/macros/latex-dev/required/latex-lab/latex-lab-bib.dtx @@ -0,0 +1,343 @@ +% \iffalse meta-comment +% +%% File: latex-lab-bib.dtx (C) Copyright 2023 LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +% The development version of the bundle can be found below +% +% https://github.com/latex3/latex2e/required/latex-lab +% +% for those people who are interested or want to report an issue. +% +%<*driver> +\documentclass{l3doc} +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{latex-lab-bib.dtx} +\end{document} +%</driver> +% +% \fi +% +% \title{The \textsf{latex-lab-bib} package\\ +% Changes and additions to the kernel related to tagging and links in citations and +% bibliography entries} +% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} +% \date{Version 0.80 2023-05-10} +% +% \maketitle +% +% \newcommand{\xt}[1]{\textsl{\textsf{#1}}} +% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} +% \newcommand{\docclass}{document class \marginpar{\raggedright document class +% customizations}} +% +% \providecommand\hook[1]{\texttt{#1}} +% +% \begin{abstract} +% \end{abstract} +% +% \section{Introduction} +% +% The followings contains small changes to improve tagging of +% bibliography entries and citations. +% +% The tagging of the bibliography is actually quite straightforward: +% A bibliography is typically a list with a heading and the sec and block tagging +% code handles that. +% +% There are here only two problems: +% +% \begin{itemize} +% \item The structure number of the \texttt{LI} element +% create by a \cs{bibitem} must be recorded somehow to allow to reference it in +% a \cs{cite}. +% \item \pkg{hyperref} redefines the item command and so breaks the list structure +% see \url{https://github.com/latex3/latex2e/discussions/1010#discussioncomment-5565418} +% \end{itemize} +% +% Both problems are rather easy to resolve, but it must be checked if other packages +% interfere again by redefining the commands. +% +% More difficult is the tagging of citation commands. Citations should be inside +% a Reference structure and contain a /Ref entry pointing to the relevant +% item in the bibliography. For simple citations like +% \enquote{[1]} or \enquote{Doody (2023)} this is easy, but it is not obvious how +% to handle combined citations like \enquote{Doody (2003,2018)} (or even compressed citations +% like \enquote{[1-3]}). The implementation follows here the links: whatever hyperref would +% link is set as the reference. +% +% An additional problem are the various packages trying to improve citation commands +% which all should be checked. Currently only natbib has been tried. +% +% The biblatex package isn't handled yet. +% +% +% \section{Implementation} +% \begin{macrocode} +%<*package> +%<@@=tag> +% \end{macrocode} +% \begin{macrocode} +\ProvidesExplPackage {latex-lab-testphase-bib} {2023-05-18} {0.8} + {Code related to the tagging of bibliography and cite command} +% \end{macrocode} +% We need at least the block tagging code. +% \begin{macrocode} +\RequirePackage{latex-lab-testphase-block-tagging} +% \end{macrocode} +% +% At first we suppress the patches from hyperref. This will only work with the next +% hyperref! +% \begin{macrocode} +\def\hyper@nopatch@bib{} +% \end{macrocode} + +% \begin{macro}{\@extra@binfo,\@extra@b@citeb} +% These are taken from hyperref, they are for chapterbib compability (and also +% signal to chapterbib not to change the citation commands) +% \begin{macrocode} +\providecommand*\@extra@binfo{}% +\providecommand\@extra@b@citeb{} +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\l_@@_bib_target_tl} +% Items should add a target, to avoid that user code +% interferes we don't rely on \cs{@currentHref} +% \begin{macrocode} +\tl_new:N\l_@@_bib_target_tl +% \end{macrocode} +% \end{variable} + +%\subsection{Handling the bibliography} +% \begin{macro}{\lbibitem} +% The item command if an optional argument is use. +% +% We only prepend some code. +% If we had already generic hooks with arguments +% we could probably use them \ldots +% \begin{macrocode} +\def\@lbibitem[#1]#2{% +% \end{macrocode} +% we store the target name for the following code. +% \begin{macrocode} + \tl_set:Nx\l_@@_bib_target_tl{cite.#2\@extra@b@citeb} +% \end{macrocode} +% The target is added at the begin of the paragraph. +% \begin{macrocode} + \AddToHookNext{para/begin}{\makebox[0pt][r]{\MakeLinkTarget*{\l_@@_bib_target_tl}\hspace{\leftmargin}}} + \item[\@biblabel{#1}\hfill]\if@filesw + {\let\protect\noexpand + \immediate + \write\@auxout{\string\bibcite{#2}{#1}}}\fi\ignorespaces} +% \end{macrocode} +% we make a copy to be able to reinstate the definition. This is e.g. +% currently needed with hyperref. +% \begin{macrocode} +\let\@kernel@copy@lbibitem\@lbibitem +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@bibitem} +% Similar for bibitem. +% TODO: If hyperref is loaded we will get a second target from the refstepcounter, +% but this is ignored for now. +% \begin{macrocode} +\def\@bibitem#1{ + \tl_set:Nx\l_@@_bib_target_tl{cite.#1\@extra@b@citeb}% + \AddToHookNext{para/begin}{\makebox[0pt][r]{\MakeLinkTarget*{\l_@@_bib_target_tl}\hspace{\leftmargin}}} + \item\if@filesw \immediate\write\@auxout + {\string\bibcite{#1}{\the\value{\@listctr}}}\fi\ignorespaces} +\let\@kernel@copy@bibitem\@bibitem +% \end{macrocode} +% \end{macro} +% +% TODO The LI-structure should set a label, we redefine the internal command locally for +% now, but perhaps this need a receipe? +% +% \begin{macrocode} +\AddToHook{env/thebibliography/begin} + {\cs_set:Npn \__block_list_item_begin: + { \tagstructbegin{tag=\LItag,label=\l_@@_bib_target_tl}} + } +% \end{macrocode} +% +% \subsection{Handling citation commands} +% We redefine similar to hyperref the \cs{bibcite} command to inject link and +% structure. Even if it looks a bit odd it is now used for many years and so +% hopefully compatible with various packages. But differently to hyperref we use +% the new hooks with arguments. +% TODO: consider name. Perhaps use the generic names? +% \begin{macrocode} +\NewMirroredHookPairWithArguments{bibcite/before}{bibcite/after}{2} +\def\bibcite#1#2{% + \@newl@bel{b}{#1\@extra@binfo}{% + \UseHookWithArguments{bibcite/before}{2}{#1}{#2} + #2 + \UseHookWithArguments{bibcite/after}{2}{#1}{#2} + }% + }% +\let\@kernel@copy@bibcite\bibcite +% \end{macrocode} +% Now we add the tagging structure. +% TODO: the ref key should expand its argument directly! +% \begin{macrocode} +\AddToHookWithArguments{bibcite/before} + { + \tag_mc_end_push: + \exp_args:Nx\tagstructbegin{tag=Reference,ref=cite.#1\@extra@b@citeb} + \tagmcbegin{} + } +\AddToHookWithArguments{bibcite/after}[tag] + { + \tag_mc_end: + \tagstructend + \tag_mc_begin_pop:n{} + } +% \end{macrocode} +% At last the code for hyperref, the link will be inside the reference, but +% this can be changed with a rule. +% \begin{macrocode} +\AddToHook{package/hyperref/after} + { +% \end{macrocode} +% the next hyperref will allow to suppress the bib patches, but with older +% versions we muss reinstated them. +% \begin{macrocode} + \@ifpackagelater{hyperref}{2023-05-01}{} + { + \@ifpackageloaded{natbib}{} + {\let\@lbibitem\@kernel@copy@lbibitem + \let\@bibitem\@kernel@copy@bibitem + \let\bibcite\@kernel@copy@bibcite} + } + \AddToHookWithArguments{bibcite/before}{\hyper@linkstart{cite}{cite.#1\@extra@b@citeb}} + \AddToHookWithArguments{bibcite/after}{\hyper@linkend} + } +% \end{macrocode} +% +% \subsection{Natbib support} +% natbib offers various hooks that can be used. The main problem is +% to coordinate with the hyperref use of the same hooks. +% We also have to add something at the begin of \cs{@lbibitem}. +% As generic hooks with arguments aren't available yet, we have to copy the definition +% +% \begin{macrocode} +\AddToHook{package/natbib/after} + { + \def\hyper@natanchorstart#1{\MakeLinkTarget*{#1}} + \def\@lbibitem[#1]#2{% + \tl_set:Nx\l__tag_bib_target_tl{cite.#2\@extra@b@citeb} + \if\relax\@extra@b@citeb\relax\else + \@ifundefined{br@#2\@extra@b@citeb}{}{% + \@namedef{br@#2}{\@nameuse{br@#2\@extra@b@citeb}}% + }% + \fi + \@ifundefined{b@#2\@extra@b@citeb}{% + \def\NAT@num{}% + }{% + \NAT@parse{#2}% + }% + \def\NAT@tmp{#1}% + \expandafter\let\expandafter\bibitemOpen\csname NAT@b@open@#2\endcsname + \expandafter\let\expandafter\bibitemShut\csname NAT@b@shut@#2\endcsname + \@ifnum{\NAT@merge>\@ne}{% + \NAT@bibitem@first@sw{% + \@firstoftwo + }{% + \@ifundefined{NAT@b*@#2}{% + \@firstoftwo + }{% + \expandafter\def\expandafter\NAT@num\expandafter{\the\c@NAT@ctr}% + \@secondoftwo + }% + }% + }{% + \@firstoftwo + }% + {% + \global\advance\c@NAT@ctr\@ne + \@ifx{\NAT@tmp\@empty}{\@firstoftwo}{% + \@secondoftwo + }% + {% + \expandafter\def\expandafter\NAT@num\expandafter{\the\c@NAT@ctr}% + \global\NAT@stdbsttrue + }{}% + \bibitem@fin + \item[\hfil\NAT@anchor{#2}{\NAT@num}]% + \global\let\NAT@bibitem@first@sw\@secondoftwo + \NAT@bibitem@init + }% + {% + \NAT@anchor{#2}{}% + \NAT@bibitem@cont + \bibitem@fin + }% + \@ifx{\NAT@tmp\@empty}{% + \NAT@wrout{\the\c@NAT@ctr}{}{}{}{#2}% + }{% + \expandafter\NAT@ifcmd\NAT@tmp(@)(@)\@nil{#2}% + }% + }% +% \end{macrocode} +% we redefine the hook to use latex hooks. +% \begin{macrocode} + \NewMirroredHookPairWithArguments{natbib/linkstart}{natbib/linkend}{1} + \renewcommand\hyper@natlinkstart[1]{\UseHookWithArguments{natbib/linkstart}{1}{#1}} + \renewcommand\hyper@natlinkend{\UseHookWithArguments{natbib/linkend}{1}{}} + \AddToHookWithArguments{natbib/linkstart} + { + \leavevmode + \tag_mc_end_push: + \exp_args:Nx\tagstructbegin{tag=Reference,ref=cite.#1\@extra@b@citeb} + \tagmcbegin{} + } + \AddToHook{natbib/linkend} + { + \tag_mc_end: + \tagstructend + \tag_mc_begin_pop:n{} + } + } +% \end{macrocode} +% if hyperref is loaded we have to repeat the definition +% +% \begin{macrocode} +\AddToHook{package/hyperref/after} + { + \renewcommand\hyper@natlinkstart[1]{\UseHookWithArguments{natbib/linkstart}{1}{#1}} + \renewcommand\hyper@natlinkend{\UseHookWithArguments{natbib/linkend}{1}{}} + \AddToHookWithArguments{natbib/linkstart} + { + \Hy@backout{#1}% + \hyper@linkstart{cite}{cite.#1}% + \def\hyper@nat@current{#1} + } + \AddToHook{natbib/linkend} + { + \hyper@linkend + } + } +% \end{macrocode} +% \begin{macrocode} +%</package> +% \end{macrocode} +% \begin{macrocode} +%<*latex-lab> +\ProvidesFile{bib-latex-lab-testphase.ltx} + [2023-05-18 v0.8 code related to the tagging of bib and citations] + +\RequirePackage{latex-lab-testphase-bib} + +%</latex-lab> +% \end{macrocode} |