[Python-checkins] bpo-30607: Use external python-doc-theme (GH-2017)

Ned Deily webhook-mailer at python.org
Thu Mar 1 16:02:59 EST 2018


https://github.com/python/cpython/commit/bf63e8d55fd2853df3bb99d66de7f428107aadb3
commit: bf63e8d55fd2853df3bb99d66de7f428107aadb3
branch: master
author: Jon Wayne Parrott <jonwayne at google.com>
committer: Ned Deily <nad at python.org>
date: 2018-03-01T16:02:50-05:00
summary:

bpo-30607: Use external python-doc-theme (GH-2017)

files:
A Doc/tools/static/changelog_search.js
A Misc/NEWS.d/next/Documentation/2018-01-25-13-58-49.bpo-30607.4dXxiq.rst
D Doc/tools/pydoctheme/static/pydoctheme.css
D Doc/tools/pydoctheme/theme.conf
D Doc/tools/static/copybutton.js
D Doc/tools/static/py.png
D Doc/tools/static/sidebar.js
M .travis.yml
M Doc/Makefile
M Doc/README.rst
M Doc/conf.py
M Doc/tools/templates/layout.html

diff --git a/.travis.yml b/.travis.yml
index 292b9c687638..af3cdf54654d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -49,7 +49,8 @@ matrix:
         - cd Doc
         # Sphinx is pinned so that new versions that introduce new warnings won't suddenly cause build failures.
         # (Updating the version is fine as long as no warnings are raised by doing so.)
-        - python -m pip install sphinx~=1.6.1 blurb
+        # The theme used by the docs is stored seperately, so we need to install that as well.
+        - python -m pip install sphinx~=1.6.1 blurb python-docs-theme
       script:
         - make check suspicious html SPHINXOPTS="-q -W -j4"
     - os: osx
diff --git a/Doc/Makefile b/Doc/Makefile
index 307d1e0e7de1..042f960b93e7 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -123,7 +123,7 @@ clean:
 
 venv:
 	$(PYTHON) -m venv $(VENVDIR)
-	$(VENVDIR)/bin/python3 -m pip install -U Sphinx blurb
+	$(VENVDIR)/bin/python3 -m pip install -U Sphinx blurb python-docs-theme
 	@echo "The venv has been created in the $(VENVDIR) directory"
 
 dist:
diff --git a/Doc/README.rst b/Doc/README.rst
index a29d1f3a708a..b34916040eb9 100644
--- a/Doc/README.rst
+++ b/Doc/README.rst
@@ -20,11 +20,11 @@ tree but are maintained separately and are available from
 
 * `Sphinx <https://pypi.org/project/Sphinx/>`_
 * `blurb <https://pypi.org/project/blurb/>`_
+* `python-docs-theme <https://pypi.org/project/python-docs-theme/>`_
 
 The easiest way to install these tools is to create a virtual environment and
 install the tools into there.
 
-
 Using make
 ----------
 
diff --git a/Doc/conf.py b/Doc/conf.py
index 19a2f7d67ff8..d8efce035c9c 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -46,9 +46,13 @@
 # -----------------------
 
 # Use our custom theme.
-html_theme = 'pydoctheme'
+html_theme = 'python_docs_theme'
 html_theme_path = ['tools']
-html_theme_options = {'collapsiblesidebar': True}
+html_theme_options = {
+    'collapsiblesidebar': True,
+    'issues_url': 'https://docs.python.org/3/bugs.html',
+    'root_include_title': False   # We use the version switcher instead.
+}
 
 # Short title used e.g. for <title> HTML tags.
 html_short_title = '%s Documentation' % release
