Skip to content

Commit f62a004

Browse files
matthias314mortenpi
andcommitted
fix broken PDF links
Co-authored-by: Morten Piibeleht <[email protected]>
1 parent 9b5105b commit f62a004

File tree

4 files changed

+27
-15
lines changed

4 files changed

+27
-15
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* ![Bugfix][badge-bugfix] Documenter now generates the correct source URLs for docstrings from other packages when the `repo` argument to `makedocs` is set (note: the source links to such docstrings only work if the external package is cloned from GitHub and added as a dev-dependency). However, this change **breaks** the case where the `repo` argument is used to override the main package/repository URL, assuming the repository is cloned from GitHub. ([#1808][github-1808])
2424
* ![Bugfix][badge-bugfix] Documenter no longer uses the `TRAVIS_REPO_SLUG` environment variable to determine the Git remote of non-main repositories (when inferring it from the Git repository configuration has failed), which could previously lead to bad source links. ([#1881][github-1881])
2525
* ![Bugfix][badge-bugfix] Line endings in Markdown source files are now normalized to `LF` before parsing, to work around [a bug in the Julia Markdown parser][julia-29344] where parsing is sensitive to line endings, and can therefore cause platform-dependent behavior. ([#1906][github-1906])
26+
* ![Bugfix][badge-bugfix] Previously broken links within the PDF output are now fixed. (Julia issues: [pdf manual 1.5.2 links][julia-38054] and second part of [Dead links in pdf documentation][julia-43652])
2627

2728
## Version `v0.27.23`
2829

assets/latex/documenter.sty

+6
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,9 @@
8585
\usepackage{graphicx}
8686
\usepackage[export]{adjustbox}
8787
%
88+
89+
% Some internal link targets are implemented with \label, some with \hypertarget,
90+
% but they require different links. This inserts a \hyperref if a corresponding label exists,
91+
% and \hyperlink if it doesn't.
92+
\def\hyperlinkref#1#2{\@ifundefined{r@#1}{\hyperlink{#1}{#2}}{\hyperref[#1]{#2}}}
93+
%

src/Anchors.jl

+6-4
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,16 @@ function anchor(m::AnchorMap, id, file, n)
124124
nothing
125125
end
126126

127+
"""
128+
Create a label from an anchor.
129+
"""
130+
label(a::Anchor) = (a.nth == 1) ? a.id : string(a.id, "-", a.nth)
131+
127132
"""
128133
Create an HTML fragment from an anchor.
129134
"""
130135
function fragment(a::Anchor)
131-
frag = string("#", a.id)
132-
if a.nth > 1
133-
frag = string(frag, "-", a.nth)
134-
end
136+
frag = string("#", label(a))
135137
# TODO: Sanitize the fragment
136138
return frag
137139
end

src/Writers/LaTeXWriter.jl

+14-11
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ Context(io) = Context{typeof(io)}(io, false, Dict(), 1, "")
8585
_print(c::Context, args...) = Base.print(c.io, args...)
8686
_println(c::Context, args...) = Base.println(c.io, args...)
8787

88+
# Labels in the TeX file are hashes of plain text labels.
89+
# To keep the plain text label (for debugging), say _hash(x) = x
90+
_hash(x) = string(hash(x))
91+
8892

8993
const STYLE = joinpath(dirname(@__FILE__), "..", "..", "assets", "latex", "documenter.sty")
9094
const DEFAULT_PREAMBLE_PATH = joinpath(dirname(@__FILE__), "..", "..", "assets", "latex", "preamble.tex")
@@ -273,9 +277,9 @@ function latex(io::IO, vec::Vector, page, doc)
273277
end
274278

275279
function latex(io::IO, anchor::Anchors.Anchor, page, doc)
276-
id = string(hash(string(anchor.id, "-", anchor.nth)))
277-
_println(io, "\n\\hypertarget{", id, "}{}\n")
280+
id = _hash(Anchors.label(anchor))
278281
latex(io, anchor.object, page, doc)
282+
_println(io, "\n\\label{", id, "}{}\n")
279283
end
280284

281285

@@ -288,10 +292,9 @@ function latex(io::IO, node::Documents.DocsNodes, page, doc)
288292
end
289293

290294
function latex(io::IO, node::Documents.DocsNode, page, doc)
291-
id = string(hash(string(node.anchor.id)))
295+
id = _hash(Anchors.label(node.anchor))
292296
# Docstring header based on the name of the binding and it's category.
293-
_println(io, "\\hypertarget{", id, "}{} ")
294-
_print(io, "\\hyperlink{", id, "}{\\texttt{")
297+
_print(io, "\\hypertarget{", id, "}{\\texttt{")
295298
latexesc(io, string(node.object.binding))
296299
_print(io, "}} ")
297300
_println(io, " -- {", Utilities.doccat(node.object), ".}\n")
@@ -329,9 +332,9 @@ function latex(io::IO, index::Documents.IndexNode, page, doc)
329332

330333
_println(io, "\\begin{itemize}")
331334
for (object, _, page, mod, cat) in index.elements
332-
id = string(hash(string(Utilities.slugify(object))))
335+
id = _hash(string(Utilities.slugify(object)))
333336
text = string(object.binding)
334-
_print(io, "\\item \\hyperlink{")
337+
_print(io, "\\item \\hyperlinkref{")
335338
_print(io, id, "}{\\texttt{")
336339
latexesc(io, text)
337340
_println(io, "}}")
@@ -352,7 +355,6 @@ function latex(io::IO, contents::Documents.ContentsNode, page, doc)
352355
# Filter out header levels smaller than the requested mindepth
353356
level = level - contents.mindepth + 1
354357
level < 1 && continue
355-
id = string(hash(string(anchor.id, "-", anchor.nth)))
356358
# If we're changing depth, we need to make sure we always print the
357359
# correct number of \begin{itemize} and \end{itemize} statements.
358360
if level > depth
@@ -370,7 +372,8 @@ function latex(io::IO, contents::Documents.ContentsNode, page, doc)
370372
end
371373
end
372374
# Print the corresponding \item statement
373-
_print(io, "\\item \\hyperlink{", id, "}{")
375+
id = _hash(Anchors.label(anchor))
376+
_print(io, "\\item \\hyperlinkref{", id, "}{")
374377
latexinline(io, header.text)
375378
_println(io, "}")
376379
end
@@ -676,8 +679,8 @@ function latexinline(io::IO, md::Markdown.Link)
676679
else
677680
if occursin(".md#", md.url)
678681
file, target = split(md.url, ".md#"; limit = 2)
679-
id = string(hash(target))
680-
wrapinline(io, "hyperlink") do
682+
id = _hash(target)
683+
wrapinline(io, "hyperlinkref") do
681684
_print(io, id)
682685
end
683686
else

0 commit comments

Comments
 (0)