Skip to content

Commit f43e549

Browse files
committed
Auto merge of rust-lang#137285 - yotamofek:pr/rustdoc/pulldown-escaping, r=GuillaumeGomez
librustdoc: Use `pulldown-cmark-escape` for HTML escaping Implementation of `@notriddle` 's [suggestion](rust-lang#137274 (comment)). Somewhat related to rust-lang#137274 , but the two PRs should be complementary. Local perf results look like a nice improvement! (so would love a perf run on the CI)
2 parents e0be1a0 + 489f5c1 commit f43e549

File tree

3 files changed

+5
-48
lines changed

3 files changed

+5
-48
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4571,6 +4571,7 @@ dependencies = [
45714571
"itertools",
45724572
"minifier",
45734573
"pulldown-cmark 0.9.6",
4574+
"pulldown-cmark-escape",
45744575
"regex",
45754576
"rinja",
45764577
"rustdoc-json-types",

src/librustdoc/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ itertools = "0.12"
1515
indexmap = "2"
1616
minifier = { version = "0.3.5", default-features = false }
1717
pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false }
18+
pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] }
1819
regex = "1"
1920
rustdoc-json-types = { path = "../rustdoc-json-types" }
2021
serde_json = "1.0"

src/librustdoc/html/escape.rs

+3-48
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
use std::fmt;
77

8+
use pulldown_cmark_escape::FmtWriter;
89
use unicode_segmentation::UnicodeSegmentation;
910

1011
/// Wrapper struct which will emit the HTML-escaped version of the contained
@@ -13,31 +14,7 @@ pub(crate) struct Escape<'a>(pub &'a str);
1314

1415
impl fmt::Display for Escape<'_> {
1516
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
16-
// Because the internet is always right, turns out there's not that many
17-
// characters to escape: http://stackoverflow.com/questions/7381974
18-
let Escape(s) = *self;
19-
let pile_o_bits = s;
20-
let mut last = 0;
21-
for (i, ch) in s.char_indices() {
22-
let s = match ch {
23-
'>' => "&gt;",
24-
'<' => "&lt;",
25-
'&' => "&amp;",
26-
'\'' => "&#39;",
27-
'"' => "&quot;",
28-
_ => continue,
29-
};
30-
fmt.write_str(&pile_o_bits[last..i])?;
31-
fmt.write_str(s)?;
32-
// NOTE: we only expect single byte characters here - which is fine as long as we
33-
// only match single byte characters
34-
last = i + 1;
35-
}
36-
37-
if last < s.len() {
38-
fmt.write_str(&pile_o_bits[last..])?;
39-
}
40-
Ok(())
17+
pulldown_cmark_escape::escape_html(FmtWriter(fmt), self.0)
4118
}
4219
}
4320

@@ -51,29 +28,7 @@ pub(crate) struct EscapeBodyText<'a>(pub &'a str);
5128

5229
impl fmt::Display for EscapeBodyText<'_> {
5330
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
54-
// Because the internet is always right, turns out there's not that many
55-
// characters to escape: http://stackoverflow.com/questions/7381974
56-
let EscapeBodyText(s) = *self;
57-
let pile_o_bits = s;
58-
let mut last = 0;
59-
for (i, ch) in s.char_indices() {
60-
let s = match ch {
61-
'>' => "&gt;",
62-
'<' => "&lt;",
63-
'&' => "&amp;",
64-
_ => continue,
65-
};
66-
fmt.write_str(&pile_o_bits[last..i])?;
67-
fmt.write_str(s)?;
68-
// NOTE: we only expect single byte characters here - which is fine as long as we
69-
// only match single byte characters
70-
last = i + 1;
71-
}
72-
73-
if last < s.len() {
74-
fmt.write_str(&pile_o_bits[last..])?;
75-
}
76-
Ok(())
31+
pulldown_cmark_escape::escape_html_body_text(FmtWriter(fmt), self.0)
7732
}
7833
}
7934

0 commit comments

Comments
 (0)