New upstream snapshot.
Debian Janitor
2 years ago
0 | Metadata-Version: 1.1 | |
0 | Metadata-Version: 2.1 | |
1 | 1 | Name: nb2plots |
2 | Version: 0.6 | |
2 | Version: 0+unknown | |
3 | 3 | Summary: Converting between ipython notebooks and sphinx docs |
4 | 4 | Home-page: http://github.com/matthew-brett/nb2plots |
5 | 5 | Author: Matthew Brett |
6 | 6 | Author-email: matthew.brett@gmail.com |
7 | Maintainer: Matthew Brett | |
8 | Maintainer-email: matthew.brett@gmail.com | |
7 | 9 | License: BSD license |
8 | Description-Content-Type: UNKNOWN | |
9 | Description: ################################################## | |
10 | nb2plots - converting between notebooks and sphinx | |
11 | ################################################## | |
12 | ||
13 | See the nb2plots documentation_ for more information. | |
14 | ||
15 | .. shared-text-body | |
16 | ||
17 | ************ | |
18 | What it does | |
19 | ************ | |
20 | ||
21 | ``nb2plots`` converts Jupyter_ notebooks to ReST_ files for Sphinx_, and back | |
22 | again. | |
23 | ||
24 | Nb2plots assumes that the ReST document will become the source for your Sphinx | |
25 | web pages, but also for future versions of the notebook. The notebook may | |
26 | serve as a draft for the polished ReST page, and an output format from the | |
27 | Sphinx build. Why? Read on. | |
28 | ||
29 | **************************************** | |
30 | Why convert Jupyter notebooks to Sphinx? | |
31 | **************************************** | |
32 | ||
33 | Jupyter notebooks are just what the doctor ordered when hacking up a quick | |
34 | tutorial, or preparing a software demo. The problems start when you want to | |
35 | do not-trivial edits to the notebooks, or you need features that notebooks | |
36 | don't have, such as flexible cross-referencing, extensible markup, and so on. | |
37 | Notebooks are also painful to use with version control. These times make you | |
38 | wish your notebook was in a standard extensible text format, such as ReST_. | |
39 | ||
40 | You could convert your notebook to ReST using the standard `nbconvert`_ | |
41 | command, but this gives rather ugly ReST, and you lose all the nice code | |
42 | execution and figure generation that the notebook is good at. | |
43 | ||
44 | Enter Nb2plots. The ``nb2plots`` command converts notebooks to specially | |
45 | formatted ReST pages. Use with:: | |
46 | ||
47 | nb2plots notebook.ipynb > with_plots.rst | |
48 | ||
49 | Nb2plots converts your notebook to not-very-ugly ReST, where the code cells | |
50 | become ``nbplot`` directives in your ReST file. | |
51 | ||
52 | Specifically, a notebook code cell like this:: | |
53 | ||
54 | a = 1 | |
55 | ||
56 | becomes (in the ReST document):: | |
57 | ||
58 | .. nbplot:: | |
59 | ||
60 | >>> a = 1 | |
61 | ||
62 | The ``nbplot`` directives run the contained code when Sphinx builds your ReST | |
63 | files, and embed the results of any plots that your code makes. Actually, | |
64 | ``nbplot`` is an extended and edited version of the `matplotlib plot | |
65 | directive`_. Building your pages runs all the code and regenerates the | |
66 | figures, and you get much of the reproducible goodness of the notebook | |
67 | experience. | |
68 | ||
69 | You can also run the standard Sphinx ``doctest`` extension over your pages to | |
70 | check the doctest output of the code cells. | |
71 | ||
72 | The ReST version of your notebook has many advantages - it is easier to edit | |
73 | in your favorite text editor, and you can extend and configure the execution | |
74 | and display of the code in several different ways. For example, you can hide | |
75 | some code cells (Nbplot directives) if the code is not interesting to your | |
76 | point, but you still want the generated figure. You can configure your Nbplot | |
77 | directives to run different code for different configurations. For these | |
78 | options, see |nbplot-documentation|. But - what do you lose, when going from | |
79 | a notebook to a Nb2plots ReST document? | |
80 | ||
81 | ********************************** | |
82 | I want notebooks and .py files too | |
83 | ********************************** | |
84 | ||
85 | You may also want a version of your document that your users can execute. | |
86 | Perhaps the page build is generating some tricky errors or warnings, and you | |
87 | want to experiment with the code in the page interactively. Perhaps your | |
88 | users are used to notebooks, and prefer the code in that format. | |
89 | ||
90 | Nb2plots also contains Sphinx extensions that cause the Sphinx build to | |
91 | generate Python code files and Jupyter notebooks from the ReST source. When | |
92 | you add the Nb2plots ReST directive ``code-links`` to your ReST page, it will | |
93 | cause the Sphinx build to create a Python code file and notebook versions of | |
94 | your page, and adds download links to these versions:: | |
95 | ||
96 | .. code-links:: | |
97 | ||
98 | See |code-links-documentation| for details. | |
99 | ||
100 | ************************** | |
101 | Show me what it looks like | |
102 | ************************** | |
103 | ||
104 | For a very simple example, see |worked-example|. | |
105 | ||
106 | For a moderate-sized teaching site that makes extensive use of Nb2plots, see | |
107 | https://matthew-brett.github.com/teaching. | |
108 | ||
109 | ************ | |
110 | Installation | |
111 | ************ | |
112 | ||
113 | :: | |
114 | ||
115 | pip install nb2plots | |
116 | ||
117 | You will need Pandoc_ installed and available as the ``pandoc`` command. | |
118 | ||
119 | To install Pandoc on OSX, we recommend homebrew_:: | |
120 | ||
121 | brew install pandoc | |
122 | ||
123 | ************* | |
124 | Configuration | |
125 | ************* | |
126 | ||
127 | Add the following to your Sphinx ``conf.py`` file:: | |
128 | ||
129 | extensions = ["nb2plots"] | |
130 | ||
131 | See |nbplot-documentation| for the various ``conf.py`` configuration settings. | |
132 | ||
133 | **** | |
134 | Code | |
135 | **** | |
136 | ||
137 | See https://github.com/matthew-brett/nb2plots | |
138 | ||
139 | Released under the BSD two-clause license - see the file ``LICENSE`` in the | |
140 | source distribution. | |
141 | ||
142 | `travis-ci <https://travis-ci.org/matthew-brett/nb2plots>`_ kindly tests the | |
143 | code automatically under Python versions 2.7, and 3.3 through 3.5. | |
144 | ||
145 | The latest released version is at https://pypi.python.org/pypi/nb2plots | |
146 | ||
147 | ***** | |
148 | Tests | |
149 | ***** | |
150 | ||
151 | * Install ``nb2plots`` | |
152 | * Install the pytest_ testing framework, the ``mock`` package, and the | |
153 | ``scripttester`` package. | |
154 | ||
155 | pip install pytest mock scripttester | |
156 | ||
157 | * Run the tests with:: | |
158 | ||
159 | py.test --pyargs nb2plots | |
160 | ||
161 | ******* | |
162 | Support | |
163 | ******* | |
164 | ||
165 | Please put up issues on the `nb2plots issue tracker`_. | |
166 | ||
167 | .. standalone-references | |
168 | ||
169 | .. |nbplot-documentation| replace:: `nbplots documentation`_ | |
170 | .. |worked-example| replace:: `worked example`_ | |
171 | .. |code-links-documentation| replace:: `code-links documentation`_ | |
172 | .. _nbplots documentation: | |
173 | https://matthew-brett.github.com/nb2plots/nbplots.html | |
174 | .. _code-links documentation: | |
175 | https://matthew-brett.github.com/nb2plots/code_links.html | |
176 | .. _worked example: | |
177 | https://matthew-brett.github.com/nb2plots/worked_example.html | |
178 | .. _documentation: https://matthew-brett.github.com/nb2plots | |
179 | .. _pandoc: http://pandoc.org | |
180 | .. _jupyter: jupyter.org | |
181 | .. _homebrew: brew.sh | |
182 | .. _sphinx: http://sphinx-doc.org | |
183 | .. _rest: http://docutils.sourceforge.net/rst.html | |
184 | .. _nb2plots issue tracker: https://github.com/matthew-brett/nb2plots/issues | |
185 | .. _matplotlib plot directive: http://matplotlib.org/sampledoc/extensions.html | |
186 | .. _nbconvert: http://nbconvert.readthedocs.org/en/latest/ | |
187 | .. _pytest: https://pytest.readthedocs.io | |
188 | .. _mock: https://github.com/testing-cabal/mock | |
189 | ||
190 | 10 | Platform: UNKNOWN |
191 | 11 | Classifier: Development Status :: 2 - Pre-Alpha |
192 | 12 | Classifier: Environment :: Console |
200 | 20 | Classifier: Operating System :: POSIX |
201 | 21 | Classifier: Operating System :: Unix |
202 | 22 | Classifier: Operating System :: MacOS |
23 | Provides-Extra: test | |
24 | License-File: LICENSE | |
25 | ||
26 | ################################################## | |
27 | nb2plots - converting between notebooks and sphinx | |
28 | ################################################## | |
29 | ||
30 | See the nb2plots documentation_ for more information. | |
31 | ||
32 | .. shared-text-body | |
33 | ||
34 | ************ | |
35 | What it does | |
36 | ************ | |
37 | ||
38 | ``nb2plots`` converts Jupyter_ notebooks to ReST_ files for Sphinx_, and back | |
39 | again. | |
40 | ||
41 | Nb2plots assumes that the ReST document will become the source for your Sphinx | |
42 | web pages, but also for future versions of the notebook. The notebook may | |
43 | serve as a draft for the polished ReST page, and an output format from the | |
44 | Sphinx build. Why? Read on. | |
45 | ||
46 | **************************************** | |
47 | Why convert Jupyter notebooks to Sphinx? | |
48 | **************************************** | |
49 | ||
50 | Jupyter notebooks are just what the doctor ordered when hacking up a quick | |
51 | tutorial, or preparing a software demo. The problems start when you want to | |
52 | do not-trivial edits to the notebooks, or you need features that notebooks | |
53 | don't have, such as flexible cross-referencing, extensible markup, and so on. | |
54 | Notebooks are also painful to use with version control. These times make you | |
55 | wish your notebook was in a standard extensible text format, such as ReST_. | |
56 | ||
57 | You could convert your notebook to ReST using the standard `nbconvert`_ | |
58 | command, but this gives rather ugly ReST, and you lose all the nice code | |
59 | execution and figure generation that the notebook is good at. | |
60 | ||
61 | Enter Nb2plots. The ``nb2plots`` command converts notebooks to specially | |
62 | formatted ReST pages. Use with:: | |
63 | ||
64 | nb2plots notebook.ipynb > with_plots.rst | |
65 | ||
66 | Nb2plots converts your notebook to not-very-ugly ReST, where the code cells | |
67 | become ``nbplot`` directives in your ReST file. | |
68 | ||
69 | Specifically, a notebook code cell like this:: | |
70 | ||
71 | a = 1 | |
72 | ||
73 | becomes (in the ReST document):: | |
74 | ||
75 | .. nbplot:: | |
76 | ||
77 | >>> a = 1 | |
78 | ||
79 | The ``nbplot`` directives run the contained code when Sphinx builds your ReST | |
80 | files, and embed the results of any plots that your code makes. Actually, | |
81 | ``nbplot`` is an extended and edited version of the `matplotlib plot | |
82 | directive`_. Building your pages runs all the code and regenerates the | |
83 | figures, and you get much of the reproducible goodness of the notebook | |
84 | experience. | |
85 | ||
86 | You can also run the standard Sphinx ``doctest`` extension over your pages to | |
87 | check the doctest output of the code cells. | |
88 | ||
89 | The ReST version of your notebook has many advantages - it is easier to edit | |
90 | in your favorite text editor, and you can extend and configure the execution | |
91 | and display of the code in several different ways. For example, you can hide | |
92 | some code cells (Nbplot directives) if the code is not interesting to your | |
93 | point, but you still want the generated figure. You can configure your Nbplot | |
94 | directives to run different code for different configurations. For these | |
95 | options, see |nbplot-documentation|. But - what do you lose, when going from | |
96 | a notebook to a Nb2plots ReST document? | |
97 | ||
98 | ********************************** | |
99 | I want notebooks and .py files too | |
100 | ********************************** | |
101 | ||
102 | You may also want a version of your document that your users can execute. | |
103 | Perhaps the page build is generating some tricky errors or warnings, and you | |
104 | want to experiment with the code in the page interactively. Perhaps your | |
105 | users are used to notebooks, and prefer the code in that format. | |
106 | ||
107 | Nb2plots also contains Sphinx extensions that cause the Sphinx build to | |
108 | generate Python code files and Jupyter notebooks from the ReST source. When | |
109 | you add the Nb2plots ReST directive ``code-links`` to your ReST page, it will | |
110 | cause the Sphinx build to create a Python code file and notebook versions of | |
111 | your page, and adds download links to these versions:: | |
112 | ||
113 | .. code-links:: | |
114 | ||
115 | See |code-links-documentation| for details. | |
116 | ||
117 | ************************** | |
118 | Show me what it looks like | |
119 | ************************** | |
120 | ||
121 | For a very simple example, see |worked-example|. | |
122 | ||
123 | For a moderate-sized teaching site that makes extensive use of Nb2plots, see | |
124 | https://matthew-brett.github.com/teaching. | |
125 | ||
126 | ************ | |
127 | Installation | |
128 | ************ | |
129 | ||
130 | :: | |
131 | ||
132 | pip install nb2plots | |
133 | ||
134 | You will need Pandoc_ installed and available as the ``pandoc`` command. | |
135 | ||
136 | To install Pandoc on OSX, we recommend homebrew_:: | |
137 | ||
138 | brew install pandoc | |
139 | ||
140 | ************* | |
141 | Configuration | |
142 | ************* | |
143 | ||
144 | Add the following to your Sphinx ``conf.py`` file:: | |
145 | ||
146 | extensions = ["nb2plots"] | |
147 | ||
148 | See |nbplot-documentation| for the various ``conf.py`` configuration settings. | |
149 | ||
150 | **** | |
151 | Code | |
152 | **** | |
153 | ||
154 | See https://github.com/matthew-brett/nb2plots | |
155 | ||
156 | Released under the BSD two-clause license - see the file ``LICENSE`` in the | |
157 | source distribution. | |
158 | ||
159 | `travis-ci <https://travis-ci.org/matthew-brett/nb2plots>`_ kindly tests the | |
160 | code automatically under Python versions 2.7, and 3.5 through 3.8. | |
161 | ||
162 | The latest released version is at https://pypi.python.org/pypi/nb2plots | |
163 | ||
164 | ***** | |
165 | Tests | |
166 | ***** | |
167 | ||
168 | * Install ``nb2plots`` | |
169 | * Install the pytest_ testing framework, the ``mock`` package, and the | |
170 | ``scripttester`` package. | |
171 | ||
172 | pip install pytest mock scripttester | |
173 | ||
174 | * Run the tests with:: | |
175 | ||
176 | py.test --pyargs nb2plots | |
177 | ||
178 | ******* | |
179 | Support | |
180 | ******* | |
181 | ||
182 | Please put up issues on the `nb2plots issue tracker`_. | |
183 | ||
184 | .. standalone-references | |
185 | ||
186 | .. |nbplot-documentation| replace:: `nbplots documentation`_ | |
187 | .. |worked-example| replace:: `worked example`_ | |
188 | .. |code-links-documentation| replace:: `code-links documentation`_ | |
189 | .. _nbplots documentation: | |
190 | https://matthew-brett.github.com/nb2plots/nbplots.html | |
191 | .. _code-links documentation: | |
192 | https://matthew-brett.github.com/nb2plots/code_links.html | |
193 | .. _worked example: | |
194 | https://matthew-brett.github.com/nb2plots/worked_example.html | |
195 | .. _documentation: https://matthew-brett.github.com/nb2plots | |
196 | .. _pandoc: http://pandoc.org | |
197 | .. _jupyter: jupyter.org | |
198 | .. _homebrew: brew.sh | |
199 | .. _sphinx: http://sphinx-doc.org | |
200 | .. _rest: http://docutils.sourceforge.net/rst.html | |
201 | .. _nb2plots issue tracker: https://github.com/matthew-brett/nb2plots/issues | |
202 | .. _matplotlib plot directive: http://matplotlib.org/sampledoc/extensions.html | |
203 | .. _nbconvert: http://nbconvert.readthedocs.org/en/latest/ | |
204 | .. _pytest: https://pytest.readthedocs.io | |
205 | .. _mock: https://github.com/testing-cabal/mock | |
206 | ||
207 |
131 | 131 | source distribution. |
132 | 132 | |
133 | 133 | `travis-ci <https://travis-ci.org/matthew-brett/nb2plots>`_ kindly tests the |
134 | code automatically under Python versions 2.7, and 3.3 through 3.5. | |
134 | code automatically under Python versions 2.7, and 3.5 through 3.8. | |
135 | 135 | |
136 | 136 | The latest released version is at https://pypi.python.org/pypi/nb2plots |
137 | 137 |
0 | nb2plots (0.6-3) UNRELEASED; urgency=medium | |
0 | nb2plots (0.6+git20201225.1.1a7bac4-1) UNRELEASED; urgency=medium | |
1 | 1 | |
2 | 2 | [ Ondřej Nový ] |
3 | 3 | * d/control: Update Vcs-* fields with new Debian Python Team Salsa |
13 | 13 | * Update standards version to 4.5.1, no changes needed. |
14 | 14 | * Remove constraints unnecessary since buster: |
15 | 15 | + Build-Depends: Drop versioned constraint on python3-six. |
16 | * New upstream snapshot. | |
16 | 17 | |
17 | -- Sandro Tosi <morph@debian.org> Mon, 04 Jan 2021 17:01:12 -0500 | |
18 | -- Sandro Tosi <morph@debian.org> Fri, 05 Nov 2021 04:36:19 -0000 | |
18 | 19 | |
19 | 20 | nb2plots (0.6-2) unstable; urgency=medium |
20 | 21 |
7 | 7 | |
8 | 8 | version_json = ''' |
9 | 9 | { |
10 | "date": "2018-02-03T21:09:07+0000", | |
11 | "dirty": false, | |
12 | "error": null, | |
13 | "full-revisionid": "8873eeca7d7ad617dcac9aa317ee0a7079e17c79", | |
14 | "version": "0.6" | |
10 | "date": null, | |
11 | "dirty": null, | |
12 | "error": "unable to compute version", | |
13 | "full-revisionid": null, | |
14 | "version": "0+unknown" | |
15 | 15 | } |
16 | 16 | ''' # END VERSION_JSON |
17 | 17 |
21 | 21 | -------------- |
22 | 22 | |
23 | 23 | When you build the full notebook, Jupyter will execute the code in each cell. |
24 | By default, Jupyter will time out of any cell takes longer than 30 seconds to | |
25 | execute. You can change this default for the whole project with the | |
24 | By default, Jupyter will time out for any cell that takes longer than 30 | |
25 | seconds to execute. You can change this default for the whole project with the | |
26 | 26 | ``fill_notebook_timeout`` setting in the ``conf.py`` file (see below). If you |
27 | 27 | just want to change the setting for a single page, you can add the ``timeout`` |
28 | 28 | option to the ``code-links`` directive. For example:: |
30 | 30 | .. code-links: |
31 | 31 | :timeout: 120 |
32 | 32 | |
33 | Set the timeout value to -1 or ``none`` to disable timeout entirely for this | |
34 | directive / page. | |
33 | Set the ``timeout`` value to -1 or ``none`` to disable timeout entirely for | |
34 | this directive / page. | |
35 | 35 | |
36 | 36 | Configuration options |
37 | 37 | --------------------- |
75 | 75 | (``app.cleanup()``) after use. |
76 | 76 | """ |
77 | 77 | app = self._make_app(rst_text) |
78 | out_fname = pjoin(app.tmp_dir, 'contents.rst') | |
78 | master_doc = app.config.master_doc | |
79 | out_fname = pjoin(app.tmp_dir, master_doc + '.rst') | |
79 | 80 | with open(out_fname, 'wt') as fobj: |
80 | 81 | fobj.write(rst_text) |
81 | 82 | # Force build of everything |
82 | 83 | app.build(True, []) |
83 | 84 | if resolve: |
84 | dt = app.env.get_and_resolve_doctree('contents', app.builder) | |
85 | dt = app.env.get_and_resolve_doctree(master_doc, app.builder) | |
85 | 86 | else: |
86 | dt = app.env.get_doctree('contents') | |
87 | dt = app.env.get_doctree(master_doc) | |
87 | 88 | return dt, app |
88 | 89 | |
89 | 90 | def from_doctree(self, doctree, builder): |
101 | 102 | output : str |
102 | 103 | Representation in output format |
103 | 104 | """ |
104 | builder.prepare_writing(['contents']) | |
105 | builder.prepare_writing([builder.config.master_doc]) | |
105 | 106 | return builder.writer.write(doctree, UnicodeOutput()) |
106 | 107 | |
107 | 108 | def from_rst(self, rst_text, resolve=True): |
142 | 143 | |
143 | 144 | |
144 | 145 | DEFAULT_CONF = """\ |
146 | master_doc = 'contents' # For compatibility with Sphinx 2 | |
145 | 147 | extensions = [{}] |
146 | 148 | """.format(',\n'.join('"{}"'.format(ext_name) |
147 | 149 | for ext_name in DEFAULT_EXTENSIONS)) |
343 | 343 | |
344 | 344 | def visit_literal_block(self, node): |
345 | 345 | self._escape_text = False |
346 | code_type = node['classes'][1] if 'code' in node['classes'] else '' | |
346 | if 'code' in node['classes']: # Sphinx < 2 | |
347 | code_type = node['classes'][1] | |
348 | else: # Sphinx >= 2 | |
349 | language = node.get('language', '') | |
350 | code_type = '' if language == 'default' else language | |
347 | 351 | self.add('```' + code_type + '\n') |
348 | 352 | |
349 | 353 | def depart_literal_block(self, node): |
13 | 13 | |
14 | 14 | # Template to label code and output and plot blocks |
15 | 15 | dl = DictLoader({'rst_plots.tpl': """\ |
16 | {%- extends 'rst.tpl' -%} | |
16 | {%- extends '__RST_DEFAULT_TEMPLATE__' -%} | |
17 | 17 | |
18 | 18 | {% block input %} |
19 | 19 | {%- if cell.source.strip() | has_mpl_inline -%} |
49 | 49 | {{ output.data['text/plain'] | ellipse_mpl | indent }} |
50 | 50 | ##END_OUT_END## |
51 | 51 | {%- endblock data_text -%} |
52 | """}) | |
52 | """.replace('__RST_DEFAULT_TEMPLATE__', | |
53 | nbconvert.RSTExporter().template_file)}) | |
53 | 54 | |
54 | 55 | |
55 | 56 | def has_mpl_inline(code): |
87 | 88 | return '\n'.join(new_code) |
88 | 89 | |
89 | 90 | |
90 | MPL_LIST_OUT = re.compile('\[<matplotlib\..*?>\]') | |
91 | MPL_OBJ_OUT = re.compile('<matplotlib\..*?>') | |
91 | MPL_LIST_OUT = re.compile(r'\[<matplotlib\..*?>\]') | |
92 | MPL_OBJ_OUT = re.compile(r'<matplotlib\..*?>') | |
92 | 93 | |
93 | 94 | def ellipse_mpl(text): |
94 | 95 | """ Replace outputs of matplotlib objects with ellipses |
112 | 113 | '^##CODE_START##\n' |
113 | 114 | '(?P<code>.*?)' |
114 | 115 | '^##CODE_END##(\n|$)' |
115 | '([\s\\n]*?' | |
116 | '([\\s\\n]*?' | |
116 | 117 | '^##STDOUT_START##\n' |
117 | 118 | '(?P<stdout>.*?)' |
118 | 119 | '^##STDOUT_END##(\n|$))?' |
119 | '([\s\\n]*?' | |
120 | '([\\s\\n]*?' | |
120 | 121 | '^##END_OUT_START##\n' |
121 | 122 | '(?P<end_out>.*?)' |
122 | 123 | '^##END_OUT_END##(\n|$))?', re.S | re.M) |
176 | 176 | |
177 | 177 | import six |
178 | 178 | |
179 | from collections import defaultdict, Sequence | |
179 | try: | |
180 | from collections.abc import Sequence | |
181 | except ImportError: | |
182 | from collections import Sequence | |
183 | from collections import defaultdict | |
180 | 184 | import sys, os, shutil, io, re, textwrap |
181 | 185 | from os.path import (relpath, abspath, join as pjoin, dirname, exists, |
182 | 186 | basename, splitext, isdir) |
672 | 676 | """ |
673 | 677 | Remove the coding comment, which six.exec_ doesn't like. |
674 | 678 | """ |
675 | sub_re = re.compile("^#\s*-\*-\s*coding:\s*.*-\*-$", flags=re.MULTILINE) | |
679 | sub_re = re.compile(r"^#\s*-\*-\s*coding:\s*.*-\*-$", flags=re.MULTILINE) | |
676 | 680 | return sub_re.sub("", text) |
677 | 681 | |
678 | 682 | #------------------------------------------------------------------------------ |
355 | 355 | # code visit, depart methods with app.add_node as we have just done for the |
356 | 356 | # html translator in the lines above. See: |
357 | 357 | # http://www.sphinx-doc.org/en/1.4.8/extdev/tutorial.html#the-setup-function |
358 | app.set_translator('markdown', doctree2py.Translator) | |
358 | 359 | app.set_translator('pyfile', doctree2py.Translator) |
359 | 360 | app.set_translator('ipynb', doctree2nb.Translator) |
5 | 5 | import numpy as np |
6 | 6 | |
7 | 7 | from sphinxtesters import SourcesBuilder |
8 | ||
9 | 8 | |
10 | 9 | DATA_PATH = abspath(pjoin( |
11 | 10 | dirname(__file__), |
29 | 28 | Used by several test functions. |
30 | 29 | """ |
31 | 30 | |
32 | conf_source = 'extensions = ["nb2plots", "sphinx.ext.doctest"]' | |
31 | conf_source = """\ | |
32 | master_doc = "contents" # Compatibility with Sphinx 2 | |
33 | extensions = ["nb2plots", "sphinx.ext.doctest"] | |
34 | """ | |
35 | ||
36 | def stripeq(actual, expected): | |
37 | """ True if LR stripped `actual` equal to LR stripped `expected` | |
38 | """ | |
39 | return actual.strip() == expected.strip() |
0 | 0 | """ Utils for testing notebooks |
1 | 1 | """ |
2 | 2 | |
3 | from copy import deepcopy | |
4 | ||
3 | 5 | from nb2plots.ipython_shim import nbf |
6 | ||
7 | ||
8 | def rm_ids(nb): | |
9 | nb2 = deepcopy(nb) | |
10 | for cell in nb2['cells']: | |
11 | if 'id' in cell: | |
12 | del cell['id'] | |
13 | return nb2 | |
4 | 14 | |
5 | 15 | |
6 | 16 | def assert_nb_equiv(ipynb, expected): |
10 | 20 | # It does not appear to be possible to request specific minor versions of |
11 | 21 | # the Notebook format. |
12 | 22 | expected_nb['nbformat_minor'] = actual_nb['nbformat_minor'] |
13 | assert actual_nb == expected_nb | |
23 | # 'language_info' key seems to have arrived in metadata as a result of | |
24 | # nbconvert 5.3.1 -> 5.4.0 (5.4.0 released September 7 2018). Previously | |
25 | # it was empty. | |
26 | actual_nb['metadata'].pop('language_info', None) | |
27 | # 'execution' in cell metadata from nbconvert 6.0 | |
28 | for cell in actual_nb['cells']: | |
29 | if 'execution' in cell['metadata']: | |
30 | cell['metadata'].pop('execution') | |
31 | assert rm_ids(actual_nb) == rm_ids(expected_nb) |
0 | """ Configuration for py.test test run | |
0 | """ Skip the origin Gohlke transforms for doctests. | |
1 | ||
2 | That file needs some specific doctest setup. | |
1 | 3 | """ |
2 | 4 | |
3 | def pytest_ignore_collect(path, config): | |
4 | """ Skip the origin Gohlke transforms for doctests. | |
5 | from os.path import join as pjoin | |
5 | 6 | |
6 | That file needs some specific doctest setup. | |
7 | """ | |
8 | return path.basename in ('conf.py', 'rst_md_files') | |
7 | collect_ignore = [pjoin('proj1', "conf.py"), 'rst_md_files'] |
2 | 2 | from __future__ import unicode_literals |
3 | 3 | |
4 | 4 | from os.path import join as pjoin, isfile |
5 | import re | |
5 | 6 | |
6 | 7 | from nb2plots.testing import PlotsBuilder |
7 | 8 | |
112 | 113 | """ Markdown builder with specified base URL |
113 | 114 | """ |
114 | 115 | |
115 | conf_source = ('extensions = ["nb2plots"]\n' | |
116 | conf_source = ('master_doc = "contents"\n' | |
117 | 'extensions = ["nb2plots"]\n' | |
116 | 118 | 'markdown_http_base = "https://dynevor.org"') |
117 | 119 | |
118 | 120 | def test_output(self): |
119 | 121 | assert self.get_built_file('contents.md').strip() == '' |
120 | assert self.get_built_file('a_page.md') == """\ | |
121 | ## Refereed section | |
122 | ||
123 | This section refers to [itself](https://dynevor.org/a_page.html#a-ref). | |
124 | ||
125 | It also refers forward to the [next section](https://dynevor.org/a_page.html#b-ref). | |
126 | ||
127 | Then, and finally, it refers to itself with its own name: [Refereed section](https://dynevor.org/a_page.html#a-ref). | |
122 | expected_re = r"""## Refereed section | |
123 | ||
124 | This section refers to \[itself\]\(https://dynevor.org/a_page.html#a-ref\)\. | |
125 | ||
126 | It also refers forward to the \[next section\]\(https://dynevor.org/a_page.html#b-ref\)\. | |
127 | ||
128 | Then, and finally, it refers to itself with its own name: \[Refereed section\]\(https://dynevor.org/a_page\.html#a-ref\)\. | |
128 | 129 | |
129 | 130 | ## Rerefereed |
130 | 131 | |
131 | This section refers to this document at [Refereed section](https://dynevor.org/a_page.html), and with an | |
132 | explicit title, to [this document](https://dynevor.org/a_page.html). | |
133 | ||
134 | Then to [Refereed section](https://dynevor.org/a_page.html). Again to [another doc](https://dynevor.org/a_page.html). | |
135 | ||
136 | Now [a_page.rst](https://dynevor.org/_downloads/a_page.rst). | |
137 | ||
138 | Then [another page](https://dynevor.org/_downloads/a_page.rst). | |
139 | ||
140 | Then [a link](https://another-place.com/page.html). | |
141 | ||
142 | Again, we [link to another doc](https://dynevor.org/subdir1/b_page.html). | |
143 | """ | |
132 | This section refers to this document at \[Refereed section\]\(https://dynevor\.org/a_page\.html\), and with an | |
133 | explicit title, to \[this document\]\(https://dynevor\.org/a_page.html\)\. | |
134 | ||
135 | Then to \[Refereed section\]\(https://dynevor\.org/a_page.html\)\. Again to \[another doc\]\(https://dynevor\.org/a_page.html\)\. | |
136 | ||
137 | Now \[a_page\.rst\]\(https://dynevor.org/_downloads/([a-f0-9]+/)?a_page.rst\)\. | |
138 | ||
139 | Then \[another page\]\(https://dynevor\.org/_downloads/([a-f0-9]+/)?a_page.rst\)\. | |
140 | ||
141 | Then \[a link\]\(https://another-place.com/page.html\)\. | |
142 | ||
143 | Again, we \[link to another doc\]\(https://dynevor.org/subdir1/b_page\.html\)\. | |
144 | """ | |
145 | actual = self.get_built_file('a_page.md') | |
146 | assert re.match(expected_re, actual) | |
144 | 147 | assert self.get_built_file(pjoin('subdir1', 'b_page.md')) == """\ |
145 | 148 | ## Another page |
146 | 149 | |
197 | 200 | """ Python builder with specified base URL |
198 | 201 | """ |
199 | 202 | |
200 | conf_source = ('extensions = ["nb2plots"]\n' | |
203 | conf_source = ('master_doc = "contents"\n' | |
204 | 'extensions = ["nb2plots"]\n' | |
201 | 205 | 'markdown_http_base = "https://dynevor.org"') |
202 | 206 | |
203 | 207 | def test_output(self): |
229 | 233 | .. code-links:: |
230 | 234 | """} |
231 | 235 | |
236 | toctree_pages = list(rst_sources) | |
237 | ||
232 | 238 | def test_output(self): |
233 | 239 | for suffix in ('.py', '.ipynb', '_full.ipynb'): |
234 | 240 | assert isfile(pjoin(self.out_dir, 'foo', 'a_page' + suffix)) |
19 | 19 | .. code-links:: |
20 | 20 | |
21 | 21 | More text here.""" |
22 | both_re = re.compile("""\ | |
23 | <document source=".*?"> | |
22 | both_re = re.compile(r"""<document source=".*?"> | |
24 | 23 | <paragraph> |
25 | 24 | Text here |
26 | 25 | <code_links> |
60 | 59 | |
61 | 60 | More text here.""" |
62 | 61 | pxml = as_pxml(page) |
63 | assert re.match("""\ | |
64 | <document source=".*?"> | |
62 | assert re.match(r"""<document source=".*?"> | |
65 | 63 | <paragraph> |
66 | 64 | Text here |
67 | 65 | <code_links> |
80 | 78 | |
81 | 79 | More text here.""" |
82 | 80 | pxml = as_pxml(page) |
83 | assert re.match("""\ | |
84 | <document source=".*?"> | |
81 | assert re.match(r"""<document source=".*?"> | |
85 | 82 | <paragraph> |
86 | 83 | Text here |
87 | 84 | <code_links> |
100 | 97 | |
101 | 98 | More text here.""" |
102 | 99 | pxml = as_pxml(page) |
103 | assert re.match("""\ | |
104 | <document source=".*?"> | |
100 | assert re.match(r"""<document source=".*?"> | |
105 | 101 | <paragraph> |
106 | 102 | Text here |
107 | 103 | <code_links> |
24 | 24 | # pseudoxml converter |
25 | 25 | conv = Converter('pseudoxml') |
26 | 26 | pxml = conv.from_rst(NEW_PAGE) |
27 | assert re.search(r"""<document source=".*/contents.rst"> | |
27 | assert re.search(r"""<document source=".*/(contents|index)\.rst"> | |
28 | 28 | <section ids="more-fancy-title" names="more\\ fancy\\ title"> |
29 | 29 | <title> |
30 | 30 | More fancy title |
1 | 1 | """ |
2 | 2 | from os.path import join as pjoin |
3 | 3 | from glob import glob |
4 | import re | |
4 | 5 | |
5 | 6 | from nb2plots.converters import to_notebook |
6 | 7 | from nb2plots.ipython_shim import nbf |
15 | 16 | from nb2plots.testing.nbtesters import assert_nb_equiv |
16 | 17 | |
17 | 18 | |
19 | ID_RE = re.compile(r'"id":\s+".*?",\s*\n?') | |
20 | ||
21 | ||
18 | 22 | def to_nb_safe(rst_str): |
19 | 23 | out = to_notebook.from_rst(rst_str) |
20 | 24 | return unsmart_nb(out) |
26 | 30 | return nbf.writes(nb) |
27 | 31 | |
28 | 32 | |
33 | def rm_json_id(s): | |
34 | return ID_RE.sub(s, '') | |
35 | ||
36 | ||
29 | 37 | def assert_rst_cells_equal(rst_text, cells): |
30 | 38 | actual = to_notebook.from_rst(rst_text) |
31 | 39 | expected = cells2json(cells) |
32 | assert actual == expected | |
40 | assert rm_json_id(actual) == rm_json_id(expected) | |
33 | 41 | |
34 | 42 | |
35 | 43 | def test_basic(): |
5 | 5 | from ..ipython_shim import nbformat |
6 | 6 | from ..from_notebook import (convert_nb, convert_nb_fname, to_doctests, |
7 | 7 | has_mpl_inline, CODE_WITH_OUTPUT) |
8 | from ..testing import stripeq | |
8 | 9 | |
9 | 10 | |
10 | 11 | DATA_PATH = pjoin(dirname(__file__), 'data') |
19 | 20 | md_cell = v4.new_markdown_cell('# Some text') |
20 | 21 | nb['cells'] = [md_cell] |
21 | 22 | exp_text = "\nSome text\n=========\n" |
22 | assert convert_nb(nb) == exp_text | |
23 | assert stripeq(convert_nb(nb), exp_text) | |
23 | 24 | # Code -> replaced with plot directive / doctest markers |
24 | 25 | code_cell = v4.new_code_cell('a = 10') |
25 | 26 | nb['cells'] = [code_cell] |
26 | 27 | exp_code = PLT_HDR + " >>> a = 10\n" |
27 | assert convert_nb(nb) == exp_code | |
28 | assert stripeq(convert_nb(nb), exp_code) | |
28 | 29 | # Empty code -> no output |
29 | 30 | empty_code_cell = v4.new_code_cell('') |
30 | 31 | nb['cells'] = [empty_code_cell] |
34 | 35 | # magic lines get stripped |
35 | 36 | magic_code_cell = v4.new_code_cell('%timeit a = 1') |
36 | 37 | nb['cells'] = [magic_code_cell] |
37 | assert convert_nb(nb) == exp_empty_code | |
38 | assert stripeq(convert_nb(nb), exp_empty_code) | |
38 | 39 | # Magic lines stripped from within other code lines |
39 | 40 | mixed_magic_code_cell = v4.new_code_cell('%timeit a = 1\nb = 2') |
40 | 41 | exp_mixed_magic = PLT_HDR + " >>> b = 2\n" |
41 | 42 | nb['cells'] = [mixed_magic_code_cell] |
42 | assert convert_nb(nb) == exp_mixed_magic | |
43 | assert stripeq(convert_nb(nb), exp_mixed_magic) | |
43 | 44 | |
44 | 45 | |
45 | 46 | def test_mpl_inline_works(): |
49 | 50 | code_cell = v4.new_code_cell('%matplotlib inline\na = 10') |
50 | 51 | nb['cells'] = [code_cell] |
51 | 52 | exp_code = "\n.. mpl-interactive::\n{} >>> a = 10\n".format(PLT_HDR) |
52 | assert convert_nb(nb) == exp_code | |
53 | assert stripeq(convert_nb(nb), exp_code) | |
53 | 54 | |
54 | 55 | |
55 | 56 | def test_mpl_inline(): |
125 | 126 | rst_fname = pjoin(DATA_PATH, 'small.rst') |
126 | 127 | out = convert_nb_fname(nb_fname) |
127 | 128 | with open(rst_fname, 'rt') as fobj: |
128 | assert out + '\n' == fobj.read() | |
129 | assert stripeq(out, fobj.read()) | |
129 | 130 | |
130 | 131 | |
131 | 132 | code = \ |
6 | 6 | |
7 | 7 | from docutils.nodes import paragraph, title |
8 | 8 | |
9 | import sphinx | |
10 | ||
11 | SPHINX_ge_1p8 = sphinx.version_info[:2] >= (1, 8) | |
12 | ||
9 | 13 | from nb2plots.nbplots import (run_code, parse_parts, nbplot_container, |
10 | 14 | nbplot_epilogue) |
11 | 15 | from sphinxtesters import SourcesBuilder |
18 | 22 | |
19 | 23 | |
20 | 24 | HERE = dirname(__file__) |
25 | ||
26 | # Variation in doctest block. | |
27 | DOCTEST_BLOCK_RE = r'<doctest_block (classes="doctest" )?xml:space="preserve">' | |
21 | 28 | |
22 | 29 | |
23 | 30 | def get_otherpage(fname): |
469 | 476 | |
470 | 477 | builder = 'pseudoxml' |
471 | 478 | |
479 | literal_header = ( | |
480 | r'<literal_block ' + | |
481 | (r'force(_highlighting)?="False" language="default" linenos="False" ' | |
482 | if SPHINX_ge_1p8 else '') + | |
483 | 'xml:space="preserve">') | |
484 | ||
472 | 485 | rst_sources=dict(a_page="""\ |
473 | 486 | A title |
474 | 487 | ------- |
492 | 505 | def test_flags(self): |
493 | 506 | # Check that flags correctly set from flag directives |
494 | 507 | built = self.get_built_file('a_page.pseudoxml') |
495 | assert """ | |
508 | expected = r""" | |
496 | 509 | <title> |
497 | 510 | A title |
498 | <literal_block xml:space="preserve"> | |
499 | {'a': 1, 'b': 2} | |
511 | {literal_header} | |
512 | {{'a': 1, 'b': 2}} | |
500 | 513 | <paragraph> |
501 | 514 | Some text |
502 | <literal_block xml:space="preserve"> | |
503 | {'a': 1, 'b': 2, 'c': 3}""" in built | |
515 | {literal_header} | |
516 | {{'a': 1, 'b': 2, 'c': 3}}""".format( | |
517 | literal_header=self.literal_header) | |
518 | assert re.search(expected, built) | |
504 | 519 | |
505 | 520 | |
506 | 521 | class TestFlagsConfig(TestFlags): |
514 | 529 | def test_flags(self): |
515 | 530 | # Check that global flags merged with local |
516 | 531 | built = self.get_built_file('a_page.pseudoxml') |
517 | assert (""" | |
532 | expected = r""" | |
518 | 533 | <title> |
519 | 534 | A title |
520 | <literal_block xml:space="preserve"> | |
521 | {'a': 1, 'b': 2, 'flag1': 5, 'flag2': 6} | |
535 | {literal_header} | |
536 | {{'a': 1, 'b': 2, 'flag1': 5, 'flag2': 6}} | |
522 | 537 | <paragraph> |
523 | 538 | Some text |
524 | <literal_block xml:space="preserve"> | |
525 | {'a': 1, 'b': 2, 'c': 3, 'flag1': 5, 'flag2': 6}""" | |
526 | in built) | |
539 | {literal_header} | |
540 | {{'a': 1, 'b': 2, 'c': 3, 'flag1': 5, 'flag2': 6}}""".format( | |
541 | literal_header=self.literal_header) | |
542 | assert re.search(expected, built) | |
527 | 543 | |
528 | 544 | |
529 | 545 | class TestWithoutSkip(PlotsBuilder): |
625 | 641 | <title> |
626 | 642 | A title |
627 | 643 | <nbplot_container> |
628 | <doctest_block xml:space="preserve"> | |
644 | {DOCTEST_BLOCK_RE} | |
629 | 645 | >>> # always |
630 | 646 | >>> a = 'default' |
631 | 647 | <nbplot_epilogue> |
635 | 651 | <paragraph> |
636 | 652 | Some text |
637 | 653 | <nbplot_container> |
638 | <doctest_block xml:space="preserve"> | |
654 | {DOCTEST_BLOCK_RE} | |
639 | 655 | >>> a = 'skip is False' |
640 | 656 | <nbplot_epilogue> |
641 | 657 | <comment xml:space="preserve"> |
644 | 660 | <paragraph> |
645 | 661 | Keep text coming |
646 | 662 | <nbplot_container> |
647 | <doctest_block xml:space="preserve"> | |
663 | {DOCTEST_BLOCK_RE} | |
648 | 664 | >>> b = 'skip appears to be False' |
649 | 665 | >>> a == 'skip is False' |
650 | 666 | True |
655 | 671 | <paragraph> |
656 | 672 | Text continues |
657 | 673 | <nbplot_container> |
658 | <doctest_block xml:space="preserve"> | |
674 | {DOCTEST_BLOCK_RE} | |
659 | 675 | >>> # doctest only run when skip flag False, always rendered |
660 | 676 | >>> b == 'skip appears to be False' |
661 | True""") | |
677 | True""".format(**globals())) | |
662 | 678 | assert(regex.match(p_xml) is not None) |
663 | 679 | |
664 | 680 | |
694 | 710 | <title> |
695 | 711 | A title |
696 | 712 | <nbplot_container> |
697 | <doctest_block xml:space="preserve"> | |
713 | {DOCTEST_BLOCK_RE} | |
698 | 714 | >>> # always |
699 | 715 | >>> a = 'default' |
700 | 716 | <nbplot_epilogue> |
704 | 720 | <paragraph> |
705 | 721 | Some text |
706 | 722 | <nbplot_container> |
707 | <doctest_block xml:space="preserve"> | |
723 | {DOCTEST_BLOCK_RE} | |
708 | 724 | >>> a = 'skip is True' |
709 | 725 | <nbplot_epilogue> |
710 | 726 | <comment xml:space="preserve"> |
713 | 729 | <paragraph> |
714 | 730 | Keep text coming |
715 | 731 | <nbplot_container> |
716 | <doctest_block xml:space="preserve"> | |
732 | {DOCTEST_BLOCK_RE} | |
717 | 733 | >>> b = 'skip appears to be True' |
718 | 734 | >>> a == 'skip is True' |
719 | 735 | True |
733 | 749 | <comment xml:space="preserve"> |
734 | 750 | <comment xml:space="preserve"> |
735 | 751 | <nbplot_container hide-from="all" show-to="doctest"> |
736 | <doctest_block xml:space="preserve"> | |
752 | {DOCTEST_BLOCK_RE} | |
737 | 753 | >>> # only when skip flag True |
738 | 754 | >>> b == 'skip appears to be True' |
739 | True""") | |
755 | True""".format(**globals())) | |
740 | 756 | assert(regex.match(p_xml) is not None) |
741 | 757 | |
742 | 758 |
1 | 1 | |
2 | 2 | from os.path import (join as pjoin, dirname, isdir, exists) |
3 | 3 | |
4 | from sphinxtesters import ModifiedPageBuilder | |
4 | from sphinxtesters import PageBuilder | |
5 | 5 | |
6 | 6 | HERE = dirname(__file__) |
7 | 7 | |
11 | 11 | |
12 | 12 | """ |
13 | 13 | |
14 | class Proj1Builder(ModifiedPageBuilder): | |
14 | class Proj1Builder(PageBuilder): | |
15 | 15 | """ Build using 'proj1' directory as template to modify |
16 | 16 | """ |
17 | 17 | |
18 | 18 | page_source_template = pjoin(HERE, 'proj1') |
19 | ||
20 | # default_page used in 'replace_page' class method | |
21 | default_page = 'a_page.rst' | |
22 | 19 | |
23 | 20 | |
24 | 21 | class TestProj1(Proj1Builder): |
5 | 5 | from nb2plots.from_notebook import convert_nb_fname |
6 | 6 | from nb2plots.converters import to_py, to_notebook |
7 | 7 | |
8 | from nb2plots.testing import stripeq | |
8 | 9 | from nb2plots.testing.convutils import fcontents |
9 | 10 | from nb2plots.testing.nbtesters import assert_nb_equiv |
10 | 11 | |
18 | 19 | output_rst_fname = pjoin(DATA, 'converted_example.rst') |
19 | 20 | # Convert to ReST, add trailing CR from output script |
20 | 21 | rst = convert_nb_fname(input_nb_fname) + '\n' |
21 | assert rst.encode('utf8') == fcontents(output_rst_fname) | |
22 | assert stripeq(rst.encode('utf8'), fcontents(output_rst_fname)) | |
22 | 23 | # Convert ReST to output formats |
23 | 24 | py_file = to_py.from_rst(rst) |
24 | 25 | assert (py_file.encode('utf8') == |
71 | 71 | dict(code_type='clearnotebook', |
72 | 72 | filebase='contents', |
73 | 73 | base='/contents', |
74 | descr='Download this page as a Jupyter notebook \(no outputs\)'), | |
74 | descr=r'Download this page as a Jupyter notebook \(no outputs\)'), | |
75 | 75 | "Text then :clearnotebook:`.` then text.") |
76 | 76 | assert_rst_pxml( |
77 | 77 | dict(code_type='fullnotebook', |
78 | 78 | filebase='contents', |
79 | 79 | base='/contents', |
80 | 80 | descr=('Download this page as a Jupyter notebook ' |
81 | '\(with outputs\)')), | |
81 | r'\(with outputs\)')), | |
82 | 82 | "Text then :fullnotebook:`.` then text.") |
83 | 83 | assert_rst_pxml( |
84 | 84 | dict(code_type='pyfile', |
18 | 18 | .. nbplot:: |
19 | 19 | |
20 | 20 | >>> from time import sleep |
21 | >>> sleep(2) | |
21 | >>> sleep(5) | |
22 | 22 | """} |
23 | 23 | |
24 | 24 | |
47 | 47 | .. nbplot:: |
48 | 48 | |
49 | 49 | >>> from time import sleep |
50 | >>> sleep(2) | |
50 | >>> sleep(5) | |
51 | 51 | """} |
52 | 52 | |
53 | 53 | should_error = True |
69 | 69 | .. nbplot:: |
70 | 70 | |
71 | 71 | >>> from time import sleep |
72 | >>> sleep(2) | |
72 | >>> sleep(5) | |
73 | 73 | """} |
74 | 74 | |
75 | 75 | should_error = True |
102 | 102 | .. nbplot:: |
103 | 103 | |
104 | 104 | >>> from time import sleep |
105 | >>> sleep(2) | |
105 | >>> sleep(5) | |
106 | 106 | """} |
107 | 107 | |
108 | 108 | |
130 | 130 | .. nbplot:: |
131 | 131 | |
132 | 132 | >>> from time import sleep |
133 | >>> sleep(3) | |
133 | >>> sleep(5) | |
134 | 134 | """} |
0 | Metadata-Version: 1.1 | |
0 | Metadata-Version: 2.1 | |
1 | 1 | Name: nb2plots |
2 | Version: 0.6 | |
2 | Version: 0+unknown | |
3 | 3 | Summary: Converting between ipython notebooks and sphinx docs |
4 | 4 | Home-page: http://github.com/matthew-brett/nb2plots |
5 | 5 | Author: Matthew Brett |
6 | 6 | Author-email: matthew.brett@gmail.com |
7 | Maintainer: Matthew Brett | |
8 | Maintainer-email: matthew.brett@gmail.com | |
7 | 9 | License: BSD license |
8 | Description-Content-Type: UNKNOWN | |
9 | Description: ################################################## | |
10 | nb2plots - converting between notebooks and sphinx | |
11 | ################################################## | |
12 | ||
13 | See the nb2plots documentation_ for more information. | |
14 | ||
15 | .. shared-text-body | |
16 | ||
17 | ************ | |
18 | What it does | |
19 | ************ | |
20 | ||
21 | ``nb2plots`` converts Jupyter_ notebooks to ReST_ files for Sphinx_, and back | |
22 | again. | |
23 | ||
24 | Nb2plots assumes that the ReST document will become the source for your Sphinx | |
25 | web pages, but also for future versions of the notebook. The notebook may | |
26 | serve as a draft for the polished ReST page, and an output format from the | |
27 | Sphinx build. Why? Read on. | |
28 | ||
29 | **************************************** | |
30 | Why convert Jupyter notebooks to Sphinx? | |
31 | **************************************** | |
32 | ||
33 | Jupyter notebooks are just what the doctor ordered when hacking up a quick | |
34 | tutorial, or preparing a software demo. The problems start when you want to | |
35 | do not-trivial edits to the notebooks, or you need features that notebooks | |
36 | don't have, such as flexible cross-referencing, extensible markup, and so on. | |
37 | Notebooks are also painful to use with version control. These times make you | |
38 | wish your notebook was in a standard extensible text format, such as ReST_. | |
39 | ||
40 | You could convert your notebook to ReST using the standard `nbconvert`_ | |
41 | command, but this gives rather ugly ReST, and you lose all the nice code | |
42 | execution and figure generation that the notebook is good at. | |
43 | ||
44 | Enter Nb2plots. The ``nb2plots`` command converts notebooks to specially | |
45 | formatted ReST pages. Use with:: | |
46 | ||
47 | nb2plots notebook.ipynb > with_plots.rst | |
48 | ||
49 | Nb2plots converts your notebook to not-very-ugly ReST, where the code cells | |
50 | become ``nbplot`` directives in your ReST file. | |
51 | ||
52 | Specifically, a notebook code cell like this:: | |
53 | ||
54 | a = 1 | |
55 | ||
56 | becomes (in the ReST document):: | |
57 | ||
58 | .. nbplot:: | |
59 | ||
60 | >>> a = 1 | |
61 | ||
62 | The ``nbplot`` directives run the contained code when Sphinx builds your ReST | |
63 | files, and embed the results of any plots that your code makes. Actually, | |
64 | ``nbplot`` is an extended and edited version of the `matplotlib plot | |
65 | directive`_. Building your pages runs all the code and regenerates the | |
66 | figures, and you get much of the reproducible goodness of the notebook | |
67 | experience. | |
68 | ||
69 | You can also run the standard Sphinx ``doctest`` extension over your pages to | |
70 | check the doctest output of the code cells. | |
71 | ||
72 | The ReST version of your notebook has many advantages - it is easier to edit | |
73 | in your favorite text editor, and you can extend and configure the execution | |
74 | and display of the code in several different ways. For example, you can hide | |
75 | some code cells (Nbplot directives) if the code is not interesting to your | |
76 | point, but you still want the generated figure. You can configure your Nbplot | |
77 | directives to run different code for different configurations. For these | |
78 | options, see |nbplot-documentation|. But - what do you lose, when going from | |
79 | a notebook to a Nb2plots ReST document? | |
80 | ||
81 | ********************************** | |
82 | I want notebooks and .py files too | |
83 | ********************************** | |
84 | ||
85 | You may also want a version of your document that your users can execute. | |
86 | Perhaps the page build is generating some tricky errors or warnings, and you | |
87 | want to experiment with the code in the page interactively. Perhaps your | |
88 | users are used to notebooks, and prefer the code in that format. | |
89 | ||
90 | Nb2plots also contains Sphinx extensions that cause the Sphinx build to | |
91 | generate Python code files and Jupyter notebooks from the ReST source. When | |
92 | you add the Nb2plots ReST directive ``code-links`` to your ReST page, it will | |
93 | cause the Sphinx build to create a Python code file and notebook versions of | |
94 | your page, and adds download links to these versions:: | |
95 | ||
96 | .. code-links:: | |
97 | ||
98 | See |code-links-documentation| for details. | |
99 | ||
100 | ************************** | |
101 | Show me what it looks like | |
102 | ************************** | |
103 | ||
104 | For a very simple example, see |worked-example|. | |
105 | ||
106 | For a moderate-sized teaching site that makes extensive use of Nb2plots, see | |
107 | https://matthew-brett.github.com/teaching. | |
108 | ||
109 | ************ | |
110 | Installation | |
111 | ************ | |
112 | ||
113 | :: | |
114 | ||
115 | pip install nb2plots | |
116 | ||
117 | You will need Pandoc_ installed and available as the ``pandoc`` command. | |
118 | ||
119 | To install Pandoc on OSX, we recommend homebrew_:: | |
120 | ||
121 | brew install pandoc | |
122 | ||
123 | ************* | |
124 | Configuration | |
125 | ************* | |
126 | ||
127 | Add the following to your Sphinx ``conf.py`` file:: | |
128 | ||
129 | extensions = ["nb2plots"] | |
130 | ||
131 | See |nbplot-documentation| for the various ``conf.py`` configuration settings. | |
132 | ||
133 | **** | |
134 | Code | |
135 | **** | |
136 | ||
137 | See https://github.com/matthew-brett/nb2plots | |
138 | ||
139 | Released under the BSD two-clause license - see the file ``LICENSE`` in the | |
140 | source distribution. | |
141 | ||
142 | `travis-ci <https://travis-ci.org/matthew-brett/nb2plots>`_ kindly tests the | |
143 | code automatically under Python versions 2.7, and 3.3 through 3.5. | |
144 | ||
145 | The latest released version is at https://pypi.python.org/pypi/nb2plots | |
146 | ||
147 | ***** | |
148 | Tests | |
149 | ***** | |
150 | ||
151 | * Install ``nb2plots`` | |
152 | * Install the pytest_ testing framework, the ``mock`` package, and the | |
153 | ``scripttester`` package. | |
154 | ||
155 | pip install pytest mock scripttester | |
156 | ||
157 | * Run the tests with:: | |
158 | ||
159 | py.test --pyargs nb2plots | |
160 | ||
161 | ******* | |
162 | Support | |
163 | ******* | |
164 | ||
165 | Please put up issues on the `nb2plots issue tracker`_. | |
166 | ||
167 | .. standalone-references | |
168 | ||
169 | .. |nbplot-documentation| replace:: `nbplots documentation`_ | |
170 | .. |worked-example| replace:: `worked example`_ | |
171 | .. |code-links-documentation| replace:: `code-links documentation`_ | |
172 | .. _nbplots documentation: | |
173 | https://matthew-brett.github.com/nb2plots/nbplots.html | |
174 | .. _code-links documentation: | |
175 | https://matthew-brett.github.com/nb2plots/code_links.html | |
176 | .. _worked example: | |
177 | https://matthew-brett.github.com/nb2plots/worked_example.html | |
178 | .. _documentation: https://matthew-brett.github.com/nb2plots | |
179 | .. _pandoc: http://pandoc.org | |
180 | .. _jupyter: jupyter.org | |
181 | .. _homebrew: brew.sh | |
182 | .. _sphinx: http://sphinx-doc.org | |
183 | .. _rest: http://docutils.sourceforge.net/rst.html | |
184 | .. _nb2plots issue tracker: https://github.com/matthew-brett/nb2plots/issues | |
185 | .. _matplotlib plot directive: http://matplotlib.org/sampledoc/extensions.html | |
186 | .. _nbconvert: http://nbconvert.readthedocs.org/en/latest/ | |
187 | .. _pytest: https://pytest.readthedocs.io | |
188 | .. _mock: https://github.com/testing-cabal/mock | |
189 | ||
190 | 10 | Platform: UNKNOWN |
191 | 11 | Classifier: Development Status :: 2 - Pre-Alpha |
192 | 12 | Classifier: Environment :: Console |
200 | 20 | Classifier: Operating System :: POSIX |
201 | 21 | Classifier: Operating System :: Unix |
202 | 22 | Classifier: Operating System :: MacOS |
23 | Provides-Extra: test | |
24 | License-File: LICENSE | |
25 | ||
26 | ################################################## | |
27 | nb2plots - converting between notebooks and sphinx | |
28 | ################################################## | |
29 | ||
30 | See the nb2plots documentation_ for more information. | |
31 | ||
32 | .. shared-text-body | |
33 | ||
34 | ************ | |
35 | What it does | |
36 | ************ | |
37 | ||
38 | ``nb2plots`` converts Jupyter_ notebooks to ReST_ files for Sphinx_, and back | |
39 | again. | |
40 | ||
41 | Nb2plots assumes that the ReST document will become the source for your Sphinx | |
42 | web pages, but also for future versions of the notebook. The notebook may | |
43 | serve as a draft for the polished ReST page, and an output format from the | |
44 | Sphinx build. Why? Read on. | |
45 | ||
46 | **************************************** | |
47 | Why convert Jupyter notebooks to Sphinx? | |
48 | **************************************** | |
49 | ||
50 | Jupyter notebooks are just what the doctor ordered when hacking up a quick | |
51 | tutorial, or preparing a software demo. The problems start when you want to | |
52 | do not-trivial edits to the notebooks, or you need features that notebooks | |
53 | don't have, such as flexible cross-referencing, extensible markup, and so on. | |
54 | Notebooks are also painful to use with version control. These times make you | |
55 | wish your notebook was in a standard extensible text format, such as ReST_. | |
56 | ||
57 | You could convert your notebook to ReST using the standard `nbconvert`_ | |
58 | command, but this gives rather ugly ReST, and you lose all the nice code | |
59 | execution and figure generation that the notebook is good at. | |
60 | ||
61 | Enter Nb2plots. The ``nb2plots`` command converts notebooks to specially | |
62 | formatted ReST pages. Use with:: | |
63 | ||
64 | nb2plots notebook.ipynb > with_plots.rst | |
65 | ||
66 | Nb2plots converts your notebook to not-very-ugly ReST, where the code cells | |
67 | become ``nbplot`` directives in your ReST file. | |
68 | ||
69 | Specifically, a notebook code cell like this:: | |
70 | ||
71 | a = 1 | |
72 | ||
73 | becomes (in the ReST document):: | |
74 | ||
75 | .. nbplot:: | |
76 | ||
77 | >>> a = 1 | |
78 | ||
79 | The ``nbplot`` directives run the contained code when Sphinx builds your ReST | |
80 | files, and embed the results of any plots that your code makes. Actually, | |
81 | ``nbplot`` is an extended and edited version of the `matplotlib plot | |
82 | directive`_. Building your pages runs all the code and regenerates the | |
83 | figures, and you get much of the reproducible goodness of the notebook | |
84 | experience. | |
85 | ||
86 | You can also run the standard Sphinx ``doctest`` extension over your pages to | |
87 | check the doctest output of the code cells. | |
88 | ||
89 | The ReST version of your notebook has many advantages - it is easier to edit | |
90 | in your favorite text editor, and you can extend and configure the execution | |
91 | and display of the code in several different ways. For example, you can hide | |
92 | some code cells (Nbplot directives) if the code is not interesting to your | |
93 | point, but you still want the generated figure. You can configure your Nbplot | |
94 | directives to run different code for different configurations. For these | |
95 | options, see |nbplot-documentation|. But - what do you lose, when going from | |
96 | a notebook to a Nb2plots ReST document? | |
97 | ||
98 | ********************************** | |
99 | I want notebooks and .py files too | |
100 | ********************************** | |
101 | ||
102 | You may also want a version of your document that your users can execute. | |
103 | Perhaps the page build is generating some tricky errors or warnings, and you | |
104 | want to experiment with the code in the page interactively. Perhaps your | |
105 | users are used to notebooks, and prefer the code in that format. | |
106 | ||
107 | Nb2plots also contains Sphinx extensions that cause the Sphinx build to | |
108 | generate Python code files and Jupyter notebooks from the ReST source. When | |
109 | you add the Nb2plots ReST directive ``code-links`` to your ReST page, it will | |
110 | cause the Sphinx build to create a Python code file and notebook versions of | |
111 | your page, and adds download links to these versions:: | |
112 | ||
113 | .. code-links:: | |
114 | ||
115 | See |code-links-documentation| for details. | |
116 | ||
117 | ************************** | |
118 | Show me what it looks like | |
119 | ************************** | |
120 | ||
121 | For a very simple example, see |worked-example|. | |
122 | ||
123 | For a moderate-sized teaching site that makes extensive use of Nb2plots, see | |
124 | https://matthew-brett.github.com/teaching. | |
125 | ||
126 | ************ | |
127 | Installation | |
128 | ************ | |
129 | ||
130 | :: | |
131 | ||
132 | pip install nb2plots | |
133 | ||
134 | You will need Pandoc_ installed and available as the ``pandoc`` command. | |
135 | ||
136 | To install Pandoc on OSX, we recommend homebrew_:: | |
137 | ||
138 | brew install pandoc | |
139 | ||
140 | ************* | |
141 | Configuration | |
142 | ************* | |
143 | ||
144 | Add the following to your Sphinx ``conf.py`` file:: | |
145 | ||
146 | extensions = ["nb2plots"] | |
147 | ||
148 | See |nbplot-documentation| for the various ``conf.py`` configuration settings. | |
149 | ||
150 | **** | |
151 | Code | |
152 | **** | |
153 | ||
154 | See https://github.com/matthew-brett/nb2plots | |
155 | ||
156 | Released under the BSD two-clause license - see the file ``LICENSE`` in the | |
157 | source distribution. | |
158 | ||
159 | `travis-ci <https://travis-ci.org/matthew-brett/nb2plots>`_ kindly tests the | |
160 | code automatically under Python versions 2.7, and 3.5 through 3.8. | |
161 | ||
162 | The latest released version is at https://pypi.python.org/pypi/nb2plots | |
163 | ||
164 | ***** | |
165 | Tests | |
166 | ***** | |
167 | ||
168 | * Install ``nb2plots`` | |
169 | * Install the pytest_ testing framework, the ``mock`` package, and the | |
170 | ``scripttester`` package. | |
171 | ||
172 | pip install pytest mock scripttester | |
173 | ||
174 | * Run the tests with:: | |
175 | ||
176 | py.test --pyargs nb2plots | |
177 | ||
178 | ******* | |
179 | Support | |
180 | ******* | |
181 | ||
182 | Please put up issues on the `nb2plots issue tracker`_. | |
183 | ||
184 | .. standalone-references | |
185 | ||
186 | .. |nbplot-documentation| replace:: `nbplots documentation`_ | |
187 | .. |worked-example| replace:: `worked example`_ | |
188 | .. |code-links-documentation| replace:: `code-links documentation`_ | |
189 | .. _nbplots documentation: | |
190 | https://matthew-brett.github.com/nb2plots/nbplots.html | |
191 | .. _code-links documentation: | |
192 | https://matthew-brett.github.com/nb2plots/code_links.html | |
193 | .. _worked example: | |
194 | https://matthew-brett.github.com/nb2plots/worked_example.html | |
195 | .. _documentation: https://matthew-brett.github.com/nb2plots | |
196 | .. _pandoc: http://pandoc.org | |
197 | .. _jupyter: jupyter.org | |
198 | .. _homebrew: brew.sh | |
199 | .. _sphinx: http://sphinx-doc.org | |
200 | .. _rest: http://docutils.sourceforge.net/rst.html | |
201 | .. _nb2plots issue tracker: https://github.com/matthew-brett/nb2plots/issues | |
202 | .. _matplotlib plot directive: http://matplotlib.org/sampledoc/extensions.html | |
203 | .. _nbconvert: http://nbconvert.readthedocs.org/en/latest/ | |
204 | .. _pytest: https://pytest.readthedocs.io | |
205 | .. _mock: https://github.com/testing-cabal/mock | |
206 | ||
207 |
0 | ipython[notebook]>=3.0 | |
0 | ipython[notebook]>=4.0 | |
1 | matplotlib>=2.0 | |
2 | numpy>=1.7.1 | |
3 | six>=1.10 | |
1 | 4 | sphinx>=1.4 |
2 | numpy>=1.6.1 | |
3 | matplotlib>=1.1.0 | |
4 | six>=1.7.0 | |
5 | sphinxtesters | |
5 | sphinxtesters>=0.2 | |
6 | 6 | texext |
7 | 7 | |
8 | 8 | [test] |
9 | mock | |
9 | 10 | pytest |
10 | mock | |
11 | 11 | scripttester |