Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.1.6.2 with link-citations: true breaks LaTeX citation hyperlinks #9022

Closed
jpcirrus opened this issue Aug 24, 2023 · 14 comments
Closed

3.1.6.2 with link-citations: true breaks LaTeX citation hyperlinks #9022

jpcirrus opened this issue Aug 24, 2023 · 14 comments
Labels

Comments

@jpcirrus
Copy link
Contributor

In pandoc 3.1.6.2, #8744 was resolved by commit 70329ed. However, with link-citations: true the applicable item in the reference list is no longer linked to the citation.

The LaTeX output in 3.1.6.1: (\protect\hyperlink{ref-casey2018}{Casey, 2018}), is changed in 3.1.6.2 to: (\hyperref[ref-casey2018]{Casey, 2018}).

@jpcirrus jpcirrus added the bug label Aug 24, 2023
@jgm
Copy link
Owner

jgm commented Aug 25, 2023

Is there a corresponding hypertarget defined for ref-casey2018?

@jpcirrus
Copy link
Contributor Author

Yes. There is no difference in the reference list between 3.1.6.1 and 3.1.6.2:

\hypertarget{refs}{}
\begin{CSLReferences}{1}{0}
\leavevmode\vadjust pre{\hypertarget{ref-casey2018}{}}%
Casey, G. (2018). Type 2 diabetes mellitus. \emph{Kai Tiaki : Nursing New Zealand}, \emph{24}(4), 20–24.
\end{CSLReferences}

@jgm
Copy link
Owner

jgm commented Aug 25, 2023

I see what is happening. From hyperref manual:

\hyperref[label]{text}
text is made into a link to the same place as \ref{label} would be linked.

The change in #8744 left headings with a label but no hypertarget; \hyperref works well to link to such headings, but it won't work for linking to an arbitrary hypertarget. Perhaps we could fix this by adding label everywhere we currently use hypertarget (perhaps, instead of hypertarget), but I don't think this would work; I think the links would point to the start of the section rather than the particular heading.

What to do? One option would be to revert #8744 and go back to the old verbose approach. The other option would be to have the writer keep track of which internal links link to headings and which link to other things, and use \hyperref for the former and \hyperlink for the latter. Ugly but maybe doable. Could also lead to bad results when people are using pandoc to assemble parts of a document (since the internal link may be in a different part than the heading itself).

@u-fischer do you have any further advice?

@u-fischer
Copy link

Well instead of \hypertarget{xxx}, you can always use \phantomsection\label{xxx} and then \hyperref[xxx]{sometext} would work.

In a current LaTeX you can also use \MakeLinkTarget*{target}\label{label}. This has the benefit that both \hyperref[label]{sometext} and \hyperlink{target}{sometext} will work. Also \MakeLinkTarget won't error if hyperref is not loaded.

But setting targets and links manually as you do here has the same problems as in the other question: They make the code ugly, and they loose semantic information. You get a link from the citation text to the bib entry but you don't get more.

As example: there just was a question on tex.sx why backref doesn't work with the LaTeX generated from pandoc: https://tex.stackexchange.com/q/693293/2388. Well backref needs to know that Casey, 2018 is a citation, and it needs to know that Casey, G. (2018). Type 2 diabetes mellitus. is the related bibentry. It does that my making use of the semantic commands \cite and \bibitem, which are missing here.

Accessibility is also a problem. If you use the standard commands (e.g. with natbib to get author year) and load the tagging code (this needs a current LaTeX!):

\DocumentMetadata{testphase=phase-III}
\documentclass{article}
\usepackage{natbib}
\begin{document}
\cite{ref-casey2018}, \citep{ref-casey2018}

\begin{thebibliography}{99}
\bibitem[Casey, G.(2018)]{ref-casey2018}
Casey, G. (2018). Type 2 diabetes mellitus. \ldots
\end{thebibliography}

\end{document} 

Then even without hyperref (and without bibtex or any external tool!) you get a structure where the citation is connected to the bib entry. The citation is surrounded by a Reference structure, which contains a /Ref pointing to the list entry in the bibliography:

/Type /StructElem /S /Reference /P 13 0 R /Ref [ 21 0 R]

But if the output of pandoc has not structure information about what is a citation and what is a bibentry then the tagging code has no chance to add such structures anymore.

@jgm
Copy link
Owner

jgm commented Aug 26, 2023

