##// END OF EJS Templates
Merge pull request #3500 from ipython/nbconvert...
Brian E. Granger -
r11104:fba37dfd merge
parent child Browse files
Show More
@@ -0,0 +1,5 b''
1 """Utilities for converting notebooks to and from different formats."""
2
3 from .exporters import *
4 import filters
5 import transformers
@@ -0,0 +1,10 b''
1 from .basichtml import BasicHtmlExporter
2 from .export import *
3 from .exporter import Exporter
4 from .fullhtml import FullHtmlExporter
5 from .latex import LatexExporter
6 from .markdown import MarkdownExporter
7 from .python import PythonExporter
8 from .rst import RstExporter
9 from .sphinx_howto import SphinxHowtoExporter
10 from .sphinx_manual import SphinxManualExporter
@@ -0,0 +1,55 b''
1 """
2 Exporter that exports Basic HTML.
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.traitlets import Unicode
18
19 from ..transformers.csshtmlheader import CSSHtmlHeaderTransformer
20
21 from .exporter import Exporter
22
23 #-----------------------------------------------------------------------------
24 # Classes
25 #-----------------------------------------------------------------------------
26
27 class BasicHtmlExporter(Exporter):
28 """
29 Exports a basic HTML document. This exporter assists with the export of
30 HTML. Inherit from it if you are writing your own HTML template and need
31 custom transformers/filters. If you don't need custom transformers/
32 filters, just change the 'template_file' config option.
33 """
34
35 file_extension = Unicode(
36 'html', config=True,
37 help="Extension of the file that should be written to disk"
38 )
39
40 template_file = Unicode(
41 'basichtml', config=True,
42 help="Name of the template file to use")
43
44
45 def _register_transformers(self):
46 """
47 Register all of the transformers needed for this exporter.
48 """
49
50 #Register the transformers of the base class.
51 super(BasicHtmlExporter, self)._register_transformers()
52
53 #Register CSSHtmlHeaderTransformer transformer
54 self.register_transformer(CSSHtmlHeaderTransformer)
55
@@ -0,0 +1,225 b''
1 """
2 Module containing single call export functions.
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 functools import wraps
17
18 from IPython.nbformat.v3.nbbase import NotebookNode
19
20 from .exporter import Exporter
21 from .basichtml import BasicHtmlExporter
22 from .fullhtml import FullHtmlExporter
23 from .latex import LatexExporter
24 from .markdown import MarkdownExporter
25 from .python import PythonExporter
26 from .python_armor import PythonArmorExporter
27 from .reveal import RevealExporter
28 from .rst import RstExporter
29 from .sphinx_howto import SphinxHowtoExporter
30 from .sphinx_manual import SphinxManualExporter
31
32 #-----------------------------------------------------------------------------
33 # Classes
34 #-----------------------------------------------------------------------------
35
36 def DocDecorator(f):
37
38 #Set docstring of function
39 f.__doc__ = f.__doc__ + """
40 nb : Notebook node
41 config : config
42 User configuration instance.
43 transformers : list[of transformer]
44 Custom transformers to apply to the notebook prior to engaging
45 the Jinja template engine. Any transformers specified here
46 will override existing transformers if a naming conflict
47 occurs.
48 filters : list[of filter]
49 Custom filters to make accessible to the Jinja templates. Any
50 filters specified here will override existing filters if a
51 naming conflict occurs.
52
53 Returns
54 ----------
55 tuple- output, resources, exporter_instance
56 output : str
57 Jinja 2 output. This is the resulting converted notebook.
58 resources : dictionary
59 Dictionary of resources used prior to and during the conversion
60 process.
61 exporter_instance : Exporter
62 Instance of the Exporter class used to export the document. Useful
63 to caller because it provides a 'file_extension' property which
64 specifies what extension the output should be saved as."""
65
66 @wraps(f)
67 def decorator(*args, **kwargs):
68 return f(*args, **kwargs)
69
70 return decorator
71
72
73 #-----------------------------------------------------------------------------
74 # Functions
75 #-----------------------------------------------------------------------------
76
77 __all__ = [
78 'export',
79 'export_sphinx_manual',
80 'export_sphinx_howto',
81 'export_basic_html',
82 'export_full_html',
83 'export_latex',
84 'export_markdown',
85 'export_python',
86 'export_python_armor',
87 'export_reveal',
88 'export_rst',
89 'export_by_name'
90 ]
91
92 @DocDecorator
93 def export(exporter_type, nb, config=None, transformers=None, filters=None):
94 """
95 Export a notebook object using specific exporter class.
96
97 exporter_type : Exporter class type
98 Class type of the exporter that should be used. This method
99 will initialize it's own instance of the class. It is
100 ASSUMED that the class type provided exposes a
101 constructor (__init__) with the same signature as the
102 base Exporter class.}
103 """
104
105 #Check arguments
106 if exporter_type is None:
107 raise TypeError("Exporter is None")
108 elif not issubclass(exporter_type, Exporter):
109 raise TypeError("Exporter type does not inherit from Exporter (base)")
110
111 if nb is None:
112 raise TypeError("nb is None")
113
114 #Create the exporter
115 exporter_instance = exporter_type(preprocessors=transformers,
116 jinja_filters=filters, config=config)
117
118 #Try to convert the notebook using the appropriate conversion function.
119 if isinstance(nb, NotebookNode):
120 output, resources = exporter_instance.from_notebook_node(nb)
121 elif isinstance(nb, basestring):
122 output, resources = exporter_instance.from_filename(nb)
123 else:
124 output, resources = exporter_instance.from_file(nb)
125 return output, resources, exporter_instance
126
127
128 @DocDecorator
129 def export_sphinx_manual(nb, config=None, transformers=None, filters=None):
130 """
131 Export a notebook object to Sphinx Manual LaTeX
132 """
133 return export(SphinxManualExporter, nb, config, transformers, filters)
134
135
136 @DocDecorator
137 def export_sphinx_howto(nb, config=None, transformers=None, filters=None):
138 """
139 Export a notebook object to Sphinx HowTo LaTeX
140 """
141 return export(SphinxHowtoExporter, nb, config, transformers, filters)
142
143
144 @DocDecorator
145 def export_basic_html(nb, config=None, transformers=None, filters=None):
146 """
147 Export a notebook object to Basic HTML
148 """
149 return export(BasicHtmlExporter, nb, config, transformers, filters)
150
151
152 @DocDecorator
153 def export_full_html(nb, config=None, transformers=None, filters=None):
154 """
155 Export a notebook object to Full HTML
156 """
157 return export(FullHtmlExporter, nb, config, transformers, filters)
158
159
160 @DocDecorator
161 def export_latex(nb, config=None, transformers=None, filters=None):
162 """
163 Export a notebook object to LaTeX
164 """
165 return export(LatexExporter, nb, config, transformers, filters)
166
167
168 @DocDecorator
169 def export_markdown(nb, config=None, transformers=None, filters=None):
170 """
171 Export a notebook object to Markdown
172 """
173 return export(MarkdownExporter, nb, config, transformers, filters)
174
175
176 @DocDecorator
177 def export_python(nb, config=None, transformers=None, filters=None):
178 """
179 Export a notebook object to Python
180 """
181 return export(PythonExporter, nb, config, transformers, filters)
182
183
184 @DocDecorator
185 def export_python_armor(nb, config=None, transformers=None, filters=None):
186 """
187 Export a notebook object to Python (Armor)
188 """
189 return export(PythonArmorExporter, nb, config, transformers, filters)
190
191
192 @DocDecorator
193 def export_reveal(nb, config=None, transformers=None, filters=None):
194 """
195 Export a notebook object to Reveal
196 """
197 return export(RevealExporter, nb, config, transformers, filters)
198
199
200 @DocDecorator
201 def export_rst(nb, config=None, transformers=None, filters=None):
202 """
203 Export a notebook object to RST
204 """
205 return export(RstExporter, nb, config, transformers, filters)
206
207
208 @DocDecorator
209 def export_by_name(template_name, nb, config=None, transformers=None, filters=None):
210 """
211 Export a notebook object to a template type by its name. Reflection
212 (Inspect) is used to find the template's corresponding explicit export
213 method defined in this module. That method is then called directly.
214
215 template_name : str
216 Name of the template style to export to.
217 """
218
219 function_name = "export_" + template_name.lower()
220
221 if function_name in globals():
222 return globals()[function_name](nb, config, transformers, filters)
223 else:
224 return None
225
@@ -0,0 +1,341 b''
1 """This module defines Exporter, a highly configurable converter
2 that uses Jinja2 to export notebook files into different formats.
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 __future__ import print_function, absolute_import
18
19 # Stdlib imports
20 import io
21 import os
22 import inspect
23 from copy import deepcopy
24
25 # other libs/dependencies
26 from jinja2 import Environment, FileSystemLoader
27 from markdown import markdown
28
29 # IPython imports
30 from IPython.config.configurable import Configurable
31 from IPython.config import Config
32 from IPython.nbformat import current as nbformat
33 from IPython.utils.traitlets import MetaHasTraits, Unicode
34 from IPython.utils.text import indent
35
36 from IPython.nbconvert import filters
37 from IPython.nbconvert import transformers
38
39 #-----------------------------------------------------------------------------
40 # Globals and constants
41 #-----------------------------------------------------------------------------
42
43 #Jinja2 extensions to load.
44 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
45
46 default_filters = {
47 'indent': indent,
48 'markdown': markdown,
49 'ansi2html': filters.ansi2html,
50 'filter_data_type': filters.DataTypeFilter,
51 'get_lines': filters.get_lines,
52 'highlight': filters.highlight,
53 'highlight2html': filters.highlight,
54 'highlight2latex': filters.highlight2latex,
55 'markdown2latex': filters.markdown2latex,
56 'markdown2rst': filters.markdown2rst,
57 'pycomment': filters.python_comment,
58 'rm_ansi': filters.remove_ansi,
59 'rm_dollars': filters.strip_dollars,
60 'rm_fake': filters.rm_fake,
61 'ansi2latex': filters.ansi2latex,
62 'rm_math_space': filters.rm_math_space,
63 'wrap': filters.wrap
64 }
65
66 #-----------------------------------------------------------------------------
67 # Class
68 #-----------------------------------------------------------------------------
69
70 class Exporter(Configurable):
71 """
72 Exports notebooks into other file formats. Uses Jinja 2 templating engine
73 to output new formats. Inherit from this class if you are creating a new
74 template type along with new filters/transformers. If the filters/
75 transformers provided by default suffice, there is no need to inherit from
76 this class. Instead, override the template_file and file_extension
77 traits via a config file.
78
79 {filters}
80 """
81
82 # finish the docstring
83 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
84
85
86 template_file = Unicode(
87 '', config=True,
88 help="Name of the template file to use")
89
90 file_extension = Unicode(
91 'txt', config=True,
92 help="Extension of the file that should be written to disk"
93 )
94
95 template_path = Unicode(
96 "/../templates/", config=True,
97 help="Path where the template files are located.")
98
99 template_skeleton_path = Unicode(
100 "/../templates/skeleton/", config=True,
101 help="Path where the template skeleton files are located.")
102
103 #Jinja block definitions
104 jinja_comment_block_start = Unicode("", config=True)
105 jinja_comment_block_end = Unicode("", config=True)
106 jinja_variable_block_start = Unicode("", config=True)
107 jinja_variable_block_end = Unicode("", config=True)
108 jinja_logic_block_start = Unicode("", config=True)
109 jinja_logic_block_end = Unicode("", config=True)
110
111 #Extension that the template files use.
112 template_extension = Unicode(".tpl", config=True)
113
114 #Processors that process the input data prior to the export, set in the
115 #constructor for this class.
116 transformers = None
117
118
119 def __init__(self, transformers=None, filters=None, config=None, **kw):
120 """
121 Public constructor
122
123 Parameters
124 ----------
125 transformers : list[of transformer]
126 Custom transformers to apply to the notebook prior to engaging
127 the Jinja template engine. Any transformers specified here
128 will override existing transformers if a naming conflict
129 occurs.
130 filters : dict[of filter]
131 filters specified here will override existing filters if a naming
132 conflict occurs. Filters are availlable in jinja template through
133 the name of the corresponding key. Cf class docstring for
134 availlable default filters.
135 config : config
136 User configuration instance.
137 """
138
139 #Call the base class constructor
140 c = self.default_config
141 if config:
142 c.merge(config)
143
144 super(Exporter, self).__init__(config=c, **kw)
145
146 #Standard environment
147 self._init_environment()
148
149 #Add transformers
150 self._register_transformers()
151
152 #Add filters to the Jinja2 environment
153 self._register_filters()
154
155 #Load user transformers. Overwrite existing transformers if need be.
156 if transformers :
157 for transformer in transformers:
158 self.register_transformer(transformer)
159
160 #Load user filters. Overwrite existing filters if need be.
161 if not filters is None:
162 for key, user_filter in filters.iteritems():
163 if issubclass(user_filter, MetaHasTraits):
164 self.environment.filters[key] = user_filter(config=config)
165 else:
166 self.environment.filters[key] = user_filter
167
168 @property
169 def default_config(self):
170 return Config()
171
172
173
174 def from_notebook_node(self, nb, resources=None):
175 """
176 Convert a notebook from a notebook node instance.
177
178 Parameters
179 ----------
180 nb : Notebook node
181 resources : a dict of additional resources that
182 can be accessed read/write by transformers
183 and filters.
184 """
185 if resources is None:
186 resources = {}
187 nb, resources = self._preprocess(nb, resources)
188
189 #Load the template file.
190 self.template = self.environment.get_template(self.template_file+self.template_extension)
191
192 return self.template.render(nb=nb, resources=resources), resources
193
194
195 def from_filename(self, filename):
196 """
197 Convert a notebook from a notebook file.
198
199 Parameters
200 ----------
201 filename : str
202 Full filename of the notebook file to open and convert.
203 """
204
205 with io.open(filename) as f:
206 return self.from_notebook_node(nbformat.read(f, 'json'))
207
208
209 def from_file(self, file_stream):
210 """
211 Convert a notebook from a notebook file.
212
213 Parameters
214 ----------
215 file_stream : file-like object
216 Notebook file-like object to convert.
217 """
218 return self.from_notebook_node(nbformat.read(file_stream, 'json'))
219
220
221 def register_transformer(self, transformer):
222 """
223 Register a transformer.
224 Transformers are classes that act upon the notebook before it is
225 passed into the Jinja templating engine. Transformers are also
226 capable of passing additional information to the Jinja
227 templating engine.
228
229 Parameters
230 ----------
231 transformer : transformer
232 """
233 if self.transformers is None:
234 self.transformers = []
235
236 if inspect.isfunction(transformer):
237 self.transformers.append(transformer)
238 return transformer
239 elif isinstance(transformer, MetaHasTraits):
240 transformer_instance = transformer(config=self.config)
241 self.transformers.append(transformer_instance)
242 return transformer_instance
243 else:
244 transformer_instance = transformer()
245 self.transformers.append(transformer_instance)
246 return transformer_instance
247
248
249 def register_filter(self, name, filter):
250 """
251 Register a filter.
252 A filter is a function that accepts and acts on one string.
253 The filters are accesible within the Jinja templating engine.
254
255 Parameters
256 ----------
257 name : str
258 name to give the filter in the Jinja engine
259 filter : filter
260 """
261 if inspect.isfunction(filter):
262 self.environment.filters[name] = filter
263 elif isinstance(filter, MetaHasTraits):
264 self.environment.filters[name] = filter(config=self.config)
265 else:
266 self.environment.filters[name] = filter()
267 return self.environment.filters[name]
268
269
270 def _register_transformers(self):
271 """
272 Register all of the transformers needed for this exporter.
273 """
274
275 self.register_transformer(transformers.coalesce_streams)
276
277 #Remember the figure extraction transformer so it can be enabled and
278 #disabled easily later.
279 self.extract_figure_transformer = self.register_transformer(transformers.ExtractFigureTransformer)
280
281
282 def _register_filters(self):
283 """
284 Register all of the filters required for the exporter.
285 """
286 for k, v in default_filters.iteritems():
287 self.register_filter(k, v)
288
289
290 def _init_environment(self):
291 """
292 Create the Jinja templating environment.
293 """
294
295 self.environment = Environment(
296 loader=FileSystemLoader([
297 os.path.dirname(os.path.realpath(__file__)) + self.template_path,
298 os.path.dirname(os.path.realpath(__file__)) + self.template_skeleton_path,
299 ]),
300 extensions=JINJA_EXTENSIONS
301 )
302
303 #Set special Jinja2 syntax that will not conflict with latex.
304 if self.jinja_logic_block_start:
305 self.environment.block_start_string = self.jinja_logic_block_start
306 if self.jinja_logic_block_end:
307 self.environment.block_end_string = self.jinja_logic_block_end
308 if self.jinja_variable_block_start:
309 self.environment.variable_start_string = self.jinja_variable_block_start
310 if self.jinja_variable_block_end:
311 self.environment.variable_end_string = self.jinja_variable_block_end
312 if self.jinja_comment_block_start:
313 self.environment.comment_start_string = self.jinja_comment_block_start
314 if self.jinja_comment_block_end:
315 self.environment.comment_end_string = self.jinja_comment_block_end
316
317
318 def _preprocess(self, nb, resources):
319 """
320 Preprocess the notebook before passing it into the Jinja engine.
321 To preprocess the notebook is to apply all of the
322
323 Parameters
324 ----------
325 nb : notebook node
326 notebook that is being exported.
327 resources : a dict of additional resources that
328 can be accessed read/write by transformers
329 and filters.
330 """
331
332 # Do a deepcopy first,
333 # we are never safe enough with what the transformers could do.
334 nbc = deepcopy(nb)
335 resc = deepcopy(resources)
336 #Run each transformer on the notebook. Carry the output along
337 #to each transformer
338 for transformer in self.transformers:
339 nb, resources = transformer(nbc, resc)
340 return nb, resources
341
@@ -0,0 +1,39 b''
1 """
2 Exporter for exporting full HTML documents.
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.traitlets import Unicode
18
19 from .basichtml import BasicHtmlExporter
20 from IPython.config import Config
21
22 #-----------------------------------------------------------------------------
23 # Classes
24 #-----------------------------------------------------------------------------
25
26 class FullHtmlExporter(BasicHtmlExporter):
27 """
28 Exports a full HTML document.
29 """
30
31 template_file = Unicode(
32 'fullhtml', config=True,
33 help="Name of the template file to use")
34
35 @property
36 def default_config(self):
37 c = Config({'CSSHtmlHeaderTransformer':{'enabled':True}})
38 c.merge(super(FullHtmlExporter,self).default_config)
39 return c
@@ -0,0 +1,105 b''
1 """
2 Exporter that allows Latex Jinja templates to work. Contains logic to
3 appropriately prepare IPYNB files for export to LaTeX. Including but
4 not limited to escaping LaTeX, fixing math region tags, using special
5 tags to circumvent Jinja/Latex syntax conflicts.
6 """
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
9 #
10 # Distributed under the terms of the Modified BSD License.
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 # IPython imports
20 from IPython.utils.traitlets import Unicode
21 from IPython.config import Config
22
23 from IPython.nbconvert import filters, transformers
24 from .exporter import Exporter
25
26 #-----------------------------------------------------------------------------
27 # Classes and functions
28 #-----------------------------------------------------------------------------
29
30 class LatexExporter(Exporter):
31 """
32 Exports to a Latex template. Inherit from this class if your template is
33 LaTeX based and you need custom tranformers/filters. Inherit from it if
34 you are writing your own HTML template and need custom tranformers/filters.
35 If you don't need custom tranformers/filters, just change the
36 'template_file' config option. Place your template in the special "/latex"
37 subfolder of the "../templates" folder.
38 """
39
40 file_extension = Unicode(
41 'tex', config=True,
42 help="Extension of the file that should be written to disk")
43
44 template_file = Unicode(
45 'base', config=True,
46 help="Name of the template file to use")
47
48 #Latex constants
49 template_path = Unicode(
50 "/../templates/latex/", config=True,
51 help="Path where the template files are located.")
52
53 template_skeleton_path = Unicode(
54 "/../templates/latex/skeleton/", config=True,
55 help="Path where the template skeleton files are located.")
56
57 #Special Jinja2 syntax that will not conflict when exporting latex.
58 jinja_comment_block_start = Unicode("((=", config=True)
59 jinja_comment_block_end = Unicode("=))", config=True)
60 jinja_variable_block_start = Unicode("(((", config=True)
61 jinja_variable_block_end = Unicode(")))", config=True)
62 jinja_logic_block_start = Unicode("((*", config=True)
63 jinja_logic_block_end = Unicode("*))", config=True)
64
65 #Extension that the template files use.
66 template_extension = Unicode(".tplx", config=True)
67
68 def _register_filters(self):
69 """
70 Register all of the filters required for the exporter.
71 """
72
73 #Register the filters of the base class.
74 super(LatexExporter, self)._register_filters()
75
76 #Add latex filters to the Jinja2 environment
77 self.register_filter('escape_tex', filters.escape_latex)
78 self.register_filter('highlight', filters.highlight2latex)
79
80
81 def _register_transformers(self):
82 """
83 Register all of the transformers needed for this exporter.
84 """
85
86 #Register the transformers of the base class.
87 super(LatexExporter, self)._register_transformers()
88
89 #Register latex transformer
90 self.register_transformer(transformers.LatexTransformer)
91
92 @property
93 def default_config(self):
94 c = Config({
95 'GlobalConfigurable': {
96 'display_data_priority' : ['latex', 'svg', 'png', 'jpg', 'jpeg' , 'text']
97 },
98 'ExtractFigureTransformer': {
99 'enabled':True,
100 'extra_ext_map':{'svg':'pdf'},
101 }
102 })
103 c.merge(super(LatexExporter,self).default_config)
104 return c
105
@@ -0,0 +1,35 b''
1 """
2 Exporter that will export your ipynb to Markdown.
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 IPython.utils.traitlets import Unicode
17
18 from .exporter import Exporter
19
20 #-----------------------------------------------------------------------------
21 # Classes
22 #-----------------------------------------------------------------------------
23
24 class MarkdownExporter(Exporter):
25 """
26 Exports to a markdown document (.md)
27 """
28
29 file_extension = Unicode(
30 'md', config=True,
31 help="Extension of the file that should be written to disk")
32
33 template_file = Unicode(
34 'markdown', config=True,
35 help="Name of the template file to use")
@@ -0,0 +1,35 b''
1 """
2 Python exporter which exports Notebook code into a PY file.
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 IPython.utils.traitlets import Unicode
17
18 from .exporter import Exporter
19
20 #-----------------------------------------------------------------------------
21 # Classes
22 #-----------------------------------------------------------------------------
23
24 class PythonExporter(Exporter):
25 """
26 Exports a Python code file.
27 """
28
29 file_extension = Unicode(
30 'py', config=True,
31 help="Extension of the file that should be written to disk")
32
33 template_file = Unicode(
34 'python', config=True,
35 help="Name of the template file to use")
@@ -0,0 +1,32 b''
1 """
2 Exporter that exports a Python-Armor code file (.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.utils.traitlets import Unicode
18
19 from .python import PythonExporter
20
21 #-----------------------------------------------------------------------------
22 # Classes
23 #-----------------------------------------------------------------------------
24
25 class PythonArmorExporter(PythonExporter):
26 """
27 Exports a Python-Armor code file (.py)
28 """
29
30 template_file = Unicode(
31 'python_armor', config=True,
32 help="Name of the template file to use")
@@ -0,0 +1,54 b''
1 """
2 Reveal slide show exporter.
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 IPython.utils.traitlets import Unicode
17 from IPython.config import Config
18
19 from .basichtml import BasicHtmlExporter
20 from IPython.nbconvert import transformers
21
22 #-----------------------------------------------------------------------------
23 # Classes
24 #-----------------------------------------------------------------------------
25
26 class RevealExporter(BasicHtmlExporter):
27 """
28 Exports a Reveal slide show (.HTML) which may be rendered in a web browser.
29 """
30
31 file_extension = Unicode(
32 'reveal.html', config=True,
33 help="Extension of the file that should be written to disk")
34
35 template_file = Unicode(
36 'reveal', config=True,
37 help="Name of the template file to use")
38
39 def _register_transformers(self):
40 """
41 Register all of the transformers needed for this exporter.
42 """
43
44 #Register the transformers of the base class.
45 super(RevealExporter, self)._register_transformers()
46
47 #Register reveal help transformer
48 self.register_transformer(transformers.RevealHelpTransformer)
49
50 @property
51 def default_config(self):
52 c = Config({'CSSHtmlHeaderTransformer':{'enabled':True}})
53 c.merge(super(RevealExporter,self).default_config)
54 return c
@@ -0,0 +1,42 b''
1 """
2 Exporter for exporting notebooks to restructured text.
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 IPython.utils.traitlets import Unicode
17 from IPython.config import Config
18
19 from .exporter import Exporter
20
21 #-----------------------------------------------------------------------------
22 # Classes
23 #-----------------------------------------------------------------------------
24
25 class RstExporter(Exporter):
26 """
27 Exports restructured text documents.
28 """
29
30 file_extension = Unicode(
31 'rst', config=True,
32 help="Extension of the file that should be written to disk")
33
34 template_file = Unicode(
35 'rst', config=True,
36 help="Name of the template file to use")
37
38 @property
39 def default_config(self):
40 c = Config({'ExtractFigureTransformer':{'enabled':True}})
41 c.merge(super(RstExporter,self).default_config)
42 return c
@@ -0,0 +1,54 b''
1 """
2 Exporter for exporting notebooks to Sphinx 'HowTo' style latex. Latex
3 formatted for use with PDFLatex.
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.traitlets import Unicode
18 from IPython.config import Config
19
20 # local import
21 from .latex import LatexExporter
22
23 from IPython.nbconvert import transformers
24
25 #-----------------------------------------------------------------------------
26 # Classes
27 #-----------------------------------------------------------------------------
28
29 class SphinxHowtoExporter(LatexExporter):
30 """
31 Exports Sphinx "HowTo" LaTeX documents. The Sphinx "HowTo" exporter
32 produces short document format latex for use with PDFLatex.
33 """
34
35 template_file = Unicode(
36 'sphinx_howto', config=True,
37 help="Name of the template file to use")
38
39 def _register_transformers(self):
40
41 #Register the transformers of the base class.
42 super(SphinxHowtoExporter, self)._register_transformers()
43
44 #Register sphinx latex transformer
45 self.register_transformer(transformers.SphinxTransformer)
46
47 @property
48 def default_config(self):
49 c = Config({
50 'SphinxTransformer': {'enabled':True}
51 })
52 c.merge(super(SphinxHowtoExporter,self).default_config)
53 return c
54
@@ -0,0 +1,34 b''
1 """
2 Exporter for exporting notebooks to Sphinx 'Manual' style latex. Latex
3 formatted for use with PDFLatex.
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.traitlets import Unicode
18
19 from .sphinx_howto import SphinxHowtoExporter
20
21 #-----------------------------------------------------------------------------
22 # Classes
23 #-----------------------------------------------------------------------------
24
25 class SphinxManualExporter(SphinxHowtoExporter):
26 """
27 Exports Sphinx "Manual" LaTeX documents. The Sphinx "Manual" exporter
28 produces book like latex output for use with PDFLatex.
29 """
30
31 template_file = Unicode(
32 'sphinx_manual', config=True,
33 help="Name of the template file to use")
34 No newline at end of file
@@ -0,0 +1,6 b''
1 from .ansi import *
2 from .datatypefilter import *
3 from .highlight import *
4 from .latex import *
5 from .markdown import *
6 from .strings import * No newline at end of file
@@ -0,0 +1,145 b''
1 """Filters for processing ANSI colors within Jinja templates.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 import re
16 from IPython.utils import coloransi
17
18 #-----------------------------------------------------------------------------
19 # Classes and functions
20 #-----------------------------------------------------------------------------
21
22 __all__ = [
23 'remove_ansi',
24 'ansi2html',
25 'single_ansi2latex',
26 'ansi2latex'
27 ]
28
29 def remove_ansi(source):
30 """
31 Remove ansi from text
32
33 Parameters
34 ----------
35 source : str
36 Source to remove the ansi from
37 """
38
39 return re.sub(r'\033\[(0|\d;\d\d)m', '', source)
40
41
42 def ansi2html(text):
43 """
44 Conver ansi colors to html colors.
45
46 Parameters
47 ----------
48 text : str
49 Text containing ansi colors to convert to html
50 """
51
52 ansi_colormap = {
53 '30': 'ansiblack',
54 '31': 'ansired',
55 '32': 'ansigreen',
56 '33': 'ansiyellow',
57 '34': 'ansiblue',
58 '35': 'ansipurple',
59 '36': 'ansicyan',
60 '37': 'ansigrey',
61 '01': 'ansibold',
62 }
63
64 # do ampersand first
65 text = text.replace('&', '&')
66 html_escapes = {
67 '<': '&lt;',
68 '>': '&gt;',
69 "'": '&apos;',
70 '"': '&quot;',
71 '`': '&#96;',
72 }
73
74 for c, escape in html_escapes.iteritems():
75 text = text.replace(c, escape)
76
77 ansi_re = re.compile('\x1b' + r'\[([\dA-Fa-f;]*?)m')
78 m = ansi_re.search(text)
79 opened = False
80 cmds = []
81 opener = ''
82 closer = ''
83 while m:
84 cmds = m.groups()[0].split(';')
85 closer = '</span>' if opened else ''
86
87 # True if there is there more than one element in cmds, *or*
88 # if there is only one but it is not equal to a string of zeroes.
89 opened = len(cmds) > 1 or cmds[0] != '0' * len(cmds[0])
90 classes = []
91 for cmd in cmds:
92 if cmd in ansi_colormap:
93 classes.append(ansi_colormap.get(cmd))
94
95 if classes:
96 opener = '<span class="%s">' % (' '.join(classes))
97 else:
98 opener = ''
99 text = re.sub(ansi_re, closer + opener, text, 1)
100
101 m = ansi_re.search(text)
102
103 if opened:
104 text += '</span>'
105 return text
106
107
108 def single_ansi2latex(code):
109 """Converts single ansi markup to latex format
110
111 Return latex code and number of open brackets.
112 """
113 for color in coloransi.color_templates:
114 colcode = getattr(coloransi.TermColors,color[0])
115 # regular fonts
116 if code == colcode:
117 return '\\'+color[0].lower()+'{', 1
118 # bold fonts
119 if code == colcode[:3]+str(1)+colcode[3:]:
120 return '\\textbf{\\textcolor{'+color[0].lower()+'}{', 2
121 return '', 0
122
123 def ansi2latex(text):
124 """Converts ansi formated text to latex version
125
126 based on https://bitbucket.org/birkenfeld/sphinx-contrib/ansi.py
127 """
128 color_pattern = re.compile('\x1b\\[([^m]+)m')
129 last_end = 0
130 openbrack = 0
131 outstring = ''
132 for match in color_pattern.finditer(text):
133 head = text[last_end:match.start()]
134 outstring += head
135 if openbrack:
136 outstring += '}'*openbrack
137 openbrack = 0
138 if match.group() <> coloransi.TermColors.Normal and not openbrack:
139 texform, openbrack = single_ansi2latex(match.group())
140 outstring += texform
141 last_end = match.end()
142 if openbrack:
143 outstring += '}'*openbrack
144 outstring += text[last_end:]
145 return outstring.strip()
@@ -0,0 +1,33 b''
1 """Filter used to select the first preferred output format available.
2
3 The filter contained in the file allows the converter templates to select
4 the output format that is most valuable to the active export format. The
5 value of the different formats is set via
6 GlobalConfigurable.display_data_priority
7 """
8 #-----------------------------------------------------------------------------
9 # Copyright (c) 2013, the IPython Development Team.
10 #
11 # Distributed under the terms of the Modified BSD License.
12 #
13 # The full license is in the file COPYING.txt, distributed with this software.
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Classes and functions
18 #-----------------------------------------------------------------------------
19
20 from ..utils.config import GlobalConfigurable
21
22 __all__ = ['DataTypeFilter']
23
24 class DataTypeFilter(GlobalConfigurable):
25 """ Returns the preferred display format """
26
27 def __call__(self, output):
28 """ Return the first available format in the priority """
29
30 for fmt in self.display_data_priority:
31 if fmt in output:
32 return [fmt]
33 return []
@@ -0,0 +1,88 b''
1 """
2 Module containing filter functions that allow code to be highlighted
3 from within Jinja templates.
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 pygments import highlight as pygements_highlight
18 from pygments.lexers import get_lexer_by_name
19 from pygments.formatters import HtmlFormatter
20 from pygments.formatters import LatexFormatter
21
22 # Our own imports
23 from IPython.nbconvert.utils.lexers import IPythonLexer
24
25 #-----------------------------------------------------------------------------
26 # Globals and constants
27 #-----------------------------------------------------------------------------
28
29 MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json']
30
31 #-----------------------------------------------------------------------------
32 # Utility functions
33 #-----------------------------------------------------------------------------
34
35 __all__ = [
36 'highlight',
37 'highlight2latex'
38 ]
39
40
41 def highlight(source, language='ipython'):
42 """
43 Return a syntax-highlighted version of the input source as html output.
44
45 Parameters
46 ----------
47 source : str
48 Source code to highlight the syntax of.
49 language : str
50 Language to highlight the syntax of.
51 """
52
53 return _pygment_highlight(source, HtmlFormatter(), language)
54
55
56 def highlight2latex(source, language='ipython'):
57 """
58 Return a syntax-highlighted version of the input source as latex output.
59
60 Parameters
61 ----------
62 source : str
63 Source code to highlight the syntax of.
64 language : str
65 Language to highlight the syntax of.
66 """
67 return _pygment_highlight(source, LatexFormatter(), language)
68
69
70 def _pygment_highlight(source, output_formatter, language='ipython'):
71 """
72 Return a syntax-highlighted version of the input source
73
74 Parameters
75 ----------
76 source : str
77 Source code to highlight the syntax of.
78 output_formatter : Pygments formatter
79 language : str
80 Language to highlight the syntax of.
81 """
82
83 if language == 'ipython':
84 lexer = IPythonLexer()
85 else:
86 lexer = get_lexer_by_name(language, stripall=True)
87
88 return pygements_highlight(source, lexer, output_formatter)
@@ -0,0 +1,115 b''
1 """Latex filters.
2
3 Module of useful filters for processing Latex within Jinja latex templates.
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 import re
17
18 #-----------------------------------------------------------------------------
19 # Globals and constants
20 #-----------------------------------------------------------------------------
21
22 #Latex substitutions for escaping latex.
23 LATEX_SUBS = (
24 (re.compile('\033\[[0-9;]+m'),''), # handle console escapes
25 (re.compile(r'\\'), r'\\textbackslash'),
26 (re.compile(r'([{}_#%&$])'), r'\\\1'),
27 (re.compile(r'~'), r'\~{}'),
28 (re.compile(r'\^'), r'\^{}'),
29 (re.compile(r'"'), r"''"),
30 (re.compile(r'\.\.\.+'), r'\\ldots'),
31 )
32
33 #-----------------------------------------------------------------------------
34 # Functions
35 #-----------------------------------------------------------------------------
36
37 __all__ = [
38 'escape_latex',
39 'rm_math_space'
40 ]
41
42
43 def escape_latex(text):
44 """
45 Escape characters that may conflict with latex.
46
47 Parameters
48 ----------
49 text : str
50 Text containing characters that may conflict with Latex
51 """
52 return_text = text
53 for pattern, replacement in LATEX_SUBS:
54 return_text = pattern.sub(replacement, return_text)
55 return return_text
56
57
58 def rm_math_space(text):
59 """
60 Remove the space between latex math commands and enclosing $ symbols.
61 This filter is important because latex isn't as flexible as the notebook
62 front end when it comes to flagging math using ampersand symbols.
63
64 Parameters
65 ----------
66 text : str
67 Text to filter.
68 """
69
70 # First, scan through the markdown looking for $. If
71 # a $ symbol is found, without a preceding \, assume
72 # it is the start of a math block. UNLESS that $ is
73 # not followed by another within two math_lines.
74 math_regions = []
75 math_lines = 0
76 within_math = False
77 math_start_index = 0
78 ptext = ''
79 last_character = ""
80 skip = False
81 for index, char in enumerate(text):
82
83 #Make sure the character isn't preceeded by a backslash
84 if (char == "$" and last_character != "\\"):
85
86 # Close the math region if this is an ending $
87 if within_math:
88 within_math = False
89 skip = True
90 ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$'
91 math_regions.append([math_start_index, index+1])
92 else:
93
94 # Start a new math region
95 within_math = True
96 math_start_index = index
97 math_lines = 0
98
99 # If we are in a math region, count the number of lines parsed.
100 # Cancel the math region if we find two line breaks!
101 elif char == "\n":
102 if within_math:
103 math_lines += 1
104 if math_lines > 1:
105 within_math = False
106 ptext = ptext+text[math_start_index:index]
107
108 # Remember the last character so we can easily watch
109 # for backslashes
110 last_character = char
111 if not within_math and not skip:
112 ptext = ptext+char
113 if skip:
114 skip = False
115 return ptext
@@ -0,0 +1,85 b''
1 """Markdown filters
2 This file contains a collection of utility filters for dealing with
3 markdown within Jinja templates.
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 from __future__ import print_function
17
18 # Stdlib imports
19 import sys
20 import subprocess
21
22 #-----------------------------------------------------------------------------
23 # Functions
24 #-----------------------------------------------------------------------------
25
26 __all__ = [
27 'markdown2latex',
28 'markdown2rst'
29 ]
30
31
32 def markdown2latex(source):
33 """Convert a markdown string to LaTeX via pandoc.
34
35 This function will raise an error if pandoc is not installed.
36 Any error messages generated by pandoc are printed to stderr.
37
38 Parameters
39 ----------
40 source : string
41 Input string, assumed to be valid markdown.
42
43 Returns
44 -------
45 out : string
46 Output as returned by pandoc.
47 """
48 p = subprocess.Popen('pandoc -f markdown -t latex'.split(),
49 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
50
51 out, err = p.communicate(source.encode('utf-8'))
52
53 if err:
54 print(err, file=sys.stderr)
55 #print('*'*20+'\n', out, '\n'+'*'*20) # dbg
56
57 return unicode(out, 'utf-8')[:-1]
58
59
60 def markdown2rst(source):
61 """Convert a markdown string to LaTeX via pandoc.
62
63 This function will raise an error if pandoc is not installed.
64 Any error messages generated by pandoc are printed to stderr.
65
66 Parameters
67 ----------
68 source : string
69 Input string, assumed to be valid markdown.
70
71 Returns
72 -------
73 out : string
74 Output as returned by pandoc.
75 """
76 p = subprocess.Popen('pandoc -f markdown -t rst'.split(),
77 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
78
79 out, err = p.communicate(source.encode('utf-8'))
80
81 if err:
82 print(err, file=sys.stderr)
83 #print('*'*20+'\n', out, '\n'+'*'*20) # dbg
84
85 return unicode(out, 'utf-8')
@@ -0,0 +1,113 b''
1 """String filters.
2
3 Contains a collection of useful string manipulation filters for use in Jinja
4 templates.
5 """
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2013, the IPython Development Team.
8 #
9 # Distributed under the terms of the Modified BSD License.
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
13
14 #-----------------------------------------------------------------------------
15 # Imports
16 #-----------------------------------------------------------------------------
17
18 # Our own imports
19 import textwrap
20
21 #-----------------------------------------------------------------------------
22 # Functions
23 #-----------------------------------------------------------------------------
24
25 __all__ = [
26 'wrap',
27 'strip_dollars',
28 'rm_fake',
29 'python_comment',
30 'get_lines'
31 ]
32
33
34 def wrap(text, width=100):
35 """
36 Intelligently wrap text.
37 Wrap text without breaking words if possible.
38
39 Parameters
40 ----------
41 text : str
42 Text to wrap.
43 width : int, optional
44 Number of characters to wrap to, default 100.
45 """
46
47 split_text = text.split('\n')
48 wrp = map(lambda x:textwrap.wrap(x,width), split_text)
49 wrpd = map('\n'.join, wrp)
50 return '\n'.join(wrpd)
51
52
53 def strip_dollars(text):
54 """
55 Remove all dollar symbols from text
56
57 Parameters
58 ----------
59 text : str
60 Text to remove dollars from
61 """
62
63 return text.strip('$')
64
65
66 def rm_fake(text):
67 """
68 Remove all occurrences of '/files/' from text
69
70 Parameters
71 ----------
72 text : str
73 Text to remove '/files/' from
74 """
75 return text.replace('/files/', '')
76
77
78 def python_comment(text):
79 """
80 Build a Python comment line from input text.
81
82 Parameters
83 ----------
84 text : str
85 Text to comment out.
86 """
87
88 #Replace line breaks with line breaks and comment symbols.
89 #Also add a comment symbol at the beginning to comment out
90 #the first line.
91 return '# '+'\n# '.join(text.split('\n'))
92
93
94 def get_lines(text, start=None,end=None):
95 """
96 Split the input text into separate lines and then return the
97 lines that the caller is interested in.
98
99 Parameters
100 ----------
101 text : str
102 Text to parse lines from.
103 start : int, optional
104 First line to grab from.
105 end : int, optional
106 Last line to grab from.
107 """
108
109 # Split the input into lines.
110 lines = text.split("\n")
111
112 # Return the right lines.
113 return "\n".join(lines[start:end]) #re-join
@@ -0,0 +1,212 b''
1 #!/usr/bin/env python
2 """NBConvert is a utility for conversion of IPYNB files.
3
4 Commandline interface for the NBConvert conversion utility. Read the
5 readme.rst for usage information
6 """
7 #-----------------------------------------------------------------------------
8 #Copyright (c) 2013, the IPython Development Team.
9 #
10 #Distributed under the terms of the Modified BSD License.
11 #
12 #The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 #Imports
17 #-----------------------------------------------------------------------------
18
19 #Stdlib imports
20 from __future__ import print_function
21 import sys
22 import io
23 import os
24
25 #From IPython
26 from IPython.config.application import Application
27 from IPython.utils.traitlets import Bool
28
29 from .exporters.export import export_by_name
30 from .exporters.exporter import Exporter
31 from .transformers import extractfigure
32 from .utils.config import GlobalConfigurable
33
34 #-----------------------------------------------------------------------------
35 #Globals and constants
36 #-----------------------------------------------------------------------------
37
38 #'Keys in resources' user prompt.
39 KEYS_PROMPT_HEAD = "====================== Keys in Resources =================================="
40 KEYS_PROMPT_BODY = """
41 ===========================================================================
42 You are responsible for writting these files into the appropriate
43 directorie(s) if need be. If you do not want to see this message, enable
44 the 'write' (boolean) flag of the converter.
45 ===========================================================================
46 """
47
48 #-----------------------------------------------------------------------------
49 #Classes and functions
50 #-----------------------------------------------------------------------------
51
52 class NbConvertApp(Application):
53 """Application used to convert to and from notebook file type (*.ipynb)"""
54
55 stdout = Bool(
56 False, config=True,
57 help="""Whether to print the converted IPYNB file to stdout
58 use full do diff files without actually writing a new file"""
59 )
60
61 write = Bool(
62 True, config=True,
63 help="""Should the converted notebook file be written to disk
64 along with potential extracted resources."""
65 )
66
67 aliases = {
68 'stdout':'NbConvertApp.stdout',
69 'write':'NbConvertApp.write',
70 }
71
72 flags = {}
73
74 flags['stdout'] = (
75 {'NbConvertApp' : {'stdout' : True}},
76 """Print converted file to stdout, equivalent to --stdout=True
77 """
78 )
79
80 flags['no-write'] = (
81 {'NbConvertApp' : {'write' : True}},
82 """Do not write to disk, equivalent to --write=False
83 """
84 )
85
86
87 def __init__(self, **kwargs):
88 """Public constructor"""
89
90 #Call base class
91 super(NbConvertApp, self).__init__(**kwargs)
92
93 #Register class here to have help with help all
94 self.classes.insert(0, Exporter)
95 self.classes.insert(0, GlobalConfigurable)
96
97
98 def start(self, argv=None):
99 """Entrypoint of NbConvert application.
100
101 Parameters
102 ----------
103 argv : list
104 Commandline arguments
105 """
106
107 #Parse the commandline options.
108 self.parse_command_line(argv)
109
110 #Call base
111 super(NbConvertApp, self).start()
112
113 #The last arguments in list will be used by nbconvert
114 if len(self.extra_args) is not 3:
115 print( "Wrong number of arguments, use --help flag for usage", file=sys.stderr)
116 sys.exit(-1)
117 export_type = (self.extra_args)[1]
118 ipynb_file = (self.extra_args)[2]
119
120 #Export
121 return_value = export_by_name(export_type, ipynb_file)
122 if return_value is None:
123 print("Error: '%s' template not found." % export_type)
124 return
125 else:
126 (output, resources, exporter) = return_value
127
128 #TODO: Allow user to set output directory and file.
129 destination_filename = None
130 destination_directory = None
131 if self.write:
132
133 #Get the file name without the '.ipynb' (6 chars) extension and then
134 #remove any addition periods and spaces. The resulting name will
135 #be used to create the directory that the files will be exported
136 #into.
137 out_root = ipynb_file[:-6].replace('.', '_').replace(' ', '_')
138 destination_filename = os.path.join(out_root+'.'+exporter.file_extension)
139
140 destination_directory = out_root+'_files'
141 if not os.path.exists(destination_directory):
142 os.mkdir(destination_directory)
143
144 #Write the results
145 if self.stdout or not (destination_filename is None and destination_directory is None):
146 self._write_results(output, resources, destination_filename, destination_directory)
147
148
149 def _write_results(self, output, resources, destination_filename=None, destination_directory=None):
150 """Output the conversion results to the console and/or filesystem
151
152 Parameters
153 ----------
154 output : str
155 Output of conversion
156 resources : dictionary
157 Additional input/output used by the transformers. For
158 example, the ExtractFigure transformer outputs the
159 figures it extracts into this dictionary. This method
160 relies on the figures being in this dictionary when
161 attempting to write the figures to the file system.
162 destination_filename : str, Optional
163 Filename to write output into. If None, output is not
164 written to a file.
165 destination_directory : str, Optional
166 Directory to write notebook data (i.e. figures) to. If
167 None, figures are not written to the file system.
168 """
169
170 if self.stdout:
171 print(output.encode('utf-8'))
172
173 #Write file output from conversion.
174 if not destination_filename is None:
175 with io.open(destination_filename, 'w') as f:
176 f.write(output)
177
178 #Get the key names used by the extract figure transformer
179 figures_key = extractfigure.FIGURES_KEY
180 binary_key = extractfigure.BINARY_KEY
181 text_key = extractfigure.TEXT_KEY
182
183 #Output any associate figures into the same "root" directory.
184 binkeys = resources.get(figures_key, {}).get(binary_key,{}).keys()
185 textkeys = resources.get(figures_key, {}).get(text_key,{}).keys()
186 if binkeys or textkeys :
187 if not destination_directory is None:
188 for key in binkeys:
189 with io.open(os.path.join(destination_directory, key), 'wb') as f:
190 f.write(resources[figures_key][binary_key][key])
191 for key in textkeys:
192 with io.open(os.path.join(destination_directory, key), 'w') as f:
193 f.write(resources[figures_key][text_key][key])
194
195 #Figures that weren't exported which will need to be created by the
196 #user. Tell the user what figures these are.
197 if self.stdout:
198 print(KEYS_PROMPT_HEAD, file=sys.stderr)
199 print(resources[figures_key].keys(), file=sys.stderr)
200 print(KEYS_PROMPT_BODY , file=sys.stderr)
201
202 #-----------------------------------------------------------------------------
203 # Main entry point
204 #-----------------------------------------------------------------------------
205
206 def launch_new_instance():
207 """Application entry point"""
208
209 app = NbConvertApp.instance()
210 app.description = __doc__
211 app.start(argv=sys.argv)
212
@@ -0,0 +1,17 b''
1 {%- extends 'reveal_cells.tpl' -%}
2
3
4
5 {%- block any_cell scoped -%}
6 {%- if cell.metadata.align_type in ['Left'] -%}
7 {{ super() }}
8 {%- elif cell.metadata.align_type in ['center'] -%}
9 <div style="text-align:center">
10 {{ super() }}
11 </div>
12 {%- elif cell.metadata.align_type in ['right'] -%}
13 <div style="text-align:right">
14 {{ super() }}
15 </div>
16 {%- endif -%}
17 {%- endblock any_cell -%}
@@ -0,0 +1,143 b''
1 {%- extends 'display_priority.tpl' -%}
2
3
4
5 {% block codecell %}
6 <div class="cell border-box-sizing code_cell vbox">
7 {{ super() }}</div>
8 {%- endblock codecell %}
9
10 {% block input_group -%}
11 <div class="input hbox">
12 {{super()}}
13 </div>
14 {% endblock input_group %}
15
16 {% block output_group %}
17 <div class="vbox output_wrapper">
18 <div class="output vbox">
19 {{ super() }}
20 </div>
21 </div>
22 {% endblock output_group %}
23
24 {% block in_prompt -%}
25 <div class="prompt input_prompt">In&nbsp;[{{cell.prompt_number}}]:</div>
26 {%- endblock in_prompt %}
27
28 {#
29 output_prompt doesn't do anything in HTML,
30 because there is a prompt div in each output area (see output block)
31 #}
32 {% block output_prompt %}
33 {% endblock output_prompt %}
34
35 {% block input %}
36 <div class="input_area box-flex1">
37 {{cell.input | highlight }}
38 </div>
39 {%- endblock input %}
40
41 {% block output %}
42 <div class="hbox output_area">
43 {%- if output.output_type == 'pyout' -%}
44 <div class="prompt output_prompt">
45 Out[{{cell.prompt_number}}]:
46 {%- else -%}
47 <div class="prompt">
48 {%- endif -%}
49 </div>
50 {{ super() }}
51 </div>
52 {% endblock output %}
53
54 {% block markdowncell scoped %}
55 <div class="text_cell_render border-box-sizing rendered_html">
56 {{ cell.source | markdown| rm_fake}}
57 </div>
58 {%- endblock markdowncell %}
59
60 {% block headingcell scoped %}
61 <div class="text_cell_render border-box-sizing rendered_html">
62 <h{{cell.level}}>
63 {% set source = cell.source | replace(' ','_') %}
64 <a class="heading-anchor" id="{{source}}" href="#{{source}}">
65 {{cell.source}}
66 </a>
67 </h{{cell.level}}>
68 </div>
69 {% endblock headingcell %}
70
71 {% block rawcell scoped %}
72 {{ cell.source }}
73 {% endblock rawcell %}
74
75 {% block unknowncell scoped %}
76 unknown type {{cell.type}}
77 {% endblock unknowncell %}
78
79
80 {% block pyout -%}
81 <div class="box-flex1 output_subarea output_pyout">
82 {% block data_priority scoped %}{{ super()}}{% endblock %}
83 </div>
84 {%- endblock pyout %}
85
86 {% block stream_stdout -%}
87 <div class="box-flex1 output_subarea output_stream output_stdout">
88 <pre>{{output.text |ansi2html}}</pre>
89 </div>
90 {%- endblock stream_stdout %}
91
92 {% block stream_stderr -%}
93 <div class="box-flex1 output_subarea output_stream output_stderr">
94 <pre>{{output.text |ansi2html}}</pre>
95 </div>
96 {%- endblock stream_stderr %}
97
98 {% block data_svg -%}
99 {{output.svg}}
100 {%- endblock data_svg %}
101
102
103 {% block data_html -%}
104 <div class="output_html rendered_html">
105 {{output.html}}
106 </div>
107 {%- endblock data_html %}
108
109 {% block data_png %}
110 <img src="data:image/png;base64,{{output.png}}">
111 {%- endblock data_png %}
112
113
114 {% block data_jpg %}
115 <img src="data:image/jpeg;base64,{{output.jpeg}}">
116 {%- endblock data_jpg %}
117
118
119 {% block data_latex %}
120 {{output.latex}}
121 {%- endblock data_latex %}
122
123 {% block pyerr -%}
124 <div class="box-flex1 output_subarea output_pyerr">
125 <pre>{{super()}}</pre>
126 </div>
127 {%- endblock pyerr %}
128
129 {%- block traceback_line %}
130 {{line| ansi2html}}
131 {%- endblock traceback_line %}
132
133
134 {%- block data_text %}
135 <pre>{{output.text | ansi2html}}</pre>
136 {%- endblock -%}
137
138
139 {%- block display_data scoped -%}
140 <div class="box-flex1 output_subarea output_display_data">
141 {{super()}}
142 </div>
143 {%- endblock display_data -%}
@@ -0,0 +1,64 b''
1 {%- extends 'basichtml.tpl' -%}
2
3 {%- block header -%}<!DOCTYPE html>
4 <html>
5 <head>
6 <meta charset="UTF-8">
7 <title>[{{nb.metadata.name}}]</title>
8 {% for css in resources.inlining.css -%}
9 <style type="text/css">
10 {{css}}
11 </style>
12 {% endfor %}
13
14 <style type="text/css">
15 /* Overrides of notebook CSS for static HTML export */
16 body {
17 overflow: visible;
18 padding: 8px;
19 }
20 .input_area {
21 padding: 0.2em;
22 }
23
24 pre {
25 border: none;
26 margin: 0px;
27 font-size: 13px;
28 }
29 </style>
30
31 <script src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" type="text/javascript">
32
33 </script>
34 <script type="text/javascript">
35 init_mathjax = function() {
36 if (window.MathJax) {
37 // MathJax loaded
38 MathJax.Hub.Config({
39 tex2jax: {
40 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
41 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
42 },
43 displayAlign: 'left', // Change this to 'center' to center equations.
44 "HTML-CSS": {
45 styles: {'.MathJax_Display': {"margin": 0}}
46 }
47 });
48 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
49 }
50 }
51 init_mathjax();
52 </script>
53 </head>
54 {%- endblock header -%}
55
56
57 {% block body %}
58 <body>{{ super() }}
59 </body>
60 {%- endblock body %}
61
62
63 {% block footer %}
64 </html>{% endblock footer %}
@@ -0,0 +1,263 b''
1 ((*- extends 'display_priority.tplx' -*))
2
3 ((* block in_prompt *))((* endblock in_prompt *))
4
5 ((* block output_prompt *))((* endblock output_prompt *))
6
7 ((* block codecell *))\begin{codecell}((( super() )))
8 \end{codecell}
9 ((* endblock *))
10
11 ((* block input *))
12 \begin{codeinput}
13 \begin{lstlisting}
14 ((( cell.input )))
15 \end{lstlisting}
16 \end{codeinput}
17 ((* endblock input *))
18
19
20 ((= Those Two are for error displaying
21 even if the first one seem to do nothing,
22 it introduces a new line
23
24 =))
25 ((* block pyerr *))
26 \begin{traceback}
27 \begin{verbatim}((( super() )))
28 \end{verbatim}
29 \end{traceback}
30 ((* endblock pyerr *))
31
32 ((* block traceback_line *))
33 ((( line |indent| rm_ansi )))((* endblock traceback_line *))
34 ((= .... =))
35
36
37 ((*- block output_group -*))
38 \begin{codeoutput}
39 ((( super() )))
40 \end{codeoutput}((* endblock *))
41
42 ((*- block data_png -*))
43 \begin{center}
44 \includegraphics[width=0.7\textwidth, height=0.9\textheight, keepaspectratio]{(((output.key_png)))}
45 \par
46 \end{center}
47 ((*- endblock -*))
48
49 ((*- block data_jpg -*))
50 \begin{center}
51 \includegraphics[width=0.7\textwidth, height=0.9\textheight, keepaspectratio]{(((output.key_jpeg)))}
52 \par
53 \end{center}
54 ((*- endblock -*))
55
56 ((*- block data_svg -*))
57 \begin{center}
58 \includegraphics[width=0.7\textwidth]{(((output.key_svg)))}
59 \par
60 \end{center}
61 ((*- endblock -*))
62
63 ((* block pyout *))
64 ((* block data_priority scoped *))((( super() )))((* endblock *))
65 ((* endblock pyout *))
66
67 ((* block data_text *))
68 \begin{verbatim}
69 ((( output.text )))
70 \end{verbatim}
71 ((* endblock *))
72
73 ((* block data_latex -*))
74 ((*- if output.latex.startswith('$'): -*)) \begin{equation*}
75 ((( output.latex | rm_dollars)))
76 \end{equation*}
77 ((*- else -*)) ((( output.latex ))) ((*- endif *))
78 ((* endblock *))
79
80 ((* block stream *))
81 \begin{Verbatim}[commandchars=\\\{\}]
82 ((( output.text | ansi2latex)))
83 \end{Verbatim}
84 ((* endblock stream *))
85
86 ((* block markdowncell scoped *))((( cell.source | markdown2latex )))
87 ((* endblock markdowncell *))
88
89 ((* block headingcell scoped -*))
90 \
91 ((*- if cell.level == 1 -*))
92 ((* block h1 -*))section((* endblock h1 -*))
93 ((*- elif cell.level == 2 -*))
94 ((* block h2 -*))subsection((* endblock h2 -*))
95 ((*- elif cell.level == 3 -*))
96 ((* block h3 -*))subsubsection((* endblock h3 -*))
97 ((*- elif cell.level == 4 -*))
98 ((* block h4 -*))paragraph((* endblock h4 -*))
99 ((*- elif cell.level == 5 -*))
100 ((* block h5 -*))subparagraph((* endblock h5 -*))
101 ((*- elif cell.level == 6 -*))
102 ((* block h6 -*))subparagraph((* endblock h6 -*))
103 ((= 6th level not available in standard latex =))
104
105 ((*- endif -*)){((( cell.source | markdown2latex )))}
106 ((* endblock headingcell *))
107
108 ((* block rawcell scoped *))
109 ((( cell.source | pycomment )))
110 ((* endblock rawcell *))
111
112 ((* block unknowncell scoped *))
113 unknown type (((cell.type)))
114 ((* endblock unknowncell *))
115
116
117
118 ((* block body *))
119
120 ((* block bodyBegin *))
121 \begin{document}
122 ((* endblock bodyBegin *))
123
124 ((( super() )))
125
126 ((* block bodyEnd *))
127 \end{document}
128 ((* endblock bodyEnd *))
129 ((* endblock body *))
130
131 ((* block header *))
132 %% This file was auto-generated by IPython.
133 %% Conversion from the original notebook file:
134 %%
135 \documentclass[11pt,english]{article}
136
137 %% This is the automatic preamble used by IPython. Note that it does *not*
138 %% include a documentclass declaration, that is added at runtime to the overall
139 %% document.
140
141 \usepackage{amsmath}
142 \usepackage{amssymb}
143 \usepackage{graphicx}
144 \usepackage{ucs}
145 \usepackage[utf8x]{inputenc}
146
147 %fancy verbatim
148 \usepackage{fancyvrb}
149 % needed for markdown enumerations to work
150 \usepackage{enumerate}
151
152 % Slightly bigger margins than the latex defaults
153 \usepackage{geometry}
154 \geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm}
155
156 % Define a few colors for use in code, links and cell shading
157 \usepackage{color}
158 \definecolor{orange}{cmyk}{0,0.4,0.8,0.2}
159 \definecolor{darkorange}{rgb}{.71,0.21,0.01}
160 \definecolor{darkgreen}{rgb}{.12,.54,.11}
161 \definecolor{myteal}{rgb}{.26, .44, .56}
162 \definecolor{gray}{gray}{0.45}
163 \definecolor{lightgray}{gray}{.95}
164 \definecolor{mediumgray}{gray}{.8}
165 \definecolor{inputbackground}{rgb}{.95, .95, .85}
166 \definecolor{outputbackground}{rgb}{.95, .95, .95}
167 \definecolor{traceback}{rgb}{1, .95, .95}
168
169 % new ansi colors
170 \definecolor{brown}{rgb}{0.54,0.27,0.07}
171 \definecolor{purple}{rgb}{0.5,0.0,0.5}
172 \definecolor{darkgray}{gray}{0.25}
173 \definecolor{lightred}{rgb}{1.0,0.39,0.28}
174 \definecolor{lightgreen}{rgb}{0.48,0.99,0.0}
175 \definecolor{lightblue}{rgb}{0.53,0.81,0.92}
176 \definecolor{lightpurple}{rgb}{0.87,0.63,0.87}
177 \definecolor{lightcyan}{rgb}{0.5,1.0,0.83}
178
179 % Framed environments for code cells (inputs, outputs, errors, ...). The
180 % various uses of \unskip (or not) at the end were fine-tuned by hand, so don't
181 % randomly change them unless you're sure of the effect it will have.
182 \usepackage{framed}
183
184 % remove extraneous vertical space in boxes
185 \setlength\fboxsep{0pt}
186
187 % codecell is the whole input+output set of blocks that a Code cell can
188 % generate.
189
190 % TODO: unfortunately, it seems that using a framed codecell environment breaks
191 % the ability of the frames inside of it to be broken across pages. This
192 % causes at least the problem of having lots of empty space at the bottom of
193 % pages as new frames are moved to the next page, and if a single frame is too
194 % long to fit on a page, will completely stop latex from compiling the
195 % document. So unless we figure out a solution to this, we'll have to instead
196 % leave the codecell env. as empty. I'm keeping the original codecell
197 % definition here (a thin vertical bar) for reference, in case we find a
198 % solution to the page break issue.
199
200 %% \newenvironment{codecell}{%
201 %% \def\FrameCommand{\color{mediumgray} \vrule width 1pt \hspace{5pt}}%
202 %% \MakeFramed{\vspace{-0.5em}}}
203 %% {\unskip\endMakeFramed}
204
205 % For now, make this a no-op...
206 \newenvironment{codecell}{}
207
208 \newenvironment{codeinput}{%
209 \def\FrameCommand{\colorbox{inputbackground}}%
210 \MakeFramed{\advance\hsize-\width \FrameRestore}}
211 {\unskip\endMakeFramed}
212
213 \newenvironment{codeoutput}{%
214 \def\FrameCommand{\colorbox{outputbackground}}%
215 \vspace{-1.4em}
216 \MakeFramed{\advance\hsize-\width \FrameRestore}}
217 {\unskip\medskip\endMakeFramed}
218
219 \newenvironment{traceback}{%
220 \def\FrameCommand{\colorbox{traceback}}%
221 \MakeFramed{\advance\hsize-\width \FrameRestore}}
222 {\endMakeFramed}
223
224 % Use and configure listings package for nicely formatted code
225 \usepackage{listingsutf8}
226 \lstset{
227 language=python,
228 inputencoding=utf8x,
229 extendedchars=\true,
230 aboveskip=\smallskipamount,
231 belowskip=\smallskipamount,
232 xleftmargin=2mm,
233 breaklines=true,
234 basicstyle=\small \ttfamily,
235 showstringspaces=false,
236 keywordstyle=\color{blue}\bfseries,
237 commentstyle=\color{myteal},
238 stringstyle=\color{darkgreen},
239 identifierstyle=\color{darkorange},
240 columns=fullflexible, % tighter character kerning, like verb
241 }
242
243 % The hyperref package gives us a pdf with properly built
244 % internal navigation ('pdf bookmarks' for the table of contents,
245 % internal cross-reference links, web links for URLs, etc.)
246 \usepackage{hyperref}
247 \hypersetup{
248 breaklinks=true, % so long urls are correctly broken across lines
249 colorlinks=true,
250 urlcolor=blue,
251 linkcolor=darkorange,
252 citecolor=darkgreen,
253 }
254
255 % hardcode size of all verbatim environments to be a bit smaller
256 \makeatletter
257 \g@addto@macro\@verbatim\small\topsep=0.5em\partopsep=0pt
258 \makeatother
259
260 % Prevent overflowing lines due to urls and other hard-to-break entities.
261 \sloppy
262
263 ((* endblock *))
@@ -0,0 +1,39 b''
1 ((= autogenerated file do not edit =))
2 ((*- extends 'null.tplx' -*))
3
4 ((=display data priority=))
5
6
7 ((*- block data_priority scoped -*))
8 ((*- for type in output | filter_data_type -*))
9 ((*- if type in ['pdf']*))
10 ((*- block data_pdf -*))
11 ((*- endblock -*))
12 ((*- endif -*))
13 ((*- if type in ['svg']*))
14 ((*- block data_svg -*))
15 ((*- endblock -*))
16 ((*- endif -*))
17 ((*- if type in ['png']*))
18 ((*- block data_png -*))
19 ((*- endblock -*))
20 ((*- endif -*))
21 ((*- if type in ['html']*))
22 ((*- block data_html -*))
23 ((*- endblock -*))
24 ((*- endif -*))
25 ((*- if type in ['jpeg']*))
26 ((*- block data_jpg -*))
27 ((*- endblock -*))
28 ((*- endif -*))
29 ((*- if type in ['text']*))
30 ((*- block data_text -*))
31 ((*- endblock -*))
32 ((*- endif -*))
33
34 ((*- if type in ['latex']*))
35 ((*- block data_latex -*))
36 ((*- endblock -*))
37 ((*- endif -*))
38 ((*- endfor -*))
39 ((*- endblock data_priority -*))
@@ -0,0 +1,92 b''
1 ((= autogenerated file do not edit =))
2 ((=
3
4 DO NOT USE THIS AS A BASE WORK,
5 IF YOU ARE COPY AND PASTING THIS FILE
6 YOU ARE PROBABLY DOING THINGS WRONG.
7
8 Null template, Does nothing except defining a basic structure
9 To layout the different blocks of a notebook.
10
11 Subtemplates can override blocks to define their custom representation.
12
13 If one of the block you do overwrite is not a leave block, consider
14 calling super.
15
16 ((*- block nonLeaveBlock -*))
17 #add stuff at beginning
18 ((( super() )))
19 #add stuff at end
20 ((*- endblock nonLeaveBlock -*))
21
22 consider calling super even if it is a leave block, we might insert more blocks later.
23
24 =))
25 ((*- block header -*))
26 ((*- endblock header -*))
27 ((*- block body -*))
28 ((*- for worksheet in nb.worksheets -*))
29 ((*- for cell in worksheet.cells -*))
30 ((*- block any_cell scoped -*))
31 ((*- if cell.cell_type in ['code'] -*))
32 ((*- block codecell scoped -*))
33 ((*- block input_group -*))
34 ((*- block in_prompt -*))((*- endblock in_prompt -*))
35 ((*- block input -*))((*- endblock input -*))
36 ((*- endblock input_group -*))
37 ((*- if cell.outputs -*))
38 ((*- block output_group -*))
39 ((*- block output_prompt -*))((*- endblock output_prompt -*))
40 ((*- block outputs scoped -*))
41 ((*- for output in cell.outputs -*))
42 ((*- block output scoped -*))
43 ((*- if output.output_type in ['pyout'] -*))
44 ((*- block pyout scoped -*))((*- endblock pyout -*))
45 ((*- elif output.output_type in ['stream'] -*))
46 ((*- block stream scoped -*))
47 ((*- if output.stream in ['stdout'] -*))
48 ((*- block stream_stdout scoped -*))
49 ((*- endblock stream_stdout -*))
50 ((*- elif output.stream in ['stderr'] -*))
51 ((*- block stream_stderr scoped -*))
52 ((*- endblock stream_stderr -*))
53 ((*- endif -*))
54 ((*- endblock stream -*))
55 ((*- elif output.output_type in ['display_data'] -*))
56 ((*- block display_data scoped -*))
57 ((*- block data_priority scoped -*))
58 ((*- endblock data_priority -*))
59 ((*- endblock display_data -*))
60 ((*- elif output.output_type in ['pyerr'] -*))
61 ((*- block pyerr scoped -*))
62 ((*- for line in output.traceback -*))
63 ((*- block traceback_line scoped -*))((*- endblock traceback_line -*))
64 ((*- endfor -*))
65 ((*- endblock pyerr -*))
66 ((*- endif -*))
67 ((*- endblock output -*))
68 ((*- endfor -*))
69 ((*- endblock outputs -*))
70 ((*- endblock output_group -*))
71 ((*- endif -*))
72 ((*- endblock codecell -*))
73 ((*- elif cell.cell_type in ['markdown'] -*))
74 ((*- block markdowncell scoped-*))
75 ((*- endblock markdowncell -*))
76 ((*- elif cell.cell_type in ['heading'] -*))
77 ((*- block headingcell scoped-*))
78 ((*- endblock headingcell -*))
79 ((*- elif cell.cell_type in ['raw'] -*))
80 ((*- block rawcell scoped-*))
81 ((*- endblock rawcell -*))
82 ((*- else -*))
83 ((*- block unknowncell scoped-*))
84 ((*- endblock unknowncell -*))
85 ((*- endif -*))
86 ((*- endblock any_cell -*))
87 ((*- endfor -*))
88 ((*- endfor -*))
89 ((*- endblock body -*))
90
91 ((*- block footer -*))
92 ((*- endblock footer -*))
@@ -0,0 +1,442 b''
1 ((= NBConvert Sphinx-Latex Template
2
3 Purpose: Allow export of PDF friendly Latex inspired by Sphinx. Most of the
4 template is derived directly from Sphinx source.
5
6 Inheritance: null>display_priority
7
8 Note: For best display, use latex syntax highlighting. =))
9
10 ((*- extends 'display_priority.tplx' -*))
11
12 %==============================================================================
13 % Declarations
14 %==============================================================================
15
16 % In order to make sure that the input/output header follows the code it
17 % preceeds, the needspace package is used to request that a certain
18 % amount of lines (specified by this variable) are reserved. If those
19 % lines aren't available on the current page, the documenter will break
20 % to the next page and the header along with accomanying lines will be
21 % rendered together. This value specifies the number of lines that
22 % the header will be forced to group with without a page break.
23 ((*- set min_header_lines = 4 -*))
24
25 % This is the number of characters that are permitted per line. It's
26 % important that this limit is set so characters do not run off the
27 % edges of latex pages (since latex does not always seem smart enough
28 % to prevent this in some cases.) This is only applied to textual output
29 ((* if resources.sphinx.outputstyle == 'simple' *))
30 ((*- set wrap_size = 85 -*))
31 ((* elif resources.sphinx.outputstyle == 'notebook' *))
32 ((*- set wrap_size = 70 -*))
33 ((* endif *))
34
35 %==============================================================================
36 % Header
37 %==============================================================================
38 ((* block header *))
39
40 % Header, overrides base
41
42 % Make sure that the sphinx doc style knows who it inherits from.
43 \def\sphinxdocclass{(((parentdocumentclass)))}
44
45 % Declare the document class
46 \documentclass[letterpaper,10pt,english]{((( resources.sphinx.texinputs )))/sphinx(((documentclass)))}
47
48 % Imports
49 \usepackage[utf8]{inputenc}
50 \DeclareUnicodeCharacter{00A0}{\\nobreakspace}
51 \usepackage[T1]{fontenc}
52 \usepackage{babel}
53 \usepackage{times}
54 \usepackage{import}
55 \usepackage[((( resources.sphinx.chapterstyle )))]{((( resources.sphinx.texinputs )))/fncychap}
56 \usepackage{longtable}
57 \usepackage{((( resources.sphinx.texinputs )))/sphinx}
58 \usepackage{multirow}
59
60 \usepackage{amsmath}
61 \usepackage{amssymb}
62 \usepackage{ucs}
63 \usepackage{enumerate}
64
65 % Used to make the Input/Output rules follow around the contents.
66 \usepackage{needspace}
67
68 % Pygments requirements
69 \usepackage{fancyvrb}
70 \usepackage{color}
71 % ansi colors additions
72 \definecolor{darkgreen}{rgb}{.12,.54,.11}
73 \definecolor{lightgray}{gray}{.95}
74 \definecolor{brown}{rgb}{0.54,0.27,0.07}
75 \definecolor{purple}{rgb}{0.5,0.0,0.5}
76 \definecolor{darkgray}{gray}{0.25}
77 \definecolor{lightred}{rgb}{1.0,0.39,0.28}
78 \definecolor{lightgreen}{rgb}{0.48,0.99,0.0}
79 \definecolor{lightblue}{rgb}{0.53,0.81,0.92}
80 \definecolor{lightpurple}{rgb}{0.87,0.63,0.87}
81 \definecolor{lightcyan}{rgb}{0.5,1.0,0.83}
82
83 % Needed to box output/input
84 \usepackage{tikz}
85 \usetikzlibrary{calc,arrows,shadows}
86 \usepackage[framemethod=tikz]{mdframed}
87
88 \usepackage{alltt}
89
90 % Used to load and display graphics
91 \usepackage{graphicx}
92 \graphicspath{ {figs/} }
93 \usepackage[Export]{adjustbox} % To resize
94
95
96 % For formatting output while also word wrapping.
97 \usepackage{listings}
98 \lstset{breaklines=true}
99 \lstset{basicstyle=\small\ttfamily}
100 \def\smaller{\fontsize{9.5pt}{9.5pt}\selectfont}
101
102 %Pygments definitions
103 ((( resources.sphinx.pygment_definitions )))
104
105 %Set pygments styles if needed...
106 ((* if resources.sphinx.outputstyle == 'notebook' *))
107 \definecolor{nbframe-border}{rgb}{0.867,0.867,0.867}
108 \definecolor{nbframe-bg}{rgb}{0.969,0.969,0.969}
109 \definecolor{nbframe-in-prompt}{rgb}{0.0,0.0,0.502}
110 \definecolor{nbframe-out-prompt}{rgb}{0.545,0.0,0.0}
111
112 \newenvironment{ColorVerbatim}
113 {\begin{mdframed}[%
114 roundcorner=1.0pt, %
115 backgroundcolor=nbframe-bg, %
116 userdefinedwidth=1\linewidth, %
117 leftmargin=0.1\linewidth, %
118 innerleftmargin=0pt, %
119 innerrightmargin=0pt, %
120 linecolor=nbframe-border, %
121 linewidth=1pt, %
122 usetwoside=false, %
123 everyline=true, %
124 innerlinewidth=3pt, %
125 innerlinecolor=nbframe-bg, %
126 middlelinewidth=1pt, %
127 middlelinecolor=nbframe-bg, %
128 outerlinewidth=0.5pt, %
129 outerlinecolor=nbframe-border, %
130 needspace=0pt
131 ]}
132 {\end{mdframed}}
133
134 \newenvironment{InvisibleVerbatim}
135 {\begin{mdframed}[leftmargin=0.1\linewidth,innerleftmargin=3pt,innerrightmargin=3pt, userdefinedwidth=1\linewidth, linewidth=0pt, linecolor=white, usetwoside=false]}
136 {\end{mdframed}}
137
138 \renewenvironment{Verbatim}[1][\unskip]
139 {\begin{alltt}\smaller}
140 {\end{alltt}}
141 ((* endif *))
142
143 % Help prevent overflowing lines due to urls and other hard-to-break
144 % entities. This doesn't catch everything...
145 \sloppy
146
147 % Document level variables
148 \title{((( nb.metadata.name | escape_tex )))}
149 \date{((( nb.metadata._draft.date | escape_tex )))}
150 \release{((( nb.metadata._draft.version | escape_tex )))}
151 \author{((( nb.metadata._draft.author | escape_tex )))}
152 \renewcommand{\releasename}{((( nb.metadata._draft.release | escape_tex )))}
153
154 % TODO: Add option for the user to specify a logo for his/her export.
155 \newcommand{\sphinxlogo}{}
156
157 % Make the index page of the document.
158 \makeindex
159
160 % Import sphinx document type specifics.
161 ((* block sphinxheader *))((* endblock sphinxheader *))
162 ((* endblock header *))
163
164 %==============================================================================
165 % Body
166 %==============================================================================
167 ((* block body *))
168 ((* block bodyBegin *))
169 % Body
170
171 % Start of the document
172 \begin{document}
173
174 ((* if resources.sphinx.header *))
175 \maketitle
176 ((* endif *))
177
178 ((* block toc *))
179 \tableofcontents
180 ((* endblock toc *))
181
182 ((* endblock bodyBegin *))((( super() )))((* block bodyEnd *))
183
184 \renewcommand{\indexname}{Index}
185 \printindex
186
187 % End of document
188 \end{document}
189 ((* endblock bodyEnd *))
190 ((* endblock body *))
191
192 %==============================================================================
193 % Footer
194 %==============================================================================
195 ((* block footer *))
196 ((* endblock footer *))
197
198 %==============================================================================
199 % Headings
200 %
201 % Purpose: Format pynb headers as sphinx headers. Depending on the Sphinx
202 % style that is active, this will change. Thus sphinx styles will
203 % override the values here.
204 %==============================================================================
205 ((* block headingcell -*))
206 \
207 ((*- if cell.level == 1 -*))
208 ((* block h1 -*))part((* endblock h1 -*))
209 ((*- elif cell.level == 2 -*))
210 ((* block h2 -*))chapter((* endblock h2 -*))
211 ((*- elif cell.level == 3 -*))
212 ((* block h3 -*))section((* endblock h3 -*))
213 ((*- elif cell.level == 4 -*))
214 ((* block h4 -*))subsection((* endblock h4 -*))
215 ((*- elif cell.level == 5 -*))
216 ((* block h5 -*))subsubsection((* endblock h5 -*))
217 ((*- elif cell.level == 6 -*))
218 ((* block h6 -*))paragraph((* endblock h6 -*))
219
220 ((= It's important to make sure that underscores (which tend to be common
221 in IPYNB file titles) do not make their way into latex. Sometimes this
222 causes latex to barf. =))
223 ((*- endif -*)){((( cell.source | markdown2latex )))}
224 ((*- endblock headingcell *))
225
226 %==============================================================================
227 % Markdown
228 %
229 % Purpose: Convert markdown to latex. Here markdown2latex is explicitly
230 % called since we know we want latex output.
231 %==============================================================================
232 ((*- block markdowncell scoped-*))
233 ((( cell.source | markdown2latex )))
234 ((*- endblock markdowncell -*))
235
236 %==============================================================================
237 % Rawcell
238 %
239 % Purpose: Raw text cells allow the user to manually inject document code that
240 % will not get touched by the templating system.
241 %==============================================================================
242 ((*- block rawcell *))
243 ((( cell.source | wrap(wrap_size) )))
244 ((* endblock rawcell -*))
245
246 %==============================================================================
247 % Unknowncell
248 %
249 % Purpose: This is the catch anything unhandled. To display this data, we
250 % remove all possible latex conflicts and wrap the characters so they
251 % can't flow off of the page.
252 %==============================================================================
253 ((* block unknowncell scoped*))
254
255 % Unsupported cell type, no formatting
256 ((( cell.source | wrap | escape_tex )))
257 ((* endblock unknowncell *))
258
259 %==============================================================================
260 % Input
261 %==============================================================================
262 ((* block input *))
263
264 % Make sure that atleast 4 lines are below the HR
265 \needspace{((( min_header_lines )))\baselineskip}
266
267 ((* if resources.sphinx.outputstyle == 'simple' *))
268
269 % Add a horizantal break, along with break title.
270 \vspace{10pt}
271 {\scriptsize Input}\\*
272 \rule[10pt]{\linewidth}{0.5pt}
273 \vspace{-25pt}
274
275 % Add contents below.
276 ((( cell.input | highlight )))
277
278 ((* elif resources.sphinx.outputstyle == 'notebook' *))
279 \vspace{6pt}
280 ((( write_prompt("In", cell.prompt_number, "nbframe-in-prompt") )))
281 \vspace{-2.65\baselineskip}
282 \begin{ColorVerbatim}
283 \vspace{-0.7\baselineskip}
284 ((( cell.input | highlight )))
285 ((* if cell.input == None or cell.input == '' *))
286 \vspace{0.3\baselineskip}
287 ((* else *))
288 \vspace{-0.2\baselineskip}
289 ((* endif *))
290 \end{ColorVerbatim}
291 ((* endif *))
292 ((* endblock input *))
293
294 %==============================================================================
295 % Output_Group
296 %
297 % Purpose: Make sure that only one header bar only attaches to the output
298 % once. By keeping track of when an input group is started
299 %==============================================================================
300 ((* block output_group *))
301 ((* if cell.outputs.__len__() > 0 *))
302
303 % If the first block is an image, minipage the image. Else
304 % request a certain amount of space for the input text.
305 ((( iff_figure(cell.outputs[0], "\\begin{minipage}{1.0\\textwidth}", "\\needspace{" ~ min_header_lines ~ "\\baselineskip}") )))
306
307 ((* if resources.sphinx.outputstyle == 'simple' *))
308
309 % Add a horizantal break, along with break title.
310 \vspace{10pt}
311 {\scriptsize Output}\\*
312 \rule[10pt]{\linewidth}{0.5pt}
313 \vspace{-20pt}
314
315 % Add the contents of the first block.
316 ((( render_output(cell.outputs[0]) )))
317
318 % Close the minipage.
319 ((( iff_figure(cell.outputs[0], "\\end{minipage}", "") )))
320
321 % Add remainer of the document contents below.
322 ((* for output in cell.outputs[1:] *))
323 ((( render_output(output, cell.prompt_number) )))
324 ((* endfor *))
325 ((* elif resources.sphinx.outputstyle == 'notebook' *))
326
327 % Add document contents.
328 ((* for output in cell.outputs *))
329 ((( render_output(output, cell.prompt_number) )))
330 ((* endfor *))
331 ((* endif *))
332 ((* endif *))
333 ((* endblock *))
334
335 %==============================================================================
336 % Additional formating
337 %==============================================================================
338 ((* block data_text *))
339 ((( custom_verbatim(output.text) | ansi2latex)))
340 ((* endblock *))
341
342 ((* block traceback_line *))
343 ((( conditionally_center_output(line | indent| rm_ansi) )))
344 ((* endblock traceback_line *))
345
346 %==============================================================================
347 % Supported image formats
348 %==============================================================================
349 ((*- block data_png -*))
350 ((( conditionally_center_output(insert_graphics(output.key_png)) )))
351 ((*- endblock -*))
352
353 ((*- block data_svg -*))
354 ((( conditionally_center_output(insert_graphics(output.key_svg)) )))
355 ((*- endblock -*))
356
357 ((*- block data_latex *))
358 ((* if resources.sphinx.centeroutput *))\begin{center}((* endif -*))((( output.latex | rm_math_space )))((*- if resources.sphinx.centeroutput *))\end{center} ((* endif -*))
359 ((*- endblock -*))
360
361 %==============================================================================
362 % Support Macros
363 %==============================================================================
364
365 % Name: write_prompt
366 % Purpose: Renders an output/input prompt for notebook style pdfs
367 ((* macro write_prompt(prompt, number, color) -*))
368 \makebox[0.1\linewidth]{\smaller\hfill\tt\color{((( color )))}((( prompt )))\hspace{4pt}{[}((( number ))){]}:\hspace{4pt}}\\*
369 ((*- endmacro *))
370
371 % Name: render_output
372 % Purpose: Renders an output block appropriately.
373 ((* macro render_output(output, prompt_number) -*))
374 ((*- if output.output_type == 'pyerr' -*))
375 ((*- block pyerr scoped *))
376 ((( custom_verbatim(super()) )))
377 ((* endblock pyerr -*))
378 ((*- else -*))
379
380 ((* if resources.sphinx.outputstyle == 'notebook' *))
381 ((*- if output.output_type == 'pyout' -*))
382 ((( write_prompt("Out", prompt_number, "nbframe-out-prompt") )))
383 \vspace{-2.55\baselineskip}
384 ((*- endif -*))
385
386 \begin{InvisibleVerbatim}
387 \vspace{-0.5\baselineskip}
388 ((*- endif -*))
389
390 ((*- block display_data scoped -*))
391 ((( super() )))
392 ((*- endblock display_data -*))
393
394 ((* if resources.sphinx.outputstyle == 'notebook' *))
395 \end{InvisibleVerbatim}
396 ((*- endif -*))
397 ((*- endif -*))
398 ((*- endmacro *))
399
400 % Name: iff_figure
401 % Purpose: If the output block provided is a figure type, the 'true_content'
402 % parameter will be returned. Else, the 'false_content'.
403 ((* macro iff_figure(output, true_content, false_content) -*))
404 ((*- set is_figure = false -*))
405 ((*- for type in output | filter_data_type -*))
406 ((*- if type in ['pdf', 'svg', 'png', 'jpeg','html']*))
407 ((*- set is_figure = true -*))
408 ((*- endif -*))
409 ((*- endfor -*))
410
411 ((* if is_figure -*))
412 ((( true_content )))
413 ((*- else -*))
414 ((( false_content )))
415 ((*- endif *))
416 ((*- endmacro *))
417
418 % Name: custom_verbatim
419 % Purpose: This macro creates a verbatim style block that fits the existing
420 % sphinx style more readily than standard verbatim blocks.
421 ((* macro custom_verbatim(text) -*))
422 \begin{alltt}
423 ((*- if resources.sphinx.centeroutput *))\begin{center} ((* endif -*))
424 ((( text | wrap(wrap_size) )))
425 ((*- if resources.sphinx.centeroutput *))\end{center}((* endif -*))
426 \end{alltt}
427 ((*- endmacro *))
428
429 % Name: conditionally_center_output
430 % Purpose: This macro centers the output if the output centering is enabled.
431 ((* macro conditionally_center_output(text) -*))
432 ((* if resources.sphinx.centeroutput *)){\centering ((* endif *))((( text )))((* if resources.sphinx.centeroutput *))}((* endif *))
433 ((*- endmacro *))
434
435 % Name: insert_graphics
436 % Purpose: This macro will insert an image in the latex document given a path.
437 ((* macro insert_graphics(path) -*))
438 \begin{center}
439 \includegraphics[max size={\textwidth}{\textheight}]{(((path)))}
440 \par
441 \end{center}
442 ((*- endmacro *))
@@ -0,0 +1,25 b''
1 ((============================================================================
2 NBConvert Sphinx-Latex HowTo Template
3
4 Purpose: Allow export of PDF friendly Latex inspired by Sphinx HowTo
5 document style. Most of the is derived directly from Sphinx source.
6
7 Inheritance: null>display_priority>latex_base->latex_sphinx_base
8
9 ==========================================================================))
10
11 ((*- extends 'sphinx_base.tplx' -*))
12
13 ((* set parentdocumentclass = 'article' *))
14 ((* set documentclass = 'howto' *))
15
16 ((* block h1 -*))part((* endblock h1 -*))
17 ((* block h2 -*))section((* endblock h2 -*))
18 ((* block h3 -*))subsection((* endblock h3 -*))
19 ((* block h4 -*))subsubsection((* endblock h4 -*))
20 ((* block h5 -*))paragraph((* endblock h5 -*))
21 ((* block h6 -*))subparagraph((* endblock h6 -*))
22
23 % Diasble table of contents for howto
24 ((* block toc *))
25 ((* endblock toc *))
@@ -0,0 +1,21 b''
1 ((============================================================================
2 NBConvert Sphinx-Latex Manual Template
3
4 Purpose: Allow export of PDF friendly Latex inspired by Sphinx Manual
5 document style. Most of the is derived directly from Sphinx source.
6
7 Inheritance: null>display_priority>latex_base->latex_sphinx_base
8
9 ==========================================================================))
10
11 ((*- extends 'sphinx_base.tplx' -*))
12
13 ((* set parentdocumentclass = 'report' *))
14 ((* set documentclass = 'manual' *))
15
16 ((* block h1 -*))part((* endblock h1 -*))
17 ((* block h2 -*))chapter((* endblock h2 -*))
18 ((* block h3 -*))section((* endblock h3 -*))
19 ((* block h4 -*))subsection((* endblock h4 -*))
20 ((* block h5 -*))subsubsection((* endblock h5 -*))
21 ((* block h6 -*))paragraph((* endblock h6 -*))
@@ -0,0 +1,73 b''
1 {% extends 'display_priority.tpl' %}
2 {% block in_prompt %}
3 In[{{cell.prompt_number if cell.prompt_number else ' '}}]:{% endblock in_prompt %}
4
5 {% block output_prompt %}{% if cell.haspyout %}Out[{{cell.prompt_number}}]:
6 {%- endif %}{%- endblock output_prompt %}
7
8 {% block input %}
9 ```
10 {{ cell.input}}
11 ```
12 {% endblock input %}
13
14 {% block pyerr %}
15 {{ super() }}
16 {% endblock pyerr %}
17
18 {% block traceback_line %}
19 {{ line |indent| rm_ansi }}{% endblock traceback_line %}
20
21 {% block pyout %}
22 {% block data_priority scoped %}{{ super()}}{% endblock %}
23 {% endblock pyout %}
24
25 {% block stream %}
26 {{ output.text| indent }}
27 {% endblock stream %}
28
29
30
31
32 {% block data_svg %}
33 [!image]({{output.key_svg}})
34 {% endblock data_svg %}
35
36 {% block data_png %}
37 [!image]({{output.key_png}})
38 {% endblock data_png %}
39
40 {% block data_jpg %}
41 [!image]({{output.key_jpg}})
42 {% endblock data_jpg %}
43
44
45
46 {% block data_latex %}
47 $$
48 {{output.latex}}
49 $$
50 {% endblock data_latex %}
51
52 {% block data_text scoped %}
53
54 {{output.text | indent}}
55
56 {% endblock data_text %}
57
58 {% block markdowncell scoped %}
59 {{ cell.source | wrap(80)}}
60 {% endblock markdowncell %}
61
62 {% block headingcell scoped %}
63
64 {{ '#' * cell.level }} {{ cell.source}}
65
66 {% endblock headingcell %}
67
68 {% block rawcell scoped %}{{ cell.source }}
69 {% endblock rawcell %}
70
71 {% block unknowncell scoped %}
72 unknown type {{cell.type}}
73 {% endblock unknowncell %}
@@ -0,0 +1,56 b''
1 {%- extends 'null.tpl' -%}
2
3 {% block in_prompt %}
4 # In[{{cell.prompt_number if cell.prompt_number else ' '}}]:
5 {% endblock in_prompt %}
6
7 {% block output_prompt %}
8 # Out[{{cell.prompt_number}}]:{% endblock output_prompt %}
9
10 {% block input %}{{ cell.input }}
11 {% endblock input %}
12
13
14 {# Those Two are for error displaying
15 even if the first one seem to do nothing,
16 it introduces a new line
17
18 #}
19 {% block pyerr %}{{ super() }}
20 {% endblock pyerr %}
21
22 {% block traceback_line %}
23 {{ line |indent| rm_ansi }}{% endblock traceback_line %}
24 {# .... #}
25
26
27 {% block pyout %}
28 {{ output.text| indent | pycomment}}
29 {% endblock pyout %}
30
31 {% block stream %}
32 {{ output.text| indent | pycomment}}
33 {% endblock stream %}
34
35
36
37
38 {% block display_data scoped %}
39 # image file:
40 {% endblock display_data %}
41
42 {% block markdowncell scoped %}
43 {{ cell.source | pycomment }}
44 {% endblock markdowncell %}
45
46 {% block headingcell scoped %}
47 {{ '#' * cell.level }}{{ cell.source | pycomment}}
48 {% endblock headingcell %}
49
50 {% block rawcell scoped %}
51 {{ cell.source | pycomment }}
52 {% endblock rawcell %}
53
54 {% block unknowncell scoped %}
55 unknown type {{cell.type}}
56 {% endblock unknowncell %}
@@ -0,0 +1,31 b''
1 {%- extends 'python.tpl' -%}
2
3 {#% block any_cell %}
4 ==============================
5 =======start {{cell.type}}=========
6 {{ super() }}
7 ======= end {{cell.type}} =========
8 =============================={% endblock any_cell %#}
9
10
11
12 {% block markdowncell %}---- Start MD ----{{ super() }}
13 ---- End MD ----
14 {% endblock markdowncell %}
15
16 {% block codecell %}---- Start Code ----{{ super() }}
17 ---- End Code ----
18 {% endblock codecell %}
19
20 {% block headingcell scoped %}---- Start heading ----{{ super() }}
21 ---- End heading ----
22 {% endblock headingcell %}
23
24 {% block rawcell scoped %}---- Start Raw ----
25 {{ super() }}
26 ---- End Raw ----{% endblock rawcell %}
27
28 {% block unknowncell scoped %}
29 unknown type {{cell.type}}
30 {% endblock unknowncell %}
31
@@ -0,0 +1,180 b''
1 {%- extends 'slides.tpl' -%}
2
3
4 {% block header %}
5 <!DOCTYPE html>
6 <html>
7 <head>
8
9 <meta charset="utf-8" />
10 <meta http-equiv="X-UA-Compatible" content="chrome=1">
11
12 <meta name="apple-mobile-web-app-capable" content="yes" />
13 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
14
15 <link rel="stylesheet" href="reveal.js/css/reveal.css">
16 <link rel="stylesheet" href="reveal.js/css/theme/simple.css" id="theme">
17
18 <!-- For syntax highlighting -->
19 <link rel="stylesheet" href="reveal.js/lib/css/zenburn.css">
20
21 <!-- If the query includes 'print-pdf', use the PDF print sheet -->
22 <script>
23 document.write( '<link rel="stylesheet" href="reveal.js/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
24 </script>
25
26 <!--[if lt IE 9]>
27 <script src="reveal.js/lib/js/html5shiv.js"></script>
28 <![endif]-->
29
30 {% for css in resources.inlining.css -%}
31 <style type="text/css">
32 {{css}}
33 </style>
34 {% endfor %}
35
36 <style type="text/css">
37 /* Overrides of notebook CSS for static HTML export */
38 .reveal {
39 font-size: 20px;
40 overflow-y: auto;
41 overflow-x: hidden;
42 }
43 .reveal pre {
44 width: 95%;
45 padding: 0.4em;
46 margin: 0px;
47 font-family: monospace, sans-serif;
48 font-size: 80%;
49 box-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
50 }
51 .reveal section img {
52 border: 0px solid black;
53 box-shadow: 0 0 10px rgba(0, 0, 0, 0);
54 }
55 .reveal .slides {
56 text-align: left;
57 }
58 .reveal.fade {
59 opacity: 1;
60 }
61 div.input_area {
62 padding: 0.06em;
63 }
64 div.code_cell {
65 background-color: transparent;
66 }
67 div.prompt {
68 width: 11ex;
69 padding: 0.4em;
70 margin: 0px;
71 font-family: monospace, sans-serif;
72 font-size: 80%;
73 text-align: right;
74 }
75 div.output_area pre {
76 font-family: monospace, sans-serif;
77 font-size: 80%;
78 }
79 div.output_prompt {
80 /* 5px right shift to account for margin in parent container */
81 margin: 5px 5px 0 -5px;
82 }
83 .rendered_html p {
84 text-align: inherit;
85 }
86 </style>
87 </head>
88 {% endblock header%}
89
90
91 {% block body %}
92 <body>
93 <div class="reveal"><div class="slides">
94
95 {{ super() }}
96
97 </div></div>
98
99 <!--
100 Uncomment the following block and the addthis_widget.js (see below inside dependencies)
101 to get enable social buttons.
102 -->
103
104 <!--
105 <div class="addthis_toolbox addthis_floating_style addthis_32x32_style" style="left:20px;top:20px;">
106 <a class="addthis_button_twitter"></a>
107 <a class="addthis_button_google_plusone_share"></a>
108 <a class="addthis_button_linkedin"></a>
109 <a class="addthis_button_facebook"></a>
110 <a class="addthis_button_more"></a>
111 </div>
112 -->
113
114 <script src="reveal.js/lib/js/head.min.js"></script>
115
116 <script src="reveal.js/js/reveal.min.js"></script>
117
118 <script>
119
120 // Full list of configuration options available here: https://github.com/hakimel/reveal.js#configuration
121 Reveal.initialize({
122 controls: true,
123 progress: true,
124 history: true,
125
126 theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
127 transition: Reveal.getQueryHash().transition || 'linear', // default/cube/page/concave/zoom/linear/none
128
129 // Optional libraries used to extend on reveal.js
130 dependencies: [
131 { src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
132 { src: 'reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
133 { src: 'reveal.js/plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
134 // { src: 'http://s7.addthis.com/js/300/addthis_widget.js', async: true},
135 ]
136 });
137 </script>
138
139 <!-- MathJax configuration -->
140 <script type="text/x-mathjax-config">
141 MathJax.Hub.Config({
142 tex2jax: {
143 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
144 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
145 },
146 displayAlign: 'left', // Change this to 'center' to center equations.
147 "HTML-CSS": {
148 styles: {'.MathJax_Display': {"margin": 0}}
149 }
150 });
151 </script>
152 <!-- End of mathjax configuration -->
153
154 <script>
155 // We wait for the onload function to load MathJax after the page is completely loaded.
156 // MathJax is loaded 1 unit of time after the page is ready.
157 // This hack prevent problems when you load multiple js files (i.e. social button from addthis).
158 //
159 window.onload = function () {
160 setTimeout(function () {
161 var script = document.createElement("script");
162 script.type = "text/javascript";
163 script.src = "https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML";
164 document.getElementsByTagName("head")[0].appendChild(script);
165 },1)
166 }
167 </script>
168
169 <script>
170 Reveal.addEventListener( 'slidechanged', function( event ) {
171 MathJax.Hub.Rerender(event.currentSlide);
172 });
173 </script>
174
175 </body>
176 {% endblock body %}
177
178 {% block footer %}
179 </html>
180 {% endblock footer %}
@@ -0,0 +1,21 b''
1 {%- extends 'basichtml.tpl' -%}
2
3
4
5 {%- block any_cell scoped -%}
6 {%- if cell.metadata.slide_type in ['-', 'slide', 'subslide'] -%}
7 {{ super() }}
8 {%- elif cell.metadata.slide_type in ['skip'] -%}
9 <div style=display:none>
10 {{ super() }}
11 </div>
12 {%- elif cell.metadata.slide_type in ['notes'] -%}
13 <aside class="notes">
14 {{ super() }}
15 </aside>
16 {%- elif cell.metadata.slide_type in ['fragment'] -%}
17 <div class="fragment">
18 {{ super() }}
19 </div>
20 {%- endif -%}
21 {%- endblock any_cell -%}
@@ -0,0 +1,89 b''
1 {%- extends 'display_priority.tpl' -%}
2 {% block in_prompt -%}
3 In[{{cell.prompt_number if cell.prompt_number else ' '}}]:
4
5 .. code:: python
6
7 {% endblock in_prompt %}
8
9 {% block output_prompt %}{% if cell.haspyout -%}
10 Out[{{cell.prompt_number}}]:{% endif %}{% endblock output_prompt %}
11
12 {% block input %}{{ cell.input | indent}}
13
14 {% endblock input %}
15
16 {% block pyerr %}::
17 {{ super() }}
18 {% endblock pyerr %}
19
20 {% block traceback_line %}
21 {{ line |indent| rm_ansi }}{% endblock traceback_line %}
22
23 {% block pyout %}
24 {% block data_priority scoped %}{{ super()}}{% endblock %}
25 {% endblock pyout %}
26
27 {% block stream %}
28 .. parsed-literal::
29
30 {{ output.text| indent }}
31 {% endblock stream %}
32
33
34
35
36 {% block data_svg %}.. image:: {{output.key_svg}}
37
38 {% endblock data_svg %}
39
40 {% block data_png %}.. image:: {{output.key_png}}
41
42 {% endblock data_png %}
43
44 {% block data_jpg %}..jpg image:: {{output.key_jpg}}
45
46 {% endblock data_jpg %}
47
48
49
50 {% block data_latex %}.. math::
51
52 {{output.latex| indent}}
53
54 {% endblock data_latex %}
55
56 {% block data_text scoped %}.. parsed-literal::
57
58 {{output.text | indent}}
59
60 {% endblock data_text %}
61
62 {% block markdowncell scoped %}{{ cell.source | markdown2rst }}
63 {% endblock markdowncell %}
64
65 {% block headingcell scoped %}
66 {%- set len = cell.source|length -%}
67 {{ cell.source}}
68 {% if cell.level == 1 %}
69 {{- '=' * len }}
70 {%- elif cell.level == 2 %}
71 {{- '-' * len }}
72 {%- elif cell.level == 3 %}
73 {{- '~' * len }}
74 {%- elif cell.level == 4 %}
75 {{- '.' * len }}
76 {%- elif cell.level == 5 %}
77 {{- '\\' * len }}
78 {%- elif cell.level == 6 %}
79 {{- '`' * len }}
80 {% endif %}
81
82 {% endblock headingcell %}
83
84 {% block rawcell scoped %}{{ cell.source }}
85 {% endblock rawcell %}
86
87 {% block unknowncell scoped %}
88 unknown type {{cell.type}}
89 {% endblock unknowncell %}
@@ -0,0 +1,23 b''
1
2
3 all: tex/null.tplx tex/display_priority.tplx
4
5 # convert jinja syntax to tex
6 # cf http://flask.pocoo.org/snippets/55/
7 tex/%.tplx: %.tpl
8 @echo 'generating tex equivalent of $^: $@'
9 @echo '((= autogenerated file do not edit =))' > $@
10 @sed \
11 -e 's/{%/((*/g' \
12 -e 's/%}/*))/g' \
13 -e 's/{{/(((/g' \
14 -e 's/}}/)))/g' \
15 -e 's/{#/((=/g' \
16 -e 's/#}/=))/g' \
17 -e "s/tpl'/tplx'/g" \
18 $^ >> $@
19
20
21 clean:
22 @echo "cleaning generated tplx files..."
23 @rm tex/*
@@ -0,0 +1,6 b''
1 ## Template skeleton
2
3 This contain skeleton template that you probably don't want
4 to inherit directly.
5
6 do not moify the content of the 'tex' folder which is generated by running 'make' in this folder.
@@ -0,0 +1,38 b''
1 {%- extends 'null.tpl' -%}
2
3 {#display data priority#}
4
5
6 {%- block data_priority scoped -%}
7 {%- for type in output | filter_data_type -%}
8 {%- if type in ['pdf']%}
9 {%- block data_pdf -%}
10 {%- endblock -%}
11 {%- endif -%}
12 {%- if type in ['svg']%}
13 {%- block data_svg -%}
14 {%- endblock -%}
15 {%- endif -%}
16 {%- if type in ['png']%}
17 {%- block data_png -%}
18 {%- endblock -%}
19 {%- endif -%}
20 {%- if type in ['html']%}
21 {%- block data_html -%}
22 {%- endblock -%}
23 {%- endif -%}
24 {%- if type in ['jpeg']%}
25 {%- block data_jpg -%}
26 {%- endblock -%}
27 {%- endif -%}
28 {%- if type in ['text']%}
29 {%- block data_text -%}
30 {%- endblock -%}
31 {%- endif -%}
32
33 {%- if type in ['latex']%}
34 {%- block data_latex -%}
35 {%- endblock -%}
36 {%- endif -%}
37 {%- endfor -%}
38 {%- endblock data_priority -%}
@@ -0,0 +1,91 b''
1 {#
2
3 DO NOT USE THIS AS A BASE WORK,
4 IF YOU ARE COPY AND PASTING THIS FILE
5 YOU ARE PROBABLY DOING THINGS WRONG.
6
7 Null template, Does nothing except defining a basic structure
8 To layout the different blocks of a notebook.
9
10 Subtemplates can override blocks to define their custom representation.
11
12 If one of the block you do overwrite is not a leave block, consider
13 calling super.
14
15 {%- block nonLeaveBlock -%}
16 #add stuff at beginning
17 {{ super() }}
18 #add stuff at end
19 {%- endblock nonLeaveBlock -%}
20
21 consider calling super even if it is a leave block, we might insert more blocks later.
22
23 #}
24 {%- block header -%}
25 {%- endblock header -%}
26 {%- block body -%}
27 {%- for worksheet in nb.worksheets -%}
28 {%- for cell in worksheet.cells -%}
29 {%- block any_cell scoped -%}
30 {%- if cell.cell_type in ['code'] -%}
31 {%- block codecell scoped -%}
32 {%- block input_group -%}
33 {%- block in_prompt -%}{%- endblock in_prompt -%}
34 {%- block input -%}{%- endblock input -%}
35 {%- endblock input_group -%}
36 {%- if cell.outputs -%}
37 {%- block output_group -%}
38 {%- block output_prompt -%}{%- endblock output_prompt -%}
39 {%- block outputs scoped -%}
40 {%- for output in cell.outputs -%}
41 {%- block output scoped -%}
42 {%- if output.output_type in ['pyout'] -%}
43 {%- block pyout scoped -%}{%- endblock pyout -%}
44 {%- elif output.output_type in ['stream'] -%}
45 {%- block stream scoped -%}
46 {%- if output.stream in ['stdout'] -%}
47 {%- block stream_stdout scoped -%}
48 {%- endblock stream_stdout -%}
49 {%- elif output.stream in ['stderr'] -%}
50 {%- block stream_stderr scoped -%}
51 {%- endblock stream_stderr -%}
52 {%- endif -%}
53 {%- endblock stream -%}
54 {%- elif output.output_type in ['display_data'] -%}
55 {%- block display_data scoped -%}
56 {%- block data_priority scoped -%}
57 {%- endblock data_priority -%}
58 {%- endblock display_data -%}
59 {%- elif output.output_type in ['pyerr'] -%}
60 {%- block pyerr scoped -%}
61 {%- for line in output.traceback -%}
62 {%- block traceback_line scoped -%}{%- endblock traceback_line -%}
63 {%- endfor -%}
64 {%- endblock pyerr -%}
65 {%- endif -%}
66 {%- endblock output -%}
67 {%- endfor -%}
68 {%- endblock outputs -%}
69 {%- endblock output_group -%}
70 {%- endif -%}
71 {%- endblock codecell -%}
72 {%- elif cell.cell_type in ['markdown'] -%}
73 {%- block markdowncell scoped-%}
74 {%- endblock markdowncell -%}
75 {%- elif cell.cell_type in ['heading'] -%}
76 {%- block headingcell scoped-%}
77 {%- endblock headingcell -%}
78 {%- elif cell.cell_type in ['raw'] -%}
79 {%- block rawcell scoped-%}
80 {%- endblock rawcell -%}
81 {%- else -%}
82 {%- block unknowncell scoped-%}
83 {%- endblock unknowncell -%}
84 {%- endif -%}
85 {%- endblock any_cell -%}
86 {%- endfor -%}
87 {%- endfor -%}
88 {%- endblock body -%}
89
90 {%- block footer -%}
91 {%- endblock footer -%}
@@ -0,0 +1,17 b''
1 {%- extends 'subslides.tpl' -%}
2
3
4
5 {%- block any_cell scoped -%}
6 {%- if cell.metadata.slide_type in ['slide'] -%}
7 <section>
8 <section>
9 {%- endif -%}
10
11 {{ super() }}
12
13 {%- if cell.metadata.slide_helper in ['slide_end'] -%}
14 </section>
15 </section>
16 {%- endif -%}
17 {%- endblock any_cell -%}
@@ -0,0 +1,15 b''
1 {%- extends 'align_reveal_cells.tpl' -%}
2
3
4
5 {%- block any_cell scoped -%}
6 {%- if cell.metadata.slide_type in ['subslide'] -%}
7 <section>
8 {%- endif -%}
9
10 {{ super() }}
11
12 {%- if cell.metadata.slide_helper in ['subslide_end'] -%}
13 </section>
14 {%- endif -%}
15 {%- endblock any_cell -%}
@@ -0,0 +1,9 b''
1 # Class base Transformers
2 from .activatable import ActivatableTransformer
3 from .base import ConfigurableTransformer
4 from .extractfigure import ExtractFigureTransformer
5 from .latex import LatexTransformer
6 from .sphinx import SphinxTransformer
7
8 # decorated function Transformers
9 from .coalescestreams import coalesce_streams
@@ -0,0 +1,53 b''
1 """
2 Contains base transformer with an enable/disable flag.
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 .base import ConfigurableTransformer
17 from IPython.utils.traitlets import (Bool)
18
19 #-----------------------------------------------------------------------------
20 # Classes and Functions
21 #-----------------------------------------------------------------------------
22
23 class ActivatableTransformer(ConfigurableTransformer):
24 """ConfigurableTransformer that has an enabled flag
25
26 Inherit from this if you just want to have a transformer which is
27 disable by default and can be enabled via the config by
28 'c.YourTransformerName.enabled = True'
29 """
30
31 enabled = Bool(False, config=True)
32
33 def __call__(self, nb, resources):
34 """
35 Transformation to apply on each notebook.
36
37 You should return modified nb, resources.
38 If you wish to apply your transform on each cell, you might want to
39 overwrite cell_transform method instead.
40
41 Parameters
42 ----------
43 nb : NotebookNode
44 Notebook being converted
45 resources : dictionary
46 Additional resources used in the conversion process. Allows
47 transformers to pass variables into the Jinja engine.
48 """
49
50 if not self.enabled :
51 return nb, resources
52 else :
53 return super(ActivatableTransformer, self).__call__(nb, resources)
@@ -0,0 +1,99 b''
1 """
2 Module that re-groups transformer that would be applied to ipynb files
3 before going through the templating machinery.
4
5 It exposes a convenient class to inherit from to access configurability.
6 """
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
9 #
10 # Distributed under the terms of the Modified BSD License.
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 from ..utils.config import GlobalConfigurable
20
21 #-----------------------------------------------------------------------------
22 # Classes and Functions
23 #-----------------------------------------------------------------------------
24
25 class ConfigurableTransformer(GlobalConfigurable):
26 """ A configurable transformer
27
28 Inherit from this class if you wish to have configurability for your
29 transformer.
30
31 Any configurable traitlets this class exposed will be configurable in profiles
32 using c.SubClassName.atribute=value
33
34 you can overwrite cell_transform to apply a transformation independently on each cell
35 or __call__ if you prefer your own logic. See corresponding docstring for informations.
36 """
37
38 def __init__(self, config=None, **kw):
39 """
40 Public constructor
41
42 Parameters
43 ----------
44 config : Config
45 Configuration file structure
46 **kw : misc
47 Additional arguments
48 """
49
50 super(ConfigurableTransformer, self).__init__(config=config, **kw)
51
52
53 def __call__(self, nb, resources):
54 return self.call(nb,resources)
55
56 def call(self, nb, resources):
57 """
58 Transformation to apply on each notebook.
59
60 You should return modified nb, resources.
61 If you wish to apply your transform on each cell, you might want to
62 overwrite cell_transform method instead.
63
64 Parameters
65 ----------
66 nb : NotebookNode
67 Notebook being converted
68 resources : dictionary
69 Additional resources used in the conversion process. Allows
70 transformers to pass variables into the Jinja engine.
71 """
72 try :
73 for worksheet in nb.worksheets :
74 for index, cell in enumerate(worksheet.cells):
75 worksheet.cells[index], resources = self.cell_transform(cell, resources, index)
76 return nb, resources
77 except NotImplementedError:
78 raise NotImplementedError('should be implemented by subclass')
79
80
81 def cell_transform(self, cell, resources, index):
82 """
83 Overwrite if you want to apply a transformation on each cell. You
84 should return modified cell and resource dictionary.
85
86 Parameters
87 ----------
88 cell : NotebookNode cell
89 Notebook cell being processed
90 resources : dictionary
91 Additional resources used in the conversion process. Allows
92 transformers to pass variables into the Jinja engine.
93 index : int
94 Index of the cell being processed
95 """
96
97 raise NotImplementedError('should be implemented by subclass')
98 return cell, resources
99
@@ -0,0 +1,75 b''
1 """Module that allows latex output notebooks to be conditioned before
2 they are converted. Exposes a decorator (@cell_preprocessor) in
3 addition to the coalesce_streams pre-proccessor.
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 # Functions
15 #-----------------------------------------------------------------------------
16
17 def cell_preprocessor(function):
18 """
19 Wrap a function to be executed on all cells of a notebook
20
21 Wrapped Parameters
22 ----------
23 cell : NotebookNode cell
24 Notebook cell being processed
25 resources : dictionary
26 Additional resources used in the conversion process. Allows
27 transformers to pass variables into the Jinja engine.
28 index : int
29 Index of the cell being processed
30 """
31
32 def wrappedfunc(nb, resources):
33 for worksheet in nb.worksheets :
34 for index, cell in enumerate(worksheet.cells):
35 worksheet.cells[index], resources = function(cell, resources, index)
36 return nb, resources
37 return wrappedfunc
38
39
40 @cell_preprocessor
41 def coalesce_streams(cell, resources, index):
42 """
43 Merge consecutive sequences of stream output into single stream
44 to prevent extra newlines inserted at flush calls
45
46 Parameters
47 ----------
48 cell : NotebookNode cell
49 Notebook cell being processed
50 resources : dictionary
51 Additional resources used in the conversion process. Allows
52 transformers to pass variables into the Jinja engine.
53 index : int
54 Index of the cell being processed
55 """
56
57 outputs = cell.get('outputs', [])
58 if not outputs:
59 return cell, resources
60
61 last = outputs[0]
62 new_outputs = [last]
63
64 for output in outputs[1:]:
65 if (output.output_type == 'stream' and
66 last.output_type == 'stream' and
67 last.stream == output.stream
68 ):
69 last.text += output.text
70 else:
71 new_outputs.append(output)
72
73 cell.outputs = new_outputs
74 return cell, resources
75
@@ -0,0 +1,105 b''
1 """Module that pre-processes the notebook for export to HTML.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 import os
16 import io
17
18 from pygments.formatters import HtmlFormatter
19
20 from IPython.utils import path
21
22 from .activatable import ActivatableTransformer
23
24 #-----------------------------------------------------------------------------
25 # Classes and functions
26 #-----------------------------------------------------------------------------
27
28 class CSSHtmlHeaderTransformer(ActivatableTransformer):
29 """
30 Transformer used to pre-process notebook for HTML output. Adds IPython notebook
31 front-end CSS and Pygments CSS to HTML output.
32 """
33
34 header = []
35
36 def __init__(self, config=None, **kw):
37 """
38 Public constructor
39
40 Parameters
41 ----------
42 config : Config
43 Configuration file structure
44 **kw : misc
45 Additional arguments
46 """
47
48 super(CSSHtmlHeaderTransformer, self).__init__(config=config, **kw)
49
50 if self.enabled :
51 self._regen_header()
52
53
54 def __call__(self, nb, resources):
55 """Fetch and add CSS to the resource dictionary
56
57 Fetch CSS from IPython and Pygments to add at the beginning
58 of the html files. Add this css in resources in the
59 "inlining.css" key
60
61 Parameters
62 ----------
63 nb : NotebookNode
64 Notebook being converted
65 resources : dictionary
66 Additional resources used in the conversion process. Allows
67 transformers to pass variables into the Jinja engine.
68 """
69
70 resources['inlining'] = {}
71 resources['inlining']['css'] = self.header
72
73 return nb, resources
74
75
76 def _regen_header(self):
77 """
78 Fills self.header with lines of CSS extracted from IPython
79 and Pygments.
80 """
81
82 #Clear existing header.
83 header = []
84
85 #Construct path to IPy CSS
86 sheet_filename = os.path.join(path.get_ipython_package_dir(),
87 'html', 'static', 'style', 'style.min.css')
88
89 #Load style CSS file.
90 try:
91 with io.open(sheet_filename, encoding='utf-8') as file:
92 file_text = file.read()
93 header.append(file_text)
94 except IOError:
95
96 # New version of IPython with style.min.css, pass
97 pass
98
99 #Add pygments CSS
100 pygments_css = HtmlFormatter().get_style_defs('.highlight')
101 header.append(pygments_css)
102
103 #Set header
104 self.header = header
105
@@ -0,0 +1,143 b''
1 """Module containing a transformer that extracts all of the figures from the
2 notebook file. The extracted figures are returned in the 'resources' dictionary.
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 import itertools
16
17 from IPython.utils.traitlets import Dict, Unicode
18 from .activatable import ActivatableTransformer
19
20 #-----------------------------------------------------------------------------
21 # Constants
22 #-----------------------------------------------------------------------------
23
24 FIGURES_KEY = "figures"
25 BINARY_KEY = "binary"
26 TEXT_KEY = "text"
27
28 #-----------------------------------------------------------------------------
29 # Classes
30 #-----------------------------------------------------------------------------
31
32 class ExtractFigureTransformer(ActivatableTransformer):
33 """
34 Extracts all of the figures from the notebook file. The extracted
35 figures are returned in the 'resources' dictionary.
36 """
37
38 extra_extension_map = Dict({},
39 config=True,
40 help="""Extra map to override extension based on type.
41 Useful for latex where SVG will be converted to PDF before inclusion
42 """)
43
44 key_format_map = Dict({}, config=True,)
45 figure_name_format_map = Dict({}, config=True)
46
47 #TODO: Change this to .format {} syntax
48 default_key_template = Unicode('_fig_{index:02d}.{ext}', config=True)
49
50 def __init__(self, config=None, **kw):
51 """
52 Public constructor
53
54 Parameters
55 ----------
56 config : Config
57 Configuration file structure
58 **kw : misc
59 Additional arguments
60 """
61
62 super(ExtractFigureTransformer, self).__init__(config=config, **kw)
63
64 # A unique index for association with extracted figures
65 self.index_generator = itertools.count(1)
66
67 def cell_transform(self, cell, resources, index):
68 """
69 Apply a transformation on each cell,
70
71 Parameters
72 ----------
73 cell : NotebookNode cell
74 Notebook cell being processed
75 resources : dictionary
76 Additional resources used in the conversion process. Allows
77 transformers to pass variables into the Jinja engine.
78 index : int
79 Index of the cell being processed (see base.py)
80 """
81
82 if resources.get(FIGURES_KEY, None) is None :
83 resources[FIGURES_KEY] = {TEXT_KEY:{},BINARY_KEY:{}}
84
85 for out in cell.get('outputs', []):
86 for out_type in self.display_data_priority:
87
88 if out.hasattr(out_type):
89 figname, key, data, binary = self._new_figure(out[out_type], out_type)
90 out['key_'+out_type] = figname
91
92 if binary :
93 resources[FIGURES_KEY][BINARY_KEY][key] = data
94 else :
95 resources[FIGURES_KEY][TEXT_KEY][key] = data
96
97 index += 1
98 return cell, resources
99
100
101 def _get_override_extension(self, extension):
102 """Gets the overriden extension if it exists, else returns extension.
103
104 Parameters
105 ----------
106 extension : str
107 File extension.
108 """
109
110 if extension in self.extra_extension_map :
111 return self.extra_extension_map[extension]
112
113 return extension
114
115
116 def _new_figure(self, data, format):
117 """Create a new figure file in the given format.
118
119 Parameters
120 ----------
121 data : str
122 Cell data (from Notebook node cell)
123 format : str
124 Figure format
125 index : int
126 Index of the figure being extracted
127 """
128
129 figure_name_template = self.figure_name_format_map.get(format, self.default_key_template)
130 key_template = self.key_format_map.get(format, self.default_key_template)
131
132 #TODO: option to pass the hash as data?
133 index = next(self.index_generator)
134 figure_name = figure_name_template.format(index=index, ext=self._get_override_extension(format))
135 key = key_template.format(index=index, ext=self._get_override_extension(format))
136
137 #Binary files are base64-encoded, SVG is already XML
138 binary = False
139 if format in ('png', 'jpg', 'pdf'):
140 data = data.decode('base64')
141 binary = True
142
143 return figure_name, key, data, binary
@@ -0,0 +1,53 b''
1 """Module that allows latex output notebooks to be conditioned before
2 they are converted.
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 __future__ import print_function, absolute_import
17
18 # Our own imports
19 # Needed to override transformer
20 from .activatable import (ActivatableTransformer)
21 from IPython.nbconvert import filters
22
23 #-----------------------------------------------------------------------------
24 # Classes
25 #-----------------------------------------------------------------------------
26
27 class LatexTransformer(ActivatableTransformer):
28 """
29 Converter for latex destined documents.
30 """
31
32 def cell_transform(self, cell, resources, index):
33 """
34 Apply a transformation on each cell,
35
36 Parameters
37 ----------
38 cell : NotebookNode cell
39 Notebook cell being processed
40 resources : dictionary
41 Additional resources used in the conversion process. Allows
42 transformers to pass variables into the Jinja engine.
43 index : int
44 Modified index of the cell being processed (see base.py)
45 """
46
47 #If the cell is a markdown cell, preprocess the ampersands used to
48 #remove the space between them and their contents. Latex will complain
49 #if spaces exist between the ampersands and the math content.
50 #See filters.latex.rm_math_space for more information.
51 if hasattr(cell, "source") and cell.cell_type == "markdown":
52 cell.source = filters.rm_math_space(cell.source)
53 return cell, resources
@@ -0,0 +1,52 b''
1 """Module that pre-processes the notebook for export via Reveal.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 from .base import ConfigurableTransformer
16
17 #-----------------------------------------------------------------------------
18 # Classes and functions
19 #-----------------------------------------------------------------------------
20
21 class RevealHelpTransformer(ConfigurableTransformer):
22
23 def call(self, nb, resources):
24 """
25 Called once to 'transform' contents of the notebook.
26
27 Parameters
28 ----------
29 nb : NotebookNode
30 Notebook being converted
31 resources : dictionary
32 Additional resources used in the conversion process. Allows
33 transformers to pass variables into the Jinja engine.
34 """
35
36
37 for worksheet in nb.worksheets :
38 for i, cell in enumerate(worksheet.cells):
39
40 #Make sure the cell has slideshow metadata.
41 cell.metadata.align_type = cell.get('metadata', {}).get('slideshow', {}).get('align_type', 'Left')
42 cell.metadata.slide_type = cell.get('metadata', {}).get('slideshow', {}).get('slide_type', '-')
43
44 #Get the slide type. If type is start of subslide or slide,
45 #end the last subslide/slide.
46 if cell.metadata.slide_type in ['slide']:
47 worksheet.cells[i - 1].metadata.slide_helper = 'slide_end'
48 if cell.metadata.slide_type in ['subslide']:
49 worksheet.cells[i - 1].metadata.slide_helper = 'subslide_end'
50
51 return nb, resources
52 No newline at end of file
@@ -0,0 +1,261 b''
1 """Module that allows custom Sphinx parameters to be set on the notebook and
2 on the 'other' object passed into Jinja. Called prior to Jinja conversion
3 process.
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 __future__ import print_function, absolute_import
18
19 # Stdlib imports
20 # Used to find Sphinx package location
21 import sphinx
22 import os.path
23
24 # Used to set the default date to today's date
25 from datetime import date
26
27 # Third-party imports
28 # Needed for Pygments latex definitions.
29 from pygments.formatters import LatexFormatter
30
31 # Our own imports
32 # Configurable traitlets
33 from IPython.utils.traitlets import Unicode, Bool
34
35 # Needed to override transformer
36 from .activatable import (ActivatableTransformer) #TODO
37
38 from IPython.nbconvert.utils import console
39
40 #-----------------------------------------------------------------------------
41 # Classes and functions
42 #-----------------------------------------------------------------------------
43
44 class SphinxTransformer(ActivatableTransformer):
45 """
46 Sphinx utility transformer.
47
48 This transformer is used to set variables needed by the latex to build
49 Sphinx stylized templates.
50 """
51
52 interactive = Bool(False, config=True, help="""
53 Allows you to define whether or not the Sphinx exporter will prompt
54 you for input during the conversion process. If this is set to false,
55 the author, version, release, date, and chapter_style traits should
56 be set.
57 """)
58
59 author = Unicode("Unknown Author", config=True, help="Author name")
60
61 version = Unicode("", config=True, help="""
62 Version number
63 You can leave this blank if you do not want to render a version number.
64 Example: "1.0.0"
65 """)
66
67 release = Unicode("", config=True, help="""
68 Release name
69 You can leave this blank if you do not want to render a release name.
70 Example: "Rough Draft"
71 """)
72
73 publish_date = Unicode("", config=True, help="""
74 Publish date
75 This is the date to render on the document as the publish date.
76 Leave this blank to default to todays date.
77 Example: "June 12, 1990"
78 """)
79
80 chapter_style = Unicode("Bjarne", config=True, help="""
81 Sphinx chapter style
82 This is the style to use for the chapter headers in the document.
83 You may choose one of the following:
84 "Bjarne" (default)
85 "Lenny"
86 "Glenn"
87 "Conny"
88 "Rejne"
89 "Sonny" (used for international documents)
90 """)
91
92 output_style = Unicode("notebook", config=True, help="""
93 Nbconvert Ipython
94 notebook input/output formatting style.
95 You may choose one of the following:
96 "simple (recommended for long code segments)"
97 "notebook" (default)
98 """)
99
100 center_output = Bool(False, config=True, help="""
101 Optional attempt to center all output. If this is false, no additional
102 formatting is applied.
103 """)
104
105 use_headers = Bool(True, config=True, help="""
106 Whether not a header should be added to the document.
107 """)
108
109 #Allow the user to override the title of the notebook (useful for
110 #fancy document titles that the file system doesn't support.)
111 overridetitle = Unicode("", config=True, help="")
112
113
114 def call(self, nb, resources):
115 """
116 Sphinx transformation to apply on each notebook.
117
118 Parameters
119 ----------
120 nb : NotebookNode
121 Notebook being converted
122 resources : dictionary
123 Additional resources used in the conversion process. Allows
124 transformers to pass variables into the Jinja engine.
125 """
126
127 # TODO: Add versatile method of additional notebook metadata. Include
128 # handling of multiple files. For now use a temporay namespace,
129 # '_draft' to signify that this needs to change.
130 if not "_draft" in nb.metadata:
131 nb.metadata._draft = {}
132
133 if not "sphinx" in resources:
134 resources["sphinx"] = {}
135
136 if self.interactive:
137
138 # Prompt the user for additional meta data that doesn't exist currently
139 # but would be usefull for Sphinx.
140 nb.metadata._draft["author"] = self._prompt_author()
141 nb.metadata._draft["version"] = self._prompt_version()
142 nb.metadata._draft["release"] = self._prompt_release()
143 nb.metadata._draft["date"] = self._prompt_date()
144
145 # Prompt the user for the document style.
146 resources["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
147 resources["sphinx"]["outputstyle"] = self._prompt_output_style()
148
149 # Small options
150 resources["sphinx"]["centeroutput"] = console.prompt_boolean("Do you want to center the output? (false)", False)
151 resources["sphinx"]["header"] = console.prompt_boolean("Should a Sphinx document header be used? (true)", True)
152 else:
153
154 # Try to use the traitlets.
155 nb.metadata._draft["author"] = self.author
156 nb.metadata._draft["version"] = self.version
157 nb.metadata._draft["release"] = self.release
158
159 # Use todays date if none is provided.
160 if len(self.publish_date.strip()) == 0:
161 nb.metadata._draft["date"] = date.today().strftime("%B %-d, %Y")
162 else:
163 nb.metadata._draft["date"] = self.publish_date
164
165 # Sphinx traitlets.
166 resources["sphinx"]["chapterstyle"] = self.chapter_style
167 resources["sphinx"]["outputstyle"] = self.output_style
168 resources["sphinx"]["centeroutput"] = self.center_output
169 resources["sphinx"]["header"] = self.use_headers
170
171 # Find and pass in the path to the Sphinx dependencies.
172 resources["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs")
173
174 # Generate Pygments definitions for Latex
175 resources["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
176
177 if not (self.overridetitle == None or len(self.overridetitle.strip()) == 0):
178 nb.metadata.name = self.overridetitle
179
180 # End
181 return nb, resources
182
183
184 def _generate_pygments_latex_def(self):
185 """
186 Generate the pygments latex definitions that allows pygments
187 to work in latex.
188 """
189
190 return LatexFormatter().get_style_defs()
191
192
193 def _prompt_author(self):
194 """
195 Prompt the user to input an Author name
196 """
197 return console.input("Author name: ")
198
199
200 def _prompt_version(self):
201 """
202 prompt the user to enter a version number
203 """
204 return console.input("Version (ie ""1.0.0""): ")
205
206
207 def _prompt_release(self):
208 """
209 Prompt the user to input a release name
210 """
211
212 return console.input("Release Name (ie ""Rough draft""): ")
213
214
215 def _prompt_date(self):
216 """
217 Prompt the user to enter a date
218 """
219
220 default_date = date.today().strftime("%B %-d, %Y")
221 user_date = console.input("Date (deafults to \"" + default_date + "\"): ")
222 if len(user_date.strip()) == 0:
223 user_date = default_date
224 return user_date
225
226
227 def _prompt_output_style(self):
228 """
229 Prompts the user to pick an IPython output style.
230 """
231
232 # Dictionary of available output styles
233 styles = {1: "simple",
234 2: "notebook"}
235
236 #Append comments to the menu when displaying it to the user.
237 comments = {1: "(recommended for long code segments)",
238 2: "(default)"}
239
240 return console.prompt_dictionary(styles, default_style=2, menu_comments=comments)
241
242
243 def _prompt_chapter_title_style(self):
244 """
245 Prompts the user to pick a Sphinx chapter style
246 """
247
248 # Dictionary of available Sphinx styles
249 styles = {1: "Bjarne",
250 2: "Lenny",
251 3: "Glenn",
252 4: "Conny",
253 5: "Rejne",
254 6: "Sonny"}
255
256 #Append comments to the menu when displaying it to the user.
257 comments = {1: "(default)",
258 6: "(for international documents)"}
259
260 return console.prompt_dictionary(styles, menu_comments=comments)
261
1 NO CONTENT: new file 100755
@@ -0,0 +1,37 b''
1 """Global configuration class."""
2 #-----------------------------------------------------------------------------
3 # Copyright (c) 2013, the IPython Development Team.
4 #
5 # Distributed under the terms of the Modified BSD License.
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 from IPython.utils.traitlets import List
15 from IPython.config.configurable import Configurable
16
17 #-----------------------------------------------------------------------------
18 # Classes and functions
19 #-----------------------------------------------------------------------------
20
21 class GlobalConfigurable(Configurable):
22 """Global configurable class for shared config
23
24 Usefull for display data priority that might be use by many trasnformers
25 """
26
27 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
28 config=True,
29 help= """
30 An ordered list of prefered output type, the first
31 encounterd will usually be used when converting discarding
32 the others.
33 """
34 )
35
36 def __init__(self, config=None, **kw):
37 super(GlobalConfigurable, self).__init__( config=config, **kw)
@@ -0,0 +1,120 b''
1 """Utility functions for interacting with the console"""
2 #-----------------------------------------------------------------------------
3 # Copyright (c) 2013, the IPython Development Team.
4 #
5 # Distributed under the terms of the Modified BSD License.
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 # Used to determine python version
15 import sys
16
17 #-----------------------------------------------------------------------------
18 # Classes and functions
19 #-----------------------------------------------------------------------------
20
21 def input(prompt_text):
22 """
23 Prompt the user for input.
24
25 The input command will change depending on the version of python
26 installed. To maintain support for 2 and earlier, we must use
27 raw_input in that case. Else use input.
28
29 Parameters
30 ----------
31 prompt_text : str
32 Prompt to display to the user.
33 """
34
35 # Try to get the python version. This command is only available in
36 # python 2 and later, so it's important that we catch the exception
37 # if the command isn't found.
38 try:
39 majorversion = sys.version_info[0]
40 except AttributeError:
41 majorversion = 1
42
43 # Use the correct function to prompt the user for input depending on
44 # what python version the code is running in.
45 if majorversion >= 3:
46 return input(prompt_text)
47 else:
48 return raw_input(prompt_text).decode(sys.stdin.encoding)
49
50
51 def prompt_boolean(prompt, default=False):
52 """
53 Prompt the user for a boolean response.
54
55 Parameters
56 ----------
57 prompt : str
58 prompt to display to the user
59 default : bool, optional
60 response to return if none is given by the user
61 """
62
63 response = input(prompt)
64 response = response.strip().lower()
65
66 #Catch 1, true, yes as True
67 if len(response) > 0 and (response == "1" or response[0] == "t" or response[0] == "y"):
68 return True
69
70 #Catch 0, false, no as False
71 elif len(response) > 0 and (response == "0" or response[0] == "f" or response[0] == "n"):
72 return False
73
74 else:
75 return default
76
77
78 def prompt_dictionary(choices, default_style=1, menu_comments={}):
79 """
80 Prompt the user to chose one of many selections from a menu.
81
82 Parameters
83 ----------
84 choices : dictionary
85 Keys - choice numbers (int)
86 Values - choice value (str), this is what the function will return
87 default_style : int, optional
88 Choice to select if the user doesn't respond
89 menu_comments : dictionary, optional
90 Additional comments to append to the menu as it is displayed
91 in the console.
92 Keys - choice numbers (int)
93 Values - comment (str), what will be appended to the
94 corresponding choice
95 """
96
97 # Build the menu that will be displayed to the user with
98 # all of the options available.
99 prompt = ""
100 for key, value in choices.iteritems():
101 prompt += "%d %s " % (key, value)
102 if key in menu_comments:
103 prompt += menu_comments[key]
104 prompt += "\n"
105
106 # Continue to ask the user for a style until an appropriate
107 # one is specified.
108 response = -1
109 while (not response in choices):
110 try:
111 text_response = input(prompt)
112
113 # Use default option if no input.
114 if len(text_response.strip()) == 0:
115 response = default_style
116 else:
117 response = int(text_response)
118 except ValueError:
119 print("Error: Value is not an available option. 0 selects the default.\n")
120 return choices[response]
@@ -0,0 +1,17 b''
1 """NbConvert specific exceptions"""
2 #-----------------------------------------------------------------------------
3 # Copyright (c) 2013, the IPython Development Team.
4 #
5 # Distributed under the terms of the Modified BSD License.
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Classes and functions
12 #-----------------------------------------------------------------------------
13
14 class ConversionException(Exception):
15 """An exception raised by the conversion process."""
16
17 pass No newline at end of file
@@ -0,0 +1,46 b''
1 """A custom pygments lexer for IPython code cells.
2
3 Informs The pygments highlighting library of the quirks of IPython's superset
4 of Python -- magic commands, !shell commands, etc.
5 """
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2013, the IPython Development Team.
8 #
9 # Distributed under the terms of the Modified BSD License.
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
13
14 #-----------------------------------------------------------------------------
15 # Imports
16 #-----------------------------------------------------------------------------
17
18 # Third-party imports
19 from pygments.lexers import PythonLexer, BashLexer
20 from pygments.lexer import bygroups, using
21 from pygments.token import Keyword, Operator, Text
22
23 #-----------------------------------------------------------------------------
24 # Class declarations
25 #-----------------------------------------------------------------------------
26
27 class IPythonLexer(PythonLexer):
28 """
29 Pygments Lexer for use with IPython code. Inherits from
30 PythonLexer and adds information about IPython specific
31 keywords (i.e. magic commands, shell commands, etc.)
32 """
33
34 #Basic properties
35 name = 'IPython'
36 aliases = ['ip', 'ipython']
37 filenames = ['*.ipy']
38
39 #Highlighting information
40 tokens = PythonLexer.tokens.copy()
41 tokens['root'] = [
42 (r'(\%+)(\w+)\s+(\.*)(\n)', bygroups(Operator, Keyword,
43 using(BashLexer), Text)),
44 (r'(\%+)(\w+)\b', bygroups(Operator, Keyword)),
45 (r'^(!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
46 ] + tokens['root']
@@ -1,395 +1,400 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 The :class:`~IPython.core.application.Application` object for the command
5 5 line :command:`ipython` program.
6 6
7 7 Authors
8 8 -------
9 9
10 10 * Brian Granger
11 11 * Fernando Perez
12 12 * Min Ragan-Kelley
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Copyright (C) 2008-2011 The IPython Development Team
17 17 #
18 18 # Distributed under the terms of the BSD License. The full license is in
19 19 # the file COPYING, distributed as part of this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26 from __future__ import absolute_import
27 27
28 28 import logging
29 29 import os
30 30 import sys
31 31
32 32 from IPython.config.loader import (
33 33 Config, PyFileConfigLoader, ConfigFileNotFound
34 34 )
35 35 from IPython.config.application import boolean_flag, catch_config_error
36 36 from IPython.core import release
37 37 from IPython.core import usage
38 38 from IPython.core.completer import IPCompleter
39 39 from IPython.core.crashhandler import CrashHandler
40 40 from IPython.core.formatters import PlainTextFormatter
41 41 from IPython.core.history import HistoryManager
42 42 from IPython.core.prompts import PromptManager
43 43 from IPython.core.application import (
44 44 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
45 45 )
46 46 from IPython.core.magics import ScriptMagics
47 47 from IPython.core.shellapp import (
48 48 InteractiveShellApp, shell_flags, shell_aliases
49 49 )
50 50 from IPython.terminal.interactiveshell import TerminalInteractiveShell
51 51 from IPython.utils import warn
52 52 from IPython.utils.path import get_ipython_dir, check_for_old_config
53 53 from IPython.utils.traitlets import (
54 54 Bool, List, Dict, CaselessStrEnum
55 55 )
56 56
57 57 #-----------------------------------------------------------------------------
58 58 # Globals, utilities and helpers
59 59 #-----------------------------------------------------------------------------
60 60
61 61 #: The default config file name for this application.
62 62 default_config_file_name = u'ipython_config.py'
63 63
64 64 _examples = """
65 65 ipython --pylab # start in pylab mode
66 66 ipython --pylab=qt # start in pylab mode with the qt4 backend
67 67 ipython --log-level=DEBUG # set logging to DEBUG
68 68 ipython --profile=foo # start with profile foo
69 69
70 70 ipython qtconsole # start the qtconsole GUI application
71 71 ipython help qtconsole # show the help for the qtconsole subcmd
72 72
73 73 ipython console # start the terminal-based console application
74 74 ipython help console # show the help for the console subcmd
75 75
76 76 ipython notebook # start the IPython notebook
77 77 ipython help notebook # show the help for the notebook subcmd
78 78
79 79 ipython profile create foo # create profile foo w/ default config files
80 80 ipython help profile # show the help for the profile subcmd
81 81
82 82 ipython locate # print the path to the IPython directory
83 83 ipython locate profile foo # print the path to the directory for profile `foo`
84
85 ipython nbconvert # convert notebooks to/from other formats
84 86 """
85 87
86 88 #-----------------------------------------------------------------------------
87 89 # Crash handler for this application
88 90 #-----------------------------------------------------------------------------
89 91
90 92 class IPAppCrashHandler(CrashHandler):
91 93 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
92 94
93 95 def __init__(self, app):
94 96 contact_name = release.author
95 97 contact_email = release.author_email
96 98 bug_tracker = 'https://github.com/ipython/ipython/issues'
97 99 super(IPAppCrashHandler,self).__init__(
98 100 app, contact_name, contact_email, bug_tracker
99 101 )
100 102
101 103 def make_report(self,traceback):
102 104 """Return a string containing a crash report."""
103 105
104 106 sec_sep = self.section_sep
105 107 # Start with parent report
106 108 report = [super(IPAppCrashHandler, self).make_report(traceback)]
107 109 # Add interactive-specific info we may have
108 110 rpt_add = report.append
109 111 try:
110 112 rpt_add(sec_sep+"History of session input:")
111 113 for line in self.app.shell.user_ns['_ih']:
112 114 rpt_add(line)
113 115 rpt_add('\n*** Last line of input (may not be in above history):\n')
114 116 rpt_add(self.app.shell._last_input_line+'\n')
115 117 except:
116 118 pass
117 119
118 120 return ''.join(report)
119 121
120 122 #-----------------------------------------------------------------------------
121 123 # Aliases and Flags
122 124 #-----------------------------------------------------------------------------
123 125 flags = dict(base_flags)
124 126 flags.update(shell_flags)
125 127 frontend_flags = {}
126 128 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
127 129 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
128 130 'Turn on auto editing of files with syntax errors.',
129 131 'Turn off auto editing of files with syntax errors.'
130 132 )
131 133 addflag('banner', 'TerminalIPythonApp.display_banner',
132 134 "Display a banner upon starting IPython.",
133 135 "Don't display a banner upon starting IPython."
134 136 )
135 137 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
136 138 """Set to confirm when you try to exit IPython with an EOF (Control-D
137 139 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
138 140 you can force a direct exit without any confirmation.""",
139 141 "Don't prompt the user when exiting."
140 142 )
141 143 addflag('term-title', 'TerminalInteractiveShell.term_title',
142 144 "Enable auto setting the terminal title.",
143 145 "Disable auto setting the terminal title."
144 146 )
145 147 classic_config = Config()
146 148 classic_config.InteractiveShell.cache_size = 0
147 149 classic_config.PlainTextFormatter.pprint = False
148 150 classic_config.PromptManager.in_template = '>>> '
149 151 classic_config.PromptManager.in2_template = '... '
150 152 classic_config.PromptManager.out_template = ''
151 153 classic_config.InteractiveShell.separate_in = ''
152 154 classic_config.InteractiveShell.separate_out = ''
153 155 classic_config.InteractiveShell.separate_out2 = ''
154 156 classic_config.InteractiveShell.colors = 'NoColor'
155 157 classic_config.InteractiveShell.xmode = 'Plain'
156 158
157 159 frontend_flags['classic']=(
158 160 classic_config,
159 161 "Gives IPython a similar feel to the classic Python prompt."
160 162 )
161 163 # # log doesn't make so much sense this way anymore
162 164 # paa('--log','-l',
163 165 # action='store_true', dest='InteractiveShell.logstart',
164 166 # help="Start logging to the default log file (./ipython_log.py).")
165 167 #
166 168 # # quick is harder to implement
167 169 frontend_flags['quick']=(
168 170 {'TerminalIPythonApp' : {'quick' : True}},
169 171 "Enable quick startup with no config files."
170 172 )
171 173
172 174 frontend_flags['i'] = (
173 175 {'TerminalIPythonApp' : {'force_interact' : True}},
174 176 """If running code from the command line, become interactive afterwards.
175 177 Note: can also be given simply as '-i.'"""
176 178 )
177 179 flags.update(frontend_flags)
178 180
179 181 aliases = dict(base_aliases)
180 182 aliases.update(shell_aliases)
181 183
182 184 #-----------------------------------------------------------------------------
183 185 # Main classes and functions
184 186 #-----------------------------------------------------------------------------
185 187
186 188
187 189 class LocateIPythonApp(BaseIPythonApplication):
188 190 description = """print the path to the IPython dir"""
189 191 subcommands = Dict(dict(
190 192 profile=('IPython.core.profileapp.ProfileLocate',
191 193 "print the path to an IPython profile directory",
192 194 ),
193 195 ))
194 196 def start(self):
195 197 if self.subapp is not None:
196 198 return self.subapp.start()
197 199 else:
198 200 print self.ipython_dir
199 201
200 202
201 203 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
202 204 name = u'ipython'
203 205 description = usage.cl_usage
204 206 default_config_file_name = default_config_file_name
205 207 crash_handler_class = IPAppCrashHandler
206 208 examples = _examples
207 209
208 210 flags = Dict(flags)
209 211 aliases = Dict(aliases)
210 212 classes = List()
211 213 def _classes_default(self):
212 214 """This has to be in a method, for TerminalIPythonApp to be available."""
213 215 return [
214 216 InteractiveShellApp, # ShellApp comes before TerminalApp, because
215 217 self.__class__, # it will also affect subclasses (e.g. QtConsole)
216 218 TerminalInteractiveShell,
217 219 PromptManager,
218 220 HistoryManager,
219 221 ProfileDir,
220 222 PlainTextFormatter,
221 223 IPCompleter,
222 224 ScriptMagics,
223 225 ]
224 226
225 227 subcommands = Dict(dict(
226 228 qtconsole=('IPython.qt.console.qtconsoleapp.IPythonQtConsoleApp',
227 229 """Launch the IPython Qt Console."""
228 230 ),
229 231 notebook=('IPython.html.notebookapp.NotebookApp',
230 232 """Launch the IPython HTML Notebook Server."""
231 233 ),
232 234 profile = ("IPython.core.profileapp.ProfileApp",
233 235 "Create and manage IPython profiles."
234 236 ),
235 237 kernel = ("IPython.kernel.zmq.kernelapp.IPKernelApp",
236 238 "Start a kernel without an attached frontend."
237 239 ),
238 240 console=('IPython.terminal.console.app.ZMQTerminalIPythonApp',
239 241 """Launch the IPython terminal-based Console."""
240 242 ),
241 243 locate=('IPython.terminal.ipapp.LocateIPythonApp',
242 244 LocateIPythonApp.description
243 245 ),
244 246 history=('IPython.core.historyapp.HistoryApp',
245 247 "Manage the IPython history database."
246 248 ),
249 nbconvert=('IPython.nbconvert.nbconvertapp.NbConvertApp',
250 "Convert notebooks to/from other formats."
251 ),
247 252 ))
248 253
249 254 # *do* autocreate requested profile, but don't create the config file.
250 255 auto_create=Bool(True)
251 256 # configurables
252 257 ignore_old_config=Bool(False, config=True,
253 258 help="Suppress warning messages about legacy config files"
254 259 )
255 260 quick = Bool(False, config=True,
256 261 help="""Start IPython quickly by skipping the loading of config files."""
257 262 )
258 263 def _quick_changed(self, name, old, new):
259 264 if new:
260 265 self.load_config_file = lambda *a, **kw: None
261 266 self.ignore_old_config=True
262 267
263 268 display_banner = Bool(True, config=True,
264 269 help="Whether to display a banner upon starting IPython."
265 270 )
266 271
267 272 # if there is code of files to run from the cmd line, don't interact
268 273 # unless the --i flag (App.force_interact) is true.
269 274 force_interact = Bool(False, config=True,
270 275 help="""If a command or file is given via the command-line,
271 276 e.g. 'ipython foo.py"""
272 277 )
273 278 def _force_interact_changed(self, name, old, new):
274 279 if new:
275 280 self.interact = True
276 281
277 282 def _file_to_run_changed(self, name, old, new):
278 283 if new:
279 284 self.something_to_run = True
280 285 if new and not self.force_interact:
281 286 self.interact = False
282 287 _code_to_run_changed = _file_to_run_changed
283 288 _module_to_run_changed = _file_to_run_changed
284 289
285 290 # internal, not-configurable
286 291 interact=Bool(True)
287 292 something_to_run=Bool(False)
288 293
289 294 def parse_command_line(self, argv=None):
290 295 """override to allow old '-pylab' flag with deprecation warning"""
291 296
292 297 argv = sys.argv[1:] if argv is None else argv
293 298
294 299 if '-pylab' in argv:
295 300 # deprecated `-pylab` given,
296 301 # warn and transform into current syntax
297 302 argv = argv[:] # copy, don't clobber
298 303 idx = argv.index('-pylab')
299 304 warn.warn("`-pylab` flag has been deprecated.\n"
300 305 " Use `--pylab` instead, or `--pylab=foo` to specify a backend.")
301 306 sub = '--pylab'
302 307 if len(argv) > idx+1:
303 308 # check for gui arg, as in '-pylab qt'
304 309 gui = argv[idx+1]
305 310 if gui in ('wx', 'qt', 'qt4', 'gtk', 'auto'):
306 311 sub = '--pylab='+gui
307 312 argv.pop(idx+1)
308 313 argv[idx] = sub
309 314
310 315 return super(TerminalIPythonApp, self).parse_command_line(argv)
311 316
312 317 @catch_config_error
313 318 def initialize(self, argv=None):
314 319 """Do actions after construct, but before starting the app."""
315 320 super(TerminalIPythonApp, self).initialize(argv)
316 321 if self.subapp is not None:
317 322 # don't bother initializing further, starting subapp
318 323 return
319 324 if not self.ignore_old_config:
320 325 check_for_old_config(self.ipython_dir)
321 326 # print self.extra_args
322 327 if self.extra_args and not self.something_to_run:
323 328 self.file_to_run = self.extra_args[0]
324 329 self.init_path()
325 330 # create the shell
326 331 self.init_shell()
327 332 # and draw the banner
328 333 self.init_banner()
329 334 # Now a variety of things that happen after the banner is printed.
330 335 self.init_gui_pylab()
331 336 self.init_extensions()
332 337 self.init_code()
333 338
334 339 def init_shell(self):
335 340 """initialize the InteractiveShell instance"""
336 341 # Create an InteractiveShell instance.
337 342 # shell.display_banner should always be False for the terminal
338 343 # based app, because we call shell.show_banner() by hand below
339 344 # so the banner shows *before* all extension loading stuff.
340 345 self.shell = TerminalInteractiveShell.instance(parent=self,
341 346 display_banner=False, profile_dir=self.profile_dir,
342 347 ipython_dir=self.ipython_dir)
343 348 self.shell.configurables.append(self)
344 349
345 350 def init_banner(self):
346 351 """optionally display the banner"""
347 352 if self.display_banner and self.interact:
348 353 self.shell.show_banner()
349 354 # Make sure there is a space below the banner.
350 355 if self.log_level <= logging.INFO: print
351 356
352 357 def _pylab_changed(self, name, old, new):
353 358 """Replace --pylab='inline' with --pylab='auto'"""
354 359 if new == 'inline':
355 360 warn.warn("'inline' not available as pylab backend, "
356 361 "using 'auto' instead.")
357 362 self.pylab = 'auto'
358 363
359 364 def start(self):
360 365 if self.subapp is not None:
361 366 return self.subapp.start()
362 367 # perform any prexec steps:
363 368 if self.interact:
364 369 self.log.debug("Starting IPython's mainloop...")
365 370 self.shell.mainloop()
366 371 else:
367 372 self.log.debug("IPython not interactive...")
368 373
369 374
370 375 def load_default_config(ipython_dir=None):
371 376 """Load the default config file from the default ipython_dir.
372 377
373 378 This is useful for embedded shells.
374 379 """
375 380 if ipython_dir is None:
376 381 ipython_dir = get_ipython_dir()
377 382 profile_dir = os.path.join(ipython_dir, 'profile_default')
378 383 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
379 384 try:
380 385 config = cl.load_config()
381 386 except ConfigFileNotFound:
382 387 # no config found
383 388 config = Config()
384 389 return config
385 390
386 391
387 392 def launch_new_instance():
388 393 """Create and run a full blown IPython instance"""
389 394 app = TerminalIPythonApp.instance()
390 395 app.initialize()
391 396 app.start()
392 397
393 398
394 399 if __name__ == '__main__':
395 400 launch_new_instance()
@@ -1,624 +1,632 b''
1 1 # -*- coding: utf-8 -*-
2 2 """IPython Test Suite Runner.
3 3
4 4 This module provides a main entry point to a user script to test IPython
5 5 itself from the command line. There are two ways of running this script:
6 6
7 7 1. With the syntax `iptest all`. This runs our entire test suite by
8 8 calling this script (with different arguments) recursively. This
9 9 causes modules and package to be tested in different processes, using nose
10 10 or trial where appropriate.
11 11 2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
12 12 the script simply calls nose, but with special command line flags and
13 13 plugins loaded.
14 14
15 15 """
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Copyright (C) 2009-2011 The IPython Development Team
19 19 #
20 20 # Distributed under the terms of the BSD License. The full license is in
21 21 # the file COPYING, distributed as part of this software.
22 22 #-----------------------------------------------------------------------------
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Imports
26 26 #-----------------------------------------------------------------------------
27 27 from __future__ import print_function
28 28
29 29 # Stdlib
30 30 import glob
31 31 import os
32 32 import os.path as path
33 33 import signal
34 34 import sys
35 35 import subprocess
36 36 import tempfile
37 37 import time
38 38 import warnings
39 39
40 40 # Note: monkeypatch!
41 41 # We need to monkeypatch a small problem in nose itself first, before importing
42 42 # it for actual use. This should get into nose upstream, but its release cycle
43 43 # is slow and we need it for our parametric tests to work correctly.
44 44 from IPython.testing import nosepatch
45 45
46 46 # Monkeypatch extra assert methods into nose.tools if they're not already there.
47 47 # This can be dropped once we no longer test on Python 2.6
48 48 from IPython.testing import nose_assert_methods
49 49
50 50 # Now, proceed to import nose itself
51 51 import nose.plugins.builtin
52 52 from nose.plugins.xunit import Xunit
53 53 from nose import SkipTest
54 54 from nose.core import TestProgram
55 55
56 56 # Our own imports
57 57 from IPython.utils import py3compat
58 58 from IPython.utils.importstring import import_item
59 59 from IPython.utils.path import get_ipython_module_path, get_ipython_package_dir
60 60 from IPython.utils.process import find_cmd, pycmd2argv
61 61 from IPython.utils.sysinfo import sys_info
62 62 from IPython.utils.tempdir import TemporaryDirectory
63 63 from IPython.utils.warn import warn
64 64
65 65 from IPython.testing import globalipapp
66 66 from IPython.testing.plugin.ipdoctest import IPythonDoctest
67 67 from IPython.external.decorators import KnownFailure, knownfailureif
68 68
69 69 pjoin = path.join
70 70
71 71
72 72 #-----------------------------------------------------------------------------
73 73 # Globals
74 74 #-----------------------------------------------------------------------------
75 75
76 76
77 77 #-----------------------------------------------------------------------------
78 78 # Warnings control
79 79 #-----------------------------------------------------------------------------
80 80
81 81 # Twisted generates annoying warnings with Python 2.6, as will do other code
82 82 # that imports 'sets' as of today
83 83 warnings.filterwarnings('ignore', 'the sets module is deprecated',
84 84 DeprecationWarning )
85 85
86 86 # This one also comes from Twisted
87 87 warnings.filterwarnings('ignore', 'the sha module is deprecated',
88 88 DeprecationWarning)
89 89
90 90 # Wx on Fedora11 spits these out
91 91 warnings.filterwarnings('ignore', 'wxPython/wxWidgets release number mismatch',
92 92 UserWarning)
93 93
94 94 # ------------------------------------------------------------------------------
95 95 # Monkeypatch Xunit to count known failures as skipped.
96 96 # ------------------------------------------------------------------------------
97 97 def monkeypatch_xunit():
98 98 try:
99 99 knownfailureif(True)(lambda: None)()
100 100 except Exception as e:
101 101 KnownFailureTest = type(e)
102 102
103 103 def addError(self, test, err, capt=None):
104 104 if issubclass(err[0], KnownFailureTest):
105 105 err = (SkipTest,) + err[1:]
106 106 return self.orig_addError(test, err, capt)
107 107
108 108 Xunit.orig_addError = Xunit.addError
109 109 Xunit.addError = addError
110 110
111 111 #-----------------------------------------------------------------------------
112 112 # Logic for skipping doctests
113 113 #-----------------------------------------------------------------------------
114 114 def extract_version(mod):
115 115 return mod.__version__
116 116
117 117 def test_for(item, min_version=None, callback=extract_version):
118 118 """Test to see if item is importable, and optionally check against a minimum
119 119 version.
120 120
121 121 If min_version is given, the default behavior is to check against the
122 122 `__version__` attribute of the item, but specifying `callback` allows you to
123 123 extract the value you are interested in. e.g::
124 124
125 125 In [1]: import sys
126 126
127 127 In [2]: from IPython.testing.iptest import test_for
128 128
129 129 In [3]: test_for('sys', (2,6), callback=lambda sys: sys.version_info)
130 130 Out[3]: True
131 131
132 132 """
133 133 try:
134 134 check = import_item(item)
135 135 except (ImportError, RuntimeError):
136 136 # GTK reports Runtime error if it can't be initialized even if it's
137 137 # importable.
138 138 return False
139 139 else:
140 140 if min_version:
141 141 if callback:
142 142 # extra processing step to get version to compare
143 143 check = callback(check)
144 144
145 145 return check >= min_version
146 146 else:
147 147 return True
148 148
149 149 # Global dict where we can store information on what we have and what we don't
150 150 # have available at test run time
151 151 have = {}
152 152
153 153 have['curses'] = test_for('_curses')
154 154 have['matplotlib'] = test_for('matplotlib')
155 155 have['numpy'] = test_for('numpy')
156 156 have['pexpect'] = test_for('IPython.external.pexpect')
157 157 have['pymongo'] = test_for('pymongo')
158 158 have['pygments'] = test_for('pygments')
159 159 have['qt'] = test_for('IPython.external.qt')
160 160 have['rpy2'] = test_for('rpy2')
161 161 have['sqlite3'] = test_for('sqlite3')
162 162 have['cython'] = test_for('Cython')
163 163 have['oct2py'] = test_for('oct2py')
164 164 have['tornado'] = test_for('tornado.version_info', (2,1,0), callback=None)
165 165 have['jinja2'] = test_for('jinja2')
166 166 have['wx'] = test_for('wx')
167 167 have['wx.aui'] = test_for('wx.aui')
168 168 have['azure'] = test_for('azure')
169 have['sphinx'] = test_for('sphinx')
170 have['markdown'] = test_for('markdown')
169 171
170 172 min_zmq = (2,1,11)
171 173
172 174 have['zmq'] = test_for('zmq.pyzmq_version_info', min_zmq, callback=lambda x: x())
173 175
174 176 #-----------------------------------------------------------------------------
175 177 # Functions and classes
176 178 #-----------------------------------------------------------------------------
177 179
178 180 def report():
179 181 """Return a string with a summary report of test-related variables."""
180 182
181 183 out = [ sys_info(), '\n']
182 184
183 185 avail = []
184 186 not_avail = []
185 187
186 188 for k, is_avail in have.items():
187 189 if is_avail:
188 190 avail.append(k)
189 191 else:
190 192 not_avail.append(k)
191 193
192 194 if avail:
193 195 out.append('\nTools and libraries available at test time:\n')
194 196 avail.sort()
195 197 out.append(' ' + ' '.join(avail)+'\n')
196 198
197 199 if not_avail:
198 200 out.append('\nTools and libraries NOT available at test time:\n')
199 201 not_avail.sort()
200 202 out.append(' ' + ' '.join(not_avail)+'\n')
201 203
202 204 return ''.join(out)
203 205
204 206
205 207 def make_exclude():
206 208 """Make patterns of modules and packages to exclude from testing.
207 209
208 210 For the IPythonDoctest plugin, we need to exclude certain patterns that
209 211 cause testing problems. We should strive to minimize the number of
210 212 skipped modules, since this means untested code.
211 213
212 214 These modules and packages will NOT get scanned by nose at all for tests.
213 215 """
214 216 # Simple utility to make IPython paths more readably, we need a lot of
215 217 # these below
216 218 ipjoin = lambda *paths: pjoin('IPython', *paths)
217 219
218 220 exclusions = [ipjoin('external'),
219 221 ipjoin('quarantine'),
220 222 ipjoin('deathrow'),
221 223 # This guy is probably attic material
222 224 ipjoin('testing', 'mkdoctests'),
223 225 # Testing inputhook will need a lot of thought, to figure out
224 226 # how to have tests that don't lock up with the gui event
225 227 # loops in the picture
226 228 ipjoin('lib', 'inputhook'),
227 229 # Config files aren't really importable stand-alone
228 230 ipjoin('config', 'profile'),
229 231 # The notebook 'static' directory contains JS, css and other
230 232 # files for web serving. Occasionally projects may put a .py
231 233 # file in there (MathJax ships a conf.py), so we might as
232 234 # well play it safe and skip the whole thing.
233 235 ipjoin('html', 'static'),
234 236 ipjoin('html', 'fabfile'),
235 237 ]
236 238 if not have['sqlite3']:
237 239 exclusions.append(ipjoin('core', 'tests', 'test_history'))
238 240 exclusions.append(ipjoin('core', 'history'))
239 241 if not have['wx']:
240 242 exclusions.append(ipjoin('lib', 'inputhookwx'))
241 243
242 244 if 'IPython.kernel.inprocess' not in sys.argv:
243 245 exclusions.append(ipjoin('kernel', 'inprocess'))
244 246
245 247 # FIXME: temporarily disable autoreload tests, as they can produce
246 248 # spurious failures in subsequent tests (cythonmagic).
247 249 exclusions.append(ipjoin('extensions', 'autoreload'))
248 250 exclusions.append(ipjoin('extensions', 'tests', 'test_autoreload'))
249 251
250 252 # We do this unconditionally, so that the test suite doesn't import
251 253 # gtk, changing the default encoding and masking some unicode bugs.
252 254 exclusions.append(ipjoin('lib', 'inputhookgtk'))
253 255 exclusions.append(ipjoin('kernel', 'zmq', 'gui', 'gtkembed'))
254 256
255 257 # These have to be skipped on win32 because the use echo, rm, cd, etc.
256 258 # See ticket https://github.com/ipython/ipython/issues/87
257 259 if sys.platform == 'win32':
258 260 exclusions.append(ipjoin('testing', 'plugin', 'test_exampleip'))
259 261 exclusions.append(ipjoin('testing', 'plugin', 'dtexample'))
260 262
261 263 if not have['pexpect']:
262 264 exclusions.extend([ipjoin('lib', 'irunner'),
263 265 ipjoin('lib', 'tests', 'test_irunner'),
264 266 ipjoin('terminal', 'console'),
265 267 ])
266 268
267 269 if not have['zmq']:
268 270 exclusions.append(ipjoin('kernel'))
269 271 exclusions.append(ipjoin('qt'))
270 272 exclusions.append(ipjoin('html'))
271 273 exclusions.append(ipjoin('consoleapp.py'))
272 274 exclusions.append(ipjoin('terminal', 'console'))
273 275 exclusions.append(ipjoin('parallel'))
274 276 elif not have['qt'] or not have['pygments']:
275 277 exclusions.append(ipjoin('qt'))
276 278
277 279 if not have['pymongo']:
278 280 exclusions.append(ipjoin('parallel', 'controller', 'mongodb'))
279 281 exclusions.append(ipjoin('parallel', 'tests', 'test_mongodb'))
280 282
281 283 if not have['matplotlib']:
282 284 exclusions.extend([ipjoin('core', 'pylabtools'),
283 285 ipjoin('core', 'tests', 'test_pylabtools'),
284 286 ipjoin('kernel', 'zmq', 'pylab'),
285 287 ])
286 288
287 289 if not have['cython']:
288 290 exclusions.extend([ipjoin('extensions', 'cythonmagic')])
289 291 exclusions.extend([ipjoin('extensions', 'tests', 'test_cythonmagic')])
290 292
291 293 if not have['oct2py']:
292 294 exclusions.extend([ipjoin('extensions', 'octavemagic')])
293 295 exclusions.extend([ipjoin('extensions', 'tests', 'test_octavemagic')])
294 296
295 297 if not have['tornado']:
296 298 exclusions.append(ipjoin('html'))
297 299
298 300 if not have['jinja2']:
299 301 exclusions.append(ipjoin('html', 'notebookapp'))
300 302
301 303 if not have['rpy2'] or not have['numpy']:
302 304 exclusions.append(ipjoin('extensions', 'rmagic'))
303 305 exclusions.append(ipjoin('extensions', 'tests', 'test_rmagic'))
304 306
305 307 if not have['azure']:
306 308 exclusions.append(ipjoin('html', 'services', 'notebooks', 'azurenbmanager'))
307 309
310 if not all((have['pygments'], have['jinja2'], have['markdown'], have['sphinx'])):
311 exclusions.append(ipjoin('nbconvert'))
312
308 313 # This is needed for the reg-exp to match on win32 in the ipdoctest plugin.
309 314 if sys.platform == 'win32':
310 315 exclusions = [s.replace('\\','\\\\') for s in exclusions]
311 316
312 317 # check for any exclusions that don't seem to exist:
313 318 parent, _ = os.path.split(get_ipython_package_dir())
314 319 for exclusion in exclusions:
315 320 if exclusion.endswith(('deathrow', 'quarantine')):
316 321 # ignore deathrow/quarantine, which exist in dev, but not install
317 322 continue
318 323 fullpath = pjoin(parent, exclusion)
319 324 if not os.path.exists(fullpath) and not glob.glob(fullpath + '.*'):
320 325 warn("Excluding nonexistent file: %r" % exclusion)
321 326
322 327 return exclusions
323 328
324 329
325 330 class IPTester(object):
326 331 """Call that calls iptest or trial in a subprocess.
327 332 """
328 333 #: string, name of test runner that will be called
329 334 runner = None
330 335 #: list, parameters for test runner
331 336 params = None
332 337 #: list, arguments of system call to be made to call test runner
333 338 call_args = None
334 339 #: list, subprocesses we start (for cleanup)
335 340 processes = None
336 341 #: str, coverage xml output file
337 342 coverage_xml = None
338 343
339 344 def __init__(self, runner='iptest', params=None):
340 345 """Create new test runner."""
341 346 p = os.path
342 347 if runner == 'iptest':
343 348 iptest_app = os.path.abspath(get_ipython_module_path('IPython.testing.iptest'))
344 349 self.runner = pycmd2argv(iptest_app) + sys.argv[1:]
345 350 else:
346 351 raise Exception('Not a valid test runner: %s' % repr(runner))
347 352 if params is None:
348 353 params = []
349 354 if isinstance(params, str):
350 355 params = [params]
351 356 self.params = params
352 357
353 358 # Assemble call
354 359 self.call_args = self.runner+self.params
355 360
356 361 # Find the section we're testing (IPython.foo)
357 362 for sect in self.params:
358 363 if sect.startswith('IPython') or sect in special_test_suites: break
359 364 else:
360 365 raise ValueError("Section not found", self.params)
361 366
362 367 if '--with-xunit' in self.call_args:
363 368
364 369 self.call_args.append('--xunit-file')
365 370 # FIXME: when Windows uses subprocess.call, these extra quotes are unnecessary:
366 371 xunit_file = path.abspath(sect+'.xunit.xml')
367 372 if sys.platform == 'win32':
368 373 xunit_file = '"%s"' % xunit_file
369 374 self.call_args.append(xunit_file)
370 375
371 376 if '--with-xml-coverage' in self.call_args:
372 377 self.coverage_xml = path.abspath(sect+".coverage.xml")
373 378 self.call_args.remove('--with-xml-coverage')
374 379 self.call_args = ["coverage", "run", "--source="+sect] + self.call_args[1:]
375 380
376 381 # Store anything we start to clean up on deletion
377 382 self.processes = []
378 383
379 384 def _run_cmd(self):
380 385 with TemporaryDirectory() as IPYTHONDIR:
381 386 env = os.environ.copy()
382 387 env['IPYTHONDIR'] = IPYTHONDIR
383 388 # print >> sys.stderr, '*** CMD:', ' '.join(self.call_args) # dbg
384 389 subp = subprocess.Popen(self.call_args, env=env)
385 390 self.processes.append(subp)
386 391 # If this fails, the process will be left in self.processes and
387 392 # cleaned up later, but if the wait call succeeds, then we can
388 393 # clear the stored process.
389 394 retcode = subp.wait()
390 395 self.processes.pop()
391 396 return retcode
392 397
393 398 def run(self):
394 399 """Run the stored commands"""
395 400 try:
396 401 retcode = self._run_cmd()
397 402 except KeyboardInterrupt:
398 403 return -signal.SIGINT
399 404 except:
400 405 import traceback
401 406 traceback.print_exc()
402 407 return 1 # signal failure
403 408
404 409 if self.coverage_xml:
405 410 subprocess.call(["coverage", "xml", "-o", self.coverage_xml])
406 411 return retcode
407 412
408 413 def __del__(self):
409 414 """Cleanup on exit by killing any leftover processes."""
410 415 for subp in self.processes:
411 416 if subp.poll() is not None:
412 417 continue # process is already dead
413 418
414 419 try:
415 420 print('Cleaning up stale PID: %d' % subp.pid)
416 421 subp.kill()
417 422 except: # (OSError, WindowsError) ?
418 423 # This is just a best effort, if we fail or the process was
419 424 # really gone, ignore it.
420 425 pass
421 426 else:
422 427 for i in range(10):
423 428 if subp.poll() is None:
424 429 time.sleep(0.1)
425 430 else:
426 431 break
427 432
428 433 if subp.poll() is None:
429 434 # The process did not die...
430 435 print('... failed. Manual cleanup may be required.')
431 436
432 437
433 438 special_test_suites = {
434 439 'autoreload': ['IPython.extensions.autoreload', 'IPython.extensions.tests.test_autoreload'],
435 440 }
436 441
437 442 def make_runners(inc_slow=False):
438 443 """Define the top-level packages that need to be tested.
439 444 """
440 445
441 446 # Packages to be tested via nose, that only depend on the stdlib
442 447 nose_pkg_names = ['config', 'core', 'extensions', 'lib', 'terminal',
443 448 'testing', 'utils', 'nbformat' ]
444 449
445 450 if have['qt']:
446 451 nose_pkg_names.append('qt')
447 452
448 453 if have['tornado']:
449 454 nose_pkg_names.append('html')
450 455
451 456 if have['zmq']:
452 457 nose_pkg_names.append('kernel')
453 458 nose_pkg_names.append('kernel.inprocess')
454 459 if inc_slow:
455 460 nose_pkg_names.append('parallel')
456 461
462 if all((have['pygments'], have['jinja2'], have['markdown'], have['sphinx'])):
463 nose_pkg_names.append('nbconvert')
464
457 465 # For debugging this code, only load quick stuff
458 466 #nose_pkg_names = ['core', 'extensions'] # dbg
459 467
460 468 # Make fully qualified package names prepending 'IPython.' to our name lists
461 469 nose_packages = ['IPython.%s' % m for m in nose_pkg_names ]
462 470
463 471 # Make runners
464 472 runners = [ (v, IPTester('iptest', params=v)) for v in nose_packages ]
465 473
466 474 for name in special_test_suites:
467 475 runners.append((name, IPTester('iptest', params=name)))
468 476
469 477 return runners
470 478
471 479
472 480 def run_iptest():
473 481 """Run the IPython test suite using nose.
474 482
475 483 This function is called when this script is **not** called with the form
476 484 `iptest all`. It simply calls nose with appropriate command line flags
477 485 and accepts all of the standard nose arguments.
478 486 """
479 487 # Apply our monkeypatch to Xunit
480 488 if '--with-xunit' in sys.argv and not hasattr(Xunit, 'orig_addError'):
481 489 monkeypatch_xunit()
482 490
483 491 warnings.filterwarnings('ignore',
484 492 'This will be removed soon. Use IPython.testing.util instead')
485 493
486 494 if sys.argv[1] in special_test_suites:
487 495 sys.argv[1:2] = special_test_suites[sys.argv[1]]
488 496 special_suite = True
489 497 else:
490 498 special_suite = False
491 499
492 500 argv = sys.argv + [ '--detailed-errors', # extra info in tracebacks
493 501
494 502 '--with-ipdoctest',
495 503 '--ipdoctest-tests','--ipdoctest-extension=txt',
496 504
497 505 # We add --exe because of setuptools' imbecility (it
498 506 # blindly does chmod +x on ALL files). Nose does the
499 507 # right thing and it tries to avoid executables,
500 508 # setuptools unfortunately forces our hand here. This
501 509 # has been discussed on the distutils list and the
502 510 # setuptools devs refuse to fix this problem!
503 511 '--exe',
504 512 ]
505 513 if '-a' not in argv and '-A' not in argv:
506 514 argv = argv + ['-a', '!crash']
507 515
508 516 if nose.__version__ >= '0.11':
509 517 # I don't fully understand why we need this one, but depending on what
510 518 # directory the test suite is run from, if we don't give it, 0 tests
511 519 # get run. Specifically, if the test suite is run from the source dir
512 520 # with an argument (like 'iptest.py IPython.core', 0 tests are run,
513 521 # even if the same call done in this directory works fine). It appears
514 522 # that if the requested package is in the current dir, nose bails early
515 523 # by default. Since it's otherwise harmless, leave it in by default
516 524 # for nose >= 0.11, though unfortunately nose 0.10 doesn't support it.
517 525 argv.append('--traverse-namespace')
518 526
519 527 # use our plugin for doctesting. It will remove the standard doctest plugin
520 528 # if it finds it enabled
521 529 ipdt = IPythonDoctest() if special_suite else IPythonDoctest(make_exclude())
522 530 plugins = [ipdt, KnownFailure()]
523 531
524 532 # We need a global ipython running in this process, but the special
525 533 # in-process group spawns its own IPython kernels, so for *that* group we
526 534 # must avoid also opening the global one (otherwise there's a conflict of
527 535 # singletons). Ultimately the solution to this problem is to refactor our
528 536 # assumptions about what needs to be a singleton and what doesn't (app
529 537 # objects should, individual shells shouldn't). But for now, this
530 538 # workaround allows the test suite for the inprocess module to complete.
531 539 if not 'IPython.kernel.inprocess' in sys.argv:
532 540 globalipapp.start_ipython()
533 541
534 542 # Now nose can run
535 543 TestProgram(argv=argv, addplugins=plugins)
536 544
537 545
538 546 def run_iptestall(inc_slow=False):
539 547 """Run the entire IPython test suite by calling nose and trial.
540 548
541 549 This function constructs :class:`IPTester` instances for all IPython
542 550 modules and package and then runs each of them. This causes the modules
543 551 and packages of IPython to be tested each in their own subprocess using
544 552 nose.
545 553
546 554 Parameters
547 555 ----------
548 556
549 557 inc_slow : bool, optional
550 558 Include slow tests, like IPython.parallel. By default, these tests aren't
551 559 run.
552 560 """
553 561
554 562 runners = make_runners(inc_slow=inc_slow)
555 563
556 564 # Run the test runners in a temporary dir so we can nuke it when finished
557 565 # to clean up any junk files left over by accident. This also makes it
558 566 # robust against being run in non-writeable directories by mistake, as the
559 567 # temp dir will always be user-writeable.
560 568 curdir = os.getcwdu()
561 569 testdir = tempfile.gettempdir()
562 570 os.chdir(testdir)
563 571
564 572 # Run all test runners, tracking execution time
565 573 failed = []
566 574 t_start = time.time()
567 575 try:
568 576 for (name, runner) in runners:
569 577 print('*'*70)
570 578 print('IPython test group:',name)
571 579 res = runner.run()
572 580 if res:
573 581 failed.append( (name, runner) )
574 582 if res == -signal.SIGINT:
575 583 print("Interrupted")
576 584 break
577 585 finally:
578 586 os.chdir(curdir)
579 587 t_end = time.time()
580 588 t_tests = t_end - t_start
581 589 nrunners = len(runners)
582 590 nfail = len(failed)
583 591 # summarize results
584 592 print()
585 593 print('*'*70)
586 594 print('Test suite completed for system with the following information:')
587 595 print(report())
588 596 print('Ran %s test groups in %.3fs' % (nrunners, t_tests))
589 597 print()
590 598 print('Status:')
591 599 if not failed:
592 600 print('OK')
593 601 else:
594 602 # If anything went wrong, point out what command to rerun manually to
595 603 # see the actual errors and individual summary
596 604 print('ERROR - %s out of %s test groups failed.' % (nfail, nrunners))
597 605 for name, failed_runner in failed:
598 606 print('-'*40)
599 607 print('Runner failed:',name)
600 608 print('You may wish to rerun this one individually, with:')
601 609 failed_call_args = [py3compat.cast_unicode(x) for x in failed_runner.call_args]
602 610 print(u' '.join(failed_call_args))
603 611 print()
604 612 # Ensure that our exit code indicates failure
605 613 sys.exit(1)
606 614
607 615
608 616 def main():
609 617 for arg in sys.argv[1:]:
610 618 if arg.startswith('IPython') or arg in special_test_suites:
611 619 # This is in-process
612 620 run_iptest()
613 621 else:
614 622 if "--all" in sys.argv:
615 623 sys.argv.remove("--all")
616 624 inc_slow = True
617 625 else:
618 626 inc_slow = False
619 627 # This starts subprocesses
620 628 run_iptestall(inc_slow=inc_slow)
621 629
622 630
623 631 if __name__ == '__main__':
624 632 main()
@@ -1,347 +1,348 b''
1 1 #!/usr/bin/env python
2 2 # -*- coding: utf-8 -*-
3 3 """Setup script for IPython.
4 4
5 5 Under Posix environments it works like a typical setup.py script.
6 6 Under Windows, the command sdist is not supported, since IPython
7 7 requires utilities which are not available under Windows."""
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (c) 2008-2011, IPython Development Team.
11 11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 14 #
15 15 # Distributed under the terms of the Modified BSD License.
16 16 #
17 17 # The full license is in the file COPYING.txt, distributed with this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Minimal Python version sanity check
22 22 #-----------------------------------------------------------------------------
23 23 from __future__ import print_function
24 24
25 25 import sys
26 26
27 27 # This check is also made in IPython/__init__, don't forget to update both when
28 28 # changing Python version requirements.
29 29 #~ if sys.version[0:3] < '2.6':
30 30 #~ error = """\
31 31 #~ ERROR: 'IPython requires Python Version 2.6 or above.'
32 32 #~ Exiting."""
33 33 #~ print >> sys.stderr, error
34 34 #~ sys.exit(1)
35 35
36 36 PY3 = (sys.version_info[0] >= 3)
37 37
38 38 # At least we're on the python version we need, move on.
39 39
40 40 #-------------------------------------------------------------------------------
41 41 # Imports
42 42 #-------------------------------------------------------------------------------
43 43
44 44 # Stdlib imports
45 45 import os
46 46 import shutil
47 47
48 48 from glob import glob
49 49
50 50 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
51 51 # update it when the contents of directories change.
52 52 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
53 53
54 54 from distutils.core import setup
55 55
56 56 # On Python 3, we need distribute (new setuptools) to do the 2to3 conversion
57 57 if PY3:
58 58 import setuptools
59 59
60 60 # Our own imports
61 61 from setupbase import target_update
62 62
63 63 from setupbase import (
64 64 setup_args,
65 65 find_packages,
66 66 find_package_data,
67 67 find_scripts,
68 68 find_data_files,
69 69 check_for_dependencies,
70 70 git_prebuild,
71 71 check_submodule_status,
72 72 update_submodules,
73 73 require_submodules,
74 74 UpdateSubmodules,
75 75 )
76 76 from setupext import setupext
77 77
78 78 isfile = os.path.isfile
79 79 pjoin = os.path.join
80 80
81 81 #-----------------------------------------------------------------------------
82 82 # Function definitions
83 83 #-----------------------------------------------------------------------------
84 84
85 85 def cleanup():
86 86 """Clean up the junk left around by the build process"""
87 87 if "develop" not in sys.argv and "egg_info" not in sys.argv:
88 88 try:
89 89 shutil.rmtree('ipython.egg-info')
90 90 except:
91 91 try:
92 92 os.unlink('ipython.egg-info')
93 93 except:
94 94 pass
95 95
96 96 #-------------------------------------------------------------------------------
97 97 # Handle OS specific things
98 98 #-------------------------------------------------------------------------------
99 99
100 100 if os.name in ('nt','dos'):
101 101 os_name = 'windows'
102 102 else:
103 103 os_name = os.name
104 104
105 105 # Under Windows, 'sdist' has not been supported. Now that the docs build with
106 106 # Sphinx it might work, but let's not turn it on until someone confirms that it
107 107 # actually works.
108 108 if os_name == 'windows' and 'sdist' in sys.argv:
109 109 print('The sdist command is not available under Windows. Exiting.')
110 110 sys.exit(1)
111 111
112 112 #-------------------------------------------------------------------------------
113 113 # Make sure we aren't trying to run without submodules
114 114 #-------------------------------------------------------------------------------
115 115 here = os.path.abspath(os.path.dirname(__file__))
116 116
117 117 def require_clean_submodules():
118 118 """Check on git submodules before distutils can do anything
119 119
120 120 Since distutils cannot be trusted to update the tree
121 121 after everything has been set in motion,
122 122 this is not a distutils command.
123 123 """
124 124 # PACKAGERS: Add a return here to skip checks for git submodules
125 125
126 126 # don't do anything if nothing is actually supposed to happen
127 127 for do_nothing in ('-h', '--help', '--help-commands', 'clean', 'submodule'):
128 128 if do_nothing in sys.argv:
129 129 return
130 130
131 131 status = check_submodule_status(here)
132 132
133 133 if status == "missing":
134 134 print("checking out submodules for the first time")
135 135 update_submodules(here)
136 136 elif status == "unclean":
137 137 print('\n'.join([
138 138 "Cannot build / install IPython with unclean submodules",
139 139 "Please update submodules with",
140 140 " python setup.py submodule",
141 141 "or",
142 142 " git submodule update",
143 143 "or commit any submodule changes you have made."
144 144 ]))
145 145 sys.exit(1)
146 146
147 147 require_clean_submodules()
148 148
149 149 #-------------------------------------------------------------------------------
150 150 # Things related to the IPython documentation
151 151 #-------------------------------------------------------------------------------
152 152
153 153 # update the manuals when building a source dist
154 154 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
155 155 import textwrap
156 156
157 157 # List of things to be updated. Each entry is a triplet of args for
158 158 # target_update()
159 159 to_update = [
160 160 # FIXME - Disabled for now: we need to redo an automatic way
161 161 # of generating the magic info inside the rst.
162 162 #('docs/magic.tex',
163 163 #['IPython/Magic.py'],
164 164 #"cd doc && ./update_magic.sh" ),
165 165
166 166 ('docs/man/ipcluster.1.gz',
167 167 ['docs/man/ipcluster.1'],
168 168 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
169 169
170 170 ('docs/man/ipcontroller.1.gz',
171 171 ['docs/man/ipcontroller.1'],
172 172 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
173 173
174 174 ('docs/man/ipengine.1.gz',
175 175 ['docs/man/ipengine.1'],
176 176 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
177 177
178 178 ('docs/man/iplogger.1.gz',
179 179 ['docs/man/iplogger.1'],
180 180 'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
181 181
182 182 ('docs/man/ipython.1.gz',
183 183 ['docs/man/ipython.1'],
184 184 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
185 185
186 186 ('docs/man/irunner.1.gz',
187 187 ['docs/man/irunner.1'],
188 188 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
189 189
190 190 ('docs/man/pycolor.1.gz',
191 191 ['docs/man/pycolor.1'],
192 192 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
193 193 ]
194 194
195 195
196 196 [ target_update(*t) for t in to_update ]
197 197
198 198 #---------------------------------------------------------------------------
199 199 # Find all the packages, package data, and data_files
200 200 #---------------------------------------------------------------------------
201 201
202 202 packages = find_packages()
203 203 package_data = find_package_data()
204 204 data_files = find_data_files()
205 205
206 206 setup_args['packages'] = packages
207 207 setup_args['package_data'] = package_data
208 208 setup_args['data_files'] = data_files
209 209
210 210 #---------------------------------------------------------------------------
211 211 # custom distutils commands
212 212 #---------------------------------------------------------------------------
213 213 # imports here, so they are after setuptools import if there was one
214 214 from distutils.command.sdist import sdist
215 215 from distutils.command.upload import upload
216 216
217 217 class UploadWindowsInstallers(upload):
218 218
219 219 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
220 220 user_options = upload.user_options + [
221 221 ('files=', 'f', 'exe file (or glob) to upload')
222 222 ]
223 223 def initialize_options(self):
224 224 upload.initialize_options(self)
225 225 meta = self.distribution.metadata
226 226 base = '{name}-{version}'.format(
227 227 name=meta.get_name(),
228 228 version=meta.get_version()
229 229 )
230 230 self.files = os.path.join('dist', '%s.*.exe' % base)
231 231
232 232 def run(self):
233 233 for dist_file in glob(self.files):
234 234 self.upload_file('bdist_wininst', 'any', dist_file)
235 235
236 236 setup_args['cmdclass'] = {
237 237 'build_py': git_prebuild('IPython'),
238 238 'sdist' : git_prebuild('IPython', sdist),
239 239 'upload_wininst' : UploadWindowsInstallers,
240 240 'submodule' : UpdateSubmodules,
241 241 }
242 242
243 243 #---------------------------------------------------------------------------
244 244 # Handle scripts, dependencies, and setuptools specific things
245 245 #---------------------------------------------------------------------------
246 246
247 247 # For some commands, use setuptools. Note that we do NOT list install here!
248 248 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
249 249 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
250 250 'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
251 251 'egg_info', 'easy_install', 'upload',
252 252 ))
253 253 if sys.platform == 'win32':
254 254 # Depend on setuptools for install on *Windows only*
255 255 # If we get script-installation working without setuptools,
256 256 # then we can back off, but until then use it.
257 257 # See Issue #369 on GitHub for more
258 258 needs_setuptools.add('install')
259 259
260 260 if len(needs_setuptools.intersection(sys.argv)) > 0:
261 261 import setuptools
262 262
263 263 # This dict is used for passing extra arguments that are setuptools
264 264 # specific to setup
265 265 setuptools_extra_args = {}
266 266
267 267 if 'setuptools' in sys.modules:
268 268 # setup.py develop should check for submodules
269 269 from setuptools.command.develop import develop
270 270 setup_args['cmdclass']['develop'] = require_submodules(develop)
271 271
272 272 setuptools_extra_args['zip_safe'] = False
273 273 setuptools_extra_args['entry_points'] = find_scripts(True)
274 274 setup_args['extras_require'] = dict(
275 275 parallel = 'pyzmq>=2.1.11',
276 276 qtconsole = ['pyzmq>=2.1.11', 'pygments'],
277 277 zmq = 'pyzmq>=2.1.11',
278 278 doc = 'Sphinx>=0.3',
279 279 test = 'nose>=0.10.1',
280 280 notebook = ['tornado>=2.0', 'pyzmq>=2.1.11', 'jinja2'],
281 nbconvert = ['pygments', 'markdown', 'jinja2', 'Sphinx>=0.3']
281 282 )
282 283 requires = setup_args.setdefault('install_requires', [])
283 284 setupext.display_status = False
284 285 if not setupext.check_for_readline():
285 286 if sys.platform == 'darwin':
286 287 requires.append('readline')
287 288 elif sys.platform.startswith('win'):
288 289 # Pyreadline 64 bit windows issue solved in versions >=1.7.1
289 290 # Also solves issues with some older versions of pyreadline that
290 291 # satisfy the unconstrained depdendency.
291 292 requires.append('pyreadline>=1.7.1')
292 293 else:
293 294 pass
294 295 # do we want to install readline here?
295 296
296 297 # Script to be run by the windows binary installer after the default setup
297 298 # routine, to add shortcuts and similar windows-only things. Windows
298 299 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
299 300 # doesn't find them.
300 301 if 'bdist_wininst' in sys.argv:
301 302 if len(sys.argv) > 2 and \
302 303 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
303 304 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
304 305 sys.exit(1)
305 306 setup_args['data_files'].append(
306 307 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
307 308 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
308 309 setup_args['options'] = {"bdist_wininst":
309 310 {"install_script":
310 311 "ipython_win_post_install.py"}}
311 312
312 313 if PY3:
313 314 setuptools_extra_args['use_2to3'] = True
314 315 # we try to make a 2.6, 2.7, and 3.1 to 3.3 python compatible code
315 316 # so we explicitly disable some 2to3 fixes to be sure we aren't forgetting
316 317 # anything.
317 318 setuptools_extra_args['use_2to3_exclude_fixers'] = [
318 319 'lib2to3.fixes.fix_apply',
319 320 'lib2to3.fixes.fix_except',
320 321 'lib2to3.fixes.fix_has_key',
321 322 'lib2to3.fixes.fix_next',
322 323 'lib2to3.fixes.fix_repr',
323 324 'lib2to3.fixes.fix_tuple_params',
324 325 ]
325 326 from setuptools.command.build_py import build_py
326 327 setup_args['cmdclass'] = {'build_py': git_prebuild('IPython', build_cmd=build_py)}
327 328 setuptools_extra_args['entry_points'] = find_scripts(True, suffix='3')
328 329 setuptools._dont_write_bytecode = True
329 330 else:
330 331 # If we are running without setuptools, call this function which will
331 332 # check for dependencies an inform the user what is needed. This is
332 333 # just to make life easy for users.
333 334 check_for_dependencies()
334 335 setup_args['scripts'] = find_scripts(False)
335 336
336 337 #---------------------------------------------------------------------------
337 338 # Do the actual setup now
338 339 #---------------------------------------------------------------------------
339 340
340 341 setup_args.update(setuptools_extra_args)
341 342
342 343 def main():
343 344 setup(**setup_args)
344 345 cleanup()
345 346
346 347 if __name__ == '__main__':
347 348 main()
@@ -1,469 +1,474 b''
1 1 # encoding: utf-8
2 2 """
3 3 This module defines the things that are used in setup.py for building IPython
4 4
5 5 This includes:
6 6
7 7 * The basic arguments to setup
8 8 * Functions for finding things like packages, package data, etc.
9 9 * A function for checking dependencies.
10 10 """
11 11 from __future__ import print_function
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import os
24 24 import sys
25 25
26 26 try:
27 27 from configparser import ConfigParser
28 28 except:
29 29 from ConfigParser import ConfigParser
30 30 from distutils.command.build_py import build_py
31 31 from distutils.cmd import Command
32 32 from glob import glob
33 33
34 34 from setupext import install_data_ext
35 35
36 36 #-------------------------------------------------------------------------------
37 37 # Useful globals and utility functions
38 38 #-------------------------------------------------------------------------------
39 39
40 40 # A few handy globals
41 41 isfile = os.path.isfile
42 42 pjoin = os.path.join
43 43 repo_root = os.path.dirname(os.path.abspath(__file__))
44 44
45 45 def oscmd(s):
46 46 print(">", s)
47 47 os.system(s)
48 48
49 49 # Py3 compatibility hacks, without assuming IPython itself is installed with
50 50 # the full py3compat machinery.
51 51
52 52 try:
53 53 execfile
54 54 except NameError:
55 55 def execfile(fname, globs, locs=None):
56 56 locs = locs or globs
57 57 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
58 58
59 59 # A little utility we'll need below, since glob() does NOT allow you to do
60 60 # exclusion on multiple endings!
61 61 def file_doesnt_endwith(test,endings):
62 62 """Return true if test is a file and its name does NOT end with any
63 63 of the strings listed in endings."""
64 64 if not isfile(test):
65 65 return False
66 66 for e in endings:
67 67 if test.endswith(e):
68 68 return False
69 69 return True
70 70
71 71 #---------------------------------------------------------------------------
72 72 # Basic project information
73 73 #---------------------------------------------------------------------------
74 74
75 75 # release.py contains version, authors, license, url, keywords, etc.
76 76 execfile(pjoin(repo_root, 'IPython','core','release.py'), globals())
77 77
78 78 # Create a dict with the basic information
79 79 # This dict is eventually passed to setup after additional keys are added.
80 80 setup_args = dict(
81 81 name = name,
82 82 version = version,
83 83 description = description,
84 84 long_description = long_description,
85 85 author = author,
86 86 author_email = author_email,
87 87 url = url,
88 88 download_url = download_url,
89 89 license = license,
90 90 platforms = platforms,
91 91 keywords = keywords,
92 92 classifiers = classifiers,
93 93 cmdclass = {'install_data': install_data_ext},
94 94 )
95 95
96 96
97 97 #---------------------------------------------------------------------------
98 98 # Find packages
99 99 #---------------------------------------------------------------------------
100 100
101 101 def find_packages():
102 102 """
103 103 Find all of IPython's packages.
104 104 """
105 105 excludes = ['deathrow', 'quarantine']
106 106 packages = []
107 107 for dir,subdirs,files in os.walk('IPython'):
108 108 package = dir.replace(os.path.sep, '.')
109 109 if any(package.startswith('IPython.'+exc) for exc in excludes):
110 110 # package is to be excluded (e.g. deathrow)
111 111 continue
112 112 if '__init__.py' not in files:
113 113 # not a package
114 114 continue
115 115 packages.append(package)
116 116 return packages
117 117
118 118 #---------------------------------------------------------------------------
119 119 # Find package data
120 120 #---------------------------------------------------------------------------
121 121
122 122 def find_package_data():
123 123 """
124 124 Find IPython's package_data.
125 125 """
126 126 # This is not enough for these things to appear in an sdist.
127 127 # We need to muck with the MANIFEST to get this to work
128 128
129 129 # exclude static things that we don't ship (e.g. mathjax)
130 130 excludes = ['mathjax']
131 131
132 132 # add 'static/' prefix to exclusions, and tuplify for use in startswith
133 133 excludes = tuple([os.path.join('static', ex) for ex in excludes])
134 134
135 135 # walk notebook resources:
136 136 cwd = os.getcwd()
137 137 os.chdir(os.path.join('IPython', 'html'))
138 138 static_walk = list(os.walk('static'))
139 139 os.chdir(cwd)
140 140 static_data = []
141 141 for parent, dirs, files in static_walk:
142 142 if parent.startswith(excludes):
143 143 continue
144 144 for f in files:
145 145 static_data.append(os.path.join(parent, f))
146 146
147 147 package_data = {
148 148 'IPython.config.profile' : ['README*', '*/*.py'],
149 149 'IPython.core.tests' : ['*.png', '*.jpg'],
150 150 'IPython.testing' : ['*.txt'],
151 151 'IPython.testing.plugin' : ['*.txt'],
152 152 'IPython.html' : ['templates/*'] + static_data,
153 153 'IPython.qt.console' : ['resources/icon/*.svg'],
154 'IPython.nbconvert.templates' : ['*.tpl', 'latex/*.tpl',
155 'latex/skeleton/*.tplx', 'skeleton/*']
154 156 }
155 157 return package_data
156 158
157 159
158 160 #---------------------------------------------------------------------------
159 161 # Find data files
160 162 #---------------------------------------------------------------------------
161 163
162 164 def make_dir_struct(tag,base,out_base):
163 165 """Make the directory structure of all files below a starting dir.
164 166
165 167 This is just a convenience routine to help build a nested directory
166 168 hierarchy because distutils is too stupid to do this by itself.
167 169
168 170 XXX - this needs a proper docstring!
169 171 """
170 172
171 173 # we'll use these a lot below
172 174 lbase = len(base)
173 175 pathsep = os.path.sep
174 176 lpathsep = len(pathsep)
175 177
176 178 out = []
177 179 for (dirpath,dirnames,filenames) in os.walk(base):
178 180 # we need to strip out the dirpath from the base to map it to the
179 181 # output (installation) path. This requires possibly stripping the
180 182 # path separator, because otherwise pjoin will not work correctly
181 183 # (pjoin('foo/','/bar') returns '/bar').
182 184
183 185 dp_eff = dirpath[lbase:]
184 186 if dp_eff.startswith(pathsep):
185 187 dp_eff = dp_eff[lpathsep:]
186 188 # The output path must be anchored at the out_base marker
187 189 out_path = pjoin(out_base,dp_eff)
188 190 # Now we can generate the final filenames. Since os.walk only produces
189 191 # filenames, we must join back with the dirpath to get full valid file
190 192 # paths:
191 193 pfiles = [pjoin(dirpath,f) for f in filenames]
192 194 # Finally, generate the entry we need, which is a pari of (output
193 195 # path, files) for use as a data_files parameter in install_data.
194 196 out.append((out_path, pfiles))
195 197
196 198 return out
197 199
198 200
199 201 def find_data_files():
200 202 """
201 203 Find IPython's data_files.
202 204
203 205 Most of these are docs.
204 206 """
205 207
206 208 docdirbase = pjoin('share', 'doc', 'ipython')
207 209 manpagebase = pjoin('share', 'man', 'man1')
208 210
209 211 # Simple file lists can be made by hand
210 212 manpages = [f for f in glob(pjoin('docs','man','*.1.gz')) if isfile(f)]
211 213 if not manpages:
212 214 # When running from a source tree, the manpages aren't gzipped
213 215 manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)]
214 216
215 217 igridhelpfiles = [f for f in glob(pjoin('IPython','extensions','igrid_help.*')) if isfile(f)]
216 218
217 219 # For nested structures, use the utility above
218 220 example_files = make_dir_struct(
219 221 'data',
220 222 pjoin('docs','examples'),
221 223 pjoin(docdirbase,'examples')
222 224 )
223 225 manual_files = make_dir_struct(
224 226 'data',
225 227 pjoin('docs','html'),
226 228 pjoin(docdirbase,'manual')
227 229 )
228 230
229 231 # And assemble the entire output list
230 232 data_files = [ (manpagebase, manpages),
231 233 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
232 234 ] + manual_files + example_files
233 235
234 236 return data_files
235 237
236 238
237 239 def make_man_update_target(manpage):
238 240 """Return a target_update-compliant tuple for the given manpage.
239 241
240 242 Parameters
241 243 ----------
242 244 manpage : string
243 245 Name of the manpage, must include the section number (trailing number).
244 246
245 247 Example
246 248 -------
247 249
248 250 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
249 251 ('docs/man/ipython.1.gz',
250 252 ['docs/man/ipython.1'],
251 253 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
252 254 """
253 255 man_dir = pjoin('docs', 'man')
254 256 manpage_gz = manpage + '.gz'
255 257 manpath = pjoin(man_dir, manpage)
256 258 manpath_gz = pjoin(man_dir, manpage_gz)
257 259 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
258 260 locals() )
259 261 return (manpath_gz, [manpath], gz_cmd)
260 262
261 263 # The two functions below are copied from IPython.utils.path, so we don't need
262 264 # to import IPython during setup, which fails on Python 3.
263 265
264 266 def target_outdated(target,deps):
265 267 """Determine whether a target is out of date.
266 268
267 269 target_outdated(target,deps) -> 1/0
268 270
269 271 deps: list of filenames which MUST exist.
270 272 target: single filename which may or may not exist.
271 273
272 274 If target doesn't exist or is older than any file listed in deps, return
273 275 true, otherwise return false.
274 276 """
275 277 try:
276 278 target_time = os.path.getmtime(target)
277 279 except os.error:
278 280 return 1
279 281 for dep in deps:
280 282 dep_time = os.path.getmtime(dep)
281 283 if dep_time > target_time:
282 284 #print "For target",target,"Dep failed:",dep # dbg
283 285 #print "times (dep,tar):",dep_time,target_time # dbg
284 286 return 1
285 287 return 0
286 288
287 289
288 290 def target_update(target,deps,cmd):
289 291 """Update a target with a given command given a list of dependencies.
290 292
291 293 target_update(target,deps,cmd) -> runs cmd if target is outdated.
292 294
293 295 This is just a wrapper around target_outdated() which calls the given
294 296 command if target is outdated."""
295 297
296 298 if target_outdated(target,deps):
297 299 os.system(cmd)
298 300
299 301 #---------------------------------------------------------------------------
300 302 # Find scripts
301 303 #---------------------------------------------------------------------------
302 304
303 305 def find_scripts(entry_points=False, suffix=''):
304 306 """Find IPython's scripts.
305 307
306 308 if entry_points is True:
307 309 return setuptools entry_point-style definitions
308 310 else:
309 311 return file paths of plain scripts [default]
310 312
311 313 suffix is appended to script names if entry_points is True, so that the
312 314 Python 3 scripts get named "ipython3" etc.
313 315 """
314 316 if entry_points:
315 317 console_scripts = [s % suffix for s in [
316 318 'ipython%s = IPython.terminal.ipapp:launch_new_instance',
317 319 'pycolor%s = IPython.utils.PyColorize:main',
318 320 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
319 321 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
320 322 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
321 323 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
322 324 'iptest%s = IPython.testing.iptest:main',
323 'irunner%s = IPython.lib.irunner:main'
325 'irunner%s = IPython.lib.irunner:main',
324 326 ]]
325 327 gui_scripts = []
326 328 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
327 329 else:
328 330 parallel_scripts = pjoin('IPython','parallel','scripts')
329 331 main_scripts = pjoin('IPython','scripts')
330 332 scripts = [
331 333 pjoin(parallel_scripts, 'ipengine'),
332 334 pjoin(parallel_scripts, 'ipcontroller'),
333 335 pjoin(parallel_scripts, 'ipcluster'),
334 336 pjoin(parallel_scripts, 'iplogger'),
335 337 pjoin(main_scripts, 'ipython'),
336 338 pjoin(main_scripts, 'pycolor'),
337 339 pjoin(main_scripts, 'irunner'),
338 340 pjoin(main_scripts, 'iptest')
339 341 ]
340 342 return scripts
341 343
342 344 #---------------------------------------------------------------------------
343 345 # Verify all dependencies
344 346 #---------------------------------------------------------------------------
345 347
346 348 def check_for_dependencies():
347 349 """Check for IPython's dependencies.
348 350
349 351 This function should NOT be called if running under setuptools!
350 352 """
351 353 from setupext.setupext import (
352 354 print_line, print_raw, print_status,
353 355 check_for_sphinx, check_for_pygments,
354 356 check_for_nose, check_for_pexpect,
355 check_for_pyzmq, check_for_readline
357 check_for_pyzmq, check_for_readline,
358 check_for_jinja2, check_for_markdown
356 359 )
357 360 print_line()
358 361 print_raw("BUILDING IPYTHON")
359 362 print_status('python', sys.version)
360 363 print_status('platform', sys.platform)
361 364 if sys.platform == 'win32':
362 365 print_status('Windows version', sys.getwindowsversion())
363 366
364 367 print_raw("")
365 368 print_raw("OPTIONAL DEPENDENCIES")
366 369
367 370 check_for_sphinx()
368 371 check_for_pygments()
369 372 check_for_nose()
370 373 check_for_pexpect()
371 374 check_for_pyzmq()
372 375 check_for_readline()
376 check_for_jinja2()
377 check_for_markdown()
373 378
374 379 #---------------------------------------------------------------------------
375 380 # VCS related
376 381 #---------------------------------------------------------------------------
377 382
378 383 # utils.submodule has checks for submodule status
379 384 execfile(pjoin('IPython','utils','submodule.py'), globals())
380 385
381 386 class UpdateSubmodules(Command):
382 387 """Update git submodules
383 388
384 389 IPython's external javascript dependencies live in a separate repo.
385 390 """
386 391 description = "Update git submodules"
387 392 user_options = []
388 393
389 394 def initialize_options(self):
390 395 pass
391 396
392 397 def finalize_options(self):
393 398 pass
394 399
395 400 def run(self):
396 401 failure = False
397 402 try:
398 403 self.spawn('git submodule init'.split())
399 404 self.spawn('git submodule update --recursive'.split())
400 405 except Exception as e:
401 406 failure = e
402 407 print(e)
403 408
404 409 if not check_submodule_status(repo_root) == 'clean':
405 410 print("submodules could not be checked out")
406 411 sys.exit(1)
407 412
408 413
409 414 def git_prebuild(pkg_dir, build_cmd=build_py):
410 415 """Return extended build or sdist command class for recording commit
411 416
412 417 records git commit in IPython.utils._sysinfo.commit
413 418
414 419 for use in IPython.utils.sysinfo.sys_info() calls after installation.
415 420
416 421 Also ensures that submodules exist prior to running
417 422 """
418 423
419 424 class MyBuildPy(build_cmd):
420 425 ''' Subclass to write commit data into installation tree '''
421 426 def run(self):
422 427 build_cmd.run(self)
423 428 # this one will only fire for build commands
424 429 if hasattr(self, 'build_lib'):
425 430 self._record_commit(self.build_lib)
426 431
427 432 def make_release_tree(self, base_dir, files):
428 433 # this one will fire for sdist
429 434 build_cmd.make_release_tree(self, base_dir, files)
430 435 self._record_commit(base_dir)
431 436
432 437 def _record_commit(self, base_dir):
433 438 import subprocess
434 439 proc = subprocess.Popen('git rev-parse --short HEAD',
435 440 stdout=subprocess.PIPE,
436 441 stderr=subprocess.PIPE,
437 442 shell=True)
438 443 repo_commit, _ = proc.communicate()
439 444 repo_commit = repo_commit.strip().decode("ascii")
440 445
441 446 out_pth = pjoin(base_dir, pkg_dir, 'utils', '_sysinfo.py')
442 447 if os.path.isfile(out_pth) and not repo_commit:
443 448 # nothing to write, don't clobber
444 449 return
445 450
446 451 print("writing git commit '%s' to %s" % (repo_commit, out_pth))
447 452
448 453 # remove to avoid overwriting original via hard link
449 454 try:
450 455 os.remove(out_pth)
451 456 except (IOError, OSError):
452 457 pass
453 458 with open(out_pth, 'w') as out_file:
454 459 out_file.writelines([
455 460 '# GENERATED BY setup.py\n',
456 461 'commit = "%s"\n' % repo_commit,
457 462 ])
458 463 return require_submodules(MyBuildPy)
459 464
460 465
461 466 def require_submodules(command):
462 467 """decorator for instructing a command to check for submodules before running"""
463 468 class DecoratedCommand(command):
464 469 def run(self):
465 470 if not check_submodule_status(repo_root) == 'clean':
466 471 print("submodules missing! Run `setup.py submodule` and try again")
467 472 sys.exit(1)
468 473 command.run(self)
469 474 return DecoratedCommand
@@ -1,172 +1,162 b''
1 1 # encoding: utf-8
2 2 from __future__ import print_function
3 3
4 4 __docformat__ = "restructuredtext en"
5 5
6 6 #-------------------------------------------------------------------------------
7 7 # Copyright (C) 2008 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-------------------------------------------------------------------------------
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Imports
15 15 #-------------------------------------------------------------------------------
16 16
17 17 import sys, os
18 18 from textwrap import fill
19 19
20 20 display_status=True
21 21
22 22 def check_display(f):
23 23 """decorator to allow display methods to be muted by mod.display_status"""
24 24 def maybe_display(*args, **kwargs):
25 25 if display_status:
26 26 return f(*args, **kwargs)
27 27 return maybe_display
28 28
29 29 @check_display
30 30 def print_line(char='='):
31 31 print(char * 76)
32 32
33 33 @check_display
34 34 def print_status(package, status):
35 35 initial_indent = "%22s: " % package
36 36 indent = ' ' * 24
37 37 print(fill(str(status), width=76,
38 38 initial_indent=initial_indent,
39 39 subsequent_indent=indent))
40 40
41 41 @check_display
42 42 def print_message(message):
43 43 indent = ' ' * 24 + "* "
44 44 print(fill(str(message), width=76,
45 45 initial_indent=indent,
46 46 subsequent_indent=indent))
47 47
48 48 @check_display
49 49 def print_raw(section):
50 50 print(section)
51 51
52 52 #-------------------------------------------------------------------------------
53 53 # Tests for specific packages
54 54 #-------------------------------------------------------------------------------
55 55
56 56 def check_for_ipython():
57 57 try:
58 58 import IPython
59 59 except ImportError:
60 60 print_status("IPython", "Not found")
61 61 return False
62 62 else:
63 63 print_status("IPython", IPython.__version__)
64 64 return True
65 65
66 66 def check_for_sphinx():
67 67 try:
68 68 import sphinx
69 69 except ImportError:
70 print_status('sphinx', "Not found (required for building documentation)")
70 print_status('sphinx', "Not found (required for docs and nbconvert)")
71 71 return False
72 72 else:
73 73 print_status('sphinx', sphinx.__version__)
74 74 return True
75 75
76 76 def check_for_pygments():
77 77 try:
78 78 import pygments
79 79 except ImportError:
80 print_status('pygments', "Not found (required for syntax highlighting documentation)")
80 print_status('pygments', "Not found (required for docs and nbconvert)")
81 81 return False
82 82 else:
83 83 print_status('pygments', pygments.__version__)
84 84 return True
85 85
86 def check_for_nose():
87 try:
88 import nose
89 except ImportError:
90 print_status('nose', "Not found (required for running the test suite)")
91 return False
92 else:
93 print_status('nose', nose.__version__)
94 return True
95
96 def check_for_pexpect():
86 def check_for_jinja2():
97 87 try:
98 import pexpect
88 import jinja2
99 89 except ImportError:
100 print_status("pexpect", "no (required for running standalone doctests)")
90 print_status('jinja2', "Not found (required for notebook and nbconvert)")
101 91 return False
102 92 else:
103 print_status("pexpect", pexpect.__version__)
93 print_status('jinja2', jinja2.__version__)
104 94 return True
105 95
106 def check_for_httplib2():
96 def check_for_markdown():
107 97 try:
108 import httplib2
98 import markdown
109 99 except ImportError:
110 print_status("httplib2", "no (required for blocking http clients)")
100 print_status('pygments', "Not found (required for nbconvert)")
111 101 return False
112 102 else:
113 print_status("httplib2","yes")
103 print_status('markdown', markdown.version)
114 104 return True
115 105
116 def check_for_sqlalchemy():
106 def check_for_nose():
117 107 try:
118 import sqlalchemy
108 import nose
119 109 except ImportError:
120 print_status("sqlalchemy", "no (required for the ipython1 notebook)")
110 print_status('nose', "Not found (required for running the test suite)")
121 111 return False
122 112 else:
123 print_status("sqlalchemy","yes")
113 print_status('nose', nose.__version__)
124 114 return True
125 115
126 def check_for_simplejson():
116 def check_for_pexpect():
127 117 try:
128 import simplejson
118 import pexpect
129 119 except ImportError:
130 print_status("simplejson", "no (required for the ipython1 notebook)")
120 print_status("pexpect", "no (required for running standalone doctests)")
131 121 return False
132 122 else:
133 print_status("simplejson","yes")
123 print_status("pexpect", pexpect.__version__)
134 124 return True
135 125
136 126 def check_for_pyzmq():
137 127 try:
138 128 import zmq
139 129 except ImportError:
140 130 print_status('pyzmq', "no (required for qtconsole, notebook, and parallel computing capabilities)")
141 131 return False
142 132 else:
143 133 # pyzmq 2.1.10 adds pyzmq_version_info funtion for returning
144 134 # version as a tuple
145 135 if hasattr(zmq, 'pyzmq_version_info') and zmq.pyzmq_version_info() >= (2,1,11):
146 136 print_status("pyzmq", zmq.__version__)
147 137 return True
148 138 else:
149 139 print_status('pyzmq', "no (have %s, but require >= 2.1.11 for"
150 140 " qtconsole, notebook, and parallel computing capabilities)" % zmq.__version__)
151 141 return False
152 142
153 143 def check_for_readline():
154 144 from distutils.version import LooseVersion
155 145 try:
156 146 import readline
157 147 except ImportError:
158 148 try:
159 149 import pyreadline
160 150 vs = pyreadline.release.version
161 151 except (ImportError, AttributeError):
162 152 print_status('readline', "no (required for good interactive behavior)")
163 153 return False
164 154 if LooseVersion(vs).version >= [1,7,1]:
165 155 print_status('readline', "yes pyreadline-" + vs)
166 156 return True
167 157 else:
168 158 print_status('readline', "no pyreadline-%s < 1.7.1" % vs)
169 159 return False
170 160 else:
171 161 print_status('readline', "yes")
172 162 return True
General Comments 0
You need to be logged in to leave comments. Login now