Skip to content

Commit d2bc614

Browse files
authored
Merge pull request #2509 from rust-lang/tshepang-auto-toc
make toc generation fully automatic
2 parents b46a764 + 6f0ae3e commit d2bc614

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+198
-147
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ jobs:
1717
MDBOOK_VERSION: 0.4.48
1818
MDBOOK_LINKCHECK2_VERSION: 0.9.1
1919
MDBOOK_MERMAID_VERSION: 0.12.6
20-
MDBOOK_TOC_VERSION: 0.11.2
2120
MDBOOK_OUTPUT__LINKCHECK__FOLLOW_WEB_LINKS: ${{ github.event_name != 'pull_request' }}
2221
DEPLOY_DIR: book/html
2322
BASE_SHA: ${{ github.event.pull_request.base.sha }}
@@ -34,7 +33,7 @@ jobs:
3433
with:
3534
path: |
3635
~/.cargo/bin
37-
key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ env.MDBOOK_TOC_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }}
36+
key: ${{ runner.os }}-${{ env.MDBOOK_VERSION }}--${{ env.MDBOOK_LINKCHECK2_VERSION }}--${{ env.MDBOOK_MERMAID_VERSION }}
3837

3938
- name: Restore cached Linkcheck
4039
if: github.event_name == 'schedule'
@@ -57,7 +56,6 @@ jobs:
5756
run: |
5857
cargo install mdbook --version ${{ env.MDBOOK_VERSION }}
5958
cargo install mdbook-linkcheck2 --version ${{ env.MDBOOK_LINKCHECK2_VERSION }}
60-
cargo install mdbook-toc --version ${{ env.MDBOOK_TOC_VERSION }}
6159
cargo install mdbook-mermaid --version ${{ env.MDBOOK_MERMAID_VERSION }}
6260
6361
- name: Check build

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ rustdocs][rustdocs].
4343
To build a local static HTML site, install [`mdbook`](https://github.com/rust-lang/mdBook) with:
4444

4545
```
46-
cargo install mdbook mdbook-linkcheck2 mdbook-toc mdbook-mermaid
46+
cargo install mdbook mdbook-linkcheck2 mdbook-mermaid
4747
```
4848

4949
and execute the following command in the root of the repository:
@@ -67,8 +67,8 @@ ENABLE_LINKCHECK=1 mdbook serve
6767

6868
### Table of Contents
6969

70-
We use `mdbook-toc` to auto-generate TOCs for long sections. You can invoke the preprocessor by
71-
including the `<!-- toc -->` marker at the place where you want the TOC.
70+
Each page has a TOC that is automatically generated by `pagetoc.js`.
71+
There is an associated `pagetoc.css`, for styling.
7272

7373
## Synchronizing josh subtree with rustc
7474

book.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ description = "A guide to developing the Rust compiler (rustc)"
66
[build]
77
create-missing = false
88

9-
[preprocessor.toc]
10-
command = "mdbook-toc"
11-
renderer = ["html"]
12-
139
[preprocessor.mermaid]
1410
command = "mdbook-mermaid"
1511

1612
[output.html]
1713
git-repository-url = "https://github.com/rust-lang/rustc-dev-guide"
1814
edit-url-template = "https://github.com/rust-lang/rustc-dev-guide/edit/master/{path}"
19-
additional-js = ["mermaid.min.js", "mermaid-init.js"]
15+
additional-js = [
16+
"mermaid.min.js",
17+
"mermaid-init.js",
18+
"pagetoc.js",
19+
]
20+
additional-css = ["pagetoc.css"]
2021

2122
[output.html.search]
2223
use-boolean-and = true

pagetoc.css

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL) */
2+
3+
:root {
4+
--toc-width: 270px;
5+
--center-content-toc-shift: calc(-1 * var(--toc-width) / 2);
6+
}
7+
8+
.nav-chapters {
9+
/* adjust width of buttons that bring to the previous or the next page */
10+
min-width: 50px;
11+
}
12+
13+
@media only screen {
14+
@media (max-width: 1179px) {
15+
.sidebar-hidden #sidetoc {
16+
display: none;
17+
}
18+
}
19+
20+
@media (max-width: 1439px) {
21+
.sidebar-visible #sidetoc {
22+
display: none;
23+
}
24+
}
25+
26+
@media (1180px <= width <= 1439px) {
27+
.sidebar-hidden main {
28+
position: relative;
29+
left: var(--center-content-toc-shift);
30+
}
31+
}
32+
33+
@media (1440px <= width <= 1700px) {
34+
.sidebar-visible main {
35+
position: relative;
36+
left: var(--center-content-toc-shift);
37+
}
38+
}
39+
40+
#sidetoc {
41+
margin-left: calc(100% + 20px);
42+
}
43+
#pagetoc {
44+
position: fixed;
45+
/* adjust TOC width */
46+
width: var(--toc-width);
47+
height: calc(100vh - var(--menu-bar-height) - 0.67em * 4);
48+
overflow: auto;
49+
}
50+
#pagetoc a {
51+
border-left: 1px solid var(--sidebar-bg);
52+
color: var(--fg);
53+
display: block;
54+
padding-bottom: 5px;
55+
padding-top: 5px;
56+
padding-left: 10px;
57+
text-align: left;
58+
text-decoration: none;
59+
}
60+
#pagetoc a:hover,
61+
#pagetoc a.active {
62+
background: var(--sidebar-bg);
63+
color: var(--sidebar-active) !important;
64+
}
65+
#pagetoc .active {
66+
background: var(--sidebar-bg);
67+
color: var(--sidebar-active);
68+
}
69+
#pagetoc .pagetoc-H2 {
70+
padding-left: 20px;
71+
}
72+
#pagetoc .pagetoc-H3 {
73+
padding-left: 40px;
74+
}
75+
#pagetoc .pagetoc-H4 {
76+
padding-left: 60px;
77+
}
78+
}
79+
80+
@media print {
81+
#sidetoc {
82+
display: none;
83+
}
84+
}

