\n",
+ "\n",
+ "**Note:**\n",
+ "\n",
+ "Most of the \"Advanced Settings\" on readthedocs.org will be ignored if you have a `readthedocs.yml` file.\n",
+ "\n",
+ "</div>\n",
+ "\n",
+ "
\n",
+ "\n",
+ "**Warning:**\n",
+ "\n",
+ "If you have a very long repository name (or branch name), you might run into this quite obscure problem: ['placeholder too short'](
https://github.com/rtfd/readthedocs.org/issues/1902).\n",
+ "\n",
+ "</div>"
]
},
{
@@ -196,11 +270,15 @@
"\n",
"The `nbsphinx` extension does *not* provide its own theme, you can use any of the available themes or [create a custom one](
http://www.sphinx-doc.org/en/stable/theming.html#creating-themes), if you feel like it.\n",
"\n",
- "The following links show how the `nbsphinx` documentation looks like in different themes.\n",
+ "The following (incomplete) list of themes contains several links for each theme:\n",
+ "\n",
+ "1. The documentation (or the official sample page) of this theme (if available, see also the [documentation of the built-in Sphinx themes](
http://www.sphinx-doc.org/en/latest/theming.html#builtin-themes))\n",
+ "1. How the `nbsphinx` documentation looks when using this theme\n",
+ "1. How to enable this theme using either `requirements.txt` or `readthedocs.yml` and theme-specific settings (in some cases)\n",
"\n",
"### Sphinx's Built-In Themes\n",
"\n",
- "* `alabaster`:\n",
+ "* [alabaster](
https://alabaster.readthedocs.io/):\n",
" [example](
http://nbsphinx.readthedocs.io/en/alabaster-theme/),\n",
" [usage](
https://github.com/spatialaudio/nbsphinx/compare/alabaster-theme^...alabaster-theme)\n",
"\n",
@@ -234,30 +312,42 @@
"\n",
"### 3rd-Party Themes\n",
"\n",
- "* `sphinx_rtd_theme`:\n",
- " [example](
http://nbsphinx.readthedocs.io/en/readthedocs-theme/),\n",
- " [usage](
https://github.com/spatialaudio/nbsphinx/compare/readthedocs-theme^...readthedocs-theme)\n",
+ "* [sphinx_rtd_theme](
https://github.com/snide/sphinx_rtd_theme):\n",
+ " [example](
http://nbsphinx.readthedocs.io/en/rtd-theme/),\n",
+ " [usage](
https://github.com/spatialaudio/nbsphinx/compare/rtd-theme^...rtd-theme)\n",
"\n",
- "* `bootstrap`:\n",
+ "* [bootstrap](
http://sphinx-bootstrap-theme.readthedocs.io/):\n",
" [example](
http://nbsphinx.readthedocs.io/en/bootstrap-theme/),\n",
" [usage](
https://github.com/spatialaudio/nbsphinx/compare/bootstrap-theme^...bootstrap-theme)\n",
"\n",
- "* `cloud`, `redcloud`:\n",
+ "* [cloud](
https://pythonhosted.org/cloud_sptheme/):\n",
" [example](
http://nbsphinx.readthedocs.io/en/cloud-theme/),\n",
" [usage](
https://github.com/spatialaudio/nbsphinx/compare/cloud-theme^...cloud-theme)\n",
"\n",
- "* `sphinx_py3doc_enhanced_theme`:\n",
- " [example](
http://nbsphinx.readthedocs.io/en/py3doc-enhanced-theme/),\n",
- " [usage](
https://github.com/spatialaudio/nbsphinx/compare/py3doc-enhanced-theme^...py3doc-enhanced-theme)\n",
+ "* [sphinx_py3doc_enhanced_theme](
https://github.com/ionelmc/sphinx-py3doc-enhanced-theme):\n",
+ " [example](
http://nbsphinx.readthedocs.io/en/py3doc-enh-theme/),\n",
+ " [usage](
https://github.com/spatialaudio/nbsphinx/compare/py3doc-enh-theme^...py3doc-enh-theme)\n",
"\n",
- "* `basicstrap`:\n",
+ "* [basicstrap](
http://pythonhosted.org/sphinxjp.themes.basicstrap/):\n",
" [example](
http://nbsphinx.readthedocs.io/en/basicstrap-theme/),\n",
" [usage](
https://github.com/spatialaudio/nbsphinx/compare/basicstrap-theme^...basicstrap-theme)\n",
"\n",
- "* `dotted`:\n",
+ "* [dotted](
https://pythonhosted.org/sphinxjp.themes.dotted/):\n",
" [example](
http://nbsphinx.readthedocs.io/en/dotted-theme/),\n",
" [usage](
https://github.com/spatialaudio/nbsphinx/compare/dotted-theme^...dotted-theme)\n",
"\n",
+ "* [better](
https://sphinx-better-theme.readthedocs.io/):\n",
+ " [example](
http://nbsphinx.readthedocs.io/en/better-theme/),\n",
+ " [usage](
https://github.com/spatialaudio/nbsphinx/compare/better-theme^...better-theme)\n",
+ "\n",
+ "* [guzzle_sphinx_theme](
https://github.com/guzzle/guzzle_sphinx_theme):\n",
+ " [example](
http://nbsphinx.readthedocs.io/en/guzzle-theme/),\n",
+ " [usage](
https://github.com/spatialaudio/nbsphinx/compare/guzzle-theme^...guzzle-theme)\n",
+ "\n",
+ "* [julia](
https://github.com/JuliaLang/JuliaDoc):\n",
+ " [example](
http://nbsphinx.readthedocs.io/en/julia-theme/),\n",
+ " [usage](
https://github.com/spatialaudio/nbsphinx/compare/julia-theme^...julia-theme)\n",
+ "\n",
"If you know of another Sphinx theme that should be included here, please open an [issue on Github](
https://github.com/spatialaudio/nbsphinx/issues)."
]
}
@@ -278,7 +368,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.4.4"
+ "version": "3.5.2+"
}
},
"nbformat": 4,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbsphinx-0.2.10/nbsphinx.egg-info/PKG-INFO new/nbsphinx-0.2.13/nbsphinx.egg-info/PKG-INFO
--- old/nbsphinx-0.2.10/nbsphinx.egg-info/PKG-INFO 2016-10-16 11:38:26.000000000 +0200
+++ new/nbsphinx-0.2.13/nbsphinx.egg-info/PKG-INFO 2017-01-25 20:03:51.000000000 +0100
@@ -1,8 +1,8 @@
Metadata-Version: 1.1
Name: nbsphinx
-Version: 0.2.10
+Version: 0.2.13
Summary: Jupyter Notebook Tools for Sphinx
-Home-page:
http://nbsphinx.rtfd.org/
+Home-page:
http://nbsphinx.rtfd.io/
Author: Matthias Geier
Author-email: Matthias.Geier@gmail.com
License: MIT
@@ -45,7 +45,6 @@
Keywords: Sphinx,Jupyter,notebook
Platform: any
-Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Sphinx
Classifier: Framework :: Sphinx :: Extension
Classifier: Intended Audience :: Education
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbsphinx-0.2.10/nbsphinx.egg-info/SOURCES.txt new/nbsphinx-0.2.13/nbsphinx.egg-info/SOURCES.txt
--- old/nbsphinx-0.2.10/nbsphinx.egg-info/SOURCES.txt 2016-10-16 11:38:26.000000000 +0200
+++ new/nbsphinx-0.2.13/nbsphinx.egg-info/SOURCES.txt 2017-01-25 20:03:52.000000000 +0100
@@ -25,6 +25,7 @@
doc/images/notebook_icon.png
doc/images/python_logo.svg
doc/images/raw_cells.png
+doc/images/stickfigure.png
doc/subdir/a-notebook-in-a-subdir.ipynb
doc/subdir/toctree.ipynb
nbsphinx.egg-info/PKG-INFO
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbsphinx-0.2.10/nbsphinx.egg-info/requires.txt new/nbsphinx-0.2.13/nbsphinx.egg-info/requires.txt
--- old/nbsphinx-0.2.10/nbsphinx.egg-info/requires.txt 2016-10-16 11:38:26.000000000 +0200
+++ new/nbsphinx-0.2.13/nbsphinx.egg-info/requires.txt 2017-01-25 20:03:51.000000000 +0100
@@ -3,4 +3,4 @@
nbconvert
traitlets
nbformat
-sphinx
+sphinx>=1.3.2,!=1.5.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbsphinx-0.2.10/nbsphinx.py new/nbsphinx-0.2.13/nbsphinx.py
--- old/nbsphinx-0.2.10/nbsphinx.py 2016-10-16 11:34:35.000000000 +0200
+++ new/nbsphinx-0.2.13/nbsphinx.py 2017-01-25 20:02:43.000000000 +0100
@@ -23,7 +23,7 @@
http://nbsphinx.rtfd.org/
"""
-__version__ = '0.2.10'
+__version__ = '0.2.13'
import copy
import json
@@ -41,6 +41,7 @@
import nbconvert
import nbformat
import sphinx
+import sphinx.errors
import traitlets
_ipynbversion = 4
@@ -48,6 +49,8 @@
# See nbconvert/exporters/html.py:
DISPLAY_DATA_PRIORITY_HTML = (
'application/javascript',
+ 'application/vnd.jupyter.widget-view+json',
+ 'application/vnd.jupyter.widget-state+json',
'text/html',
'text/markdown',
'image/svg+xml',
@@ -155,6 +158,11 @@
var element = document.getElementById('{{ div_id }}');
{{ output.data['application/javascript'] | indent | indent }}
</script>
+{%- elif datatype.startswith('application') and datatype.endswith('+json') %}
+
+ .. raw:: html
+
+ <script type="{{ datatype }}">{{ output.data[datatype] | json_dumps }}</script>
{%- elif datatype == 'ansi' %}
.. rst-class:: highlight
@@ -232,6 +240,20 @@
{{ cell.source }}
{% endif %}
{% endblock rawcell %}
+
+
+{% block footer %}
+
+{% if 'application/vnd.jupyter.widget-state+json' in nb.metadata.widgets %}
+
+.. raw:: html
+
+ <script type="application/vnd.jupyter.widget-state+json">
+ {{ nb.metadata.widgets['application/vnd.jupyter.widget-state+json'] | json_dumps }}
+ </script>
+{% endif %}
+{{ super() }}
+{% endblock footer %}
"""
@@ -264,13 +286,15 @@
/* remove conflicting styling from Sphinx themes */
div.nbinput,
-div.nbinput > div,
-div.nbinput div[class^=highlight],
-div.nbinput div[class^=highlight] pre,
+div.nbinput div.prompt,
+div.nbinput div.input_area,
+div.nbinput div[class*=highlight],
+div.nbinput div[class*=highlight] pre,
div.nboutput,
-div.nboutput > div,
-div.nboutput div[class^=highlight],
-div.nboutput div[class^=highlight] pre {
+div.nbinput div.prompt,
+div.nbinput div.output_area,
+div.nboutput div[class*=highlight],
+div.nboutput div[class*=highlight] pre {
background: none;
border: none;
padding: 0 0;
@@ -279,7 +303,7 @@
}
/* avoid gaps between output lines */
-div.nboutput div[class^=highlight] pre {
+div.nboutput div[class*=highlight] pre {
line-height: normal;
}
@@ -290,6 +314,13 @@
display: flex;
align-items: flex-start;
margin: 0;
+ width: 100%%;
+}
+@media (max-width: %(nbsphinx_responsive_width)s) {
+ div.nbinput,
+ div.nboutput {
+ flex-direction: column;
+ }
}
/* input container */
@@ -303,38 +334,58 @@
}
/* input prompt */
-div.nbinput > :first-child pre {
+div.nbinput div.prompt pre {
color: #303F9F;
}
/* output prompt */
-div.nboutput > :first-child pre {
+div.nboutput div.prompt pre {
color: #D84315;
}
/* all prompts */
-div.nbinput > :first-child[class^=highlight],
-div.nboutput > :first-child[class^=highlight],
-div.nboutput > :first-child {
+div.nbinput div.prompt,
+div.nboutput div.prompt {
min-width: %(nbsphinx_prompt_width)s;
padding-top: 0.4em;
padding-right: 0.4em;
text-align: right;
flex: 0;
}
+@media (max-width: %(nbsphinx_responsive_width)s) {
+ div.nbinput div.prompt,
+ div.nboutput div.prompt {
+ text-align: left;
+ padding: 0.4em;
+ }
+ div.nboutput div.prompt.empty {
+ padding: 0;
+ }
+}
+
+/* disable scrollbars on prompts */
+div.nbinput div.prompt pre,
+div.nboutput div.prompt pre {
+ overflow: hidden;
+}
/* input/output area */
-div.nbinput > :nth-child(2)[class^=highlight],
-div.nboutput > :nth-child(2),
-div.nboutput > :nth-child(2)[class^=highlight] {
+div.nbinput div.input_area,
+div.nboutput div.output_area {
padding: 0.4em;
-webkit-flex: 1;
flex: 1;
overflow: auto;
}
+@media (max-width: %(nbsphinx_responsive_width)s) {
+ div.nbinput div.input_area,
+ div.nboutput div.output_area {
+ width: 100%%;
+ }
+}
/* input area */
-div.nbinput > :nth-child(2)[class^=highlight] {
+div.nbinput div.input_area {
border: 1px solid #cfcfcf;
border-radius: 2px;
background: #f7f7f7;
@@ -351,7 +402,7 @@
}
/* standard error */
-div.nboutput > :nth-child(2).stderr {
+div.nboutput div.output_area.stderr {
background: #fdd;
}
@@ -448,21 +499,17 @@
self._codecell_lexer = codecell_lexer
loader = jinja2.DictLoader({'nbsphinx-rst.tpl': RST_TEMPLATE})
super(Exporter, self).__init__(
- template_file='nbsphinx-rst', extra_loaders=[loader],
+ template_file='nbsphinx-rst.tpl', extra_loaders=[loader],
+ config= traitlets.config.Config(
+ {'HighlightMagicsPreprocessor': {'enabled': True}}),
filters={
'markdown2rst': markdown2rst,
'get_empty_lines': _get_empty_lines,
'extract_toctree': _extract_toctree,
'get_output_type': _get_output_type,
+ 'json_dumps': json.dumps,
})
- @property
- def default_config(self):
- c = traitlets.config.Config(
- {'HighlightMagicsPreprocessor': {'enabled': True}})
- c.merge(super(Exporter, self).default_config)
- return c
-
def from_notebook_node(self, nb, resources=None, **kw):
nb = copy.deepcopy(nb)
if resources is None:
@@ -478,13 +525,14 @@
if execute not in ('always', 'never', 'auto'):
raise ValueError('invalid execute option: {!r}'.format(execute))
auto_execute = (
+ execute == 'auto' and
# At least one code cell actually containing source code:
any(c.source for c in nb.cells if c.cell_type == 'code') and
# No outputs, not even a prompt number:
not any(c.get('outputs') or c.get('execution_count')
for c in nb.cells if c.cell_type == 'code')
)
- if execute == 'always' or (execute == 'auto' and auto_execute):
+ if auto_execute or execute == 'always':
allow_errors = nbsphinx_metadata.get(
'allow_errors', self._allow_errors)
timeout = nbsphinx_metadata.get('timeout', self._timeout)
@@ -515,6 +563,8 @@
"""
+ supported = ()
+
def get_transforms(self):
"""List of transforms for documents parsed by this parser."""
return rst.Parser.get_transforms(self) + [
@@ -533,7 +583,7 @@
resources['metadata'] = {'path': srcdir}
# Sphinx doesn't accept absolute paths in images etc.
resources['output_files_dir'] = os.path.relpath(auxdir, srcdir)
- resources['unique_key'] = env.docname.replace('/', '_')
+ resources['unique_key'] = re.sub('[/ ]', '_', env.docname)
exporter = Exporter(
execute=env.config.nbsphinx_execute,
@@ -577,14 +627,15 @@
"""A custom node that contains a literal_block node."""
@classmethod
- def create(cls, text, language='none'):
+ def create(cls, text, language='none', **kwargs):
"""Create a new CodeNode containing a literal_block node.
Apparently, this cannot be done in CodeNode.__init__(), see:
https://groups.google.com/forum/#!topic/sphinx-dev/0chv7BsYuW0
"""
- node = docutils.nodes.literal_block(text, text, language=language)
+ node = docutils.nodes.literal_block(text, text, language=language,
+ **kwargs)
return cls(text, node)
@@ -618,13 +669,14 @@
# Input prompt
text = 'In [{}]:'.format(execution_count if execution_count else ' ')
- container += CodeNode.create(text)
+ container += CodeNode.create(text, classes=['prompt'])
latex_prompt = text + ' '
# Input code area
text = '\n'.join(self.content.data)
node = CodeNode.create(
- text, language=self.arguments[0] if self.arguments else 'none')
+ text, language=self.arguments[0] if self.arguments else 'none',
+ classes=['input_area'])
_set_empty_lines(node, self.options)
node.attributes['latex_prompt'] = latex_prompt
container += node
@@ -659,22 +711,23 @@
# Optional output prompt
if execution_count:
text = 'Out[{}]:'.format(execution_count)
- container += CodeNode.create(text)
+ container += CodeNode.create(text, classes=['prompt'])
latex_prompt = text + ' '
else:
- container += rst.nodes.container() # empty container for HTML
+ # Empty container for HTML:
+ container += rst.nodes.container(classes=['prompt', 'empty'])
latex_prompt = ''
# Output area
if outputtype == 'rst':
- classes = [self.options.get('class', '')]
+ classes = [self.options.get('class', ''), 'output_area']
output_area = docutils.nodes.container(classes=classes)
self.state.nested_parse(self.content, self.content_offset,
output_area)
container += output_area
else:
text = '\n'.join(self.content.data)
- node = CodeNode.create(text)
+ node = CodeNode.create(text, classes=['output_area'])
_set_empty_lines(node, self.options)
node.attributes['latex_prompt'] = latex_prompt
container += node
@@ -886,9 +939,10 @@
elif uri.startswith('#') or uri.startswith('mailto:'):
continue # Nothing to be done
+ unquoted_uri = unquote(uri)
for suffix in env.config.source_suffix:
- if uri.lower().endswith(suffix.lower()):
- target = uri[:-len(suffix)]
+ if unquoted_uri.lower().endswith(suffix.lower()):
+ target = unquoted_uri[:-len(suffix)]
break
else:
target = ''
@@ -899,13 +953,13 @@
refdomain = None
elif '.ipynb#' in uri.lower():
idx = uri.lower().find('.ipynb#')
- target = uri[:idx]
+ target = unquote(uri[:idx])
target_ext = uri[idx:]
reftype = 'ref'
refdomain = 'std'
else:
file = os.path.normpath(
- os.path.join(os.path.dirname(env.docname), uri))
+ os.path.join(os.path.dirname(env.docname), unquoted_uri))
if not os.path.isfile(os.path.join(env.srcdir, file)):
env.app.warn('file not found: {!r}'.format(file),
env.doc2path(env.docname))
@@ -1036,10 +1090,13 @@
if app.config.nbsphinx_prompt_width is None:
app.config.nbsphinx_prompt_width = {
'agogo': '7ex',
+ 'alabaster': '8ex',
+ 'better': '8ex',
'classic': '7ex',
'cloud': '8ex',
'dotted': '8ex',
'haiku': '7ex',
+ 'julia': '7ex',
'nature': '8ex',
'pyramid': '8ex',
'redcloud': '8ex',
@@ -1054,7 +1111,7 @@
style = ''
if doctree and doctree.get('nbsphinx_include_css'):
style += CSS_STRING % app.config
- if doctree and app.config.html_theme == 'sphinx_rtd_theme':
+ if doctree and app.config.html_theme in ('sphinx_rtd_theme', 'julia'):
style += CSS_STRING_READTHEDOCS
if style:
context['body'] = '\n<style>' + style + '</style>\n' + context['body']
@@ -1097,11 +1154,13 @@
def visit_code_latex(self, node):
"""Avoid creating a separate prompt node.
- The prompt will be pre-pended in the main code node.
+ The prompt (which is stored in the "latex_prompt" attribute) will be
+ pre-pended in the main code node.
"""
if 'latex_prompt' not in node.attributes:
raise docutils.nodes.SkipNode()
+ self.pushbody([]) # See popbody() below
def depart_code_latex(self, node):
@@ -1112,7 +1171,7 @@
* Add prompt to the first line, empty space to the following lines
"""
- lines = self.body[-1].split('\n')
+ lines = ''.join(self.popbody()).split('\n')
out = []
assert lines[0] == ''
out.append(lines[0])
@@ -1143,13 +1202,13 @@
assert False
assert lines[-1] == ''
out.append(lines[-1])
- self.body[-1] = '\n'.join(out)
+ self.body.append('\n'.join(out))
def visit_admonition_html(self, node):
self.body.append(self.starttag(node, 'div'))
self.set_first_last(node)
- if self.settings.env.config.html_theme == 'sphinx_rtd_theme':
+ if self.settings.env.config.html_theme in ('sphinx_rtd_theme', 'julia'):
if node.children:
classes = node.children[0]['classes']
if 'last' not in classes:
@@ -1207,6 +1266,7 @@
app.add_config_value('nbsphinx_codecell_lexer', 'none', rebuild='env')
# Default value is set in builder_inited():
app.add_config_value('nbsphinx_prompt_width', None, rebuild='html')
+ app.add_config_value('nbsphinx_responsive_width', '540px', rebuild='html')
app.add_directive('nbinput', NbInput)
app.add_directive('nboutput', NbOutput)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nbsphinx-0.2.10/setup.py new/nbsphinx-0.2.13/setup.py
--- old/nbsphinx-0.2.10/setup.py 2016-09-29 13:35:51.000000000 +0200
+++ new/nbsphinx-0.2.13/setup.py 2016-12-23 13:48:39.000000000 +0100
@@ -1,8 +1,8 @@
from setuptools import setup
# "import" __version__
-for line in open("nbsphinx.py"):
- if line.startswith("__version__"):
+for line in open('nbsphinx.py'):
+ if line.startswith('__version__'):
exec(line)
break
@@ -16,7 +16,7 @@
'nbconvert',
'traitlets',
'nbformat',
- 'sphinx',
+ 'sphinx>=1.3.2,!=1.5.0',
],
author='Matthias Geier',
author_email='Matthias.Geier@gmail.com',
@@ -24,10 +24,9 @@
long_description=open('README.rst').read(),
license='MIT',
keywords='Sphinx Jupyter notebook'.split(),
- url='
http://nbsphinx.rtfd.org/',
+ url='
http://nbsphinx.rtfd.io/',
platforms='any',
classifiers=[
- 'Development Status :: 3 - Alpha',
'Framework :: Sphinx',
'Framework :: Sphinx :: Extension',
'Intended Audience :: Education',