Skip to content

DOC [PST] version switcher and warning banner #28347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
6 changes: 1 addition & 5 deletions build_tools/circle/build_doc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,13 @@ export OMP_NUM_THREADS=1
if [[ "$CIRCLE_BRANCH" =~ ^main$ && -z "$CI_PULL_REQUEST" ]]
then
# List available documentation versions if on main
python build_tools/circle/list_versions.py > doc/versions.rst
python build_tools/circle/list_versions.py --json doc/versions.json --rst doc/versions.rst
fi


# The pipefail is requested to propagate exit code
set -o pipefail && cd doc && make $make_args 2>&1 | tee ~/log.txt

# Insert the version warning for deployment
find _build/html/stable -name "*.html" | xargs sed -i '/<\/body>/ i \
\ <script src="https://scikit-learn.org/versionwarning.js"></script>'

cd -
set +o pipefail

Expand Down
62 changes: 43 additions & 19 deletions build_tools/circle/list_versions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#!/usr/bin/env python3

# List all available versions of the documentation
# Write the available versions page (--rst) and the version switcher JSON (--json).
# Version switcher see:
# https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/version-dropdown.html
# https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/announcements.html#announcement-banners

import argparse
import json
import re
import sys
Expand Down Expand Up @@ -52,14 +57,19 @@ def get_file_size(version):
return human_readable_data_quantity(path_details["size"], 1000)


print(":orphan:")
print()
heading = "Available documentation for Scikit-learn"
print(heading)
print("=" * len(heading))
print()
print("Web-based documentation is available for versions listed below:")
print()
parser = argparse.ArgumentParser()
parser.add_argument("--rst", type=str, required=True)
parser.add_argument("--json", type=str, required=True)
args = parser.parse_args()

heading = "Available documentation for scikit-learn"
json_content = []
rst_content = [
":orphan:\n",
heading,
"=" * len(heading) + "\n",
"Web-based documentation is available for versions listed below:\n",
]

