##// END OF EJS Templates
Added writers and supporting code.
Jonathan Frederic -
Show More
@@ -0,0 +1,74 b''
1 """Module containing a transformer that converts outputs in the notebook from
2 one format to another.
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 .activatable import ActivatableTransformer
17
18 #-----------------------------------------------------------------------------
19 # Classes
20 #-----------------------------------------------------------------------------
21
22 class ConvertFiguresTransformer(ActivatableTransformer):
23 """
24 Converts all of the outputs in a notebook from one format to another.
25 """
26
27
28 def __init__(self, from_formats, to_format, **kw):
29 """
30 Public constructor
31
32 Parameters
33 ----------
34 from_formats : list [of string]
35 Formats that the converter can convert from
36 to_format : string
37 Format that the converter converts to
38 config : Config
39 Configuration file structure
40 **kw : misc
41 Additional arguments
42 """
43 super(ConvertFiguresTransformer, self).__init__(**kw)
44
45 self._from_formats = from_formats
46 self._to_format = to_format
47
48
49 def convert_figure(self, data_format, data):
50 raise NotImplementedError()
51
52
53 def transform_cell(self, cell, resources, cell_index):
54 """
55 Apply a transformation on each cell,
56
57 See base.py
58 """
59
60 #Loop through all of the datatypes of the outputs in the cell.
61 for index, cell_out in enumerate(cell.get('outputs', [])):
62 for data_type, data in cell_out.items():
63 self._convert_figure(cell_out, data_type, data)
64 return cell, resources
65
66
67 def _convert_figure(self, cell_out, data_type, data):
68 """
69 Convert a figure and output the results to the cell output
70 """
71
72 if not self._to_format in cell_out:
73 if data_type in self._from_formats:
74 cell_out[self._to_format] = self.convert_figure(data_type, data)
@@ -0,0 +1,70 b''
1 """Module containing a transformer that converts outputs in the notebook from
2 one format to another.
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
16 import os
17 from IPython.utils.tempdir import TemporaryDirectory
18
19 from .convertfigures import ConvertFiguresTransformer
20
21
22 #-----------------------------------------------------------------------------
23 # Constants
24 #-----------------------------------------------------------------------------
25
26 INKSCAPE_COMMAND = "inkscape --without-gui --export-pdf=\"{to_filename}\" \"{from_filename}\""
27
28
29 #-----------------------------------------------------------------------------
30 # Classes
31 #-----------------------------------------------------------------------------
32
33 class ConvertSvgTransformer(ConvertFiguresTransformer):
34 """
35 Converts all of the outputs in a notebook from one format to another.
36 """
37
38
39 def __init__(self, **kw):
40 """
41 Constructor
42 """
43 super(ConvertSvgTransformer, self).__init__(['svg'], 'pdf', **kw)
44
45
46 def convert_figure(self, data_format, data):
47 """
48 Convert a single Svg figure. Returns converted data.
49 """
50
51 #Work in a temporary directory
52 with TemporaryDirectory() as tmpdir:
53
54 #Write fig to temp file
55 input_filename = os.path.join(tmpdir, 'figure.' + data_format)
56 with open(input_filename, 'w') as f:
57 f.write(data)
58
59 #Call conversion application
60 output_filename = os.path.join(tmpdir, 'figure.pdf')
61 shell = INKSCAPE_COMMAND.format(from_filename=input_filename,
62 to_filename=output_filename)
63 subprocess.call(shell, shell=True) #Shell=True okay since input is trusted.
64
65 #Read output from drive
66 if os.path.isfile(output_filename):
67 with open(output_filename) as f:
68 return f.read()
69 else:
70 return TypeError("Inkscape svg to png conversion failed")
@@ -1,5 +1,6 b''
1 """Utilities for converting notebooks to and from different formats."""
1 """Utilities for converting notebooks to and from different formats."""
2
2
3 from .exporters import *
3 from .exporters import *
4 import filters
4 import filters
5 import transformers
5 import transformers
6 import writers
@@ -1,223 +1,217 b''
1 """
1 """
2 Module containing single call export functions.
2 Module containing single call export functions.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
5 # Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from functools import wraps
16 from functools import wraps
17
17
18 from IPython.nbformat.v3.nbbase import NotebookNode
18 from IPython.nbformat.v3.nbbase import NotebookNode
19 from IPython.config import Config
19
20
20 from .exporter import Exporter
21 from .exporter import Exporter
21 from .basichtml import BasicHTMLExporter
22 from .basichtml import BasicHTMLExporter
22 from .fullhtml import FullHTMLExporter
23 from .fullhtml import FullHTMLExporter
23 from .latex import LatexExporter
24 from .latex import LatexExporter
24 from .markdown import MarkdownExporter
25 from .markdown import MarkdownExporter
25 from .python import PythonExporter
26 from .python import PythonExporter
26 from .reveal import RevealExporter
27 from .reveal import RevealExporter
27 from .rst import RstExporter
28 from .rst import RstExporter
28 from .sphinx_howto import SphinxHowtoExporter
29 from .sphinx_howto import SphinxHowtoExporter
29 from .sphinx_manual import SphinxManualExporter
30 from .sphinx_manual import SphinxManualExporter
30
31
31 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
32 # Classes
33 # Classes
33 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
34
35
35 def DocDecorator(f):
36 def DocDecorator(f):
36
37
37 #Set docstring of function
38 #Set docstring of function
38 f.__doc__ = f.__doc__ + """
39 f.__doc__ = f.__doc__ + """
39 nb : Notebook node
40 nb : Notebook node
40 config : config
41 config : config (optional, keyword arg)
41 User configuration instance.
42 User configuration instance.
42 transformers : list[of transformer]
43 resources : dict (optional, keyword arg)
43 Custom transformers to apply to the notebook prior to engaging
44 Resources used in the conversion process.
44 the Jinja template engine. Any transformers specified here
45 will override existing transformers if a naming conflict
46 occurs.
47 filters : list[of filter]
48 Custom filters to make accessible to the Jinja templates. Any
49 filters specified here will override existing filters if a
50 naming conflict occurs.
51
45
52 Returns
46 Returns
53 ----------
47 ----------
54 tuple- output, resources, exporter_instance
48 tuple- output, resources, exporter_instance
55 output : str
49 output : str
56 Jinja 2 output. This is the resulting converted notebook.
50 Jinja 2 output. This is the resulting converted notebook.
57 resources : dictionary
51 resources : dictionary
58 Dictionary of resources used prior to and during the conversion
52 Dictionary of resources used prior to and during the conversion
59 process.
53 process.
60 exporter_instance : Exporter
54 exporter_instance : Exporter
61 Instance of the Exporter class used to export the document. Useful
55 Instance of the Exporter class used to export the document. Useful
62 to caller because it provides a 'file_extension' property which
56 to caller because it provides a 'file_extension' property which
63 specifies what extension the output should be saved as."""
57 specifies what extension the output should be saved as."""
64
58
65 @wraps(f)
59 @wraps(f)
66 def decorator(*args, **kwargs):
60 def decorator(*args, **kwargs):
67 return f(*args, **kwargs)
61 return f(*args, **kwargs)
68
62
69 return decorator
63 return decorator
70
64
71
65
72 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
73 # Functions
67 # Functions
74 #-----------------------------------------------------------------------------
68 #-----------------------------------------------------------------------------
75
69
76 __all__ = [
70 __all__ = [
77 'export',
71 'export',
78 'export_sphinx_manual',
72 'export_sphinx_manual',
79 'export_sphinx_howto',
73 'export_sphinx_howto',
80 'export_basic_html',
74 'export_basic_html',
81 'export_full_html',
75 'export_full_html',
82 'export_latex',
76 'export_latex',
83 'export_markdown',
77 'export_markdown',
84 'export_python',
78 'export_python',
85 'export_reveal',
79 'export_reveal',
86 'export_rst',
80 'export_rst',
87 'export_by_name',
81 'export_by_name',
88 'get_export_names'
82 'get_export_names'
89 ]
83 ]
90
84
91 @DocDecorator
85 @DocDecorator
92 def export(exporter_type, nb, config=None, transformers=None, filters=None):
86 def export(exporter_type, nb, **kw):
93 """
87 """
94 Export a notebook object using specific exporter class.
88 Export a notebook object using specific exporter class.
95
89
96 exporter_type : Exporter class type
90 exporter_type : Exporter class type
97 Class type of the exporter that should be used. This method
91 Class type of the exporter that should be used. This method
98 will initialize it's own instance of the class. It is
92 will initialize it's own instance of the class. It is
99 ASSUMED that the class type provided exposes a
93 ASSUMED that the class type provided exposes a
100 constructor (__init__) with the same signature as the
94 constructor (__init__) with the same signature as the
101 base Exporter class.}
95 base Exporter class.}
102 """
96 """
103
97
104 #Check arguments
98 #Check arguments
105 if exporter_type is None:
99 if exporter_type is None:
106 raise TypeError("Exporter is None")
100 raise TypeError("Exporter is None")
107 elif not issubclass(exporter_type, Exporter):
101 elif not issubclass(exporter_type, Exporter):
108 raise TypeError("Exporter type does not inherit from Exporter (base)")
102 raise TypeError("Exporter type does not inherit from Exporter (base)")
109
110 if nb is None:
103 if nb is None:
111 raise TypeError("nb is None")
104 raise TypeError("nb is None")
112
105
113 #Create the exporter
106 #Create the exporter
114 exporter_instance = exporter_type(preprocessors=transformers,
107 exporter_instance = exporter_type(config=kw.get('config', Config()))
115 jinja_filters=filters, config=config)
116
108
117 #Try to convert the notebook using the appropriate conversion function.
109 #Try to convert the notebook using the appropriate conversion function.
110 resources = kw.get('resources', {})
118 if isinstance(nb, NotebookNode):
111 if isinstance(nb, NotebookNode):
119 output, resources = exporter_instance.from_notebook_node(nb)
112 output, resources = exporter_instance.from_notebook_node(nb, resources)
120 elif isinstance(nb, basestring):
113 elif isinstance(nb, basestring):
121 output, resources = exporter_instance.from_filename(nb)
114 output, resources = exporter_instance.from_filename(nb, resources)
122 else:
115 else:
123 output, resources = exporter_instance.from_file(nb)
116 output, resources = exporter_instance.from_file(nb, resources)
124 return output, resources, exporter_instance
117 return output, resources
125
118
126
119
127 @DocDecorator
120 @DocDecorator
128 def export_sphinx_manual(nb, config=None, transformers=None, filters=None):
121 def export_sphinx_manual(nb, **kw):
129 """
122 """
130 Export a notebook object to Sphinx Manual LaTeX
123 Export a notebook object to Sphinx Manual LaTeX
131 """
124 """
132 return export(SphinxManualExporter, nb, config, transformers, filters)
125 return export(SphinxManualExporter, nb, **kw)
133
126
134
127
135 @DocDecorator
128 @DocDecorator
136 def export_sphinx_howto(nb, config=None, transformers=None, filters=None):
129 def export_sphinx_howto(nb, **kw):
137 """
130 """
138 Export a notebook object to Sphinx HowTo LaTeX
131 Export a notebook object to Sphinx HowTo LaTeX
139 """
132 """
140 return export(SphinxHowtoExporter, nb, config, transformers, filters)
133 return export(SphinxHowtoExporter, nb, **kw)
141
134
142
135
143 @DocDecorator
136 @DocDecorator
144 def export_basic_html(nb, config=None, transformers=None, filters=None):
137 def export_basic_html(nb, **kw):
145 """
138 """
146 Export a notebook object to Basic HTML
139 Export a notebook object to Basic HTML
147 """
140 """
148 return export(BasicHTMLExporter, nb, config, transformers, filters)
141 return export(BasicHTMLExporter, nb, **kw)
149
142
150
143
151 @DocDecorator
144 @DocDecorator
152 def export_full_html(nb, config=None, transformers=None, filters=None):
145 def export_full_html(nb, **kw):
153 """
146 """
154 Export a notebook object to Full HTML
147 Export a notebook object to Full HTML
155 """
148 """
156 return export(FullHTMLExporter, nb, config, transformers, filters)
149 return export(FullHTMLExporter, nb, **kw)
157
150
158
151
159 @DocDecorator
152 @DocDecorator
160 def export_latex(nb, config=None, transformers=None, filters=None):
153 def export_latex(nb, **kw):
161 """
154 """
162 Export a notebook object to LaTeX
155 Export a notebook object to LaTeX
163 """
156 """
164 return export(LatexExporter, nb, config, transformers, filters)
157 return export(LatexExporter, nb, **kw)
165
158
166
159
167 @DocDecorator
160 @DocDecorator
168 def export_markdown(nb, config=None, transformers=None, filters=None):
161 def export_markdown(nb, **kw):
169 """
162 """
170 Export a notebook object to Markdown
163 Export a notebook object to Markdown
171 """
164 """
172 return export(MarkdownExporter, nb, config, transformers, filters)
165 return export(MarkdownExporter, nb, **kw)
173
166
174
167
175 @DocDecorator
168 @DocDecorator
176 def export_python(nb, config=None, transformers=None, filters=None):
169 def export_python(nb, **kw):
177 """
170 """
178 Export a notebook object to Python
171 Export a notebook object to Python
179 """
172 """
180 return export(PythonExporter, nb, config, transformers, filters)
173 return export(PythonExporter, nb, **kw)
181
174
182
175
183 @DocDecorator
176 @DocDecorator
184 def export_reveal(nb, config=None, transformers=None, filters=None):
177 def export_reveal(nb, **kw):
185 """
178 """
186 Export a notebook object to Reveal
179 Export a notebook object to Reveal
187 """
180 """
188 return export(RevealExporter, nb, config, transformers, filters)
181 return export(RevealExporter, nb, **kw)
189
182
190
183
191 @DocDecorator
184 @DocDecorator
192 def export_rst(nb, config=None, transformers=None, filters=None):
185 def export_rst(nb, **kw):
193 """
186 """
194 Export a notebook object to RST
187 Export a notebook object to RST
195 """
188 """
196 return export(RstExporter, nb, config, transformers, filters)
189 return export(RstExporter, nb, **kw)
197
190
198
191
199 @DocDecorator
192 @DocDecorator
200 def export_by_name(template_name, nb, config=None, transformers=None, filters=None):
193 def export_by_name(format_name, nb, **kw):
201 """
194 """
202 Export a notebook object to a template type by its name. Reflection
195 Export a notebook object to a template type by its name. Reflection
203 (Inspect) is used to find the template's corresponding explicit export
196 (Inspect) is used to find the template's corresponding explicit export
204 method defined in this module. That method is then called directly.
197 method defined in this module. That method is then called directly.
205
198
206 template_name : str
199 format_name : str
207 Name of the template style to export to.
200 Name of the template style to export to.
208 """
201 """
209
202
210 function_name = "export_" + template_name.lower()
203 function_name = "export_" + format_name.lower()
211
204
212 if function_name in globals():
205 if function_name in globals():
213 return globals()[function_name](nb, config, transformers, filters)
206 return globals()[function_name](nb, **kw)
214 else:
207 else:
215 raise NameError("template for `%s` not found" % function_name)
208 raise NameError("template for `%s` not found" % function_name)
216
209
217 def get_export_names():
210 def get_export_names():
218 "Return a list of the currently supported export targets"
211 "Return a list of the currently supported export targets"
219 # grab everything after 'export_'
212 # grab everything after 'export_'
220 l = [x[len('export_'):] for x in __all__ if x.startswith('export_')]
213 l = [x[len('export_'):] for x in __all__ if x.startswith('export_')]
221 # filter out the one method that is not a template
214
215 # filter out the one method that is not a template
222 l = [x for x in l if 'by_name' not in x]
216 l = [x for x in l if 'by_name' not in x]
223 return sorted(l)
217 return sorted(l)
@@ -1,346 +1,360 b''
1 """This module defines Exporter, a highly configurable converter
1 """This module defines Exporter, a highly configurable converter
2 that uses Jinja2 to export notebook files into different formats.
2 that uses Jinja2 to export notebook files into different formats.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import print_function, absolute_import
17 from __future__ import print_function, absolute_import
18
18
19 # Stdlib imports
19 # Stdlib imports
20 import io
20 import io
21 import os
21 import os
22 import inspect
22 import inspect
23 import types
23 from copy import deepcopy
24 from copy import deepcopy
24
25
25 # other libs/dependencies
26 # other libs/dependencies
26 from jinja2 import Environment, FileSystemLoader, ChoiceLoader
27 from jinja2 import Environment, FileSystemLoader, ChoiceLoader
27
28
28 # IPython imports
29 # IPython imports
29 from IPython.config.configurable import Configurable
30 from IPython.config.configurable import Configurable
30 from IPython.config import Config
31 from IPython.config import Config
31 from IPython.nbformat import current as nbformat
32 from IPython.nbformat import current as nbformat
32 from IPython.utils.traitlets import MetaHasTraits, Unicode
33 from IPython.utils.traitlets import MetaHasTraits, DottedObjectName, Unicode, List, Dict
34 from IPython.utils.importstring import import_item
33 from IPython.utils.text import indent
35 from IPython.utils.text import indent
34
36
35 from IPython.nbconvert import filters
37 from IPython.nbconvert import filters
36 from IPython.nbconvert import transformers
38 from IPython.nbconvert import transformers
37
39
38 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
39 # Globals and constants
41 # Globals and constants
40 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
41
43
42 #Jinja2 extensions to load.
44 #Jinja2 extensions to load.
43 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
45 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
44
46
45 default_filters = {
47 default_filters = {
46 'indent': indent,
48 'indent': indent,
47 'markdown': filters.markdown2html,
49 'markdown': filters.markdown2html,
48 'ansi2html': filters.ansi2html,
50 'ansi2html': filters.ansi2html,
49 'filter_data_type': filters.DataTypeFilter,
51 'filter_data_type': filters.DataTypeFilter,
50 'get_lines': filters.get_lines,
52 'get_lines': filters.get_lines,
51 'highlight': filters.highlight,
53 'highlight': filters.highlight,
52 'highlight2html': filters.highlight,
54 'highlight2html': filters.highlight,
53 'highlight2latex': filters.highlight2latex,
55 'highlight2latex': filters.highlight2latex,
54 'markdown2latex': filters.markdown2latex,
56 'markdown2latex': filters.markdown2latex,
55 'markdown2rst': filters.markdown2rst,
57 'markdown2rst': filters.markdown2rst,
56 'pycomment': filters.python_comment,
58 'pycomment': filters.python_comment,
57 'rm_ansi': filters.remove_ansi,
59 'rm_ansi': filters.remove_ansi,
58 'rm_dollars': filters.strip_dollars,
60 'rm_dollars': filters.strip_dollars,
59 'rm_fake': filters.rm_fake,
61 'rm_fake': filters.rm_fake,
60 'ansi2latex': filters.ansi2latex,
62 'ansi2latex': filters.ansi2latex,
61 'rm_math_space': filters.rm_math_space,
63 'rm_math_space': filters.rm_math_space,
62 'wrap': filters.wrap
64 'wrap': filters.wrap
63 }
65 }
64
66
65 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
66 # Class
68 # Class
67 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
68
70
69 class Exporter(Configurable):
71 class Exporter(Configurable):
70 """
72 """
71 Exports notebooks into other file formats. Uses Jinja 2 templating engine
73 Exports notebooks into other file formats. Uses Jinja 2 templating engine
72 to output new formats. Inherit from this class if you are creating a new
74 to output new formats. Inherit from this class if you are creating a new
73 template type along with new filters/transformers. If the filters/
75 template type along with new filters/transformers. If the filters/
74 transformers provided by default suffice, there is no need to inherit from
76 transformers provided by default suffice, there is no need to inherit from
75 this class. Instead, override the template_file and file_extension
77 this class. Instead, override the template_file and file_extension
76 traits via a config file.
78 traits via a config file.
77
79
78 {filters}
80 {filters}
79 """
81 """
80
82
81 # finish the docstring
83 # finish the docstring
82 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
84 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
83
85
84
86
85 template_file = Unicode(
87 template_file = Unicode(
86 '', config=True,
88 '', config=True,
87 help="Name of the template file to use")
89 help="Name of the template file to use")
88
90
89 file_extension = Unicode(
91 file_extension = Unicode(
90 'txt', config=True,
92 'txt', config=True,
91 help="Extension of the file that should be written to disk"
93 help="Extension of the file that should be written to disk"
92 )
94 )
93
95
94 template_path = Unicode(
96 template_path = Unicode(
95 os.path.join("..", "templates"), config=True,
97 os.path.join("..", "templates"), config=True,
96 help="Path where the template files are located.")
98 help="Path where the template files are located.")
97
99
98 template_skeleton_path = Unicode(
100 template_skeleton_path = Unicode(
99 os.path.join("..", "templates", "skeleton"), config=True,
101 os.path.join("..", "templates", "skeleton"), config=True,
100 help="Path where the template skeleton files are located.")
102 help="Path where the template skeleton files are located.")
101
103
102 #Jinja block definitions
104 #Jinja block definitions
103 jinja_comment_block_start = Unicode("", config=True)
105 jinja_comment_block_start = Unicode("", config=True)
104 jinja_comment_block_end = Unicode("", config=True)
106 jinja_comment_block_end = Unicode("", config=True)
105 jinja_variable_block_start = Unicode("", config=True)
107 jinja_variable_block_start = Unicode("", config=True)
106 jinja_variable_block_end = Unicode("", config=True)
108 jinja_variable_block_end = Unicode("", config=True)
107 jinja_logic_block_start = Unicode("", config=True)
109 jinja_logic_block_start = Unicode("", config=True)
108 jinja_logic_block_end = Unicode("", config=True)
110 jinja_logic_block_end = Unicode("", config=True)
109
111
110 #Extension that the template files use.
112 #Extension that the template files use.
111 template_extension = Unicode(".tpl", config=True)
113 template_extension = Unicode(".tpl", config=True)
112
114
113 #Processors that process the input data prior to the export, set in the
115 #Configurability, allows the user to easily add filters and transformers.
114 #constructor for this class.
116 transformers = List(config=True,
115 transformers = None
117 help="""List of transformers, by name or namespace, to enable.""")
116
118 filters = Dict(config=True,
119 help="""Dictionary of filters, by name and namespace, to add to the Jinja
120 environment.""")
117
121
118 def __init__(self, transformers=None, filters=None, config=None, extra_loaders=None, **kw):
122 def __init__(self, config=None, extra_loaders=None, **kw):
119 """
123 """
120 Public constructor
124 Public constructor
121
125
122 Parameters
126 Parameters
123 ----------
127 ----------
124 transformers : list[of transformer]
125 Custom transformers to apply to the notebook prior to engaging
126 the Jinja template engine. Any transformers specified here
127 will override existing transformers if a naming conflict
128 occurs.
129 filters : dict[of filter]
130 filters specified here will override existing filters if a naming
131 conflict occurs. Filters are availlable in jinja template through
132 the name of the corresponding key. Cf class docstring for
133 availlable default filters.
134 config : config
128 config : config
135 User configuration instance.
129 User configuration instance.
136 extra_loaders : list[of Jinja Loaders]
130 extra_loaders : list[of Jinja Loaders]
137 ordered list of Jinja loder to find templates. Will be tried in order
131 ordered list of Jinja loder to find templates. Will be tried in order
138 before the default FileSysteme ones.
132 before the default FileSysteme ones.
139 """
133 """
140
134
141 #Call the base class constructor
135 #Call the base class constructor
142 c = self.default_config
136 c = self.default_config
143 if config:
137 if config:
144 c.merge(config)
138 c.merge(config)
145
139
146 super(Exporter, self).__init__(config=c, **kw)
140 super(Exporter, self).__init__(config=c, **kw)
147
141
148 #Standard environment
142 #Standard environment
149 self._init_environment(extra_loaders=extra_loaders)
143 self._init_environment(extra_loaders=extra_loaders)
150
144
151 #Add transformers
145 #Add transformers
146 self._transformers = []
152 self._register_transformers()
147 self._register_transformers()
153
148
154 #Add filters to the Jinja2 environment
149 #Add filters to the Jinja2 environment
155 self._register_filters()
150 self._register_filters()
156
151
157 #Load user transformers. Overwrite existing transformers if need be.
152 #Load user transformers. Enabled by default.
158 if transformers :
153 if self.transformers:
159 for transformer in transformers:
154 for transformer in self.transformers:
160 self.register_transformer(transformer)
155 self.register_transformer(transformer, True)
161
156
162 #Load user filters. Overwrite existing filters if need be.
157 #Load user filters. Overwrite existing filters if need be.
163 if not filters is None:
158 if self.filters:
164 for key, user_filter in filters.iteritems():
159 for key, user_filter in self.filters.iteritems():
165 self.register_filter(key, user_filter)
160 self.register_filter(key, user_filter)
166
161
162
167 @property
163 @property
168 def default_config(self):
164 def default_config(self):
169 return Config()
165 return Config()
170
166
171
167
172
168 def from_notebook_node(self, nb, resources={}, **kw):
173 def from_notebook_node(self, nb, resources=None):
174 """
169 """
175 Convert a notebook from a notebook node instance.
170 Convert a notebook from a notebook node instance.
176
171
177 Parameters
172 Parameters
178 ----------
173 ----------
179 nb : Notebook node
174 nb : Notebook node
180 resources : a dict of additional resources that
175 resources : dict (**kw)
181 can be accessed read/write by transformers
176 of additional resources that can be accessed read/write by
182 and filters.
177 transformers and filters.
183 """
178 """
184 if resources is None:
179
185 resources = {}
180 #Preprocess
186 nb, resources = self._preprocess(nb, resources)
181 nb, resources = self._preprocess(nb, resources)
187
188 #Load the template file.
189 self.template = self.environment.get_template(self.template_file+self.template_extension)
190
191 return self.template.render(nb=nb, resources=resources), resources
192
182
183 #Convert
184 self.template = self.environment.get_template(self.template_file + self.template_extension)
185 output = self.template.render(nb=nb, resources=resources)
186
187 #Set output extension in resources dict
188 resources['output_extension'] = self.file_extension
189 return output, resources
193
190
194 def from_filename(self, filename):
191
192 def from_filename(self, filename, resources={}, **kw):
195 """
193 """
196 Convert a notebook from a notebook file.
194 Convert a notebook from a notebook file.
197
195
198 Parameters
196 Parameters
199 ----------
197 ----------
200 filename : str
198 filename : str
201 Full filename of the notebook file to open and convert.
199 Full filename of the notebook file to open and convert.
202 """
200 """
203
201
204 with io.open(filename) as f:
202 with io.open(filename) as f:
205 return self.from_notebook_node(nbformat.read(f, 'json'))
203 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources,**kw)
206
204
207
205
208 def from_file(self, file_stream):
206 def from_file(self, file_stream, resources={}, **kw):
209 """
207 """
210 Convert a notebook from a notebook file.
208 Convert a notebook from a notebook file.
211
209
212 Parameters
210 Parameters
213 ----------
211 ----------
214 file_stream : file-like object
212 file_stream : file-like object
215 Notebook file-like object to convert.
213 Notebook file-like object to convert.
216 """
214 """
217 return self.from_notebook_node(nbformat.read(file_stream, 'json'))
215 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
218
216
219
217
220 def register_transformer(self, transformer):
218 def register_transformer(self, transformer, enabled=None):
221 """
219 """
222 Register a transformer.
220 Register a transformer.
223 Transformers are classes that act upon the notebook before it is
221 Transformers are classes that act upon the notebook before it is
224 passed into the Jinja templating engine. Transformers are also
222 passed into the Jinja templating engine. Transformers are also
225 capable of passing additional information to the Jinja
223 capable of passing additional information to the Jinja
226 templating engine.
224 templating engine.
227
225
228 Parameters
226 Parameters
229 ----------
227 ----------
230 transformer : transformer
228 transformer : transformer
231 """
229 """
232 if self.transformers is None:
230
233 self.transformers = []
231 #Handle transformer's registration based on it's type
234
235 if inspect.isfunction(transformer):
232 if inspect.isfunction(transformer):
236 self.transformers.append(transformer)
233 #Transformer is a function, no need to construct it.
234 self._transformers.append(transformer)
237 return transformer
235 return transformer
236
237 elif isinstance(transformer, types.StringTypes):
238 #Transformer is a string, import the namespace and recursively call
239 #this register_transformer method
240 transformer_cls = import_item(DottedObjectName(transformer))
241 return self.register_transformer(transformer_cls, enabled=None)
242
238 elif isinstance(transformer, MetaHasTraits):
243 elif isinstance(transformer, MetaHasTraits):
239 transformer_instance = transformer(config=self.config)
244 #Transformer is configurable. Make sure to pass in new default for
240 self.transformers.append(transformer_instance)
245 #the enabled flag if one was specified.
241 return transformer_instance
246 c = Config()
247 if not enabled is None:
248 c = Config({transformer.__name__: {'enabled': enabled}})
249 c.merge(self.config)
250 transformer_instance = transformer(config=c)
251
242 else:
252 else:
253 #Transformer is not configurable, construct it
243 transformer_instance = transformer()
254 transformer_instance = transformer()
244 self.transformers.append(transformer_instance)
255
245 return transformer_instance
256 #Register and return the transformer.
257 self._transformers.append(transformer_instance)
258 return transformer_instance
246
259
247
260
248 def register_filter(self, name, filter):
261 def register_filter(self, name, filter):
249 """
262 """
250 Register a filter.
263 Register a filter.
251 A filter is a function that accepts and acts on one string.
264 A filter is a function that accepts and acts on one string.
252 The filters are accesible within the Jinja templating engine.
265 The filters are accesible within the Jinja templating engine.
253
266
254 Parameters
267 Parameters
255 ----------
268 ----------
256 name : str
269 name : str
257 name to give the filter in the Jinja engine
270 name to give the filter in the Jinja engine
258 filter : filter
271 filter : filter
259 """
272 """
260 if inspect.isfunction(filter):
273 if inspect.isfunction(filter):
261 self.environment.filters[name] = filter
274 self.environment.filters[name] = filter
275 elif isinstance(filter, types.StringTypes):
276 filter_cls = import_item(DottedObjectName(filter))
277 self.register_filter(name, filter_cls)
262 elif isinstance(filter, MetaHasTraits):
278 elif isinstance(filter, MetaHasTraits):
263 self.environment.filters[name] = filter(config=self.config)
279 self.environment.filters[name] = filter(config=self.config)
264 else:
280 else:
265 self.environment.filters[name] = filter()
281 self.environment.filters[name] = filter()
266 return self.environment.filters[name]
282 return self.environment.filters[name]
267
283
268
284
269 def _register_transformers(self):
285 def _register_transformers(self):
270 """
286 """
271 Register all of the transformers needed for this exporter.
287 Register all of the transformers needed for this exporter, disabled
288 unless specified explicitly.
272 """
289 """
273
290
274 self.register_transformer(transformers.coalesce_streams)
291 self.register_transformer(transformers.coalesce_streams)
275
292 self.register_transformer(transformers.ExtractFigureTransformer)
276 #Remember the figure extraction transformer so it can be enabled and
277 #disabled easily later.
278 self.extract_figure_transformer = self.register_transformer(transformers.ExtractFigureTransformer)
279
293
280
294
281 def _register_filters(self):
295 def _register_filters(self):
282 """
296 """
283 Register all of the filters required for the exporter.
297 Register all of the filters required for the exporter.
284 """
298 """
285 for k, v in default_filters.iteritems():
299 for key, value in default_filters.iteritems():
286 self.register_filter(k, v)
300 self.register_filter(key, value)
287
301
288
302
289 def _init_environment(self, extra_loaders=None):
303 def _init_environment(self, extra_loaders=None):
290 """
304 """
291 Create the Jinja templating environment.
305 Create the Jinja templating environment.
292 """
306 """
293 here = os.path.dirname(os.path.realpath(__file__))
307 here = os.path.dirname(os.path.realpath(__file__))
294 loaders = []
308 loaders = []
295 if extra_loaders:
309 if extra_loaders:
296 loaders.extend(extra_loaders)
310 loaders.extend(extra_loaders)
297
311
298 loaders.append(FileSystemLoader([
312 loaders.append(FileSystemLoader([
299 os.path.join(here, self.template_path),
313 os.path.join(here, self.template_path),
300 os.path.join(here, self.template_skeleton_path),
314 os.path.join(here, self.template_skeleton_path),
301 ]))
315 ]))
302
316
303 self.environment = Environment(
317 self.environment = Environment(
304 loader= ChoiceLoader(loaders),
318 loader= ChoiceLoader(loaders),
305 extensions=JINJA_EXTENSIONS
319 extensions=JINJA_EXTENSIONS
306 )
320 )
307
321
308 #Set special Jinja2 syntax that will not conflict with latex.
322 #Set special Jinja2 syntax that will not conflict with latex.
309 if self.jinja_logic_block_start:
323 if self.jinja_logic_block_start:
310 self.environment.block_start_string = self.jinja_logic_block_start
324 self.environment.block_start_string = self.jinja_logic_block_start
311 if self.jinja_logic_block_end:
325 if self.jinja_logic_block_end:
312 self.environment.block_end_string = self.jinja_logic_block_end
326 self.environment.block_end_string = self.jinja_logic_block_end
313 if self.jinja_variable_block_start:
327 if self.jinja_variable_block_start:
314 self.environment.variable_start_string = self.jinja_variable_block_start
328 self.environment.variable_start_string = self.jinja_variable_block_start
315 if self.jinja_variable_block_end:
329 if self.jinja_variable_block_end:
316 self.environment.variable_end_string = self.jinja_variable_block_end
330 self.environment.variable_end_string = self.jinja_variable_block_end
317 if self.jinja_comment_block_start:
331 if self.jinja_comment_block_start:
318 self.environment.comment_start_string = self.jinja_comment_block_start
332 self.environment.comment_start_string = self.jinja_comment_block_start
319 if self.jinja_comment_block_end:
333 if self.jinja_comment_block_end:
320 self.environment.comment_end_string = self.jinja_comment_block_end
334 self.environment.comment_end_string = self.jinja_comment_block_end
321
335
322
336
323 def _preprocess(self, nb, resources):
337 def _preprocess(self, nb, resources):
324 """
338 """
325 Preprocess the notebook before passing it into the Jinja engine.
339 Preprocess the notebook before passing it into the Jinja engine.
326 To preprocess the notebook is to apply all of the
340 To preprocess the notebook is to apply all of the
327
341
328 Parameters
342 Parameters
329 ----------
343 ----------
330 nb : notebook node
344 nb : notebook node
331 notebook that is being exported.
345 notebook that is being exported.
332 resources : a dict of additional resources that
346 resources : a dict of additional resources that
333 can be accessed read/write by transformers
347 can be accessed read/write by transformers
334 and filters.
348 and filters.
335 """
349 """
336
350
337 # Do a deepcopy first,
351 # Do a deepcopy first,
338 # we are never safe enough with what the transformers could do.
352 # we are never safe enough with what the transformers could do.
339 nbc = deepcopy(nb)
353 nbc = deepcopy(nb)
340 resc = deepcopy(resources)
354 resc = deepcopy(resources)
355
341 #Run each transformer on the notebook. Carry the output along
356 #Run each transformer on the notebook. Carry the output along
342 #to each transformer
357 #to each transformer
343 for transformer in self.transformers:
358 for transformer in self._transformers:
344 nb, resources = transformer(nbc, resc)
359 nbc, resc = transformer(nbc, resc)
345 return nb, resources
360 return nbc, resc
346
@@ -1,108 +1,111 b''
1 """
1 """
2 Exporter that allows Latex Jinja templates to work. Contains logic to
2 Exporter that allows Latex Jinja templates to work. Contains logic to
3 appropriately prepare IPYNB files for export to LaTeX. Including but
3 appropriately prepare IPYNB files for export to LaTeX. Including but
4 not limited to escaping LaTeX, fixing math region tags, using special
4 not limited to escaping LaTeX, fixing math region tags, using special
5 tags to circumvent Jinja/Latex syntax conflicts.
5 tags to circumvent Jinja/Latex syntax conflicts.
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
8 # Copyright (c) 2013, the IPython Development Team.
9 #
9 #
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11 #
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 # Stdlib imports
19 # Stdlib imports
20 import os
20 import os
21
21
22 # IPython imports
22 # IPython imports
23 from IPython.utils.traitlets import Unicode
23 from IPython.utils.traitlets import Unicode
24 from IPython.config import Config
24 from IPython.config import Config
25
25
26 from IPython.nbconvert import filters, transformers
26 from IPython.nbconvert import filters, transformers
27 from .exporter import Exporter
27 from .exporter import Exporter
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Classes and functions
30 # Classes and functions
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 class LatexExporter(Exporter):
33 class LatexExporter(Exporter):
34 """
34 """
35 Exports to a Latex template. Inherit from this class if your template is
35 Exports to a Latex template. Inherit from this class if your template is
36 LaTeX based and you need custom tranformers/filters. Inherit from it if
36 LaTeX based and you need custom tranformers/filters. Inherit from it if
37 you are writing your own HTML template and need custom tranformers/filters.
37 you are writing your own HTML template and need custom tranformers/filters.
38 If you don't need custom tranformers/filters, just change the
38 If you don't need custom tranformers/filters, just change the
39 'template_file' config option. Place your template in the special "/latex"
39 'template_file' config option. Place your template in the special "/latex"
40 subfolder of the "../templates" folder.
40 subfolder of the "../templates" folder.
41 """
41 """
42
42
43 file_extension = Unicode(
43 file_extension = Unicode(
44 'tex', config=True,
44 'tex', config=True,
45 help="Extension of the file that should be written to disk")
45 help="Extension of the file that should be written to disk")
46
46
47 template_file = Unicode(
47 template_file = Unicode(
48 'base', config=True,
48 'base', config=True,
49 help="Name of the template file to use")
49 help="Name of the template file to use")
50
50
51 #Latex constants
51 #Latex constants
52 template_path = Unicode(
52 template_path = Unicode(
53 os.path.join("..", "templates", "latex"), config=True,
53 os.path.join("..", "templates", "latex"), config=True,
54 help="Path where the template files are located.")
54 help="Path where the template files are located.")
55
55
56 template_skeleton_path = Unicode(
56 template_skeleton_path = Unicode(
57 os.path.join("..", "templates", "latex", "skeleton"), config=True,
57 os.path.join("..", "templates", "latex", "skeleton"), config=True,
58 help="Path where the template skeleton files are located.")
58 help="Path where the template skeleton files are located.")
59
59
60 #Special Jinja2 syntax that will not conflict when exporting latex.
60 #Special Jinja2 syntax that will not conflict when exporting latex.
61 jinja_comment_block_start = Unicode("((=", config=True)
61 jinja_comment_block_start = Unicode("((=", config=True)
62 jinja_comment_block_end = Unicode("=))", config=True)
62 jinja_comment_block_end = Unicode("=))", config=True)
63 jinja_variable_block_start = Unicode("(((", config=True)
63 jinja_variable_block_start = Unicode("(((", config=True)
64 jinja_variable_block_end = Unicode(")))", config=True)
64 jinja_variable_block_end = Unicode(")))", config=True)
65 jinja_logic_block_start = Unicode("((*", config=True)
65 jinja_logic_block_start = Unicode("((*", config=True)
66 jinja_logic_block_end = Unicode("*))", config=True)
66 jinja_logic_block_end = Unicode("*))", config=True)
67
67
68 #Extension that the template files use.
68 #Extension that the template files use.
69 template_extension = Unicode(".tplx", config=True)
69 template_extension = Unicode(".tplx", config=True)
70
70
71 def _register_filters(self):
71 def _register_filters(self):
72 """
72 """
73 Register all of the filters required for the exporter.
73 Register all of the filters required for the exporter.
74 """
74 """
75
75
76 #Register the filters of the base class.
76 #Register the filters of the base class.
77 super(LatexExporter, self)._register_filters()
77 super(LatexExporter, self)._register_filters()
78
78
79 #Add latex filters to the Jinja2 environment
79 #Add latex filters to the Jinja2 environment
80 self.register_filter('escape_tex', filters.escape_latex)
80 self.register_filter('escape_tex', filters.escape_latex)
81 self.register_filter('highlight', filters.highlight2latex)
81 self.register_filter('highlight', filters.highlight2latex)
82
82
83
83
84 def _register_transformers(self):
84 def _register_transformers(self):
85 """
85 """
86 Register all of the transformers needed for this exporter.
86 Register all of the transformers needed for this exporter.
87 """
87 """
88
89 #Register ConvertSvgTransformer before any other transformers!
90 #Important because it allows the conversion of svg->png BEFORE the
91 #extract figure transformer acts on the data.
92 self.register_transformer(transformers.ConvertSvgTransformer, True)
88
93
89 #Register the transformers of the base class.
94 #Register transformers
90 super(LatexExporter, self)._register_transformers()
95 super(LatexExporter, self)._register_transformers()
91
96 self.register_transformer(transformers.LatexTransformer, True)
92 #Register latex transformer
93 self.register_transformer(transformers.LatexTransformer)
94
97
95 @property
98 @property
96 def default_config(self):
99 def default_config(self):
97 c = Config({
100 c = Config({
98 'GlobalConfigurable': {
101 'GlobalConfigurable': {
99 'display_data_priority' : ['latex', 'svg', 'png', 'jpg', 'jpeg' , 'text']
102 'display_data_priority' : ['latex', 'png', 'jpg', 'jpeg']
100 },
103 },
101 'ExtractFigureTransformer': {
104 'ExtractFigureTransformer': {
102 'enabled':True,
105 'enabled':True
103 'extra_ext_map':{'svg':'pdf'},
104 }
106 }
107
105 })
108 })
106 c.merge(super(LatexExporter,self).default_config)
109 c.merge(super(LatexExporter,self).default_config)
107 return c
110 return c
108
111
@@ -1,61 +1,61 b''
1 """
1 """
2 Reveal slide show exporter.
2 Reveal slide show exporter.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
5 # Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from IPython.utils.traitlets import Unicode
16 from IPython.utils.traitlets import Unicode
17 from IPython.config import Config
17 from IPython.config import Config
18
18
19 from .basichtml import BasicHTMLExporter
19 from .basichtml import BasicHTMLExporter
20 from IPython.nbconvert import transformers
20 from IPython.nbconvert import transformers
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Classes
23 # Classes
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 class RevealExporter(BasicHTMLExporter):
26 class RevealExporter(BasicHTMLExporter):
27 """
27 """
28 Exports a Reveal slide show (.HTML) which may be rendered in a web browser.
28 Exports a Reveal slide show (.HTML) which may be rendered in a web browser.
29 """
29 """
30
30
31 file_extension = Unicode(
31 file_extension = Unicode(
32 'reveal.html', config=True,
32 'reveal.html', config=True,
33 help="Extension of the file that should be written to disk")
33 help="Extension of the file that should be written to disk")
34
34
35 template_file = Unicode(
35 template_file = Unicode(
36 'reveal', config=True,
36 'reveal', config=True,
37 help="Name of the template file to use")
37 help="Name of the template file to use")
38
38
39 def _register_transformers(self):
39 def _register_transformers(self):
40 """
40 """
41 Register all of the transformers needed for this exporter.
41 Register all of the transformers needed for this exporter.
42 """
42 """
43
43
44 #Register the transformers of the base class.
44 #Register the transformers of the base class.
45 super(RevealExporter, self)._register_transformers()
45 super(RevealExporter, self)._register_transformers()
46
46
47 #Register reveal help transformer
47 #Register reveal help transformer
48 self.register_transformer(transformers.RevealHelpTransformer)
48 self.register_transformer(transformers.RevealHelpTransformer, True)
49
49
50 @property
50 @property
51 def default_config(self):
51 def default_config(self):
52 c = Config({
52 c = Config({
53 'CSSHTMLHeaderTransformer':{
53 'CSSHTMLHeaderTransformer':{
54 'enabled':True
54 'enabled':True
55 },
55 },
56 'RevealHelpTransformer':{
56 'RevealHelpTransformer':{
57 'enabled':True,
57 'enabled':True,
58 },
58 },
59 })
59 })
60 c.merge(super(RevealExporter,self).default_config)
60 c.merge(super(RevealExporter,self).default_config)
61 return c
61 return c
@@ -1,54 +1,45 b''
1 """
1 """
2 Exporter for exporting notebooks to Sphinx 'HowTo' style latex. Latex
2 Exporter for exporting notebooks to Sphinx 'HowTo' style latex. Latex
3 formatted for use with PDFLatex.
3 formatted for use with PDFLatex.
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from IPython.utils.traitlets import Unicode
17 from IPython.utils.traitlets import Unicode
18 from IPython.config import Config
18 from IPython.config import Config
19
19
20 # local import
20 # local import
21 from .latex import LatexExporter
21 from .latex import LatexExporter
22
22
23 from IPython.nbconvert import transformers
23 from IPython.nbconvert import transformers
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Classes
26 # Classes
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 class SphinxHowtoExporter(LatexExporter):
29 class SphinxHowtoExporter(LatexExporter):
30 """
30 """
31 Exports Sphinx "HowTo" LaTeX documents. The Sphinx "HowTo" exporter
31 Exports Sphinx "HowTo" LaTeX documents. The Sphinx "HowTo" exporter
32 produces short document format latex for use with PDFLatex.
32 produces short document format latex for use with PDFLatex.
33 """
33 """
34
34
35 template_file = Unicode(
35 template_file = Unicode(
36 'sphinx_howto', config=True,
36 'sphinx_howto', config=True,
37 help="Name of the template file to use")
37 help="Name of the template file to use")
38
38
39 def _register_transformers(self):
39 def _register_transformers(self):
40
40
41 #Register the transformers of the base class.
41 #Register the transformers of the base class.
42 super(SphinxHowtoExporter, self)._register_transformers()
42 super(SphinxHowtoExporter, self)._register_transformers()
43
43
44 #Register sphinx latex transformer
44 #Register sphinx latex transformer
45 self.register_transformer(transformers.SphinxTransformer)
45 self.register_transformer(transformers.SphinxTransformer, True)
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
@@ -1,229 +1,167 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """NBConvert is a utility for conversion of IPYNB files.
2 """NBConvert is a utility for conversion of IPYNB files.
3
3
4 Commandline interface for the NBConvert conversion utility. Read the
4 Commandline interface for the NBConvert conversion utility. Read the
5 readme.rst for usage information
5 readme.rst for usage information
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 #Copyright (c) 2013, the IPython Development Team.
8 #Copyright (c) 2013, the IPython Development Team.
9 #
9 #
10 #Distributed under the terms of the Modified BSD License.
10 #Distributed under the terms of the Modified BSD License.
11 #
11 #
12 #The full license is in the file COPYING.txt, distributed with this software.
12 #The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 #Imports
16 #Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #Stdlib imports
19 #Stdlib imports
20 from __future__ import print_function
20 from __future__ import print_function
21 import sys
21 import sys
22 import io
23 import os
22 import os
23 import glob
24
24
25 #From IPython
25 #From IPython
26 from IPython.config.application import Application
26 from IPython.core.application import BaseIPythonApplication
27 from IPython.utils.traitlets import Bool, Unicode
27 from IPython.config.application import catch_config_error
28 from IPython.utils.traitlets import Unicode, List, Instance, DottedObjectName, Type
29 from IPython.utils.importstring import import_item
28
30
29 from .exporters.export import export_by_name, get_export_names
31 from .exporters.export import export_by_name, get_export_names
30 from .exporters.exporter import Exporter
32 from .exporters.exporter import Exporter
31 from .transformers import extractfigure
33 from .writers.base import WriterBase
32 from .utils.config import GlobalConfigurable
34 from .utils.config import GlobalConfigurable
33
35
34 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
35 #Globals and constants
37 #Classes and functions
36 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
37
39
38 #'Keys in resources' user prompt.
40 class NbConvertApp(BaseIPythonApplication):
39 KEYS_PROMPT_HEAD = "====================== Keys in Resources =================================="
41 """Application used to convert to and from notebook file type (*.ipynb)"""
40 KEYS_PROMPT_BODY = """
41 ===========================================================================
42 You are responsible for writing these files into the appropriate
43 directory(ies) if need be. If you do not want to see this message, enable
44 the 'write' (boolean) flag of the converter.
45 ===========================================================================
46 """
47
42
48 _examples = """
49 ipython nbconvert rst Untitled0.ipynb # convert ipynb to ReStructured Text
50 ipython nbconvert latex Untitled0.ipynb # convert ipynb to LaTeX
51 ipython nbconvert reveal Untitled0.ipynb # convert to Reveal (HTML/JS) slideshow
52 """
53
43
44 description = Unicode(
45 u"""This application is used to convert notebook files (*.ipynb).
46 An ipython config file can be used to batch convert notebooks in the
47 current directory.""")
54
48
55 #-----------------------------------------------------------------------------
49 examples = Unicode(u"""
56 #Classes and functions
50 Running `ipython nbconvert` will read the directory config file and then
57 #-----------------------------------------------------------------------------
51 apply it to one or more notebooks.
58
52
59 class NbConvertApp(Application):
53 Multiple notebooks can be given at the command line in a couple of
60 __doc__ = """IPython notebook conversion utility
54 different ways:
55
56 > ipython nbconvert notebook*.ipynb
57 > ipython nbconvert notebook1.ipynb notebook2.ipynb
58 > ipython nbconvert # this will use the config file to fill in the notebooks
59 """)
61
60
62 Convert to and from notebook file type (*.ipynb)
61 config_file_name = Unicode(u'ipython_nbconvert_config.py')
63
62
64 ipython nbconvert TARGET FILENAME
63 #Writer specific variables
64 writer = Instance('IPython.nbconvert.writers.base.WriterBase',
65 help="""Instance of the writer class used to write the
66 results of the conversion.""")
67 writer_class = DottedObjectName('FilesWriter', config=True,
68 help="""Writer class used to write the
69 results of the conversion""")
70 writer_aliases = {'FilesWriter': 'IPython.nbconvert.writers.files.FilesWriter',
71 'DebugWriter': 'IPython.nbconvert.writers.debug.DebugWriter',
72 'StdoutWriter': 'IPython.nbconvert.writers.stdout.StdoutWriter'}
73 writer_factory = Type()
65
74
66 Supported export TARGETs are: %s
75 def _writer_class_changed(self, name, old, new):
67 """ % (" ".join(get_export_names()))
76 if new in self.writer_aliases:
68 description = Unicode(__doc__)
77 new = self.writer_aliases[new]
78 self.writer_factory = import_item(new)
69
79
70 examples = _examples
71
80
72 stdout = Bool(
81 #Other configurable variables
73 False, config=True,
82 export_format = Unicode(
74 help="""Whether to print the converted IPYNB file to stdout
83 "", config=True,
75 use full do diff files without actually writing a new file"""
84 help="""If specified, nbconvert will convert the document(s) specified
76 )
85 using this format.""")
77
86
78 write = Bool(
87 notebooks = List([], config=True, help="""List of notebooks to convert.
79 True, config=True,
88 Search patterns are supported.""")
80 help="""Should the converted notebook file be written to disk
81 along with potential extracted resources."""
82 )
83
89
84 aliases = {
90 aliases = {'format':'NbConvertApp.export_format',
85 'stdout':'NbConvertApp.stdout',
91 'notebooks':'NbConvertApp.notebooks',
86 'write':'NbConvertApp.write',
92 'writer':'NbConvertApp.writer_class'}
87 }
88
93
89 flags = {}
90
94
91 flags['stdout'] = (
95 @catch_config_error
92 {'NbConvertApp' : {'stdout' : True}},
96 def initialize(self, argv=None):
93 """Print converted file to stdout, equivalent to --stdout=True
97 super(NbConvertApp, self).initialize(argv)
94 """
95 )
96
98
97 flags['no-write'] = (
99 #Register class here to have help with help all
98 {'NbConvertApp' : {'write' : True}},
100 self.classes.insert(0, Exporter)
99 """Do not write to disk, equivalent to --write=False
101 self.classes.insert(0, WriterBase)
100 """
102 self.classes.insert(0, GlobalConfigurable)
101 )
102
103
104 #Init
105 self.init_config(self.extra_args)
106 self.init_writer()
103
107
104 def __init__(self, **kwargs):
105 """Public constructor"""
106
108
107 #Call base class
109 def init_config(self, extra_args):
108 super(NbConvertApp, self).__init__(**kwargs)
110 """
111 Add notebooks to the config if needed. Glob each notebook to replace
112 notebook patterns with filenames.
113 """
109
114
110 #Register class here to have help with help all
115 #Get any additional notebook patterns from the commandline
111 self.classes.insert(0, Exporter)
116 if len(extra_args) > 0:
112 self.classes.insert(0, GlobalConfigurable)
117 for pattern in extra_args:
118 self.notebooks.append(pattern)
119
120 #Use glob to replace all the notebook patterns with filenames.
121 filenames = []
122 for pattern in self.notebooks:
123 for filename in glob.glob(pattern):
124 if not filename in filenames:
125 filenames.append(filename)
126 self.notebooks = filenames
127
128
129 def init_writer(self):
130 """
131 Initialize the writer (which is stateless)
132 """
133 self._writer_class_changed(None, self.writer_class, self.writer_class)
134 self.writer = self.writer_factory(parent=self)
113
135
114
136
115 def start(self, argv=None):
137 def start(self, argv=None):
116 """Entrypoint of NbConvert application.
117
118 Parameters
119 ----------
120 argv : list
121 Commandline arguments
122 """
138 """
123
139 Entrypoint of NbConvert application.
124 #Parse the commandline options.
140 """
125 self.parse_command_line(argv)
126
141
127 #Call base
142 #Call base
128 super(NbConvertApp, self).start()
143 super(NbConvertApp, self).start()
129
144
130 #The last arguments in list will be used by nbconvert
145 #Export each notebook
131 if len(self.extra_args) is not 3:
146 for notebook_filename in self.notebooks:
132 print( "Wrong number of arguments, use --help flag for usage", file=sys.stderr)
147
133 sys.exit(-1)
148 #Get a unique key for the notebook and set it in the resources object.
134 export_type = (self.extra_args)[1]
149 basename = os.path.basename(notebook_filename)
135 ipynb_file = (self.extra_args)[2]
150 notebook_name = basename[:basename.rfind('.')]
136
151 resources = {}
137 #Export
152 resources['unique_key'] = notebook_name
138 try:
153
139 return_value = export_by_name(export_type, ipynb_file)
154 #Export & write
140 except NameError as e:
155 output, resources = export_by_name(self.export_format,
141 print("Error: '%s' exporter not found." % export_type,
156 notebook_filename,
142 file=sys.stderr)
157 resources=resources,
143 print("Known exporters are:",
158 config=self.config)
144 "\n\t" + "\n\t".join(get_export_names()),
159 self.writer.write(output, resources, notebook_name=notebook_name)
145 file=sys.stderr)
160
146 sys.exit(-1)
147 else:
148 (output, resources, exporter) = return_value
149
150 #TODO: Allow user to set output directory and file.
151 destination_filename = None
152 destination_directory = None
153 if self.write:
154
155 #Get the file name without the '.ipynb' (6 chars) extension and then
156 #remove any addition periods and spaces. The resulting name will
157 #be used to create the directory that the files will be exported
158 #into.
159 out_root = ipynb_file[:-6].replace('.', '_').replace(' ', '_')
160 destination_filename = os.path.join(out_root+'.'+exporter.file_extension)
161
162 destination_directory = out_root+'_files'
163 if not os.path.exists(destination_directory):
164 os.mkdir(destination_directory)
165
166 #Write the results
167 if self.stdout or not (destination_filename is None and destination_directory is None):
168 self._write_results(output, resources, destination_filename, destination_directory)
169
170
171 def _write_results(self, output, resources, destination_filename=None, destination_directory=None):
172 """Output the conversion results to the console and/or filesystem
173
174 Parameters
175 ----------
176 output : str
177 Output of conversion
178 resources : dictionary
179 Additional input/output used by the transformers. For
180 example, the ExtractFigure transformer outputs the
181 figures it extracts into this dictionary. This method
182 relies on the figures being in this dictionary when
183 attempting to write the figures to the file system.
184 destination_filename : str, Optional
185 Filename to write output into. If None, output is not
186 written to a file.
187 destination_directory : str, Optional
188 Directory to write notebook data (i.e. figures) to. If
189 None, figures are not written to the file system.
190 """
191
192 if self.stdout:
193 print(output.encode('utf-8'))
194
195 #Write file output from conversion.
196 if not destination_filename is None:
197 with io.open(destination_filename, 'w') as f:
198 f.write(output)
199
200 #Get the key names used by the extract figure transformer
201 figures_key = extractfigure.FIGURES_KEY
202 binary_key = extractfigure.BINARY_KEY
203 text_key = extractfigure.TEXT_KEY
204
205 #Output any associate figures into the same "root" directory.
206 binkeys = resources.get(figures_key, {}).get(binary_key,{}).keys()
207 textkeys = resources.get(figures_key, {}).get(text_key,{}).keys()
208 if binkeys or textkeys :
209 if not destination_directory is None:
210 for key in binkeys:
211 with io.open(os.path.join(destination_directory, key), 'wb') as f:
212 f.write(resources[figures_key][binary_key][key])
213 for key in textkeys:
214 with io.open(os.path.join(destination_directory, key), 'w') as f:
215 f.write(resources[figures_key][text_key][key])
216
217 #Figures that weren't exported which will need to be created by the
218 #user. Tell the user what figures these are.
219 if self.stdout:
220 print(KEYS_PROMPT_HEAD, file=sys.stderr)
221 print(resources[figures_key].keys(), file=sys.stderr)
222 print(KEYS_PROMPT_BODY , file=sys.stderr)
223
161
224 #-----------------------------------------------------------------------------
162 #-----------------------------------------------------------------------------
225 # Main entry point
163 # Main entry point
226 #-----------------------------------------------------------------------------
164 #-----------------------------------------------------------------------------
227
165
228 launch_new_instance = NbConvertApp.launch_instance
166 launch_new_instance = NbConvertApp.launch_instance
229
167
@@ -1,10 +1,12 b''
1 # Class base Transformers
1 # Class base Transformers
2 from .activatable import ActivatableTransformer
2 from .activatable import ActivatableTransformer
3 from .base import ConfigurableTransformer
3 from .base import ConfigurableTransformer
4 from .convertfigures import ConvertFiguresTransformer
5 from .convertsvg import ConvertSvgTransformer
4 from .extractfigure import ExtractFigureTransformer
6 from .extractfigure import ExtractFigureTransformer
5 from .revealhelp import RevealHelpTransformer
7 from .revealhelp import RevealHelpTransformer
6 from .latex import LatexTransformer
8 from .latex import LatexTransformer
7 from .sphinx import SphinxTransformer
9 from .sphinx import SphinxTransformer
8
10
9 # decorated function Transformers
11 # decorated function Transformers
10 from .coalescestreams import coalesce_streams
12 from .coalescestreams import coalesce_streams
@@ -1,99 +1,99 b''
1 """
1 """
2 Module that re-groups transformer that would be applied to ipynb files
2 Module that re-groups transformer that would be applied to ipynb files
3 before going through the templating machinery.
3 before going through the templating machinery.
4
4
5 It exposes a convenient class to inherit from to access configurability.
5 It exposes a convenient class to inherit from to access configurability.
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
8 # Copyright (c) 2013, the IPython Development Team.
9 #
9 #
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11 #
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from ..utils.config import GlobalConfigurable
19 from ..utils.config import GlobalConfigurable
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Classes and Functions
22 # Classes and Functions
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 class ConfigurableTransformer(GlobalConfigurable):
25 class ConfigurableTransformer(GlobalConfigurable):
26 """ A configurable transformer
26 """ A configurable transformer
27
27
28 Inherit from this class if you wish to have configurability for your
28 Inherit from this class if you wish to have configurability for your
29 transformer.
29 transformer.
30
30
31 Any configurable traitlets this class exposed will be configurable in profiles
31 Any configurable traitlets this class exposed will be configurable in profiles
32 using c.SubClassName.atribute=value
32 using c.SubClassName.atribute=value
33
33
34 you can overwrite cell_transform to apply a transformation independently on each cell
34 you can overwrite transform_cell to apply a transformation independently on each cell
35 or __call__ if you prefer your own logic. See corresponding docstring for informations.
35 or __call__ if you prefer your own logic. See corresponding docstring for informations.
36 """
36 """
37
37
38 def __init__(self, config=None, **kw):
38 def __init__(self, config=None, **kw):
39 """
39 """
40 Public constructor
40 Public constructor
41
41
42 Parameters
42 Parameters
43 ----------
43 ----------
44 config : Config
44 config : Config
45 Configuration file structure
45 Configuration file structure
46 **kw : misc
46 **kw : misc
47 Additional arguments
47 Additional arguments
48 """
48 """
49
49
50 super(ConfigurableTransformer, self).__init__(config=config, **kw)
50 super(ConfigurableTransformer, self).__init__(config=config, **kw)
51
51
52
52
53 def __call__(self, nb, resources):
53 def __call__(self, nb, resources):
54 return self.call(nb,resources)
54 return self.call(nb,resources)
55
55
56 def call(self, nb, resources):
56 def call(self, nb, resources):
57 """
57 """
58 Transformation to apply on each notebook.
58 Transformation to apply on each notebook.
59
59
60 You should return modified nb, resources.
60 You should return modified nb, resources.
61 If you wish to apply your transform on each cell, you might want to
61 If you wish to apply your transform on each cell, you might want to
62 overwrite cell_transform method instead.
62 overwrite transform_cell method instead.
63
63
64 Parameters
64 Parameters
65 ----------
65 ----------
66 nb : NotebookNode
66 nb : NotebookNode
67 Notebook being converted
67 Notebook being converted
68 resources : dictionary
68 resources : dictionary
69 Additional resources used in the conversion process. Allows
69 Additional resources used in the conversion process. Allows
70 transformers to pass variables into the Jinja engine.
70 transformers to pass variables into the Jinja engine.
71 """
71 """
72 try :
72 try :
73 for worksheet in nb.worksheets :
73 for worksheet in nb.worksheets :
74 for index, cell in enumerate(worksheet.cells):
74 for index, cell in enumerate(worksheet.cells):
75 worksheet.cells[index], resources = self.cell_transform(cell, resources, index)
75 worksheet.cells[index], resources = self.transform_cell(cell, resources, index)
76 return nb, resources
76 return nb, resources
77 except NotImplementedError:
77 except NotImplementedError:
78 raise NotImplementedError('should be implemented by subclass')
78 raise NotImplementedError('should be implemented by subclass')
79
79
80
80
81 def cell_transform(self, cell, resources, index):
81 def transform_cell(self, cell, resources, index):
82 """
82 """
83 Overwrite if you want to apply a transformation on each cell. You
83 Overwrite if you want to apply a transformation on each cell. You
84 should return modified cell and resource dictionary.
84 should return modified cell and resource dictionary.
85
85
86 Parameters
86 Parameters
87 ----------
87 ----------
88 cell : NotebookNode cell
88 cell : NotebookNode cell
89 Notebook cell being processed
89 Notebook cell being processed
90 resources : dictionary
90 resources : dictionary
91 Additional resources used in the conversion process. Allows
91 Additional resources used in the conversion process. Allows
92 transformers to pass variables into the Jinja engine.
92 transformers to pass variables into the Jinja engine.
93 index : int
93 index : int
94 Index of the cell being processed
94 Index of the cell being processed
95 """
95 """
96
96
97 raise NotImplementedError('should be implemented by subclass')
97 raise NotImplementedError('should be implemented by subclass')
98 return cell, resources
98 return cell, resources
99
99
@@ -1,143 +1,97 b''
1 """Module containing a transformer that extracts all of the figures from the
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.
2 notebook file. The extracted figures are returned in the 'resources' dictionary.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
5 # Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 import itertools
16
15
17 from IPython.utils.traitlets import Dict, Unicode
16 from IPython.utils.traitlets import Dict, Unicode
18 from .activatable import ActivatableTransformer
17 from .activatable import ActivatableTransformer
19
18
20 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
21 # Constants
20 # Constants
22 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
23
22
24 FIGURES_KEY = "figures"
23 # win64 is win32 for backwards compatability, for now. See
25 BINARY_KEY = "binary"
24 # http://mail.python.org/pipermail/patches/2000-May/000648.html
26 TEXT_KEY = "text"
25 # for the original patch that this decision was made.
26 WINDOWS_PLATFORMS = ['win32']
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Classes
29 # Classes
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 class ExtractFigureTransformer(ActivatableTransformer):
32 class ExtractFigureTransformer(ActivatableTransformer):
33 """
33 """
34 Extracts all of the figures from the notebook file. The extracted
34 Extracts all of the figures from the notebook file. The extracted
35 figures are returned in the 'resources' dictionary.
35 figures are returned in the 'resources' dictionary.
36 """
36 """
37
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
38
47 #TODO: Change this to .format {} syntax
39 figure_filename_template = Unicode(
48 default_key_template = Unicode('_fig_{index:02d}.{ext}', config=True)
40 "{unique_key}_{cell_index}_{index}.{extension}", config=True)
49
41
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
42
67 def cell_transform(self, cell, resources, index):
43 def transform_cell(self, cell, resources, cell_index):
68 """
44 """
69 Apply a transformation on each cell,
45 Apply a transformation on each cell,
70
46
71 Parameters
47 Parameters
72 ----------
48 ----------
73 cell : NotebookNode cell
49 cell : NotebookNode cell
74 Notebook cell being processed
50 Notebook cell being processed
75 resources : dictionary
51 resources : dictionary
76 Additional resources used in the conversion process. Allows
52 Additional resources used in the conversion process. Allows
77 transformers to pass variables into the Jinja engine.
53 transformers to pass variables into the Jinja engine.
78 index : int
54 cell_index : int
79 Index of the cell being processed (see base.py)
55 Index of the cell being processed (see base.py)
80 """
56 """
57
58 #Get the unique key from the resource dict if it exists. If it does not
59 #exist, use 'figure' as the default.
60 unique_key = resources.get('unique_key', 'figure')
81
61
82 if resources.get(FIGURES_KEY, None) is None :
62 #Make sure figures key exists
83 resources[FIGURES_KEY] = {TEXT_KEY:{},BINARY_KEY:{}}
63 if not 'figures' in resources:
64 resources['figures'] = {}
84
65
85 for out in cell.get('outputs', []):
66 #Loop through all of the outputs in the cell
67 for index, out in enumerate(cell.get('outputs', [])):
68
69 #Get the output in data formats that the template is interested in.
86 for out_type in self.display_data_priority:
70 for out_type in self.display_data_priority:
87
88 if out.hasattr(out_type):
71 if out.hasattr(out_type):
89 figname, key, data, binary = self._new_figure(out[out_type], out_type)
72 data = out[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
73
104 Parameters
74 #Binary files are base64-encoded, SVG is already XML
105 ----------
75 if out_type in ('png', 'jpg', 'pdf'):
106 extension : str
76 data = data.decode('base64')
107 File extension.
77 elif sys.platform in WINDOWS_PLATFORMS:
108 """
78 data = data.replace('\n', '\r\n')
109
79
110 if extension in self.extra_extension_map :
80 #Build a figure name
111 return self.extra_extension_map[extension]
81 figure_name = self.figure_filename_template.format(
112
82 unique_key=unique_key,
113 return extension
83 cell_index=cell_index,
114
84 index=index,
115
85 extension=out_type)
116 def _new_figure(self, data, format):
86
117 """Create a new figure file in the given format.
87 #On the cell, make the figure available via
88 # cell.outputs[i].svg_filename ... etc (svg in example)
89 # Where
90 # cell.outputs[i].svg contains the data
91 out[out_type + '_filename'] = figure_name
92
93 #In the resources, make the figure available via
94 # resources['figures']['filename'] = data
95 resources['figures'][figure_name] = data
118
96
119 Parameters
97 return cell, resources
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
@@ -1,53 +1,53 b''
1 """Module that allows latex output notebooks to be conditioned before
1 """Module that allows latex output notebooks to be conditioned before
2 they are converted.
2 they are converted.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
5 # Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from __future__ import print_function, absolute_import
16 from __future__ import print_function, absolute_import
17
17
18 # Our own imports
18 # Our own imports
19 # Needed to override transformer
19 # Needed to override transformer
20 from .activatable import (ActivatableTransformer)
20 from .activatable import (ActivatableTransformer)
21 from IPython.nbconvert import filters
21 from IPython.nbconvert import filters
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Classes
24 # Classes
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 class LatexTransformer(ActivatableTransformer):
27 class LatexTransformer(ActivatableTransformer):
28 """
28 """
29 Converter for latex destined documents.
29 Converter for latex destined documents.
30 """
30 """
31
31
32 def cell_transform(self, cell, resources, index):
32 def transform_cell(self, cell, resources, index):
33 """
33 """
34 Apply a transformation on each cell,
34 Apply a transformation on each cell,
35
35
36 Parameters
36 Parameters
37 ----------
37 ----------
38 cell : NotebookNode cell
38 cell : NotebookNode cell
39 Notebook cell being processed
39 Notebook cell being processed
40 resources : dictionary
40 resources : dictionary
41 Additional resources used in the conversion process. Allows
41 Additional resources used in the conversion process. Allows
42 transformers to pass variables into the Jinja engine.
42 transformers to pass variables into the Jinja engine.
43 index : int
43 index : int
44 Modified index of the cell being processed (see base.py)
44 Modified index of the cell being processed (see base.py)
45 """
45 """
46
46
47 #If the cell is a markdown cell, preprocess the ampersands used to
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
48 #remove the space between them and their contents. Latex will complain
49 #if spaces exist between the ampersands and the math content.
49 #if spaces exist between the ampersands and the math content.
50 #See filters.latex.rm_math_space for more information.
50 #See filters.latex.rm_math_space for more information.
51 if hasattr(cell, "source") and cell.cell_type == "markdown":
51 if hasattr(cell, "source") and cell.cell_type == "markdown":
52 cell.source = filters.rm_math_space(cell.source)
52 cell.source = filters.rm_math_space(cell.source)
53 return cell, resources
53 return cell, resources
@@ -1,62 +1,61 b''
1 """Module that pre-processes the notebook for export via Reveal.
1 """Module that pre-processes the notebook for export via Reveal.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 from .base import ConfigurableTransformer
15 from .base import ConfigurableTransformer
16 from IPython.utils.traitlets import Unicode
16 from IPython.utils.traitlets import Unicode
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Classes and functions
19 # Classes and functions
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 class RevealHelpTransformer(ConfigurableTransformer):
22 class RevealHelpTransformer(ConfigurableTransformer):
23
23
24 url_prefix = Unicode('//cdn.jsdelivr.net/reveal.js/2.4.0',
24 url_prefix = Unicode('//cdn.jsdelivr.net/reveal.js/2.4.0',
25 config=True,
25 config=True,
26 help="""If you want to use a local reveal.js library,
26 help="""If you want to use a local reveal.js library,
27 use 'url_prefix':'reveal.js' in your config object.""")
27 use 'url_prefix':'reveal.js' in your config object.""")
28
28
29 def call(self, nb, resources):
29 def call(self, nb, resources):
30 """
30 """
31 Called once to 'transform' contents of the notebook.
31 Called once to 'transform' contents of the notebook.
32
32
33 Parameters
33 Parameters
34 ----------
34 ----------
35 nb : NotebookNode
35 nb : NotebookNode
36 Notebook being converted
36 Notebook being converted
37 resources : dictionary
37 resources : dictionary
38 Additional resources used in the conversion process. Allows
38 Additional resources used in the conversion process. Allows
39 transformers to pass variables into the Jinja engine.
39 transformers to pass variables into the Jinja engine.
40 """
40 """
41
41
42
43 for worksheet in nb.worksheets :
42 for worksheet in nb.worksheets :
44 for i, cell in enumerate(worksheet.cells):
43 for index, cell in enumerate(worksheet.cells):
45
44
46 #Make sure the cell has slideshow metadata.
45 #Make sure the cell has slideshow metadata.
47 cell.metadata.align_type = cell.get('metadata', {}).get('slideshow', {}).get('align_type', 'Left')
46 cell.metadata.align_type = cell.get('metadata', {}).get('slideshow', {}).get('align_type', 'Left')
48 cell.metadata.slide_type = cell.get('metadata', {}).get('slideshow', {}).get('slide_type', '-')
47 cell.metadata.slide_type = cell.get('metadata', {}).get('slideshow', {}).get('slide_type', '-')
49
48
50 #Get the slide type. If type is start of subslide or slide,
49 #Get the slide type. If type is start of subslide or slide,
51 #end the last subslide/slide.
50 #end the last subslide/slide.
52 if cell.metadata.slide_type in ['slide']:
51 if cell.metadata.slide_type in ['slide']:
53 worksheet.cells[i - 1].metadata.slide_helper = 'slide_end'
52 worksheet.cells[index - 1].metadata.slide_helper = 'slide_end'
54 if cell.metadata.slide_type in ['subslide']:
53 if cell.metadata.slide_type in ['subslide']:
55 worksheet.cells[i - 1].metadata.slide_helper = 'subslide_end'
54 worksheet.cells[index - 1].metadata.slide_helper = 'subslide_end'
56
55
57
56
58 if 'reveal' not in resources:
57 if 'reveal' not in resources:
59 resources['reveal'] = {}
58 resources['reveal'] = {}
60 resources['reveal']['url_prefix'] = self.url_prefix
59 resources['reveal']['url_prefix'] = self.url_prefix
61
60
62 return nb, resources
61 return nb, resources
General Comments 0
You need to be logged in to leave comments. Login now