diff --git a/Doc/tools/pydoctheme/static/pydoctheme.css b/Doc/tools/pydoctheme/static/pydoctheme.css
deleted file mode 100644
index 1d5c18e5f623..000000000000
--- a/Doc/tools/pydoctheme/static/pydoctheme.css
+++ /dev/null
@@ -1,194 +0,0 @@
- at import url("default.css");
-
-body {
-    background-color: white;
-    margin-left: 1em;
-    margin-right: 1em;
-}
-
-div.related {
-    margin-bottom: 1.2em;
-    padding: 0.5em 0;
-    border-top: 1px solid #ccc;
-    margin-top: 0.5em;
-}
-
-div.related a:hover {
-    color: #0095C4;
-}
-
-div.related:first-child {
-    border-top: 0;
-    border-bottom: 1px solid #ccc;
-}
-
-.inline-search {
-    display: inline;
-}
-form.inline-search input {
-    display: inline;
-}
-form.inline-search input[type="submit"] {
-    width: 30px;
-}
-
-div.sphinxsidebar {
-    background-color: #eeeeee;
-    border-radius: 5px;
-    line-height: 130%;
-    font-size: smaller;
-}
-
-div.sphinxsidebar h3, div.sphinxsidebar h4 {
-    margin-top: 1.5em;
-}
-
-div.sphinxsidebarwrapper > h3:first-child {
-    margin-top: 0.2em;
-}
-
-div.sphinxsidebarwrapper > ul > li > ul > li {
-    margin-bottom: 0.4em;
-}
-
-div.sphinxsidebar a:hover {
-    color: #0095C4;
-}
-
-form.inline-search input,
-div.sphinxsidebar input {
-    font-family: 'Lucida Grande',Arial,sans-serif;
-    border: 1px solid #999999;
-    font-size: smaller;
-    border-radius: 3px;
-}
-
-div.sphinxsidebar input[type=text] {
-    max-width: 150px;
-}
-
-div.body {
-    padding: 0 0 0 1.2em;
-}
-
-div.body p {
-    line-height: 140%;
-}
-
-div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 {
-    margin: 0;
-    border: 0;
-    padding: 0.3em 0;
-}
-
-div.body hr {
-    border: 0;
-    background-color: #ccc;
-    height: 1px;
-}
-
-div.body pre {
-    border-radius: 3px;
-    border: 1px solid #ac9;
-}
-
-div.body div.admonition, div.body div.impl-detail {
-    border-radius: 3px;
-}
-
-div.body div.impl-detail > p {
-    margin: 0;
-}
-
-div.body div.seealso {
-    border: 1px solid #dddd66;
-}
-
-div.body a {
-    color: #0072aa;
-}
-
-div.body a:visited {
-    color: #6363bb;
-}
-
-div.body a:hover {
-    color: #00B0E4;
-}
-
-tt, code, pre {
-    font-family: monospace, sans-serif;
-    font-size: 96.5%;
-}
-
-div.body tt, div.body code {
-    border-radius: 3px;
-}
-
-div.body tt.descname, div.body code.descname {
-    font-size: 120%;
-}
-
-div.body tt.xref, div.body a tt, div.body code.xref, div.body a code {
-    font-weight: normal;
-}
-
-.deprecated {
-    border-radius: 3px;
-}
-
-table.docutils {
-    border: 1px solid #ddd;
-    min-width: 20%;
-    border-radius: 3px;
-    margin-top: 10px;
-    margin-bottom: 10px;
-}
-
-table.docutils td, table.docutils th {
-    border: 1px solid #ddd !important;
-    border-radius: 3px;
-}
-
-table p, table li {
-    text-align: left !important;
-}
-
-table.docutils th {
-    background-color: #eee;
-    padding: 0.3em 0.5em;
-}
-
-table.docutils td {
-    background-color: white;
-    padding: 0.3em 0.5em;
-}
-
-table.footnote, table.footnote td {
-    border: 0 !important;
-}
-
-div.footer {
-    line-height: 150%;
-    margin-top: -2em;
-    text-align: right;
-    width: auto;
-    margin-right: 10px;
-}
-
-div.footer a:hover {
-    color: #0095C4;
-}
-
-.refcount {
-    color: #060;
-}
-
-.stableabi {
-    color: #229;
-}
-
-.highlight {
-    background: none !important;
-}
-
diff --git a/Doc/tools/pydoctheme/theme.conf b/Doc/tools/pydoctheme/theme.conf
deleted file mode 100644
index 0c438816740e..000000000000
--- a/Doc/tools/pydoctheme/theme.conf
+++ /dev/null
@@ -1,23 +0,0 @@
-[theme]
-inherit = default
-stylesheet = pydoctheme.css
-pygments_style = sphinx
-
-[options]
-bodyfont = 'Lucida Grande', Arial, sans-serif
-headfont = 'Lucida Grande', Arial, sans-serif
-footerbgcolor = white
-footertextcolor = #555555
-relbarbgcolor = white
-relbartextcolor = #666666
-relbarlinkcolor = #444444
-sidebarbgcolor = white
-sidebartextcolor = #444444
-sidebarlinkcolor = #444444
-bgcolor = white
-textcolor = #222222
-linkcolor = #0090c0
-visitedlinkcolor = #00608f
-headtextcolor = #1a1a1a
-headbgcolor = white
-headlinkcolor = #aaaaaa
diff --git a/Doc/tools/static/changelog_search.js b/Doc/tools/static/changelog_search.js
new file mode 100644
index 000000000000..c881a9bd4c84
--- /dev/null
+++ b/Doc/tools/static/changelog_search.js
@@ -0,0 +1,53 @@
+$(document).ready(function() {
+    // add the search form and bind the events
+    $('h1').after([
+      '<p>Filter entries by content:',
+      '<input type="text" value="" id="searchbox" style="width: 50%">',
+      '<input type="submit" id="searchbox-submit" value="Filter"></p>'
+    ].join('\n'));
+
+    function dofilter() {
+        try {
+            var query = new RegExp($('#searchbox').val(), 'i');
+        }
+        catch (e) {
+            return; // not a valid regex (yet)
+        }
+        // find headers for the versions (What's new in Python X.Y.Z?)
+        $('#changelog h2').each(function(index1, h2) {
+            var h2_parent = $(h2).parent();
+            var sections_found = 0;
+            // find headers for the sections (Core, Library, etc.)
+            h2_parent.find('h3').each(function(index2, h3) {
+                var h3_parent = $(h3).parent();
+                var entries_found = 0;
+                // find all the entries
+                h3_parent.find('li').each(function(index3, li) {
+                    var li = $(li);
+                    // check if the query matches the entry
+                    if (query.test(li.text())) {
+                        li.show();
+                        entries_found++;
+                    }
+                    else {
+                        li.hide();
+                    }
+                });
+                // if there are entries, show the section, otherwise hide it
+                if (entries_found > 0) {
+                    h3_parent.show();
+                    sections_found++;
+                }
+                else {
+                    h3_parent.hide();
+                }
+            });
+            if (sections_found > 0)
+                h2_parent.show();
+            else
+                h2_parent.hide();
+        });
+    }
+    $('#searchbox').keyup(dofilter);
+    $('#searchbox-submit').click(dofilter);
+});
diff --git a/Doc/tools/static/copybutton.js b/Doc/tools/static/copybutton.js
deleted file mode 100644
index 716c9e472f4b..000000000000
--- a/Doc/tools/static/copybutton.js
+++ /dev/null
@@ -1,62 +0,0 @@
-$(document).ready(function() {
-    /* Add a [>>>] button on the top-right corner of code samples to hide
-     * the >>> and ... prompts and the output and thus make the code
-     * copyable. */
-    var div = $('.highlight-python .highlight,' +
-                '.highlight-python3 .highlight')
-    var pre = div.find('pre');
-
-    // get the styles from the current theme
-    pre.parent().parent().css('position', 'relative');
-    var hide_text = 'Hide the prompts and output';
-    var show_text = 'Show the prompts and output';
-    var border_width = pre.css('border-top-width');
-    var border_style = pre.css('border-top-style');
-    var border_color = pre.css('border-top-color');
-    var button_styles = {
-        'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0',
-        'border-color': border_color, 'border-style': border_style,
-        'border-width': border_width, 'color': border_color, 'text-size': '75%',
-        'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em',
-        'border-radius': '0 3px 0 0'
-    }
-
-    // create and add the button to all the code blocks that contain >>>
-    div.each(function(index) {
-        var jthis = $(this);
-        if (jthis.find('.gp').length > 0) {
-            var button = $('<span class="copybutton">>>></span>');
-            button.css(button_styles)
-            button.attr('title', hide_text);
-            button.data('hidden', 'false');
-            jthis.prepend(button);
-        }
-        // tracebacks (.gt) contain bare text elements that need to be
-        // wrapped in a span to work with .nextUntil() (see later)
-        jthis.find('pre:has(.gt)').contents().filter(function() {
-            return ((this.nodeType == 3) && (this.data.trim().length > 0));
-        }).wrap('<span>');
-    });
-
-    // define the behavior of the button when it's clicked
-    $('.copybutton').click(function(e){
-        e.preventDefault();
-        var button = $(this);
-        if (button.data('hidden') === 'false') {
-            // hide the code output
-            button.parent().find('.go, .gp, .gt').hide();
-            button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
-            button.css('text-decoration', 'line-through');
-            button.attr('title', show_text);
-            button.data('hidden', 'true');
-        } else {
-            // show the code output
-            button.parent().find('.go, .gp, .gt').show();
-            button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
-            button.css('text-decoration', 'none');
-            button.attr('title', hide_text);
-            button.data('hidden', 'false');
-        }
-    });
-});
-
diff --git a/Doc/tools/static/py.png b/Doc/tools/static/py.png
deleted file mode 100644
index 93e4a02c3d32..000000000000
Binary files a/Doc/tools/static/py.png and /dev/null differ
diff --git a/Doc/tools/static/sidebar.js b/Doc/tools/static/sidebar.js
deleted file mode 100644
index e8d58f4bfaac..000000000000
--- a/Doc/tools/static/sidebar.js
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * sidebar.js
- * ~~~~~~~~~~
- *
- * This script makes the Sphinx sidebar collapsible and implements intelligent
- * scrolling.
- *
- * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds in
- * .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to
- * collapse and expand the sidebar.
- *
- * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden and the
- * width of the sidebar and the margin-left of the document are decreased.
- * When the sidebar is expanded the opposite happens.  This script saves a
- * per-browser/per-session cookie used to remember the position of the sidebar
- * among the pages.  Once the browser is closed the cookie is deleted and the
- * position reset to the default (expanded).
- *
- * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-$(function() {
-  // global elements used by the functions.
-  // the 'sidebarbutton' element is defined as global after its
-  // creation, in the add_sidebar_button function
-  var jwindow = $(window);
-  var jdocument = $(document);
-  var bodywrapper = $('.bodywrapper');
-  var sidebar = $('.sphinxsidebar');
-  var sidebarwrapper = $('.sphinxsidebarwrapper');
-
-  // original margin-left of the bodywrapper and width of the sidebar
-  // with the sidebar expanded
-  var bw_margin_expanded = bodywrapper.css('margin-left');
-  var ssb_width_expanded = sidebar.width();
-
-  // margin-left of the bodywrapper and width of the sidebar
-  // with the sidebar collapsed
-  var bw_margin_collapsed = '.8em';
-  var ssb_width_collapsed = '.8em';
-
-  // colors used by the current theme
-  var dark_color = '#AAAAAA';
-  var light_color = '#CCCCCC';
-
-  function get_viewport_height() {
-    if (window.innerHeight)
-      return window.innerHeight;
-    else
-      return jwindow.height();
-  }
-
-  function sidebar_is_collapsed() {
-    return sidebarwrapper.is(':not(:visible)');
-  }
-
-  function toggle_sidebar() {
-    if (sidebar_is_collapsed())
-      expand_sidebar();
-    else
-      collapse_sidebar();
-    // adjust the scrolling of the sidebar
-    scroll_sidebar();
-  }
-
-  function collapse_sidebar() {
-    sidebarwrapper.hide();
-    sidebar.css('width', ssb_width_collapsed);
-    bodywrapper.css('margin-left', bw_margin_collapsed);
-    sidebarbutton.css({
-        'margin-left': '0',
-        'height': bodywrapper.height(),
-        'border-radius': '5px'
-    });
-    sidebarbutton.find('span').text('»');
-    sidebarbutton.attr('title', _('Expand sidebar'));
-    document.cookie = 'sidebar=collapsed';
-  }
-
-  function expand_sidebar() {
-    bodywrapper.css('margin-left', bw_margin_expanded);
-    sidebar.css('width', ssb_width_expanded);
-    sidebarwrapper.show();
-    sidebarbutton.css({
-        'margin-left': ssb_width_expanded-12,
-        'height': bodywrapper.height(),
-        'border-radius': '0 5px 5px 0'
-    });
-    sidebarbutton.find('span').text('«');
-    sidebarbutton.attr('title', _('Collapse sidebar'));
-    //sidebarwrapper.css({'padding-top':
-    //  Math.max(window.pageYOffset - sidebarwrapper.offset().top, 10)});
-    document.cookie = 'sidebar=expanded';
-  }
-
-  function add_sidebar_button() {
-    sidebarwrapper.css({
-        'float': 'left',
-        'margin-right': '0',
-        'width': ssb_width_expanded - 28
-    });
-    // create the button
-    sidebar.append(
-      '<div id="sidebarbutton"><span>«</span></div>'
-    );
-    var sidebarbutton = $('#sidebarbutton');
-    // find the height of the viewport to center the '<<' in the page
-    var viewport_height = get_viewport_height();
-    var sidebar_offset = sidebar.offset().top;
-    var sidebar_height = Math.max(bodywrapper.height(), sidebar.height());
-    sidebarbutton.find('span').css({
-        'display': 'block',
-        'position': 'fixed',
-        'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10
-    });
-
-    sidebarbutton.click(toggle_sidebar);
-    sidebarbutton.attr('title', _('Collapse sidebar'));
-    sidebarbutton.css({
-        'border-radius': '0 5px 5px 0',
-        'color': '#444444',
-        'background-color': '#CCCCCC',
-        'font-size': '1.2em',
-        'cursor': 'pointer',
-        'height': sidebar_height,
-        'padding-top': '1px',
-        'padding-left': '1px',
-        'margin-left': ssb_width_expanded - 12
-    });
-
-    sidebarbutton.hover(
-      function () {
-          $(this).css('background-color', dark_color);
-      },
-      function () {
-          $(this).css('background-color', light_color);
-      }
-    );
-  }
-
-  function set_position_from_cookie() {
-    if (!document.cookie)
-      return;
-    var items = document.cookie.split(';');
-    for(var k=0; k<items.length; k++) {
-      var key_val = items[k].split('=');
-      var key = key_val[0];
-      if (key == 'sidebar') {
-        var value = key_val[1];
-        if ((value == 'collapsed') && (!sidebar_is_collapsed()))
-          collapse_sidebar();
-        else if ((value == 'expanded') && (sidebar_is_collapsed()))
-          expand_sidebar();
-      }
-    }
-  }
-
-  add_sidebar_button();
-  var sidebarbutton = $('#sidebarbutton');
-  set_position_from_cookie();
-
-
-  /* intelligent scrolling */
-  function scroll_sidebar() {
-    var sidebar_height = sidebarwrapper.height();
-    var viewport_height = get_viewport_height();
-    var offset = sidebar.position()['top'];
-    var wintop = jwindow.scrollTop();
-    var winbot = wintop + viewport_height;
-    var curtop = sidebarwrapper.position()['top'];
-    var curbot = curtop + sidebar_height;
-    // does sidebar fit in window?
-    if (sidebar_height < viewport_height) {
-      // yes: easy case -- always keep at the top
-      sidebarwrapper.css('top', $u.min([$u.max([0, wintop - offset - 10]),
-                            jdocument.height() - sidebar_height - 200]));
-    }
-    else {
-      // no: only scroll if top/bottom edge of sidebar is at
-      // top/bottom edge of window
-      if (curtop > wintop && curbot > winbot) {
-        sidebarwrapper.css('top', $u.max([wintop - offset - 10, 0]));
-      }
-      else if (curtop < wintop && curbot < winbot) {
-        sidebarwrapper.css('top', $u.min([winbot - sidebar_height - offset - 20,
-                              jdocument.height() - sidebar_height - 200]));
-      }
-    }
-  }
-  jwindow.scroll(scroll_sidebar);
-});
diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html
index c2106678ac60..37811725d86b 100644
--- a/Doc/tools/templates/layout.html
+++ b/Doc/tools/templates/layout.html
@@ -1,118 +1,25 @@
 {% extends "!layout.html" %}
