plk / biblatex

biblatex is a sophisticated bibliography system for LaTeX users. It has considerably more features than traditional bibtex and supports UTF-8
506 stars 116 forks source link

improve tagging support if hyperref is not used #1366

Open u-fischer opened 2 weeks ago

u-fischer commented 2 weeks ago

Tagging of citations are basically like adding links: some literals must be put around the citation which references/links to the bibliography.

The tagging code in latex lab makes therefore use of \hyper@natlinkstart and hyper@natlinkend to add the tagging. Sadly this means that with biblatex (differently to natbib) tagging currently works correctly only if hyperref has been loaded as it doesn't use the commands if hyperref is not detected.

Could biblatex similar to natbib simply provide the commands and use them always? Then I would get something like this which is correctly tagged even if hyperref is not there:

\DocumentMetadata{
  lang        = de,
  pdfversion  = 2.0,
  pdfstandard = ua-2,
  pdfstandard = a-4f,
  testphase   =
  {
   phase-III
  },
  uncompress,
}

\documentclass{article}
\usepackage{biblatex}
\addbibresource{biblatex-examples.bib}
\begin{document}
\makeatletter
\providecommand\hyper@natlinkstart[1]{}% 
\providecommand\hyper@natlinkend{}%
\hyper@natlinkstart{\the\c@refsection @doody}%
\cite{doody}
\hyper@natlinkend
\printbibliography
\end{document}
moewew commented 2 weeks ago

Sounds like a plan.

I also found \ifundef\hyper@natanchorstart in the hyperref code

https://github.com/plk/biblatex/blob/58f64eb55fb9f534457ebaaca22ae446168218bf/tex/latex/biblatex/biblatex.sty#L12167-L12205

so that \hyper@natlinkstart is only used if that command is defined. Do you happen to know why the test is there? Were these commands "new" at some point, so that biblatex needed backwards compatibility code? If so, we can probably get rid of that now and simplify the code further.

moewew commented 2 weeks ago

Ah. Another thing: For the hyperref branch, biblatex currently saves and resets spacefactor codes (with \blx@sfsave and \blx@sfrest - presumably due to whatsits?). Will we need the same for the tagging code if hyperref is not loaded? Or should we simplify the code to skip that bit.

u-fischer commented 2 weeks ago

Sorry I didn't really check your code (or I did but that was sometimes last year when I wrote the tagging support ;-)). I only remember that I couldn't find a clean hook if hyperref is not loaded.

\hyper@natlinkstart etc is old and in hyperref and natbib for quite some time.

The names of the commands do not really fit to biblatex, but nevertheless I think one can view them as "official" citations interfaces. and I do not think there is a problem if biblatex does like natbib

\providecommand\hyper@natanchorstart[1]{}%
\providecommand\hyper@natanchorend{}%
\providecommand\hyper@natlinkstart[1]{}%
\providecommand\hyper@natlinkend{}%
\providecommand\hyper@natlinkbreak[2]{#1}%

and uses them where suited.

hyperref redefines that currently like this,

\def\hyper@natlinkstart#1{%
  \Hy@backout{#1}%
  \hyper@linkstart{cite}{cite.#1}%
  \def\hyper@nat@current{#1}%
}
\def\hyper@natlinkend{%
  \hyper@linkend
}
\def\hyper@natlinkbreak#1#2{%
  \hyper@linkend#1\hyper@linkstart{cite}{cite.#2}%
}
\def\hyper@natanchorstart#1{%
  \Hy@raisedlink{\hyper@anchorstart{cite.#1}}%
}
\def\hyper@natanchorend{\hyper@anchorend}

It is quite possible that at some time the tagging code is added directly and not through hooks as it is done now. So if you see any need to change these definitions, please tell us and do not redefine them silently!

u-fischer commented 2 weeks ago

Another thing: For the hyperref branch, biblatex currently saves and resets spacefactor codes (with \blx@sfsave and \blx@sfrest - presumably due to whatsits?). Will we need the same for the tagging code if hyperref is not loaded?

Yes, I assume so. At least with pdflatex the tagging code inserts whatsits.

moewew commented 2 weeks ago

Ah, nice. That should unify the interface a little. Thanks for the answer. I will see if I can rustle something up.

moewew commented 2 weeks ago

It would be great if you could have a look at https://github.com/moewew/biblatex/commit/c8198ff8bee8a9d4948d13716003cfba164456ae in https://github.com/moewew/biblatex/tree/nohypertag and give it a spin.

u-fischer commented 2 weeks ago

can I use l3build to install the package for tests? I don't think it is necessary to hide the \providecommand inside some test. Simply define always ...

moewew commented 2 weeks ago

I've never tried that. We use l3build for our tests, but I'm not sure about other package tests.

You can use the file https://github.com/moewew/biblatex/blob/nohypertag/tex/latex/biblatex/biblatex.sty as a drop-in replacement for the current biblatex.sty if you change the

https://github.com/moewew/biblatex/blob/c8198ff8bee8a9d4948d13716003cfba164456ae/tex/latex/biblatex/biblatex.sty#L15-L16

to usable values. That's what I usually do.

u-fischer commented 2 weeks ago

Ok, one can partly install with l3build. It copies at least biblatex.sty. But one then has to exchange the start manually with.

\def\abx@date{2024/03/21}
\def\abx@version{3.20}

Perhaps biblatex could use some defaults here, which work always?

Apart from this the code works fine and the tagging is correct. As I said, I would provide the command always and not inside \blx@mknohyperref, that only complicates without much gain.

moewew commented 2 weeks ago

I'll look into l3build at some point, but the last time I looked I had trouble getting it to use the files in subfolders (like lbx etc.) for tests and had to give up.

The tagging is already automatically changed for testing, so maybe it's just a matter of making that also happen for install.


I didn't dare using \providecommand globally, because I feared hyperref or some other code might use \newcommand and we would run into trouble. But if that's not the case and you think the global approach is preferable, I can of course change that.

u-fischer commented 2 weeks ago

I didn't dare using \providecommand globally, because I feared hyperref or some other code might use \newcommand and we would run into trouble

natbib provides the commands since a long time. I think we would know by know if there is a package clash.

The tagging is already automatically changed for testing, so maybe it's just a matter of making that also happen for install.

It uses the checkinit_hook to tag the file, but I'm not aware of a similar hook for installing. @josephwright would know better. But I wonder if you shouldn't change your version check and allow "DATE" and "VERSION", perhaps with a warning. That would make your own testing easier - you could even test with various biber versions etc.