Skip to content

Commit ebe4c7e

Browse files
DOC add permalink to summary of collapsed details section (scikit-learn#27409)
Co-authored-by: Arturo Amor <86408019+ArturoAmorQ@users.noreply.github.com>
1 parent e3d67d5 commit ebe4c7e

File tree

5 files changed

+66
-2
lines changed

5 files changed

+66
-2
lines changed

doc/conf.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,15 +312,18 @@
312312
html_show_search_summary = False
313313

314314

315+
# The "summary-anchor" IDs will be overwritten via JavaScript to be unique.
316+
# See `doc/theme/scikit-learn-modern/static/js/details-permalink.js`.
315317
rst_prolog = """
316318
.. |details-start| raw:: html
317319
318-
<details>
320+
<details id="summary-anchor">
319321
<summary class="btn btn-light">
320322
321323
.. |details-split| raw:: html
322324
323325
<span class="tooltiptext">Click for more details</span>
326+
<a class="headerlink" href="#summary-anchor" title="Permalink to this heading">¶</a>
324327
</summary>
325328
<div class="card">
326329

doc/modules/grid_search.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ Here, ``<estimator>`` is the parameter name of the nested estimator,
612612
in this case ``estimator``.
613613
If the meta-estimator is constructed as a collection of estimators as in
614614
`pipeline.Pipeline`, then ``<estimator>`` refers to the name of the estimator,
615-
see :ref:`pipeline_nested_parameters`. In practice, there can be several
615+
see :ref:`pipeline_nested_parameters`. In practice, there can be several
616616
levels of nesting::
617617

618618
>>> from sklearn.pipeline import Pipeline

doc/themes/scikit-learn-modern/layout.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
<link rel="stylesheet" href="{{ pathto('_static/' + styles[0], 1) }}" type="text/css" />
3737
<script id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
3838
<script src="{{ pathto('_static/js/vendor/jquery-3.6.3.slim.min.js', 1) }}"></script>
39+
<script src="{{ pathto('_static/js/details-permalink.js', 1) }}"></script>
3940
{%- block extrahead %} {% endblock %}
4041
</head>
4142
<body>

doc/themes/scikit-learn-modern/static/css/theme.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,15 @@ div.clearer {
149149

150150
/* details / summary */
151151

152+
/* Enables section links to be visible when anchor-linked */
153+
div.sk-page-content details::before {
154+
display: block;
155+
height: 52px;
156+
margin-top: -52px;
157+
visibility: hidden;
158+
content: "";
159+
}
160+
152161
div.sk-page-content details {
153162
margin: 4ex 0pt;
154163
}
@@ -202,6 +211,10 @@ div.sk-page-content summary:hover .tooltiptext {
202211
visibility: visible;
203212
}
204213

214+
div.sk-page-content summary:hover .headerlink {
215+
visibility: visible;
216+
}
217+
205218
/* Button */
206219

207220
.sk-btn-primary {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Function to create permalink into <details> elements to be able to link them
2+
// The assumption is that such a block will be defined as follows:
3+
// <details id="summary-anchor">
4+
// <summary class="btn btn-light">
5+
// Some title
6+
// <span class="tooltiptext">Click for more details</span>
7+
// <a class="headerlink" href="#summary-anchor" title="Permalink to this heading">¶</a>
8+
// </summary>
9+
// <div class="card">
10+
// Some details
11+
// </div>
12+
// </details>
13+
// We seek to replace `#summary-anchor` with a unique identifier based on the
14+
// summary text.
15+
// This syntax is defined in `doc/conf.py` in the `rst_prolog` variable.
16+
function updateIdAndHrefBasedOnSummaryText() {
17+
var allDetailsElements = document.querySelectorAll('details');
18+
// Counter to store the duplicated summary text to add it as a suffix in the
19+
// anchor ID
20+
var anchorIDCounters = {};
21+
22+
allDetailsElements.forEach(function (detailsElement) {
23+
// Get the <summary> element within the current <details>
24+
var summaryElement = detailsElement.querySelector('summary');
25+
26+
// The ID uses the first line, lowercased, and spaces replaced with dashes
27+
var anchorID = summaryElement.textContent.trim().split("\n")[0].replace(/\s+/g, '-').toLowerCase();
28+
29+
// Suffix the anchor ID with a counter if it already exists
30+
if (anchorIDCounters[anchorID]) {
31+
anchorIDCounters[anchorID] += 1;
32+
anchorID = anchorID + '-' + anchorIDCounters[anchorID];
33+
} else {
34+
anchorIDCounters[anchorID] = 1;
35+
}
36+
37+
detailsElement.setAttribute('id', anchorID);
38+
39+
var anchorElement = summaryElement.querySelector('a.headerlink');
40+
anchorElement.setAttribute('href', '#' + anchorID);
41+
});
42+
}
43+
44+
// Add an event listener to execute the function when the page is loaded
45+
document.addEventListener('DOMContentLoaded', function () {
46+
updateIdAndHrefBasedOnSummaryText();
47+
});

0 commit comments

Comments
 (0)