##// END OF EJS Templates
Transformer refactor
Jonathan Frederic -
Show More
@@ -0,0 +1,3 b''
1 See COPYING.txt distributed with iPython.
2
3 #TODO, give NBCONVERT its own license No newline at end of file
@@ -0,0 +1,1 b''
1
@@ -0,0 +1,1 b''
1
@@ -0,0 +1,1 b''
1
@@ -0,0 +1,1 b''
1
@@ -0,0 +1,31 b''
1 """Filter used to select the first prefered output format available.
2
3 The filter contained in the file allows the converter templates to select
4 the output format that is most valuable to the active export format. The
5 value of the different formats is set via
6 GlobalConfigurable.display_data_priority
7 """
8 #-----------------------------------------------------------------------------
9 # Copyright (c) 2013, the IPython Development Team.
10 #
11 # Distributed under the terms of the Modified BSD License.
12 #
13 # The full license is in the file COPYING.txt, distributed with this software.
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Classes and functions
18 #-----------------------------------------------------------------------------
19 class DataTypeFilter(GlobalConfigurable):
20 """ Returns the prefered display format """
21
22 def __init__(self, config=None, **kw):
23 super(FilterDataType, self).__init__(config=config, **kw)
24
25 def __call__(self, output):
26 """ Return the first available format in the priority """
27
28 for fmt in self.display_data_priority:
29 if fmt in output:
30 return [fmt]
31 return [] No newline at end of file
@@ -0,0 +1,75 b''
1 """Markdown utilities
2
3 This file contains a collection of utility functions for dealing with
4 markdown.
5 """
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2013, the IPython Development Team.
8 #
9 # Distributed under the terms of the Modified BSD License.
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
13
14 #-----------------------------------------------------------------------------
15 # Imports
16 #-----------------------------------------------------------------------------
17 from __future__ import print_function
18
19 # Stdlib imports
20 import subprocess
21
22 #-----------------------------------------------------------------------------
23 # Functions
24 #-----------------------------------------------------------------------------
25 # Pandoc-dependent code
26 def markdown2latex(src):
27 """Convert a markdown string to LaTeX via pandoc.
28
29 This function will raise an error if pandoc is not installed.
30
31 Any error messages generated by pandoc are printed to stderr.
32
33 Parameters
34 ----------
35 src : string
36 Input string, assumed to be valid markdown.
37
38 Returns
39 -------
40 out : string
41 Output as returned by pandoc.
42 """
43 p = subprocess.Popen('pandoc -f markdown -t latex'.split(),
44 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
45 out, err = p.communicate(src.encode('utf-8'))
46 if err:
47 print(err, file=sys.stderr)
48 #print('*'*20+'\n', out, '\n'+'*'*20) # dbg
49 return unicode(out, 'utf-8')
50
51
52 def markdown2rst(src):
53 """Convert a markdown string to LaTeX via pandoc.
54
55 This function will raise an error if pandoc is not installed.
56
57 Any error messages generated by pandoc are printed to stderr.
58
59 Parameters
60 ----------
61 src : string
62 Input string, assumed to be valid markdown.
63
64 Returns
65 -------
66 out : string
67 Output as returned by pandoc.
68 """
69 p = subprocess.Popen('pandoc -f markdown -t rst'.split(),
70 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
71 out, err = p.communicate(src.encode('utf-8'))
72 if err:
73 print(err, file=sys.stderr)
74 #print('*'*20+'\n', out, '\n'+'*'*20) # dbg
75 return unicode(out, 'utf-8') No newline at end of file
@@ -1,387 +1,381 b''
1 """Exporter for the notebook conversion pipeline.
1 """Exporter for the notebook conversion pipeline.
2
2
3 This module defines Exporter, a highly configurable converter
3 This module defines Exporter, a highly configurable converter
4 that uses Jinja2 to export notebook files into different format.
4 that uses Jinja2 to export notebook files into different format.
5
5
6 You can register both pre-transformers that will act on the notebook format
6 You can register both pre-transformers that will act on the notebook format
7 befor conversion and jinja filter that would then be availlable in the templates
7 befor conversion and jinja filter that would then be availlable in the templates
8 """
8 """
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (c) 2013, the IPython Development Team.
11 # Copyright (c) 2013, the IPython Development Team.
12 #
12 #
13 # Distributed under the terms of the Modified BSD License.
13 # Distributed under the terms of the Modified BSD License.
14 #
14 #
15 # The full license is in the file COPYING.txt, distributed with this software.
15 # The full license is in the file COPYING.txt, distributed with this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 from __future__ import print_function, absolute_import
21 from __future__ import print_function, absolute_import
22
22
23 # Stdlib imports
23 # Stdlib imports
24 import io
24 import io
25 import os
25 import os
26 import re
26 import re
27
27
28 # IPython imports
28 # IPython imports
29 from IPython.config.configurable import Configurable
29 from IPython.config.configurable import Configurable
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, Bool
31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List, Bool
32 from IPython.utils.text import indent
32 from IPython.utils.text import indent
33
33
34 # other libs/dependencies
34 # other libs/dependencies
35 from jinja2 import Environment, FileSystemLoader
35 from jinja2 import Environment, FileSystemLoader
36 from markdown import markdown
36 from markdown import markdown
37
37
38 # local import (pre-transformers)
38 # local import (pre-transformers)
39 from exceptions import ConversionException
39 from exceptions import ConversionException
40 from . import transformers as trans #TODO
40 from . import transformers as trans #TODO
41 from .latex_transformer import (LatexTransformer) #TODO
42 from .utils import markdown2rst #TODO
43 from .utils import markdown2latex #TODO
44 from .utils import highlight2latex #TODO
41 from .utils import highlight2latex #TODO
45 from .utils import get_lines #TODO
42 from .utils import get_lines #TODO
46 from .utils import remove_ansi #TODO
43 from .utils import remove_ansi #TODO
47 from .utils import highlight, ansi2html #TODO
44 from .utils import highlight, ansi2html #TODO
48 from .latex_transformer import rm_math_space #TODO
49 import .utils.strings as strings
50
45
51 #Jinja2 filters
46 from .transformers.latex import LatexTransformer, rm_math_space
52 from .jinja_filters import (python_comment,
47
53 rm_fake,
48 import .utils.strings as strings
54 escape_tex, FilterDataType,
49 import .utils.markdown as markdown_utils
55 rm_dollars
50 import .utils.datatypefilter.DataTypeFilter as DataTypeFilter
56 )
57
51
58 #Try to import the Sphinx exporter. If the user doesn't have Sphinx isntalled
52 #Try to import the Sphinx exporter. If the user doesn't have Sphinx isntalled
59 #on his/her machine, fail silently.
53 #on his/her machine, fail silently.
60 try:
54 try:
61 from .sphinx_transformer import (SphinxTransformer) #TODO
55 from .sphinx_transformer import (SphinxTransformer) #TODO
62 except ImportError:
56 except ImportError:
63 SphinxTransformer = None
57 SphinxTransformer = None
64
58
65 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
66 # Globals and constants
60 # Globals and constants
67 #-----------------------------------------------------------------------------
61 #-----------------------------------------------------------------------------
68
62
69 #Standard Jinja2 environment constants
63 #Standard Jinja2 environment constants
70 TEMPLATE_PATH = "/../templates/"
64 TEMPLATE_PATH = "/../templates/"
71 TEMPLATE_SKELETON_PATH = "/../templates/skeleton/"
65 TEMPLATE_SKELETON_PATH = "/../templates/skeleton/"
72 TEMPLATE_EXTENSION = ".tpl"
66 TEMPLATE_EXTENSION = ".tpl"
73
67
74 #Latex Jinja2 constants
68 #Latex Jinja2 constants
75 LATEX_TEMPLATE_PATH = "/../templates/tex/"
69 LATEX_TEMPLATE_PATH = "/../templates/tex/"
76 LATEX_TEMPLATE_SKELETON_PATH = "/../templates/tex/skeleton/"
70 LATEX_TEMPLATE_SKELETON_PATH = "/../templates/tex/skeleton/"
77 LATEX_TEMPLATE_EXTENSION = ".tplx"
71 LATEX_TEMPLATE_EXTENSION = ".tplx"
78
72
79 #Special Jinja2 syntax that will not conflict when exporting latex.
73 #Special Jinja2 syntax that will not conflict when exporting latex.
80 LATEX_JINJA_COMMENT_BLOCK = ["((=", "=))"]
74 LATEX_JINJA_COMMENT_BLOCK = ["((=", "=))"]
81 LATEX_JINJA_VARIABLE_BLOCK = ["(((", ")))"]
75 LATEX_JINJA_VARIABLE_BLOCK = ["(((", ")))"]
82 LATEX_JINJA_LOGIC_BLOCK = ["((*", "*))"]
76 LATEX_JINJA_LOGIC_BLOCK = ["((*", "*))"]
83
77
84 #Jinja2 extensions to load.
78 #Jinja2 extensions to load.
85 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
79 JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols']
86
80
87 #Latex substitutions for escaping latex.
81 #Latex substitutions for escaping latex.
88 LATEX_SUBS = (
82 LATEX_SUBS = (
89 (re.compile(r'\\'), r'\\textbackslash'),
83 (re.compile(r'\\'), r'\\textbackslash'),
90 (re.compile(r'([{}_#%&$])'), r'\\\1'),
84 (re.compile(r'([{}_#%&$])'), r'\\\1'),
91 (re.compile(r'~'), r'\~{}'),
85 (re.compile(r'~'), r'\~{}'),
92 (re.compile(r'\^'), r'\^{}'),
86 (re.compile(r'\^'), r'\^{}'),
93 (re.compile(r'"'), r"''"),
87 (re.compile(r'"'), r"''"),
94 (re.compile(r'\.\.\.+'), r'\\ldots'),
88 (re.compile(r'\.\.\.+'), r'\\ldots'),
95 )
89 )
96
90
97 #-----------------------------------------------------------------------------
91 #-----------------------------------------------------------------------------
98 # Classes and functions
92 # Classes and functions
99 #-----------------------------------------------------------------------------
93 #-----------------------------------------------------------------------------
100 class Exporter(Configurable):
94 class Exporter(Configurable):
101 """ A Jinja2 base converter templates
95 """ A Jinja2 base converter templates
102
96
103 Preprocess the ipynb files, feed it throug jinja templates,
97 Preprocess the ipynb files, feed it throug jinja templates,
104 and spit an converted files and a data object with other data
98 and spit an converted files and a data object with other data
105 should be mostly configurable
99 should be mostly configurable
106 """
100 """
107
101
108 pre_transformer_order = List(['haspyout_transformer'],
102 pre_transformer_order = List(['haspyout_transformer'],
109 config=True,
103 config=True,
110 help= """
104 help= """
111 An ordered list of pre transformer to apply to the ipynb
105 An ordered list of pre transformer to apply to the ipynb
112 file before running through templates
106 file before running through templates
113 """
107 """
114 )
108 )
115
109
116 tex_environement = Bool(
110 tex_environement = Bool(
117 False,
111 False,
118 config=True,
112 config=True,
119 help=" Whether or not the user is exporting to latex.")
113 help=" Whether or not the user is exporting to latex.")
120
114
121 template_file = Unicode(
115 template_file = Unicode(
122 '', config=True,
116 '', config=True,
123 help="Name of the template file to use")
117 help="Name of the template file to use")
124
118
125 fileext = Unicode(
119 fileext = Unicode(
126 'txt', config=True,
120 'txt', config=True,
127 help="Extension of the file that should be written to disk"
121 help="Extension of the file that should be written to disk"
128 )
122 )
129
123
130 stdout = Bool(
124 stdout = Bool(
131 True, config=True,
125 True, config=True,
132 help="""Whether to print the converted ipynb file to stdout
126 help="""Whether to print the converted ipynb file to stdout
133 "use full do diff files without actually writing a new file"""
127 "use full do diff files without actually writing a new file"""
134 )
128 )
135
129
136 write = Bool(
130 write = Bool(
137 False, config=True,
131 False, config=True,
138 help="""Should the converted notebook file be written to disk
132 help="""Should the converted notebook file be written to disk
139 along with potential extracted resources."""
133 along with potential extracted resources."""
140 )
134 )
141
135
142 #Processors that process the input data prior to the export, set in the
136 #Processors that process the input data prior to the export, set in the
143 #constructor for this class.
137 #constructor for this class.
144 preprocessors = []
138 preprocessors = []
145
139
146 def __init__(self, preprocessors={}, jinja_filters={}, config=None, export_format, **kw):
140 def __init__(self, preprocessors={}, jinja_filters={}, config=None, export_format, **kw):
147 """ Init a new converter.
141 """ Init a new converter.
148
142
149 config: the Configurable config object to pass around.
143 config: the Configurable config object to pass around.
150
144
151 preprocessors: dict of **availlable** key/value function to run on
145 preprocessors: dict of **availlable** key/value function to run on
152 ipynb json data before conversion to extract/inline file.
146 ipynb json data before conversion to extract/inline file.
153 See `transformer.py` and `ConfigurableTransformers`
147 See `transformer.py` and `ConfigurableTransformers`
154
148
155 set the order in which the transformers should apply
149 set the order in which the transformers should apply
156 with the `pre_transformer_order` trait of this class
150 with the `pre_transformer_order` trait of this class
157
151
158 transformers registerd by this key will take precedence on
152 transformers registerd by this key will take precedence on
159 default one.
153 default one.
160
154
161 jinja_filters: dict of supplementary jinja filter that should be made
155 jinja_filters: dict of supplementary jinja filter that should be made
162 availlable in template. If those are of Configurable Class type,
156 availlable in template. If those are of Configurable Class type,
163 they will be instanciated with the config object as argument.
157 they will be instanciated with the config object as argument.
164
158
165 user defined filter will overwrite the one availlable by default.
159 user defined filter will overwrite the one availlable by default.
166 """
160 """
167
161
168 #Merge default config options with user specific override options.
162 #Merge default config options with user specific override options.
169 default_config = self._get_default_options()
163 default_config = self._get_default_options()
170 if not config == None:
164 if not config == None:
171 default_config._merge(config)
165 default_config._merge(config)
172 config = default_config
166 config = default_config
173
167
174 #Call the base class constructor
168 #Call the base class constructor
175 super(Exporter, self).__init__(config=config, **kw)
169 super(Exporter, self).__init__(config=config, **kw)
176
170
177 #Create a Latex environment if the user is exporting latex.
171 #Create a Latex environment if the user is exporting latex.
178 if self.tex_environement:
172 if self.tex_environement:
179 self.ext = LATEX_TEMPLATE_EXTENSION
173 self.ext = LATEX_TEMPLATE_EXTENSION
180 self.env = Environment(
174 self.env = Environment(
181 loader=FileSystemLoader([
175 loader=FileSystemLoader([
182 os.path.dirname(os.path.realpath(__file__)) + LATEX_TEMPLATE_PATH,
176 os.path.dirname(os.path.realpath(__file__)) + LATEX_TEMPLATE_PATH,
183 os.path.dirname(os.path.realpath(__file__)) + LATEX_TEMPLATE_SKELETON_PATH,
177 os.path.dirname(os.path.realpath(__file__)) + LATEX_TEMPLATE_SKELETON_PATH,
184 ]),
178 ]),
185 extensions=JINJA_EXTENSIONS
179 extensions=JINJA_EXTENSIONS
186 )
180 )
187
181
188 #Set special Jinja2 syntax that will not conflict with latex.
182 #Set special Jinja2 syntax that will not conflict with latex.
189 self.env.block_start_string = LATEX_JINJA_LOGIC_BLOCK[0]
183 self.env.block_start_string = LATEX_JINJA_LOGIC_BLOCK[0]
190 self.env.block_end_string = LATEX_JINJA_LOGIC_BLOCK[1]
184 self.env.block_end_string = LATEX_JINJA_LOGIC_BLOCK[1]
191 self.env.variable_start_string = LATEX_JINJA_VARIABLE_BLOCK[0]
185 self.env.variable_start_string = LATEX_JINJA_VARIABLE_BLOCK[0]
192 self.env.variable_end_string = LATEX_JINJA_VARIABLE_BLOCK[1]
186 self.env.variable_end_string = LATEX_JINJA_VARIABLE_BLOCK[1]
193 self.env.comment_start_string = LATEX_JINJA_COMMENT_BLOCK[0]
187 self.env.comment_start_string = LATEX_JINJA_COMMENT_BLOCK[0]
194 self.env.comment_end_string = LATEX_JINJA_COMMENT_BLOCK[1]
188 self.env.comment_end_string = LATEX_JINJA_COMMENT_BLOCK[1]
195
189
196 else: #Standard environment
190 else: #Standard environment
197 self.ext = TEMPLATE_EXTENSION
191 self.ext = TEMPLATE_EXTENSION
198 self.env = Environment(
192 self.env = Environment(
199 loader=FileSystemLoader([
193 loader=FileSystemLoader([
200 os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_PATH,
194 os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_PATH,
201 os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_SKELETON_PATH,
195 os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_SKELETON_PATH,
202 ]),
196 ]),
203 extensions=JINJA_EXTENSIONS
197 extensions=JINJA_EXTENSIONS
204 )
198 )
205
199
206 for name in self.pre_transformer_order:
200 for name in self.pre_transformer_order:
207 # get the user-defined transformer first
201 # get the user-defined transformer first
208 transformer = preprocessors.get(name, getattr(trans, name, None))
202 transformer = preprocessors.get(name, getattr(trans, name, None))
209 if isinstance(transformer, MetaHasTraits):
203 if isinstance(transformer, MetaHasTraits):
210 transformer = transformer(config=config)
204 transformer = transformer(config=config)
211 self.preprocessors.append(transformer)
205 self.preprocessors.append(transformer)
212
206
213 #For compatibility, TODO: remove later.
207 #For compatibility, TODO: remove later.
214 self.preprocessors.append(trans.coalesce_streams)
208 self.preprocessors.append(trans.coalesce_streams)
215 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
209 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
216 self.preprocessors.append(trans.RevealHelpTransformer(config=config))
210 self.preprocessors.append(trans.RevealHelpTransformer(config=config))
217 self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config))
211 self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config))
218 self.preprocessors.append(LatexTransformer(config=config))
212 self.preprocessors.append(LatexTransformer(config=config))
219
213
220 #Only load the sphinx transformer if the file reference worked
214 #Only load the sphinx transformer if the file reference worked
221 #(Sphinx dependencies exist on the user's machine.)
215 #(Sphinx dependencies exist on the user's machine.)
222 if SphinxTransformer:
216 if SphinxTransformer:
223 self.preprocessors.append(SphinxTransformer(config=config))
217 self.preprocessors.append(SphinxTransformer(config=config))
224
218
225 #Add filters to the Jinja2 environment
219 #Add filters to the Jinja2 environment
226 self.env.filters['filter_data_type'] = FilterDataType(config=config)
220 self.env.filters['filter_data_type'] = DataTypeFilter(config=config)
227 self.env.filters['pycomment'] = _python_comment
221 self.env.filters['pycomment'] = _python_comment
228 self.env.filters['indent'] = indent
222 self.env.filters['indent'] = indent
229 self.env.filters['rm_fake'] = _rm_fake
223 self.env.filters['rm_fake'] = _rm_fake
230 self.env.filters['rm_ansi'] = remove_ansi
224 self.env.filters['rm_ansi'] = remove_ansi
231 self.env.filters['markdown'] = markdown
225 self.env.filters['markdown'] = markdown
232 self.env.filters['ansi2html'] = ansi2html
226 self.env.filters['ansi2html'] = ansi2html
233 self.env.filters['markdown2latex'] = markdown2latex
227 self.env.filters['markdown2latex'] = markdown_utils.markdown2latex
234 self.env.filters['markdown2rst'] = markdown2rst
228 self.env.filters['markdown2rst'] = markdown_utils.markdown2rst
235 self.env.filters['get_lines'] = get_lines
229 self.env.filters['get_lines'] = get_lines
236 self.env.filters['wrap'] = strings.wrap
230 self.env.filters['wrap'] = strings.wrap
237 self.env.filters['rm_dollars'] = strings.strip_dollars
231 self.env.filters['rm_dollars'] = strings.strip_dollars
238 self.env.filters['rm_math_space'] = rm_math_space
232 self.env.filters['rm_math_space'] = rm_math_space
239 self.env.filters['highlight2html'] = highlight
233 self.env.filters['highlight2html'] = highlight
240 self.env.filters['highlight2latex'] = highlight2latex
234 self.env.filters['highlight2latex'] = highlight2latex
241
235
242 #Latex specific filters
236 #Latex specific filters
243 if self.tex_environement:
237 if self.tex_environement:
244 self.env.filters['escape_tex'] = _escape_tex
238 self.env.filters['escape_tex'] = _escape_tex
245 self.env.filters['highlight'] = highlight2latex
239 self.env.filters['highlight'] = highlight2latex
246 else:
240 else:
247 self.env.filters['highlight'] = highlight
241 self.env.filters['highlight'] = highlight
248
242
249 #Load user filters. Overwrite existing filters if need be.
243 #Load user filters. Overwrite existing filters if need be.
250 for key, user_filter in jinja_filters.iteritems():
244 for key, user_filter in jinja_filters.iteritems():
251 if isinstance(user_filter, MetaHasTraits):
245 if isinstance(user_filter, MetaHasTraits):
252 self.env.filters[key] = user_filter(config=config)
246 self.env.filters[key] = user_filter(config=config)
253 else:
247 else:
254 self.env.filters[key] = user_filter
248 self.env.filters[key] = user_filter
255
249
256 #Load the template file.
250 #Load the template file.
257 self.template = self.env.get_template(self.template_file+self.ext)
251 self.template = self.env.get_template(self.template_file+self.ext)
258
252
259
253
260 def export(self, nb):
254 def export(self, nb):
261 """Export notebook object
255 """Export notebook object
262
256
263 nb: Notebook object to export.
257 nb: Notebook object to export.
264
258
265 Returns both the converted ipynb file and a dict containing the
259 Returns both the converted ipynb file and a dict containing the
266 resources created along the way via the transformers and Jinja2
260 resources created along the way via the transformers and Jinja2
267 processing.
261 processing.
268 """
262 """
269
263
270 nb, resources = self._preprocess(nb)
264 nb, resources = self._preprocess(nb)
271 return self.template.render(nb=nb, resources=resources), resources
265 return self.template.render(nb=nb, resources=resources), resources
272
266
273
267
274 def from_filename(self, filename):
268 def from_filename(self, filename):
275 """Read and export a notebook from a filename
269 """Read and export a notebook from a filename
276
270
277 filename: Filename of the notebook file to export.
271 filename: Filename of the notebook file to export.
278
272
279 Returns both the converted ipynb file and a dict containing the
273 Returns both the converted ipynb file and a dict containing the
280 resources created along the way via the transformers and Jinja2
274 resources created along the way via the transformers and Jinja2
281 processing.
275 processing.
282 """
276 """
283 with io.open(filename) as f:
277 with io.open(filename) as f:
284 return self.export(nbformat.read(f, 'json'))
278 return self.export(nbformat.read(f, 'json'))
285
279
286
280
287 def from_file(self, file_stream):
281 def from_file(self, file_stream):
288 """Read and export a notebook from a filename
282 """Read and export a notebook from a filename
289
283
290 file_stream: File handle of file that contains notebook data.
284 file_stream: File handle of file that contains notebook data.
291
285
292 Returns both the converted ipynb file and a dict containing the
286 Returns both the converted ipynb file and a dict containing the
293 resources created along the way via the transformers and Jinja2
287 resources created along the way via the transformers and Jinja2
294 processing.
288 processing.
295 """
289 """
296
290
297 return self.export(nbformat.read(file_stream, 'json'))
291 return self.export(nbformat.read(file_stream, 'json'))
298
292
299
293
300 def _preprocess(self, nb):
294 def _preprocess(self, nb):
301 """ Preprocess the notebook using the transformers specific
295 """ Preprocess the notebook using the transformers specific
302 for the current export format.
296 for the current export format.
303
297
304 nb: Notebook to preprocess
298 nb: Notebook to preprocess
305 """
299 """
306
300
307 #Dict of 'resources' that can be filled by the preprocessors.
301 #Dict of 'resources' that can be filled by the preprocessors.
308 resources = {}
302 resources = {}
309
303
310 #Run each transformer on the notebook. Carry the output along
304 #Run each transformer on the notebook. Carry the output along
311 #to each transformer
305 #to each transformer
312 for transformer in self.preprocessors:
306 for transformer in self.preprocessors:
313 nb, resources = transformer(nb, resources)
307 nb, resources = transformer(nb, resources)
314 return nb, resources
308 return nb, resources
315
309
316
310
317 def _get_default_options(self, export_format):
311 def _get_default_options(self, export_format):
318 """ Load the default options for built in formats.
312 """ Load the default options for built in formats.
319
313
320 export_format: Format being exported to.
314 export_format: Format being exported to.
321 """
315 """
322
316
323 c = get_config()
317 c = get_config()
324
318
325 #Set default data extraction priorities.
319 #Set default data extraction priorities.
326 c.GlobalConfigurable.display_data_priority =['svg', 'png', 'latex', 'jpg', 'jpeg','text']
320 c.GlobalConfigurable.display_data_priority =['svg', 'png', 'latex', 'jpg', 'jpeg','text']
327 c.ExtractFigureTransformer.display_data_priority=['svg', 'png', 'latex', 'jpg', 'jpeg','text']
321 c.ExtractFigureTransformer.display_data_priority=['svg', 'png', 'latex', 'jpg', 'jpeg','text']
328 c.ConverterTemplate.display_data_priority= ['svg', 'png', 'latex', 'jpg', 'jpeg','text']
322 c.ConverterTemplate.display_data_priority= ['svg', 'png', 'latex', 'jpg', 'jpeg','text']
329
323
330 #For most (or all cases), the template file name matches the format name.
324 #For most (or all cases), the template file name matches the format name.
331 c.ConverterTemplate.template_file = export_format
325 c.ConverterTemplate.template_file = export_format
332
326
333 if export_format == "basichtml" or "fullhtml" or "reveal":
327 if export_format == "basichtml" or "fullhtml" or "reveal":
334 c.CSSHtmlHeaderTransformer.enabled=True
328 c.CSSHtmlHeaderTransformer.enabled=True
335 if export_format == 'reveal'
329 if export_format == 'reveal'
336 c.NbconvertApp.fileext='reveal.html'
330 c.NbconvertApp.fileext='reveal.html'
337 else:
331 else:
338 c.NbconvertApp.fileext='html'
332 c.NbconvertApp.fileext='html'
339
333
340 elif export_format == "latex_sphinx_howto" or export_format == "latex_sphinx_manual":
334 elif export_format == "latex_sphinx_howto" or export_format == "latex_sphinx_manual":
341
335
342 #Turn on latex environment
336 #Turn on latex environment
343 c.ConverterTemplate.tex_environement=True
337 c.ConverterTemplate.tex_environement=True
344
338
345 #Standard latex extension
339 #Standard latex extension
346 c.NbconvertApp.fileext='tex'
340 c.NbconvertApp.fileext='tex'
347
341
348 #Prioritize latex extraction for latex exports.
342 #Prioritize latex extraction for latex exports.
349 c.GlobalConfigurable.display_data_priority =['latex', 'svg', 'png', 'jpg', 'jpeg' , 'text']
343 c.GlobalConfigurable.display_data_priority =['latex', 'svg', 'png', 'jpg', 'jpeg' , 'text']
350 c.ExtractFigureTransformer.display_data_priority=['latex', 'svg', 'png', 'jpg', 'jpeg']
344 c.ExtractFigureTransformer.display_data_priority=['latex', 'svg', 'png', 'jpg', 'jpeg']
351 c.ExtractFigureTransformer.extra_ext_map={'svg':'pdf'}
345 c.ExtractFigureTransformer.extra_ext_map={'svg':'pdf'}
352 c.ExtractFigureTransformer.enabled=True
346 c.ExtractFigureTransformer.enabled=True
353
347
354 # Enable latex transformers (make markdown2latex work with math $.)
348 # Enable latex transformers (make markdown2latex work with math $.)
355 c.LatexTransformer.enabled=True
349 c.LatexTransformer.enabled=True
356 c.SphinxTransformer.enabled = True
350 c.SphinxTransformer.enabled = True
357
351
358 elif export_format == 'markdown':
352 elif export_format == 'markdown':
359 c.NbconvertApp.fileext='md'
353 c.NbconvertApp.fileext='md'
360 c.ExtractFigureTransformer.enabled=True
354 c.ExtractFigureTransformer.enabled=True
361
355
362 elif export_format == 'python':
356 elif export_format == 'python':
363 c.NbconvertApp.fileext='py'
357 c.NbconvertApp.fileext='py'
364
358
365
359
366 elif export_format == 'rst':
360 elif export_format == 'rst':
367 c.NbconvertApp.fileext='rst'
361 c.NbconvertApp.fileext='rst'
368 c.ExtractFigureTransformer.enabled=True
362 c.ExtractFigureTransformer.enabled=True
369 return c
363 return c
370
364
371
365
372 #TODO: Comment me.
366 #TODO: Comment me.
373 def _rm_fake(strng):
367 def _rm_fake(strng):
374 return strng.replace('/files/', '')
368 return strng.replace('/files/', '')
375
369
376
370
377 #TODO: Comment me.
371 #TODO: Comment me.
378 def _python_comment(string):
372 def _python_comment(string):
379 return '# '+'\n# '.join(string.split('\n'))
373 return '# '+'\n# '.join(string.split('\n'))
380
374
381
375
382 #TODO: Comment me.
376 #TODO: Comment me.
383 def _escape_tex(value):
377 def _escape_tex(value):
384 newval = value
378 newval = value
385 for pattern, replacement in LATEX_SUBS:
379 for pattern, replacement in LATEX_SUBS:
386 newval = pattern.sub(replacement, newval)
380 newval = pattern.sub(replacement, newval)
387 return newval No newline at end of file
381 return newval
1 NO CONTENT: file renamed from nbconvert1/converters/transformers.py to transformers/base.py
NO CONTENT: file renamed from nbconvert1/converters/transformers.py to transformers/base.py
@@ -1,75 +1,92 b''
1 """
1 """Latex transformer.
2
2 Module that allows latex output notebooks to be conditioned before
3 Module that allows latex output notebooks to be conditioned before
3 they are converted.
4 they are converted.
4 """
5 """
5 from __future__ import absolute_import
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2013, the IPython Development Team.
8 #
9 # Distributed under the terms of the Modified BSD License.
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
6
13
7 # Configurable traitlets
14 #-----------------------------------------------------------------------------
15 # Imports
16 #-----------------------------------------------------------------------------
17 from __future__ import print_function, absolute_import
8
18
19 # Our own imports
9 # Needed to override transformer
20 # Needed to override transformer
10 from .transformers import (ActivatableTransformer)
21 from .transformers import (ActivatableTransformer) #TODO
11
22
23 #-----------------------------------------------------------------------------
24 # Classes
25 #-----------------------------------------------------------------------------
12 class LatexTransformer(ActivatableTransformer):
26 class LatexTransformer(ActivatableTransformer):
13 """
27 """
14 Converter for latex destined documents.
28 Converter for latex destined documents.
15 """
29 """
16
30
17 def cell_transform(self, cell, other, index):
31 def cell_transform(self, cell, other, index):
18 """
32 """
19 Apply a transformation on each cell,
33 Apply a transformation on each cell,
20
34
21 receive the current cell, the resource dict and the index of current cell as parameter.
35 receive the current cell, the resource dict and the index of current cell as parameter.
22
36
23 Returns modified cell and resource dict.
37 Returns modified cell and resource dict.
24 """
38 """
25 if hasattr(cell, "source") and cell.cell_type == "markdown":
39 if hasattr(cell, "source") and cell.cell_type == "markdown":
26 cell.source = rm_math_space(cell.source)
40 cell.source = rm_math_space(cell.source)
27 return cell, other
41 return cell, other
28
42
43 #-----------------------------------------------------------------------------
44 # Functions
45 #-----------------------------------------------------------------------------
29 def rm_math_space(text):
46 def rm_math_space(text):
30 """
47 """
31 Remove the space between latex math commands and enclosing $ symbols.
48 Remove the space between latex math commands and enclosing $ symbols.
32 """
49 """
33
50
34 # First, scan through the markdown looking for $. If
51 # First, scan through the markdown looking for $. If
35 # a $ symbol is found, without a preceding \, assume
52 # a $ symbol is found, without a preceding \, assume
36 # it is the start of a math block. UNLESS that $ is
53 # it is the start of a math block. UNLESS that $ is
37 # not followed by another within two math_lines.
54 # not followed by another within two math_lines.
38 math_regions = []
55 math_regions = []
39 math_lines = 0
56 math_lines = 0
40 within_math = False
57 within_math = False
41 math_start_index = 0
58 math_start_index = 0
42 ptext = ''
59 ptext = ''
43 last_character = ""
60 last_character = ""
44 skip = False
61 skip = False
45 for index, char in enumerate(text):
62 for index, char in enumerate(text):
46 #Make sure the character isn't preceeded by a backslash
63 #Make sure the character isn't preceeded by a backslash
47 if (char == "$" and last_character != "\\"):
64 if (char == "$" and last_character != "\\"):
48 # Close the math region if this is an ending $
65 # Close the math region if this is an ending $
49 if within_math:
66 if within_math:
50 within_math = False
67 within_math = False
51 skip = True
68 skip = True
52 ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$'
69 ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$'
53 math_regions.append([math_start_index, index+1])
70 math_regions.append([math_start_index, index+1])
54 else:
71 else:
55 # Start a new math region
72 # Start a new math region
56 within_math = True
73 within_math = True
57 math_start_index = index
74 math_start_index = index
58 math_lines = 0
75 math_lines = 0
59 # If we are in a math region, count the number of lines parsed.
76 # If we are in a math region, count the number of lines parsed.
60 # Cancel the math region if we find two line breaks!
77 # Cancel the math region if we find two line breaks!
61 elif char == "\n":
78 elif char == "\n":
62 if within_math:
79 if within_math:
63 math_lines += 1
80 math_lines += 1
64 if math_lines > 1:
81 if math_lines > 1:
65 within_math = False
82 within_math = False
66 ptext = ptext+text[math_start_index:index]
83 ptext = ptext+text[math_start_index:index]
67
84
68 # Remember the last character so we can easily watch
85 # Remember the last character so we can easily watch
69 # for backslashes
86 # for backslashes
70 last_character = char
87 last_character = char
71 if not within_math and not skip:
88 if not within_math and not skip:
72 ptext = ptext+char
89 ptext = ptext+char
73 if skip:
90 if skip:
74 skip = False
91 skip = False
75 return ptext
92 return ptext
@@ -1,271 +1,287 b''
1 """
1 """Module that allows custom Sphinx parameters to be set on the notebook and
2 Module that allows custom Sphinx parameters to be set on the notebook and
3 on the 'other' object passed into Jinja.
2 on the 'other' object passed into Jinja.
4 """
3 """
5 from __future__ import absolute_import
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15 from __future__ import print_function, absolute_import
6
16
17 # Stdlib imports
7 # Used to find Sphinx package location
18 # Used to find Sphinx package location
8 import sphinx
19 import sphinx
9 import os.path
20 import os.path
10
21
11 # Used to determine python version
22 # Used to determine python version
12 import sys
23 import sys
13
24
14 # Used to set the default date to today's date
25 # Used to set the default date to today's date
15 from datetime import date
26 from datetime import date
16
27
17 # Configurable traitlets
28 # Third-party imports
18 from IPython.utils.traitlets import Unicode, Bool
19
20 # Needed for Pygments latex definitions.
29 # Needed for Pygments latex definitions.
21 from pygments.formatters import LatexFormatter
30 from pygments.formatters import LatexFormatter
22
31
32 # Our own imports
33 # Configurable traitlets
34 from IPython.utils.traitlets import Unicode, Bool
35
23 # Needed to override transformer
36 # Needed to override transformer
24 from .transformers import (ActivatableTransformer)
37 from .transformers import (ActivatableTransformer) #TODO
25
38
39 #-----------------------------------------------------------------------------
40 # Classes and functions
41 #-----------------------------------------------------------------------------
26 class SphinxTransformer(ActivatableTransformer):
42 class SphinxTransformer(ActivatableTransformer):
27 """
43 """
28 Sphinx utility transformer.
44 Sphinx utility transformer.
29
45
30 This transformer is used to set variables needed by the latex to build
46 This transformer is used to set variables needed by the latex to build
31 Sphinx stylized templates.
47 Sphinx stylized templates.
32 """
48 """
33
49
34 interactive = Bool(True, config=True, help="""
50 interactive = Bool(True, config=True, help="""
35 Allows you to define whether or not the Sphinx exporter will prompt
51 Allows you to define whether or not the Sphinx exporter will prompt
36 you for input during the conversion process. If this is set to false,
52 you for input during the conversion process. If this is set to false,
37 the author, version, release, date, and chapter_style traits should
53 the author, version, release, date, and chapter_style traits should
38 be set.
54 be set.
39 """)
55 """)
40
56
41 author = Unicode("Unknown Author", config=True, help="Author name")
57 author = Unicode("Unknown Author", config=True, help="Author name")
42
58
43 version = Unicode("", config=True, help="""Version number
59 version = Unicode("", config=True, help="""Version number
44 You can leave this blank if you do not want to render a version number.
60 You can leave this blank if you do not want to render a version number.
45 Example: "1.0.0"
61 Example: "1.0.0"
46 """)
62 """)
47
63
48 release = Unicode("", config=True, help="""Release name
64 release = Unicode("", config=True, help="""Release name
49 You can leave this blank if you do not want to render a release name.
65 You can leave this blank if you do not want to render a release name.
50 Example: "Rough Draft"
66 Example: "Rough Draft"
51 """)
67 """)
52
68
53 publish_date = Unicode("", config=True, help="""Publish date
69 publish_date = Unicode("", config=True, help="""Publish date
54 This is the date to render on the document as the publish date.
70 This is the date to render on the document as the publish date.
55 Leave this blank to default to todays date.
71 Leave this blank to default to todays date.
56 Example: "June 12, 1990"
72 Example: "June 12, 1990"
57 """)
73 """)
58
74
59 chapter_style = Unicode("Bjarne", config=True, help="""Sphinx chapter style
75 chapter_style = Unicode("Bjarne", config=True, help="""Sphinx chapter style
60 This is the style to use for the chapter headers in the document.
76 This is the style to use for the chapter headers in the document.
61 You may choose one of the following:
77 You may choose one of the following:
62 "Bjarne" (default)
78 "Bjarne" (default)
63 "Lenny"
79 "Lenny"
64 "Glenn"
80 "Glenn"
65 "Conny"
81 "Conny"
66 "Rejne"
82 "Rejne"
67 "Sonny" (used for international documents)
83 "Sonny" (used for international documents)
68 """)
84 """)
69
85
70 output_style = Unicode("notebook", config=True, help="""Nbconvert Ipython
86 output_style = Unicode("notebook", config=True, help="""Nbconvert Ipython
71 notebook input/output formatting style.
87 notebook input/output formatting style.
72 You may choose one of the following:
88 You may choose one of the following:
73 "simple (recommended for long code segments)"
89 "simple (recommended for long code segments)"
74 "notebook" (default)
90 "notebook" (default)
75 """)
91 """)
76
92
77 center_output = Bool(False, config=True, help="""
93 center_output = Bool(False, config=True, help="""
78 Optional attempt to center all output. If this is false, no additional
94 Optional attempt to center all output. If this is false, no additional
79 formatting is applied.
95 formatting is applied.
80 """)
96 """)
81
97
82 use_headers = Bool(True, config=True, help="""
98 use_headers = Bool(True, config=True, help="""
83 Whether not a header should be added to the document.
99 Whether not a header should be added to the document.
84 """)
100 """)
85
101
86 overridetitle = Unicode("", config=True, help="")
102 overridetitle = Unicode("", config=True, help="")
87
103
88 def __call__(self, nb, other):
104 def __call__(self, nb, other):
89 """
105 """
90 Entry
106 Entry
91 Since we are not interested in any additional manipulation on a cell
107 Since we are not interested in any additional manipulation on a cell
92 by cell basis, we do not call the base implementation.
108 by cell basis, we do not call the base implementation.
93 """
109 """
94 if self.enabled:
110 if self.enabled:
95 return self.transform(nb, other)
111 return self.transform(nb, other)
96 else:
112 else:
97 return nb,other
113 return nb,other
98
114
99 def transform(self, nb, other):
115 def transform(self, nb, other):
100 """
116 """
101 Sphinx transformation to apply on each notebook.
117 Sphinx transformation to apply on each notebook.
102 """
118 """
103
119
104 # TODO: Add versatile method of additional notebook metadata. Include
120 # TODO: Add versatile method of additional notebook metadata. Include
105 # handling of multiple files. For now use a temporay namespace,
121 # handling of multiple files. For now use a temporay namespace,
106 # '_draft' to signify that this needs to change.
122 # '_draft' to signify that this needs to change.
107 if not "_draft" in nb.metadata:
123 if not "_draft" in nb.metadata:
108 nb.metadata._draft = {}
124 nb.metadata._draft = {}
109
125
110 if not "sphinx" in other:
126 if not "sphinx" in other:
111 other["sphinx"] = {}
127 other["sphinx"] = {}
112
128
113 if self.interactive:
129 if self.interactive:
114
130
115 # Prompt the user for additional meta data that doesn't exist currently
131 # Prompt the user for additional meta data that doesn't exist currently
116 # but would be usefull for Sphinx.
132 # but would be usefull for Sphinx.
117 nb.metadata._draft["author"] = self._prompt_author()
133 nb.metadata._draft["author"] = self._prompt_author()
118 nb.metadata._draft["version"] = self._prompt_version()
134 nb.metadata._draft["version"] = self._prompt_version()
119 nb.metadata._draft["release"] = self._prompt_release()
135 nb.metadata._draft["release"] = self._prompt_release()
120 nb.metadata._draft["date"] = self._prompt_date()
136 nb.metadata._draft["date"] = self._prompt_date()
121
137
122 # Prompt the user for the document style.
138 # Prompt the user for the document style.
123 other["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
139 other["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
124 other["sphinx"]["outputstyle"] = self._prompt_output_style()
140 other["sphinx"]["outputstyle"] = self._prompt_output_style()
125
141
126 # Small options
142 # Small options
127 other["sphinx"]["centeroutput"] = self._prompt_boolean("Do you want to center the output? (false)", False)
143 other["sphinx"]["centeroutput"] = self._prompt_boolean("Do you want to center the output? (false)", False)
128 other["sphinx"]["header"] = self._prompt_boolean("Should a Sphinx document header be used? (true)", True)
144 other["sphinx"]["header"] = self._prompt_boolean("Should a Sphinx document header be used? (true)", True)
129 else:
145 else:
130
146
131 # Try to use the traitlets.
147 # Try to use the traitlets.
132 nb.metadata._draft["author"] = self.author
148 nb.metadata._draft["author"] = self.author
133 nb.metadata._draft["version"] = self.version
149 nb.metadata._draft["version"] = self.version
134 nb.metadata._draft["release"] = self.release
150 nb.metadata._draft["release"] = self.release
135
151
136 # Use todays date if none is provided.
152 # Use todays date if none is provided.
137 if len(self.publish_date.strip()) == 0:
153 if len(self.publish_date.strip()) == 0:
138 nb.metadata._draft["date"] = date.today().strftime("%B %-d, %Y")
154 nb.metadata._draft["date"] = date.today().strftime("%B %-d, %Y")
139 else:
155 else:
140 nb.metadata._draft["date"] = self.publish_date
156 nb.metadata._draft["date"] = self.publish_date
141
157
142 # Sphinx traitlets.
158 # Sphinx traitlets.
143 other["sphinx"]["chapterstyle"] = self.chapter_style
159 other["sphinx"]["chapterstyle"] = self.chapter_style
144 other["sphinx"]["outputstyle"] = self.output_style
160 other["sphinx"]["outputstyle"] = self.output_style
145 other["sphinx"]["centeroutput"] = self.center_output
161 other["sphinx"]["centeroutput"] = self.center_output
146 other["sphinx"]["header"] = self.use_headers
162 other["sphinx"]["header"] = self.use_headers
147
163
148 # Find and pass in the path to the Sphinx dependencies.
164 # Find and pass in the path to the Sphinx dependencies.
149 other["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs")
165 other["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs")
150
166
151 # Generate Pygments definitions for Latex
167 # Generate Pygments definitions for Latex
152 other["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
168 other["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
153
169
154 if not (self.overridetitle == None or len(self.overridetitle.strip()) == 0):
170 if not (self.overridetitle == None or len(self.overridetitle.strip()) == 0):
155 nb.metadata.name = self.overridetitle
171 nb.metadata.name = self.overridetitle
156
172
157 # End
173 # End
158 return nb, other
174 return nb, other
159
175
160 def _generate_pygments_latex_def(self):
176 def _generate_pygments_latex_def(self):
161 return LatexFormatter().get_style_defs()
177 return LatexFormatter().get_style_defs()
162
178
163 def _prompt_author(self):
179 def _prompt_author(self):
164 return self._input("Author name: ")
180 return self._input("Author name: ")
165
181
166 def _prompt_version(self):
182 def _prompt_version(self):
167 return self._input("Version (ie ""1.0.0""): ")
183 return self._input("Version (ie ""1.0.0""): ")
168
184
169 def _prompt_release(self):
185 def _prompt_release(self):
170 return self._input("Release Name (ie ""Rough draft""): ")
186 return self._input("Release Name (ie ""Rough draft""): ")
171
187
172 def _prompt_date(self):
188 def _prompt_date(self):
173 default_date = date.today().strftime("%B %-d, %Y")
189 default_date = date.today().strftime("%B %-d, %Y")
174 user_date = self._input("Date (deafults to \"" + default_date + "\"): ")
190 user_date = self._input("Date (deafults to \"" + default_date + "\"): ")
175 if len(user_date.strip()) == 0:
191 if len(user_date.strip()) == 0:
176 user_date = default_date
192 user_date = default_date
177 return user_date
193 return user_date
178
194
179 def _prompt_boolean(self, prompt, default=False):
195 def _prompt_boolean(self, prompt, default=False):
180 response = self._input(prompt)
196 response = self._input(prompt)
181 response = response.strip().lower()
197 response = response.strip().lower()
182
198
183 #Catch 1, true, yes as True
199 #Catch 1, true, yes as True
184 if len(response) > 0 and (response == "1" or response[0] == "t" or response[0] == "y"):
200 if len(response) > 0 and (response == "1" or response[0] == "t" or response[0] == "y"):
185 return True
201 return True
186
202
187 #Catch 0, false, no as False
203 #Catch 0, false, no as False
188 elif len(response) > 0 and (response == "0" or response[0] == "f" or response[0] == "n"):
204 elif len(response) > 0 and (response == "0" or response[0] == "f" or response[0] == "n"):
189 return False
205 return False
190
206
191 else:
207 else:
192 return default
208 return default
193
209
194 def _prompt_output_style(self):
210 def _prompt_output_style(self):
195
211
196 # Dictionary of available output styles
212 # Dictionary of available output styles
197 styles = {1: "simple",
213 styles = {1: "simple",
198 2: "notebook"}
214 2: "notebook"}
199
215
200 #Append comments to the menu when displaying it to the user.
216 #Append comments to the menu when displaying it to the user.
201 comments = {1: "(recommended for long code segments)",
217 comments = {1: "(recommended for long code segments)",
202 2: "(default)"}
218 2: "(default)"}
203
219
204 return self._prompt_dictionary(styles, default_style=2, menu_comments=comments)
220 return self._prompt_dictionary(styles, default_style=2, menu_comments=comments)
205
221
206 def _prompt_chapter_title_style(self):
222 def _prompt_chapter_title_style(self):
207
223
208 # Dictionary of available Sphinx styles
224 # Dictionary of available Sphinx styles
209 styles = {1: "Bjarne",
225 styles = {1: "Bjarne",
210 2: "Lenny",
226 2: "Lenny",
211 3: "Glenn",
227 3: "Glenn",
212 4: "Conny",
228 4: "Conny",
213 5: "Rejne",
229 5: "Rejne",
214 6: "Sonny"}
230 6: "Sonny"}
215
231
216 #Append comments to the menu when displaying it to the user.
232 #Append comments to the menu when displaying it to the user.
217 comments = {1: "(default)",
233 comments = {1: "(default)",
218 6: "(for international documents)"}
234 6: "(for international documents)"}
219
235
220 return self._prompt_dictionary(styles, menu_comments=comments)
236 return self._prompt_dictionary(styles, menu_comments=comments)
221
237
222 def _prompt_dictionary(self, choices, default_style=1, menu_comments={}):
238 def _prompt_dictionary(self, choices, default_style=1, menu_comments={}):
223
239
224 # Build the menu that will be displayed to the user with
240 # Build the menu that will be displayed to the user with
225 # all of the options available.
241 # all of the options available.
226 prompt = ""
242 prompt = ""
227 for key, value in choices.iteritems():
243 for key, value in choices.iteritems():
228 prompt += "%d %s " % (key, value)
244 prompt += "%d %s " % (key, value)
229 if key in menu_comments:
245 if key in menu_comments:
230 prompt += menu_comments[key]
246 prompt += menu_comments[key]
231 prompt += "\n"
247 prompt += "\n"
232
248
233 # Continue to ask the user for a style until an appropriate
249 # Continue to ask the user for a style until an appropriate
234 # one is specified.
250 # one is specified.
235 response = -1
251 response = -1
236 while (not response in choices):
252 while (not response in choices):
237 try:
253 try:
238 text_response = self._input(prompt)
254 text_response = self._input(prompt)
239
255
240 # Use default option if no input.
256 # Use default option if no input.
241 if len(text_response.strip()) == 0:
257 if len(text_response.strip()) == 0:
242 response = default_style
258 response = default_style
243 else:
259 else:
244 response = int(text_response)
260 response = int(text_response)
245 except:
261 except:
246 print("Error: Value is not an available option. 0 selects the default.\n")
262 print("Error: Value is not an available option. 0 selects the default.\n")
247 return choices[response]
263 return choices[response]
248
264
249 def _input(self, prompt_text):
265 def _input(self, prompt_text):
250 """
266 """
251 Prompt the user for input.
267 Prompt the user for input.
252
268
253 The input command will change depending on the version of python
269 The input command will change depending on the version of python
254 installed. To maintain support for 2 and earlier, we must use
270 installed. To maintain support for 2 and earlier, we must use
255 raw_input in that case. Else use input.
271 raw_input in that case. Else use input.
256 """
272 """
257
273
258 # Try to get the python version. This command is only available in
274 # Try to get the python version. This command is only available in
259 # python 2 and later, so it's important that we catch the exception
275 # python 2 and later, so it's important that we catch the exception
260 # if the command isn't found.
276 # if the command isn't found.
261 try:
277 try:
262 majorversion = sys.version_info[0]
278 majorversion = sys.version_info[0]
263 except:
279 except:
264 majorversion = 1
280 majorversion = 1
265
281
266 # Use the correct function to prompt the user for input depending on
282 # Use the correct function to prompt the user for input depending on
267 # what python version the code is running in.
283 # what python version the code is running in.
268 if majorversion >= 3:
284 if majorversion >= 3:
269 return input(prompt_text)
285 return input(prompt_text)
270 else:
286 else:
271 return raw_input(prompt_text)
287 return raw_input(prompt_text)
General Comments 0
You need to be logged in to leave comments. Login now