Of course, it's possible to tell pandoc to produce natbib or biblatex citation commands instead of using citeproc (--natbib, --biblatex options). (We don't attempt to run biber or bibtex in generating a PDF though -- these options are for people who know what they're doing and can add a separate build step for the PDF.) But when we're using citeproc I don't think we can use \cite, since we need to use the text of the citation generated by citeproc. (Or is there a way to override the generation of text so that \cite just uses the citation text we supply?)

@jgm
Copy link
Owner

jgm commented Aug 26, 2023

Thanks for the pointer about \phantomsection...I didn't know about that. We should be using this with unnumbered section headings, too, presumably.

@u-fischer
Copy link

(Or is there a way to override the generation of text so that \cite just uses the citation text we supply?)

It depends on how many different texts the \cite should produce. If there is only one for a reference, it is rather trivial, you simply give it as label of the \bibitem command. If there are more variants you need to code a bit (natbib handles typically three variants).

@jgm
Copy link
Owner

jgm commented Aug 26, 2023

Just to be clear, what I mean is this: using --citeproc, we'll have some arbitrary LaTeX string that is the text for the citation. It might be author date or numeric or something else. So, the question is whether there's a way to do something like

\cite[smith2000]{Arbitrary LaTeX text here which will be printed instead of the citation natbib would ordinarily generate}

@u-fischer
Copy link

yes, the main question is how many different arbitrary text you have for every citation. If it is only one you can make use of the natbib interface:

\documentclass{article}
\usepackage{natbib}
\let\citeproc\citefullauthor %just a nicer name ...
\usepackage{hyperref}
\begin{document}
\cite{ref-casey2018}, \citeproc{ref-casey2018} 

\citeproc[see p. 24]{ref-doody2020} 

\begin{thebibliography}{99}
\bibitem[Casey(2018)Arbitrary LaTeX text]{ref-casey2018} Casey, G. (2018). 
    Type 
    2     
    diabetes mellitus. \ldots 

\bibitem[doody(2020)Another Arbitrary LaTeX text]{ref-doody2020} Doody 
    (2029). \ldots 
\end{thebibliography}

\end{document}

image

If it is more, you need to do some coding, but you can store basically what you want in the \bibitem argument - jurabib used that e.g. to implement an author-title system.

@jgm
Copy link
Owner

jgm commented Aug 26, 2023

Interestingly, when I use \phantomsection\label{...} on the bibliography entries, \hyperref works to link to them in regular LaTeX documents, but not in Beamer documents ; \hyperlink works for both though.

@jgm
Copy link
Owner

jgm commented Aug 26, 2023

Unfortunately this trick with bibitem won't work for us. citeproc won't always generate the same citation (part) for the same item, because of things like "ibid."

@jgm jgm closed this as completed in f7035d0 Aug 26, 2023
@u-fischer
Copy link

u-fischer commented Aug 27, 2023

Unfortunately this trick with bibitem won't work for us. citeproc won't always generate the same citation (part) for the same item, because of things like "ibid."

That's why I asked about the variants. If you really want arbitrary text you need a bit code (mostly to get rid of the default brackets ...):

Note: the empty lines between the bibitems are needed for backref.

\documentclass{article}
\usepackage[backref]{hyperref}

\NewDocumentCommand\citeproctext{}{}
\NewDocumentCommand\citeproc{mm}{%
  \begingroup\def\citeproctext{#2}\cite{#1}\endgroup}
\makeatletter
%no brackets:
 \def\@biblabel#1{}
 \def\@cite#1#2{{#1\if@tempswa , #2\fi}}
\makeatother 
\begin{document}
\section{Introduction}

\citeproc{ref-casey2018}{first arbitrary text}


\section{test}

\citeproc{ref-casey2018}{ibid}

\citeproc{ref-doody2018}{another arbitrary text}

\begin{thebibliography}{99}
\bibitem[\citeproctext]{ref-casey2018} Casey, G. (2018). Text

\bibitem[\citeproctext]{ref-doody2018} Doody, G. (2018). Text

\bibitem[\citeproctext]{other} other
\end{thebibliography}
\end{document}

image

@jgm
Copy link
Owner

jgm commented Aug 27, 2023

That's a neat approach! I may try that.

@jgm
Copy link
Owner

jgm commented Aug 27, 2023

Created new issue #9031 for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants