Skip to content

Commit

Permalink
Deduplicate version and language switchers informations.
Browse files Browse the repository at this point in the history
  • Loading branch information
JulienPalard committed Jun 6, 2020
1 parent 037a41e commit dd65c34
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 53 deletions.
76 changes: 55 additions & 21 deletions build_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"""

from bisect import bisect_left as bisect
from collections import namedtuple
from collections import namedtuple, OrderedDict
from contextlib import contextmanager, suppress
import filecmp
import json
Expand Down Expand Up @@ -197,6 +197,14 @@ def git_clone(repository, directory, branch=None):
shell_out(["git", "-C", directory, "checkout", branch])


def version_to_tuple(version):
return tuple(int(part) for part in version.split("."))


def tuple_to_version(version_tuple):
return ".".join(str(part) for part in version_tuple)


def locate_nearest_version(available_versions, target_version):
"""Look for the nearest version of target_version in available_versions.
Versions are to be given as tuples, like (3, 7) for 3.7.
Expand All @@ -213,12 +221,6 @@ def locate_nearest_version(available_versions, target_version):
'3.7'
"""

def version_to_tuple(version):
return tuple(int(part) for part in version.split("."))

def tuple_to_version(version_tuple):
return ".".join(str(part) for part in version_tuple)

available_versions_tuples = sorted(
[
version_to_tuple(available_version)
Expand Down Expand Up @@ -267,6 +269,14 @@ def edit(file):
os.rename(temporary, file)


def picker_label(version):
if version.status == "in development":
return "dev ({})".format(version.name)
if version.status == "pre-release":
return "pre ({})".format(version.name)
return version.name


def setup_switchers(html_root):
"""Setup cross-links between cpython versions:
- Cross-link various languages in a language switcher
Expand All @@ -281,18 +291,36 @@ def setup_switchers(html_root):
template.safe_substitute(
{
"LANGUAGES": json.dumps(
{
language.tag: language.name
for language in LANGUAGES
if language.in_prod
}
)
OrderedDict(
sorted(
[
(language.tag, language.name)
for language in LANGUAGES
if language.in_prod
]
)
)
),
"VERSIONS": json.dumps(
OrderedDict(
[
(version.name, picker_label(version))
for version in sorted(
VERSIONS,
key=lambda v: version_to_tuple(v.name),
reverse=True,
)
]
)
),
}
)
)
for file in Path(html_root).glob("**/*.html"):
depth = len(file.relative_to(html_root).parts) - 1
script = f""" <script type="text/javascript" src="{'../' * depth}_static/switchers.js"></script>\n"""
script = """ <script type="text/javascript" src="{}_static/switchers.js"></script>\n""".format(
"../" * depth
)
with edit(file) as (i, o):
for line in i:
if line == script:
Expand Down Expand Up @@ -385,13 +413,13 @@ def copy_build_to_webroot(
"""Copy a given build to the appropriate webroot with appropriate rights.
"""
logging.info(
"Publishing start for version: %s, language: %s", version, language.tag
"Publishing start for version: %s, language: %s", version.name, language.tag
)
checkout = os.path.join(
build_root, version, "cpython-{lang}".format(lang=language.tag)
build_root, version.name, "cpython-{lang}".format(lang=language.tag)
)
if language.tag == "en":
target = os.path.join(www_root, version)
target = os.path.join(www_root, version.name)
else:
language_dir = os.path.join(www_root, language.tag)
os.makedirs(language_dir, exist_ok=True)
Expand All @@ -400,7 +428,7 @@ def copy_build_to_webroot(
except subprocess.CalledProcessError as err:
logging.warning("Can't change group of %s: %s", language_dir, str(err))
os.chmod(language_dir, 0o775)
target = os.path.join(language_dir, version)
target = os.path.join(language_dir, version.name)

os.makedirs(target, exist_ok=True)
try:
Expand Down Expand Up @@ -475,7 +503,9 @@ def copy_build_to_webroot(
shell_out(
["curl", "-XPURGE", "https://docs.python.org/{%s}" % ",".join(to_purge)]
)
logging.info("Publishing done for version: %s, language: %s", version, language.tag)
logging.info(
"Publishing done for version: %s, language: %s", version.name, language.tag
)


def head(lines, n=10):
Expand All @@ -491,7 +521,7 @@ def version_info():
subprocess.check_output(["xelatex", "--version"], universal_newlines=True), n=2
)
print(
f"""build_docs: {VERSION}
"""build_docs: {VERSION}
# platex
Expand All @@ -501,7 +531,11 @@ def version_info():
# xelatex
{xelatex_version}
"""
""".format(
VERSION=VERSION,
platex_version=platex_version,
xelatex_version=xelatex_version,
)
)


Expand Down
66 changes: 34 additions & 32 deletions switchers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
(function() {
'use strict';

if (!String.prototype.startsWith) {
Object.defineProperty(String.prototype, 'startsWith', {
value: function(search, rawPos) {
var pos = rawPos > 0 ? rawPos|0 : 0;
return this.substring(pos, pos + search.length) === search;
}
});
}

// Parses versions in URL segments like:
// "3", "dev", "release/2.7" or "3.6rc2"
var version_regexs = [
Expand All @@ -9,27 +18,22 @@
'(?:dev)',
'(?:release/\\d.\\d[\\x\\d\\.]*)'];

var all_versions = {
'3.10': 'dev (3.10)',
'3.9': 'pre (3.9)',
'3.8': '3.8',
'3.7': '3.7',
'3.6': '3.6',
'3.5': '3.5',
'2.7': '2.7',
};

var all_versions = $VERSIONS;
var all_languages = $LANGUAGES;

function build_version_select(current_version, current_release) {
function quote_attr(str) {
return '"' + str.replace('"', '\\"') + '"';
}

function build_version_select(release) {
var buf = ['<select>'];
var major_minor = release.split(".").slice(0, 2).join(".");

$.each(all_versions, function(version, title) {
buf.push('<option value="' + version + '"');
if (version == current_version)
buf.push(' selected="selected">' + current_release + '</option>');
if (version == major_minor)
buf.push('<option value=' + quote_attr(version) + ' selected="selected">' + release + '</option>');
else
buf.push('>' + title + '</option>');
buf.push('<option value=' + quote_attr(version) + '>' + title + '</option>');
});

buf.push('</select>');
Expand Down Expand Up @@ -59,7 +63,7 @@
function navigate_to_first_existing(urls) {
// Navigate to the first existing URL in urls.
var url = urls.shift();
if (urls.length == 0) {
if (urls.length == 0 || url.startsWith("file:///")) {
window.location.href = url;
return;
}
Expand All @@ -79,16 +83,16 @@
var url = window.location.href;
var current_language = language_segment_from_url(url);
var current_version = version_segment_in_url(url);
var new_url = url.replace('.org/' + current_language + current_version,
'.org/' + current_language + selected_version);
var new_url = url.replace('/' + current_language + current_version,
'/' + current_language + selected_version);
if (new_url != url) {
navigate_to_first_existing([
new_url,
url.replace('.org/' + current_language + current_version,
'.org/' + selected_version),
'https://docs.python.org/' + current_language + selected_version,
'https://docs.python.org/' + selected_version,
'https://docs.python.org/'
url.replace('/' + current_language + current_version,
'/' + selected_version),
'/' + current_language + selected_version,
'/' + selected_version,
'/'
]);
}
}
Expand All @@ -100,20 +104,20 @@
var current_version = version_segment_in_url(url);
if (selected_language == 'en/') // Special 'default' case for english.
selected_language = '';
var new_url = url.replace('.org/' + current_language + current_version,
'.org/' + selected_language + current_version);
var new_url = url.replace('/' + current_language + current_version,
'/' + selected_language + current_version);
if (new_url != url) {
navigate_to_first_existing([
new_url,
'https://docs.python.org/'
'/'
]);
}
}

// Returns the path segment of the language as a string, like 'fr/'
// or '' if not found.
function language_segment_from_url(url) {
var language_regexp = '\.org/([a-z]{2}(?:-[a-z]{2})?/)';
var language_regexp = '/((?:' + Object.keys(all_languages).join("|") + ')/)'
var match = url.match(language_regexp);
if (match !== null)
return match[1];
Expand All @@ -123,9 +127,9 @@
// Returns the path segment of the version as a string, like '3.6/'
// or '' if not found.
function version_segment_in_url(url) {
var language_segment = '(?:[a-z]{2}(?:-[a-z]{2})?/)';
var language_segment = language_segment_from_url(url);
var version_segment = '(?:(?:' + version_regexs.join('|') + ')/)';
var version_regexp = '\\.org/' + language_segment + '?(' + version_segment + ')';
var version_regexp = language_segment + '(' + version_segment + ')';
var match = url.match(version_regexp);
if (match !== null)
return match[1];
Expand All @@ -141,11 +145,9 @@
}

$(document).ready(function() {
var release = DOCUMENTATION_OPTIONS.VERSION;
var language_segment = language_segment_from_url(window.location.href);
var current_language = language_segment.replace(/\/+$/g, '') || 'en';
var version = release.substr(0, 3);
var version_select = build_version_select(version, release);
var version_select = build_version_select(DOCUMENTATION_OPTIONS.VERSION);

create_placeholders_if_missing();
$('.version_switcher_placeholder').html(version_select);
Expand Down

0 comments on commit dd65c34

Please sign in to comment.