Skip to content

Commit 3d04d95

Browse files
authored
Merge pull request #240 from pytorch/add-collapsible
Add collapsible styles for C++ docs
2 parents f987ecc + 946e75a commit 3d04d95

File tree

4 files changed

+129
-1
lines changed

4 files changed

+129
-1
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Collapsible "Subclassed by" list behavior.
3+
* Finds paragraphs starting with "Subclassed by" that have more than 5 items,
4+
* collapses them to a single line, and adds a "See All" / "Hide" toggle button.
5+
*
6+
* Breathe/Doxygen renders "Subclassed by" in a <p> tag. The subclass names may
7+
* be <a> links (when targets exist) or plain text (when they don't). We count
8+
* both to determine whether to collapse.
9+
*/
10+
document.addEventListener('DOMContentLoaded', function() {
11+
var paragraphs = document.querySelectorAll('p');
12+
13+
paragraphs.forEach(function(p) {
14+
var text = p.textContent.trim();
15+
if (!text.startsWith('Subclassed by')) return;
16+
17+
// Count items: use <a> links if present, otherwise count comma-separated entries
18+
var links = p.querySelectorAll('a');
19+
var itemCount = links.length;
20+
if (itemCount <= 5) {
21+
// Links may not exist (plain text subclass names). Count comma-separated items.
22+
var afterLabel = text.replace(/^Subclassed by\s*/, '');
23+
var commaCount = afterLabel.split(',').filter(function(s) { return s.trim().length > 0; }).length;
24+
if (commaCount > itemCount) {
25+
itemCount = commaCount;
26+
}
27+
}
28+
29+
if (itemCount > 5) {
30+
p.classList.add('subclassed-by-list', 'collapsed');
31+
32+
var toggle = document.createElement('button');
33+
toggle.className = 'subclassed-by-toggle';
34+
toggle.textContent = 'See All (' + itemCount + ')';
35+
toggle.type = 'button';
36+
37+
toggle.addEventListener('click', function(e) {
38+
e.preventDefault();
39+
40+
if (p.classList.contains('collapsed')) {
41+
p.classList.remove('collapsed');
42+
p.classList.add('expanded');
43+
toggle.textContent = 'Hide';
44+
} else {
45+
p.classList.remove('expanded');
46+
p.classList.add('collapsed');
47+
toggle.textContent = 'See All (' + itemCount + ')';
48+
}
49+
});
50+
51+
p.appendChild(toggle);
52+
}
53+
});
54+
});
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Collapsible "Subclassed by" list styles.
3+
* When a paragraph has more than 5 links, it collapses to a single line
4+
* with a "See All" button to expand the full list.
5+
* Main use case is C++ docs
6+
*/
7+
8+
/* Container for the subclassed-by list */
9+
.subclassed-by-list {
10+
position: relative;
11+
12+
/* Initially collapsed state - show only 1 line */
13+
&.collapsed {
14+
max-height: 1.6em;
15+
overflow: hidden;
16+
white-space: nowrap;
17+
text-overflow: ellipsis;
18+
padding-right: 140px; /* Space for the button */
19+
}
20+
21+
/* Expanded state */
22+
&.expanded {
23+
max-height: none;
24+
overflow: visible;
25+
white-space: normal;
26+
padding-right: 0;
27+
padding-bottom: 2em; /* Space for the button at the bottom */
28+
29+
.subclassed-by-toggle {
30+
position: absolute;
31+
top: auto;
32+
bottom: 0;
33+
right: 0;
34+
}
35+
}
36+
}
37+
38+
/* The "See All" / "Hide" toggle button */
39+
.subclassed-by-toggle {
40+
position: absolute;
41+
top: 0;
42+
right: 0;
43+
background-color: #f0f0f0;
44+
border: 1px solid #ccc;
45+
border-radius: 4px;
46+
padding: 2px 10px;
47+
color: #333;
48+
cursor: pointer;
49+
font-size: 0.85em;
50+
text-decoration: none;
51+
font-family: inherit;
52+
font-weight: 500;
53+
transition: background-color 0.2s, border-color 0.2s;
54+
55+
&:hover {
56+
background-color: #e0e0e0;
57+
border-color: #999;
58+
text-decoration: none;
59+
}
60+
}

pytorch_sphinx_theme2/static/scss/main.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
@use 'search';
1616
@use 'tippy';
1717
@use 'navbar_dropdown';
18+
@use 'collapsible_list';
1819

1920
// Import FontAwesome
2021
@use "@fortawesome/fontawesome-free/scss/fontawesome";

pytorch_sphinx_theme2/templates/layout.html

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,24 @@
208208
link.parentElement.classList.remove('active');
209209
});
210210

211-
// Add active class to the matching link
211+
// Add active class to the matching link and all its ancestor TOC items
212212
const matchingLink = tocNav.querySelector(`a[href="#${CSS.escape(targetId)}"]`);
213213
if (matchingLink) {
214214
matchingLink.classList.add('active');
215215
matchingLink.parentElement.classList.add('active');
216+
217+
// Walk up the DOM to activate parent TOC entries (e.g. h2 parent of h3)
218+
let ancestor = matchingLink.parentElement.parentElement;
219+
while (ancestor && ancestor !== tocNav) {
220+
if (ancestor.classList.contains('toc-entry')) {
221+
ancestor.classList.add('active');
222+
const parentLink = ancestor.querySelector(':scope > a.nav-link');
223+
if (parentLink) {
224+
parentLink.classList.add('active');
225+
}
226+
}
227+
ancestor = ancestor.parentElement;
228+
}
216229
}
217230

218231
// Use setTimeout to reset the guard after the current call stack

0 commit comments

Comments
 (0)