##// END OF EJS Templates
Merged upstream master
David P. Sanders -
r11600:e859739e merge
parent child Browse files
Show More
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,30 b''
1 """
2 Module with tests base for exporters
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 import os
18
19 from ...tests.base import TestsBase
20
21 #-----------------------------------------------------------------------------
22 # Class
23 #-----------------------------------------------------------------------------
24
25 class ExportersTestsBase(TestsBase):
26 """Contains base test functions for exporters"""
27
28 def _get_notebook(self):
29 return os.path.join(self._get_files_path(), 'notebook2.ipynb')
30 No newline at end of file
@@ -0,0 +1,48 b''
1 """
2 Contains CheeseTransformer
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
16 from ...transformers.base import Transformer
17
18 #-----------------------------------------------------------------------------
19 # Classes
20 #-----------------------------------------------------------------------------
21
22 class CheeseTransformer(Transformer):
23 """
24 Adds a cheese tag to the resources object
25 """
26
27
28 def __init__(self, **kw):
29 """
30 Public constructor
31 """
32 super(CheeseTransformer, self).__init__(**kw)
33
34
35 def call(self, nb, resources):
36 """
37 Sphinx transformation to apply on each notebook.
38
39 Parameters
40 ----------
41 nb : NotebookNode
42 Notebook being converted
43 resources : dictionary
44 Additional resources used in the conversion process. Allows
45 transformers to pass variables into the Jinja engine.
46 """
47 resources['cheese'] = 'real'
48 return nb, resources
@@ -0,0 +1,177 b''
1 {
2 "metadata": {
3 "name": "notebook2"
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
9 "cells": [
10 {
11 "cell_type": "heading",
12 "level": 1,
13 "metadata": {},
14 "source": [
15 "NumPy and Matplotlib examples"
16 ]
17 },
18 {
19 "cell_type": "markdown",
20 "metadata": {},
21 "source": [
22 "First import NumPy and Matplotlib:"
23 ]
24 },
25 {
26 "cell_type": "code",
27 "collapsed": false,
28 "input": [
29 "%pylab inline"
30 ],
31 "language": "python",
32 "metadata": {},
33 "outputs": [
34 {
35 "output_type": "stream",
36 "stream": "stdout",
37 "text": [
38 "\n",
39 "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].\n",
40 "For more information, type 'help(pylab)'.\n"
41 ]
42 }
43 ],
44 "prompt_number": 1
45 },
46 {
47 "cell_type": "code",
48 "collapsed": false,
49 "input": [
50 "import numpy as np"
51 ],
52 "language": "python",
53 "metadata": {},
54 "outputs": [],
55 "prompt_number": 2
56 },
57 {
58 "cell_type": "markdown",
59 "metadata": {},
60 "source": [
61 "Now we show some very basic examples of how they can be used."
62 ]
63 },
64 {
65 "cell_type": "code",
66 "collapsed": false,
67 "input": [
68 "a = np.random.uniform(size=(100,100))"
69 ],
70 "language": "python",
71 "metadata": {},
72 "outputs": [],
73 "prompt_number": 6
74 },
75 {
76 "cell_type": "code",
77 "collapsed": false,
78 "input": [
79 "a.shape"
80 ],
81 "language": "python",
82 "metadata": {},
83 "outputs": [
84 {
85 "metadata": {},
86 "output_type": "pyout",
87 "prompt_number": 7,
88 "text": [
89 "(100, 100)"
90 ]
91 }
92 ],
93 "prompt_number": 7
94 },
95 {
96 "cell_type": "code",
97 "collapsed": false,
98 "input": [
99 "evs = np.linalg.eigvals(a)"
100 ],
101 "language": "python",
102 "metadata": {},
103 "outputs": [],
104 "prompt_number": 8
105 },
106 {
107 "cell_type": "code",
108 "collapsed": false,
109 "input": [
110 "evs.shape"
111 ],
112 "language": "python",
113 "metadata": {},
114 "outputs": [
115 {
116 "metadata": {},
117 "output_type": "pyout",
118 "prompt_number": 10,
119 "text": [
120 "(100,)"
121 ]
122 }
123 ],
124 "prompt_number": 10
125 },
126 {
127 "cell_type": "markdown",
128 "metadata": {},
129 "source": [
130 "Here is a cell that has both text and PNG output:"
131 ]
132 },
133 {
134 "cell_type": "code",
135 "collapsed": false,
136 "input": [
137 "hist(evs.real)"
138 ],
139 "language": "python",
140 "metadata": {},
141 "outputs": [
142 {
143 "metadata": {},
144 "output_type": "pyout",
145 "prompt_number": 14,
146 "text": [
147 "(array([95, 4, 0, 0, 0, 0, 0, 0, 0, 1]),\n",
148 " array([ -2.93566063, 2.35937011, 7.65440086, 12.9494316 ,\n",
149 " 18.24446235, 23.53949309, 28.83452384, 34.12955458,\n",
150 " 39.42458533, 44.71961607, 50.01464682]),\n",
151 " <a list of 10 Patch objects>)"
152 ]
153 },
154 {
155 "metadata": {},
156 "output_type": "display_data",
157 "png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAD9CAYAAAC2l2x5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEhdJREFUeJzt3X1olfX/x/HXtVbT8CZDmsK6KmrubEu3U2xnZOpxLBnG\nOqsIE7RoE3QRZkT/yEAjcIh/LIs6i/BEGSU1CkxT0+pkFp1zMmsxZ5uUTIXoxm95lmdlef3+8Nep\ndbtz7exs16fnAw7sXNs5n/c14nmurl3naDmO4wgAYJy8sR4AADA6CDwAGIrAA4ChCDwAGIrAA4Ch\nCDwAGOofA9/U1KTCwkLNnj07vS2ZTCoUCsm2bTU2NmpgYCD9vccee0zFxcUqKyvTgQMHRm9qAMC/\n+sfA33PPPdq9e/eQbeFwWLZtq6+vT0VFRero6JAkffXVV3ryySf15ptvKhwOa/Xq1aM3NQDgX/1j\n4OfNm6dp06YN2RaPx9Xc3KyCggI1NTUpFotJkmKxmOrr62XbthYsWCDHcZRMJkdvcgDAP8r4HHwi\nkZDP55Mk+Xw+xeNxSecDX1pamv65kpKS9PcAALmXn+kDMvlkA8uyhrUNAPDvMv1kmYyP4KuqqtTT\n0yNJ6unpUVVVlSQpEAjo8OHD6Z87cuRI+nt/NaRXb+vWrRvzGZh/7Odgfu/dvDy747j7yLCMAx8I\nBBSJRJRKpRSJRFRTUyNJqq6u1p49e9Tf369oNKq8vDxNnjzZ1VAAgJH7x8AvXbpUN9xwg3p7e3X5\n5ZfrmWeeUUtLi/r7+1VSUqKTJ09q1apVkqTCwkK1tLSotrZW9957rzZv3pyTHQAA/DXLcXvs73ZB\ny3L9vxvjQTQaVTAYHOsxXGP+scX8Y8fLs0vu2kngAcAD3LSTjyoAAEMReAAwFIEHAEMReAAwFIEH\nAEP9ZwM/Zcqlsixr1G9Tplw61rsK4D/qP3uZ5PnPxMnFHONjfwF4G5dJAgDSCDwAGIrAA4ChCDwA\nGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrA\nA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChXAf+6aef1g03\n3KDrr79ea9askSQlk0mFQiHZtq3GxkYNDAxkbVAAQGZcBf7UqVPasGGD9u7dq0Qiod7eXu3Zs0fh\ncFi2bauvr09FRUXq6OjI9rwAgGFyFfiJEyfKcRx9//33SqVSOnPmjC655BLF43E1NzeroKBATU1N\nisVi2Z4XADBMrgMfDod15ZVXasaMGZo7d64CgYASiYR8Pp8kyefzKR6PZ3VYAMDw5bt50Ndff62W\nlhYdPnxY06ZN0x133KEdO3bIcZxhPX79+vXpr4PBoILBoJsxAMBY0WhU0Wh0RM9hOcOt8u/s3LlT\nW7du1bZt2yRJ4XBYx44d09GjR9Xa2iq/36+DBw+qra1NnZ2dQxe0rGG/EIwmy7Ik5WKO8bG/ALzN\nTTtdnaKZN2+ePvzwQ506dUo//vijdu3apUWLFikQCCgSiSiVSikSiaimpsbN0wMAssBV4KdMmaLW\n1lbdeuutuvHGG1VRUaGFCxeqpaVF/f39Kikp0cmTJ7Vq1apszwsAGCZXp2hGtCCnaAAgYzk7RQMA\nGP8IPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEI\nPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAY\nisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYynXgf/jhB919992a\nNWuWysrKFIvFlEwmFQqFZNu2GhsbNTAwkM1ZAQAZcB34devWybZtdXV1qaurSz6fT+FwWLZtq6+v\nT0VFRero6MjmrACADLgO/L59+7R27VpNmDBB+fn5mjp1quLxuJqbm1VQUKCmpibFYrFszgoAyICr\nwJ84cUKDg4NqaWlRIBDQxo0blUqllEgk5PP5JEk+n0/xeDyrwwIAhi/fzYMGBwfV29urTZs2qa6u\nTitXrtRLL70kx3GG9fj169envw4GgwoGg27GAABjRaNRRaPRET2H5Qy3yn9QWlqqnp4eSdKuXbv0\n3HPP6aefflJra6v8fr8OHjyotrY2dXZ2Dl3Qsob9QjCaLMuSlIs5xsf+AvA2N+10fQ6+uLhYsVhM\n586d086dO1VXV6dAIKBIJKJUKqVIJKKamhq3Tw8AGCHXR/C9vb266667NDg4qLq6Oj388MM6d+6c\nli1bpkOHDum6667T888/r0mTJg1dkCN4AMiYm3a6DrxbBB4AMpfTUzQAgPGNwAOAoQg8ABiKwAOA\n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\n",
158 "text": [
159 "<matplotlib.figure.Figure at 0x108c8f1d0>"
160 ]
161 }
162 ],
163 "prompt_number": 14
164 },
165 {
166 "cell_type": "code",
167 "collapsed": false,
168 "input": [],
169 "language": "python",
170 "metadata": {},
171 "outputs": []
172 }
173 ],
174 "metadata": {}
175 }
176 ]
177 } No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for basichtml.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..basichtml import BasicHTMLExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestBasicHTMLExporter(ExportersTestsBase):
25 """Contains test functions for basichtml.py"""
26
27 def test_constructor(self):
28 """
29 Can a BasicHTMLExporter be constructed?
30 """
31 BasicHTMLExporter()
32
33
34 def test_export(self):
35 """
36 Can a BasicHTMLExporter export something?
37 """
38 (output, resources) = BasicHTMLExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
@@ -0,0 +1,102 b''
1 """
2 Module with tests for export.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 import os
18
19 from IPython.nbformat import current as nbformat
20
21 from .base import ExportersTestsBase
22 from ..export import *
23 from ..python import PythonExporter
24
25 #-----------------------------------------------------------------------------
26 # Class
27 #-----------------------------------------------------------------------------
28
29 class TestExport(ExportersTestsBase):
30 """Contains test functions for export.py"""
31
32
33 def test_export_wrong_name(self):
34 """
35 Is the right error thrown when a bad template name is used?
36 """
37 try:
38 export_by_name('not_a_name', self._get_notebook())
39 except ExporterNameError as e:
40 pass
41
42
43 def test_export_filename(self):
44 """
45 Can a notebook be exported by filename?
46 """
47 (output, resources) = export_by_name('python', self._get_notebook())
48 assert len(output) > 0
49
50
51 def test_export_nbnode(self):
52 """
53 Can a notebook be exported by a notebook node handle?
54 """
55 with open(self._get_notebook(), 'r') as f:
56 notebook = nbformat.read(f, 'json')
57 (output, resources) = export_by_name('python', notebook)
58 assert len(output) > 0
59
60
61 def test_export_filestream(self):
62 """
63 Can a notebook be exported by a filesteam?
64 """
65 with open(self._get_notebook(), 'r') as f:
66 (output, resources) = export_by_name('python', f)
67 assert len(output) > 0
68
69
70 def test_export_using_exporter(self):
71 """
72 Can a notebook be exported using an instanciated exporter?
73 """
74 (output, resources) = export(PythonExporter(), self._get_notebook())
75 assert len(output) > 0
76
77
78 def test_export_using_exporter_class(self):
79 """
80 Can a notebook be exported using an exporter class type?
81 """
82 (output, resources) = export(PythonExporter, self._get_notebook())
83 assert len(output) > 0
84
85
86 def test_export_resources(self):
87 """
88 Can a notebook be exported along with a custom resources dict?
89 """
90 (output, resources) = export(PythonExporter, self._get_notebook(), resources={})
91 assert len(output) > 0
92
93
94 def test_no_exporter(self):
95 """
96 Is the right error thrown if no exporter is provided?
97 """
98 try:
99 (output, resources) = export(None, self._get_notebook())
100 except TypeError:
101 pass
102 No newline at end of file
@@ -0,0 +1,113 b''
1 """
2 Module with tests for exporter.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from IPython.config import Config
18
19 from .base import ExportersTestsBase
20 from .cheese import CheeseTransformer
21 from ..exporter import Exporter
22
23
24 #-----------------------------------------------------------------------------
25 # Class
26 #-----------------------------------------------------------------------------
27
28 class TestExporter(ExportersTestsBase):
29 """Contains test functions for exporter.py"""
30
31
32 def test_constructor(self):
33 """
34 Can an Exporter be constructed?
35 """
36 Exporter()
37
38
39 def test_export(self):
40 """
41 Can an Exporter export something?
42 """
43 exporter = self._make_exporter()
44 (output, resources) = exporter.from_filename(self._get_notebook())
45 assert len(output) > 0
46
47
48 def test_extract_figures(self):
49 """
50 If the ExtractFigureTransformer is enabled, are figures extracted?
51 """
52 config = Config({'ExtractFigureTransformer': {'enabled': True}})
53 exporter = self._make_exporter(config=config)
54 (output, resources) = exporter.from_filename(self._get_notebook())
55 assert resources is not None
56 assert 'figures' in resources
57 assert len(resources['figures']) > 0
58
59
60 def test_transformer_class(self):
61 """
62 Can a transformer be added to the transformers list by class type?
63 """
64 config = Config({'Exporter': {'transformers': [CheeseTransformer]}})
65 exporter = self._make_exporter(config=config)
66 (output, resources) = exporter.from_filename(self._get_notebook())
67 assert resources is not None
68 assert 'cheese' in resources
69 assert resources['cheese'] == 'real'
70
71
72 def test_transformer_instance(self):
73 """
74 Can a transformer be added to the transformers list by instance?
75 """
76 config = Config({'Exporter': {'transformers': [CheeseTransformer()]}})
77 exporter = self._make_exporter(config=config)
78 (output, resources) = exporter.from_filename(self._get_notebook())
79 assert resources is not None
80 assert 'cheese' in resources
81 assert resources['cheese'] == 'real'
82
83
84 def test_transformer_dottedobjectname(self):
85 """
86 Can a transformer be added to the transformers list by dotted object name?
87 """
88 config = Config({'Exporter': {'transformers': ['IPython.nbconvert.exporters.tests.cheese.CheeseTransformer']}})
89 exporter = self._make_exporter(config=config)
90 (output, resources) = exporter.from_filename(self._get_notebook())
91 assert resources is not None
92 assert 'cheese' in resources
93 assert resources['cheese'] == 'real'
94
95
96 def test_transformer_via_method(self):
97 """
98 Can a transformer be added via the Exporter convinience method?
99 """
100 exporter = self._make_exporter()
101 exporter.register_transformer(CheeseTransformer, enabled=True)
102 (output, resources) = exporter.from_filename(self._get_notebook())
103 assert resources is not None
104 assert 'cheese' in resources
105 assert resources['cheese'] == 'real'
106
107
108 def _make_exporter(self, config=None):
109 #Create the exporter instance, make sure to set a template name since
110 #the base Exporter doesn't have a template associated with it.
111 exporter = Exporter(config=config)
112 exporter.template_file = 'python'
113 return exporter No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for fullhtml.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..fullhtml import FullHTMLExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestFullHTMLExporter(ExportersTestsBase):
25 """Contains test functions for fullhtml.py"""
26
27 def test_constructor(self):
28 """
29 Can a FullHTMLExporter be constructed?
30 """
31 FullHTMLExporter()
32
33
34 def test_export(self):
35 """
36 Can a FullHTMLExporter export something?
37 """
38 (output, resources) = FullHTMLExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for latex.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..latex import LatexExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestLatexExporter(ExportersTestsBase):
25 """Contains test functions for latex.py"""
26
27 def test_constructor(self):
28 """
29 Can a LatexExporter be constructed?
30 """
31 LatexExporter()
32
33
34 def test_export(self):
35 """
36 Can a LatexExporter export something?
37 """
38 (output, resources) = LatexExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for markdown.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..markdown import MarkdownExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestMarkdownExporter(ExportersTestsBase):
25 """Contains test functions for markdown.py"""
26
27 def test_constructor(self):
28 """
29 Can a MarkdownExporter be constructed?
30 """
31 MarkdownExporter()
32
33
34 def test_export(self):
35 """
36 Can a MarkdownExporter export something?
37 """
38 (output, resources) = MarkdownExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for python.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..python import PythonExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestPythonExporter(ExportersTestsBase):
25 """Contains test functions for python.py"""
26
27 def test_constructor(self):
28 """
29 Can a PythonExporter be constructed?
30 """
31 PythonExporter()
32
33
34 def test_export(self):
35 """
36 Can a PythonExporter export something?
37 """
38 (output, resources) = PythonExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for reveal.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..reveal import RevealExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestRevealExporter(ExportersTestsBase):
25 """Contains test functions for reveal.py"""
26
27 def test_constructor(self):
28 """
29 Can a RevealExporter be constructed?
30 """
31 RevealExporter()
32
33
34 def test_export(self):
35 """
36 Can a RevealExporter export something?
37 """
38 (output, resources) = RevealExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for rst.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..rst import RSTExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestRSTExporter(ExportersTestsBase):
25 """Contains test functions for rst.py"""
26
27 def test_constructor(self):
28 """
29 Can a RSTExporter be constructed?
30 """
31 RSTExporter()
32
33
34 def test_export(self):
35 """
36 Can a RSTExporter export something?
37 """
38 (output, resources) = RSTExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for sphinx_howto.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..sphinx_howto import SphinxHowtoExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestSphinxHowtoExporter(ExportersTestsBase):
25 """Contains test functions for sphinx_howto.py"""
26
27 def test_constructor(self):
28 """
29 Can a SphinxHowtoExporter be constructed?
30 """
31 SphinxHowtoExporter()
32
33
34 def test_export(self):
35 """
36 Can a SphinxHowtoExporter export something?
37 """
38 (output, resources) = SphinxHowtoExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
@@ -0,0 +1,39 b''
1 """
2 Module with tests for sphinx_manual.py
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from .base import ExportersTestsBase
18 from ..sphinx_manual import SphinxManualExporter
19
20 #-----------------------------------------------------------------------------
21 # Class
22 #-----------------------------------------------------------------------------
23
24 class TestSphinxManualExporter(ExportersTestsBase):
25 """Contains test functions for sphinx_manual.py"""
26
27 def test_constructor(self):
28 """
29 Can a SphinxManualExporter be constructed?
30 """
31 SphinxManualExporter()
32
33
34 def test_export(self):
35 """
36 Can a SphinxManualExporter export something?
37 """
38 (output, resources) = SphinxManualExporter().from_filename(self._get_notebook())
39 assert len(output) > 0 No newline at end of file
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,91 b''
1 """
2 Module with tests for ansi filters
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from IPython.utils.coloransi import TermColors
18
19 from ...tests.base import TestsBase
20 from ..ansi import *
21
22
23 #-----------------------------------------------------------------------------
24 # Class
25 #-----------------------------------------------------------------------------
26
27 class TestAnsi(TestsBase):
28 """Contains test functions for ansi.py"""
29
30
31 def test_remove_ansi(self):
32 """
33 remove_ansi test
34 """
35 correct_outputs = {
36 '%s%s%s' % (TermColors.Green, TermColors.White, TermColors.Red) : '',
37 'hello%s' % TermColors.Blue: 'hello',
38 'he%s%sllo' % (TermColors.Yellow, TermColors.Cyan) : 'hello',
39 '%shello' % TermColors.Blue : 'hello',
40 '{0}h{0}e{0}l{0}l{0}o{0}'.format(TermColors.Red) : 'hello',
41 'hel%slo' % TermColors.Green : 'hello',
42 'hello' : 'hello'}
43
44 for inval, outval in correct_outputs.items():
45 yield self._try_remove_ansi, inval, outval
46
47
48 def _try_remove_ansi(self, inval, outval):
49 assert outval == remove_ansi(inval)
50
51
52 def test_ansi2html(self):
53 """
54 ansi2html test
55 """
56 correct_outputs = {
57 '%s' % (TermColors.Red) : '<span class="ansired"></span>',
58 'hello%s' % TermColors.Blue: 'hello<span class="ansiblue"></span>',
59 'he%s%sllo' % (TermColors.Green, TermColors.Cyan) : 'he<span class="ansigreen"></span><span class="ansicyan">llo</span>',
60 '%shello' % TermColors.Yellow : '<span class="ansiyellow">hello</span>',
61 '{0}h{0}e{0}l{0}l{0}o{0}'.format(TermColors.White) : '<span class="ansigrey">h</span><span class="ansigrey">e</span><span class="ansigrey">l</span><span class="ansigrey">l</span><span class="ansigrey">o</span><span class="ansigrey"></span>',
62 'hel%slo' % TermColors.Green : 'hel<span class="ansigreen">lo</span>',
63 'hello' : 'hello'}
64
65 for inval, outval in correct_outputs.items():
66 yield self._try_ansi2html, inval, outval
67
68
69 def _try_ansi2html(self, inval, outval):
70 assert self.fuzzy_compare(outval, ansi2html(inval))
71
72
73 def test_ansi2latex(self):
74 """
75 ansi2latex test
76 """
77 correct_outputs = {
78 '%s' % (TermColors.Red) : r'\red{}',
79 'hello%s' % TermColors.Blue: r'hello\blue{}',
80 'he%s%sllo' % (TermColors.Green, TermColors.Cyan) : r'he\green{}\cyan{llo}',
81 '%shello' % TermColors.Yellow : r'\yellow{hello}',
82 '{0}h{0}e{0}l{0}l{0}o{0}'.format(TermColors.White) : r'\white{h}\white{e}\white{l}\white{l}\white{o}\white{}',
83 'hel%slo' % TermColors.Green : r'hel\green{lo}',
84 'hello' : 'hello'}
85
86 for inval, outval in correct_outputs.items():
87 yield self._try_ansi2latex, inval, outval
88
89
90 def _try_ansi2latex(self, inval, outval):
91 assert self.fuzzy_compare(outval, ansi2latex(inval), case_sensitive=True)
@@ -0,0 +1,46 b''
1 """
2 Module with tests for DataTypeFilter
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17
18 from ...tests.base import TestsBase
19 from ..datatypefilter import DataTypeFilter
20
21
22 #-----------------------------------------------------------------------------
23 # Class
24 #-----------------------------------------------------------------------------
25
26 class TestDataTypeFilter(TestsBase):
27 """Contains test functions for datatypefilter.py"""
28
29
30 def test_constructor(self):
31 """Can an instance of a DataTypeFilter be created?"""
32 DataTypeFilter()
33
34
35 def test_junk_types(self):
36 """Can the DataTypeFilter pickout a useful type from a list of junk types?"""
37 filter = DataTypeFilter()
38 assert filter(["hair", "water", "png", "rock"]) == ["png"]
39 assert filter(["pdf", "hair", "water", "png", "rock"]) == ["pdf"]
40 assert filter(["hair", "water", "rock"]) == []
41
42
43 def test_null(self):
44 """Will the DataTypeFilter fail if no types are passed in?"""
45 filter = DataTypeFilter()
46 assert filter([]) == []
@@ -0,0 +1,35 b''
1 """
2 Module with tests for Highlight
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17
18 from ...tests.base import TestsBase
19 from ..highlight import *
20
21
22 #-----------------------------------------------------------------------------
23 # Class
24 #-----------------------------------------------------------------------------
25
26 class TestHighlight(TestsBase):
27 """Contains test functions for highlight.py"""
28
29
30 def test_highlight(source, language='ipython'):
31 pass
32
33
34 def test_highlight2latex(source, language='ipython'):
35 pass
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,178 b''
1 #!/usr/bin/env python
2 """
3 Contains base test class for nbconvert
4 """
5 #-----------------------------------------------------------------------------
6 #Copyright (c) 2013, the IPython Development Team.
7 #
8 #Distributed under the terms of the Modified BSD License.
9 #
10 #The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 import subprocess
18 import os
19 import glob
20 import shutil
21 import sys
22
23 import IPython
24 from IPython.utils.tempdir import TemporaryDirectory
25 from IPython.utils import py3compat
26
27 #-----------------------------------------------------------------------------
28 # Classes and functions
29 #-----------------------------------------------------------------------------
30
31 class TemporaryWorkingDirectory(TemporaryDirectory):
32 """
33 Creates a temporary directory and sets the cwd to that directory.
34 Automatically reverts to previous cwd upon cleanup.
35 Usage example:
36
37 with TemporaryWorakingDirectory() as tmpdir:
38 ...
39 """
40
41 def __init__(self, **kw):
42 """
43 Constructor
44 """
45 super(TemporaryWorkingDirectory, self).__init__(**kw)
46
47 #Change cwd to new temp dir. Remember old cwd.
48 self.old_wd = os.getcwd()
49 os.chdir(self.name)
50
51
52 def cleanup(self):
53 """
54 Destructor
55 """
56
57 #Revert to old cwd.
58 os.chdir(self.old_wd)
59
60 #Cleanup
61 super(TemporaryWorkingDirectory, self).cleanup()
62
63
64 class TestsBase(object):
65 """Base tests class. Contains usefull fuzzy comparison and nbconvert
66 functions."""
67
68
69 def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True,
70 fuzzy_spacing=True, ignore_spaces=False,
71 ignore_newlines=False, case_sensitive=False):
72 """
73 Performs a fuzzy comparison of two strings. A fuzzy comparison is a
74 comparison that ignores insignificant differences in the two comparands.
75 The significance of certain differences can be specified via the keyword
76 parameters of this method.
77 """
78
79 if newlines_are_spaces:
80 a = a.replace('\n', ' ')
81 b = b.replace('\n', ' ')
82
83 if tabs_are_spaces:
84 a = a.replace('\t', ' ')
85 b = b.replace('\t', ' ')
86
87 if ignore_spaces:
88 a = a.replace(' ', '')
89 b = b.replace(' ', '')
90
91 if fuzzy_spacing:
92 a = self.recursive_replace(a, ' ', ' ')
93 b = self.recursive_replace(b, ' ', ' ')
94
95 if ignore_newlines:
96 a = a.replace('\n', '')
97 b = b.replace('\n', '')
98
99 if not case_sensitive:
100 a = a.lower()
101 b = b.lower()
102
103 return a == b
104
105
106 def recursive_replace(self, text, search, replacement):
107 """
108 Performs a recursive replacement operation. Replaces all instances
109 of a search string in a text string with a replacement string until
110 the search string no longer exists. Recursion is needed because the
111 replacement string may generate additional search strings.
112
113 For example:
114 Replace "ii" with "i" in the string "Hiiii" yields "Hii"
115 Another replacement yields "Hi" (the desired output)
116
117 Parameters:
118 -----------
119 text : string
120 Text to replace in.
121 search : string
122 String to search for within "text"
123 replacement : string
124 String to replace "search" with
125 """
126 while search in text:
127 text = text.replace(search, replacement)
128 return text
129
130
131 def create_temp_cwd(self, copy_filenames=None):
132 temp_dir = TemporaryWorkingDirectory()
133
134 #Copy the files if requested.
135 if not copy_filenames is None:
136 self.copy_files_to(copy_filenames)
137
138 #Return directory handler
139 return temp_dir
140
141
142 def copy_files_to(self, copy_filenames=None, destination=None):
143
144 #Copy test files into the destination directory.
145 if copy_filenames:
146 for pattern in copy_filenames:
147 for match in glob.glob(os.path.join(self._get_files_path(), pattern)):
148 if destination is None:
149 shutil.copyfile(match, os.path.basename(match))
150 else:
151 if not os.path.isdir(destination):
152 os.makedirs(destination)
153 shutil.copyfile(match, os.path.join(destination, os.path.basename(match)))
154
155
156 def _get_files_path(self):
157
158 #Get the relative path to this module in the IPython directory.
159 names = self.__module__.split('.')[1:-1]
160 names.append('files')
161
162 #Build a path using the IPython directory and the relative path we just
163 #found.
164 path = IPython.__path__[0]
165 for name in names:
166 path = os.path.join(path, name)
167 return path
168
169
170 def call(self, parameters):
171 output = subprocess.Popen(parameters, stdout=subprocess.PIPE).communicate()[0]
172
173 #Convert the output to a string if running Python3
174 if py3compat.PY3:
175 return output.decode('utf-8')
176 else:
177 return output
178 No newline at end of file
@@ -0,0 +1,6 b''
1 c = get_config()
2
3 #Export all the notebooks in the current directory to the sphinx_howto format.
4 c.NbConvertApp.notebooks = ['notebook1.ipynb']
5 c.NbConvertApp.export_format = 'python'
6
@@ -0,0 +1,149 b''
1 {
2 "metadata": {
3 "name": "notebook1"
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
9 "cells": [
10 {
11 "cell_type": "heading",
12 "level": 1,
13 "metadata": {},
14 "source": [
15 "A simple SymPy example"
16 ]
17 },
18 {
19 "cell_type": "markdown",
20 "metadata": {},
21 "source": [
22 "First we import SymPy and initialize printing:"
23 ]
24 },
25 {
26 "cell_type": "code",
27 "collapsed": false,
28 "input": [
29 "from sympy import init_printing\n",
30 "from sympy import *\n",
31 " init_printing()"
32 ],
33 "language": "python",
34 "metadata": {},
35 "outputs": [],
36 "prompt_number": 2
37 },
38 {
39 "cell_type": "markdown",
40 "metadata": {},
41 "source": [
42 "Create a few symbols:"
43 ]
44 },
45 {
46 "cell_type": "code",
47 "collapsed": false,
48 "input": [
49 "x,y,z = symbols('x y z')"
50 ],
51 "language": "python",
52 "metadata": {},
53 "outputs": [],
54 "prompt_number": 4
55 },
56 {
57 "cell_type": "markdown",
58 "metadata": {},
59 "source": [
60 "Here is a basic expression:"
61 ]
62 },
63 {
64 "cell_type": "code",
65 "collapsed": false,
66 "input": [
67 "e = x**2 + 2.0*y + sin(z); e"
68 ],
69 "language": "python",
70 "metadata": {},
71 "outputs": [
72 {
73 "latex": [
74 "$$x^{2} + 2.0 y + \\sin{\\left (z \\right )}$$"
75 ],
76 "metadata": {},
77 "output_type": "pyout",
78 "png": "iVBORw0KGgoAAAANSUhEUgAAAKMAAAAZBAMAAACvE4OgAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\nme8Q6PJIAAACz0lEQVRIDa1UTWjUQBT+ZpvdzW7TGlrxItjYSg/C6vbiDwjmoCgUpHioPYhdqig9\nFJYiPYmW4klB14NgFGnw4EHpj7UgUtTFXhSEBgVBxIOFggWVrrUqiMY3mZkkLNIK7oN575vvvfky\n8yYJIGzgkSlRrULKrivVSkvq6LbxtcaSjV3aSo0lgWyl5pK69V+SRlEsPxNTGYhhDrV3M2Ue2etc\nEDmuMmM+IjolrCuHXNoLoQDNSAXdzbjsfFVKTY1vCgFXFIxenG4cFSSzRewAPnN0FugXjPDr45MQ\nJwoKtitgXL9zT+CsJeIHYG+Z4H1gwhRU4G/FcAQbbYU3KdDo+0sCK8lRU0guA72uKqMYk9RehHxP\niDIu0NS2v90KGShJYi7T7tgvkrQ2vIT2XtRISWNra6lzGc8/PW3ji4PL7Vmge095YIX0iB71NCaZ\n5N3XyM0VCuNIyFNIyY3AMG/KDUvjn90DGmwq9wpIl5AyU5WsTYy0aJf6JFGB5An3Der5jExKHjNR\n4JKPge/EXqDBoOXpkxkmkJHFfAFRVhDIveWA0S57N2Me6yw+DSX1n1uCq3sIfCF2IcjNkjeWyKli\nginHubboOB4vSNAjyaiXE26ygrkyTfod55Lj3CTE+n2P73ImJpnk6wJJKjYJSwt3OQbNJu4icM5s\nKGGbzMuD70N6JSbJD44x7pLDyJrbkfiLpOEhYVMJSVEj83x5YFLyNrAzJsmvJ+uhLrieXvcJDshy\nHtQuD54c2IWWEnSXfUTDZJJfAjcpOW5imp9aHvw4ZZ4NDV4FGjw0tzadKgbFwinJUd//AT0P1tdW\nBtuRU39oKdk9ONQ163fM+nvu/s4D/FX30otdQIZGlSnJKpq6KUxKVqV1WxGHFIhishjhEO1Gi3r4\nkZCMg+hH1henV8EjmFoly1PTMs/Uadaox+FceY2STpmvt9co/Pe0Jvt1GvgDK/Osw/4jQ4wAAAAA\nSUVORK5CYII=\n",
79 "prompt_number": 6,
80 "text": [
81 " 2 \n",
82 "x + 2.0\u22c5y + sin(z)"
83 ]
84 }
85 ],
86 "prompt_number": 6
87 },
88 {
89 "cell_type": "code",
90 "collapsed": false,
91 "input": [
92 "diff(e, x)"
93 ],
94 "language": "python",
95 "metadata": {},
96 "outputs": [
97 {
98 "latex": [
99 "$$2 x$$"
100 ],
101 "metadata": {},
102 "output_type": "pyout",
103 "png": "iVBORw0KGgoAAAANSUhEUgAAABQAAAAOBAMAAADd6iHDAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpm7MhCriUTv3c12\nVGZoascqAAAAgElEQVQIHWNgVDJ2YICAMAb2H1BmKgPDTChzFgNDvgOEvT8AzgQKrA9gPZPYUwNk\ncXxnCGd4dWA1kMllwFDKUB9wEchUZmAIYNgMZDDwJIDIPyDiEgOjAAPLFwZWBhYFBh6BqzwfGI4y\nSJUXZXH8Zf7A+IBh////v1hzjh5/xwAAW80hUDE8HYkAAAAASUVORK5CYII=\n",
104 "prompt_number": 7,
105 "text": [
106 "2\u22c5x"
107 ]
108 }
109 ],
110 "prompt_number": 7
111 },
112 {
113 "cell_type": "code",
114 "collapsed": false,
115 "input": [
116 "integrate(e, z)"
117 ],
118 "language": "python",
119 "metadata": {},
120 "outputs": [
121 {
122 "latex": [
123 "$$x^{2} z + 2.0 y z - \\cos{\\left (z \\right )}$$"
124 ],
125 "metadata": {},
126 "output_type": "pyout",
127 "png": "iVBORw0KGgoAAAANSUhEUgAAALsAAAAZBAMAAACbakK8AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\nme8Q6PJIAAADAklEQVRIDbVVS2gTURQ90/wmk0k6tCJCsR1SKShIsxE3CgNWBKUxq9qFmqFqShfF\nUKQrkaDiF0pcCKYgBBcuBLV+wIWKARe6kQ4UhNKKWdiF4KIptmA/xPvmzZuMxdYUzIPcd+655568\nvLlJAL6G32oOasQWNHz5Rvg6nrKh/mygfSzlX2ygPaBUGmov6//NXs1yq4sex2EPrsHemTd2snNg\ntkb+Cx1zBL6SqwxZLvQAKYHzKZaPY4fh4TeHd0S5Nox9OClItm/jiU9DrEwwVEawpiVis9VkimqX\nAOr4o2cCs/0BT2I5+FYJRhJbePQxgzcD7QLEqtV5gdnu2Icr3L45gcCyt74Z7neL4SLQ0nm4S+dM\nYCz1gSPHnhKZDWyHhcCCNKwjqaF/TkwGl0L6nClie/wc1D1xdoNsSLhT0IJkhi7Lzr22xb8keE/N\nPm0Sc9yEuhRUyuiG9HzvFNeImCyq39SriOhtQI7IV/TiTqE8glqwohjE0NJwiANxOZTdZoxtfzSa\nx2tI8DtHcKQoQFmV6f1XT2swibxFL+6k5EgenhBCqKLTPX3ULnaYdDlaTMcCSd8zuXTvBq2bJUJr\nlE4WgSV5ZRdBzLFgO6nzhJp1ltvrlB2HCoWxQuG+jTvt2GxBWUZaU2mMApZNuSHA3vJpCliRhqqs\nZtvbTrb9ZIk+i70Ut1OcnpgeKskTCFUwjaYy8Jhr3eiefq0HIfa7yC6HOwVyULRuNDn21JngbcL+\nE8A+MNnSxb+w59+Cj2tELJBbjEZr8SGwn0j2aLkTPdp08R2OcKV6fXB3ikPH3n8tM5WTfrETtZcw\ng3QWH0dH7nKNiMkszqo/EDafaHhJ5Bm6ee4UtdAabxnMcmUUl0SnYx+uVqs5XAGN9QGgdeCrASv0\n3TmCsJcOdhnozexD38goK9HXynEKr1OKDs9guhQD039kGySyIQpJAdbvJ9YTlPvyUl3/aLUf34G/\nuGxIyXpE37DoLbAHwJaU53t9MRCfrU8o/k4iRn36Lar8Wd5wAfgN4R6xelyy/ssAAAAASUVORK5C\nYII=\n",
128 "prompt_number": 8,
129 "text": [
130 " 2 \n",
131 "x \u22c5z + 2.0\u22c5y\u22c5z - cos(z)"
132 ]
133 }
134 ],
135 "prompt_number": 8
136 },
137 {
138 "cell_type": "code",
139 "collapsed": false,
140 "input": [],
141 "language": "python",
142 "metadata": {},
143 "outputs": []
144 }
145 ],
146 "metadata": {}
147 }
148 ]
149 } No newline at end of file
@@ -0,0 +1,177 b''
1 {
2 "metadata": {
3 "name": "notebook2"
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
9 "cells": [
10 {
11 "cell_type": "heading",
12 "level": 1,
13 "metadata": {},
14 "source": [
15 "NumPy and Matplotlib examples"
16 ]
17 },
18 {
19 "cell_type": "markdown",
20 "metadata": {},
21 "source": [
22 "First import NumPy and Matplotlib:"
23 ]
24 },
25 {
26 "cell_type": "code",
27 "collapsed": false,
28 "input": [
29 "%pylab inline"
30 ],
31 "language": "python",
32 "metadata": {},
33 "outputs": [
34 {
35 "output_type": "stream",
36 "stream": "stdout",
37 "text": [
38 "\n",
39 "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].\n",
40 "For more information, type 'help(pylab)'.\n"
41 ]
42 }
43 ],
44 "prompt_number": 1
45 },
46 {
47 "cell_type": "code",
48 "collapsed": false,
49 "input": [
50 "import numpy as np"
51 ],
52 "language": "python",
53 "metadata": {},
54 "outputs": [],
55 "prompt_number": 2
56 },
57 {
58 "cell_type": "markdown",
59 "metadata": {},
60 "source": [
61 "Now we show some very basic examples of how they can be used."
62 ]
63 },
64 {
65 "cell_type": "code",
66 "collapsed": false,
67 "input": [
68 "a = np.random.uniform(size=(100,100))"
69 ],
70 "language": "python",
71 "metadata": {},
72 "outputs": [],
73 "prompt_number": 6
74 },
75 {
76 "cell_type": "code",
77 "collapsed": false,
78 "input": [
79 "a.shape"
80 ],
81 "language": "python",
82 "metadata": {},
83 "outputs": [
84 {
85 "metadata": {},
86 "output_type": "pyout",
87 "prompt_number": 7,
88 "text": [
89 "(100, 100)"
90 ]
91 }
92 ],
93 "prompt_number": 7
94 },
95 {
96 "cell_type": "code",
97 "collapsed": false,
98 "input": [
99 "evs = np.linalg.eigvals(a)"
100 ],
101 "language": "python",
102 "metadata": {},
103 "outputs": [],
104 "prompt_number": 8
105 },
106 {
107 "cell_type": "code",
108 "collapsed": false,
109 "input": [
110 "evs.shape"
111 ],
112 "language": "python",
113 "metadata": {},
114 "outputs": [
115 {
116 "metadata": {},
117 "output_type": "pyout",
118 "prompt_number": 10,
119 "text": [
120 "(100,)"
121 ]
122 }
123 ],
124 "prompt_number": 10
125 },
126 {
127 "cell_type": "markdown",
128 "metadata": {},
129 "source": [
130 "Here is a cell that has both text and PNG output:"
131 ]
132 },
133 {
134 "cell_type": "code",
135 "collapsed": false,
136 "input": [
137 "hist(evs.real)"
138 ],
139 "language": "python",
140 "metadata": {},
141 "outputs": [
142 {
143 "metadata": {},
144 "output_type": "pyout",
145 "prompt_number": 14,
146 "text": [
147 "(array([95, 4, 0, 0, 0, 0, 0, 0, 0, 1]),\n",
148 " array([ -2.93566063, 2.35937011, 7.65440086, 12.9494316 ,\n",
149 " 18.24446235, 23.53949309, 28.83452384, 34.12955458,\n",
150 " 39.42458533, 44.71961607, 50.01464682]),\n",
151 " <a list of 10 Patch objects>)"
152 ]
153 },
154 {
155 "metadata": {},
156 "output_type": "display_data",
157 "png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAD9CAYAAAC2l2x5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEhdJREFUeJzt3X1olfX/x/HXtVbT8CZDmsK6KmrubEu3U2xnZOpxLBnG\nOqsIE7RoE3QRZkT/yEAjcIh/LIs6i/BEGSU1CkxT0+pkFp1zMmsxZ5uUTIXoxm95lmdlef3+8Nep\ndbtz7exs16fnAw7sXNs5n/c14nmurl3naDmO4wgAYJy8sR4AADA6CDwAGIrAA4ChCDwAGIrAA4Ch\nCDwAGOofA9/U1KTCwkLNnj07vS2ZTCoUCsm2bTU2NmpgYCD9vccee0zFxcUqKyvTgQMHRm9qAMC/\n+sfA33PPPdq9e/eQbeFwWLZtq6+vT0VFRero6JAkffXVV3ryySf15ptvKhwOa/Xq1aM3NQDgX/1j\n4OfNm6dp06YN2RaPx9Xc3KyCggI1NTUpFotJkmKxmOrr62XbthYsWCDHcZRMJkdvcgDAP8r4HHwi\nkZDP55Mk+Xw+xeNxSecDX1pamv65kpKS9PcAALmXn+kDMvlkA8uyhrUNAPDvMv1kmYyP4KuqqtTT\n0yNJ6unpUVVVlSQpEAjo8OHD6Z87cuRI+nt/NaRXb+vWrRvzGZh/7Odgfu/dvDy747j7yLCMAx8I\nBBSJRJRKpRSJRFRTUyNJqq6u1p49e9Tf369oNKq8vDxNnjzZ1VAAgJH7x8AvXbpUN9xwg3p7e3X5\n5ZfrmWeeUUtLi/r7+1VSUqKTJ09q1apVkqTCwkK1tLSotrZW9957rzZv3pyTHQAA/DXLcXvs73ZB\ny3L9vxvjQTQaVTAYHOsxXGP+scX8Y8fLs0vu2kngAcAD3LSTjyoAAEMReAAwFIEHAEMReAAwFIEH\nAEP9ZwM/Zcqlsixr1G9Tplw61rsK4D/qP3uZ5PnPxMnFHONjfwF4G5dJAgDSCDwAGIrAA4ChCDwA\nGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrA\nA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChXAf+6aef1g03\n3KDrr79ea9askSQlk0mFQiHZtq3GxkYNDAxkbVAAQGZcBf7UqVPasGGD9u7dq0Qiod7eXu3Zs0fh\ncFi2bauvr09FRUXq6OjI9rwAgGFyFfiJEyfKcRx9//33SqVSOnPmjC655BLF43E1NzeroKBATU1N\nisVi2Z4XADBMrgMfDod15ZVXasaMGZo7d64CgYASiYR8Pp8kyefzKR6PZ3VYAMDw5bt50Ndff62W\nlhYdPnxY06ZN0x133KEdO3bIcZxhPX79+vXpr4PBoILBoJsxAMBY0WhU0Wh0RM9hOcOt8u/s3LlT\nW7du1bZt2yRJ4XBYx44d09GjR9Xa2iq/36+DBw+qra1NnZ2dQxe0rGG/EIwmy7Ik5WKO8bG/ALzN\nTTtdnaKZN2+ePvzwQ506dUo//vijdu3apUWLFikQCCgSiSiVSikSiaimpsbN0wMAssBV4KdMmaLW\n1lbdeuutuvHGG1VRUaGFCxeqpaVF/f39Kikp0cmTJ7Vq1apszwsAGCZXp2hGtCCnaAAgYzk7RQMA\nGP8IPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEI\nPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAY\nisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYynXgf/jhB919992a\nNWuWysrKFIvFlEwmFQqFZNu2GhsbNTAwkM1ZAQAZcB34devWybZtdXV1qaurSz6fT+FwWLZtq6+v\nT0VFRero6MjmrACADLgO/L59+7R27VpNmDBB+fn5mjp1quLxuJqbm1VQUKCmpibFYrFszgoAyICr\nwJ84cUKDg4NqaWlRIBDQxo0blUqllEgk5PP5JEk+n0/xeDyrwwIAhi/fzYMGBwfV29urTZs2qa6u\nTitXrtRLL70kx3GG9fj169envw4GgwoGg27GAABjRaNRRaPRET2H5Qy3yn9QWlqqnp4eSdKuXbv0\n3HPP6aefflJra6v8fr8OHjyotrY2dXZ2Dl3Qsob9QjCaLMuSlIs5xsf+AvA2N+10fQ6+uLhYsVhM\n586d086dO1VXV6dAIKBIJKJUKqVIJKKamhq3Tw8AGCHXR/C9vb266667NDg4qLq6Oj388MM6d+6c\nli1bpkOHDum6667T888/r0mTJg1dkCN4AMiYm3a6DrxbBB4AMpfTUzQAgPGNwAOAoQg8ABiKwAOA\noQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8\nABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiK\nwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoVwH/pdffpHf71dDQ4MkKZlMKhQKybZtNTY2\namBgIGtDAgAy5zrwmzdvVllZmSzLkiSFw2HZtq2+vj4VFRWpo6Mja0MCADLnKvAnTpzQ66+/rhUr\nVshxHElSPB5Xc3OzCgoK1NTUpFgsltVBAQCZcRX4Bx54QJs2bVJe3m8PTyQS8vl8kiSfz6d4PJ6d\nCQEAruRn+oAdO3bosssuk9/vVzQaTW//9Uh+ONavX5/+OhgMKhgMZjoGABgtGo0OaawblpNJmSWt\nXbtWW7duVX5+vgYHB3X69GnddtttOnPmjFpbW+X3+3Xw4EG1tbWps7PzzwtaVkYvBqPl/N8OcjHH\n+NhfAN7mpp0Zn6LZsGGDjh8/ri+++ELbtm1TbW2ttm7dqkAgoEgkolQqpUgkopqamkyfGgCQRSO+\nDv7Xq2haWlrU39+vkpISnTx5UqtWrRrxcAAA9zI+RTPiBTlFAwAZy8kpGgCANxB4ADAUgQcAQxF4\nADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAU\ngQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcA\nQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQ7kK/PHjx7Vw4UKVl5crGAzqhRdekCQlk0mFQiHZ\ntq3GxkYNDAxkdVgAwPC5CvyFF16o9vZ2dXd3q7OzU62trUomkwqHw7JtW319fSoqKlJHR0e25wUA\nDJOrwM+YMUOVlZWSpOnTp6u8vFyJRELxeFzNzc0qKChQU1OTYrFYVocFAAzfiM/BHz16VN3d3aqu\nrlYikZDP55Mk+Xw+xePxEQ8IAHAnfyQPTiaTWrJkidrb2zVp0iQ5jjOsx61fvz79dTAYVDAYHMkY\nAGCcaDSqaDQ6ouewnOFW+Q/Onj2rm2++WYsXL9aaNWskSbfffrtaW1vl9/t18OBBtbW1qbOzc+iC\nljXsF4LRZFmWpFzMMT72F4C3uWmnq1M0juOoublZ1157bTrukhQIBBSJRJRKpRSJRFRTU+Pm6QEA\nWeDqCP7AgQOaP3++5syZ8/9HwlJbW5vmzp2rZcuW6dChQ7ruuuv0/PPPa9KkSUMX5AgeADLmpp2u\nT9G4ReABIHM5O0UDABj/CDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrA\nA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4Ch\nCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4Ch8sd6APPly7KsUV1h8uRpOn361Kiu\nAcB7LMdxnJwuaFnK8ZJ/O4eUizlysc74+J0CGD1u2skpGgAwFIEHAEMReAAwVNYDv3//fpWWlqq4\nuFiPP/54tp9+HIiO9QAjEo1Gx3qEEWH+seXl+b08u1tZD/z999+vp556Svv27dMTTzyhb775JttL\njLHoWA8wIl7/j5z5x5aX5/fy7G5lNfDff/+9JGn+/Pm64oortGjRIsVisWwuAcBAU6ZcKsuyRvXW\n1rZxrHcz57Ia+EQiIZ/Pl75fVlamDz74IJtLADBQMvk/nb+cePRuP/00mLsdGieyeh38vn37tGXL\nFr344ouSpI6ODp08eVKPPPLIbwuO8pt+AMBUmeY6q+9kraqq0kMPPZS+393drfr6+iE/wxtyACA3\nsnqKZurUqZLOX0lz7Ngx7d27V4FAIJtLAACGKeufRfPoo49q5cqVOnv2rFavXq3p06dnewkAwDBk\n/TLJBQsWqKenR0ePHtXq1aslSS+//LLKy8t1wQUX6KOPPhry84899piKi4tVVlamAwcOZHucrPHa\n9f1NTU0qLCzU7Nmz09uSyaRCoZBs21ZjY6MGBgbGcMJ/dvz4cS1cuFDl5eUKBoN64YUXJHlnHwYH\nBxUIBFRZWamamhq1t7dL8s78kvTLL7/I7/eroaFBkrdmv/LKKzVnzhz5/X5VV1dL8tb8P/zwg+6+\n+27NmjVLZWVlisVirubPyTtZZ8+erVdffVXz588fsv2rr77Sk08+qTfffFPhcDj9gjAeee36/nvu\nuUe7d+8esi0cDsu2bfX19amoqEgdHR1jNN2/u/DCC9Xe3q7u7m51dnaqtbVVyWTSM/swYcIEvf32\n2/r444/1zjvvaMuWLerr6/PM/JK0efNmlZWVpS+M8NLslmUpGo3q0KFDisfjkrw1/7p162Tbtrq6\nutTV1SWfz+dq/pwE3ufzadasWX/aHovFVF9fL9u2tWDBAjmOo2QymYuRMuLF6/vnzZunadOmDdkW\nj8fV3NysgoICNTU1jet9mDFjhiorKyVJ06dPV3l5uRKJhKf24eKLL5YkDQwM6Oeff1ZBQYFn5j9x\n4oRef/11rVixIn1hhFdm/9UfL+jw0vz79u3T2rVrNWHCBOXn52vq1Kmu5h/Tz6KJx+MqLS1N3y8p\nKUm/2o4nplzf//v98Pl84/J3/VeOHj2q7u5uVVdXe2ofzp07p4qKChUWFuq+++6Tbduemf+BBx7Q\npk2blJf3WyK8Mrt0/gi+trZWjY2N2r59uyTvzH/ixAkNDg6qpaVFgUBAGzduVCqVcjV/1v7IetNN\nN+nLL7/80/YNGzakz+H90V9dMsl18qPHi5eoJpNJLVmyRO3t7Zo0aZKn9iEvL0+ffPKJjh07psWL\nF2vu3LmemH/Hjh267LLL5Pf7h7y93wuz/+q9997TzJkz1dPTo4aGBlVXV3tm/sHBQfX29mrTpk2q\nq6vTypUr9dJLL7maP2tH8Hv37tWnn376p9vfxV2SAoGADh8+nL5/5MgRVVVVZWukrKmqqtKRI0fS\n97u7u1VTUzOGE7lTVVWlnp4eSVJPT8+4/F3/3tmzZ3X77bdr+fLlCoVCkry3D9L5P/gtXrxYsVjM\nE/O///772r59u6666iotXbpUb731lpYvX+6J2X81c+ZMSVJpaaluueUWvfbaa56Z/5prrlFJSYka\nGho0ceJELV26VLt373Y1f85P0fz+Vai6ulp79uxRf3+/otGo8vLyNHny5FyP9K9Mub4/EAgoEoko\nlUopEomM6xcpx3HU3Nysa6+9VmvWrElv98o+fPPNN/ruu+8kSd9++63eeOMNhUIhT8y/YcMGHT9+\nXF988YW2bdum2tpabd261ROzS9KZM2fSf8v7+uuvtWfPHtXX13tmfkkqLi5WLBbTuXPntHPnTtXV\n1bmb38mBV155xSkqKnImTJjgFBYWOvX19envPfroo87VV1/tlJaWOvv378/FOK5Eo1HH5/M5V199\ntbN58+axHudf3Xnnnc7MmTOdiy66yCkqKnIikYhz+vRp55ZbbnEuv/xyJxQKOclkcqzH/Fvvvvuu\nY1mWU1FR4VRWVjqVlZXOrl27PLMPXV1djt/vd+bMmeMsWrTIefbZZx3HcTwz/6+i0ajT0NDgOI53\nZv/888+diooKp6KiwqmtrXW2bNniOI535nccx/nss8+cQCDgVFRUOA8++KAzMDDgav6c/5usAIDc\n4F90AgBDEXgAMBSBBwBDEXgAMBSBBwBDEXgAMNT/AQKseNIf7mhWAAAAAElFTkSuQmCC\n",
158 "text": [
159 "<matplotlib.figure.Figure at 0x108c8f1d0>"
160 ]
161 }
162 ],
163 "prompt_number": 14
164 },
165 {
166 "cell_type": "code",
167 "collapsed": false,
168 "input": [],
169 "language": "python",
170 "metadata": {},
171 "outputs": []
172 }
173 ],
174 "metadata": {}
175 }
176 ]
177 } No newline at end of file
@@ -0,0 +1,6 b''
1 c = get_config()
2
3 #Export all the notebooks in the current directory to the sphinx_howto format.
4 c.NbConvertApp.notebooks = ['notebook2.ipynb']
5 c.NbConvertApp.export_format = 'python'
6
@@ -0,0 +1,123 b''
1 """
2 Contains tests for the nbconvertapp
3 """
4 #-----------------------------------------------------------------------------
5 #Copyright (c) 2013, the IPython Development Team.
6 #
7 #Distributed under the terms of the Modified BSD License.
8 #
9 #The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
16 import os
17 from .base import TestsBase
18
19 from IPython.utils import py3compat
20
21
22 #-----------------------------------------------------------------------------
23 # Constants
24 #-----------------------------------------------------------------------------
25
26 #Define ipython commandline name
27 if py3compat.PY3:
28 IPYTHON = 'ipython3'
29 else:
30 IPYTHON = 'ipython'
31
32
33 #-----------------------------------------------------------------------------
34 # Classes and functions
35 #-----------------------------------------------------------------------------
36
37 class TestNbConvertApp(TestsBase):
38 """Collection of NbConvertApp tests"""
39
40
41 def test_notebook_help(self):
42 """
43 Will help show if no notebooks are specified?
44 """
45 with self.create_temp_cwd():
46 assert "see '--help-all'" in self.call([IPYTHON, 'nbconvert'])
47
48
49 def test_glob(self):
50 """
51 Do search patterns work for notebook names?
52 """
53 with self.create_temp_cwd(['notebook*.ipynb']):
54 assert not 'error' in self.call([IPYTHON, 'nbconvert',
55 '--format="python"', '--notebooks=["*.ipynb"]']).lower()
56 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
57 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
58
59
60 def test_glob_subdir(self):
61 """
62 Do search patterns work for subdirectory notebook names?
63 """
64 with self.create_temp_cwd() as cwd:
65 self.copy_files_to(['notebook*.ipynb'], 'subdir/')
66 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"',
67 '--notebooks=["%s"]' % os.path.join('subdir', '*.ipynb')]).lower()
68 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
69 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
70
71
72 def test_explicit(self):
73 """
74 Do explicit notebook names work?
75 """
76 with self.create_temp_cwd(['notebook*.ipynb']):
77 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"',
78 '--notebooks=["notebook2.ipynb"]']).lower()
79 assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
80 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
81
82
83 def test_glob_explicit(self):
84 """
85 Can a search pattern be used along with matching explicit notebook names?
86 """
87 with self.create_temp_cwd(['notebook*.ipynb']):
88 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"',
89 '--notebooks=["*.ipynb", "notebook1.ipynb", "notebook2.ipynb"]']).lower()
90 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
91 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
92
93
94 def test_explicit_glob(self):
95 """
96 Can explicit notebook names be used and then a matching search pattern?
97 """
98 with self.create_temp_cwd(['notebook*.ipynb']):
99 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--format="python"',
100 '--notebooks=["notebook1.ipynb", "notebook2.ipynb", "*.ipynb"]']).lower()
101 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
102 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
103
104
105 def test_default_config(self):
106 """
107 Does the default config work?
108 """
109 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']):
110 assert not 'error' in self.call([IPYTHON, 'nbconvert']).lower()
111 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
112 assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
113
114
115 def test_override_config(self):
116 """
117 Can the default config be overriden?
118 """
119 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py',
120 'override.py']):
121 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--config="override.py"']).lower()
122 assert not os.path.isfile(os.path.join('nbconvert_build', 'notebook1.py'))
123 assert os.path.isfile(os.path.join('nbconvert_build', 'notebook2.py'))
@@ -6,7 +6,12 b' python:'
6 - 3.2
6 - 3.2
7 - 3.3
7 - 3.3
8 before_install:
8 before_install:
9 - "if [[ $TRAVIS_PYTHON_VERSION == '3.2'* ]]; then pip install -Iv https://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.6.tar.gz; fi"
10 - "if [[ ! $TRAVIS_PYTHON_VERSION == '3.2'* ]]; then pip install jinja2; fi"
9 - easy_install -q pyzmq
11 - easy_install -q pyzmq
12 - sudo apt-get install pandoc
13 - pip install pygments
14 - pip install sphinx
10 install:
15 install:
11 - python setup.py install -q
16 - python setup.py install -q
12 script:
17 script:
@@ -64,6 +64,14 b' IPython.dialog = (function (IPython) {'
64 dialog.remove();
64 dialog.remove();
65 });
65 });
66 }
66 }
67 if (options.reselect_cell !== false) {
68 dialog.on("hidden", function () {
69 if (IPython.notebook) {
70 cell = IPython.notebook.get_selected_cell();
71 if (cell) cell.select();
72 }
73 });
74 }
67
75
68 return dialog.modal(options);
76 return dialog.modal(options);
69 }
77 }
@@ -142,7 +142,7 b' var IPython = (function (IPython) {'
142 };
142 };
143
143
144 Pager.prototype.detach = function(){
144 Pager.prototype.detach = function(){
145 var w = window.open("","_blank")
145 var w = window.open("","_blank");
146 $(w.document.head)
146 $(w.document.head)
147 .append(
147 .append(
148 $('<link>')
148 $('<link>')
@@ -153,10 +153,10 b' var IPython = (function (IPython) {'
153 .append(
153 .append(
154 $('<title>').text("IPython Pager")
154 $('<title>').text("IPython Pager")
155 );
155 );
156 var pager_body = $(w.document.body)
156 var pager_body = $(w.document.body);
157 pager_body.attr('style','overflow:scroll');
157 pager_body.css('overflow','scroll');
158
158
159 pager_body.append(this.pager_element.children())
159 pager_body.append(this.pager_element.clone().children());
160 w.document.close();
160 w.document.close();
161 this.collapse();
161 this.collapse();
162
162
@@ -87,6 +87,7 b' var IPython = (function (IPython) {'
87 "have 1 or more characters and can contain any characters " +
87 "have 1 or more characters and can contain any characters " +
88 "except :/\\. Please enter a new notebook name:"
88 "except :/\\. Please enter a new notebook name:"
89 );
89 );
90 return false;
90 } else {
91 } else {
91 IPython.notebook.set_notebook_name(new_name);
92 IPython.notebook.set_notebook_name(new_name);
92 IPython.notebook.save_notebook();
93 IPython.notebook.save_notebook();
@@ -20,7 +20,6 b' from __future__ import print_function, absolute_import'
20 import io
20 import io
21 import os
21 import os
22 import inspect
22 import inspect
23 import types
24 import copy
23 import copy
25 import collections
24 import collections
26 import datetime
25 import datetime
@@ -35,6 +34,7 b' from IPython.nbformat import current as nbformat'
35 from IPython.utils.traitlets import MetaHasTraits, DottedObjectName, Unicode, List, Dict
34 from IPython.utils.traitlets import MetaHasTraits, DottedObjectName, Unicode, List, Dict
36 from IPython.utils.importstring import import_item
35 from IPython.utils.importstring import import_item
37 from IPython.utils.text import indent
36 from IPython.utils.text import indent
37 from IPython.utils import py3compat
38
38
39 from IPython.nbconvert import transformers as nbtransformers
39 from IPython.nbconvert import transformers as nbtransformers
40 from IPython.nbconvert import filters
40 from IPython.nbconvert import filters
@@ -247,11 +247,11 b' class Exporter(Configurable):'
247 """
247 """
248 if transformer is None:
248 if transformer is None:
249 raise TypeError('transformer')
249 raise TypeError('transformer')
250 isclass = inspect.isclass(transformer)
250 isclass = isinstance(transformer, type)
251 constructed = not isclass
251 constructed = not isclass
252
252
253 #Handle transformer's registration based on it's type
253 #Handle transformer's registration based on it's type
254 if constructed and isinstance(transformer, types.StringTypes):
254 if constructed and isinstance(transformer, py3compat.string_types):
255 #Transformer is a string, import the namespace and recursively call
255 #Transformer is a string, import the namespace and recursively call
256 #this register_transformer method
256 #this register_transformer method
257 transformer_cls = import_item(transformer)
257 transformer_cls = import_item(transformer)
@@ -280,7 +280,7 b' class Exporter(Configurable):'
280 raise TypeError('transformer')
280 raise TypeError('transformer')
281
281
282
282
283 def register_filter(self, name, filter):
283 def register_filter(self, name, jinja_filter):
284 """
284 """
285 Register a filter.
285 Register a filter.
286 A filter is a function that accepts and acts on one string.
286 A filter is a function that accepts and acts on one string.
@@ -292,31 +292,33 b' class Exporter(Configurable):'
292 name to give the filter in the Jinja engine
292 name to give the filter in the Jinja engine
293 filter : filter
293 filter : filter
294 """
294 """
295 if filter is None:
295 if jinja_filter is None:
296 raise TypeError('filter')
296 raise TypeError('filter')
297 isclass = inspect.isclass(filter)
297 isclass = isinstance(jinja_filter, type)
298 constructed = not isclass
298 constructed = not isclass
299
299
300 #Handle filter's registration based on it's type
300 #Handle filter's registration based on it's type
301 if constructed and isinstance(filter, types.StringTypes):
301 if constructed and isinstance(jinja_filter, py3compat.string_types):
302 #filter is a string, import the namespace and recursively call
302 #filter is a string, import the namespace and recursively call
303 #this register_filter method
303 #this register_filter method
304 filter_cls = import_item(filter)
304 filter_cls = import_item(jinja_filter)
305 return self.register_filter(name, filter_cls)
305 return self.register_filter(name, filter_cls)
306
306
307 if constructed and hasattr(filter, '__call__'):
307 if constructed and hasattr(jinja_filter, '__call__'):
308 #filter is a function, no need to construct it.
308 #filter is a function, no need to construct it.
309 self.environment.filters[name] = filter
309 self.environment.filters[name] = jinja_filter
310 return filter
310 return jinja_filter
311
311
312 elif isclass and isinstance(filter, MetaHasTraits):
312 elif isclass and isinstance(jinja_filter, MetaHasTraits):
313 #filter is configurable. Make sure to pass in new default for
313 #filter is configurable. Make sure to pass in new default for
314 #the enabled flag if one was specified.
314 #the enabled flag if one was specified.
315 self.register_filter(name, filter(parent=self))
315 filter_instance = jinja_filter(parent=self)
316 self.register_filter(name, filter_instance )
316
317
317 elif isclass:
318 elif isclass:
318 #filter is not configurable, construct it
319 #filter is not configurable, construct it
319 self.register_filter(name, filter())
320 filter_instance = jinja_filter()
321 self.register_filter(name, filter_instance)
320
322
321 else:
323 else:
322 #filter is an instance of something without a __call__
324 #filter is an instance of something without a __call__
@@ -382,12 +384,12 b' class Exporter(Configurable):'
382 """
384 """
383
385
384 #Add default filters to the Jinja2 environment
386 #Add default filters to the Jinja2 environment
385 for key, value in default_filters.iteritems():
387 for key, value in default_filters.items():
386 self.register_filter(key, value)
388 self.register_filter(key, value)
387
389
388 #Load user filters. Overwrite existing filters if need be.
390 #Load user filters. Overwrite existing filters if need be.
389 if self.filters:
391 if self.filters:
390 for key, user_filter in self.filters.iteritems():
392 for key, user_filter in self.filters.items():
391 self.register_filter(key, user_filter)
393 self.register_filter(key, user_filter)
392
394
393
395
@@ -86,7 +86,7 b' class LatexExporter(Exporter):'
86 def default_config(self):
86 def default_config(self):
87 c = Config({
87 c = Config({
88 'NbConvertBase': {
88 'NbConvertBase': {
89 'display_data_priority' : ['latex', 'svg', 'png', 'jpg', 'jpeg', 'text']
89 'display_data_priority' : ['latex', 'pdf', 'png', 'jpg', 'svg', 'jpeg', 'text']
90 },
90 },
91 'ExtractFigureTransformer': {
91 'ExtractFigureTransformer': {
92 'enabled':True
92 'enabled':True
@@ -111,12 +111,22 b' def single_ansi2latex(code):'
111 Return latex code and number of open brackets.
111 Return latex code and number of open brackets.
112 """
112 """
113 for color in coloransi.color_templates:
113 for color in coloransi.color_templates:
114 colcode = getattr(coloransi.TermColors,color[0])
114
115 #Make sure to get the color code (which is a part of the overall style)
116 # i.e. 0;31 is valid
117 # 31 is also valid, and means the same thing
118 #coloransi.color_templates stores the longer of the two formats %d;%d
119 #Get the short format so we can parse that too. Short format only exist
120 #if no other formating is applied (the other number must be a 0)!
121 style_code = getattr(coloransi.TermColors, color[0])
122 color_code = style_code.split(';')[1]
123 is_normal = style_code.split(';')[0] == '0'
124
115 # regular fonts
125 # regular fonts
116 if code == colcode:
126 if (code == style_code) or (is_normal and code == color_code):
117 return '\\'+color[0].lower()+'{', 1
127 return '\\'+color[0].lower()+'{', 1
118 # bold fonts
128 # bold fonts
119 if code == colcode[:3]+str(1)+colcode[3:]:
129 if code == style_code[:3]+str(1)+style_code[3:]:
120 return '\\textbf{\\textcolor{'+color[0].lower()+'}{', 2
130 return '\\textbf{\\textcolor{'+color[0].lower()+'}{', 2
121 return '', 0
131 return '', 0
122
132
@@ -135,11 +145,13 b' def ansi2latex(text):'
135 if openbrack:
145 if openbrack:
136 outstring += '}'*openbrack
146 outstring += '}'*openbrack
137 openbrack = 0
147 openbrack = 0
138 if match.group() <> coloransi.TermColors.Normal and not openbrack:
148 if not (match.group() == coloransi.TermColors.Normal or openbrack):
139 texform, openbrack = single_ansi2latex(match.group())
149 texform, openbrack = single_ansi2latex(match.group())
140 outstring += texform
150 outstring += texform
141 last_end = match.end()
151 last_end = match.end()
152
153 #Add the remainer of the string and THEN close any remaining color brackets.
154 outstring += text[last_end:]
142 if openbrack:
155 if openbrack:
143 outstring += '}'*openbrack
156 outstring += '}'*openbrack
144 outstring += text[last_end:]
145 return outstring.strip()
157 return outstring.strip()
@@ -23,7 +23,7 b" __all__ = ['DataTypeFilter']"
23
23
24 class DataTypeFilter(NbConvertBase):
24 class DataTypeFilter(NbConvertBase):
25 """ Returns the preferred display format """
25 """ Returns the preferred display format """
26
26
27 def __call__(self, output):
27 def __call__(self, output):
28 """ Return the first available format in the priority """
28 """ Return the first available format in the priority """
29
29
@@ -19,7 +19,6 b' templates.'
19 import re
19 import re
20 import textwrap
20 import textwrap
21 from xml.etree import ElementTree
21 from xml.etree import ElementTree
22
23 from IPython.utils import py3compat
22 from IPython.utils import py3compat
24
23
25 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
@@ -61,7 +60,7 b' def html_text(element):'
61
60
62 Analog of jQuery's $(element).text()
61 Analog of jQuery's $(element).text()
63 """
62 """
64 if not isinstance(element, (ElementTree.ElementTree, ElementTree.Element)):
63 if isinstance(element, py3compat.string_types):
65 element = ElementTree.fromstring(element)
64 element = ElementTree.fromstring(element)
66
65
67 text = element.text or ""
66 text = element.text or ""
@@ -22,6 +22,7 b' body {'
22 }
22 }
23
23
24 pre {
24 pre {
25 padding: 0.2em;
25 border: none;
26 border: none;
26 margin: 0px;
27 margin: 0px;
27 font-size: 13px;
28 font-size: 13px;
@@ -60,6 +60,13 b' it introduces a new line'
60 \end{center}
60 \end{center}
61 ((*- endblock -*))
61 ((*- endblock -*))
62
62
63 ((*- block data_pdf -*))
64 \begin{center}
65 \includegraphics[width=0.7\textwidth]{(((output.pdf_filename[:-4])))}
66 \par
67 \end{center}
68 ((*- endblock -*))
69
63 ((* block pyout *))
70 ((* block pyout *))
64 ((* block data_priority scoped *))((( super() )))((* endblock *))
71 ((* block data_priority scoped *))((( super() )))((* endblock *))
65 ((* endblock pyout *))
72 ((* endblock pyout *))
@@ -358,6 +358,10 b' Note: For best display, use latex syntax highlighting. =))'
358 ((( conditionally_center_output(insert_graphics(output.svg_filename)) )))
358 ((( conditionally_center_output(insert_graphics(output.svg_filename)) )))
359 ((*- endblock -*))
359 ((*- endblock -*))
360
360
361 ((*- block data_pdf -*))
362 ((( conditionally_center_output(insert_graphics(output.pdf_filename[:-4])) )))
363 ((*- endblock -*))
364
361 ((*- block data_latex *))
365 ((*- block data_latex *))
362 ((* if resources.sphinx.centeroutput *))\begin{center}((* endif -*))((( output.latex | rm_math_space )))((*- if resources.sphinx.centeroutput *))\end{center} ((* endif -*))
366 ((* if resources.sphinx.centeroutput *))\begin{center}((* endif -*))((( output.latex | rm_math_space )))((*- if resources.sphinx.centeroutput *))\end{center} ((* endif -*))
363 ((*- endblock -*))
367 ((*- endblock -*))
@@ -79,7 +79,7 b' font-size: 80%;'
79 }
79 }
80 div.output_prompt {
80 div.output_prompt {
81 /* 5px right shift to account for margin in parent container */
81 /* 5px right shift to account for margin in parent container */
82 margin: 5px 5px 0 -5px;
82 margin: 5px 5px 0 0;
83 }
83 }
84 .rendered_html p {
84 .rendered_html p {
85 text-align: inherit;
85 text-align: inherit;
@@ -49,31 +49,16 b' class ConvertFiguresTransformer(Transformer):'
49 #Loop through all of the datatypes of the outputs in the cell.
49 #Loop through all of the datatypes of the outputs in the cell.
50 for index, cell_out in enumerate(cell.get('outputs', [])):
50 for index, cell_out in enumerate(cell.get('outputs', [])):
51 for data_type, data in cell_out.items():
51 for data_type, data in cell_out.items():
52
52 # this must run *before* extract figures,
53 #Get the name of the file exported by the extract figure
53 # so figure_name and filename do not exist
54 #transformer. Do not try to convert the figure if the extract
54 self._convert_figure(cell_out, resources, data_type, data)
55 #fig transformer hasn't touched it
56 filename = cell_out.get(data_type + '_filename', None)
57 if filename:
58 figure_name = filename[:filename.rfind('.')]
59 self._convert_figure(cell_out, figure_name, resources, data_type, data)
60 return cell, resources
55 return cell, resources
61
56
62
57
63 def _convert_figure(self, cell_out, resources, figure_name, data_type, data):
58 def _convert_figure(self, cell_out, resources, data_type, data):
64 """
59 """
65 Convert a figure and output the results to the cell output
60 Convert a figure and output the results to the cell output
66 """
61 """
67
62 if not self.to_format in cell_out and data_type == self.from_format:
68 if not self.to_format in cell_out:
63 data = self.convert_figure(data_type, data)
69 if data_type == self.from_format:
64 cell_out[self.to_format] = data
70 filename = figure_name + '.' + self.to_format
71 if filename not in resources['figures']:
72
73 #On the cell, make the figure available via
74 # cell.outputs[i].pdf_filename ... etc (PDF in example)
75 cell_out[self.to_format + '_filename'] = filename
76
77 #In the resources, make the figure available via
78 # resources['figures']['filename'] = data
79 resources['figures'][filename] = self.convert_figure(data_type, data)
@@ -13,9 +13,12 b" notebook file. The extracted figures are returned in the 'resources' dictionary"
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 import base64
16 import sys
17 import sys
18
17 from IPython.utils.traitlets import Unicode
19 from IPython.utils.traitlets import Unicode
18 from .base import Transformer
20 from .base import Transformer
21 from IPython.utils import py3compat
19
22
20 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
21 # Classes
24 # Classes
@@ -64,7 +67,10 b' class ExtractFigureTransformer(Transformer):'
64
67
65 #Binary files are base64-encoded, SVG is already XML
68 #Binary files are base64-encoded, SVG is already XML
66 if out_type in ('png', 'jpg', 'jpeg', 'pdf'):
69 if out_type in ('png', 'jpg', 'jpeg', 'pdf'):
67 data = data.decode('base64')
70 # data is b64-encoded as text (str, unicode)
71 # decodestring only accepts bytes
72 data = py3compat.cast_bytes(data)
73 data = base64.decodestring(data)
68 elif sys.platform == 'win32':
74 elif sys.platform == 'win32':
69 data = data.replace('\n', '\r\n').encode("UTF-8")
75 data = data.replace('\n', '\r\n').encode("UTF-8")
70 else:
76 else:
@@ -13,6 +13,8 b' one format to another.'
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 import base64
17 import io
16 import os
18 import os
17 import sys
19 import sys
18 import subprocess
20 import subprocess
@@ -27,9 +29,7 b' from .convertfigures import ConvertFiguresTransformer'
27 # Constants
29 # Constants
28 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
29
31
30 INKSCAPE_COMMAND = 'inkscape --without-gui --export-pdf="{to_filename}" "{from_filename}"'
32 INKSCAPE_APP = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
31 #INKSCAPE_OSX_COMMAND = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape --without-gui --export-pdf="{to_filename}" "{from_filename}"'
32
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Classes
35 # Classes
@@ -37,16 +37,37 b' INKSCAPE_COMMAND = \'inkscape --without-gui --export-pdf="{to_filename}" "{from_f'
37
37
38 class SVG2PDFTransformer(ConvertFiguresTransformer):
38 class SVG2PDFTransformer(ConvertFiguresTransformer):
39 """
39 """
40 Converts all of the outputs in a notebook from one format to another.
40 Converts all of the outputs in a notebook from SVG to PDF.
41 """
41 """
42
42
43 from_format = Unicode('svg', config=True, help='Format the converter accepts')
43 from_format = Unicode('svg', config=True, help='Format the converter accepts')
44 to_format = Unicode('pdf', config=False, help='Format the converter writes')
44 to_format = Unicode('pdf', config=False, help='Format the converter writes')
45
46 command = Unicode(config=True,
47 help="""The command to use for converting SVG to PDF
48
49 This string is a template, which will be formatted with the keys
50 to_filename and from_filename.
51
52 The conversion call must read the SVG from {from_flename},
53 and write a PDF to {to_filename}.
54 """)
55
56 def _command_default(self):
57 return self.inkscape + \
58 ' --without-gui --export-pdf="{to_filename}" "{from_filename}"'
59
60 inkscape = Unicode(config=True, help="The path to Inkscape, if necessary")
61 def _inkscape_default(self):
62 if sys.platform == "darwin":
63 if os.path.isfile(INKSCAPE_APP):
64 return INKSCAPE_APP
65 return "inkscape"
45
66
46
67
47 def convert_figure(self, data_format, data):
68 def convert_figure(self, data_format, data):
48 """
69 """
49 Convert a single Svg figure. Returns converted data.
70 Convert a single SVG figure to PDF. Returns converted data.
50 """
71 """
51
72
52 #Work in a temporary directory
73 #Work in a temporary directory
@@ -54,24 +75,21 b' class SVG2PDFTransformer(ConvertFiguresTransformer):'
54
75
55 #Write fig to temp file
76 #Write fig to temp file
56 input_filename = os.path.join(tmpdir, 'figure.' + data_format)
77 input_filename = os.path.join(tmpdir, 'figure.' + data_format)
57 with open(input_filename, 'w') as f:
78 # SVG data is unicode text
79 with io.open(input_filename, 'w', encoding='utf8') as f:
58 f.write(data)
80 f.write(data)
59
81
60 #Determine command (different on Mac OSX)
61 command = INKSCAPE_COMMAND
62 if sys.platform == 'darwin':
63 command = INKSCAPE_OSX_COMMAND
64
65 #Call conversion application
82 #Call conversion application
66 output_filename = os.path.join(tmpdir, 'figure.pdf')
83 output_filename = os.path.join(tmpdir, 'figure.pdf')
67 shell = command.format(from_filename=input_filename,
84 shell = self.command.format(from_filename=input_filename,
68 to_filename=output_filename)
85 to_filename=output_filename)
69 subprocess.call(shell, shell=True) #Shell=True okay since input is trusted.
86 subprocess.call(shell, shell=True) #Shell=True okay since input is trusted.
70
87
71 #Read output from drive
88 #Read output from drive
89 # return value expects a filename
72 if os.path.isfile(output_filename):
90 if os.path.isfile(output_filename):
73 with open(output_filename, 'rb') as f:
91 with open(output_filename, 'rb') as f:
74 return f.read().encode("base64") #PDF is a nb supported binary
92 # PDF is a nb supported binary, data type, so base64 encode.
75 #data type, so base64 encode.
93 return base64.encodestring(f.read())
76 else:
94 else:
77 return TypeError("Inkscape svg to png conversion failed")
95 raise TypeError("Inkscape svg to png conversion failed")
@@ -27,7 +27,7 b' class DebugWriter(WriterBase):'
27 resources that were extracted from the notebook(s) during export."""
27 resources that were extracted from the notebook(s) during export."""
28
28
29
29
30 def write(self, output, resources, **kw):
30 def write(self, output, resources, notebook_name='notebook', **kw):
31 """
31 """
32 Consume and write Jinja output.
32 Consume and write Jinja output.
33
33
@@ -9,6 +9,7 b' import os.path'
9 import re
9 import re
10 import sys
10 import sys
11 from textwrap import dedent
11 from textwrap import dedent
12 import time
12 from unicodedata import category
13 from unicodedata import category
13 import webbrowser
14 import webbrowser
14
15
@@ -291,6 +292,21 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
291 self._reading_callback = None
292 self._reading_callback = None
292 self._tab_width = 8
293 self._tab_width = 8
293
294
295 # List of strings pending to be appended as plain text in the widget.
296 # The text is not immediately inserted when available to not
297 # choke the Qt event loop with paint events for the widget in
298 # case of lots of output from kernel.
299 self._pending_insert_text = []
300
301 # Timer to flush the pending stream messages. The interval is adjusted
302 # later based on actual time taken for flushing a screen (buffer_size)
303 # of output text.
304 self._pending_text_flush_interval = QtCore.QTimer(self._control)
305 self._pending_text_flush_interval.setInterval(100)
306 self._pending_text_flush_interval.setSingleShot(True)
307 self._pending_text_flush_interval.timeout.connect(
308 self._flush_pending_stream)
309
294 # Set a monospaced font.
310 # Set a monospaced font.
295 self.reset_font()
311 self.reset_font()
296
312
@@ -877,8 +893,11 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
877 # Determine where to insert the content.
893 # Determine where to insert the content.
878 cursor = self._control.textCursor()
894 cursor = self._control.textCursor()
879 if before_prompt and (self._reading or not self._executing):
895 if before_prompt and (self._reading or not self._executing):
896 self._flush_pending_stream()
880 cursor.setPosition(self._append_before_prompt_pos)
897 cursor.setPosition(self._append_before_prompt_pos)
881 else:
898 else:
899 if insert != self._insert_plain_text:
900 self._flush_pending_stream()
882 cursor.movePosition(QtGui.QTextCursor.End)
901 cursor.movePosition(QtGui.QTextCursor.End)
883 start_pos = cursor.position()
902 start_pos = cursor.position()
884
903
@@ -1459,6 +1478,20 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1459
1478
1460 return False
1479 return False
1461
1480
1481 def _flush_pending_stream(self):
1482 """ Flush out pending text into the widget. """
1483 text = self._pending_insert_text
1484 self._pending_insert_text = []
1485 buffer_size = self._control.document().maximumBlockCount()
1486 if buffer_size > 0:
1487 text = self._get_last_lines_from_list(text, buffer_size)
1488 text = ''.join(text)
1489 t = time.time()
1490 self._insert_plain_text(self._get_end_cursor(), text, flush=True)
1491 # Set the flush interval to equal the maximum time to update text.
1492 self._pending_text_flush_interval.setInterval(max(100,
1493 (time.time()-t)*1000))
1494
1462 def _format_as_columns(self, items, separator=' '):
1495 def _format_as_columns(self, items, separator=' '):
1463 """ Transform a list of strings into a single string with columns.
1496 """ Transform a list of strings into a single string with columns.
1464
1497
@@ -1540,6 +1573,43 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1540 else:
1573 else:
1541 return None
1574 return None
1542
1575
1576 def _get_last_lines(self, text, num_lines, return_count=False):
1577 """ Return last specified number of lines of text (like `tail -n`).
1578 If return_count is True, returns a tuple of clipped text and the
1579 number of lines in the clipped text.
1580 """
1581 pos = len(text)
1582 if pos < num_lines:
1583 if return_count:
1584 return text, text.count('\n') if return_count else text
1585 else:
1586 return text
1587 i = 0
1588 while i < num_lines:
1589 pos = text.rfind('\n', None, pos)
1590 if pos == -1:
1591 pos = None
1592 break
1593 i += 1
1594 if return_count:
1595 return text[pos:], i
1596 else:
1597 return text[pos:]
1598
1599 def _get_last_lines_from_list(self, text_list, num_lines):
1600 """ Return the list of text clipped to last specified lines.
1601 """
1602 ret = []
1603 lines_pending = num_lines
1604 for text in reversed(text_list):
1605 text, lines_added = self._get_last_lines(text, lines_pending,
1606 return_count=True)
1607 ret.append(text)
1608 lines_pending -= lines_added
1609 if lines_pending <= 0:
1610 break
1611 return ret[::-1]
1612
1543 def _get_prompt_cursor(self):
1613 def _get_prompt_cursor(self):
1544 """ Convenience method that returns a cursor for the prompt position.
1614 """ Convenience method that returns a cursor for the prompt position.
1545 """
1615 """
@@ -1644,10 +1714,29 b' class ConsoleWidget(LoggingConfigurable, QtGui.QWidget):'
1644 cursor.endEditBlock()
1714 cursor.endEditBlock()
1645 return text
1715 return text
1646
1716
1647 def _insert_plain_text(self, cursor, text):
1717 def _insert_plain_text(self, cursor, text, flush=False):
1648 """ Inserts plain text using the specified cursor, processing ANSI codes
1718 """ Inserts plain text using the specified cursor, processing ANSI codes
1649 if enabled.
1719 if enabled.
1650 """
1720 """
1721 # maximumBlockCount() can be different from self.buffer_size in
1722 # case input prompt is active.
1723 buffer_size = self._control.document().maximumBlockCount()
1724
1725 if self._executing and not flush and \
1726 self._pending_text_flush_interval.isActive():
1727 self._pending_insert_text.append(text)
1728 if buffer_size > 0:
1729 self._pending_insert_text = self._get_last_lines_from_list(
1730 self._pending_insert_text, buffer_size)
1731 return
1732
1733 if self._executing and not self._pending_text_flush_interval.isActive():
1734 self._pending_text_flush_interval.start()
1735
1736 # Clip the text to last `buffer_size` lines.
1737 if buffer_size > 0:
1738 text = self._get_last_lines(text, buffer_size)
1739
1651 cursor.beginEditBlock()
1740 cursor.beginEditBlock()
1652 if self.ansi_codes:
1741 if self.ansi_codes:
1653 for substring in self._ansi_processor.split_string(text):
1742 for substring in self._ansi_processor.split_string(text):
@@ -167,7 +167,6 b" have['wx'] = test_for('wx')"
167 have['wx.aui'] = test_for('wx.aui')
167 have['wx.aui'] = test_for('wx.aui')
168 have['azure'] = test_for('azure')
168 have['azure'] = test_for('azure')
169 have['sphinx'] = test_for('sphinx')
169 have['sphinx'] = test_for('sphinx')
170 have['markdown'] = test_for('markdown')
171
170
172 min_zmq = (2,1,11)
171 min_zmq = (2,1,11)
173
172
@@ -254,6 +253,12 b' def make_exclude():'
254 exclusions.append(ipjoin('lib', 'inputhookgtk'))
253 exclusions.append(ipjoin('lib', 'inputhookgtk'))
255 exclusions.append(ipjoin('kernel', 'zmq', 'gui', 'gtkembed'))
254 exclusions.append(ipjoin('kernel', 'zmq', 'gui', 'gtkembed'))
256
255
256 #Also done unconditionally, exclude nbconvert directories containing
257 #config files used to test. Executing the config files with iptest would
258 #cause an exception.
259 exclusions.append(ipjoin('nbconvert', 'tests', 'files'))
260 exclusions.append(ipjoin('nbconvert', 'exporters', 'tests', 'files'))
261
257 # These have to be skipped on win32 because the use echo, rm, cd, etc.
262 # These have to be skipped on win32 because the use echo, rm, cd, etc.
258 # See ticket https://github.com/ipython/ipython/issues/87
263 # See ticket https://github.com/ipython/ipython/issues/87
259 if sys.platform == 'win32':
264 if sys.platform == 'win32':
@@ -307,7 +312,7 b' def make_exclude():'
307 if not have['azure']:
312 if not have['azure']:
308 exclusions.append(ipjoin('html', 'services', 'notebooks', 'azurenbmanager'))
313 exclusions.append(ipjoin('html', 'services', 'notebooks', 'azurenbmanager'))
309
314
310 if not all((have['pygments'], have['jinja2'], have['markdown'], have['sphinx'])):
315 if not all((have['pygments'], have['jinja2'], have['sphinx'])):
311 exclusions.append(ipjoin('nbconvert'))
316 exclusions.append(ipjoin('nbconvert'))
312
317
313 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
318 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
@@ -459,7 +464,7 b' def make_runners(inc_slow=False):'
459 if inc_slow:
464 if inc_slow:
460 nose_pkg_names.append('parallel')
465 nose_pkg_names.append('parallel')
461
466
462 if all((have['pygments'], have['jinja2'], have['markdown'], have['sphinx'])):
467 if all((have['pygments'], have['jinja2'], have['sphinx'])):
463 nose_pkg_names.append('nbconvert')
468 nose_pkg_names.append('nbconvert')
464
469
465 # For debugging this code, only load quick stuff
470 # For debugging this code, only load quick stuff
@@ -41,14 +41,15 b' optional dependencies:'
41
41
42 .. code-block:: bash
42 .. code-block:: bash
43
43
44 $ easy_install ipython[zmq,qtconsole,notebook,test]
44 $ easy_install ipython[all]
45
45
46 This will get:
46 This will get:
47
47
48 - jinja2, needed for the notebook
48 - jinja2, needed for the notebook
49 - sphinx, needed for nbconvert
49 - pyzmq, needed for IPython's parallel computing features, qt console and
50 - pyzmq, needed for IPython's parallel computing features, qt console and
50 notebook.
51 notebook.
51 - pygments, used by the Qt console for syntax highlighting.
52 - pygments, used by nbconvert and the Qt console for syntax highlighting.
52 - tornado, needed by the web-based notebook
53 - tornado, needed by the web-based notebook
53 - nose, used by the test suite.
54 - nose, used by the test suite.
54
55
@@ -275,7 +276,7 b' and OSX clients will use the shell ssh command, but on Windows, we also'
275 support tunneling with paramiko_.
276 support tunneling with paramiko_.
276
277
277 Dependencies for IPython.kernel.zmq
278 Dependencies for IPython.kernel.zmq
278 ============================
279 ===================================
279
280
280 pyzmq
281 pyzmq
281 -----
282 -----
@@ -396,11 +397,29 b' There are some early reports that the Notebook works on Internet Explorer 10, bu'
396 expect there will be some CSS issues related to the flexible box model.
397 expect there will be some CSS issues related to the flexible box model.
397
398
398
399
400 Dependencies for nbconvert (converting notebooks to various formats)
401 ====================================================================
402
403 pandoc
404 ------
405
406 The most important dependency of nbconvert is Pandoc_, a document format translation program.
407 This is not a Python package, so it cannot be expressed as a regular IPython dependency with setuptools.
408
409 To install pandoc on Linux, you can generally use your package manager::
410
411 sudo apt-get install pandoc
412
413 On other platforms, you can get pandoc from `their website <http://johnmacfarlane.net/pandoc/installing.html>`_.
414
415
399 .. _ZeroMQ: http://www.zeromq.org
416 .. _ZeroMQ: http://www.zeromq.org
400 .. _PyZMQ: https://github.com/zeromq/pyzmq
417 .. _PyZMQ: https://github.com/zeromq/pyzmq
401 .. _paramiko: https://github.com/robey/paramiko
418 .. _paramiko: https://github.com/robey/paramiko
402 .. _pygments: http://pygments.org
419 .. _pygments: http://pygments.org
403 .. _pexpect: http://www.noah.org/wiki/Pexpect
420 .. _pexpect: http://www.noah.org/wiki/Pexpect
404 .. _Jinja: http://jinja.pocoo.org
421 .. _Jinja: http://jinja.pocoo.org
422 .. _Sphinx: http://sphinx-doc.org
423 .. _pandoc: http://johnmacfarlane.net/pandoc
405 .. _Tornado: http://www.tornadoweb.org
424 .. _Tornado: http://www.tornadoweb.org
406 .. _MathJax: http://www.mathjax.org
425 .. _MathJax: http://www.mathjax.org
@@ -280,6 +280,14 b" if 'setuptools' in sys.modules:"
280 notebook = ['tornado>=2.0', 'pyzmq>=2.1.11', 'jinja2'],
280 notebook = ['tornado>=2.0', 'pyzmq>=2.1.11', 'jinja2'],
281 nbconvert = ['pygments', 'jinja2', 'Sphinx>=0.3']
281 nbconvert = ['pygments', 'jinja2', 'Sphinx>=0.3']
282 )
282 )
283 everything = set()
284 for deps in setup_args['extras_require'].values():
285 if not isinstance(deps, list):
286 deps = [deps]
287 for dep in deps:
288 everything.add(dep)
289 setup_args['extras_require']['all'] = everything
290
283 requires = setup_args.setdefault('install_requires', [])
291 requires = setup_args.setdefault('install_requires', [])
284 setupext.display_status = False
292 setupext.display_status = False
285 if not setupext.check_for_readline():
293 if not setupext.check_for_readline():
@@ -152,7 +152,8 b' def find_package_data():'
152 'IPython.html' : ['templates/*'] + static_data,
152 'IPython.html' : ['templates/*'] + static_data,
153 'IPython.qt.console' : ['resources/icon/*.svg'],
153 'IPython.qt.console' : ['resources/icon/*.svg'],
154 'IPython.nbconvert' : ['templates/*.tpl', 'templates/latex/*.tplx',
154 'IPython.nbconvert' : ['templates/*.tpl', 'templates/latex/*.tplx',
155 'templates/latex/skeleton/*.tplx', 'templates/skeleton/*']
155 'templates/latex/skeleton/*.tplx', 'templates/skeleton/*',
156 'tests/files/*.*', 'exporters/tests/files/*.*']
156 }
157 }
157 return package_data
158 return package_data
158
159
General Comments 0
You need to be logged in to leave comments. Login now