Skip to content

Commit 286a51d

Browse files
Fix id generation
1 parent 47e4abf commit 286a51d

File tree

2 files changed

+56
-51
lines changed

2 files changed

+56
-51
lines changed

src/Cargo.lock

+5-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustdoc/html/markdown.rs

+51-47
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,20 @@ thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> =
105105
});
106106

107107
macro_rules! event_loop_break {
108-
($parser:expr, $toc_builder:expr, $shorter:expr, $buf:expr, $($end_event:pat)|*) => {{
109-
event_loop_break($parser, $toc_builder, $shorter, $buf, false, $($end_event:pat)|*);
110-
}};
111-
($parser:expr, $toc_builder:expr, $shorter:expr, $buf:expr, $escape:expr,
108+
($parser:expr, $toc_builder:expr, $shorter:expr, $buf:expr, $escape:expr, $id:expr,
112109
$($end_event:pat)|*) => {{
110+
fn inner(id: &mut Option<&mut String>, s: &str) {
111+
if let Some(ref mut id) = *id {
112+
id.push_str(s);
113+
}
114+
}
113115
while let Some(event) = $parser.next() {
114116
match event {
115117
$($end_event)|* => break,
116118
Event::Text(ref s) => {
119+
inner($id, s);
117120
if $escape {
118-
$buf.push_str(&escape(s));
121+
$buf.push_str(&format!("{}", Escape(s)));
119122
} else {
120123
$buf.push_str(s);
121124
}
@@ -124,7 +127,7 @@ macro_rules! event_loop_break {
124127
$buf.push(' ');
125128
}
126129
x => {
127-
looper($parser, &mut $buf, Some(x), $toc_builder, $shorter);
130+
looper($parser, &mut $buf, Some(x), $toc_builder, $shorter, $id);
128131
}
129132
}
130133
}
@@ -135,13 +138,6 @@ pub fn render(w: &mut fmt::Formatter,
135138
s: &str,
136139
print_toc: bool,
137140
shorter: MarkdownOutputStyle) -> fmt::Result {
138-
fn escape(entry: &str) -> String {
139-
entry.replace("<", "&lt;")
140-
.replace("'", "&#39;")
141-
.replace(">", "&gt;")
142-
.replace("&", "&amp;")
143-
}
144-
145141
fn block(parser: &mut Parser, buffer: &mut String, lang: &str) {
146142
let mut origtext = String::new();
147143
while let Some(event) = parser.next() {
@@ -223,10 +219,11 @@ pub fn render(w: &mut fmt::Formatter,
223219
fn header(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
224220
shorter: MarkdownOutputStyle, level: i32) {
225221
let mut ret = String::new();
226-
event_loop_break!(parser, toc_builder, shorter, ret, true, Event::End(Tag::Header(_)));
222+
let mut id = String::new();
223+
event_loop_break!(parser, toc_builder, shorter, ret, true, &mut Some(&mut id),
224+
Event::End(Tag::Header(_)));
227225
ret = ret.trim_right().to_owned();
228226

229-
let id = ret.clone();
230227
let id = id.chars().filter_map(|c| {
231228
if c.is_alphanumeric() || c == '-' || c == '_' {
232229
if c.is_ascii() {
@@ -254,30 +251,33 @@ pub fn render(w: &mut fmt::Formatter,
254251
}
255252

256253
fn codespan(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
257-
shorter: MarkdownOutputStyle) {
254+
shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
258255
let mut content = String::new();
259-
event_loop_break!(parser, toc_builder, shorter, content, true, Event::End(Tag::Code));
256+
event_loop_break!(parser, toc_builder, shorter, content, false, id, Event::End(Tag::Code));
260257
buffer.push_str(&format!("<code>{}</code>",
261258
Escape(&collapse_whitespace(content.trim_right()))));
262259
}
263260

264261
fn link(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
265-
shorter: MarkdownOutputStyle, url: &str, mut title: String) {
266-
event_loop_break!(parser, toc_builder, shorter, title, true, Event::End(Tag::Link(_, _)));
262+
shorter: MarkdownOutputStyle, url: &str, mut title: String,
263+
id: &mut Option<&mut String>) {
264+
event_loop_break!(parser, toc_builder, shorter, title, true, id,
265+
Event::End(Tag::Link(_, _)));
267266
buffer.push_str(&format!("<a href=\"{}\">{}</a>", url, title));
268267
}
269268

270269
fn paragraph(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
271-
shorter: MarkdownOutputStyle) {
270+
shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
272271
let mut content = String::new();
273-
event_loop_break!(parser, toc_builder, shorter, content, true, Event::End(Tag::Paragraph));
272+
event_loop_break!(parser, toc_builder, shorter, content, true, id,
273+
Event::End(Tag::Paragraph));
274274
buffer.push_str(&format!("<p>{}</p>", content.trim_right()));
275275
}
276276

277277
fn cell(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
278278
shorter: MarkdownOutputStyle) {
279279
let mut content = String::new();
280-
event_loop_break!(parser, toc_builder, shorter, content, true,
280+
event_loop_break!(parser, toc_builder, shorter, content, true, &mut None,
281281
Event::End(Tag::TableHead) |
282282
Event::End(Tag::Table(_)) |
283283
Event::End(Tag::TableRow) |
@@ -297,7 +297,7 @@ pub fn render(w: &mut fmt::Formatter,
297297
cell(parser, &mut content, toc_builder, shorter);
298298
}
299299
x => {
300-
looper(parser, &mut content, Some(x), toc_builder, shorter);
300+
looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
301301
}
302302
}
303303
}
@@ -314,7 +314,7 @@ pub fn render(w: &mut fmt::Formatter,
314314
cell(parser, &mut content, toc_builder, shorter);
315315
}
316316
x => {
317-
looper(parser, &mut content, Some(x), toc_builder, shorter);
317+
looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
318318
}
319319
}
320320
}
@@ -351,7 +351,8 @@ pub fn render(w: &mut fmt::Formatter,
351351
fn blockquote(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
352352
shorter: MarkdownOutputStyle) {
353353
let mut content = String::new();
354-
event_loop_break!(parser, toc_builder, shorter, content, true, Event::End(Tag::BlockQuote));
354+
event_loop_break!(parser, toc_builder, shorter, content, true, &mut None,
355+
Event::End(Tag::BlockQuote));
355356
buffer.push_str(&format!("<blockquote>{}</blockquote>", content.trim_right()));
356357
}
357358

@@ -362,10 +363,10 @@ pub fn render(w: &mut fmt::Formatter,
362363
match event {
363364
Event::End(Tag::Item) => break,
364365
Event::Text(ref s) => {
365-
content.push_str(&escape(s));
366+
content.push_str(&format!("{}", Escape(s)));
366367
}
367368
x => {
368-
looper(parser, &mut content, Some(x), toc_builder, shorter);
369+
looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
369370
}
370371
}
371372
}
@@ -382,29 +383,32 @@ pub fn render(w: &mut fmt::Formatter,
382383
list_item(parser, &mut content, toc_builder, shorter);
383384
}
384385
x => {
385-
looper(parser, &mut content, Some(x), toc_builder, shorter);
386+
looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
386387
}
387388
}
388389
}
389390
buffer.push_str(&format!("<ul>{}</ul>", content));
390391
}
391392

392393
fn emphasis(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
393-
shorter: MarkdownOutputStyle) {
394+
shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
394395
let mut content = String::new();
395-
event_loop_break!(parser, toc_builder, shorter, content, true, Event::End(Tag::Emphasis));
396+
event_loop_break!(parser, toc_builder, shorter, content, false, id,
397+
Event::End(Tag::Emphasis));
396398
buffer.push_str(&format!("<em>{}</em>", content));
397399
}
398400

399401
fn strong(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
400-
shorter: MarkdownOutputStyle) {
402+
shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
401403
let mut content = String::new();
402-
event_loop_break!(parser, toc_builder, shorter, content, true, Event::End(Tag::Strong));
404+
event_loop_break!(parser, toc_builder, shorter, content, false, id,
405+
Event::End(Tag::Strong));
403406
buffer.push_str(&format!("<strong>{}</strong>", content));
404407
}
405408

406409
fn looper<'a>(parser: &'a mut Parser, buffer: &mut String, next_event: Option<Event<'a>>,
407-
toc_builder: &mut Option<TocBuilder>, shorter: MarkdownOutputStyle) -> bool {
410+
toc_builder: &mut Option<TocBuilder>, shorter: MarkdownOutputStyle,
411+
id: &mut Option<&mut String>) -> bool {
408412
if let Some(event) = next_event {
409413
match event {
410414
Event::Start(Tag::CodeBlock(lang)) => {
@@ -414,13 +418,13 @@ pub fn render(w: &mut fmt::Formatter,
414418
header(parser, buffer, toc_builder, shorter, level);
415419
}
416420
Event::Start(Tag::Code) => {
417-
codespan(parser, buffer, toc_builder, shorter);
421+
codespan(parser, buffer, toc_builder, shorter, id);
418422
}
419423
Event::Start(Tag::Paragraph) => {
420-
paragraph(parser, buffer, toc_builder, shorter);
424+
paragraph(parser, buffer, toc_builder, shorter, id);
421425
}
422426
Event::Start(Tag::Link(ref url, ref t)) => {
423-
link(parser, buffer, toc_builder, shorter, url, t.as_ref().to_owned());
427+
link(parser, buffer, toc_builder, shorter, url, t.as_ref().to_owned(), id);
424428
}
425429
Event::Start(Tag::Table(_)) => {
426430
table(parser, buffer, toc_builder, shorter);
@@ -432,10 +436,10 @@ pub fn render(w: &mut fmt::Formatter,
432436
list(parser, buffer, toc_builder, shorter);
433437
}
434438
Event::Start(Tag::Emphasis) => {
435-
emphasis(parser, buffer, toc_builder, shorter);
439+
emphasis(parser, buffer, toc_builder, shorter, id);
436440
}
437441
Event::Start(Tag::Strong) => {
438-
strong(parser, buffer, toc_builder, shorter);
442+
strong(parser, buffer, toc_builder, shorter, id);
439443
}
440444
Event::Html(h) | Event::InlineHtml(h) => {
441445
buffer.push_str(&*h);
@@ -457,7 +461,7 @@ pub fn render(w: &mut fmt::Formatter,
457461
let mut parser = Parser::new_ext(s, pulldown_cmark::OPTION_ENABLE_TABLES);
458462
loop {
459463
let next_event = parser.next();
460-
if !looper(&mut parser, &mut buffer, next_event, &mut toc_builder, shorter) {
464+
if !looper(&mut parser, &mut buffer, next_event, &mut toc_builder, shorter, &mut None) {
461465
break
462466
}
463467
}
@@ -742,7 +746,7 @@ mod tests {
742746
fn test_header() {
743747
fn t(input: &str, expect: &str) {
744748
let output = format!("{}", Markdown(input, MarkdownOutputStyle::Fancy));
745-
assert_eq!(output, expect);
749+
assert_eq!(output, expect, "original: {}", input);
746750
reset_ids(true);
747751
}
748752

@@ -751,10 +755,10 @@ mod tests {
751755
t("## Foo-bar_baz qux", "<h2 id=\"foo-bar_baz-qux\" class=\"section-\
752756
header\"><a href=\"#foo-bar_baz-qux\">Foo-bar_baz qux</a></h2>");
753757
t("### **Foo** *bar* baz!?!& -_qux_-%",
754-
"<h3 id=\"foo-bar-baz--_qux_-\" class=\"section-header\">\
755-
<a href=\"#foo-bar-baz--_qux_-\"><strong>Foo</strong> \
756-
<em>bar</em> baz!?!&amp; -_qux_-%</a></h3>");
757-
t("####**Foo?** & \\*bar?!* _`baz`_ ❤ #qux",
758+
"<h3 id=\"foo-bar-baz--qux-\" class=\"section-header\">\
759+
<a href=\"#foo-bar-baz--qux-\"><strong>Foo</strong> \
760+
<em>bar</em> baz!?!&amp; -<em>qux</em>-%</a></h3>");
761+
t("#### **Foo?** & \\*bar?!* _`baz`_ ❤ #qux",
758762
"<h4 id=\"foo--bar--baz--qux\" class=\"section-header\">\
759763
<a href=\"#foo--bar--baz--qux\"><strong>Foo?</strong> &amp; *bar?!* \
760764
<em><code>baz</code></em> ❤ #qux</a></h4>");
@@ -764,7 +768,7 @@ mod tests {
764768
fn test_header_ids_multiple_blocks() {
765769
fn t(input: &str, expect: &str) {
766770
let output = format!("{}", Markdown(input, MarkdownOutputStyle::Fancy));
767-
assert_eq!(output, expect);
771+
assert_eq!(output, expect, "original: {}", input);
768772
}
769773

770774
let test = || {
@@ -790,7 +794,7 @@ mod tests {
790794
fn test_plain_summary_line() {
791795
fn t(input: &str, expect: &str) {
792796
let output = plain_summary_line(input);
793-
assert_eq!(output, expect);
797+
assert_eq!(output, expect, "original: {}", input);
794798
}
795799

796800
t("hello [Rust](https://www.rust-lang.org) :)", "hello Rust :)");
@@ -804,7 +808,7 @@ mod tests {
804808
fn test_markdown_html_escape() {
805809
fn t(input: &str, expect: &str) {
806810
let output = format!("{}", MarkdownHtml(input));
807-
assert_eq!(output, expect);
811+
assert_eq!(output, expect, "original: {}", input);
808812
}
809813

810814
t("`Struct<'a, T>`", "<p><code>Struct&lt;&#39;a, T&gt;</code></p>");

0 commit comments

Comments
 (0)