Skip to content

rustdoc: Allow multiple references to a single footnote #140434

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

a4lg
Copy link
Contributor

@a4lg a4lg commented Apr 29, 2025

Multiple references to a single footnote is a part of GitHub Flavored Markdown syntax (although not explicitly documented as well as regular footnotes, it is implemented in GitHub's fork of CommonMark) and not prohibited by rustdoc.

cf. https://github.com/github/cmark-gfm/blob/587a12bb54d95ac37241377e6ddc93ea0e45439b/test/extensions.txt#L762-L780

However, using it causes multiple sup elements with the same id attribute, which is invalid per the HTML specification.

Still, not only this is a valid GitHub Flavored Markdown syntax, this is helpful on certain cases and actually tested (accidentally) in tests/rustdoc/footnote-reference-in-footnote-def.rs.

This commit keeps track of the number of references per footnote and gives unique ID to each reference.
It also emits all back links from a footnote to its references as "↩" (return symbol) plus a numeric list in superscript.

As a known limitation, it assumes that all references to a footnote are rendered (this is not always true if a dangling footnote has one or more references but considered a reasonable compromise).

Also note that, this commit is designed so that no HTML changes will occur unless multiple references to a single footnote is actually used.

Background

A failure is detected on the CI process of #140389, which adopted stdarch submodule with PR rust-lang/stdarch#1779.

As you see in the screenshot of that stdarch PR, it uses multiple references to a single footnote to simplify showing various platform/version-specific notes (this is far more important than x86 because there are no architectural, fine-grained feature detection methods on RISC-V and hence feature detection is highly platform/version-specific).

And I thought this kind of references are allowed because:

  1. rustdoc does not reject such links and
  2. One of the tests tests/rustdoc/footnote-reference-in-footnote-def.rs contains multiple references to a single footnote [^a].

...until I encounter a linkchecker failure (ran on CI).

Proposal

Of course, rejecting such references might be an option but this PR attempts to resolve the issue by explicitly allowing multiple references to a single footnote by:

  1. Generating unique id attribute per a reference to a footnote and
  2. Emitting all back links from a footnote as a return symbol plus a numeric list in superscript.

Note that, this PR is designed so that no HTML changes will occur unless multiple references to a single footnote is actually used.

Known Limitation

To simplify the implementation, it just keeps track of the number of references per footnote and assumes that all references to footnotes are rendered. This is usually true but may not be always true if a reference is inside a footnote and that footnote is dangling (in this case, broken links (that won't cause any action when clicked/touched) will be generated but otherwise fine).

I also didn't use atomics but was it necessary?

Screenshot

This is a screenshot of this PR plus rust-lang/stdarch#1779, showing how back links are rendered.
You can see the differences in the footnotes 1, 2 and 5.

Screenshot of stdarch PR 1779 with this PR (footnote part)

Design Considerations / Options

I just used 1-origin numbers for back links from a footnote but if this is confusing, using alphabet-based list "a", "b"..."z", "aa", "ab"... might be an option like in Wikipedia. The reason I didn't do this (in the first proposal) is because back links are visually distinct than Wikipedia and seems easy to make distinction between regular references to footnotes due to the return symbol "↩" (Wikipedia: caret "^" is used).

History

Version 1 (2025-04-29)

The initial proposal.

Version 2 and 3 (2025-04-30)

Excluding the rebase, they only change the commit message (mainly grammar fixes)
and the code is unchanged from the version 1.

Version 4 (2025-05-06)

No changes in the source code.

  • Commit Message: Added minor adjustments
  • Commit Message: Added references to GitHub Flavored Markdown syntax and GitHub's fork of CommonMark
  • Commit Message: Clarified that multiple references in tests/rustdoc/footnote-reference-in-footnote-def.rs are (most likely) not to test such references themselves.

@rustbot
Copy link
Collaborator

rustbot commented Apr 29, 2025

r? @notriddle

rustbot has assigned @notriddle.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Apr 29, 2025
@notriddle notriddle removed the T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. label Apr 29, 2025
@notriddle
Copy link
Contributor

I'm satisfied with the known limitation on nested, hidden footnotes.

Since this is a UI-visible change, I'll cc the frontend team about it.

@rfcbot poll appearance

@rfcbot
Copy link
Collaborator

rfcbot commented Apr 29, 2025

Team member @notriddle has asked teams: T-rustdoc-frontend, for consensus on:

appearance

@GuillaumeGomez
Copy link
Member

It's really cool, nicely done!

@a4lg
Copy link
Contributor Author

a4lg commented May 2, 2025

With all due respect, if time constraints allow, I would greatly appreciate it if this PR could be merged within the version 1.88 cycle (before beta branching occurs). That would allow re-applying platform-specific guide documentation (RISC-V) on stdarch in the version 1.89 cycle.
Thank you for your consideration.

@a4lg
Copy link
Contributor Author

a4lg commented May 5, 2025

The syntax of using multiple references to a single footnote is compatible to GitHub Flavored Markdown
but with a slight design differences in both:

  • Footnote reference
    • GitHub: brackets are used like [1]
    • rustdoc (current implementation): raw number is used like 1) and
  • Back link list
    • GitHub: every back links have the "return" symbol
    • rustdoc (this PR): only the first back link has the "return" symbol).

For instance, GitHub Flavored Markdown source code:

This is an example [^a] of multiple references [^a] to a single footnote [^a].

[^a]: This is the footnote.

is rendered as below:

This is an example 1 of multiple references 1 to a single footnote 1.

Footnotes

  1. This is the footnote. 2 3

Multiple references to a single footnote is a part of GitHub Flavored
Markdown syntax (although not explicitly documented as well as regular
footnotes, it is implemented in GitHub's fork of CommonMark) and not
prohibited by rustdoc.

cf. <https://github.com/github/cmark-gfm/blob/587a12bb54d95ac37241377e6ddc93ea0e45439b/test/extensions.txt#L762-L780>

However, using it causes multiple "sup" elements with the same "id"
attribute, which is invalid per the HTML specification.

Still, not only this is a valid GitHub Flavored Markdown syntax, this is
helpful on certain cases and actually tested (accidentally) in
tests/rustdoc/footnote-reference-in-footnote-def.rs.

This commit keeps track of the number of references per footnote and gives
unique ID to each reference.  It also emits *all* back links from a footnote
to its references as "↩" (return symbol) plus a numeric list in superscript.

As a known limitation, it assumes that all references to a footnote are
rendered (this is not always true if a dangling footnote has one or more
references but considered a reasonable compromise).

Also note that, this commit is designed so that no HTML changes will occur
unless multiple references to a single footnote is actually used.
@a4lg a4lg force-pushed the rustdoc-multi-footnote-refs branch from 8e5cc42 to ed3dba9 Compare May 6, 2025 05:07
@a4lg
Copy link
Contributor Author

a4lg commented May 6, 2025

If we apply GitHub's design in back links, it will look like this:

image

Please compare this to the screenshot in the root comment; footnote 2 has 11 references instead of 12 but this is caused by an independent fix in my stdarch proposal):

In my opinion, it looks a bit cluttered.

For rustdoc source code which generated the image just above, see my experimental branch.

@notriddle
Copy link
Contributor

I think it’s not a good idea to worry about how bad it looks when there are nine references to one footnote. Even if it looked better, the user still needs to pick one, and it’s not clear how to tell which one you want. So, if you have eight refs, you have bigger problems than appearance.

On the other hand, the GFM approach makes the link bigger, so it’s easier to click or tap.

@a4lg
Copy link
Contributor Author

a4lg commented May 6, 2025

Yeah, I agree that.

To be fair, I just implemented to test almost-GitHub-compatible design as an experiment and on rustdoc, it's (currently) nearly pointless to evaluate the design of back links (unless it's really bad) because there's no visual cue to tell which footnote reference link the user previously tapped (corresponding to the back link which performs an actual "back to contents" action; surprisingly, it also applies to the GFM implementation).

Unless we have a strong reason to choose different one, I prefer the design in the initial proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants