1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
import os
import shutil
import glob
import codecs
from nbformat import NotebookNode
from nbformat.v4 import reads
from nbconvert.preprocessors import ExecutePreprocessor
from nbconvert.exporters.notebook import NotebookExporter
from nbconvert.exporters.rst import RSTExporter
from brian2.utils.stringtools import deindent, indent
src_dir = os.path.abspath('../../../tutorials')
target_dir = os.path.abspath('../../../docs_sphinx/resources/tutorials')
# Start from scratch to avoid left-over files due to renamed tutorials, changed
# cell numbers, etc.
if os.path.exists(target_dir):
shutil.rmtree(target_dir)
os.mkdir(target_dir)
tutorials = []
for fname in sorted(glob.glob1(src_dir, '*.ipynb')):
basename = fname[:-6]
output_ipynb_fname = os.path.join(target_dir, fname)
output_rst_fname = os.path.join(target_dir, basename + '.rst')
print('Running', fname)
with open(os.path.join(src_dir, fname), 'r') as f:
notebook = reads(f.read())
# The first line of the tutorial file should give the title
title = notebook.cells[0]['source'].split('\n')[0].strip('# ')
tutorials.append((basename, title))
# Execute the notebook
preprocessor = ExecutePreprocessor(timeout=None)
preprocessor.allow_errors = True
notebook, _ = preprocessor.preprocess(notebook,
{'metadata': {'path': src_dir}})
print('Saving notebook and converting to RST')
exporter = NotebookExporter()
output, _ = exporter.from_notebook_node(notebook)
with codecs.open(output_ipynb_fname, 'w', encoding='utf-8') as f:
f.write(output)
# Insert a note about ipython notebooks with a download link
note = deindent('''
.. only:: html
.. |launchbinder| image:: file:///usr/share/doc/python-brian-doc/docs/badge.svg
.. _launchbinder: https://mybinder.org/v2/gh/brian-team/brian2-binder/master?filepath=tutorials/{tutorial}.ipynb
.. note::
This tutorial is a static non-editable version. You can launch an
interactive, editable version without installing any local files
using the Binder service (although note that at some times this
may be slow or fail to open): |launchbinder|_
Alternatively, you can download a copy of the notebook file
to use locally: :download:`{tutorial}.ipynb`
See the :doc:`tutorial overview page <index>` for more details.
'''.format(tutorial=basename))
notebook.cells.insert(1, NotebookNode(cell_type='raw', metadata={},
source=note))
exporter = RSTExporter()
output, resources = exporter.from_notebook_node(notebook,
resources={'unique_key': basename+'_image'})
with codecs.open(output_rst_fname, 'w', encoding='utf-8') as f:
f.write(output)
for image_name, image_data in resources['outputs'].items():
with open(os.path.join(target_dir, image_name), 'wb') as f:
f.write(image_data)
print('Generating index.rst')
text = '''
..
This is a generated file, do not edit directly.
(See dev/tools/docs/build_tutorials.py)
Tutorials
=========
The tutorial consists of a series of `Jupyter Notebooks`_ [#]_.
.. only:: html
You can quickly view these using the first links below. To use them interactively - allowing you
to edit and run the code - there are two options. The easiest option is to click
on the "Launch Binder" link, which will open up an interactive version in the
browser without having to install Brian locally. This uses the
`mybinder.org <http://mybinder.org>`_ service. Occasionally, this
service will be down or running slowly. The other option is to download the
notebook file and run it locally, which requires you to have Brian installed.
For more information about how to use Jupyter Notebooks, see the
`Jupyter Notebook documentation`_.
.. toctree::
:maxdepth: 1
:titlesonly:
'''
for tutorial, _ in tutorials:
text += ' ' + tutorial + '\n'
text += '''
.. only:: html
Interactive notebooks and files
-------------------------------
'''
for tutorial, _ in tutorials:
text += indent(deindent('''
.. |launchbinder{tutid}| image:: file:///usr/share/doc/python-brian-doc/docs/badge.svg
.. _launchbinder{tutid}: https://mybinder.org/v2/gh/brian-team/brian2-binder/master?filepath=tutorials/{tutorial}.ipynb
'''.format(tutorial=tutorial, tutid=tutorial.replace('-', ''))))
text += '\n'
for tutorial, title in tutorials:
text += ' * |launchbinder{tutid}|_ :download:`{title} <{tutorial}.ipynb>`\n'.format(title=title,
tutorial=tutorial, tutid=tutorial.replace('-', ''))
text += '''
.. _`Jupyter Notebooks`: http://jupyter-notebook-beginner-guide.readthedocs.org/en/latest/what_is_jupyter.html
.. _`Jupyter`: http://jupyter.org/
.. _`Jupyter Notebook documentation`: http://jupyter.readthedocs.org/
.. [#] Formerly known as "IPython Notebooks".
'''
with open(os.path.join(target_dir, 'index.rst'), 'w') as f:
f.write(text)
|