Skip to content

Commit

Permalink
fix broken PDF links
Browse files Browse the repository at this point in the history
Co-authored-by: Morten Piibeleht <[email protected]>
  • Loading branch information
matthias314 and mortenpi committed Aug 24, 2022
1 parent 9b5105b commit cc25856
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* ![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])
* ![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])
* ![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])
* ![Bugfix][badge-bugfix] Previously broken links within the PDF output are now fixed. ([JuliaLang/julia#38054][julia-38054] and second part of [JuliaLang/julia#43652][julia-43652])

## Version `v0.27.23`

Expand Down
6 changes: 6 additions & 0 deletions assets/latex/documenter.sty
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,9 @@
\usepackage{graphicx}
\usepackage[export]{adjustbox}
%

% Some internal link targets are implemented with \label, some with \hypertarget,
% but they require different links. This inserts a \hyperref if a corresponding label exists,
% and \hyperlink if it doesn't.
\def\hyperlinkref#1#2{\@ifundefined{r@#1}{\hyperlink{#1}{#2}}{\hyperref[#1]{#2}}}
%
10 changes: 6 additions & 4 deletions src/Anchors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,16 @@ function anchor(m::AnchorMap, id, file, n)
nothing
end

"""
Create a label from an anchor.
"""
label(a::Anchor) = (a.nth == 1) ? a.id : string(a.id, "-", a.nth)

"""
Create an HTML fragment from an anchor.
"""
function fragment(a::Anchor)
frag = string("#", a.id)
if a.nth > 1
frag = string(frag, "-", a.nth)
end
frag = string("#", label(a))
# TODO: Sanitize the fragment
return frag
end
Expand Down
25 changes: 14 additions & 11 deletions src/Writers/LaTeXWriter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ Context(io) = Context{typeof(io)}(io, false, Dict(), 1, "")
_print(c::Context, args...) = Base.print(c.io, args...)
_println(c::Context, args...) = Base.println(c.io, args...)

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


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

function latex(io::IO, anchor::Anchors.Anchor, page, doc)
id = string(hash(string(anchor.id, "-", anchor.nth)))
_println(io, "\n\\hypertarget{", id, "}{}\n")
id = _hash(Anchors.label(anchor))
latex(io, anchor.object, page, doc)
_println(io, "\n\\label{", id, "}{}\n")
end


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

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

_println(io, "\\begin{itemize}")
for (object, _, page, mod, cat) in index.elements
id = string(hash(string(Utilities.slugify(object))))
id = _hash(string(Utilities.slugify(object)))
text = string(object.binding)
_print(io, "\\item \\hyperlink{")
_print(io, "\\item \\hyperlinkref{")
_print(io, id, "}{\\texttt{")
latexesc(io, text)
_println(io, "}}")
Expand All @@ -352,7 +355,6 @@ function latex(io::IO, contents::Documents.ContentsNode, page, doc)
# Filter out header levels smaller than the requested mindepth
level = level - contents.mindepth + 1
level < 1 && continue
id = string(hash(string(anchor.id, "-", anchor.nth)))
# If we're changing depth, we need to make sure we always print the
# correct number of \begin{itemize} and \end{itemize} statements.
if level > depth
Expand All @@ -370,7 +372,8 @@ function latex(io::IO, contents::Documents.ContentsNode, page, doc)
end
end
# Print the corresponding \item statement
_print(io, "\\item \\hyperlink{", id, "}{")
id = _hash(Anchors.label(anchor))
_print(io, "\\item \\hyperlinkref{", id, "}{")
latexinline(io, header.text)
_println(io, "}")
end
Expand Down Expand Up @@ -676,8 +679,8 @@ function latexinline(io::IO, md::Markdown.Link)
else
if occursin(".md#", md.url)
file, target = split(md.url, ".md#"; limit = 2)
id = string(hash(target))
wrapinline(io, "hyperlink") do
id = _hash(target)
wrapinline(io, "hyperlinkref") do
_print(io, id)
end
else
Expand Down

0 comments on commit cc25856

Please sign in to comment.