From cc56dec43fd0def153f0510ac15a2d4068bdb131 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Tue, 14 Apr 2020 13:07:29 +0200 Subject: [PATCH] Omit the number for the first link fragment on a page; Before: #foobar-1, #foobar-2, After: #foobar, #foobar-2. For legacy reasons the old fragments are also insert in order to not break old links spread throughout the internet. --- CHANGELOG.md | 3 +++ src/Anchors.jl | 13 +++++++++++++ src/CrossReferences.jl | 2 +- src/Writers/HTMLWriter.jl | 28 +++++++++++++++------------- src/Writers/MarkdownWriter.jl | 8 ++++++-- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 597bfd0134..7f5d7eeeb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * ![Bugfix][badge-bugfix] `Deps.pip` is again a closure and gets executed during the `deploydocs` call, not before it. ([#1240][github-1240]) +* ![Enhancement][badge-enhancement] The first link fragment on each page now omits the number; before the rendering resulted in: `#foobar-1`, `#foobar-2`, and now: `#foobar`, `#foobar-2`. For backwards compatibility the old fragments are also inserted such that old links will still point to the same location. ([#1292][github-1292]) + ## Version `v0.24.9` * ![Bugfix][badge-bugfix] Canonical URLs are now properly prettified (e.g. `/path/` instead of `/path/index.html`) when using `prettyurls=true`. ([#1293][github-1293]) @@ -544,6 +546,7 @@ [github-1269]: https://github.com/JuliaDocs/Documenter.jl/pull/1269 [github-1279]: https://github.com/JuliaDocs/Documenter.jl/issues/1279 [github-1280]: https://github.com/JuliaDocs/Documenter.jl/pull/1280 +[github-1292]: https://github.com/JuliaDocs/Documenter.jl/pull/1292 [github-1293]: https://github.com/JuliaDocs/Documenter.jl/pull/1293 [documenterlatex]: https://github.com/JuliaDocs/DocumenterLaTeX.jl diff --git a/src/Anchors.jl b/src/Anchors.jl index c1f7115193..f0e9af1b93 100644 --- a/src/Anchors.jl +++ b/src/Anchors.jl @@ -124,4 +124,17 @@ function anchor(m::AnchorMap, id, file, n) nothing end +""" +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 + # TODO: Sanitize the fragment + return frag +end + + end diff --git a/src/CrossReferences.jl b/src/CrossReferences.jl index 451bf14045..3776b59b9a 100644 --- a/src/CrossReferences.jl +++ b/src/CrossReferences.jl @@ -94,7 +94,7 @@ function namedxref(link::Markdown.Link, slug, meta, page, doc) # Replace the `@ref` url with a path to the referenced header. anchor = Anchors.anchor(headers, slug) path = relpath(anchor.file, dirname(page.build)) - link.url = string(path, '#', slug, '-', anchor.nth) + link.url = string(path, Anchors.fragment(anchor)) else push!(doc.internal.errors, :cross_references) @warn "'$slug' is not unique in $(Utilities.locrepr(page.source))." diff --git a/src/Writers/HTMLWriter.jl b/src/Writers/HTMLWriter.jl index 482966ee8f..76a494b016 100644 --- a/src/Writers/HTMLWriter.jl +++ b/src/Writers/HTMLWriter.jl @@ -470,7 +470,7 @@ end struct SearchRecord src :: String page :: Documents.Page - loc :: String + fragment :: String category :: String title :: String page_title :: String @@ -496,7 +496,7 @@ end HTMLContext(doc, settings=HTML()) = HTMLContext(doc, settings, [], "", "", "", [], "", Documents.NavNode("search", "Search", nothing), []) -function SearchRecord(ctx::HTMLContext, navnode; loc="", title=nothing, category="page", text="") +function SearchRecord(ctx::HTMLContext, navnode; fragment="", title=nothing, category="page", text="") page_title = mdflatten(pagetitle(ctx, navnode)) if title === nothing title = page_title @@ -504,7 +504,7 @@ function SearchRecord(ctx::HTMLContext, navnode; loc="", title=nothing, category SearchRecord( pretty_url(ctx, get_url(ctx, navnode.page)), getpage(ctx, navnode), - loc, + fragment, lowercase(category), title, page_title, @@ -515,7 +515,7 @@ end function SearchRecord(ctx::HTMLContext, navnode, node::Markdown.Header) a = getpage(ctx, navnode).mapping[node] SearchRecord(ctx, navnode; - loc="$(a.id)-$(a.nth)", + fragment=Anchors.fragment(a), title=mdflatten(node), category="section") end @@ -527,7 +527,7 @@ end function JSON.lower(rec::SearchRecord) # Replace any backslashes in links, if building the docs on Windows src = replace(rec.src, '\\' => '/') - ref = string(src, '#', rec.loc) + ref = string(src, rec.fragment) Dict{String, String}( "location" => ref, "page" => rec.page_title, @@ -1218,16 +1218,18 @@ end function domify(ctx, navnode, anchor::Anchors.Anchor) @tags a - aid = "$(anchor.id)-$(anchor.nth)" + frag = Anchors.fragment(anchor) + legacy = anchor.nth == 1 ? (a[:id => lstrip(frag, '#')*"-1"],) : () if isa(anchor.object, Markdown.Header) h = anchor.object fixlinks!(ctx, navnode, h) - DOM.Tag(Symbol("h$(Utilities.header_level(h))"))[:id => aid]( - a[".docs-heading-anchor", :href => "#$aid"](mdconvert(h.text, h)), - a[".docs-heading-anchor-permalink", :href => "#$aid", :title => "Permalink"] + DOM.Tag(Symbol("h$(Utilities.header_level(h))"))[:id => lstrip(frag, '#')]( + a[".docs-heading-anchor", :href => frag](mdconvert(h.text, h)), + legacy..., + a[".docs-heading-anchor-permalink", :href => frag, :title => "Permalink"] ) else - a[:id => aid, :href => "#$aid"](domify(ctx, navnode, anchor.object)) + a[:id => frag, :href => frag](legacy..., domify(ctx, navnode, anchor.object)) end end @@ -1264,7 +1266,7 @@ function domify(ctx, navnode, contents::Documents.ContentsNode) path = joinpath(navnode_dir, path) # links in ContentsNodes are relative to current page path = pretty_url(ctx, relhref(navnode_url, get_url(ctx, path))) header = anchor.object - url = string(path, '#', anchor.id, '-', anchor.nth) + url = string(path, Anchors.fragment(anchor)) node = a[:href=>url](mdconvert(header.text; droplinks=true)) level = Utilities.header_level(header) push!(lb, level, node) @@ -1295,7 +1297,7 @@ function domify(ctx, navnode, node::Documents.DocsNode) # push to search index rec = SearchRecord(ctx, navnode; - loc=node.anchor.id, + fragment=Anchors.fragment(node.anchor), title=string(node.object.binding), category=Utilities.doccat(node.object), text = mdflatten(node.docstr)) @@ -1469,7 +1471,7 @@ function collect_subsections(page::Documents.Page) continue end anchor = page.mapping[element] - push!(sections, (toplevel, "#$(anchor.id)-$(anchor.nth)", element.text)) + push!(sections, (toplevel, Anchors.fragment(anchor), element.text)) end end return sections diff --git a/src/Writers/MarkdownWriter.jl b/src/Writers/MarkdownWriter.jl index ddc930cc6f..ed6fa9ac5a 100644 --- a/src/Writers/MarkdownWriter.jl +++ b/src/Writers/MarkdownWriter.jl @@ -61,7 +61,11 @@ function render(io::IO, mime::MIME"text/plain", vec::Vector, page, doc) end function render(io::IO, mime::MIME"text/plain", anchor::Anchors.Anchor, page, doc) - println(io, "\n") + println(io, "\n") + if anchor.nth == 1 # add legacy id + legacy = lstrip(Anchors.fragment(anchor), '#') * "-1" + println(io, "\n") + end render(io, mime, anchor.object, page, doc) end @@ -125,7 +129,7 @@ function render(io::IO, ::MIME"text/plain", contents::Documents.ContentsNode, pa for (count, path, anchor) in contents.elements path = mdext(path) header = anchor.object - url = string(path, '#', anchor.id, '-', anchor.nth) + url = string(path, Anchors.fragment(anchor)) link = MarkdownStdlib.Link(header.text, url) level = Utilities.header_level(header) print(io, " "^(level - 1), "- ")