Skip to content

Commit 7b2de35

Browse files
committed
Add version switcher script and js
1 parent 1210e14 commit 7b2de35

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

docs/generate_versions_json.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python
2+
import argparse
3+
import json
4+
import os
5+
import re
6+
7+
8+
def version_key(name):
9+
"""Key function for sorting versions."""
10+
match = re.match(r'^(\d+)\.(\d+)\.(\d+)$', name)
11+
if match:
12+
# Sort by major, minor, patch
13+
return tuple(map(int, match.groups()))
14+
return ()
15+
16+
17+
# Mode: local or production
18+
parser = argparse.ArgumentParser(
19+
description='Generate versions.json for MPAS Analysis documentation.')
20+
parser.add_argument(
21+
'--local',
22+
action='store_true',
23+
help='Generate versions.json for local build.'
24+
)
25+
args = parser.parse_args()
26+
local = args.local
27+
base_dir = '_build/html' if local else 'gh-pages'
28+
shared_dir = os.path.join(base_dir, 'shared')
29+
30+
entries = []
31+
32+
if not os.path.exists(base_dir) or not os.listdir(base_dir):
33+
raise FileNotFoundError(
34+
f"Base directory '{base_dir}' does not exist or is empty.")
35+
36+
versions = os.listdir(base_dir)
37+
numeric_versions = []
38+
non_numeric_versions = []
39+
40+
for version in versions:
41+
# Check if it matches version pattern
42+
if re.match(r'^\d+\.\d+\.\d+$', version):
43+
numeric_versions.append(version)
44+
else:
45+
non_numeric_versions.append(version)
46+
47+
# Sort numeric versions by major, minor, patch in descending order
48+
numeric_versions.sort(key=version_key, reverse=True)
49+
# Sort non-numeric versions alphabetically
50+
non_numeric_versions.sort()
51+
52+
# Combine the sorted lists
53+
versions = non_numeric_versions + numeric_versions
54+
55+
if 'main' in versions:
56+
versions.insert(0, versions.pop(versions.index('main')))
57+
58+
for name in versions:
59+
path = os.path.join(base_dir, name)
60+
if os.path.isdir(path) and name not in ('shared', '.git'):
61+
entries.append({
62+
'version': name,
63+
'url': f'../{name}/' if local else f'/mpas_analysis/{name}/'
64+
})
65+
66+
os.makedirs(shared_dir, exist_ok=True)
67+
with open(os.path.join(shared_dir, 'versions.json'), 'w') as f:
68+
json.dump(entries, f, indent=2)
69+

docs/version-switcher.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
(async function () {
2+
const container = document.getElementById("version-switcher");
3+
if (!container) return;
4+
5+
const metaVersion = document.querySelector('meta[name="doc-version"]');
6+
const currentVersion = metaVersion ? metaVersion.content : "unknown";
7+
console.log("Detected current version:", currentVersion);
8+
9+
async function fetchVersions() {
10+
try {
11+
const scriptUrl = document.currentScript.src;
12+
const basePath = scriptUrl.substring(0, scriptUrl.lastIndexOf('/') + 1);
13+
const versionsUrl = basePath + "versions.json";
14+
15+
const res = await fetch(versionsUrl);
16+
if (!res.ok) throw new Error(`Failed to load ${versionsUrl}`);
17+
return await res.json();
18+
} catch (err) {
19+
console.error("Could not load versions.json:", err);
20+
return [];
21+
}
22+
}
23+
24+
const versions = await fetchVersions();
25+
if (!versions.length) return;
26+
27+
const select = document.createElement("select");
28+
select.style.marginLeft = "1em";
29+
select.onchange = () => {
30+
window.location.href = select.value;
31+
};
32+
33+
versions.forEach(({ version, url }) => {
34+
const option = document.createElement("option");
35+
option.value = url;
36+
option.textContent = version;
37+
if (version === currentVersion) {
38+
option.selected = true;
39+
}
40+
select.appendChild(option);
41+
});
42+
43+
const label = document.createElement("label");
44+
label.textContent = "Version: ";
45+
label.style.color = "white";
46+
label.appendChild(select);
47+
container.appendChild(label);
48+
})();

0 commit comments

Comments
 (0)