Skip to content

Added anchor links to admonition blocks for direct referencing #2676

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

Merged
merged 7 commits into from
Apr 16, 2025

Conversation

Rahban1
Copy link
Contributor

@Rahban1 Rahban1 commented Apr 6, 2025

Close #2505

I have added a new field to HTMLContext admonition_counters which stores counters for each admonition so each one gets a unique identifier. The main challenge was generating unique id for each admonition which is the meat of the pr, added some css for hover functionality of link

Before :
Screenshot 2025-04-07 at 2 22 43 AM

After :
Screenshot 2025-04-07 at 2 23 25 AM

works well when tested locally

@fingolfin
Copy link
Collaborator

Won't this be rather brittle, though? I.e. if another admonition is inserted or removed before the linked on, it will silently break the link (or rather the link will end up pointing to something different than intended).

@fingolfin
Copy link
Collaborator

Though of course that's fine for "throw away linking ", eg when sending someone in Slack a link so they find something more quickly.

But for stable links eg between one part of a manual to another it'd be better if there was a way to specify an anchor name.

@fingolfin
Copy link
Collaborator

All that said, I don't really mean to be a buzzkill, sorry for that, and thank you for working on this!

@Rahban1
Copy link
Contributor Author

Rahban1 commented Apr 6, 2025

you're right. now I think of it I think we can add syntax for manually assigning IDs to admonitions that need to be referenced like we are doing with headers like [Header] (#id) . do you think that's a good idea?

@Rahban1
Copy link
Contributor Author

Rahban1 commented Apr 6, 2025

All that said, I don't really mean to be a buzzkill, sorry for that, and thank you for working on this!

absolutely not, I agree with your point of this approach being brittle, thank you for pointing that out!

@mortenpi
Copy link
Member

mortenpi commented Apr 8, 2025

One super-minor style nitpick: I think it would be nice if the link icon was the same size as the existing heading icons:

image

I think we can add syntax for manually assigning IDs to admonitions that need to be referenced

It's a bit tricky with admonitions actually -- syntax-wise, there is no way to add "silent" metadata (like you can with the @id links). Whatever syntax we'd add would show up in the REPL etc.

We already create the slug based on the admonition title, if present. So if the user gives their admonitions titles, then we're less likely to run into this issue (although I guess admonition titles could also be repetitive in some cases). And OTOH, we have similar brittleness issues with headings and docstrings.

I guess one option would be to create the (fallback) slug based on a hash of the content of the admonition block. That should ensure that it would only change if the content changes, and ensure that you don't get linked to the wrong admonition.

But I'd also be fine with this as is to be honest, as it's already an improvement.

@Rahban1
Copy link
Contributor Author

Rahban1 commented Apr 8, 2025

I was thinking of something like this :
Screenshot 2025-04-09 at 1 51 59 AM

thoughts?

@Rahban1
Copy link
Contributor Author

Rahban1 commented Apr 8, 2025

I have fixed the link size, if you think this is good enough that is also fine with me :)

@mortenpi mortenpi added Type: Enhancement Format: HTML Related to the default HTML output labels Apr 9, 2025
@mortenpi
Copy link
Member

mortenpi commented Apr 9, 2025

@Rahban1 Yea, that hashing seems fine! If I am not mistaken, it will hash the MarkdownAST's @ast MarkdownAST.Document() do ...-style, right (https://markdownast.juliadocs.org/stable/astmacro/#MarkdownAST.@ast)? I think that's quite fine though -- it should be a pretty stable representation of the Markdown.

@Rahban1
Copy link
Contributor Author

Rahban1 commented Apr 9, 2025

Yes @mortenpi you're right, it converts MarkdownAST node into a string representation and then hash it and uses the first 8 characters. I will implement it tomorrow since I am traveling today :)

@Rahban1
Copy link
Contributor Author

Rahban1 commented Apr 10, 2025

works fine for me locally.

@mortenpi
Copy link
Member

Sorry for the delay, but LGTM! Thank you @Rahban1!

@mortenpi mortenpi merged commit 03b09f8 into JuliaDocs:master Apr 16, 2025
24 checks passed
@Rahban1
Copy link
Contributor Author

Rahban1 commented Apr 16, 2025

Thank you 😁

@@ -2393,16 +2393,24 @@ function domify(dctx::DCtx, node::Node, a::MarkdownAST.Admonition)
# apply a class
isempty(cat_sanitized) ? "" : ".is-category-$(cat_sanitized)"
end

node_repr = sprint(io -> show(io, node))
content_hash = bytes2hex(SHA.sha1(node_repr))[1:8]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this has introduced a severe performance regressions. For the Oscar.jl package, building its manual went from ~40 seconds to ~680 seconds on my machine. It spends all that time computing SHA1 checksums it then doesn't need...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rats. Do you have any sense of whether it's the SHA calculation that's slow, or the rendering of the block (i.e. the sprint line)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've interrupted this via ctrl-c a few (~5?) times and each time it was in the middle of a SHA computation. Not a proof yet but quite suggestive

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need crypto safety here. Perhaps a weaker but faster hash suffices. Maybe even CRC32?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, that's interesting. When working on this issue, I was testing this locally and I had realized a slight delay in build time like 5-10% increase so I thought it wouldn't be a big deal (maybe because Julia docs doesn't use admonitions that much) but I didn't realize this would have such a exponential effect on other docs. Apologies!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't Base.hash of the string sufficient?

@Rahban1 Rahban1 restored the anchors-for-admonitions branch April 25, 2025 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Format: HTML Related to the default HTML output Type: Enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Anchors for admonitions
4 participants