+
 {% block rootrellink %}
-        <li><img src="{{ pathto('_static/py.png', 1) }}" alt=""
-                 style="vertical-align: middle; margin-top: -1px"/></li>
-        <li><a href="https://www.python.org/">Python</a>{{ reldelim1 }}</li>
-        <li>
-          {%- if switchers is defined %}
-          <span class="language_switcher_placeholder">{{ language or 'en' }}</span>
-          <span class="version_switcher_placeholder">{{ release }}</span>
-          <a href="{{ pathto('index') }}">{% trans %}Documentation {% endtrans %}</a>{{ reldelim1 }}
-          {%- else %}
-          <a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}
-          {%- endif %}
-        </li>
-{% endblock %}
-{%- macro searchbox() %}
-{# modified from sphinx/themes/basic/searchbox.html #}
-    {%- if builder != "htmlhelp" %}
-    <div class="inline-search" style="display: none" role="search">
-        <form class="inline-search" action="{{ pathto('search') }}" method="get">
-          <input placeholder="{{ _('Quick search') }}" type="text" name="q" />
-          <input type="submit" value="{{ _('Go') }}" />
-          <input type="hidden" name="check_keywords" value="yes" />
-          <input type="hidden" name="area" value="default" />
-        </form>
-    </div>
-    <script type="text/javascript">$('.inline-search').show(0);</script>
-    {%- endif %}
-{%- endmacro %}
-{% block relbar1 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %}
-{% block relbar2 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %}
-{% block relbaritems %}
-    {%- if pagename != "search" and builder != "singlehtml" and builder != "htmlhelp" %}
-    <li class="right">
-        {{ searchbox() }}
-        {{ reldelim2 }}
+{{ super() }}
+    <li>
+      {%- if switchers is defined %}
+      <span class="language_switcher_placeholder">{{ language or 'en' }}</span>
+      <span class="version_switcher_placeholder">{{ release }}</span>
+      <a href="{{ pathto('index') }}">{% trans %}Documentation {% endtrans %}</a>{{ reldelim1 }}
+      {%- else %}
+      <a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}
+      {%- endif %}
     </li>
