Commit bf63e8d5 authored by Jon Wayne Parrott's avatar Jon Wayne Parrott Committed by Ned Deily

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

parent 5da8cfb8
......@@ -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
......
......@@ -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:
......
......@@ -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
----------
......
......@@ -46,9 +46,13 @@ exclude_patterns = [venvdir+'/*', 'README.rst']
# -----------------------
# 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
......
@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;
}
[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
$(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);
});
$(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">&gt;&gt;&gt;</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');
}
});
});
This diff was suppressed by a .gitattributes entry.
/*
* 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>&laquo;</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);
});
{% 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">
&copy; <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 %}
Use the externalized ``python-docs-theme`` package when building the
documenation.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment