Skip to content

Commit ae5d0cb

Browse files
committed
Improve alignment of additional scraped examples, add scrape examples help page
1 parent f1e3e2c commit ae5d0cb

File tree

9 files changed

+164
-42
lines changed

9 files changed

+164
-42
lines changed

src/doc/rustdoc/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [Linking to items by name](write-documentation/linking-to-items-by-name.md)
1010
- [Documentation tests](write-documentation/documentation-tests.md)
1111
- [Rustdoc-specific lints](lints.md)
12+
- [Scraped examples](scraped-examples.md)
1213
- [Advanced features](advanced-features.md)
1314
- [Unstable features](unstable-features.md)
1415
- [Deprecated features](deprecated-features.md)
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Scraped examples
2+
3+
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:
4+
5+
```rust,ignore(needs-other-file)
6+
// a_crate/src/lib.rs
7+
pub fn a_func() {}
8+
```
9+
10+
And you have an example calling this function:
11+
12+
```rust,ignore(needs-other-file)
13+
// a_crate/examples/ex.rs
14+
fn main() {
15+
a_crate::a_func();
16+
}
17+
```
18+
19+
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.
20+
21+
22+
## How to use this feature
23+
24+
This feature is unstable, so you can enable it by calling Rustdoc with the unstable `rustdoc-scrape-examples` flag:
25+
26+
```bash
27+
cargo doc -Zunstable-options -Zrustdoc-scrape-examples=examples
28+
```
29+
30+
To enable this feature on [docs.rs](https://docs.rs), add this to your Cargo.toml:
31+
32+
```toml
33+
[package.metadata.docs.rs]
34+
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"]
35+
```
36+
37+
38+
## How it works
39+
40+
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.
41+
42+
Rustdoc has a few techniques to ensure these examples don't overwhelm documentation readers, and that it doesn't blow up the page size:
43+
44+
1. For a given item, a maximum of 5 examples are included in the page. The remaining examples are just links to source code.
45+
2. Only one example is shown by default, and the remaining examples are hidden behind a toggle.
46+
3. For a given file that contains examples, only the item containing the examples will be included in the generated documentation.
47+
48+
For a given item, Rustdoc sorts its examples based on the size of the example — smaller ones are shown first.
49+
50+
51+
## FAQ
52+
53+
### My example is not showing up in the documentation
54+
55+
This feature uses Cargo's convention for finding examples. You should ensure that `cargo check --examples` includes your example file.

src/librustdoc/html/render/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2671,6 +2671,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
26712671
<span></span>\
26722672
<h5 id=\"{id}\">\
26732673
<a href=\"#{id}\">Examples found in repository</a>\
2674+
<a class=\"scrape-help\" href=\"https://doc.rust-lang.org/rustdoc/scraped-examples.html\" target=\"_blank\">?</a>\
26742675
</h5>",
26752676
id = id
26762677
);
@@ -2842,6 +2843,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) {
28422843
<summary class=\"hideme\">\
28432844
<span>More examples</span>\
28442845
</summary>\
2846+
<div class=\"hide-more\">Hide additional examples</div>\
28452847
<div class=\"more-scraped-examples\">\
28462848
<div class=\"toggle-line\"><div class=\"toggle-line-inner\"></div></div>\
28472849
<div class=\"more-scraped-examples-inner\">"

src/librustdoc/html/static/css/rustdoc.css

+43-34
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ h2.location a {
618618
position: relative;
619619
}
620620

621-
.docblock > :not(.information) {
621+
.docblock > :not(.information):not(.more-examples-toggle) {
622622
max-width: 100%;
623623
overflow-x: auto;
624624
}
@@ -836,8 +836,8 @@ h2.small-section-header > .anchor {
836836
content: '§';
837837
}
838838

839-
.docblock a:not(.srclink):not(.test-arrow):hover,
840-
.docblock-short a:not(.srclink):not(.test-arrow):hover, .item-info a {
839+
.docblock a:not(.srclink):not(.test-arrow):not(.scrape-help):hover,
840+
.docblock-short a:not(.srclink):not(.test-arrow):not(.scrape-help):hover, .item-info a {
841841
text-decoration: underline;
842842
}
843843

@@ -2034,10 +2034,36 @@ details.rustdoc-toggle[open] > summary.hideme::after {
20342034

20352035
/* Begin: styles for --scrape-examples feature */
20362036

2037+
.scraped-example-list .section-header .scrape-help {
2038+
cursor: pointer;
2039+
border-radius: 2px;
2040+
margin-left: 10px;
2041+
padding: 0 4px;
2042+
font-weight: normal;
2043+
font-size: 12px;
2044+
position: relative;
2045+
bottom: 1px;
2046+
background: transparent;
2047+
border-width: 1px;
2048+
border-style: solid;
2049+
}
2050+
20372051
.scraped-example-title {
20382052
font-family: 'Fira Sans';
20392053
}
20402054

2055+
.scraped-example .code-wrapper {
2056+
position: relative;
2057+
display: flex;
2058+
flex-direction: row;
2059+
flex-wrap: wrap;
2060+
width: 100%;
2061+
}
2062+
2063+
.scraped-example:not(.expanded) .code-wrapper {
2064+
max-height: 240px;
2065+
}
2066+
20412067
.scraped-example:not(.expanded) .code-wrapper pre {
20422068
overflow-y: hidden;
20432069
max-height: 240px;
@@ -2072,22 +2098,13 @@ details.rustdoc-toggle[open] > summary.hideme::after {
20722098
cursor: pointer;
20732099
}
20742100

2075-
.scraped-example .code-wrapper {
2076-
position: relative;
2077-
display: flex;
2078-
flex-direction: row;
2079-
flex-wrap: wrap;
2080-
width: 100%;
2081-
}
2082-
20832101
.scraped-example:not(.expanded) .code-wrapper:before {
20842102
content: " ";
20852103
width: 100%;
20862104
height: 5px;
20872105
position: absolute;
20882106
z-index: 100;
20892107
top: 0;
2090-
background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
20912108
}
20922109

20932110
.scraped-example:not(.expanded) .code-wrapper:after {
@@ -2097,12 +2114,6 @@ details.rustdoc-toggle[open] > summary.hideme::after {
20972114
position: absolute;
20982115
z-index: 100;
20992116
bottom: 0;
2100-
background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
2101-
}
2102-
2103-
.scraped-example:not(.expanded) .code-wrapper {
2104-
overflow: hidden;
2105-
max-height: 240px;
21062117
}
21072118

21082119
.scraped-example .code-wrapper .line-numbers {
@@ -2121,34 +2132,37 @@ details.rustdoc-toggle[open] > summary.hideme::after {
21212132
margin-bottom: 0;
21222133
}
21232134

2135+
.scraped-example:not(.expanded) .code-wrapper .example-wrap {
2136+
overflow-x: hidden;
2137+
}
2138+
21242139
.scraped-example .code-wrapper .example-wrap pre.rust {
21252140
overflow-x: inherit;
21262141
width: inherit;
21272142
overflow-y: hidden;
21282143
}
21292144

2130-
.scraped-example .example-wrap .rust span.highlight {
2131-
background: #fcffd6;
2132-
}
2133-
2134-
.scraped-example .example-wrap .rust span.highlight.focus {
2135-
background: #f6fdb0;
2136-
}
21372145

21382146
.more-examples-toggle {
2147+
max-width: calc(100% + 25px);
21392148
margin-top: 10px;
2149+
margin-left: -25px;
2150+
}
2151+
2152+
.more-examples-toggle .hide-more {
2153+
margin-left: 25px;
2154+
margin-bottom: 5px;
2155+
cursor: pointer;
21402156
}
21412157

2142-
.more-examples-toggle summary {
2143-
color: #999;
2158+
.more-examples-toggle summary, .more-examples-toggle .hide-more {
21442159
font-family: 'Fira Sans';
21452160
}
21462161

21472162
.more-scraped-examples {
2148-
margin-left: 25px;
2163+
margin-left: 5px;
21492164
display: flex;
21502165
flex-direction: row;
2151-
width: calc(100% - 25px);
21522166
}
21532167

21542168
.more-scraped-examples-inner {
@@ -2164,13 +2178,8 @@ details.rustdoc-toggle[open] > summary.hideme::after {
21642178
cursor: pointer;
21652179
}
21662180

2167-
.toggle-line:hover .toggle-line-inner {
2168-
background: #aaa;
2169-
}
2170-
21712181
.toggle-line-inner {
21722182
min-width: 2px;
2173-
background: #ddd;
21742183
height: 100%;
21752184
}
21762185

src/librustdoc/html/static/css/themes/ayu.css

+14-2
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,18 @@ input:checked + .slider {
611611
background-color: #ffb454 !important;
612612
}
613613

614+
615+
.scraped-example-list .section-header .scrape-help {
616+
border-color: #999;
617+
color: #999;
618+
}
619+
.scraped-example-list .section-header .scrape-help:hover {
620+
border-color: #c5c5c5;
621+
color: #c5c5c5;
622+
}
623+
.more-examples-toggle summary, .more-examples-toggle .hide-more {
624+
color: #999;
625+
}
614626
.scraped-example .example-wrap .rust span.highlight {
615627
background: rgb(91, 59, 1);
616628
}
@@ -624,8 +636,8 @@ input:checked + .slider {
624636
background: linear-gradient(to top, rgba(15, 20, 25, 1), rgba(15, 20, 25, 0));
625637
}
626638
.toggle-line-inner {
627-
background: #616161;
639+
background: #999;
628640
}
629641
.toggle-line:hover .toggle-line-inner {
630-
background: #898989;
642+
background: #c5c5c5;
631643
}

src/librustdoc/html/static/css/themes/dark.css

+13-2
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,17 @@ div.files > .selected {
478478
border-bottom-color: #ddd;
479479
}
480480

481+
.scraped-example-list .section-header .scrape-help {
482+
border-color: #999;
483+
color: #999;
484+
}
485+
.scraped-example-list .section-header .scrape-help:hover {
486+
border-color: #c5c5c5;
487+
color: #c5c5c5;
488+
}
489+
.more-examples-toggle summary, .more-examples-toggle .hide-more {
490+
color: #999;
491+
}
481492
.scraped-example .example-wrap .rust span.highlight {
482493
background: rgb(91, 59, 1);
483494
}
@@ -491,8 +502,8 @@ div.files > .selected {
491502
background: linear-gradient(to top, rgba(53, 53, 53, 1), rgba(53, 53, 53, 0));
492503
}
493504
.toggle-line-inner {
494-
background: #616161;
505+
background: #999;
495506
}
496507
.toggle-line:hover .toggle-line-inner {
497-
background: #898989;
508+
background: #c5c5c5;
498509
}

src/librustdoc/html/static/css/themes/light.css

+30
Original file line numberDiff line numberDiff line change
@@ -462,3 +462,33 @@ div.files > .selected {
462462
.setting-line > .title {
463463
border-bottom-color: #D5D5D5;
464464
}
465+
466+
.scraped-example-list .section-header .scrape-help {
467+
border-color: #999;
468+
color: #999;
469+
}
470+
.scraped-example-list .section-header .scrape-help:hover {
471+
border-color: black;
472+
color: black;
473+
}
474+
.more-examples-toggle summary, .more-examples-toggle .hide-more {
475+
color: #999;
476+
}
477+
.scraped-example .example-wrap .rust span.highlight {
478+
background: #fcffd6;
479+
}
480+
.scraped-example .example-wrap .rust span.highlight.focus {
481+
background: #f6fdb0;
482+
}
483+
.scraped-example:not(.expanded) .code-wrapper:before {
484+
background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
485+
}
486+
.scraped-example:not(.expanded) .code-wrapper:after {
487+
background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
488+
}
489+
.toggle-line-inner {
490+
background: #ccc;
491+
}
492+
.toggle-line:hover .toggle-line-inner {
493+
background: #999;
494+
}

src/librustdoc/html/static/js/scrape-examples.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@
8484
onEach(document.querySelectorAll('.more-examples-toggle'), function(toggle) {
8585
// Allow users to click the left border of the <details> section to close it,
8686
// since the section can be large and finding the [+] button is annoying.
87-
toggle.querySelector('.toggle-line').addEventListener('click', function() {
88-
toggle.open = false;
87+
toggle.querySelectorAll('.toggle-line, .hide-more').forEach(button => {
88+
button.addEventListener('click', function() {
89+
toggle.open = false;
90+
});
8991
});
9092

9193
var moreExamples = toggle.querySelectorAll('.scraped-example');
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]' 'ex2'
22
// @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' 'ex1'
3-
// @has foobar/fn.ok.html '//*[@class="highlight focus"]' ''
4-
// @has foobar/fn.ok.html '//*[@class="highlight"]' ''
3+
// @has foobar/fn.ok.html '//*[@class="highlight focus"]' 'ok'
4+
// @has foobar/fn.ok.html '//*[@class="highlight"]' 'ok'
55

66
pub fn ok(_x: i32) {}

0 commit comments

Comments
 (0)