Skip to content
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

rustdoc: implement unprefixed html class / id lint #106603

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions src/doc/rustdoc/src/how-to-write-documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,131 @@ characters:

So, no need to manually enter those Unicode characters!

### Inline HTML

As a standard Commonmark parser with no special restrictions, rustdoc allows
you to write HTML whenever the regular markup isn't sufficient, such as
advanced table layouts:

```html
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Category</th>
</tr>
</thead>
<tbody>
<tr>
<td>traits</td>
<td>static and dynamic dispatch</td>
<td>generics</td>
</tr>
<tr>
<td colspan="3">enums</td>
</tr>
<tr>
<td rowspan="2">doc comments</td>
<td colspan="2">reference documentation</td>
</tr>
<tr>
<td>markdown comments</td>
<td>attributes with custom syntax</td>
</tr>
</tbody>
</table>
```

This will render the same way Markdown tables do, even though Markdown tables
don't support `colspan`:

<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Category</th>
</tr>
</thead>
<tbody>
<tr>
<td>traits</td>
<td>static and dynamic dispatch</td>
<td>generics</td>
</tr>
<tr>
<td colspan="3">enums</td>
</tr>
<tr>
<td rowspan="2">doc comments</td>
<td colspan="2">reference documentation</td>
</tr>
<tr>
<td>markdown comments</td>
<td>attributes with custom syntax</td>
</tr>
</tbody>
</table>

HTML is not sanitized when included in the documentation, though
improperly-nested tags will produce a build-time warning.

```text
warning: unclosed HTML tag `h2`
--> $DIR/invalid-html-tags.rs:19:7
|
LL | /// <h2>
| ^^^^

warning: unclosed quoted HTML attribute on tag `p`
--> $DIR/invalid-html-self-closing-tag.rs:19:14
|
LL | /// <p style="x/></p>
| ^
```

Additionally, IDs and classes should be prefixed with your crate's name,
followed by an underscore `_`. Since rustdoc sometimes includes excerpts
of the documentation of your dependencies in your crate's documentation,
this ensures you don't conflict with them.

```text
warning: unprefixed HTML `class` attribute
--> $DIR/unprefixed-html-class.rs:4:27
|
LL | /// Test with <div class="evil"></div>
| -^^^
| |
| help: add prefix: `unprefixed_html_class_`
|
= help: classes should start with `{cratename}_`, or be: `stab`, `stab deprecated`, or `stab portability`

warning: unprefixed HTML `id` attribute
--> $DIR/unprefixed-html-id.rs:4:24
|
LL | /// Test with <div id="evil"></div>
| -^^^
| |
| help: add prefix: `unprefixed_html_id_`
|

warning: 2 warnings emitted
```

We recommend the following additional restrictions:

* Start all doc comments with a one-sentence summary that doesn't use
inline HTML. This summary will be used in contexts where arbitrary HTML
cannot, such as tooltips.
* Though JavaScript is allowed, many viewers won't run it. Ensure your docs
are readable without JavaScript.
* Do not embed CSS or JavaScript in doc comments to customize rustdoc's
UI. If you want to publish documentation with a customized UI, invoke
rustdoc with the `--html-in-header` [command-line parameter] to generate it
with your custom stylesheet or script, then publish the result as
pre-built HTML.
Comment on lines +376 to +380
Copy link
Member

Choose a reason for hiding this comment

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

Do we have plans to enforce that at some point? It would be helpful for rust-lang/docs.rs#167, I think.

cc @rust-lang/docs-rs

Copy link
Contributor Author

@notriddle notriddle Jan 10, 2023

Choose a reason for hiding this comment

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

This bullet point was really only intended to address scripts and styles that actually modified rustdoc's UI. A one-off script that only modifies things in your own doc probably should be part of the doc comment so that it gets inline along with its DOM.

The thing that actually makes solid recommendations tough is code like KaTeX. It doesn't modify rustdoc's UI (so it can probably be safely inlined across crates), but it also isn't a one-off (so it probably shouldn't be included in the doc comment).

CC: https://internals.rust-lang.org/t/proposed-lint-rustdoc-unprefixed-html-id/18099/15?u=notriddle


[`backtrace`]: https://docs.rs/backtrace/0.3.50/backtrace/
[commonmark markdown specification]: https://commonmark.org/
[commonmark quick reference]: https://commonmark.org/help/
Expand All @@ -268,3 +393,4 @@ So, no need to manually enter those Unicode characters!
[strikethrough]: https://github.github.com/gfm/#strikethrough-extension-
[tables]: https://github.github.com/gfm/#tables-extension-
[task list extension]: https://github.github.com/gfm/#task-list-items-extension-
[command-line parameter]: command-line-arguments.md#--html-in-header-include-more-html-in
22 changes: 22 additions & 0 deletions src/librustdoc/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,26 @@ declare_rustdoc_lint! {
"detects invalid HTML tags in doc comments"
}

declare_rustdoc_lint! {
/// The `unprefixed_html_id` lint detects potential HTML ID conflicts. This is a
/// `rustdoc` only lint, see the documentation in the [rustdoc book].
///
/// [rustdoc book]: ../../../rustdoc/lints.html#unprefixed_html_ids
UNPREFIXED_HTML_ID,
Warn,
"detects HTML id attributes that do not start with the crate name"
}

declare_rustdoc_lint! {
/// The `unprefixed_html_class` lint detects potential HTML class conflicts. This is a
/// `rustdoc` only lint, see the documentation in the [rustdoc book].
///
/// [rustdoc book]: ../../../rustdoc/lints.html#unprefixed_html_ids
UNPREFIXED_HTML_CLASS,
Warn,
"detects HTML class attributes that do not start with the crate name"
}

declare_rustdoc_lint! {
/// The `bare_urls` lint detects when a URL is not a hyperlink.
/// This is a `rustdoc` only lint, see the documentation in the [rustdoc book].
Expand Down Expand Up @@ -185,6 +205,8 @@ pub(crate) static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
INVALID_HTML_TAGS,
BARE_URLS,
MISSING_CRATE_LEVEL_DOCS,
UNPREFIXED_HTML_ID,
UNPREFIXED_HTML_CLASS,
]
});

Expand Down
Loading