diff --git a/src/doc/rustdoc/src/write-documentation/what-to-include.md b/src/doc/rustdoc/src/write-documentation/what-to-include.md index 75d3b7dae61ed..93e374f0214a9 100644 --- a/src/doc/rustdoc/src/write-documentation/what-to-include.md +++ b/src/doc/rustdoc/src/write-documentation/what-to-include.md @@ -85,6 +85,34 @@ The example is the same on the doc page, but has that extra information available to anyone trying to use your crate. More about tests in the upcoming [Documentation tests] chapter. +In case you're writing documentation for a macro, it might be useful to use +the `no-hidden-lines` attribute in order to prevent some `#` characters to be +stripped: + +``````rust +//! ```rust,no-hidden-lines +//! +//! test!( +//! # a, +//! ##b, +//! ###c +//! ); +//! ``` +macro_rules! test { + (# a,##b,###c) => {} +} +`````` + +Without using the `no-hidden-lines` attribute, the generated code example would +look like this: + +```text +test!( + #b, + ##c +); +``` + ## What to Exclude Certain parts of your public interface may be included by default in the output diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index abc27bcdf0782..6a08493294859 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -288,7 +288,13 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { }; let added_classes = parse_result.added_classes; - let lines = original_text.lines().filter_map(|l| map_line(l).for_html()); + let lines = original_text.lines().filter_map(|l| { + if parse_result.no_hidden_lines { + Some(Cow::Borrowed(l)) + } else { + map_line(l).for_html() + } + }); let text = lines.intersperse("\n".into()).collect::(); compile_fail = parse_result.compile_fail; @@ -879,6 +885,7 @@ pub(crate) struct LangString { pub(crate) edition: Option, pub(crate) added_classes: Vec, pub(crate) unknown: Vec, + pub(crate) no_hidden_lines: bool, } #[derive(Eq, PartialEq, Clone, Debug)] @@ -1213,6 +1220,7 @@ impl Default for LangString { edition: None, added_classes: Vec::new(), unknown: Vec::new(), + no_hidden_lines: false, } } } @@ -1274,6 +1282,10 @@ impl LangString { data.rust = true; seen_rust_tags = true; } + LangStringToken::LangToken("no_hidden_lines") => { + data.no_hidden_lines = true; + seen_rust_tags = !seen_other_tags; + } LangStringToken::LangToken("custom") => { if custom_code_classes_in_docs { seen_custom_tag = true; diff --git a/tests/rustdoc/no-hidden-lines-codeblock-format.codeblock-non-raw.html b/tests/rustdoc/no-hidden-lines-codeblock-format.codeblock-non-raw.html new file mode 100644 index 0000000000000..853f5bc8fd47c --- /dev/null +++ b/tests/rustdoc/no-hidden-lines-codeblock-format.codeblock-non-raw.html @@ -0,0 +1,8 @@ +macro_rules! test { + (# a,##b,###c) => {} +} + +test!( + #b, + ##c +); \ No newline at end of file diff --git a/tests/rustdoc/no-hidden-lines-codeblock-format.codeblock.html b/tests/rustdoc/no-hidden-lines-codeblock-format.codeblock.html new file mode 100644 index 0000000000000..836da5c4bd9b7 --- /dev/null +++ b/tests/rustdoc/no-hidden-lines-codeblock-format.codeblock.html @@ -0,0 +1,9 @@ +macro_rules! test { + (# a,##b,###c) => {} +} + +test!( + # a, + ##b, + ###c +); \ No newline at end of file diff --git a/tests/rustdoc/no-hidden-lines-codeblock-format.rs b/tests/rustdoc/no-hidden-lines-codeblock-format.rs new file mode 100644 index 0000000000000..86093de329dfd --- /dev/null +++ b/tests/rustdoc/no-hidden-lines-codeblock-format.rs @@ -0,0 +1,54 @@ +// Test that the `no_hidden_lines` codeblock attribute prevents lines starting with `#` to +// be stripped. + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// @matches - '//*[@class="rust rust-example-rendered"]/code' '\(\s+# a,\s+##b,\s+###c\s+\);' +// @snapshot 'codeblock' - '//*[@class="rust rust-example-rendered"]/code' + +//! ```rust,no_hidden_lines +//! macro_rules! test { +//! (# a,##b,###c) => {} +//! } +//! +//! test!( +//! # a, +//! ##b, +//! ###c +//! ); +//! ``` + +// @has 'foo/fn.foo.html' +// @matches - '//*[@class="rust rust-example-rendered"]/code' '\(\s+#b,\s+##c\s+\);' +// @snapshot 'codeblock-non-raw' - '//*[@class="rust rust-example-rendered"]/code' + +/// ``` +/// macro_rules! test { +/// (# a,##b,###c) => {} +/// } +/// +/// test!( +/// # a, +/// ##b, +/// ###c +/// ); +/// ``` +pub fn foo() {} + +// Testing that `raw` means that it is a rust code block by default. +// @has 'foo/fn.bar.html' +// @matches - '//*[@class="rust rust-example-rendered"]/code' '\(\s+#a,\s+##b,\s+###c\s+\);' + +/// ```no_hidden_lines +/// macro_rules! test { +/// (#a,##b,###c) => {} +/// } +/// +/// test!( +/// #a, +/// ##b, +/// ###c +/// ); +/// ``` +pub fn bar() {}