##// END OF EJS Templates
add raw_format to Exporter classes...
MinRK -
Show More
@@ -1,270 +1,270 b''
1 """This module defines Exporter, a highly configurable converter
1 """This module defines a base Exporter class. For Jinja template-based export,
2 that uses Jinja2 to export notebook files into different formats.
2 see templateexporter.py.
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 copy
22 import copy
23 import collections
23 import collections
24 import datetime
24 import datetime
25
25
26
26
27 # IPython imports
27 # IPython imports
28 from IPython.config.configurable import LoggingConfigurable
28 from IPython.config.configurable import LoggingConfigurable
29 from IPython.config import Config
29 from IPython.config import Config
30 from IPython.nbformat import current as nbformat
30 from IPython.nbformat import current as nbformat
31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
32 from IPython.utils.importstring import import_item
32 from IPython.utils.importstring import import_item
33 from IPython.utils import text, py3compat
33 from IPython.utils import text, py3compat
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Class
36 # Class
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 class ResourcesDict(collections.defaultdict):
39 class ResourcesDict(collections.defaultdict):
40 def __missing__(self, key):
40 def __missing__(self, key):
41 return ''
41 return ''
42
42
43
43
44 class Exporter(LoggingConfigurable):
44 class Exporter(LoggingConfigurable):
45 """
45 """
46 Class containing methods that sequentially run a list of preprocessors on a
46 Class containing methods that sequentially run a list of preprocessors on a
47 NotebookNode object and then return the modified NotebookNode object and
47 NotebookNode object and then return the modified NotebookNode object and
48 accompanying resources dict.
48 accompanying resources dict.
49 """
49 """
50
50
51 file_extension = Unicode(
51 file_extension = Unicode(
52 'txt', config=True,
52 'txt', config=True,
53 help="Extension of the file that should be written to disk"
53 help="Extension of the file that should be written to disk"
54 )
54 )
55
55
56 #Configurability, allows the user to easily add filters and preprocessors.
56 #Configurability, allows the user to easily add filters and preprocessors.
57 preprocessors = List(config=True,
57 preprocessors = List(config=True,
58 help="""List of preprocessors, by name or namespace, to enable.""")
58 help="""List of preprocessors, by name or namespace, to enable.""")
59
59
60 _preprocessors = None
60 _preprocessors = None
61
61
62 default_preprocessors = List(['IPython.nbconvert.preprocessors.coalesce_streams',
62 default_preprocessors = List(['IPython.nbconvert.preprocessors.coalesce_streams',
63 'IPython.nbconvert.preprocessors.SVG2PDFPreprocessor',
63 'IPython.nbconvert.preprocessors.SVG2PDFPreprocessor',
64 'IPython.nbconvert.preprocessors.ExtractOutputPreprocessor',
64 'IPython.nbconvert.preprocessors.ExtractOutputPreprocessor',
65 'IPython.nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
65 'IPython.nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
66 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
66 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
67 'IPython.nbconvert.preprocessors.LatexPreprocessor',
67 'IPython.nbconvert.preprocessors.LatexPreprocessor',
68 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
68 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
69 config=True,
69 config=True,
70 help="""List of preprocessors available by default, by name, namespace,
70 help="""List of preprocessors available by default, by name, namespace,
71 instance, or type.""")
71 instance, or type.""")
72
72
73
73
74 def __init__(self, config=None, **kw):
74 def __init__(self, config=None, **kw):
75 """
75 """
76 Public constructor
76 Public constructor
77
77
78 Parameters
78 Parameters
79 ----------
79 ----------
80 config : config
80 config : config
81 User configuration instance.
81 User configuration instance.
82 """
82 """
83 with_default_config = self.default_config
83 with_default_config = self.default_config
84 if config:
84 if config:
85 with_default_config.merge(config)
85 with_default_config.merge(config)
86
86
87 super(Exporter, self).__init__(config=with_default_config, **kw)
87 super(Exporter, self).__init__(config=with_default_config, **kw)
88
88
89 self._init_preprocessors()
89 self._init_preprocessors()
90
90
91
91
92 @property
92 @property
93 def default_config(self):
93 def default_config(self):
94 return Config()
94 return Config()
95
95
96 @nbformat.docstring_nbformat_mod
96 @nbformat.docstring_nbformat_mod
97 def from_notebook_node(self, nb, resources=None, **kw):
97 def from_notebook_node(self, nb, resources=None, **kw):
98 """
98 """
99 Convert a notebook from a notebook node instance.
99 Convert a notebook from a notebook node instance.
100
100
101 Parameters
101 Parameters
102 ----------
102 ----------
103 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
103 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
104 Notebook node
104 Notebook node
105 resources : dict
105 resources : dict
106 Additional resources that can be accessed read/write by
106 Additional resources that can be accessed read/write by
107 preprocessors and filters.
107 preprocessors and filters.
108 **kw
108 **kw
109 Ignored (?)
109 Ignored (?)
110 """
110 """
111 nb_copy = copy.deepcopy(nb)
111 nb_copy = copy.deepcopy(nb)
112 resources = self._init_resources(resources)
112 resources = self._init_resources(resources)
113
113
114 # Preprocess
114 # Preprocess
115 nb_copy, resources = self._preprocess(nb_copy, resources)
115 nb_copy, resources = self._preprocess(nb_copy, resources)
116
116
117 return nb_copy, resources
117 return nb_copy, resources
118
118
119
119
120 def from_filename(self, filename, resources=None, **kw):
120 def from_filename(self, filename, resources=None, **kw):
121 """
121 """
122 Convert a notebook from a notebook file.
122 Convert a notebook from a notebook file.
123
123
124 Parameters
124 Parameters
125 ----------
125 ----------
126 filename : str
126 filename : str
127 Full filename of the notebook file to open and convert.
127 Full filename of the notebook file to open and convert.
128 """
128 """
129
129
130 # Pull the metadata from the filesystem.
130 # Pull the metadata from the filesystem.
131 if resources is None:
131 if resources is None:
132 resources = ResourcesDict()
132 resources = ResourcesDict()
133 if not 'metadata' in resources or resources['metadata'] == '':
133 if not 'metadata' in resources or resources['metadata'] == '':
134 resources['metadata'] = ResourcesDict()
134 resources['metadata'] = ResourcesDict()
135 basename = os.path.basename(filename)
135 basename = os.path.basename(filename)
136 notebook_name = basename[:basename.rfind('.')]
136 notebook_name = basename[:basename.rfind('.')]
137 resources['metadata']['name'] = notebook_name
137 resources['metadata']['name'] = notebook_name
138
138
139 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
139 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
140 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
140 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
141
141
142 with io.open(filename, encoding='utf-8') as f:
142 with io.open(filename, encoding='utf-8') as f:
143 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
143 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
144
144
145
145
146 def from_file(self, file_stream, resources=None, **kw):
146 def from_file(self, file_stream, resources=None, **kw):
147 """
147 """
148 Convert a notebook from a notebook file.
148 Convert a notebook from a notebook file.
149
149
150 Parameters
150 Parameters
151 ----------
151 ----------
152 file_stream : file-like object
152 file_stream : file-like object
153 Notebook file-like object to convert.
153 Notebook file-like object to convert.
154 """
154 """
155 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
155 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
156
156
157
157
158 def register_preprocessor(self, preprocessor, enabled=False):
158 def register_preprocessor(self, preprocessor, enabled=False):
159 """
159 """
160 Register a preprocessor.
160 Register a preprocessor.
161 Preprocessors are classes that act upon the notebook before it is
161 Preprocessors are classes that act upon the notebook before it is
162 passed into the Jinja templating engine. preprocessors are also
162 passed into the Jinja templating engine. preprocessors are also
163 capable of passing additional information to the Jinja
163 capable of passing additional information to the Jinja
164 templating engine.
164 templating engine.
165
165
166 Parameters
166 Parameters
167 ----------
167 ----------
168 preprocessor : preprocessor
168 preprocessor : preprocessor
169 """
169 """
170 if preprocessor is None:
170 if preprocessor is None:
171 raise TypeError('preprocessor')
171 raise TypeError('preprocessor')
172 isclass = isinstance(preprocessor, type)
172 isclass = isinstance(preprocessor, type)
173 constructed = not isclass
173 constructed = not isclass
174
174
175 # Handle preprocessor's registration based on it's type
175 # Handle preprocessor's registration based on it's type
176 if constructed and isinstance(preprocessor, py3compat.string_types):
176 if constructed and isinstance(preprocessor, py3compat.string_types):
177 # Preprocessor is a string, import the namespace and recursively call
177 # Preprocessor is a string, import the namespace and recursively call
178 # this register_preprocessor method
178 # this register_preprocessor method
179 preprocessor_cls = import_item(preprocessor)
179 preprocessor_cls = import_item(preprocessor)
180 return self.register_preprocessor(preprocessor_cls, enabled)
180 return self.register_preprocessor(preprocessor_cls, enabled)
181
181
182 if constructed and hasattr(preprocessor, '__call__'):
182 if constructed and hasattr(preprocessor, '__call__'):
183 # Preprocessor is a function, no need to construct it.
183 # Preprocessor is a function, no need to construct it.
184 # Register and return the preprocessor.
184 # Register and return the preprocessor.
185 if enabled:
185 if enabled:
186 preprocessor.enabled = True
186 preprocessor.enabled = True
187 self._preprocessors.append(preprocessor)
187 self._preprocessors.append(preprocessor)
188 return preprocessor
188 return preprocessor
189
189
190 elif isclass and isinstance(preprocessor, MetaHasTraits):
190 elif isclass and isinstance(preprocessor, MetaHasTraits):
191 # Preprocessor is configurable. Make sure to pass in new default for
191 # Preprocessor is configurable. Make sure to pass in new default for
192 # the enabled flag if one was specified.
192 # the enabled flag if one was specified.
193 self.register_preprocessor(preprocessor(parent=self), enabled)
193 self.register_preprocessor(preprocessor(parent=self), enabled)
194
194
195 elif isclass:
195 elif isclass:
196 # Preprocessor is not configurable, construct it
196 # Preprocessor is not configurable, construct it
197 self.register_preprocessor(preprocessor(), enabled)
197 self.register_preprocessor(preprocessor(), enabled)
198
198
199 else:
199 else:
200 # Preprocessor is an instance of something without a __call__
200 # Preprocessor is an instance of something without a __call__
201 # attribute.
201 # attribute.
202 raise TypeError('preprocessor')
202 raise TypeError('preprocessor')
203
203
204
204
205 def _init_preprocessors(self):
205 def _init_preprocessors(self):
206 """
206 """
207 Register all of the preprocessors needed for this exporter, disabled
207 Register all of the preprocessors needed for this exporter, disabled
208 unless specified explicitly.
208 unless specified explicitly.
209 """
209 """
210 if self._preprocessors is None:
210 if self._preprocessors is None:
211 self._preprocessors = []
211 self._preprocessors = []
212
212
213 #Load default preprocessors (not necessarly enabled by default).
213 #Load default preprocessors (not necessarly enabled by default).
214 if self.default_preprocessors:
214 if self.default_preprocessors:
215 for preprocessor in self.default_preprocessors:
215 for preprocessor in self.default_preprocessors:
216 self.register_preprocessor(preprocessor)
216 self.register_preprocessor(preprocessor)
217
217
218 #Load user preprocessors. Enable by default.
218 #Load user preprocessors. Enable by default.
219 if self.preprocessors:
219 if self.preprocessors:
220 for preprocessor in self.preprocessors:
220 for preprocessor in self.preprocessors:
221 self.register_preprocessor(preprocessor, enabled=True)
221 self.register_preprocessor(preprocessor, enabled=True)
222
222
223
223
224 def _init_resources(self, resources):
224 def _init_resources(self, resources):
225
225
226 #Make sure the resources dict is of ResourcesDict type.
226 #Make sure the resources dict is of ResourcesDict type.
227 if resources is None:
227 if resources is None:
228 resources = ResourcesDict()
228 resources = ResourcesDict()
229 if not isinstance(resources, ResourcesDict):
229 if not isinstance(resources, ResourcesDict):
230 new_resources = ResourcesDict()
230 new_resources = ResourcesDict()
231 new_resources.update(resources)
231 new_resources.update(resources)
232 resources = new_resources
232 resources = new_resources
233
233
234 #Make sure the metadata extension exists in resources
234 #Make sure the metadata extension exists in resources
235 if 'metadata' in resources:
235 if 'metadata' in resources:
236 if not isinstance(resources['metadata'], ResourcesDict):
236 if not isinstance(resources['metadata'], ResourcesDict):
237 resources['metadata'] = ResourcesDict(resources['metadata'])
237 resources['metadata'] = ResourcesDict(resources['metadata'])
238 else:
238 else:
239 resources['metadata'] = ResourcesDict()
239 resources['metadata'] = ResourcesDict()
240 if not resources['metadata']['name']:
240 if not resources['metadata']['name']:
241 resources['metadata']['name'] = 'Notebook'
241 resources['metadata']['name'] = 'Notebook'
242
242
243 #Set the output extension
243 #Set the output extension
244 resources['output_extension'] = self.file_extension
244 resources['output_extension'] = self.file_extension
245 return resources
245 return resources
246
246
247
247
248 def _preprocess(self, nb, resources):
248 def _preprocess(self, nb, resources):
249 """
249 """
250 Preprocess the notebook before passing it into the Jinja engine.
250 Preprocess the notebook before passing it into the Jinja engine.
251 To preprocess the notebook is to apply all of the
251 To preprocess the notebook is to apply all of the
252
252
253 Parameters
253 Parameters
254 ----------
254 ----------
255 nb : notebook node
255 nb : notebook node
256 notebook that is being exported.
256 notebook that is being exported.
257 resources : a dict of additional resources that
257 resources : a dict of additional resources that
258 can be accessed read/write by preprocessors
258 can be accessed read/write by preprocessors
259 """
259 """
260
260
261 # Do a copy.deepcopy first,
261 # Do a copy.deepcopy first,
262 # we are never safe enough with what the preprocessors could do.
262 # we are never safe enough with what the preprocessors could do.
263 nbc = copy.deepcopy(nb)
263 nbc = copy.deepcopy(nb)
264 resc = copy.deepcopy(resources)
264 resc = copy.deepcopy(resources)
265
265
266 #Run each preprocessor on the notebook. Carry the output along
266 #Run each preprocessor on the notebook. Carry the output along
267 #to each preprocessor
267 #to each preprocessor
268 for preprocessor in self._preprocessors:
268 for preprocessor in self._preprocessors:
269 nbc, resc = preprocessor(nbc, resc)
269 nbc, resc = preprocessor(nbc, resc)
270 return nbc, resc
270 return nbc, resc
@@ -1,55 +1,56 b''
1 """
1 """HTML Exporter class"""
2 Exporter that exports Basic HTML.
3 """
4
2
5 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
7 #
5 #
8 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
9 #
7 #
10 # 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.
11 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
12
10
13 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
14 # Imports
12 # Imports
15 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
16
14
17 from IPython.utils.traitlets import Unicode, List
15 from IPython.utils.traitlets import Unicode, List
18
16
19 from IPython.nbconvert import preprocessors
17 from IPython.nbconvert import preprocessors
20 from IPython.config import Config
18 from IPython.config import Config
21
19
22 from .templateexporter import TemplateExporter
20 from .templateexporter import TemplateExporter
23
21
24 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
25 # Classes
23 # Classes
26 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
27
25
28 class HTMLExporter(TemplateExporter):
26 class HTMLExporter(TemplateExporter):
29 """
27 """
30 Exports a basic HTML document. This exporter assists with the export of
28 Exports a basic HTML document. This exporter assists with the export of
31 HTML. Inherit from it if you are writing your own HTML template and need
29 HTML. Inherit from it if you are writing your own HTML template and need
32 custom preprocessors/filters. If you don't need custom preprocessors/
30 custom preprocessors/filters. If you don't need custom preprocessors/
33 filters, just change the 'template_file' config option.
31 filters, just change the 'template_file' config option.
34 """
32 """
35
33
36 file_extension = Unicode(
34 file_extension = Unicode(
37 'html', config=True,
35 'html', config=True,
38 help="Extension of the file that should be written to disk"
36 help="Extension of the file that should be written to disk"
39 )
37 )
40
38
41 default_template = Unicode('full', config=True, help="""Flavor of the data
39 default_template = Unicode('full', config=True, help="""Flavor of the data
42 format to use. I.E. 'full' or 'basic'""")
40 format to use. I.E. 'full' or 'basic'""")
43
41
42 def _raw_format_default(self):
43 return 'html'
44
44 @property
45 @property
45 def default_config(self):
46 def default_config(self):
46 c = Config({
47 c = Config({
47 'CSSHTMLHeaderPreprocessor':{
48 'CSSHTMLHeaderPreprocessor':{
48 'enabled':True
49 'enabled':True
49 },
50 },
50 'HighlightMagicsPreprocessor': {
51 'HighlightMagicsPreprocessor': {
51 'enabled':True
52 'enabled':True
52 }
53 }
53 })
54 })
54 c.merge(super(HTMLExporter,self).default_config)
55 c.merge(super(HTMLExporter,self).default_config)
55 return c
56 return c
@@ -1,94 +1,93 b''
1 """
1 """LaTeX Exporter class"""
2 Exporter that allows Latex Jinja templates to work. Contains logic to
2
3 appropriately prepare IPYNB files for export to LaTeX. Including but
4 not limited to escaping LaTeX, fixing math region tags, using special
5 tags to circumvent Jinja/Latex syntax conflicts.
6 """
7 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
9 #
5 #
10 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
11 #
7 #
12 # 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.
13 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
14
10
15 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
16 # Imports
12 # Imports
17 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
18
14
19 # Stdlib imports
15 # Stdlib imports
20 import os
16 import os
21
17
22 # IPython imports
18 # IPython imports
23 from IPython.utils.traitlets import Unicode, List
19 from IPython.utils.traitlets import Unicode, List
24 from IPython.config import Config
20 from IPython.config import Config
25
21
26 from IPython.nbconvert import filters, preprocessors
22 from IPython.nbconvert import filters, preprocessors
27 from .templateexporter import TemplateExporter
23 from .templateexporter import TemplateExporter
28
24
29 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
30 # Classes and functions
26 # Classes and functions
31 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
32
28
33 class LatexExporter(TemplateExporter):
29 class LatexExporter(TemplateExporter):
34 """
30 """
35 Exports to a Latex template. Inherit from this class if your template is
31 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
32 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.
33 you are writing your own HTML template and need custom tranformers/filters.
38 If you don't need custom tranformers/filters, just change the
34 If you don't need custom tranformers/filters, just change the
39 'template_file' config option. Place your template in the special "/latex"
35 'template_file' config option. Place your template in the special "/latex"
40 subfolder of the "../templates" folder.
36 subfolder of the "../templates" folder.
41 """
37 """
42
38
43 file_extension = Unicode(
39 file_extension = Unicode(
44 'tex', config=True,
40 'tex', config=True,
45 help="Extension of the file that should be written to disk")
41 help="Extension of the file that should be written to disk")
46
42
47 default_template = Unicode('article', config=True, help="""Template of the
43 default_template = Unicode('article', config=True, help="""Template of the
48 data format to use. I.E. 'article' or 'report'""")
44 data format to use. I.E. 'article' or 'report'""")
49
45
50 #Latex constants
46 #Latex constants
51 default_template_path = Unicode(
47 default_template_path = Unicode(
52 os.path.join("..", "templates", "latex"), config=True,
48 os.path.join("..", "templates", "latex"), config=True,
53 help="Path where the template files are located.")
49 help="Path where the template files are located.")
54
50
55 template_skeleton_path = Unicode(
51 template_skeleton_path = Unicode(
56 os.path.join("..", "templates", "latex", "skeleton"), config=True,
52 os.path.join("..", "templates", "latex", "skeleton"), config=True,
57 help="Path where the template skeleton files are located.")
53 help="Path where the template skeleton files are located.")
58
54
59 #Special Jinja2 syntax that will not conflict when exporting latex.
55 #Special Jinja2 syntax that will not conflict when exporting latex.
60 jinja_comment_block_start = Unicode("((=", config=True)
56 jinja_comment_block_start = Unicode("((=", config=True)
61 jinja_comment_block_end = Unicode("=))", config=True)
57 jinja_comment_block_end = Unicode("=))", config=True)
62 jinja_variable_block_start = Unicode("(((", config=True)
58 jinja_variable_block_start = Unicode("(((", config=True)
63 jinja_variable_block_end = Unicode(")))", config=True)
59 jinja_variable_block_end = Unicode(")))", config=True)
64 jinja_logic_block_start = Unicode("((*", config=True)
60 jinja_logic_block_start = Unicode("((*", config=True)
65 jinja_logic_block_end = Unicode("*))", config=True)
61 jinja_logic_block_end = Unicode("*))", config=True)
66
62
67 #Extension that the template files use.
63 #Extension that the template files use.
68 template_extension = Unicode(".tplx", config=True)
64 template_extension = Unicode(".tplx", config=True)
69
65
66 def _raw_format_default(self):
67 return 'latex'
68
70
69
71 @property
70 @property
72 def default_config(self):
71 def default_config(self):
73 c = Config({
72 c = Config({
74 'NbConvertBase': {
73 'NbConvertBase': {
75 'display_data_priority' : ['latex', 'pdf', 'png', 'jpg', 'svg', 'jpeg', 'text']
74 'display_data_priority' : ['latex', 'pdf', 'png', 'jpg', 'svg', 'jpeg', 'text']
76 },
75 },
77 'ExtractOutputPreprocessor': {
76 'ExtractOutputPreprocessor': {
78 'enabled':True
77 'enabled':True
79 },
78 },
80 'SVG2PDFPreprocessor': {
79 'SVG2PDFPreprocessor': {
81 'enabled':True
80 'enabled':True
82 },
81 },
83 'LatexPreprocessor': {
82 'LatexPreprocessor': {
84 'enabled':True
83 'enabled':True
85 },
84 },
86 'SphinxPreprocessor': {
85 'SphinxPreprocessor': {
87 'enabled':True
86 'enabled':True
88 },
87 },
89 'HighlightMagicsPreprocessor': {
88 'HighlightMagicsPreprocessor': {
90 'enabled':True
89 'enabled':True
91 }
90 }
92 })
91 })
93 c.merge(super(LatexExporter,self).default_config)
92 c.merge(super(LatexExporter,self).default_config)
94 return c
93 return c
@@ -1,38 +1,43 b''
1 """
1 """Markdown Exporter class"""
2 Exporter that will export your ipynb to Markdown.
2
3 """
4 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
6 #
5 #
7 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
8 #
7 #
9 # 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.
10 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
11
10
12 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
13 # Imports
12 # Imports
14 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
15
14
16 from IPython.config import Config
15 from IPython.config import Config
17 from IPython.utils.traitlets import Unicode
16 from IPython.utils.traitlets import Unicode
18
17
19 from .templateexporter import TemplateExporter
18 from .templateexporter import TemplateExporter
20
19
21 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
22 # Classes
21 # Classes
23 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
24
23
25 class MarkdownExporter(TemplateExporter):
24 class MarkdownExporter(TemplateExporter):
26 """
25 """
27 Exports to a markdown document (.md)
26 Exports to a markdown document (.md)
28 """
27 """
29
28
30 file_extension = Unicode(
29 file_extension = Unicode(
31 'md', config=True,
30 'md', config=True,
32 help="Extension of the file that should be written to disk")
31 help="Extension of the file that should be written to disk")
33
32
33 def _raw_format_default(self):
34 return 'markdown'
35
36 def _raw_formats_default(self):
37 return ['md', 'markdown', 'html']
38
34 @property
39 @property
35 def default_config(self):
40 def default_config(self):
36 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
41 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
37 c.merge(super(MarkdownExporter,self).default_config)
42 c.merge(super(MarkdownExporter,self).default_config)
38 return c
43 return c
@@ -1,31 +1,37 b''
1 """
1 """Python script Exporter class"""
2 Python exporter which exports Notebook code into a PY file.
2
3 """
4 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
6 #
5 #
7 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
8 #
7 #
9 # 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.
10 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
11
10
12 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
13 # Imports
12 # Imports
14 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
15
14
16 from IPython.utils.traitlets import Unicode
15 from IPython.utils.traitlets import Unicode
17
16
18 from .templateexporter import TemplateExporter
17 from .templateexporter import TemplateExporter
19
18
20 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
21 # Classes
20 # Classes
22 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
23
22
24 class PythonExporter(TemplateExporter):
23 class PythonExporter(TemplateExporter):
25 """
24 """
26 Exports a Python code file.
25 Exports a Python code file.
27 """
26 """
28
27
29 file_extension = Unicode(
28 file_extension = Unicode(
30 'py', config=True,
29 'py', config=True,
31 help="Extension of the file that should be written to disk")
30 help="Extension of the file that should be written to disk")
31
32 def _raw_format_default(self):
33 return 'python'
34
35 def _raw_formats_default(self):
36 return ['py', 'python']
37
@@ -1,38 +1,43 b''
1 """
1 """restructuredText Exporter class"""
2 Exporter for exporting notebooks to restructured text.
2
3 """
4 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
6 #
5 #
7 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
8 #
7 #
9 # 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.
10 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
11
10
12 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
13 # Imports
12 # Imports
14 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
15
14
16 from IPython.utils.traitlets import Unicode
15 from IPython.utils.traitlets import Unicode
17 from IPython.config import Config
16 from IPython.config import Config
18
17
19 from .templateexporter import TemplateExporter
18 from .templateexporter import TemplateExporter
20
19
21 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
22 # Classes
21 # Classes
23 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
24
23
25 class RSTExporter(TemplateExporter):
24 class RSTExporter(TemplateExporter):
26 """
25 """
27 Exports restructured text documents.
26 Exports restructured text documents.
28 """
27 """
29
28
30 file_extension = Unicode(
29 file_extension = Unicode(
31 'rst', config=True,
30 'rst', config=True,
32 help="Extension of the file that should be written to disk")
31 help="Extension of the file that should be written to disk")
33
32
33 def _raw_format_default(self):
34 return 'rst'
35
36 def _raw_formats_default(self):
37 return ['rst', 'restructuredtext']
38
34 @property
39 @property
35 def default_config(self):
40 def default_config(self):
36 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
41 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
37 c.merge(super(RSTExporter,self).default_config)
42 c.merge(super(RSTExporter,self).default_config)
38 return c
43 return c
@@ -1,55 +1,45 b''
1 """
1 """HTML slide show Exporter class"""
2 Contains slide show exporter
3 """
4
2
5 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
7 #
5 #
8 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
9 #
7 #
10 # 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.
11 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
12
10
13 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
14 # Imports
12 # Imports
15 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
16
14
17 from IPython.utils.traitlets import Unicode
15 from IPython.utils.traitlets import Unicode
18
16
19 from IPython.nbconvert import preprocessors
17 from IPython.nbconvert import preprocessors
20 from IPython.config import Config
18 from IPython.config import Config
21
19
22 from .templateexporter import TemplateExporter
20 from .html import HTMLExporter
23
21
24 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
25 # Classes
23 # Classes
26 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
27
25
28 class SlidesExporter(TemplateExporter):
26 class SlidesExporter(HTMLExporter):
29 """
27 """Exports HTML slides with reveal.js"""
30 Exports slides
31 """
32
28
33 file_extension = Unicode(
29 file_extension = Unicode(
34 'slides.html', config=True,
30 'slides.html', config=True,
35 help="Extension of the file that should be written to disk"
31 help="Extension of the file that should be written to disk"
36 )
32 )
37
33
38 default_template = Unicode('reveal', config=True, help="""Template of the
34 default_template = Unicode('reveal', config=True, help="""Template of the
39 data format to use. I.E. 'reveal'""")
35 data format to use. I.E. 'reveal'""")
40
36
41 @property
37 @property
42 def default_config(self):
38 def default_config(self):
43 c = Config({
39 c = Config({
44 'CSSHTMLHeaderPreprocessor':{
45 'enabled':True
46 },
47 'RevealHelpPreprocessor':{
40 'RevealHelpPreprocessor': {
48 'enabled':True,
41 'enabled': True,
49 },
42 },
50 'HighlightMagicsPreprocessor': {
51 'enabled':True
52 }
53 })
43 })
54 c.merge(super(SlidesExporter,self).default_config)
44 c.merge(super(SlidesExporter,self).default_config)
55 return c
45 return c
@@ -1,315 +1,324 b''
1 """This module defines Exporter, a highly configurable converter
1 """This module defines TemplateExporter, 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 os
20 import os
21
21
22 # other libs/dependencies
22 # other libs/dependencies
23 from jinja2 import Environment, FileSystemLoader, ChoiceLoader, TemplateNotFound
23 from jinja2 import Environment, FileSystemLoader, ChoiceLoader, TemplateNotFound
24
24
25 # IPython imports
25 # IPython imports
26 from IPython.utils.traitlets import MetaHasTraits, Unicode, List, Dict, Any
26 from IPython.utils.traitlets import MetaHasTraits, Unicode, List, Dict, Any
27 from IPython.utils.importstring import import_item
27 from IPython.utils.importstring import import_item
28 from IPython.utils import py3compat, text
28 from IPython.utils import py3compat, text
29
29
30 from IPython.nbformat.current import docstring_nbformat_mod
30 from IPython.nbformat.current import docstring_nbformat_mod
31 from IPython.nbconvert import filters
31 from IPython.nbconvert import filters
32 from .exporter import Exporter
32 from .exporter import Exporter
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Globals and constants
35 # Globals and constants
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 #Jinja2 extensions to load.
38 #Jinja2 extensions to load.
39 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
39 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
40
40
41 default_filters = {
41 default_filters = {
42 'indent': text.indent,
42 'indent': text.indent,
43 'markdown2html': filters.markdown2html,
43 'markdown2html': filters.markdown2html,
44 'ansi2html': filters.ansi2html,
44 'ansi2html': filters.ansi2html,
45 'filter_data_type': filters.DataTypeFilter,
45 'filter_data_type': filters.DataTypeFilter,
46 'get_lines': filters.get_lines,
46 'get_lines': filters.get_lines,
47 'highlight2html': filters.Highlight2Html,
47 'highlight2html': filters.Highlight2Html,
48 'highlight2latex': filters.Highlight2Latex,
48 'highlight2latex': filters.Highlight2Latex,
49 'ipython2python': filters.ipython2python,
49 'ipython2python': filters.ipython2python,
50 'posix_path': filters.posix_path,
50 'posix_path': filters.posix_path,
51 'markdown2latex': filters.markdown2latex,
51 'markdown2latex': filters.markdown2latex,
52 'markdown2rst': filters.markdown2rst,
52 'markdown2rst': filters.markdown2rst,
53 'comment_lines': filters.comment_lines,
53 'comment_lines': filters.comment_lines,
54 'strip_ansi': filters.strip_ansi,
54 'strip_ansi': filters.strip_ansi,
55 'strip_dollars': filters.strip_dollars,
55 'strip_dollars': filters.strip_dollars,
56 'strip_files_prefix': filters.strip_files_prefix,
56 'strip_files_prefix': filters.strip_files_prefix,
57 'html2text' : filters.html2text,
57 'html2text' : filters.html2text,
58 'add_anchor': filters.add_anchor,
58 'add_anchor': filters.add_anchor,
59 'ansi2latex': filters.ansi2latex,
59 'ansi2latex': filters.ansi2latex,
60 'wrap_text': filters.wrap_text,
60 'wrap_text': filters.wrap_text,
61 'escape_latex': filters.escape_latex,
61 'escape_latex': filters.escape_latex,
62 'citation2latex': filters.citation2latex,
62 'citation2latex': filters.citation2latex,
63 'path2url': filters.path2url,
63 'path2url': filters.path2url,
64 'add_prompts': filters.add_prompts,
64 'add_prompts': filters.add_prompts,
65 }
65 }
66
66
67 #-----------------------------------------------------------------------------
67 #-----------------------------------------------------------------------------
68 # Class
68 # Class
69 #-----------------------------------------------------------------------------
69 #-----------------------------------------------------------------------------
70
70
71 class TemplateExporter(Exporter):
71 class TemplateExporter(Exporter):
72 """
72 """
73 Exports notebooks into other file formats. Uses Jinja 2 templating engine
73 Exports notebooks into other file formats. Uses Jinja 2 templating engine
74 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
75 template type along with new filters/preprocessors. If the filters/
75 template type along with new filters/preprocessors. If the filters/
76 preprocessors provided by default suffice, there is no need to inherit from
76 preprocessors provided by default suffice, there is no need to inherit from
77 this class. Instead, override the template_file and file_extension
77 this class. Instead, override the template_file and file_extension
78 traits via a config file.
78 traits via a config file.
79
79
80 {filters}
80 {filters}
81 """
81 """
82
82
83 # finish the docstring
83 # finish the docstring
84 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
84 __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))
85
85
86
86
87 template_file = Unicode(u'default',
87 template_file = Unicode(u'default',
88 config=True,
88 config=True,
89 help="Name of the template file to use")
89 help="Name of the template file to use")
90 def _template_file_changed(self, name, old, new):
90 def _template_file_changed(self, name, old, new):
91 if new == 'default':
91 if new == 'default':
92 self.template_file = self.default_template
92 self.template_file = self.default_template
93 else:
93 else:
94 self.template_file = new
94 self.template_file = new
95 self.template = None
95 self.template = None
96 self._load_template()
96 self._load_template()
97
97
98 default_template = Unicode(u'')
98 default_template = Unicode(u'')
99 template = Any()
99 template = Any()
100 environment = Any()
100 environment = Any()
101
101
102 template_path = List(['.'], config=True)
102 template_path = List(['.'], config=True)
103 def _template_path_changed(self, name, old, new):
103 def _template_path_changed(self, name, old, new):
104 self._load_template()
104 self._load_template()
105
105
106 default_template_path = Unicode(
106 default_template_path = Unicode(
107 os.path.join("..", "templates"),
107 os.path.join("..", "templates"),
108 help="Path where the template files are located.")
108 help="Path where the template files are located.")
109
109
110 template_skeleton_path = Unicode(
110 template_skeleton_path = Unicode(
111 os.path.join("..", "templates", "skeleton"),
111 os.path.join("..", "templates", "skeleton"),
112 help="Path where the template skeleton files are located.")
112 help="Path where the template skeleton files are located.")
113
113
114 #Jinja block definitions
114 #Jinja block definitions
115 jinja_comment_block_start = Unicode("", config=True)
115 jinja_comment_block_start = Unicode("", config=True)
116 jinja_comment_block_end = Unicode("", config=True)
116 jinja_comment_block_end = Unicode("", config=True)
117 jinja_variable_block_start = Unicode("", config=True)
117 jinja_variable_block_start = Unicode("", config=True)
118 jinja_variable_block_end = Unicode("", config=True)
118 jinja_variable_block_end = Unicode("", config=True)
119 jinja_logic_block_start = Unicode("", config=True)
119 jinja_logic_block_start = Unicode("", config=True)
120 jinja_logic_block_end = Unicode("", config=True)
120 jinja_logic_block_end = Unicode("", config=True)
121
121
122 #Extension that the template files use.
122 #Extension that the template files use.
123 template_extension = Unicode(".tpl", config=True)
123 template_extension = Unicode(".tpl", config=True)
124
124
125 filters = Dict(config=True,
125 filters = Dict(config=True,
126 help="""Dictionary of filters, by name and namespace, to add to the Jinja
126 help="""Dictionary of filters, by name and namespace, to add to the Jinja
127 environment.""")
127 environment.""")
128
128
129 raw_format = Unicode('')
130 raw_formats = List(config=True,
131 help="""formats of raw cells to be included in this Exporter's output."""
132 )
133 def _raw_formats_default(self):
134 return [self.raw_format]
135
129
136
130 def __init__(self, config=None, extra_loaders=None, **kw):
137 def __init__(self, config=None, extra_loaders=None, **kw):
131 """
138 """
132 Public constructor
139 Public constructor
133
140
134 Parameters
141 Parameters
135 ----------
142 ----------
136 config : config
143 config : config
137 User configuration instance.
144 User configuration instance.
138 extra_loaders : list[of Jinja Loaders]
145 extra_loaders : list[of Jinja Loaders]
139 ordered list of Jinja loader to find templates. Will be tried in order
146 ordered list of Jinja loader to find templates. Will be tried in order
140 before the default FileSystem ones.
147 before the default FileSystem ones.
141 template : str (optional, kw arg)
148 template : str (optional, kw arg)
142 Template to use when exporting.
149 Template to use when exporting.
143 """
150 """
144 super(TemplateExporter, self).__init__(config=config, **kw)
151 super(TemplateExporter, self).__init__(config=config, **kw)
145
152
146 #Init
153 #Init
147 self._init_template()
154 self._init_template()
148 self._init_environment(extra_loaders=extra_loaders)
155 self._init_environment(extra_loaders=extra_loaders)
149 self._init_preprocessors()
156 self._init_preprocessors()
150 self._init_filters()
157 self._init_filters()
151
158
152
159
153 def _load_template(self):
160 def _load_template(self):
154 """Load the Jinja template object from the template file
161 """Load the Jinja template object from the template file
155
162
156 This is a no-op if the template attribute is already defined,
163 This is a no-op if the template attribute is already defined,
157 or the Jinja environment is not setup yet.
164 or the Jinja environment is not setup yet.
158
165
159 This is triggered by various trait changes that would change the template.
166 This is triggered by various trait changes that would change the template.
160 """
167 """
161 if self.template is not None:
168 if self.template is not None:
162 return
169 return
163 # called too early, do nothing
170 # called too early, do nothing
164 if self.environment is None:
171 if self.environment is None:
165 return
172 return
166 # Try different template names during conversion. First try to load the
173 # Try different template names during conversion. First try to load the
167 # template by name with extension added, then try loading the template
174 # template by name with extension added, then try loading the template
168 # as if the name is explicitly specified, then try the name as a
175 # as if the name is explicitly specified, then try the name as a
169 # 'flavor', and lastly just try to load the template by module name.
176 # 'flavor', and lastly just try to load the template by module name.
170 module_name = self.__module__.rsplit('.', 1)[-1]
177 module_name = self.__module__.rsplit('.', 1)[-1]
171 try_names = []
178 try_names = []
172 if self.template_file:
179 if self.template_file:
173 try_names.extend([
180 try_names.extend([
174 self.template_file + self.template_extension,
181 self.template_file + self.template_extension,
175 self.template_file,
182 self.template_file,
176 module_name + '_' + self.template_file + self.template_extension,
183 module_name + '_' + self.template_file + self.template_extension,
177 ])
184 ])
178 try_names.append(module_name + self.template_extension)
185 try_names.append(module_name + self.template_extension)
179 for try_name in try_names:
186 for try_name in try_names:
180 self.log.debug("Attempting to load template %s", try_name)
187 self.log.debug("Attempting to load template %s", try_name)
181 try:
188 try:
182 self.template = self.environment.get_template(try_name)
189 self.template = self.environment.get_template(try_name)
183 except (TemplateNotFound, IOError):
190 except (TemplateNotFound, IOError):
184 pass
191 pass
185 except Exception as e:
192 except Exception as e:
186 self.log.warn("Unexpected exception loading template: %s", try_name, exc_info=True)
193 self.log.warn("Unexpected exception loading template: %s", try_name, exc_info=True)
187 else:
194 else:
188 self.log.info("Loaded template %s", try_name)
195 self.log.info("Loaded template %s", try_name)
189 break
196 break
190
197
191 @docstring_nbformat_mod
198 @docstring_nbformat_mod
192 def from_notebook_node(self, nb, resources=None, **kw):
199 def from_notebook_node(self, nb, resources=None, **kw):
193 """
200 """
194 Convert a notebook from a notebook node instance.
201 Convert a notebook from a notebook node instance.
195
202
196 Parameters
203 Parameters
197 ----------
204 ----------
198 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
205 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
199 Notebook node
206 Notebook node
200 resources : dict
207 resources : dict
201 Additional resources that can be accessed read/write by
208 Additional resources that can be accessed read/write by
202 preprocessors and filters.
209 preprocessors and filters.
203 """
210 """
204 nb_copy, resources = super(TemplateExporter, self).from_notebook_node(nb, resources, **kw)
211 nb_copy, resources = super(TemplateExporter, self).from_notebook_node(nb, resources, **kw)
212 resources.setdefault('raw_format', self.raw_format)
213 resources.setdefault('raw_formats', self.raw_formats)
205
214
206 self._load_template()
215 self._load_template()
207
216
208 if self.template is not None:
217 if self.template is not None:
209 output = self.template.render(nb=nb_copy, resources=resources)
218 output = self.template.render(nb=nb_copy, resources=resources)
210 else:
219 else:
211 raise IOError('template file "%s" could not be found' % self.template_file)
220 raise IOError('template file "%s" could not be found' % self.template_file)
212 return output, resources
221 return output, resources
213
222
214
223
215 def register_filter(self, name, jinja_filter):
224 def register_filter(self, name, jinja_filter):
216 """
225 """
217 Register a filter.
226 Register a filter.
218 A filter is a function that accepts and acts on one string.
227 A filter is a function that accepts and acts on one string.
219 The filters are accesible within the Jinja templating engine.
228 The filters are accesible within the Jinja templating engine.
220
229
221 Parameters
230 Parameters
222 ----------
231 ----------
223 name : str
232 name : str
224 name to give the filter in the Jinja engine
233 name to give the filter in the Jinja engine
225 filter : filter
234 filter : filter
226 """
235 """
227 if jinja_filter is None:
236 if jinja_filter is None:
228 raise TypeError('filter')
237 raise TypeError('filter')
229 isclass = isinstance(jinja_filter, type)
238 isclass = isinstance(jinja_filter, type)
230 constructed = not isclass
239 constructed = not isclass
231
240
232 #Handle filter's registration based on it's type
241 #Handle filter's registration based on it's type
233 if constructed and isinstance(jinja_filter, py3compat.string_types):
242 if constructed and isinstance(jinja_filter, py3compat.string_types):
234 #filter is a string, import the namespace and recursively call
243 #filter is a string, import the namespace and recursively call
235 #this register_filter method
244 #this register_filter method
236 filter_cls = import_item(jinja_filter)
245 filter_cls = import_item(jinja_filter)
237 return self.register_filter(name, filter_cls)
246 return self.register_filter(name, filter_cls)
238
247
239 if constructed and hasattr(jinja_filter, '__call__'):
248 if constructed and hasattr(jinja_filter, '__call__'):
240 #filter is a function, no need to construct it.
249 #filter is a function, no need to construct it.
241 self.environment.filters[name] = jinja_filter
250 self.environment.filters[name] = jinja_filter
242 return jinja_filter
251 return jinja_filter
243
252
244 elif isclass and isinstance(jinja_filter, MetaHasTraits):
253 elif isclass and isinstance(jinja_filter, MetaHasTraits):
245 #filter is configurable. Make sure to pass in new default for
254 #filter is configurable. Make sure to pass in new default for
246 #the enabled flag if one was specified.
255 #the enabled flag if one was specified.
247 filter_instance = jinja_filter(parent=self)
256 filter_instance = jinja_filter(parent=self)
248 self.register_filter(name, filter_instance )
257 self.register_filter(name, filter_instance )
249
258
250 elif isclass:
259 elif isclass:
251 #filter is not configurable, construct it
260 #filter is not configurable, construct it
252 filter_instance = jinja_filter()
261 filter_instance = jinja_filter()
253 self.register_filter(name, filter_instance)
262 self.register_filter(name, filter_instance)
254
263
255 else:
264 else:
256 #filter is an instance of something without a __call__
265 #filter is an instance of something without a __call__
257 #attribute.
266 #attribute.
258 raise TypeError('filter')
267 raise TypeError('filter')
259
268
260
269
261 def _init_template(self):
270 def _init_template(self):
262 """
271 """
263 Make sure a template name is specified. If one isn't specified, try to
272 Make sure a template name is specified. If one isn't specified, try to
264 build one from the information we know.
273 build one from the information we know.
265 """
274 """
266 self._template_file_changed('template_file', self.template_file, self.template_file)
275 self._template_file_changed('template_file', self.template_file, self.template_file)
267
276
268
277
269 def _init_environment(self, extra_loaders=None):
278 def _init_environment(self, extra_loaders=None):
270 """
279 """
271 Create the Jinja templating environment.
280 Create the Jinja templating environment.
272 """
281 """
273 here = os.path.dirname(os.path.realpath(__file__))
282 here = os.path.dirname(os.path.realpath(__file__))
274 loaders = []
283 loaders = []
275 if extra_loaders:
284 if extra_loaders:
276 loaders.extend(extra_loaders)
285 loaders.extend(extra_loaders)
277
286
278 paths = self.template_path
287 paths = self.template_path
279 paths.extend([os.path.join(here, self.default_template_path),
288 paths.extend([os.path.join(here, self.default_template_path),
280 os.path.join(here, self.template_skeleton_path)])
289 os.path.join(here, self.template_skeleton_path)])
281 loaders.append(FileSystemLoader(paths))
290 loaders.append(FileSystemLoader(paths))
282
291
283 self.environment = Environment(
292 self.environment = Environment(
284 loader= ChoiceLoader(loaders),
293 loader= ChoiceLoader(loaders),
285 extensions=JINJA_EXTENSIONS
294 extensions=JINJA_EXTENSIONS
286 )
295 )
287
296
288 #Set special Jinja2 syntax that will not conflict with latex.
297 #Set special Jinja2 syntax that will not conflict with latex.
289 if self.jinja_logic_block_start:
298 if self.jinja_logic_block_start:
290 self.environment.block_start_string = self.jinja_logic_block_start
299 self.environment.block_start_string = self.jinja_logic_block_start
291 if self.jinja_logic_block_end:
300 if self.jinja_logic_block_end:
292 self.environment.block_end_string = self.jinja_logic_block_end
301 self.environment.block_end_string = self.jinja_logic_block_end
293 if self.jinja_variable_block_start:
302 if self.jinja_variable_block_start:
294 self.environment.variable_start_string = self.jinja_variable_block_start
303 self.environment.variable_start_string = self.jinja_variable_block_start
295 if self.jinja_variable_block_end:
304 if self.jinja_variable_block_end:
296 self.environment.variable_end_string = self.jinja_variable_block_end
305 self.environment.variable_end_string = self.jinja_variable_block_end
297 if self.jinja_comment_block_start:
306 if self.jinja_comment_block_start:
298 self.environment.comment_start_string = self.jinja_comment_block_start
307 self.environment.comment_start_string = self.jinja_comment_block_start
299 if self.jinja_comment_block_end:
308 if self.jinja_comment_block_end:
300 self.environment.comment_end_string = self.jinja_comment_block_end
309 self.environment.comment_end_string = self.jinja_comment_block_end
301
310
302
311
303 def _init_filters(self):
312 def _init_filters(self):
304 """
313 """
305 Register all of the filters required for the exporter.
314 Register all of the filters required for the exporter.
306 """
315 """
307
316
308 #Add default filters to the Jinja2 environment
317 #Add default filters to the Jinja2 environment
309 for key, value in default_filters.items():
318 for key, value in default_filters.items():
310 self.register_filter(key, value)
319 self.register_filter(key, value)
311
320
312 #Load user filters. Overwrite existing filters if need be.
321 #Load user filters. Overwrite existing filters if need be.
313 if self.filters:
322 if self.filters:
314 for key, user_filter in self.filters.items():
323 for key, user_filter in self.filters.items():
315 self.register_filter(key, user_filter)
324 self.register_filter(key, user_filter)
General Comments 0
You need to be logged in to leave comments. Login now