Skip to content
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

Sync jinja sphinx theme templates from qiskit metapackage #49

Merged
merged 1 commit into from
Aug 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions qiskit_sphinx_theme/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
</li>

<li>
<a href="{{ theme_variables.external_urls['partners'] }}" target="_blank">Qiskit Providers</a>
<a href="{{ theme_variables.external_urls['partners'] }}" target="_blank">Partners</a>
</li>

<li>
Expand Down Expand Up @@ -127,7 +127,9 @@
</a>
</div>
</li>

<li>
<a href="{{ theme_variables.external_urls['experiments'] }}" target="_blank">Experiments</a>
</li>
<li>
<div id="resourcesDropdownButton" data-toggle="resources-dropdown" class="resources-dropdown">
<a class="resource-option with-down-orange-arrow">
Expand All @@ -149,7 +151,7 @@
</div>
</li>
<li>
<a href="{{ theme_variables.external_urls['github'] }}" target="_blank">Github</a>
<a href="{{ theme_variables.external_urls['github'] }}" target="_blank">GitHub</a>
</li>
</ul>
</div>
Expand All @@ -166,7 +168,6 @@
{% block extrabody %} {% endblock %}

{# SIDE NAV, TOGGLES ON MOBILE #}

{% include "versions.html" %}

<div class="table-of-contents-link-wrapper">
Expand Down Expand Up @@ -215,6 +216,7 @@
<div class="local-toc">{{ toc }}</div>
{% endif %}
{% endblock %}
{% include "stable_versions.html" %}
</div>
</div>
</nav>
Expand Down Expand Up @@ -331,7 +333,7 @@
<a href="{{ pathto('tutorials') }}">Tutorials</a>
</li>
<li>
<a href="{{ theme_variables.external_urls['partners'] }}">Qiskit Providers</a>
<a href="{{ theme_variables.external_urls['partners'] }}">Partners</a>
</li>
<br>
<li class="resources-mobile-menu-title">
Expand All @@ -354,9 +356,11 @@
<a href="{{ theme_variables.external_urls['optim'] }}">Optimization</a>
</li>
</ul>

<br>

<li>
<a href="{{ theme_variables.external_urls['experiments'] }}">Experiments</a>
</li>
<br>
<li class="resources-mobile-menu-title">
Resources
</li>
Expand Down
8 changes: 8 additions & 0 deletions qiskit_sphinx_theme/stable_versions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div>
<dl>
<dt>Previous Releases</dt>
{% for version in version_list | sort(reverse=True) %}
<dd><a class="version" href="/documentation/stable/{{ version }}/index.html">{{ version }}</a></dd>
{% endfor %}
</dl>
</div>
59 changes: 23 additions & 36 deletions qiskit_sphinx_theme/versions.html
Original file line number Diff line number Diff line change
@@ -1,37 +1,24 @@
{% if READTHEDOCS %}
{# Add rst-badge after rst-versions for small badge style. #}
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book"> Read the Docs</span>
v: {{ current_version }}
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
<dl>
<dt>{{ _('Versions') }}</dt>
{% for slug, url in versions %}
<dd><a href="{{ url }}">{{ slug }}</a></dd>
{% endfor %}
</dl>
<dl>
<dt>{{ _('Downloads') }}</dt>
{% for type, url in downloads %}
<dd><a href="{{ url }}">{{ type }}</a></dd>
{% endfor %}
</dl>
<dl>
<dt>{{ _('On Read the Docs') }}</dt>
<dd>
<a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}">{{ _('Project Home') }}</a>
</dd>
<dd>
<a href="//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}">{{ _('Builds') }}</a>
</dd>
</dl>
<hr/>
{% trans %}Free document hosting provided by <a href="http://www.readthedocs.org">Read the Docs</a>.{% endtrans %}

</div>
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="rst-current-version-label">{{ language_label }}</span>
<span class="rst-versions-dropdown-icon"></span>
</span>
<div class="rst-other-versions">
{% if translations %}
<dl>
<dt>{{ _('Languages') }}</dt>
{% for code, language in translations_list %}
<dd><a class="version" href="{{ translation_url(code, pagename) }}">{{ language }}</a></dd>
{% endfor %}
</dl>
{% endif %}
</div>
{% endif %}

<script>
jQuery('.version').click((evt) => {
const hash = window.location.hash
const complete_url = evt.target.href + hash
window.location = complete_url
evt.preventDefault()
})
</script>
</div>
247 changes: 247 additions & 0 deletions qiskit_sphinx_theme/versionutils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2018.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

import os
import re
import subprocess
import tempfile
from functools import partial

from docutils import nodes
from docutils.parsers.rst.directives.tables import Table
from docutils.parsers.rst import Directive, directives
from sphinx.util import logging


logger = logging.getLogger(__name__)

translations_list = [
('en', 'English'),
('bn_BN', 'Bengali'),
('fr_FR', 'French'),
('de_DE', 'German'),
('ja_JP', 'Japanese'),
('ko_KR', 'Korean'),
('pt_UN', 'Portuguese'),
('es_UN', 'Spanish'),
('ta_IN', 'Tamil'),
]

default_language = 'en'


def setup(app):
app.connect('config-inited', _extend_html_context)
app.add_config_value('content_prefix', '', '')
app.add_config_value('translations', True, 'html')
app.add_directive('version-history', _VersionHistory)


def _extend_html_context(app, config):
context = config.html_context
context['translations'] = config.translations
context['translations_list'] = translations_list
context['version_list'] = _get_version_list()
context['current_translation'] = _get_current_translation(config) or config.language
context['translation_url'] = partial(_get_translation_url, config)
context['version_label'] = _get_version_label(config)
context['language_label'] = _get_language_label(config)


def _get_current_translation(config):
language = config.language or default_language
try:
found = next(v for k, v in translations_list if k == language)
except StopIteration:
found = None
return found


def _get_translation_url(config, code, pagename):
base = '/locale/%s' % code if code and code != default_language else ''
return _get_url(config, base, pagename)


def _get_version_label(config):
proc = subprocess.run(
['git', 'describe', '--abbrev=0', '--tags', 'HEAD'],
encoding='utf8', capture_output=True)
return proc.stdout

def _get_language_label(config):
return '%s' % (_get_current_translation(config) or config.language,)



def _get_version_list():
start_version = (0, 24, 0)
proc = subprocess.run(['git', 'describe', '--abbrev=0'],
capture_output=True)
proc.check_returncode()
current_version = proc.stdout.decode('utf8')
current_version_info = current_version.split('.')
if current_version_info[0] == '0':
version_list = [
'0.%s' % x for x in range(start_version[1],
int(current_version_info[1]) + 1)]
else:
#TODO: When 1.0.0 add code to handle 0.x version list
version_list = []
pass
# Prepend version 0.19 which was built and uploaded manually:
version_list.insert(0, '0.19')
return version_list


def _get_url(config, base, pagename):
return _add_content_prefix(config, '%s/%s.html' % (base, pagename))


def _add_content_prefix(config, url):
prefix = ''
if config.content_prefix:
prefix = '/%s' % config.content_prefix
return '%s%s' % (prefix, url)


class _VersionHistory(Table):

headers = ["Qiskit Metapackage Version", "qiskit-terra", "qiskit-aer",
"qiskit-ignis", "qiskit-ibmq-provider", "qiskit-aqua",
"Release Date"]
repo_root = os.path.abspath(os.path.dirname(__file__))

def _get_setup_py(self, version, git_dir):
cmd = ['git', 'show', '%s:setup.py' % version]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=git_dir)
stdout, stderr = proc.communicate()
if proc.returncode > 0:
logger.warn("%s failed with:\nstdout:\n%s\nstderr:\n%s\n"
% (cmd, stdout, stderr))
return ''
return stdout.decode('utf8')

