##// END OF EJS Templates
Condense raw_mimetype and mime_type traitlets into output_mimetype
Thomas Kluyver -
Show More
@@ -1,83 +1,85 b''
1 import os
1 import os
2
2
3 from tornado import web
3 from tornado import web
4
4
5 from ..base.handlers import IPythonHandler
5 from ..base.handlers import IPythonHandler
6 from IPython.nbformat.current import to_notebook_json
6 from IPython.nbformat.current import to_notebook_json
7 from IPython.nbconvert.exporters.export import exporter_map
7 from IPython.nbconvert.exporters.export import exporter_map
8 from IPython.utils import tz
8 from IPython.utils import tz
9
9
10
10
11 def has_resource_files(resources):
11 def has_resource_files(resources):
12 output_files_dir = resources.get('output_files_dir', "")
12 output_files_dir = resources.get('output_files_dir', "")
13 return bool(os.path.isdir(output_files_dir) and \
13 return bool(os.path.isdir(output_files_dir) and \
14 os.listdir(output_files_dir))
14 os.listdir(output_files_dir))
15
15
16 class NbconvertFileHandler(IPythonHandler):
16 class NbconvertFileHandler(IPythonHandler):
17
17
18 SUPPORTED_METHODS = ('GET',)
18 SUPPORTED_METHODS = ('GET',)
19
19
20 @web.authenticated
20 @web.authenticated
21 def get(self, format, path='', name=None):
21 def get(self, format, path='', name=None):
22 exporter = exporter_map[format]()
22 exporter = exporter_map[format]()
23
23
24 path = path.strip('/')
24 path = path.strip('/')
25 os_path = self.notebook_manager.get_os_path(name, path)
25 os_path = self.notebook_manager.get_os_path(name, path)
26 if not os.path.isfile(os_path):
26 if not os.path.isfile(os_path):
27 raise web.HTTPError(404, u'Notebook does not exist: %s' % name)
27 raise web.HTTPError(404, u'Notebook does not exist: %s' % name)
28
28
29 info = os.stat(os_path)
29 info = os.stat(os_path)
30 self.set_header('Last-Modified', tz.utcfromtimestamp(info.st_mtime))
30 self.set_header('Last-Modified', tz.utcfromtimestamp(info.st_mtime))
31
31
32 # Force download if requested
32 # Force download if requested
33 if self.get_argument('download', 'false').lower() == 'true':
33 if self.get_argument('download', 'false').lower() == 'true':
34 filename = os.path.splitext(name)[0] + '.' + exporter.file_extension
34 filename = os.path.splitext(name)[0] + '.' + exporter.file_extension
35 self.set_header('Content-Disposition',
35 self.set_header('Content-Disposition',
36 'attachment; filename="%s"' % filename)
36 'attachment; filename="%s"' % filename)
37
37
38 # MIME type
38 # MIME type
39 if exporter.mime_type:
39 if exporter.output_mimetype:
40 self.set_header('Content-Type', '%s; charset=utf-8' % exporter.mime_type)
40 self.set_header('Content-Type',
41 '%s; charset=utf-8' % exporter.output_mimetype)
41
42
42 output, resources = exporter.from_filename(os_path)
43 output, resources = exporter.from_filename(os_path)
43
44
44 # TODO: If there are resources, combine them into a zip file
45 # TODO: If there are resources, combine them into a zip file
45 assert not has_resource_files(resources)
46 assert not has_resource_files(resources)
46
47
47 self.finish(output)
48 self.finish(output)
48
49
49 class NbconvertPostHandler(IPythonHandler):
50 class NbconvertPostHandler(IPythonHandler):
50 SUPPORTED_METHODS = ('POST',)
51 SUPPORTED_METHODS = ('POST',)
51
52
52 @web.authenticated
53 @web.authenticated
53 def post(self, format):
54 def post(self, format):
54 exporter = exporter_map[format]()
55 exporter = exporter_map[format]()
55
56
56 model = self.get_json_body()
57 model = self.get_json_body()
57 nbnode = to_notebook_json(model['content'])
58 nbnode = to_notebook_json(model['content'])
58
59
59 # MIME type
60 # MIME type
60 if exporter.mime_type:
61 if exporter.output_mimetype:
61 self.set_header('Content-Type', '%s; charset=utf-8' % exporter.mime_type)
62 self.set_header('Content-Type',
63 '%s; charset=utf-8' % exporter.output_mimetype)
62
64
63 output, resources = exporter.from_notebook_node(nbnode)
65 output, resources = exporter.from_notebook_node(nbnode)
64
66
65 # TODO: If there are resources, combine them into a zip file
67 # TODO: If there are resources, combine them into a zip file
66 assert not has_resource_files(resources)
68 assert not has_resource_files(resources)
67
69
68 self.finish(output)
70 self.finish(output)
69
71
70 #-----------------------------------------------------------------------------
72 #-----------------------------------------------------------------------------
71 # URL to handler mappings
73 # URL to handler mappings
72 #-----------------------------------------------------------------------------
74 #-----------------------------------------------------------------------------
73
75
74 _format_regex = r"(?P<format>\w+)"
76 _format_regex = r"(?P<format>\w+)"
75 _path_regex = r"(?P<path>(?:/.*)*)"
77 _path_regex = r"(?P<path>(?:/.*)*)"
76 _notebook_name_regex = r"(?P<name>[^/]+\.ipynb)"
78 _notebook_name_regex = r"(?P<name>[^/]+\.ipynb)"
77 _notebook_path_regex = "%s/%s" % (_path_regex, _notebook_name_regex)
79 _notebook_path_regex = "%s/%s" % (_path_regex, _notebook_name_regex)
78
80
79 default_handlers = [
81 default_handlers = [
80 (r"/nbconvert/%s%s" % (_format_regex, _notebook_path_regex),
82 (r"/nbconvert/%s%s" % (_format_regex, _notebook_path_regex),
81 NbconvertFileHandler),
83 NbconvertFileHandler),
82 (r"/nbconvert/%s" % _format_regex, NbconvertPostHandler),
84 (r"/nbconvert/%s" % _format_regex, NbconvertPostHandler),
83 ] No newline at end of file
85 ]
@@ -1,90 +1,90 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2012 The IPython Development Team
2 // Copyright (C) 2012 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // CellToolbar Example
9 // CellToolbar Example
10 //============================================================================
10 //============================================================================
11
11
12 (function(IPython) {
12 (function(IPython) {
13 "use strict";
13 "use strict";
14
14
15 var CellToolbar = IPython.CellToolbar;
15 var CellToolbar = IPython.CellToolbar;
16 var raw_cell_preset = [];
16 var raw_cell_preset = [];
17 var utils = IPython.utils;
17 var utils = IPython.utils;
18
18
19 var select_type = CellToolbar.utils.select_ui_generator([
19 var select_type = CellToolbar.utils.select_ui_generator([
20 ["None", "-"],
20 ["None", "-"],
21 ["LaTeX", "text/latex"],
21 ["LaTeX", "text/latex"],
22 ["reST", "text/restructuredtext"],
22 ["reST", "text/restructuredtext"],
23 ["HTML", "text/html"],
23 ["HTML", "text/html"],
24 ["Markdown", "text/markdown"],
24 ["Markdown", "text/markdown"],
25 ["Python", "application/x-python"],
25 ["Python", "text/x-python"],
26 ["Custom", "dialog"],
26 ["Custom", "dialog"],
27
27
28 ],
28 ],
29 // setter
29 // setter
30 function(cell, value) {
30 function(cell, value) {
31 if (value === "-") {
31 if (value === "-") {
32 delete cell.metadata.raw_mimetype;
32 delete cell.metadata.raw_mimetype;
33 } else if (value === 'dialog'){
33 } else if (value === 'dialog'){
34 var dialog = $('<div/>').append(
34 var dialog = $('<div/>').append(
35 $("<p/>")
35 $("<p/>")
36 .html("Set the MIME type of the raw cell:")
36 .html("Set the MIME type of the raw cell:")
37 ).append(
37 ).append(
38 $("<br/>")
38 $("<br/>")
39 ).append(
39 ).append(
40 $('<input/>').attr('type','text').attr('size','25')
40 $('<input/>').attr('type','text').attr('size','25')
41 .val(cell.metadata.raw_mimetype || "-")
41 .val(cell.metadata.raw_mimetype || "-")
42 );
42 );
43 IPython.dialog.modal({
43 IPython.dialog.modal({
44 title: "Raw Cell MIME Type",
44 title: "Raw Cell MIME Type",
45 body: dialog,
45 body: dialog,
46 buttons : {
46 buttons : {
47 "Cancel": {},
47 "Cancel": {},
48 "OK": {
48 "OK": {
49 class: "btn-primary",
49 class: "btn-primary",
50 click: function () {
50 click: function () {
51 console.log(cell);
51 console.log(cell);
52 cell.metadata.raw_mimetype = $(this).find('input').val();
52 cell.metadata.raw_mimetype = $(this).find('input').val();
53 console.log(cell.metadata);
53 console.log(cell.metadata);
54 }
54 }
55 }
55 }
56 },
56 },
57 open : function (event, ui) {
57 open : function (event, ui) {
58 var that = $(this);
58 var that = $(this);
59 // Upon ENTER, click the OK button.
59 // Upon ENTER, click the OK button.
60 that.find('input[type="text"]').keydown(function (event, ui) {
60 that.find('input[type="text"]').keydown(function (event, ui) {
61 if (event.which === utils.keycodes.ENTER) {
61 if (event.which === utils.keycodes.ENTER) {
62 that.find('.btn-primary').first().click();
62 that.find('.btn-primary').first().click();
63 return false;
63 return false;
64 }
64 }
65 });
65 });
66 that.find('input[type="text"]').focus().select();
66 that.find('input[type="text"]').focus().select();
67 }
67 }
68 });
68 });
69 } else {
69 } else {
70 cell.metadata.raw_mimetype = value;
70 cell.metadata.raw_mimetype = value;
71 }
71 }
72 },
72 },
73 //getter
73 //getter
74 function(cell) {
74 function(cell) {
75 return cell.metadata.raw_mimetype || "";
75 return cell.metadata.raw_mimetype || "";
76 },
76 },
77 // name
77 // name
78 "Raw NBConvert Format",
78 "Raw NBConvert Format",
79 // cell_types
79 // cell_types
80 ["raw"]
80 ["raw"]
81 );
81 );
82
82
83 CellToolbar.register_callback('raw_cell.select', select_type);
83 CellToolbar.register_callback('raw_cell.select', select_type);
84
84
85 raw_cell_preset.push('raw_cell.select');
85 raw_cell_preset.push('raw_cell.select');
86
86
87 CellToolbar.register_preset('Raw Cell Format', raw_cell_preset);
87 CellToolbar.register_preset('Raw Cell Format', raw_cell_preset);
88 console.log('Raw Cell Format toolbar preset loaded.');
88 console.log('Raw Cell Format toolbar preset loaded.');
89
89
90 }(IPython)); No newline at end of file
90 }(IPython));
@@ -1,274 +1,274 b''
1 """This module defines a base Exporter class. For Jinja template-based export,
1 """This module defines a base Exporter class. For Jinja template-based export,
2 see templateexporter.py.
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 mime_type = Unicode('', config=True,
56 output_mimetype = Unicode('', config=True,
57 help="MIME type of the result file, for HTTP response headers."
57 help="MIME type of the result file, for HTTP response headers."
58 )
58 )
59
59
60 #Configurability, allows the user to easily add filters and preprocessors.
60 #Configurability, allows the user to easily add filters and preprocessors.
61 preprocessors = List(config=True,
61 preprocessors = List(config=True,
62 help="""List of preprocessors, by name or namespace, to enable.""")
62 help="""List of preprocessors, by name or namespace, to enable.""")
63
63
64 _preprocessors = None
64 _preprocessors = None
65
65
66 default_preprocessors = List(['IPython.nbconvert.preprocessors.coalesce_streams',
66 default_preprocessors = List(['IPython.nbconvert.preprocessors.coalesce_streams',
67 'IPython.nbconvert.preprocessors.SVG2PDFPreprocessor',
67 'IPython.nbconvert.preprocessors.SVG2PDFPreprocessor',
68 'IPython.nbconvert.preprocessors.ExtractOutputPreprocessor',
68 'IPython.nbconvert.preprocessors.ExtractOutputPreprocessor',
69 'IPython.nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
69 'IPython.nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
70 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
70 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
71 'IPython.nbconvert.preprocessors.LatexPreprocessor',
71 'IPython.nbconvert.preprocessors.LatexPreprocessor',
72 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
72 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
73 config=True,
73 config=True,
74 help="""List of preprocessors available by default, by name, namespace,
74 help="""List of preprocessors available by default, by name, namespace,
75 instance, or type.""")
75 instance, or type.""")
76
76
77
77
78 def __init__(self, config=None, **kw):
78 def __init__(self, config=None, **kw):
79 """
79 """
80 Public constructor
80 Public constructor
81
81
82 Parameters
82 Parameters
83 ----------
83 ----------
84 config : config
84 config : config
85 User configuration instance.
85 User configuration instance.
86 """
86 """
87 with_default_config = self.default_config
87 with_default_config = self.default_config
88 if config:
88 if config:
89 with_default_config.merge(config)
89 with_default_config.merge(config)
90
90
91 super(Exporter, self).__init__(config=with_default_config, **kw)
91 super(Exporter, self).__init__(config=with_default_config, **kw)
92
92
93 self._init_preprocessors()
93 self._init_preprocessors()
94
94
95
95
96 @property
96 @property
97 def default_config(self):
97 def default_config(self):
98 return Config()
98 return Config()
99
99
100 @nbformat.docstring_nbformat_mod
100 @nbformat.docstring_nbformat_mod
101 def from_notebook_node(self, nb, resources=None, **kw):
101 def from_notebook_node(self, nb, resources=None, **kw):
102 """
102 """
103 Convert a notebook from a notebook node instance.
103 Convert a notebook from a notebook node instance.
104
104
105 Parameters
105 Parameters
106 ----------
106 ----------
107 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
107 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
108 Notebook node
108 Notebook node
109 resources : dict
109 resources : dict
110 Additional resources that can be accessed read/write by
110 Additional resources that can be accessed read/write by
111 preprocessors and filters.
111 preprocessors and filters.
112 **kw
112 **kw
113 Ignored (?)
113 Ignored (?)
114 """
114 """
115 nb_copy = copy.deepcopy(nb)
115 nb_copy = copy.deepcopy(nb)
116 resources = self._init_resources(resources)
116 resources = self._init_resources(resources)
117
117
118 # Preprocess
118 # Preprocess
119 nb_copy, resources = self._preprocess(nb_copy, resources)
119 nb_copy, resources = self._preprocess(nb_copy, resources)
120
120
121 return nb_copy, resources
121 return nb_copy, resources
122
122
123
123
124 def from_filename(self, filename, resources=None, **kw):
124 def from_filename(self, filename, resources=None, **kw):
125 """
125 """
126 Convert a notebook from a notebook file.
126 Convert a notebook from a notebook file.
127
127
128 Parameters
128 Parameters
129 ----------
129 ----------
130 filename : str
130 filename : str
131 Full filename of the notebook file to open and convert.
131 Full filename of the notebook file to open and convert.
132 """
132 """
133
133
134 # Pull the metadata from the filesystem.
134 # Pull the metadata from the filesystem.
135 if resources is None:
135 if resources is None:
136 resources = ResourcesDict()
136 resources = ResourcesDict()
137 if not 'metadata' in resources or resources['metadata'] == '':
137 if not 'metadata' in resources or resources['metadata'] == '':
138 resources['metadata'] = ResourcesDict()
138 resources['metadata'] = ResourcesDict()
139 basename = os.path.basename(filename)
139 basename = os.path.basename(filename)
140 notebook_name = basename[:basename.rfind('.')]
140 notebook_name = basename[:basename.rfind('.')]
141 resources['metadata']['name'] = notebook_name
141 resources['metadata']['name'] = notebook_name
142
142
143 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
143 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
144 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
144 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
145
145
146 with io.open(filename, encoding='utf-8') as f:
146 with io.open(filename, encoding='utf-8') as f:
147 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
147 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
148
148
149
149
150 def from_file(self, file_stream, resources=None, **kw):
150 def from_file(self, file_stream, resources=None, **kw):
151 """
151 """
152 Convert a notebook from a notebook file.
152 Convert a notebook from a notebook file.
153
153
154 Parameters
154 Parameters
155 ----------
155 ----------
156 file_stream : file-like object
156 file_stream : file-like object
157 Notebook file-like object to convert.
157 Notebook file-like object to convert.
158 """
158 """
159 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
159 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
160
160
161
161
162 def register_preprocessor(self, preprocessor, enabled=False):
162 def register_preprocessor(self, preprocessor, enabled=False):
163 """
163 """
164 Register a preprocessor.
164 Register a preprocessor.
165 Preprocessors are classes that act upon the notebook before it is
165 Preprocessors are classes that act upon the notebook before it is
166 passed into the Jinja templating engine. preprocessors are also
166 passed into the Jinja templating engine. preprocessors are also
167 capable of passing additional information to the Jinja
167 capable of passing additional information to the Jinja
168 templating engine.
168 templating engine.
169
169
170 Parameters
170 Parameters
171 ----------
171 ----------
172 preprocessor : preprocessor
172 preprocessor : preprocessor
173 """
173 """
174 if preprocessor is None:
174 if preprocessor is None:
175 raise TypeError('preprocessor')
175 raise TypeError('preprocessor')
176 isclass = isinstance(preprocessor, type)
176 isclass = isinstance(preprocessor, type)
177 constructed = not isclass
177 constructed = not isclass
178
178
179 # Handle preprocessor's registration based on it's type
179 # Handle preprocessor's registration based on it's type
180 if constructed and isinstance(preprocessor, py3compat.string_types):
180 if constructed and isinstance(preprocessor, py3compat.string_types):
181 # Preprocessor is a string, import the namespace and recursively call
181 # Preprocessor is a string, import the namespace and recursively call
182 # this register_preprocessor method
182 # this register_preprocessor method
183 preprocessor_cls = import_item(preprocessor)
183 preprocessor_cls = import_item(preprocessor)
184 return self.register_preprocessor(preprocessor_cls, enabled)
184 return self.register_preprocessor(preprocessor_cls, enabled)
185
185
186 if constructed and hasattr(preprocessor, '__call__'):
186 if constructed and hasattr(preprocessor, '__call__'):
187 # Preprocessor is a function, no need to construct it.
187 # Preprocessor is a function, no need to construct it.
188 # Register and return the preprocessor.
188 # Register and return the preprocessor.
189 if enabled:
189 if enabled:
190 preprocessor.enabled = True
190 preprocessor.enabled = True
191 self._preprocessors.append(preprocessor)
191 self._preprocessors.append(preprocessor)
192 return preprocessor
192 return preprocessor
193
193
194 elif isclass and isinstance(preprocessor, MetaHasTraits):
194 elif isclass and isinstance(preprocessor, MetaHasTraits):
195 # Preprocessor is configurable. Make sure to pass in new default for
195 # Preprocessor is configurable. Make sure to pass in new default for
196 # the enabled flag if one was specified.
196 # the enabled flag if one was specified.
197 self.register_preprocessor(preprocessor(parent=self), enabled)
197 self.register_preprocessor(preprocessor(parent=self), enabled)
198
198
199 elif isclass:
199 elif isclass:
200 # Preprocessor is not configurable, construct it
200 # Preprocessor is not configurable, construct it
201 self.register_preprocessor(preprocessor(), enabled)
201 self.register_preprocessor(preprocessor(), enabled)
202
202
203 else:
203 else:
204 # Preprocessor is an instance of something without a __call__
204 # Preprocessor is an instance of something without a __call__
205 # attribute.
205 # attribute.
206 raise TypeError('preprocessor')
206 raise TypeError('preprocessor')
207
207
208
208
209 def _init_preprocessors(self):
209 def _init_preprocessors(self):
210 """
210 """
211 Register all of the preprocessors needed for this exporter, disabled
211 Register all of the preprocessors needed for this exporter, disabled
212 unless specified explicitly.
212 unless specified explicitly.
213 """
213 """
214 if self._preprocessors is None:
214 if self._preprocessors is None:
215 self._preprocessors = []
215 self._preprocessors = []
216
216
217 #Load default preprocessors (not necessarly enabled by default).
217 #Load default preprocessors (not necessarly enabled by default).
218 if self.default_preprocessors:
218 if self.default_preprocessors:
219 for preprocessor in self.default_preprocessors:
219 for preprocessor in self.default_preprocessors:
220 self.register_preprocessor(preprocessor)
220 self.register_preprocessor(preprocessor)
221
221
222 #Load user preprocessors. Enable by default.
222 #Load user preprocessors. Enable by default.
223 if self.preprocessors:
223 if self.preprocessors:
224 for preprocessor in self.preprocessors:
224 for preprocessor in self.preprocessors:
225 self.register_preprocessor(preprocessor, enabled=True)
225 self.register_preprocessor(preprocessor, enabled=True)
226
226
227
227
228 def _init_resources(self, resources):
228 def _init_resources(self, resources):
229
229
230 #Make sure the resources dict is of ResourcesDict type.
230 #Make sure the resources dict is of ResourcesDict type.
231 if resources is None:
231 if resources is None:
232 resources = ResourcesDict()
232 resources = ResourcesDict()
233 if not isinstance(resources, ResourcesDict):
233 if not isinstance(resources, ResourcesDict):
234 new_resources = ResourcesDict()
234 new_resources = ResourcesDict()
235 new_resources.update(resources)
235 new_resources.update(resources)
236 resources = new_resources
236 resources = new_resources
237
237
238 #Make sure the metadata extension exists in resources
238 #Make sure the metadata extension exists in resources
239 if 'metadata' in resources:
239 if 'metadata' in resources:
240 if not isinstance(resources['metadata'], ResourcesDict):
240 if not isinstance(resources['metadata'], ResourcesDict):
241 resources['metadata'] = ResourcesDict(resources['metadata'])
241 resources['metadata'] = ResourcesDict(resources['metadata'])
242 else:
242 else:
243 resources['metadata'] = ResourcesDict()
243 resources['metadata'] = ResourcesDict()
244 if not resources['metadata']['name']:
244 if not resources['metadata']['name']:
245 resources['metadata']['name'] = 'Notebook'
245 resources['metadata']['name'] = 'Notebook'
246
246
247 #Set the output extension
247 #Set the output extension
248 resources['output_extension'] = self.file_extension
248 resources['output_extension'] = self.file_extension
249 return resources
249 return resources
250
250
251
251
252 def _preprocess(self, nb, resources):
252 def _preprocess(self, nb, resources):
253 """
253 """
254 Preprocess the notebook before passing it into the Jinja engine.
254 Preprocess the notebook before passing it into the Jinja engine.
255 To preprocess the notebook is to apply all of the
255 To preprocess the notebook is to apply all of the
256
256
257 Parameters
257 Parameters
258 ----------
258 ----------
259 nb : notebook node
259 nb : notebook node
260 notebook that is being exported.
260 notebook that is being exported.
261 resources : a dict of additional resources that
261 resources : a dict of additional resources that
262 can be accessed read/write by preprocessors
262 can be accessed read/write by preprocessors
263 """
263 """
264
264
265 # Do a copy.deepcopy first,
265 # Do a copy.deepcopy first,
266 # we are never safe enough with what the preprocessors could do.
266 # we are never safe enough with what the preprocessors could do.
267 nbc = copy.deepcopy(nb)
267 nbc = copy.deepcopy(nb)
268 resc = copy.deepcopy(resources)
268 resc = copy.deepcopy(resources)
269
269
270 #Run each preprocessor on the notebook. Carry the output along
270 #Run each preprocessor on the notebook. Carry the output along
271 #to each preprocessor
271 #to each preprocessor
272 for preprocessor in self._preprocessors:
272 for preprocessor in self._preprocessors:
273 nbc, resc = preprocessor(nbc, resc)
273 nbc, resc = preprocessor(nbc, resc)
274 return nbc, resc
274 return nbc, resc
@@ -1,60 +1,60 b''
1 """HTML Exporter class"""
1 """HTML Exporter class"""
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 IPython.utils.traitlets import Unicode, List
15 from IPython.utils.traitlets import Unicode, List
16
16
17 from IPython.nbconvert import preprocessors
17 from IPython.nbconvert import preprocessors
18 from IPython.config import Config
18 from IPython.config import Config
19
19
20 from .templateexporter import TemplateExporter
20 from .templateexporter import TemplateExporter
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Classes
23 # Classes
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 class HTMLExporter(TemplateExporter):
26 class HTMLExporter(TemplateExporter):
27 """
27 """
28 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
29 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
30 custom preprocessors/filters. If you don't need custom preprocessors/
30 custom preprocessors/filters. If you don't need custom preprocessors/
31 filters, just change the 'template_file' config option.
31 filters, just change the 'template_file' config option.
32 """
32 """
33
33
34 file_extension = Unicode(
34 file_extension = Unicode(
35 'html', config=True,
35 'html', config=True,
36 help="Extension of the file that should be written to disk"
36 help="Extension of the file that should be written to disk"
37 )
37 )
38
38
39 mime_type = Unicode('text/html', config=True,
39 mime_type = Unicode('text/html', config=True,
40 help="MIME type of the result file, for HTTP response headers."
40 help="MIME type of the result file, for HTTP response headers."
41 )
41 )
42
42
43 default_template = Unicode('full', config=True, help="""Flavor of the data
43 default_template = Unicode('full', config=True, help="""Flavor of the data
44 format to use. I.E. 'full' or 'basic'""")
44 format to use. I.E. 'full' or 'basic'""")
45
45
46 def _raw_mimetype_default(self):
46 def _output_mimetype_default(self):
47 return 'text/html'
47 return 'text/html'
48
48
49 @property
49 @property
50 def default_config(self):
50 def default_config(self):
51 c = Config({
51 c = Config({
52 'CSSHTMLHeaderPreprocessor':{
52 'CSSHTMLHeaderPreprocessor':{
53 'enabled':True
53 'enabled':True
54 },
54 },
55 'HighlightMagicsPreprocessor': {
55 'HighlightMagicsPreprocessor': {
56 'enabled':True
56 'enabled':True
57 }
57 }
58 })
58 })
59 c.merge(super(HTMLExporter,self).default_config)
59 c.merge(super(HTMLExporter,self).default_config)
60 return c
60 return c
@@ -1,97 +1,93 b''
1 """LaTeX Exporter class"""
1 """LaTeX Exporter class"""
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 # Stdlib imports
15 # Stdlib imports
16 import os
16 import os
17
17
18 # IPython imports
18 # IPython imports
19 from IPython.utils.traitlets import Unicode, List
19 from IPython.utils.traitlets import Unicode, List
20 from IPython.config import Config
20 from IPython.config import Config
21
21
22 from IPython.nbconvert import filters, preprocessors
22 from IPython.nbconvert import filters, preprocessors
23 from .templateexporter import TemplateExporter
23 from .templateexporter import TemplateExporter
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Classes and functions
26 # Classes and functions
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 class LatexExporter(TemplateExporter):
29 class LatexExporter(TemplateExporter):
30 """
30 """
31 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
32 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
33 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.
34 If you don't need custom tranformers/filters, just change the
34 If you don't need custom tranformers/filters, just change the
35 'template_file' config option. Place your template in the special "/latex"
35 'template_file' config option. Place your template in the special "/latex"
36 subfolder of the "../templates" folder.
36 subfolder of the "../templates" folder.
37 """
37 """
38
38
39 file_extension = Unicode(
39 file_extension = Unicode(
40 'tex', config=True,
40 'tex', config=True,
41 help="Extension of the file that should be written to disk")
41 help="Extension of the file that should be written to disk")
42
42
43 mime_type = Unicode('application/x-tex', config=True,
44 help="MIME type of the result file, for HTTP response headers."
45 )
46
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
70 def _raw_mimetype_default(self):
66 def _output_mimetype_default(self):
71 return 'text/latex'
67 return 'text/latex'
72
68
73
69
74 @property
70 @property
75 def default_config(self):
71 def default_config(self):
76 c = Config({
72 c = Config({
77 'NbConvertBase': {
73 'NbConvertBase': {
78 'display_data_priority' : ['latex', 'pdf', 'png', 'jpg', 'svg', 'jpeg', 'text']
74 'display_data_priority' : ['latex', 'pdf', 'png', 'jpg', 'svg', 'jpeg', 'text']
79 },
75 },
80 'ExtractOutputPreprocessor': {
76 'ExtractOutputPreprocessor': {
81 'enabled':True
77 'enabled':True
82 },
78 },
83 'SVG2PDFPreprocessor': {
79 'SVG2PDFPreprocessor': {
84 'enabled':True
80 'enabled':True
85 },
81 },
86 'LatexPreprocessor': {
82 'LatexPreprocessor': {
87 'enabled':True
83 'enabled':True
88 },
84 },
89 'SphinxPreprocessor': {
85 'SphinxPreprocessor': {
90 'enabled':True
86 'enabled':True
91 },
87 },
92 'HighlightMagicsPreprocessor': {
88 'HighlightMagicsPreprocessor': {
93 'enabled':True
89 'enabled':True
94 }
90 }
95 })
91 })
96 c.merge(super(LatexExporter,self).default_config)
92 c.merge(super(LatexExporter,self).default_config)
97 return c
93 return c
@@ -1,47 +1,43 b''
1 """Markdown Exporter class"""
1 """Markdown Exporter class"""
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 IPython.config import Config
15 from IPython.config import Config
16 from IPython.utils.traitlets import Unicode
16 from IPython.utils.traitlets import Unicode
17
17
18 from .templateexporter import TemplateExporter
18 from .templateexporter import TemplateExporter
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Classes
21 # Classes
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 class MarkdownExporter(TemplateExporter):
24 class MarkdownExporter(TemplateExporter):
25 """
25 """
26 Exports to a markdown document (.md)
26 Exports to a markdown document (.md)
27 """
27 """
28
28
29 file_extension = Unicode(
29 file_extension = Unicode(
30 'md', config=True,
30 'md', config=True,
31 help="Extension of the file that should be written to disk")
31 help="Extension of the file that should be written to disk")
32
32
33 def _raw_mimetype_default(self):
33 def _output_mimetype_default(self):
34 return 'text/markdown'
34 return 'text/markdown'
35
35
36 def _raw_mimetypes_default(self):
36 def _raw_mimetypes_default(self):
37 return ['text/markdown', 'text/html']
37 return ['text/markdown', 'text/html', '']
38
39 mime_type = Unicode('text/x-markdown', config=True,
40 help="MIME type of the result file, for HTTP response headers."
41 )
42
38
43 @property
39 @property
44 def default_config(self):
40 def default_config(self):
45 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
41 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
46 c.merge(super(MarkdownExporter,self).default_config)
42 c.merge(super(MarkdownExporter,self).default_config)
47 return c
43 return c
@@ -1,37 +1,33 b''
1 """Python script Exporter class"""
1 """Python script Exporter class"""
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 IPython.utils.traitlets import Unicode
15 from IPython.utils.traitlets import Unicode
16
16
17 from .templateexporter import TemplateExporter
17 from .templateexporter import TemplateExporter
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Classes
20 # Classes
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 class PythonExporter(TemplateExporter):
23 class PythonExporter(TemplateExporter):
24 """
24 """
25 Exports a Python code file.
25 Exports a Python code file.
26 """
26 """
27
27
28 file_extension = Unicode(
28 file_extension = Unicode(
29 'py', config=True,
29 'py', config=True,
30 help="Extension of the file that should be written to disk")
30 help="Extension of the file that should be written to disk")
31
31
32 def _raw_mimetype_default(self):
32 def _output_mimetype_default(self):
33 return 'application/x-python'
33 return 'text/x-python'
34
35 mime_type = Unicode('text/x-python', config=True,
36 help="MIME type of the result file, for HTTP response headers."
37 )
@@ -1,44 +1,40 b''
1 """restructuredText Exporter class"""
1 """restructuredText Exporter class"""
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 IPython.utils.traitlets import Unicode
15 from IPython.utils.traitlets import Unicode
16 from IPython.config import Config
16 from IPython.config import Config
17
17
18 from .templateexporter import TemplateExporter
18 from .templateexporter import TemplateExporter
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Classes
21 # Classes
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 class RSTExporter(TemplateExporter):
24 class RSTExporter(TemplateExporter):
25 """
25 """
26 Exports restructured text documents.
26 Exports restructured text documents.
27 """
27 """
28
28
29 file_extension = Unicode(
29 file_extension = Unicode(
30 'rst', config=True,
30 'rst', config=True,
31 help="Extension of the file that should be written to disk")
31 help="Extension of the file that should be written to disk")
32
32
33 def _raw_mimetype_default(self):
33 def _output_mimetype_default(self):
34 return 'text/restructuredtext'
34 return 'text/restructuredtext'
35
35
36 mime_type = Unicode('text/x-rst', config=True,
37 help="MIME type of the result file, for HTTP response headers."
38 )
39
40 @property
36 @property
41 def default_config(self):
37 def default_config(self):
42 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
38 c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
43 c.merge(super(RSTExporter,self).default_config)
39 c.merge(super(RSTExporter,self).default_config)
44 return c
40 return c
@@ -1,49 +1,48 b''
1 """HTML slide show Exporter class"""
1 """HTML slide show Exporter class"""
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 IPython.utils.traitlets import Unicode
15 from IPython.utils.traitlets import Unicode
16
16
17 from IPython.nbconvert import preprocessors
17 from IPython.nbconvert import preprocessors
18 from IPython.config import Config
18 from IPython.config import Config
19
19
20 from .html import HTMLExporter
20 from .html import HTMLExporter
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Classes
23 # Classes
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 class SlidesExporter(HTMLExporter):
26 class SlidesExporter(HTMLExporter):
27 """Exports HTML slides with reveal.js"""
27 """Exports HTML slides with reveal.js"""
28
28
29 file_extension = Unicode(
29 file_extension = Unicode(
30 'slides.html', config=True,
30 'slides.html', config=True,
31 help="Extension of the file that should be written to disk"
31 help="Extension of the file that should be written to disk"
32 )
32 )
33
33
34 mime_type = Unicode('text/html', config=True,
34 def _output_mimetype_default(self):
35 help="MIME type of the result file, for HTTP response headers."
35 return 'text/html'
36 )
37
36
38 default_template = Unicode('reveal', config=True, help="""Template of the
37 default_template = Unicode('reveal', config=True, help="""Template of the
39 data format to use. I.E. 'reveal'""")
38 data format to use. I.E. 'reveal'""")
40
39
41 @property
40 @property
42 def default_config(self):
41 def default_config(self):
43 c = Config({
42 c = Config({
44 'RevealHelpPreprocessor': {
43 'RevealHelpPreprocessor': {
45 'enabled': True,
44 'enabled': True,
46 },
45 },
47 })
46 })
48 c.merge(super(SlidesExporter,self).default_config)
47 c.merge(super(SlidesExporter,self).default_config)
49 return c
48 return c
@@ -1,324 +1,324 b''
1 """This module defines TemplateExporter, 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_mimetype = Unicode('')
129 output_mimetype = Unicode('')
130
130 raw_mimetypes = List(config=True,
131 raw_mimetypes = List(config=True,
131 help="""formats of raw cells to be included in this Exporter's output."""
132 help="""formats of raw cells to be included in this Exporter's output."""
132 )
133 )
133 def _raw_mimetypes_default(self):
134 def _raw_mimetypes_default(self):
134 return [self.raw_mimetype]
135 return [self.output_mimetype, '']
135
136
136
137
137 def __init__(self, config=None, extra_loaders=None, **kw):
138 def __init__(self, config=None, extra_loaders=None, **kw):
138 """
139 """
139 Public constructor
140 Public constructor
140
141
141 Parameters
142 Parameters
142 ----------
143 ----------
143 config : config
144 config : config
144 User configuration instance.
145 User configuration instance.
145 extra_loaders : list[of Jinja Loaders]
146 extra_loaders : list[of Jinja Loaders]
146 ordered list of Jinja loader to find templates. Will be tried in order
147 ordered list of Jinja loader to find templates. Will be tried in order
147 before the default FileSystem ones.
148 before the default FileSystem ones.
148 template : str (optional, kw arg)
149 template : str (optional, kw arg)
149 Template to use when exporting.
150 Template to use when exporting.
150 """
151 """
151 super(TemplateExporter, self).__init__(config=config, **kw)
152 super(TemplateExporter, self).__init__(config=config, **kw)
152
153
153 #Init
154 #Init
154 self._init_template()
155 self._init_template()
155 self._init_environment(extra_loaders=extra_loaders)
156 self._init_environment(extra_loaders=extra_loaders)
156 self._init_preprocessors()
157 self._init_preprocessors()
157 self._init_filters()
158 self._init_filters()
158
159
159
160
160 def _load_template(self):
161 def _load_template(self):
161 """Load the Jinja template object from the template file
162 """Load the Jinja template object from the template file
162
163
163 This is a no-op if the template attribute is already defined,
164 This is a no-op if the template attribute is already defined,
164 or the Jinja environment is not setup yet.
165 or the Jinja environment is not setup yet.
165
166
166 This is triggered by various trait changes that would change the template.
167 This is triggered by various trait changes that would change the template.
167 """
168 """
168 if self.template is not None:
169 if self.template is not None:
169 return
170 return
170 # called too early, do nothing
171 # called too early, do nothing
171 if self.environment is None:
172 if self.environment is None:
172 return
173 return
173 # Try different template names during conversion. First try to load the
174 # Try different template names during conversion. First try to load the
174 # template by name with extension added, then try loading the template
175 # template by name with extension added, then try loading the template
175 # as if the name is explicitly specified, then try the name as a
176 # as if the name is explicitly specified, then try the name as a
176 # 'flavor', and lastly just try to load the template by module name.
177 # 'flavor', and lastly just try to load the template by module name.
177 module_name = self.__module__.rsplit('.', 1)[-1]
178 module_name = self.__module__.rsplit('.', 1)[-1]
178 try_names = []
179 try_names = []
179 if self.template_file:
180 if self.template_file:
180 try_names.extend([
181 try_names.extend([
181 self.template_file + self.template_extension,
182 self.template_file + self.template_extension,
182 self.template_file,
183 self.template_file,
183 module_name + '_' + self.template_file + self.template_extension,
184 module_name + '_' + self.template_file + self.template_extension,
184 ])
185 ])
185 try_names.append(module_name + self.template_extension)
186 try_names.append(module_name + self.template_extension)
186 for try_name in try_names:
187 for try_name in try_names:
187 self.log.debug("Attempting to load template %s", try_name)
188 self.log.debug("Attempting to load template %s", try_name)
188 try:
189 try:
189 self.template = self.environment.get_template(try_name)
190 self.template = self.environment.get_template(try_name)
190 except (TemplateNotFound, IOError):
191 except (TemplateNotFound, IOError):
191 pass
192 pass
192 except Exception as e:
193 except Exception as e:
193 self.log.warn("Unexpected exception loading template: %s", try_name, exc_info=True)
194 self.log.warn("Unexpected exception loading template: %s", try_name, exc_info=True)
194 else:
195 else:
195 self.log.info("Loaded template %s", try_name)
196 self.log.info("Loaded template %s", try_name)
196 break
197 break
197
198
198 @docstring_nbformat_mod
199 @docstring_nbformat_mod
199 def from_notebook_node(self, nb, resources=None, **kw):
200 def from_notebook_node(self, nb, resources=None, **kw):
200 """
201 """
201 Convert a notebook from a notebook node instance.
202 Convert a notebook from a notebook node instance.
202
203
203 Parameters
204 Parameters
204 ----------
205 ----------
205 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
206 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
206 Notebook node
207 Notebook node
207 resources : dict
208 resources : dict
208 Additional resources that can be accessed read/write by
209 Additional resources that can be accessed read/write by
209 preprocessors and filters.
210 preprocessors and filters.
210 """
211 """
211 nb_copy, resources = super(TemplateExporter, self).from_notebook_node(nb, resources, **kw)
212 nb_copy, resources = super(TemplateExporter, self).from_notebook_node(nb, resources, **kw)
212 resources.setdefault('raw_mimetype', self.raw_mimetype)
213 resources.setdefault('raw_mimetypes', self.raw_mimetypes)
213 resources.setdefault('raw_mimetypes', self.raw_mimetypes)
214
214
215 self._load_template()
215 self._load_template()
216
216
217 if self.template is not None:
217 if self.template is not None:
218 output = self.template.render(nb=nb_copy, resources=resources)
218 output = self.template.render(nb=nb_copy, resources=resources)
219 else:
219 else:
220 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)
221 return output, resources
221 return output, resources
222
222
223
223
224 def register_filter(self, name, jinja_filter):
224 def register_filter(self, name, jinja_filter):
225 """
225 """
226 Register a filter.
226 Register a filter.
227 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.
228 The filters are accesible within the Jinja templating engine.
228 The filters are accesible within the Jinja templating engine.
229
229
230 Parameters
230 Parameters
231 ----------
231 ----------
232 name : str
232 name : str
233 name to give the filter in the Jinja engine
233 name to give the filter in the Jinja engine
234 filter : filter
234 filter : filter
235 """
235 """
236 if jinja_filter is None:
236 if jinja_filter is None:
237 raise TypeError('filter')
237 raise TypeError('filter')
238 isclass = isinstance(jinja_filter, type)
238 isclass = isinstance(jinja_filter, type)
239 constructed = not isclass
239 constructed = not isclass
240
240
241 #Handle filter's registration based on it's type
241 #Handle filter's registration based on it's type
242 if constructed and isinstance(jinja_filter, py3compat.string_types):
242 if constructed and isinstance(jinja_filter, py3compat.string_types):
243 #filter is a string, import the namespace and recursively call
243 #filter is a string, import the namespace and recursively call
244 #this register_filter method
244 #this register_filter method
245 filter_cls = import_item(jinja_filter)
245 filter_cls = import_item(jinja_filter)
246 return self.register_filter(name, filter_cls)
246 return self.register_filter(name, filter_cls)
247
247
248 if constructed and hasattr(jinja_filter, '__call__'):
248 if constructed and hasattr(jinja_filter, '__call__'):
249 #filter is a function, no need to construct it.
249 #filter is a function, no need to construct it.
250 self.environment.filters[name] = jinja_filter
250 self.environment.filters[name] = jinja_filter
251 return jinja_filter
251 return jinja_filter
252
252
253 elif isclass and isinstance(jinja_filter, MetaHasTraits):
253 elif isclass and isinstance(jinja_filter, MetaHasTraits):
254 #filter is configurable. Make sure to pass in new default for
254 #filter is configurable. Make sure to pass in new default for
255 #the enabled flag if one was specified.
255 #the enabled flag if one was specified.
256 filter_instance = jinja_filter(parent=self)
256 filter_instance = jinja_filter(parent=self)
257 self.register_filter(name, filter_instance )
257 self.register_filter(name, filter_instance )
258
258
259 elif isclass:
259 elif isclass:
260 #filter is not configurable, construct it
260 #filter is not configurable, construct it
261 filter_instance = jinja_filter()
261 filter_instance = jinja_filter()
262 self.register_filter(name, filter_instance)
262 self.register_filter(name, filter_instance)
263
263
264 else:
264 else:
265 #filter is an instance of something without a __call__
265 #filter is an instance of something without a __call__
266 #attribute.
266 #attribute.
267 raise TypeError('filter')
267 raise TypeError('filter')
268
268
269
269
270 def _init_template(self):
270 def _init_template(self):
271 """
271 """
272 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
273 build one from the information we know.
273 build one from the information we know.
274 """
274 """
275 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)
276
276
277
277
278 def _init_environment(self, extra_loaders=None):
278 def _init_environment(self, extra_loaders=None):
279 """
279 """
280 Create the Jinja templating environment.
280 Create the Jinja templating environment.
281 """
281 """
282 here = os.path.dirname(os.path.realpath(__file__))
282 here = os.path.dirname(os.path.realpath(__file__))
283 loaders = []
283 loaders = []
284 if extra_loaders:
284 if extra_loaders:
285 loaders.extend(extra_loaders)
285 loaders.extend(extra_loaders)
286
286
287 paths = self.template_path
287 paths = self.template_path
288 paths.extend([os.path.join(here, self.default_template_path),
288 paths.extend([os.path.join(here, self.default_template_path),
289 os.path.join(here, self.template_skeleton_path)])
289 os.path.join(here, self.template_skeleton_path)])
290 loaders.append(FileSystemLoader(paths))
290 loaders.append(FileSystemLoader(paths))
291
291
292 self.environment = Environment(
292 self.environment = Environment(
293 loader= ChoiceLoader(loaders),
293 loader= ChoiceLoader(loaders),
294 extensions=JINJA_EXTENSIONS
294 extensions=JINJA_EXTENSIONS
295 )
295 )
296
296
297 #Set special Jinja2 syntax that will not conflict with latex.
297 #Set special Jinja2 syntax that will not conflict with latex.
298 if self.jinja_logic_block_start:
298 if self.jinja_logic_block_start:
299 self.environment.block_start_string = self.jinja_logic_block_start
299 self.environment.block_start_string = self.jinja_logic_block_start
300 if self.jinja_logic_block_end:
300 if self.jinja_logic_block_end:
301 self.environment.block_end_string = self.jinja_logic_block_end
301 self.environment.block_end_string = self.jinja_logic_block_end
302 if self.jinja_variable_block_start:
302 if self.jinja_variable_block_start:
303 self.environment.variable_start_string = self.jinja_variable_block_start
303 self.environment.variable_start_string = self.jinja_variable_block_start
304 if self.jinja_variable_block_end:
304 if self.jinja_variable_block_end:
305 self.environment.variable_end_string = self.jinja_variable_block_end
305 self.environment.variable_end_string = self.jinja_variable_block_end
306 if self.jinja_comment_block_start:
306 if self.jinja_comment_block_start:
307 self.environment.comment_start_string = self.jinja_comment_block_start
307 self.environment.comment_start_string = self.jinja_comment_block_start
308 if self.jinja_comment_block_end:
308 if self.jinja_comment_block_end:
309 self.environment.comment_end_string = self.jinja_comment_block_end
309 self.environment.comment_end_string = self.jinja_comment_block_end
310
310
311
311
312 def _init_filters(self):
312 def _init_filters(self):
313 """
313 """
314 Register all of the filters required for the exporter.
314 Register all of the filters required for the exporter.
315 """
315 """
316
316
317 #Add default filters to the Jinja2 environment
317 #Add default filters to the Jinja2 environment
318 for key, value in default_filters.items():
318 for key, value in default_filters.items():
319 self.register_filter(key, value)
319 self.register_filter(key, value)
320
320
321 #Load user filters. Overwrite existing filters if need be.
321 #Load user filters. Overwrite existing filters if need be.
322 if self.filters:
322 if self.filters:
323 for key, user_filter in self.filters.items():
323 for key, user_filter in self.filters.items():
324 self.register_filter(key, user_filter)
324 self.register_filter(key, user_filter)
@@ -1,54 +1,54 b''
1 """Base TestCase class for testing Exporters"""
1 """Base TestCase class for testing Exporters"""
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 import os
15 import os
16
16
17 from IPython.testing.decorators import onlyif_cmds_exist
17 from IPython.testing.decorators import onlyif_cmds_exist
18
18
19 from ...tests.base import TestsBase
19 from ...tests.base import TestsBase
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Class
22 # Class
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 all_raw_mimetypes = {
25 all_raw_mimetypes = {
26 'application/x-python',
26 'text/x-python',
27 'text/markdown',
27 'text/markdown',
28 'text/html',
28 'text/html',
29 'text/restructuredtext',
29 'text/restructuredtext',
30 'text/latex',
30 'text/latex',
31 }
31 }
32
32
33 class ExportersTestsBase(TestsBase):
33 class ExportersTestsBase(TestsBase):
34 """Contains base test functions for exporters"""
34 """Contains base test functions for exporters"""
35
35
36 exporter_class = None
36 exporter_class = None
37 should_include_raw = None
37 should_include_raw = None
38
38
39 def _get_notebook(self, nb_name='notebook2.ipynb'):
39 def _get_notebook(self, nb_name='notebook2.ipynb'):
40 return os.path.join(self._get_files_path(), nb_name)
40 return os.path.join(self._get_files_path(), nb_name)
41
41
42 @onlyif_cmds_exist('pandoc')
42 @onlyif_cmds_exist('pandoc')
43 def test_raw_cell_inclusion(self):
43 def test_raw_cell_inclusion(self):
44 """test raw cell inclusion based on raw_mimetype metadata"""
44 """test raw cell inclusion based on raw_mimetype metadata"""
45 if self.should_include_raw is None:
45 if self.should_include_raw is None:
46 return
46 return
47 exporter = self.exporter_class()
47 exporter = self.exporter_class()
48 (output, resources) = exporter.from_filename(self._get_notebook('rawtest.ipynb'))
48 (output, resources) = exporter.from_filename(self._get_notebook('rawtest.ipynb'))
49 for inc in self.should_include_raw:
49 for inc in self.should_include_raw:
50 self.assertIn('raw %s' % inc, output, "should include %s" % inc)
50 self.assertIn('raw %s' % inc, output, "should include %s" % inc)
51 self.assertIn('no raw_mimetype metadata', output)
51 self.assertIn('no raw_mimetype metadata', output)
52 for exc in all_raw_mimetypes.difference(self.should_include_raw):
52 for exc in all_raw_mimetypes.difference(self.should_include_raw):
53 self.assertNotIn('raw %s' % exc, output, "should exclude %s" % exc)
53 self.assertNotIn('raw %s' % exc, output, "should exclude %s" % exc)
54 self.assertNotIn('never be included', output)
54 self.assertNotIn('never be included', output)
@@ -1,84 +1,84 b''
1 {
1 {
2 "metadata": {
2 "metadata": {
3 "name": ""
3 "name": ""
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "nbformat_minor": 0,
7 "worksheets": [
7 "worksheets": [
8 {
8 {
9 "cells": [
9 "cells": [
10 {
10 {
11 "cell_type": "raw",
11 "cell_type": "raw",
12 "metadata": {
12 "metadata": {
13 "raw_mimetype": "text/html"
13 "raw_mimetype": "text/html"
14 },
14 },
15 "source": [
15 "source": [
16 "<b>raw html</b>"
16 "<b>raw html</b>"
17 ]
17 ]
18 },
18 },
19 {
19 {
20 "cell_type": "raw",
20 "cell_type": "raw",
21 "metadata": {
21 "metadata": {
22 "raw_mimetype": "text/markdown"
22 "raw_mimetype": "text/markdown"
23 },
23 },
24 "source": [
24 "source": [
25 "* raw markdown\n",
25 "* raw markdown\n",
26 "* bullet\n",
26 "* bullet\n",
27 "* list"
27 "* list"
28 ]
28 ]
29 },
29 },
30 {
30 {
31 "cell_type": "raw",
31 "cell_type": "raw",
32 "metadata": {
32 "metadata": {
33 "raw_mimetype": "text/restructuredtext"
33 "raw_mimetype": "text/restructuredtext"
34 },
34 },
35 "source": [
35 "source": [
36 "``raw rst``\n",
36 "``raw rst``\n",
37 "\n",
37 "\n",
38 ".. sourcecode:: python\n",
38 ".. sourcecode:: python\n",
39 "\n",
39 "\n",
40 " def foo(): pass\n"
40 " def foo(): pass\n"
41 ]
41 ]
42 },
42 },
43 {
43 {
44 "cell_type": "raw",
44 "cell_type": "raw",
45 "metadata": {
45 "metadata": {
46 "raw_mimetype": "application/x-python"
46 "raw_mimetype": "text/x-python"
47 },
47 },
48 "source": [
48 "source": [
49 "def bar():\n",
49 "def bar():\n",
50 " \"\"\"raw python\"\"\"\n",
50 " \"\"\"raw python\"\"\"\n",
51 " pass"
51 " pass"
52 ]
52 ]
53 },
53 },
54 {
54 {
55 "cell_type": "raw",
55 "cell_type": "raw",
56 "metadata": {
56 "metadata": {
57 "raw_mimetype": "text/latex"
57 "raw_mimetype": "text/latex"
58 },
58 },
59 "source": [
59 "source": [
60 "\\LaTeX\n",
60 "\\LaTeX\n",
61 "% raw latex"
61 "% raw latex"
62 ]
62 ]
63 },
63 },
64 {
64 {
65 "cell_type": "raw",
65 "cell_type": "raw",
66 "metadata": {},
66 "metadata": {},
67 "source": [
67 "source": [
68 "# no raw_mimetype metadata, should be included by default"
68 "# no raw_mimetype metadata, should be included by default"
69 ]
69 ]
70 },
70 },
71 {
71 {
72 "cell_type": "raw",
72 "cell_type": "raw",
73 "metadata": {
73 "metadata": {
74 "raw_mimetype": "doesnotexist"
74 "raw_mimetype": "doesnotexist"
75 },
75 },
76 "source": [
76 "source": [
77 "garbage format defined, should never be included"
77 "garbage format defined, should never be included"
78 ]
78 ]
79 }
79 }
80 ],
80 ],
81 "metadata": {}
81 "metadata": {}
82 }
82 }
83 ]
83 ]
84 } No newline at end of file
84 }
@@ -1,98 +1,98 b''
1 ((= Auto-generated template file, DO NOT edit directly!
1 ((= Auto-generated template file, DO NOT edit directly!
2 To edit this file, please refer to ../../skeleton/README.md =))
2 To edit this file, please refer to ../../skeleton/README.md =))
3
3
4
4
5 ((=
5 ((=
6
6
7 DO NOT USE THIS AS A BASE,
7 DO NOT USE THIS AS A BASE,
8 IF YOU ARE COPY AND PASTING THIS FILE
8 IF YOU ARE COPY AND PASTING THIS FILE
9 YOU ARE PROBABLY DOING THINGS INCORRECTLY.
9 YOU ARE PROBABLY DOING THINGS INCORRECTLY.
10
10
11 Null template, does nothing except defining a basic structure
11 Null template, does nothing except defining a basic structure
12 To layout the different blocks of a notebook.
12 To layout the different blocks of a notebook.
13
13
14 Subtemplates can override blocks to define their custom representation.
14 Subtemplates can override blocks to define their custom representation.
15
15
16 If one of the block you do overwrite is not a leave block, consider
16 If one of the block you do overwrite is not a leave block, consider
17 calling super.
17 calling super.
18
18
19 ((*- block nonLeaveBlock -*))
19 ((*- block nonLeaveBlock -*))
20 #add stuff at beginning
20 #add stuff at beginning
21 ((( super() )))
21 ((( super() )))
22 #add stuff at end
22 #add stuff at end
23 ((*- endblock nonLeaveBlock -*))
23 ((*- endblock nonLeaveBlock -*))
24
24
25 consider calling super even if it is a leave block, we might insert more blocks later.
25 consider calling super even if it is a leave block, we might insert more blocks later.
26
26
27 =))
27 =))
28 ((*- block header -*))
28 ((*- block header -*))
29 ((*- endblock header -*))
29 ((*- endblock header -*))
30 ((*- block body -*))
30 ((*- block body -*))
31 ((*- for worksheet in nb.worksheets -*))
31 ((*- for worksheet in nb.worksheets -*))
32 ((*- for cell in worksheet.cells -*))
32 ((*- for cell in worksheet.cells -*))
33 ((*- block any_cell scoped -*))
33 ((*- block any_cell scoped -*))
34 ((*- if cell.cell_type in ['code'] -*))
34 ((*- if cell.cell_type in ['code'] -*))
35 ((*- block codecell scoped -*))
35 ((*- block codecell scoped -*))
36 ((*- block input_group -*))
36 ((*- block input_group -*))
37 ((*- block in_prompt -*))((*- endblock in_prompt -*))
37 ((*- block in_prompt -*))((*- endblock in_prompt -*))
38 ((*- block input -*))((*- endblock input -*))
38 ((*- block input -*))((*- endblock input -*))
39 ((*- endblock input_group -*))
39 ((*- endblock input_group -*))
40 ((*- if cell.outputs -*))
40 ((*- if cell.outputs -*))
41 ((*- block output_group -*))
41 ((*- block output_group -*))
42 ((*- block output_prompt -*))((*- endblock output_prompt -*))
42 ((*- block output_prompt -*))((*- endblock output_prompt -*))
43 ((*- block outputs scoped -*))
43 ((*- block outputs scoped -*))
44 ((*- for output in cell.outputs -*))
44 ((*- for output in cell.outputs -*))
45 ((*- block output scoped -*))
45 ((*- block output scoped -*))
46 ((*- if output.output_type in ['pyout'] -*))
46 ((*- if output.output_type in ['pyout'] -*))
47 ((*- block pyout scoped -*))((*- endblock pyout -*))
47 ((*- block pyout scoped -*))((*- endblock pyout -*))
48 ((*- elif output.output_type in ['stream'] -*))
48 ((*- elif output.output_type in ['stream'] -*))
49 ((*- block stream scoped -*))
49 ((*- block stream scoped -*))
50 ((*- if output.stream in ['stdout'] -*))
50 ((*- if output.stream in ['stdout'] -*))
51 ((*- block stream_stdout scoped -*))
51 ((*- block stream_stdout scoped -*))
52 ((*- endblock stream_stdout -*))
52 ((*- endblock stream_stdout -*))
53 ((*- elif output.stream in ['stderr'] -*))
53 ((*- elif output.stream in ['stderr'] -*))
54 ((*- block stream_stderr scoped -*))
54 ((*- block stream_stderr scoped -*))
55 ((*- endblock stream_stderr -*))
55 ((*- endblock stream_stderr -*))
56 ((*- endif -*))
56 ((*- endif -*))
57 ((*- endblock stream -*))
57 ((*- endblock stream -*))
58 ((*- elif output.output_type in ['display_data'] -*))
58 ((*- elif output.output_type in ['display_data'] -*))
59 ((*- block display_data scoped -*))
59 ((*- block display_data scoped -*))
60 ((*- block data_priority scoped -*))
60 ((*- block data_priority scoped -*))
61 ((*- endblock data_priority -*))
61 ((*- endblock data_priority -*))
62 ((*- endblock display_data -*))
62 ((*- endblock display_data -*))
63 ((*- elif output.output_type in ['pyerr'] -*))
63 ((*- elif output.output_type in ['pyerr'] -*))
64 ((*- block pyerr scoped -*))
64 ((*- block pyerr scoped -*))
65 ((*- for line in output.traceback -*))
65 ((*- for line in output.traceback -*))
66 ((*- block traceback_line scoped -*))((*- endblock traceback_line -*))
66 ((*- block traceback_line scoped -*))((*- endblock traceback_line -*))
67 ((*- endfor -*))
67 ((*- endfor -*))
68 ((*- endblock pyerr -*))
68 ((*- endblock pyerr -*))
69 ((*- endif -*))
69 ((*- endif -*))
70 ((*- endblock output -*))
70 ((*- endblock output -*))
71 ((*- endfor -*))
71 ((*- endfor -*))
72 ((*- endblock outputs -*))
72 ((*- endblock outputs -*))
73 ((*- endblock output_group -*))
73 ((*- endblock output_group -*))
74 ((*- endif -*))
74 ((*- endif -*))
75 ((*- endblock codecell -*))
75 ((*- endblock codecell -*))
76 ((*- elif cell.cell_type in ['markdown'] -*))
76 ((*- elif cell.cell_type in ['markdown'] -*))
77 ((*- block markdowncell scoped-*))
77 ((*- block markdowncell scoped-*))
78 ((*- endblock markdowncell -*))
78 ((*- endblock markdowncell -*))
79 ((*- elif cell.cell_type in ['heading'] -*))
79 ((*- elif cell.cell_type in ['heading'] -*))
80 ((*- block headingcell scoped-*))
80 ((*- block headingcell scoped-*))
81 ((*- endblock headingcell -*))
81 ((*- endblock headingcell -*))
82 ((*- elif cell.cell_type in ['raw'] -*))
82 ((*- elif cell.cell_type in ['raw'] -*))
83 ((*- block rawcell scoped -*))
83 ((*- block rawcell scoped -*))
84 ((* if cell.metadata.get('raw_mimetype', resources.get('raw_mimetype')) == resources.get('raw_mimetype') *))
84 ((* if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) *))
85 ((( cell.source )))
85 ((( cell.source )))
86 ((* endif *))
86 ((* endif *))
87 ((*- endblock rawcell -*))
87 ((*- endblock rawcell -*))
88 ((*- else -*))
88 ((*- else -*))
89 ((*- block unknowncell scoped-*))
89 ((*- block unknowncell scoped-*))
90 ((*- endblock unknowncell -*))
90 ((*- endblock unknowncell -*))
91 ((*- endif -*))
91 ((*- endif -*))
92 ((*- endblock any_cell -*))
92 ((*- endblock any_cell -*))
93 ((*- endfor -*))
93 ((*- endfor -*))
94 ((*- endfor -*))
94 ((*- endfor -*))
95 ((*- endblock body -*))
95 ((*- endblock body -*))
96
96
97 ((*- block footer -*))
97 ((*- block footer -*))
98 ((*- endblock footer -*))
98 ((*- endblock footer -*))
@@ -1,94 +1,94 b''
1 {#
1 {#
2
2
3 DO NOT USE THIS AS A BASE,
3 DO NOT USE THIS AS A BASE,
4 IF YOU ARE COPY AND PASTING THIS FILE
4 IF YOU ARE COPY AND PASTING THIS FILE
5 YOU ARE PROBABLY DOING THINGS INCORRECTLY.
5 YOU ARE PROBABLY DOING THINGS INCORRECTLY.
6
6
7 Null template, does nothing except defining a basic structure
7 Null template, does nothing except defining a basic structure
8 To layout the different blocks of a notebook.
8 To layout the different blocks of a notebook.
9
9
10 Subtemplates can override blocks to define their custom representation.
10 Subtemplates can override blocks to define their custom representation.
11
11
12 If one of the block you do overwrite is not a leave block, consider
12 If one of the block you do overwrite is not a leave block, consider
13 calling super.
13 calling super.
14
14
15 {%- block nonLeaveBlock -%}
15 {%- block nonLeaveBlock -%}
16 #add stuff at beginning
16 #add stuff at beginning
17 {{ super() }}
17 {{ super() }}
18 #add stuff at end
18 #add stuff at end
19 {%- endblock nonLeaveBlock -%}
19 {%- endblock nonLeaveBlock -%}
20
20
21 consider calling super even if it is a leave block, we might insert more blocks later.
21 consider calling super even if it is a leave block, we might insert more blocks later.
22
22
23 #}
23 #}
24 {%- block header -%}
24 {%- block header -%}
25 {%- endblock header -%}
25 {%- endblock header -%}
26 {%- block body -%}
26 {%- block body -%}
27 {%- for worksheet in nb.worksheets -%}
27 {%- for worksheet in nb.worksheets -%}
28 {%- for cell in worksheet.cells -%}
28 {%- for cell in worksheet.cells -%}
29 {%- block any_cell scoped -%}
29 {%- block any_cell scoped -%}
30 {%- if cell.cell_type in ['code'] -%}
30 {%- if cell.cell_type in ['code'] -%}
31 {%- block codecell scoped -%}
31 {%- block codecell scoped -%}
32 {%- block input_group -%}
32 {%- block input_group -%}
33 {%- block in_prompt -%}{%- endblock in_prompt -%}
33 {%- block in_prompt -%}{%- endblock in_prompt -%}
34 {%- block input -%}{%- endblock input -%}
34 {%- block input -%}{%- endblock input -%}
35 {%- endblock input_group -%}
35 {%- endblock input_group -%}
36 {%- if cell.outputs -%}
36 {%- if cell.outputs -%}
37 {%- block output_group -%}
37 {%- block output_group -%}
38 {%- block output_prompt -%}{%- endblock output_prompt -%}
38 {%- block output_prompt -%}{%- endblock output_prompt -%}
39 {%- block outputs scoped -%}
39 {%- block outputs scoped -%}
40 {%- for output in cell.outputs -%}
40 {%- for output in cell.outputs -%}
41 {%- block output scoped -%}
41 {%- block output scoped -%}
42 {%- if output.output_type in ['pyout'] -%}
42 {%- if output.output_type in ['pyout'] -%}
43 {%- block pyout scoped -%}{%- endblock pyout -%}
43 {%- block pyout scoped -%}{%- endblock pyout -%}
44 {%- elif output.output_type in ['stream'] -%}
44 {%- elif output.output_type in ['stream'] -%}
45 {%- block stream scoped -%}
45 {%- block stream scoped -%}
46 {%- if output.stream in ['stdout'] -%}
46 {%- if output.stream in ['stdout'] -%}
47 {%- block stream_stdout scoped -%}
47 {%- block stream_stdout scoped -%}
48 {%- endblock stream_stdout -%}
48 {%- endblock stream_stdout -%}
49 {%- elif output.stream in ['stderr'] -%}
49 {%- elif output.stream in ['stderr'] -%}
50 {%- block stream_stderr scoped -%}
50 {%- block stream_stderr scoped -%}
51 {%- endblock stream_stderr -%}
51 {%- endblock stream_stderr -%}
52 {%- endif -%}
52 {%- endif -%}
53 {%- endblock stream -%}
53 {%- endblock stream -%}
54 {%- elif output.output_type in ['display_data'] -%}
54 {%- elif output.output_type in ['display_data'] -%}
55 {%- block display_data scoped -%}
55 {%- block display_data scoped -%}
56 {%- block data_priority scoped -%}
56 {%- block data_priority scoped -%}
57 {%- endblock data_priority -%}
57 {%- endblock data_priority -%}
58 {%- endblock display_data -%}
58 {%- endblock display_data -%}
59 {%- elif output.output_type in ['pyerr'] -%}
59 {%- elif output.output_type in ['pyerr'] -%}
60 {%- block pyerr scoped -%}
60 {%- block pyerr scoped -%}
61 {%- for line in output.traceback -%}
61 {%- for line in output.traceback -%}
62 {%- block traceback_line scoped -%}{%- endblock traceback_line -%}
62 {%- block traceback_line scoped -%}{%- endblock traceback_line -%}
63 {%- endfor -%}
63 {%- endfor -%}
64 {%- endblock pyerr -%}
64 {%- endblock pyerr -%}
65 {%- endif -%}
65 {%- endif -%}
66 {%- endblock output -%}
66 {%- endblock output -%}
67 {%- endfor -%}
67 {%- endfor -%}
68 {%- endblock outputs -%}
68 {%- endblock outputs -%}
69 {%- endblock output_group -%}
69 {%- endblock output_group -%}
70 {%- endif -%}
70 {%- endif -%}
71 {%- endblock codecell -%}
71 {%- endblock codecell -%}
72 {%- elif cell.cell_type in ['markdown'] -%}
72 {%- elif cell.cell_type in ['markdown'] -%}
73 {%- block markdowncell scoped-%}
73 {%- block markdowncell scoped-%}
74 {%- endblock markdowncell -%}
74 {%- endblock markdowncell -%}
75 {%- elif cell.cell_type in ['heading'] -%}
75 {%- elif cell.cell_type in ['heading'] -%}
76 {%- block headingcell scoped-%}
76 {%- block headingcell scoped-%}
77 {%- endblock headingcell -%}
77 {%- endblock headingcell -%}
78 {%- elif cell.cell_type in ['raw'] -%}
78 {%- elif cell.cell_type in ['raw'] -%}
79 {%- block rawcell scoped -%}
79 {%- block rawcell scoped -%}
80 {% if cell.metadata.get('raw_mimetype', resources.get('raw_mimetype', '')).lower() in resources.get('raw_mimetypes', ['']) %}
80 {% if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) %}
81 {{ cell.source }}
81 {{ cell.source }}
82 {% endif %}
82 {% endif %}
83 {%- endblock rawcell -%}
83 {%- endblock rawcell -%}
84 {%- else -%}
84 {%- else -%}
85 {%- block unknowncell scoped-%}
85 {%- block unknowncell scoped-%}
86 {%- endblock unknowncell -%}
86 {%- endblock unknowncell -%}
87 {%- endif -%}
87 {%- endif -%}
88 {%- endblock any_cell -%}
88 {%- endblock any_cell -%}
89 {%- endfor -%}
89 {%- endfor -%}
90 {%- endfor -%}
90 {%- endfor -%}
91 {%- endblock body -%}
91 {%- endblock body -%}
92
92
93 {%- block footer -%}
93 {%- block footer -%}
94 {%- endblock footer -%}
94 {%- endblock footer -%}
General Comments 0
You need to be logged in to leave comments. Login now