ROOT_URL = (
"https://api.github.com/repos/scikit-learn/scikit-learn.github.io/contents/" # noqa
Expand Down Expand Up @@ -93,26 +103,40 @@ def get_file_size(version):

# Output in order: dev, stable, decreasing other version
seen = set()
for name in NAMED_DIRS + sorted(
(k for k in dirs if k[:1].isdigit()), key=parse_version, reverse=True
for i, name in enumerate(
NAMED_DIRS
+ sorted((k for k in dirs if k[:1].isdigit()), key=parse_version, reverse=True)
):
version_num, file_size = dirs[name]
if version_num in seen:
# symlink came first
continue
else:
seen.add(version_num)
name_display = "" if name[:1].isdigit() else " (%s)" % name
path = "https://scikit-learn.org/%s/" % name
out = "* `Scikit-learn %s%s documentation <%s>`_" % (
version_num,
name_display,
path,
)

full_name = f"{version_num}" if name[:1].isdigit() else f"{version_num} ({name})"
path = f"https://scikit-learn.org/{name}/"

# Update JSON for the version switcher; only keep the 8 latest versions to avoid
# overloading the version switcher dropdown
if i < 8:
info = {"name": full_name, "version": version_num, "url": path}
if name == "stable":
info["preferred"] = True
json_content.append(info)

# Printout for the historical version page
out = f"* `scikit-learn {full_name} documentation <{path}>`_"
if file_size is not None:
file_extension = get_file_extension(version_num)
out += (
f" (`{file_extension.upper()} {file_size} <{path}/"
f"_downloads/scikit-learn-docs.{file_extension}>`_)"
)
print(out)
rst_content.append(out)

with open(args.rst, "w", encoding="utf-8") as f:
f.write("\n".join(rst_content) + "\n")

with open(args.json_loc, "w", encoding="utf-8") as f:
json.dump(json_content, f, indent=2)
23 changes: 12 additions & 11 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,9 @@
# to be displayed, one adds "version-switcher" somewhere in the page layout. See
# https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/version-dropdown.html
"switcher": {
# TODO: Change to (maybe) https://scikit-learn.org/dev/_static/versions.json
# The current URL is hosted on my personal website, and is for testing purpose.
# My ideal logic is here: in CircleCI when running build_doc.sh we generate the
# versions.json file under doc/, and this file is added in html_extra_path to be
# copied into the build directory, uploaded somewhere under scikit-learn.org,
# and that "somewhere" is the "json_url" here.
"json_url": (
"https://charlie-xiao.github.io/assets/json/sklearn-versions-test.json"
),
# TODO: change to https://scikit-learn.org/dev/_static/versions.json before
# merging the new_web_theme branch into main
"json_url": "https://scikit-learn.org/_pst_preview/_static/versions.json",
"version_match": release,
},
# check_switcher may be set to False if docbuild pipeline fails. See
Expand Down Expand Up @@ -281,7 +275,7 @@
# Use :html_theme.sidebar_secondary.remove: for file-wide removal
"secondary_sidebar_items": {"**": ["page-toc", "sourcelink"]},
"show_version_warning_banner": True,
"announcement": [],
"announcement": None,
}

# Add any paths that contain custom themes here, relative to this directory.
Expand Down Expand Up @@ -316,8 +310,15 @@
# template names.
html_additional_pages = {"index": "index.html"}

# Additional files to copy
# versions.json is generated in build_tools/circle/build_doc.sh
html_extra_path = ["versions.json"]

# Additional JS files
html_js_files = ["scripts/details-permalink.js"]
html_js_files = [
"scripts/details-permalink.js",
"scripts/version-switcher.js",
]

# Compile scss files into css files using sphinxcontrib-sass
sass_src_dir, sass_out_dir = "scss", "css/styles"
Expand Down
1 change: 0 additions & 1 deletion doc/index.rst.template
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,3 @@
roadmap
Governance <governance>
about
Other Versions and Download <https://scikit-learn.org/dev/versions.html>
40 changes: 40 additions & 0 deletions doc/js/scripts/version-switcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Adds the link to available documentation page as the last entry in the version
* switcher dropdown. Since other entries in the dropdown are also added dynamically,
* we only add the link when the user clicks on some version switcher button to make
* sure that this entry is the last one.
*/

function addVersionSwitcherAvailDocsLink() {
var availDocsLinkAdded = false;

// There can be multiple version switcher buttons because there is at least one for
// laptop size and one for mobile size (in the sidebar)
document
.querySelectorAll(".version-switcher__button")
.forEach(function (btn) {
btn.addEventListener("click", function () {
if (!availDocsLinkAdded) {
// All version switcher dropdowns are updated once any button is clicked
document
.querySelectorAll(".version-switcher__menu")
.forEach(function (menu) {
var availDocsLink = document.createElement("a");
availDocsLink.setAttribute(
"href",
"https://scikit-learn.org/dev/versions.html"
);
availDocsLink.innerHTML = "More";
// We use the same class as the last entry to be safe
availDocsLink.className = menu.lastChild.className;
availDocsLink.classList.add("sk-avail-docs-link");
menu.appendChild(availDocsLink);
});
// Set the flag so we do not add again
availDocsLinkAdded = true;
}
});
});
}

document.addEventListener("DOMContentLoaded", addVersionSwitcherAvailDocsLink);
14 changes: 14 additions & 0 deletions doc/scss/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ code.literal {
border: 0;
}

/* Version switcher */

.version-switcher__menu a.list-group-item.sk-avail-docs-link {
display: flex;
align-items: center;

&:after {
content: var(--pst-icon-external-link);
font: var(--fa-font-solid);
font-size: 0.75rem;
margin-left: 0.5rem;
}
}

/* Primary sidebar */

.bd-sidebar-primary {
Expand Down