Auto merge of #51803 - lucasem:rustdoc-code-hash-escape, r=GuillaumeGomez
rustdoc codeblock hash escape So that docstring text such as the following (in a code block) can be created ergonomically: ```rust let s = " foo # bar baz "; ``` Such code in a docstring hide the <code> # bar</code> line. Previously, using two consecutive hashes <code> ## bar</code> would turn the line into _shown_ `# bar`, losing the leading whitespace. A line of code like <code> # bar</code> (such as in the example above) **could not be represented** in the docstring text. This commit makes the two consecutive hashes not also trim the leading whitespace — the two hashes simply **escape** into a single hash and do not hide the line, leaving the rest of that line unaffected. The new docstring text to achieve the above code block is: ```rust /// ``` /// let s = " /// foo /// ## bar /// baz /// "; /// ``` ```
This commit is contained in:
commit
afaa406465
@ -170,6 +170,23 @@ By repeating all parts of the example, you can ensure that your example still
|
||||
compiles, while only showing the parts that are relevant to that part of your
|
||||
explanation.
|
||||
|
||||
The `#`-hiding of lines can be prevented by using two consecutive hashes
|
||||
`##`. This only needs to be done with with the first `#` which would've
|
||||
otherwise caused hiding. If we have a string literal like the following,
|
||||
which has a line that starts with a `#`:
|
||||
|
||||
```rust
|
||||
let s = "foo
|
||||
## bar # baz";
|
||||
```
|
||||
|
||||
We can document it by escaping the initial `#`:
|
||||
|
||||
```text
|
||||
/// let s = "foo
|
||||
/// ## bar # baz";
|
||||
```
|
||||
|
||||
|
||||
## Using `?` in doc tests
|
||||
|
||||
|
@ -64,21 +64,21 @@
|
||||
/// All lines are used in documentation tests.
|
||||
enum Line<'a> {
|
||||
Hidden(&'a str),
|
||||
Shown(&'a str),
|
||||
Shown(Cow<'a, str>),
|
||||
}
|
||||
|
||||
impl<'a> Line<'a> {
|
||||
fn for_html(self) -> Option<&'a str> {
|
||||
fn for_html(self) -> Option<Cow<'a, str>> {
|
||||
match self {
|
||||
Line::Shown(l) => Some(l),
|
||||
Line::Hidden(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn for_code(self) -> &'a str {
|
||||
fn for_code(self) -> Cow<'a, str> {
|
||||
match self {
|
||||
Line::Shown(l) |
|
||||
Line::Hidden(l) => l,
|
||||
Line::Shown(l) => l,
|
||||
Line::Hidden(l) => Cow::Borrowed(l),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,7 +91,7 @@ fn for_code(self) -> &'a str {
|
||||
fn map_line(s: &str) -> Line {
|
||||
let trimmed = s.trim();
|
||||
if trimmed.starts_with("##") {
|
||||
Line::Shown(&trimmed[1..])
|
||||
Line::Shown(Cow::Owned(s.replacen("##", "#", 1)))
|
||||
} else if trimmed.starts_with("# ") {
|
||||
// # text
|
||||
Line::Hidden(&trimmed[2..])
|
||||
@ -99,7 +99,7 @@ fn map_line(s: &str) -> Line {
|
||||
// We cannot handle '#text' because it could be #[attr].
|
||||
Line::Hidden("")
|
||||
} else {
|
||||
Line::Shown(s)
|
||||
Line::Shown(Cow::Borrowed(s))
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ fn next(&mut self) -> Option<Self::Item> {
|
||||
}
|
||||
}
|
||||
let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
|
||||
let text = lines.collect::<Vec<&str>>().join("\n");
|
||||
let text = lines.collect::<Vec<Cow<str>>>().join("\n");
|
||||
PLAYGROUND.with(|play| {
|
||||
// insert newline to clearly separate it from the
|
||||
// previous block so we can shorten the html output
|
||||
@ -179,7 +179,7 @@ fn next(&mut self) -> Option<Self::Item> {
|
||||
}
|
||||
let test = origtext.lines()
|
||||
.map(|l| map_line(l).for_code())
|
||||
.collect::<Vec<&str>>().join("\n");
|
||||
.collect::<Vec<Cow<str>>>().join("\n");
|
||||
let krate = krate.as_ref().map(|s| &**s);
|
||||
let (test, _) = test::make_test(&test, krate, false,
|
||||
&Default::default());
|
||||
@ -477,7 +477,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
|
||||
}
|
||||
if let Some(offset) = offset {
|
||||
let lines = test_s.lines().map(|l| map_line(l).for_code());
|
||||
let text = lines.collect::<Vec<&str>>().join("\n");
|
||||
let text = lines.collect::<Vec<Cow<str>>>().join("\n");
|
||||
nb_lines += doc[prev_offset..offset].lines().count();
|
||||
let line = tests.get_line() + (nb_lines - 1);
|
||||
let filename = tests.get_filename();
|
||||
|
Loading…
Reference in New Issue
Block a user