7

Consider the document

\documentclass{article}
\usepackage{lipsum}
\usepackage{hyperref}
\begin{document}
\edef\l{Lorem,ipsum,dolor,sit,amet,,
  consectetur,adipiscing,elit,,sed,do,
  eiusmod,tempor,incididunt,ut,labore,et,dolore,magna,aliqua.  ,,Ut,
  enim,ad,minim,veniam,,quis,nostrud,exercitation,ullamco,laboris,
  nisi,ut,aliquip,ex,ea,commodo,consequat.  ,,Duis,aute,irure,
  dolor,in,reprehenderit,in,voluptate,velit,esse,cillum,dolore,eu,
  fugiat,nulla,pariatur.  ,,Excepteur,
  sint,occaecat,cupidatat,non,proident,,sunt,in,culpa,qui,officia,
  deserunt,mollit,anim,id,est,laborum.}
\url{\l}

\url{\l}

\url{\l}

\url{\l}

\url{\l}

\url{\l}

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
\url{\l}
\end{document}

It produces a url that breaks across the page, causing the issues described in Hyperref Link Spans a Pagebreak, Looks Ugly. However, if I put the link in an \mbox as suggested by https://tex.stackexchange.com/a/182769/2066, then the url runs off the right side of the page. I can set \interlinepenalty 10000 as suggested by https://tex.stackexchange.com/a/21985/2066, but that's not ideal for long paragraphs as it results in not breaking that paragraph at all. I can insert \widowpenalties 7 10000 10000 10000 10000 10000 10000 0 which does what I want here, but that requires knowing how many lines the link spans and where it is in the paragraph, etc. Is there a better way, or at least a way to automate the calculation of the arguments to \windowpenalties and hide it behind a command? (And is there a way to support multiple non-page-breakable links in the same paragraph? (It would be nice for this to be an option of the hyperref package...))

Edit: Since it seems like it might be relevant, I need a solution that works with PDFs generated by LuaLaTeX and not just pdflatex.

1
  • 1
    Good question. I'd consider trying sloppypar with the urls in \mboxes, perhaps with a bit of rewriting. (But, of course, that's not automatic.) Jan 11, 2021 at 2:26

1 Answer 1

14

Update 2022-11-04

The patches needed to interrupt the links will move from pdfmanagement-testphase to latex-lab and will not be loaded automatically anymore.

That means that starting with version 0.95t of the pdfmanagment the patches must be loaded in \DocumentMetadata explicitly until they are added to LaTeX directly:

\DocumentMetadata{testphase=new-or-1}

Update 2021-08-28.

I just uploaded a new version of the pdfmanagment-testphase package. It now contains code to interrupt the links in the header and footer. So the following will give the same output as with the patches mentioned below. It requires a current tex system (texlive 2021 or a current miktex) as it needs some new primitives.

\RequirePackage{pdfmanagement-testphase} % no longer needed with next latex 2022-06-01
\DeclareDocumentMetadata{} % Change to \DocumentMetadata{} in latex 2022-06-01

\documentclass{article}
\usepackage{lipsum}
\usepackage{hyperref}
\usepackage{color,fancyhdr}
\pagestyle{fancy}
\lhead{HEADER}
\lfoot{FOOTER}

\textheight=2.5cm
\begin{document}

\section{abc}
x\\x\\x\\x
\href{https://www.latex-project.org}{Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.}\\x

\end{document}

Old answer

A link in a pdf is basically a rectangular (leaving out more complicated shapes) area on a page.

If a link is broken over lines or pages, pdftex has to create a number of links, one for each piece/box. To decide if a piece is part of such a broken link, pdftex keeps a stack of links created by \pdfstartlink, called pdf_link_stack. When writing out an hbox to pdf, pdftex checks if the nesting level of the box is the same as the nesting level of the top entry in pdf_link_stack if yes that box would become a link, too.

This means that it depends on the boxing level if the header or the footer is a link or not.

The boxing level of the header and footer are different: In your example only the header is a link. But if you load the color package this changes, as color adds an additional box. Similar if you use fancyhdr which adds boxes too.

One way around the problem could be to add more box commands around the text body. But this is not easy to do as you can't know how many levels are needed: packages and users can easily add more boxes, e.g. by using a \parbox in the footer.

So in TeXLive 2021 pdftex instead will get two new primitives which will help to avoid this problem (there are modelled around a similar \special from dvipdfmx) (for windows one can get the binaries from w32tex.org. MiKTeX has the new binaries already too):

\pdfrunninglinkoff and \pdfrunninglinkon will allow to interrupt the linking.

Their use is not completly trivial as they must be placed at the correct box level. The following shows how \@outputpage should be changed to get this working with the box setup if color is loaded:

\documentclass{article}
\usepackage{lipsum}
\usepackage{hyperref}
\usepackage{color,xpatch,fancyhdr}
\pagestyle{fancy}
\lhead{HEADER}
\lfoot{FOOTER}

\makeatletter
%patches for texlive 2021/current miktex
\xpatchcmd\@outputpage{\vfil\color@hbox}{\vfil\pdfrunninglinkoff\color@hbox}{}{\fail}
\xpatchcmd\@outputpage{{\@thehead}\color@endbox}{{\@thehead}\color@endbox\pdfrunninglinkon}{}{\fail}
\xpatchcmd\@outputpage{\footskip\color@hbox\normalcolor}{\footskip\color@hbox\normalcolor\pdfrunninglinkoff}{}{\fail}
\xpatchcmd\@outputpage{{\@thefoot}\color@endbox}{{\@thefoot}\pdfrunninglinkon\color@endbox}{}{\fail}
\makeatother

\textheight=2.5cm
\begin{document}

\section{abc}
x\\x\\x\\x
\href{https://www.latex-project.org}{Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.}\\x

\end{document}

Output without the patches:

output without patches

Output with the patches:

enter image description here

11
  • Ah, neat! It's awesome that this problem seems like it'll finally be getting fixed. (I take it this fix will make it's way into the documentclasses or whatever defines \@outputpage eventually?) I neglected to mention (since I thought it was unrelated) that I need to use lualatex instead of pdflatex because pdftex runs out of its memory limits with the number of points in the pgf/tikz plots I have, and I haven't found a platform-independent way to increase the various memory limits. Will this solution work for lualatex too? Jan 11, 2021 at 15:16
  • I'm just discussing on the luatex-dev list if they can add this too: mailman.ntg.nl/pipermail/dev-luatex/2021-January/006426.html. \@outputpage is defined by the latex format. Links in a footnote are another problem. But probably here LaTeX should simply add another boxing level around the insert. Jan 11, 2021 at 15:24
  • @JasonGross with the newest version of the pdfmanagement which should be tomorrow or on monday in the tex systems it should work. Aug 28, 2021 at 18:31
  • Would anybody who knows please tell me how to use this in current Overleaf? I have this problem, however, I do not know what pdfmanagement-testphase and latex-lab are and placing this to my document just creates errors \DocumentMetadata{testphase=new-or-1}. Sorry for my ignorance.
    – Paloha
    Apr 4 at 0:45
  • @Paloha I can't test now, but imho simply \DocumentMetadata{} should work in overleaf. Apr 4 at 1:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .