diff options
| author | bors <bors@rust-lang.org> | 2017-05-07 10:52:26 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-05-07 10:52:26 +0000 |
| commit | ced823e267c132fab172b1890b24073995e79ffa (patch) | |
| tree | 117de1fef83db2e8e211d08125fb33d28d3eb14d | |
| parent | 892be3f30791aeec6ca408446b4505696eb21212 (diff) | |
| parent | ffe12b1274732e791e117d8cc79b3db0f4161956 (diff) | |
| download | rust-ced823e267c132fab172b1890b24073995e79ffa.tar.gz rust-ced823e267c132fab172b1890b24073995e79ffa.zip | |
Auto merge of #41785 - Mark-Simulacrum:issue-41783, r=GuillaumeGomez
Allow # to appear in rustdoc code output. "##" at the start of a trimmed rustdoc line is now cut to "#" and then shown. If the user wanted to show "##", they can type "###". I'm somewhat concerned about the potential implications for users, since this does make a potentially backwards-incompatible change. Previously, `##` had no special handling, and now we do change it. However, I'm not really sure what we can do here to improve this, and I can't think of any cases where `##` would likely be correct in a code block, though of course I could be wrong. Fixes #41783.
| -rw-r--r-- | src/librustdoc/html/markdown.rs | 75 | ||||
| -rw-r--r-- | src/test/rustdoc/issue-41783.rs | 25 |
2 files changed, 73 insertions, 27 deletions
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 85a28bbfbc6..ec4a23b0417 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -66,18 +66,47 @@ pub struct MarkdownHtml<'a>(pub &'a str, pub RenderType); /// A unit struct like `Markdown`, that renders only the first paragraph. pub struct MarkdownSummaryLine<'a>(pub &'a str); -/// Returns Some(code) if `s` is a line that should be stripped from -/// documentation but used in example code. `code` is the portion of -/// `s` that should be used in tests. (None for lines that should be -/// left as-is.) -fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> { +/// Controls whether a line will be hidden or shown in HTML output. +/// +/// All lines are used in documentation tests. +enum Line<'a> { + Hidden(&'a str), + Shown(&'a str), +} + +impl<'a> Line<'a> { + fn for_html(self) -> Option<&'a str> { + match self { + Line::Shown(l) => Some(l), + Line::Hidden(_) => None, + } + } + + fn for_code(self) -> &'a str { + match self { + Line::Shown(l) | + Line::Hidden(l) => l, + } + } +} + +// FIXME: There is a minor inconsistency here. For lines that start with ##, we +// have no easy way of removing a potential single space after the hashes, which +// is done in the single # case. This inconsistency seems okay, if non-ideal. In +// order to fix it we'd have to iterate to find the first non-# character, and +// then reallocate to remove it; which would make us return a String. +fn map_line(s: &str) -> Line { let trimmed = s.trim(); - if trimmed == "#" { - Some("") + if trimmed.starts_with("##") { + Line::Shown(&trimmed[1..]) } else if trimmed.starts_with("# ") { - Some(&trimmed[2..]) + // # text + Line::Hidden(&trimmed[2..]) + } else if trimmed == "#" { + // We cannot handle '#text' because it could be #[attr]. + Line::Hidden("") } else { - None + Line::Shown(s) } } @@ -148,9 +177,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> { _ => {} } } - let lines = origtext.lines().filter(|l| { - stripped_filtered_line(*l).is_none() - }); + let lines = origtext.lines().filter_map(|l| map_line(l).for_html()); let text = lines.collect::<Vec<&str>>().join("\n"); PLAYGROUND.with(|play| { // insert newline to clearly separate it from the @@ -160,9 +187,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> { if url.is_empty() { return None; } - let test = origtext.lines().map(|l| { - stripped_filtered_line(l).unwrap_or(l) - }).collect::<Vec<&str>>().join("\n"); + let test = origtext.lines() + .map(|l| map_line(l).for_code()) + .collect::<Vec<&str>>().join("\n"); let krate = krate.as_ref().map(|s| &**s); let test = test::maketest(&test, krate, false, &Default::default()); @@ -543,9 +570,7 @@ pub fn render(w: &mut fmt::Formatter, } }; - let lines = origtext.lines().filter(|l| { - stripped_filtered_line(*l).is_none() - }); + let lines = origtext.lines().filter_map(|l| map_line(l).for_html()); let text = lines.collect::<Vec<&str>>().join("\n"); if rendered { return } PLAYGROUND.with(|play| { @@ -556,9 +581,9 @@ pub fn render(w: &mut fmt::Formatter, if url.is_empty() { return None; } - let test = origtext.lines().map(|l| { - stripped_filtered_line(l).unwrap_or(l) - }).collect::<Vec<&str>>().join("\n"); + let test = origtext.lines() + .map(|l| map_line(l).for_code()) + .collect::<Vec<&str>>().join("\n"); let krate = krate.as_ref().map(|s| &**s); let test = test::maketest(&test, krate, false, &Default::default()); @@ -734,9 +759,7 @@ pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position let opaque = (*data).opaque as *mut hoedown_html_renderer_state; let tests = &mut *((*opaque).opaque as *mut ::test::Collector); let text = str::from_utf8(text).unwrap(); - let lines = text.lines().map(|l| { - stripped_filtered_line(l).unwrap_or(l) - }); + let lines = text.lines().map(|l| map_line(l).for_code()); let text = lines.collect::<Vec<&str>>().join("\n"); let filename = tests.get_filename(); @@ -827,9 +850,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp } } let offset = offset.unwrap_or(0); - let lines = test_s.lines().map(|l| { - stripped_filtered_line(l).unwrap_or(l) - }); + let lines = test_s.lines().map(|l| map_line(l).for_code()); let text = lines.collect::<Vec<&str>>().join("\n"); nb_lines += doc[prev_offset..offset].lines().count(); let line = tests.get_line() + (nb_lines - 1); diff --git a/src/test/rustdoc/issue-41783.rs b/src/test/rustdoc/issue-41783.rs new file mode 100644 index 00000000000..3933b8bcbb8 --- /dev/null +++ b/src/test/rustdoc/issue-41783.rs @@ -0,0 +1,25 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// @has issue_41783/struct.Foo.html +// @!has - 'space' +// @!has - 'comment' +// @has - '# <span class="ident">single' +// @has - '#<span class="attribute"># <span class="ident">double</span>' +// @has - '#<span class="attribute">#<span class="attribute"># <span class="ident">triple</span>' + +/// ```no_run +/// # # space +/// # comment +/// ## single +/// ### double +/// #### triple +/// ``` +pub struct Foo; |