def _get_date(self, version, git_dir):
cmd = ['git', 'log', '--format=%ai', str(version), '-1']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=git_dir)
stdout, stderr = proc.communicate()
if proc.returncode > 0:
logger.warn("%s failed with:\nstdout:\n%s\nstderr:\n%s\n"
% (cmd, stdout, stderr))
return ''
return stdout.decode('utf8').split(' ')[0]

def get_versions(self, tags, git_dir):
versions = {}
for tag in tags:
version = {}
setup_py = self._get_setup_py(tag, git_dir)
version['Release Date'] = self._get_date(tag, git_dir)
for package in self.headers[1:] + ['qiskit_terra']:
version_regex = re.compile(package + '[=|>]=(.*)\"')
match = version_regex.search(setup_py)
if match:
ver = match[1]
if '<' in match[1]:
ver = '>=' + ver
if package != 'qiskit_terra':
version[package] = ver
else:
version['qiskit-terra'] = ver
if version:
versions[tag] = version
return versions

def build_table(self, versions):
table = nodes.table()
table['classes'] += ['colwidths-auto']
tgroup = nodes.tgroup(cols=len(self.headers))
table += tgroup
self.options['widths'] = [30, 15, 15, 15, 20, 15]
tgroup.extend(
nodes.colspec(colwidth=col_width, colname='c' + str(idx))
for idx, col_width in enumerate(self.col_widths)
)

thead = nodes.thead()
tgroup += thead

row_node = nodes.row()
thead += row_node
row_node.extend(nodes.entry(h, nodes.paragraph(text=h))
for h in self.headers)

tbody = nodes.tbody()
tgroup += tbody

rows = []
for version in versions:
row_node = nodes.row()
entry = nodes.entry()
entry += nodes.paragraph(text=version)
row_node += entry
for cell in self.headers[1:]:
if cell in versions[version]:
entry = nodes.entry()
text = versions[version][cell]
entry += nodes.paragraph(text=text)
else:
entry = nodes.entry()
row_node += entry
rows.append(row_node)
tbody.extend(rows)
return table

def run(self):
with tempfile.TemporaryDirectory() as tmp_dir:
tags, git_dir = _get_qiskit_metapackage_git_tags(tmp_dir)
versions = self.get_versions(tags, git_dir)
self.max_cols = len(self.headers)
self.col_widths = self.get_column_widths(self.max_cols)
table_node = self.build_table(versions)
title, messages = self.make_title()
if title:
table_node.insert(0, title)
return [table_node] + messages


def _get_qiskit_metapackage_git_tags(tmp_dir):
cmd = ['git', 'clone', 'https://github.com/Qiskit/qiskit.git']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, cwd=tmp_dir)
stdout, stderr = proc.communicate()
if proc.returncode > 0:
logger.warn("%s failed with:\nstdout:\n%s\nstderr:\n%s\n"
% (cmd, stdout, stderr))
return []
else:

return _get_git_tags(os.path.join(tmp_dir, 'qiskit'))


def _get_git_tags(git_dir):
cmd = ['git', 'tag', '--sort=-creatordate']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, cwd=git_dir)
stdout, stderr = proc.communicate()
if proc.returncode > 0:
logger.warn("%s failed with:\nstdout:\n%s\nstderr:\n%s\n"
% (cmd, stdout, stderr))
return []

return stdout.decode('utf8').splitlines(), git_dir