diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md
index d627f5b0389..747cc629ba4 100644
--- a/src/doc/rustdoc/src/SUMMARY.md
+++ b/src/doc/rustdoc/src/SUMMARY.md
@@ -9,6 +9,7 @@
- [Linking to items by name](write-documentation/linking-to-items-by-name.md)
- [Documentation tests](write-documentation/documentation-tests.md)
- [Rustdoc-specific lints](lints.md)
+- [Scraped examples](scraped-examples.md)
- [Advanced features](advanced-features.md)
- [Unstable features](unstable-features.md)
- [Deprecated features](deprecated-features.md)
diff --git a/src/doc/rustdoc/src/scraped-examples.md b/src/doc/rustdoc/src/scraped-examples.md
new file mode 100644
index 00000000000..bab992ccc50
--- /dev/null
+++ b/src/doc/rustdoc/src/scraped-examples.md
@@ -0,0 +1,55 @@
+# Scraped examples
+
+Rustdoc can automatically scrape examples of items being documented from the `examples/` directory of a Cargo workspace. These examples will be included within the generated documentation for that item. For example, if your library contains a public function:
+
+```rust,ignore(needs-other-file)
+// a_crate/src/lib.rs
+pub fn a_func() {}
+```
+
+And you have an example calling this function:
+
+```rust,ignore(needs-other-file)
+// a_crate/examples/ex.rs
+fn main() {
+ a_crate::a_func();
+}
+```
+
+Then this code snippet will be included in the documentation for `a_func`. This documentation is inserted by Rustdoc and cannot be manually edited by the crate author.
+
+
+## How to use this feature
+
+This feature is unstable, so you can enable it by calling Rustdoc with the unstable `rustdoc-scrape-examples` flag:
+
+```bash
+cargo doc -Zunstable-options -Zrustdoc-scrape-examples=examples
+```
+
+To enable this feature on [docs.rs](https://docs.rs), add this to your Cargo.toml:
+
+```toml
+[package.metadata.docs.rs]
+cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"]
+```
+
+
+## How it works
+
+When you run `cargo doc`, Rustdoc will analyze all the crates that match Cargo's `--examples` filter for instances of items being documented. Then Rustdoc will include the source code of these instances in the generated documentation.
+
+Rustdoc has a few techniques to ensure these examples don't overwhelm documentation readers, and that it doesn't blow up the page size:
+
+1. For a given item, a maximum of 5 examples are included in the page. The remaining examples are just links to source code.
+2. Only one example is shown by default, and the remaining examples are hidden behind a toggle.
+3. For a given file that contains examples, only the item containing the examples will be included in the generated documentation.
+
+For a given item, Rustdoc sorts its examples based on the size of the example — smaller ones are shown first.
+
+
+## FAQ
+
+### My example is not showing up in the documentation
+
+This feature uses Cargo's convention for finding examples. You should ensure that `cargo check --examples` includes your example file.
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 6b57ff5eeba..b5536dc930f 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2671,6 +2671,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
\
\
\
"
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 42b66c70c4c..b278ab6b24d 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -618,7 +618,7 @@ h2.location a {
position: relative;
}
-.docblock > :not(.information) {
+.docblock > :not(.information):not(.more-examples-toggle) {
max-width: 100%;
overflow-x: auto;
}
@@ -836,8 +836,8 @@ h2.small-section-header > .anchor {
content: 'ยง';
}
-.docblock a:not(.srclink):not(.test-arrow):hover,
-.docblock-short a:not(.srclink):not(.test-arrow):hover, .item-info a {
+.docblock a:not(.srclink):not(.test-arrow):not(.scrape-help):hover,
+.docblock-short a:not(.srclink):not(.test-arrow):not(.scrape-help):hover, .item-info a {
text-decoration: underline;
}
@@ -2034,10 +2034,36 @@ details.rustdoc-toggle[open] > summary.hideme::after {
/* Begin: styles for --scrape-examples feature */
+.scraped-example-list .section-header .scrape-help {
+ cursor: pointer;
+ border-radius: 2px;
+ margin-left: 10px;
+ padding: 0 4px;
+ font-weight: normal;
+ font-size: 12px;
+ position: relative;
+ bottom: 1px;
+ background: transparent;
+ border-width: 1px;
+ border-style: solid;
+}
+
.scraped-example-title {
font-family: 'Fira Sans';
}
+.scraped-example .code-wrapper {
+ position: relative;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ width: 100%;
+}
+
+.scraped-example:not(.expanded) .code-wrapper {
+ max-height: 240px;
+}
+
.scraped-example:not(.expanded) .code-wrapper pre {
overflow-y: hidden;
max-height: 240px;
@@ -2072,14 +2098,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
cursor: pointer;
}
-.scraped-example .code-wrapper {
- position: relative;
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- width: 100%;
-}
-
.scraped-example:not(.expanded) .code-wrapper:before {
content: " ";
width: 100%;
@@ -2087,7 +2105,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
position: absolute;
z-index: 100;
top: 0;
- background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
}
.scraped-example:not(.expanded) .code-wrapper:after {
@@ -2097,12 +2114,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
position: absolute;
z-index: 100;
bottom: 0;
- background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
-}
-
-.scraped-example:not(.expanded) .code-wrapper {
- overflow: hidden;
- max-height: 240px;
}
.scraped-example .code-wrapper .line-numbers {
@@ -2121,34 +2132,37 @@ details.rustdoc-toggle[open] > summary.hideme::after {
margin-bottom: 0;
}
+.scraped-example:not(.expanded) .code-wrapper .example-wrap {
+ overflow-x: hidden;
+}
+
.scraped-example .code-wrapper .example-wrap pre.rust {
overflow-x: inherit;
width: inherit;
overflow-y: hidden;
}
-.scraped-example .example-wrap .rust span.highlight {
- background: #fcffd6;
-}
-
-.scraped-example .example-wrap .rust span.highlight.focus {
- background: #f6fdb0;
-}
.more-examples-toggle {
+ max-width: calc(100% + 25px);
margin-top: 10px;
+ margin-left: -25px;
}
-.more-examples-toggle summary {
- color: #999;
+.more-examples-toggle .hide-more {
+ margin-left: 25px;
+ margin-bottom: 5px;
+ cursor: pointer;
+}
+
+.more-examples-toggle summary, .more-examples-toggle .hide-more {
font-family: 'Fira Sans';
}
.more-scraped-examples {
- margin-left: 25px;
+ margin-left: 5px;
display: flex;
flex-direction: row;
- width: calc(100% - 25px);
}
.more-scraped-examples-inner {
@@ -2164,13 +2178,8 @@ details.rustdoc-toggle[open] > summary.hideme::after {
cursor: pointer;
}
-.toggle-line:hover .toggle-line-inner {
- background: #aaa;
-}
-
.toggle-line-inner {
min-width: 2px;
- background: #ddd;
height: 100%;
}
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index e402b3583f3..0fee0ba54fa 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -611,6 +611,18 @@ input:checked + .slider {
background-color: #ffb454 !important;
}
+
+.scraped-example-list .section-header .scrape-help {
+ border-color: #999;
+ color: #999;
+}
+.scraped-example-list .section-header .scrape-help:hover {
+ border-color: #c5c5c5;
+ color: #c5c5c5;
+}
+.more-examples-toggle summary, .more-examples-toggle .hide-more {
+ color: #999;
+}
.scraped-example .example-wrap .rust span.highlight {
background: rgb(91, 59, 1);
}
@@ -624,8 +636,8 @@ input:checked + .slider {
background: linear-gradient(to top, rgba(15, 20, 25, 1), rgba(15, 20, 25, 0));
}
.toggle-line-inner {
- background: #616161;
+ background: #999;
}
.toggle-line:hover .toggle-line-inner {
- background: #898989;
+ background: #c5c5c5;
}
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 0a56055b8cb..e121c984dbd 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -478,6 +478,17 @@ div.files > .selected {
border-bottom-color: #ddd;
}
+.scraped-example-list .section-header .scrape-help {
+ border-color: #999;
+ color: #999;
+}
+.scraped-example-list .section-header .scrape-help:hover {
+ border-color: #c5c5c5;
+ color: #c5c5c5;
+}
+.more-examples-toggle summary, .more-examples-toggle .hide-more {
+ color: #999;
+}
.scraped-example .example-wrap .rust span.highlight {
background: rgb(91, 59, 1);
}
@@ -491,8 +502,8 @@ div.files > .selected {
background: linear-gradient(to top, rgba(53, 53, 53, 1), rgba(53, 53, 53, 0));
}
.toggle-line-inner {
- background: #616161;
+ background: #999;
}
.toggle-line:hover .toggle-line-inner {
- background: #898989;
+ background: #c5c5c5;
}
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index dc1715b2a78..be1da8df2b5 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -462,3 +462,33 @@ div.files > .selected {
.setting-line > .title {
border-bottom-color: #D5D5D5;
}
+
+.scraped-example-list .section-header .scrape-help {
+ border-color: #999;
+ color: #999;
+}
+.scraped-example-list .section-header .scrape-help:hover {
+ border-color: black;
+ color: black;
+}
+.more-examples-toggle summary, .more-examples-toggle .hide-more {
+ color: #999;
+}
+.scraped-example .example-wrap .rust span.highlight {
+ background: #fcffd6;
+}
+.scraped-example .example-wrap .rust span.highlight.focus {
+ background: #f6fdb0;
+}
+.scraped-example:not(.expanded) .code-wrapper:before {
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
+}
+.scraped-example:not(.expanded) .code-wrapper:after {
+ background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
+}
+.toggle-line-inner {
+ background: #ccc;
+}
+.toggle-line:hover .toggle-line-inner {
+ background: #999;
+}
diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js
index 383ae001bc2..a28fb461729 100644
--- a/src/librustdoc/html/static/js/scrape-examples.js
+++ b/src/librustdoc/html/static/js/scrape-examples.js
@@ -84,8 +84,10 @@
onEach(document.querySelectorAll('.more-examples-toggle'), function(toggle) {
// Allow users to click the left border of the section to close it,
// since the section can be large and finding the [+] button is annoying.
- toggle.querySelector('.toggle-line').addEventListener('click', function() {
- toggle.open = false;
+ toggle.querySelectorAll('.toggle-line, .hide-more').forEach(button => {
+ button.addEventListener('click', function() {
+ toggle.open = false;
+ });
});
var moreExamples = toggle.querySelectorAll('.scraped-example');
diff --git a/src/test/run-make/rustdoc-scrape-examples-ordering/src/lib.rs b/src/test/run-make/rustdoc-scrape-examples-ordering/src/lib.rs
index 7bd57609fa2..c53c987a7cb 100644
--- a/src/test/run-make/rustdoc-scrape-examples-ordering/src/lib.rs
+++ b/src/test/run-make/rustdoc-scrape-examples-ordering/src/lib.rs
@@ -1,6 +1,6 @@
// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' 'ex2'
// @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' 'ex1'
-// @has foobar/fn.ok.html '//*[@class="highlight focus"]' ''
-// @has foobar/fn.ok.html '//*[@class="highlight"]' ''
+// @has foobar/fn.ok.html '//*[@class="highlight focus"]' 'ok'
+// @has foobar/fn.ok.html '//*[@class="highlight"]' 'ok'
pub fn ok(_x: i32) {}