pagetoc.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Inspired by https://github.com/JorelAli/mdBook-pagetoc/tree/98ee241 (under WTFPL)
2+
3+
let activeHref = ___location.href;
4+
function updatePageToc(elem = undefined) {
5+
let selectedPageTocElem = elem;
6+
const pagetoc = document.getElementById("pagetoc");
7+
8+
function getRect(element) {
9+
return element.getBoundingClientRect();
10+
}
11+
12+
function overflowTop(container, element) {
13+
return getRect(container).top - getRect(element).top;
14+
}
15+
16+
function overflowBottom(container, element) {
17+
return getRect(container).bottom - getRect(element).bottom;
18+
}
19+
20+
// We've not selected a heading to highlight, and the URL needs updating
21+
// so we need to find a heading based on the URL
22+
if (selectedPageTocElem === undefined && ___location.href !== activeHref) {
23+
activeHref = ___location.href;
24+
for (const pageTocElement of pagetoc.children) {
25+
if (pageTocElement.href === activeHref) {
26+
selectedPageTocElem = pageTocElement;
27+
}
28+
}
29+
}
30+
31+
// We still don't have a selected heading, let's try and find the most
32+
// suitable heading based on the scroll position
33+
if (selectedPageTocElem === undefined) {
34+
const margin = window.innerHeight / 3;
35+
36+
const headers = document.getElementsByClassName("header");
37+
for (let i = 0; i < headers.length; i++) {
38+
const header = headers[i];
39+
if (selectedPageTocElem === undefined && getRect(header).top >= 0) {
40+
if (getRect(header).top < margin) {
41+
selectedPageTocElem = header;
42+
} else {
43+
selectedPageTocElem = headers[Math.max(0, i - 1)];
44+
}
45+
}
46+
// a very long last section's heading is over the screen
47+
if (selectedPageTocElem === undefined && i === headers.length - 1) {
48+
selectedPageTocElem = header;
49+
}
50+
}
51+
}
52+
53+
// Remove the active flag from all pagetoc elements
54+
for (const pageTocElement of pagetoc.children) {
55+
pageTocElement.classList.remove("active");
56+
}
57+
58+
// If we have a selected heading, set it to active and scroll to it
59+
if (selectedPageTocElem !== undefined) {
60+
for (const pageTocElement of pagetoc.children) {
61+
if (selectedPageTocElem.href.localeCompare(pageTocElement.href) === 0) {
62+
pageTocElement.classList.add("active");
63+
if (overflowTop(pagetoc, pageTocElement) > 0) {
64+
pagetoc.scrollTop = pageTocElement.offsetTop;
65+
}
66+
if (overflowBottom(pagetoc, pageTocElement) < 0) {
67+
pagetoc.scrollTop -= overflowBottom(pagetoc, pageTocElement);
68+
}
69+
}
70+
}
71+
}
72+
}
73+
74+
if (document.getElementById("sidetoc") === null &&
75+
document.getElementsByClassName("header").length > 0) {
76+
// The sidetoc element doesn't exist yet, let's create it
77+
78+
// Create the empty sidetoc and pagetoc elements
79+
const sidetoc = document.createElement("div");
80+
const pagetoc = document.createElement("div");
81+
sidetoc.id = "sidetoc";
82+
pagetoc.id = "pagetoc";
83+
sidetoc.appendChild(pagetoc);
84+
85+
// And append them to the current DOM
86+
const main = document.querySelector('main');
87+
main.insertBefore(sidetoc, main.firstChild);
88+
89+
// Populate sidebar on load
90+
window.addEventListener("load", () => {
91+
for (const header of document.getElementsByClassName("header")) {
92+
const link = document.createElement("a");
93+
link.innerHTML = header.innerHTML;
94+
link.href = header.hash;
95+
link.classList.add("pagetoc-" + header.parentElement.tagName);
96+
document.getElementById("pagetoc").appendChild(link);
97+
link.onclick = () => updatePageToc(link);
98+
}
99+
updatePageToc();
100+
});
101+
102+
// Update page table of contents selected heading on scroll
103+
window.addEventListener("scroll", () => updatePageToc());
104+
}

src/asm.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Inline assembly
22

3-
<!-- toc -->
4-
53
## Overview
64

75
Inline assembly in rustc mostly revolves around taking an `asm!` macro invocation and plumbing it

src/backend/backend-agnostic.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Backend Agnostic Codegen
22

3-
<!-- toc -->
4-
53
[`rustc_codegen_ssa`]
64
provides an abstract interface for all backends to implement,
75
namely LLVM, [Cranelift], and [GCC].

src/backend/implicit-caller-___location.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Implicit caller ___location
22

3-
<!-- toc -->
4-
53
Approved in [RFC 2091], this feature enables the accurate reporting of caller ___location during panics
64
initiated from functions like `Option::unwrap`, `Result::expect`, and `Index::index`. This feature
75
adds the [`#[track_caller]`][attr-reference] attribute for functions, the

src/backend/monomorph.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Monomorphization
22

3-
<!-- toc -->
4-
53
As you probably know, Rust has a very expressive type system that has extensive
64
support for generic types. But of course, assembly is not generic, so we need
75
to figure out the concrete types of all the generics before the code can

src/backend/updating-llvm.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Updating LLVM
22

3-
<!-- toc -->
4-
53
<!-- date-check: Aug 2024 -->
64
Rust supports building against multiple LLVM versions:
75

0 commit comments

Comments
 (0)