rust icon indicating copy to clipboard operation
rust copied to clipboard

Rustdoc: transpose links-containing-code into code-containing-links

Open dtolnay opened this issue 1 year ago • 1 comments

For example, consider this documentation on i32::unchecked_add: https://doc.rust-lang.org/1.82.0/std/primitive.i32.html#method.unchecked_add

https://github.com/rust-lang/rust/blob/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/num/int_macros.rs#L493-L494

Rustdoc currently produces the following HTML. (I have inserted newlines for readability. These are not present in rustdoc's output.)

<code>x.</code>
<a href="primitive.i32.html#method.checked_add"><code>checked_add</code></a>
<code>(y).</code>
<a href="option/enum.Option.html#method.unwrap_unchecked"><code>unwrap_unchecked</code></a>
<code>()</code>

Because there are 5 individual code blocks, there is weird padding between their otherwise-monospaced text, and inappropriately placed rounded corners.

It would be better to produce, from exactly the above Markdown source code, the following HTML structure instead.

<code>
x.
<a href="primitive.i32.html#method.checked_add">checked_add</a>
(y).
<a href="option/enum.Option.html#method.unwrap_unchecked">unwrap_unchecked</a>
()
</code>

It is sometimes possible to achieve this output today by manually writing <code> and <a>:

/// <code>x.<a href="...">checked_add</a>(y).<a href="...">unwrap_unchecked</a>()</code>

But the reason I say "sometimes" and the reason I have tagged https://github.com/rust-lang/rust/labels/A-intra-doc-links is that this workaround does not work if our links need to be intra-doc links. Rustdoc's intra-doc linking only kicks in for Markdown links ([`Option::unwrap_unchecked`]) and not for HTML links (<a href="Option::unwrap_unchecked"></a>). Whether or not that changes in the future as a separate issue, I still think the suggestion in this issue will remain valuable because writing inline code and links in Markdown syntax is always going to be more convenient than falling back to HTML syntax.

dtolnay avatar Oct 17 '24 17:10 dtolnay

It is sometimes possible to achieve this output today by manually writing <code> and <a>:

/// <code>x.<a href="...">checked_add</a>(y).<a href="...">unwrap_unchecked</a>()</code>

But the reason I say "sometimes" and the reason I have tagged A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name is that this workaround does not work if our links need to be intra-doc links. Rustdoc's intra-doc linking only kicks in for Markdown links ([`Option::unwrap_unchecked`]) and not for HTML links (<a href="Option::unwrap_unchecked"></a>).

It is possible to archieve this output today by putting markdown links inside a <code> tag:

/// <code>x.[checked_add]\(y).[unwrap_unchecked]\()</code>

This is used in the docs for Box::pin for example.

bluurryy avatar Oct 18 '24 03:10 bluurryy

Whoa! That's great, thank you! I did not think to try that because Markdown syntax does not consistently work in other HTML elements. For example:

<table><tr><td>**strong**</td><td>_emph_</td><td>[link](#)</td></tr></table>
**strong**_emph_[link](#)

But from looking further into this, it's a distinction between block-level vs span-level HTML tags. <code> is span-level so nested Markdown works.

https://daringfireball.net/projects/markdown/syntax#html:

Note that Markdown formatting syntax is not processed within block-level HTML tags. E.g., you can’t use Markdown-style *emphasis* inside an HTML block.

Unlike block-level HTML tags, Markdown syntax is processed within span-level tags.

dtolnay avatar Oct 18 '24 14:10 dtolnay