Skip to content

Commit 67842d7

Browse files
committed
categorize specific SDR chapters into a collapsible, expanded by default for now
1 parent 7a46022 commit 67842d7

3 files changed

Lines changed: 118 additions & 1 deletion

File tree

_static/custom.css

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,33 @@ pre.mermaid > svg,
295295
}
296296

297297
/* End of PhasedArrayVisualizer part */
298+
299+
/* Collapsible "Specific SDRs" sidebar group (see js/sidebar_groups.js) */
300+
.sphinxsidebar .sdr-group-toggle {
301+
cursor: pointer;
302+
display: inline-block;
303+
user-select: none;
304+
}
305+
.sphinxsidebar .sdr-caret {
306+
display: inline-block;
307+
width: 0;
308+
height: 0;
309+
margin-right: 6px;
310+
border-left: 5px solid currentColor;
311+
border-top: 4px solid transparent;
312+
border-bottom: 4px solid transparent;
313+
vertical-align: middle;
314+
transition: transform 0.15s ease;
315+
}
316+
.sphinxsidebar .sdr-group.open .sdr-caret {
317+
transform: rotate(90deg);
318+
}
319+
.sphinxsidebar .sdr-group-children {
320+
display: none;
321+
list-style: none;
322+
margin: 0;
323+
padding-left: 15px;
324+
}
325+
.sphinxsidebar .sdr-group.open .sdr-group-children {
326+
display: block;
327+
}

_static/js/sidebar_groups.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Groups the hardware SDRs chapters into a collapsible section in the left sidebar
2+
// Expanded by default; the reader can expand/collapse in place without navigating away
3+
// State is remembered across pages via localStorage.
4+
(function () {
5+
var GROUP_LABEL = 'Specific SDR Hardware';
6+
var FILES = ['pluto.html', 'usrp.html', 'bladerf.html', 'rtlsdr.html', 'hackrf.html'];
7+
8+
function fileName(url) {
9+
return (url || '').split('#')[0].split('?')[0].split('/').pop();
10+
}
11+
12+
function init() {
13+
var sidebar = document.querySelector('.sphinxsidebarwrapper') || document.body;
14+
15+
// Collect the SDR chapter <li> items, keeping the order in FILES.
16+
var byFile = {};
17+
sidebar.querySelectorAll('li.toctree-l1 > a[href]').forEach(function (a) {
18+
var f = fileName(a.getAttribute('href'));
19+
if (FILES.indexOf(f) !== -1) byFile[f] = a.parentElement;
20+
});
21+
22+
// The chapter you're currently on is rendered as the "current" item with an
23+
// href of "#" (plus a nested list of its sections), so it needs its own
24+
// lookup rather than matching by filename.
25+
var currentFile = fileName(window.location.pathname);
26+
if (FILES.indexOf(currentFile) !== -1) {
27+
var currentLi = sidebar.querySelector('li.toctree-l1.current');
28+
if (currentLi) byFile[currentFile] = currentLi;
29+
}
30+
31+
var lis = [];
32+
FILES.forEach(function (f) { if (byFile[f]) lis.push(byFile[f]); });
33+
if (!lis.length) return;
34+
35+
var firstLi = lis[0];
36+
var parentUl = firstLi.parentElement;
37+
38+
// Build the collapsible group header and its (initially empty) child list.
39+
var groupLi = document.createElement('li');
40+
groupLi.className = 'toctree-l1 sdr-group';
41+
42+
var toggle = document.createElement('a');
43+
toggle.href = '#';
44+
toggle.className = 'sdr-group-toggle';
45+
toggle.setAttribute('role', 'button');
46+
toggle.innerHTML = '<span class="sdr-caret"></span>' + GROUP_LABEL;
47+
48+
var childUl = document.createElement('ul');
49+
childUl.className = 'sdr-group-children';
50+
51+
groupLi.appendChild(toggle);
52+
groupLi.appendChild(childUl);
53+
parentUl.insertBefore(groupLi, firstLi);
54+
55+
// Keep them as toctree-l1 so they retain the full-size chapter text;
56+
// indentation under the group is handled by .sdr-group-children CSS.
57+
lis.forEach(function (li) {
58+
childUl.appendChild(li);
59+
});
60+
61+
function setOpen(open) {
62+
groupLi.classList.toggle('open', open);
63+
toggle.setAttribute('aria-expanded', open ? 'true' : 'false');
64+
}
65+
66+
// Expanded by default. Stay open unless the reader explicitly collapsed it
67+
// last time (stored === '0'); always open when on one of these pages.
68+
var onSdrPage = FILES.indexOf(currentFile) !== -1;
69+
var stored = null;
70+
try { stored = window.localStorage.getItem('sdrGroupOpen'); } catch (e) {}
71+
setOpen(onSdrPage || stored !== '0');
72+
73+
toggle.addEventListener('click', function (e) {
74+
e.preventDefault();
75+
var open = !groupLi.classList.contains('open');
76+
setOpen(open);
77+
try { window.localStorage.setItem('sdrGroupOpen', open ? '1' : '0'); } catch (e2) {}
78+
});
79+
}
80+
81+
if (document.readyState === 'loading') {
82+
document.addEventListener('DOMContentLoaded', init);
83+
} else {
84+
init();
85+
}
86+
})();

conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ def setup(app):
202202
'js/FFT.js',
203203
'js/cyclostationary_app.js',
204204
'js/homepage_app.js',
205-
'js/tdoa.js'
205+
'js/tdoa.js',
206+
'js/sidebar_groups.js'
206207
# we also include the index.js file from the PhasedArrayVisualizer directory in setup() above
207208
]
208209

0 commit comments

Comments
 (0)