-    {%- endif %}
 {% endblock %}
+
 {% block extrahead %}
-    <link rel="shortcut icon" type="image/png" href="{{ pathto('_static/py.png', 1) }}" />
     <link rel="canonical" href="https://docs.python.org/3/{{pagename}}.html" />
     {% if builder != "htmlhelp" %}
-    {% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
-    {% if switchers is defined and not embedded %}<script type="text/javascript" src="{{ pathto('_static/switchers.js', 1) }}"></script>{% endif %}
-    {% if pagename == 'whatsnew/changelog' and not embedded %}
-    <script type="text/javascript">
-      $(document).ready(function() {
-          // add the search form and bind the events
-          $('h1').after([
-            '<p>Filter entries by content:',
-            '<input type="text" value="" id="searchbox" style="width: 50%">',
-            '<input type="submit" id="searchbox-submit" value="Filter"></p>'
-          ].join('\n'));
-
-          function dofilter() {
-              try {
-                  var query = new RegExp($('#searchbox').val(), 'i');
-              }
-              catch (e) {
-                  return; // not a valid regex (yet)
-              }
-              // find headers for the versions (What's new in Python X.Y.Z?)
-              $('#changelog h2').each(function(index1, h2) {
-                  var h2_parent = $(h2).parent();
-                  var sections_found = 0;
-                  // find headers for the sections (Core, Library, etc.)
-                  h2_parent.find('h3').each(function(index2, h3) {
-                      var h3_parent = $(h3).parent();
-                      var entries_found = 0;
-                      // find all the entries
-                      h3_parent.find('li').each(function(index3, li) {
-                          var li = $(li);
-                          // check if the query matches the entry
-                          if (query.test(li.text())) {
-                              li.show();
-                              entries_found++;
-                          }
-                          else {
-                              li.hide();
-                          }
-                      });
-                      // if there are entries, show the section, otherwise hide it
-                      if (entries_found > 0) {
-                          h3_parent.show();
-                          sections_found++;
-                      }
-                      else {
-                          h3_parent.hide();
-                      }
-                  });
-                  if (sections_found > 0)
-                      h2_parent.show();
-                  else
-                      h2_parent.hide();
-              });
-          }
-          $('#searchbox').keyup(dofilter);
-          $('#searchbox-submit').click(dofilter);
-      });
-    </script>
-    {% endif %}
+      {% if switchers is defined and not embedded %}
+      <script type="text/javascript" src="{{ pathto('_static/switchers.js', 1) }}"></script>{% endif %}
+      {% if pagename == 'whatsnew/changelog' and not embedded %}
+      <script type="text/javascript" src="{{ pathto('_static/changelog_search.js', 1) }}"></script>{% endif %}
     {% endif %}
 {{ super() }}
 {% endblock %}
-{% block footer %}
-    <div class="footer">
-    © <a href="{{ pathto('copyright') }}">{% trans %}Copyright{% endtrans %}</a> {{ copyright|e }}.
-    <br />
-    {% trans %}The Python Software Foundation is a non-profit corporation.{% endtrans %}
-    <a href="https://www.python.org/psf/donations/">{% trans %}Please donate.{% endtrans %}</a>
-    <br />
-    {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
-    {% trans pathto_bugs=pathto('bugs') %}<a href="{{ pathto_bugs }}">Found a bug</a>?{% endtrans %}
-    <br />
-    {% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
-    </div>
-{% endblock %}
diff --git a/Misc/NEWS.d/next/Documentation/2018-01-25-13-58-49.bpo-30607.4dXxiq.rst b/Misc/NEWS.d/next/Documentation/2018-01-25-13-58-49.bpo-30607.4dXxiq.rst
new file mode 100644
index 000000000000..8ff3b7887810
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2018-01-25-13-58-49.bpo-30607.4dXxiq.rst
@@ -0,0 +1,2 @@
+Use the externalized ``python-docs-theme`` package when building the
+documenation.



More information about the Python-checkins mailing list