##// END OF EJS Templates
Cleanup and refactor, transformers
Jonathan Frederic -
Show More
@@ -1,19 +1,53 b''
1 """
2 Contains base transformer with an enable/disable flag.
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
1 16 from .base import ConfigurableTransformer
2 17 from IPython.utils.traitlets import (Bool)
3 18
4 class ActivatableTransformer(ConfigurableTransformer):
5 """A simple ConfigurableTransformers that have an enabled flag
19 #-----------------------------------------------------------------------------
20 # Classes and Functions
21 #-----------------------------------------------------------------------------
6 22
7 Inherit from that if you just want to have a transformer which is
8 no-op by default but can be activated in profiles with
23 class ActivatableTransformer(ConfigurableTransformer):
24 """ConfigurableTransformer that has an enabled flag
9 25
10 c.YourTransformerName.enabled = True
26 Inherit from this if you just want to have a transformer which is
27 enabled by default and can be disabled via the config by
28 'c.YourTransformerName.enabled = True'
11 29 """
12 30
13 31 enabled = Bool(True, config=True)
14 32
15 def __call__(self, nb, other):
33 def __call__(self, nb, resources):
34 """
35 Transformation to apply on each notebook.
36
37 You should return modified nb, resources.
38 If you wish to apply your transform on each cell, you might want to
39 overwrite cell_transform method instead.
40
41 Parameters
42 ----------
43 nb : NotebookNode
44 Notebook being converted
45 resources : dictionary
46 Additional resources used in the conversion process. Allows
47 transformers to pass variables into the Jinja engine.
48 """
49
16 50 if not self.enabled :
17 return nb, other
51 return nb, resources
18 52 else :
19 return super(ActivatableTransformer, self).__call__(nb, other)
53 return super(ActivatableTransformer, self).__call__(nb, resources)
@@ -1,59 +1,99 b''
1 1 """
2 Module that regroups transformer that woudl be applied to ipynb files
2 Module that re-groups transformer that would be applied to iPyNB files
3 3 before going through the templating machinery.
4 4
5 It exposes convenient classes to inherit from to access configurability
6 as well as decorator to simplify tasks.
5 It exposes a convenient class to inherit from to access configurability.
7 6 """
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
9 #
10 # Distributed under the terms of the Modified BSD License.
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
8 18
9 19 from __future__ import print_function, absolute_import
10 20
11 21 from IPython.config.configurable import Configurable
12 22
23 #-----------------------------------------------------------------------------
24 # Classes and Functions
25 #-----------------------------------------------------------------------------
26
13 27 class ConfigurableTransformer(Configurable):
14 28 """ A configurable transformer
15 29
16 30 Inherit from this class if you wish to have configurability for your
17 31 transformer.
18 32
19 33 Any configurable traitlets this class exposed will be configurable in profiles
20 34 using c.SubClassName.atribute=value
21 35
22 36 you can overwrite cell_transform to apply a transformation independently on each cell
23 37 or __call__ if you prefer your own logic. See orresponding docstring for informations.
24
25
26 38 """
27 39
28 40 def __init__(self, config=None, **kw):
41 """
42 Public constructor
43
44 Parameters
45 ----------
46 config : Config
47 Configuration file structure
48 **kw : misc
49 Additional arguments
50 """
51
29 52 super(ConfigurableTransformer, self).__init__(config=config, **kw)
30 53
31 def __call__(self, nb, other):
32 """transformation to apply on each notebook.
33
34 received a handle to the current notebook as well as a dict of resources
35 which structure depends on the transformer.
36 54
37 You should return modified nb, other.
38
39 If you wish to apply on each cell, you might want to overwrite cell_transform method.
55 def __call__(self, nb, resources):
56 """
57 Transformation to apply on each notebook.
58
59 You should return modified nb, resources.
60 If you wish to apply your transform on each cell, you might want to
61 overwrite cell_transform method instead.
62
63 Parameters
64 ----------
65 nb : NotebookNode
66 Notebook being converted
67 resources : dictionary
68 Additional resources used in the conversion process. Allows
69 transformers to pass variables into the Jinja engine.
40 70 """
41 71 try :
42 72 for worksheet in nb.worksheets :
43 73 for index, cell in enumerate(worksheet.cells):
44 worksheet.cells[index], other = self.cell_transform(cell, other, 100*index)
45 return nb, other
74
75 #TODO: Why are we multiplying the index by 100 here???
76 worksheet.cells[index], resources = self.cell_transform(cell, resources, 100*index)
77 return nb, resources
46 78 except NotImplementedError:
47 79 raise NotImplementedError('should be implemented by subclass')
48 80
49 def cell_transform(self, cell, other, index):
50 """
51 Overwrite if you want to apply a transformation on each cell,
52 81
53 receive the current cell, the resource dict and the index of current cell as parameter.
54
55 You should return modified cell and resource dict.
82 def cell_transform(self, cell, resources, index):
83 """
84 Overwrite if you want to apply a transformation on each cell. You
85 should return modified cell and resource dictionary.
86
87 Parameters
88 ----------
89 cell : NotebookNode cell
90 Notebook cell being processed
91 resources : dictionary
92 Additional resources used in the conversion process. Allows
93 transformers to pass variables into the Jinja engine.
94 index : int
95 Index of the cell being processed
56 96 """
57 97
58 98 raise NotImplementedError('should be implemented by subclass')
59 return cell, other
99 return cell, resources
@@ -1,42 +1,75 b''
1 """Module that allows latex output notebooks to be conditioned before
2 they are converted. Exposes a decorator (@cell_preprocessor) in
3 addition to the coalesce_streams pre-proccessor.
4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
1 12
2 def cell_preprocessor(function):
3 """ wrap a function to be executed on all cells of a notebook
13 #-----------------------------------------------------------------------------
14 # Functions
15 #-----------------------------------------------------------------------------
4 16
5 wrapped function parameters :
6 cell : the cell
7 other : external resources
8 index : index of the cell
9 """
10 def wrappedfunc(nb, other):
17 def cell_preprocessor(function):
18 """
19 Wrap a function to be executed on all cells of a notebook
20
21 Wrapped Parameters
22 ----------
23 cell : NotebookNode cell
24 Notebook cell being processed
25 resources : dictionary
26 Additional resources used in the conversion process. Allows
27 transformers to pass variables into the Jinja engine.
28 index : int
29 Index of the cell being processed
30 """
31
32 def wrappedfunc(nb, resources):
11 33 for worksheet in nb.worksheets :
12 34 for index, cell in enumerate(worksheet.cells):
13 worksheet.cells[index], other = function(cell, other, index)
14 return nb, other
35 worksheet.cells[index], resources = function(cell, resources, index)
36 return nb, resources
15 37 return wrappedfunc
16 38
17 39
18 40 @cell_preprocessor
19 def coalesce_streams(cell, other, count):
20 """merge consecutive sequences of stream output into single stream
21
22 to prevent extra newlines inserted at flush calls
23
24 TODO: handle \r deletion
25 """
41 def coalesce_streams(cell, resources, index):
42 """
43 Merge consecutive sequences of stream output into single stream
44 to prevent extra newlines inserted at flush calls
45
46 Parameters
47 ----------
48 cell : NotebookNode cell
49 Notebook cell being processed
50 resources : dictionary
51 Additional resources used in the conversion process. Allows
52 transformers to pass variables into the Jinja engine.
53 index : int
54 Index of the cell being processed
55 """
56
26 57 outputs = cell.get('outputs', [])
27 58 if not outputs:
28 return cell, other
59 return cell, resources
60
29 61 last = outputs[0]
30 62 new_outputs = [last]
63
31 64 for output in outputs[1:]:
32 65 if (output.output_type == 'stream' and
33 66 last.output_type == 'stream' and
34 67 last.stream == output.stream
35 68 ):
36 69 last.text += output.text
37 70 else:
38 71 new_outputs.append(output)
39 72
40 73 cell.outputs = new_outputs
41 return cell, other
74 return cell, resources
42 75
@@ -1,57 +1,119 b''
1 """Module that pre-processes the notebook for export to HTML.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 import os
16 import io
17
18 from pygments.formatters import HtmlFormatter
19
20 from IPython.utils import path
21
1 22 from .activatable import ActivatableTransformer
23
24 #-----------------------------------------------------------------------------
25 # Classes and functions
26 #-----------------------------------------------------------------------------
2 27
3 28 class CSSHtmlHeaderTransformer(ActivatableTransformer):
29 """
30 Transformer used to pre-process notebook for HTML output. Adds IPython notebook
31 front-end CSS and Pygments CSS to HTML output.
32 """
4 33
5 def __call__(self, nb, resources):
6 """Fetch and add css to the resource dict
34 header = []
7 35
8 Fetch css from IPython adn Pygment to add at the beginning
9 of the html files.
36 def __init__(self, config=None, **kw):
37 """
38 Public constructor
39
40 Parameters
41 ----------
42 config : Config
43 Configuration file structure
44 **kw : misc
45 Additional arguments
46 """
47
48 super(CSSHtmlHeaderTransformer, self).__init__(config=config, **kw)
10 49
11 Add this css in resources in the "inlining.css" key
50 if self.enabled :
51 self._regen_header()
52
53
54 def __call__(self, nb, resources):
55 """Fetch and add CSS to the resource dictionary
56
57 Fetch CSS from IPython and Pygments to add at the beginning
58 of the html files. Add this css in resources in the
59 "inlining.css" key
60
61 Parameters
62 ----------
63 nb : NotebookNode
64 Notebook being converted
65 resources : dictionary
66 Additional resources used in the conversion process. Allows
67 transformers to pass variables into the Jinja engine.
12 68 """
69
13 70 resources['inlining'] = {}
14 71 resources['inlining']['css'] = self.header
72
15 73 return nb, resources
16 74
17 header = []
18 75
19 def __init__(self, config=None, **kw):
20 super(CSSHtmlHeaderTransformer, self).__init__(config=config, **kw)
21 if self.enabled :
22 self.regen_header()
23
24 def regen_header(self):
25 ## lazy load asa this might not be use in many transformers
26 import os
27 from IPython.utils import path
28 import io
29 from pygments.formatters import HtmlFormatter
76 def _regen_header(self):
77 """
78 Fills self.header with lines of CSS extracted from iPython
79 and Pygments.
80 """
81
82 #Clear existing header.
30 83 header = []
31 static = os.path.join(path.get_ipython_package_dir(),
32 'frontend', 'html', 'notebook', 'static',
33 )
84
85 #Construct path to iPy CSS
86 static = os.path.join(path.get_ipython_package_dir(), 'frontend',
87 'html', 'notebook', 'static')
34 88 css = os.path.join(static, 'css')
89
90 #Load each known CSS file.
35 91 for sheet in [
36 # do we need jquery and prettify?
92 # TODO: do we need jquery and prettify?
37 93 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
38 94 # 'jquery-ui.min.css'),
39 95 # os.path.join(static, 'prettify', 'prettify.css'),
96
40 97 os.path.join(css, 'boilerplate.css'),
41 98 os.path.join(css, 'fbm.css'),
42 99 os.path.join(css, 'notebook.css'),
43 100 os.path.join(css, 'renderedhtml.css'),
44 101 os.path.join(css, 'style.min.css'),
45 ]:
102 ]:
103
46 104 try:
47 with io.open(sheet, encoding='utf-8') as f:
48 s = f.read()
49 header.append(s)
105 with io.open(sheet, encoding='utf-8') as file:
106 file_text = file.read()
107 header.append(file_text)
50 108 except IOError:
51 # new version of ipython with style.min.css, pass
109
110 # New version of iPython with style.min.css, pass
52 111 pass
53 112
113 #Add pygments CSS
54 114 pygments_css = HtmlFormatter().get_style_defs('.highlight')
55 115 header.append(pygments_css)
116
117 #Set header
56 118 self.header = header
57 119
@@ -1,66 +1,127 b''
1 """Module containing a transformer that extracts all of the figures from the
2 notebook file. The extracted figures are returned in the 'resources' dictionary.
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
1 16 from IPython.utils.traitlets import (Dict, List, Unicode)
2 17 from .activatable import ActivatableTransformer
3 18
19 #-----------------------------------------------------------------------------
20 # Constants
21 #-----------------------------------------------------------------------------
22
23 FIGURES_KEY = "figures"
24 BINARY_KEY = "binary"
25 TEXT_KEY = "text"
26
27 #-----------------------------------------------------------------------------
28 # Classes
29 #-----------------------------------------------------------------------------
30
4 31 class ExtractFigureTransformer(ActivatableTransformer):
32 """
33 Extracts all of the figures from the notebook file. The extracted
34 figures are returned in the 'resources' dictionary.
35 """
36
37 extra_extension_map = Dict({},
38 config=True,
39 help="""Extra map to override extension based on type.
40 Useful for latex where SVG will be converted to PDF before inclusion
41 """)
42
43 key_format_map = Dict({}, config=True,)
44 figure_name_format_map = Dict({}, config=True)
5 45
46 display_data_priority = List(['svg', 'png', 'latex', 'jpg', 'jpeg','text'])
6 47
7 extra_ext_map = Dict({},
8 config=True,
9 help="""extra map to override extension based on type.
10 Usefull for latex where svg will be converted to pdf before inclusion
11 """
12 )
48 #TODO: Change this to .format {} syntax
49 default_key_template = Unicode('_fig_{count:02d}.{ext}', config=True)
13 50
14 key_format_map = Dict({},
15 config=True,
16 )
51 def cell_transform(self, cell, resources, index):
52 """
53 Apply a transformation on each cell,
54
55 Parameters
56 ----------
57 cell : NotebookNode cell
58 Notebook cell being processed
59 resources : dictionary
60 Additional resources used in the conversion process. Allows
61 transformers to pass variables into the Jinja engine.
62 index : int
63 Modified index of the cell being processed (see base.py)
64 """
65
66 if resources.get(FIGURES_KEY, None) is None :
67 resources[FIGURES_KEY] = {TEXT_KEY:{},BINARY_KEY:{}}
68
69 for out in cell.get('outputs', []):
70 for out_type in self.display_data_priority:
71
72 if out.hasattr(out_type):
73 figname, key, data, binary = self._new_figure(out[out_type], out_type, index)
74 out['key_'+out_type] = figname
75
76 if binary :
77 resources[FIGURES_KEY][BINARY_KEY][key] = data
78 else :
79 resources[FIGURES_KEY][TEXT_KEY][key] = data
80
81 index += 1
82 return cell, resources
17 83
18 figname_format_map = Dict({},
19 config=True,
20 )
21 84
22 display_data_priority = List(['svg', 'png', 'latex', 'jpg', 'jpeg','text'])
85 def _get_override_extension(self, extension):
86 """Gets the overriden extension if it exists, else returns extension.
23 87
24 #to do change this to .format {} syntax
25 default_key_tpl = Unicode('_fig_{count:02d}.{ext}', config=True)
88 Parameters
89 ----------
90 extension : str
91 File extension.
92 """
93
94 if extension in self.extra_extension_map :
95 return self.extra_extension_map[extension]
96
97 return extension
26 98
27 def _get_ext(self, ext):
28 if ext in self.extra_ext_map :
29 return self.extra_ext_map[ext]
30 return ext
31 99
32 def _new_figure(self, data, fmt, count):
100 def _new_figure(self, data, format, index):
33 101 """Create a new figure file in the given format.
34 102
103 Parameters
104 ----------
105 data : str
106 Cell data (from Notebook node cell)
107 resources : dictionary
108 Additional resources used in the conversion process. Allows
109 transformers to pass variables into the Jinja engine.
110 index : int
111 Modified index of the cell being processed (see base.py)
35 112 """
36 tplf = self.figname_format_map.get(fmt, self.default_key_tpl)
37 tplk = self.key_format_map.get(fmt, self.default_key_tpl)
113
114 figure_name_template = self.figure_name_format_map.get(format, self.default_key_template)
115 key_template = self.key_format_map.get(format, self.default_key_template)
38 116
39 # option to pass the hash as data ?
40 figname = tplf.format(count=count, ext=self._get_ext(fmt))
41 key = tplk.format(count=count, ext=self._get_ext(fmt))
117 #TODO: option to pass the hash as data?
118 figure_name = figure_name_template.format(index=index, ext=self._get_override_extension(format))
119 key = key_template.format(index=index, ext=self._get_override_extension(format))
42 120
43 # Binary files are base64-encoded, SVG is already XML
121 #Binary files are base64-encoded, SVG is already XML
44 122 binary = False
45 if fmt in ('png', 'jpg', 'pdf'):
123 if format in ('png', 'jpg', 'pdf'):
46 124 data = data.decode('base64')
47 125 binary = True
48 126
49 return figname, key, data, binary
50
51
52 def cell_transform(self, cell, other, count):
53 if other.get('figures', None) is None :
54 other['figures'] = {'text':{},'binary':{}}
55 for out in cell.get('outputs', []):
56 for out_type in self.display_data_priority:
57 if out.hasattr(out_type):
58 figname, key, data, binary = self._new_figure(out[out_type], out_type, count)
59 out['key_'+out_type] = figname
60 if binary :
61 other['figures']['binary'][key] = data
62 else :
63 other['figures']['text'][key] = data
64 count = count+1
65 return cell, other
66
127 return figure_name, key, data, binary
@@ -1,43 +1,53 b''
1 """Latex transformer.
2
3 Module that allows latex output notebooks to be conditioned before
1 """Module that allows latex output notebooks to be conditioned before
4 2 they are converted.
5 3 """
6 4 #-----------------------------------------------------------------------------
7 5 # Copyright (c) 2013, the IPython Development Team.
8 6 #
9 7 # Distributed under the terms of the Modified BSD License.
10 8 #
11 9 # The full license is in the file COPYING.txt, distributed with this software.
12 10 #-----------------------------------------------------------------------------
13 11
14 12 #-----------------------------------------------------------------------------
15 13 # Imports
16 14 #-----------------------------------------------------------------------------
15
17 16 from __future__ import print_function, absolute_import
18 17
19 18 # Our own imports
20 19 # Needed to override transformer
21 20 from .activatable import (ActivatableTransformer)
22 21 from nbconvert.filters import latex
23 22
24 23 #-----------------------------------------------------------------------------
25 24 # Classes
26 25 #-----------------------------------------------------------------------------
26
27 27 class LatexTransformer(ActivatableTransformer):
28 28 """
29 29 Converter for latex destined documents.
30 30 """
31 31
32 def cell_transform(self, cell, other, index):
32 def cell_transform(self, cell, resources, index):
33 33 """
34 34 Apply a transformation on each cell,
35
36 receive the current cell, the resource dict and the index of current cell as parameter.
37
38 Returns modified cell and resource dict.
35
36 Parameters
37 ----------
38 cell : NotebookNode cell
39 Notebook cell being processed
40 resources : dictionary
41 Additional resources used in the conversion process. Allows
42 transformers to pass variables into the Jinja engine.
43 index : int
44 Modified index of the cell being processed (see base.py)
39 45 """
40 46
47 #If the cell is a markdown cell, preprocess the ampersands used to
48 #remove the space between them and their contents. Latex will complain
49 #if spaces exist between the ampersands and the math content.
50 #See filters.latex.rm_math_space for more information.
41 51 if hasattr(cell, "source") and cell.cell_type == "markdown":
42 52 cell.source = latex.rm_math_space(cell.source)
43 return cell, other
53 return cell, resources
@@ -1,17 +1,55 b''
1 """Module that pre-processes the notebook for export via Reveal.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
1 15 from .base import ConfigurableTransformer
2 16
17 #-----------------------------------------------------------------------------
18 # Classes and functions
19 #-----------------------------------------------------------------------------
20
3 21 class RevealHelpTransformer(ConfigurableTransformer):
4 22
5 def __call__(self, nb, other):
23 def __call__(self, nb, resources):
24 """
25 Called once to 'transform' contents of the notebook.
26
27 Parameters
28 ----------
29 nb : NotebookNode
30 Notebook being converted
31 resources : dictionary
32 Additional resources used in the conversion process. Allows
33 transformers to pass variables into the Jinja engine.
34 """
35
36
6 37 for worksheet in nb.worksheets :
7 38 for i, cell in enumerate(worksheet.cells):
39
40 #Make sure the cell has metadata.
8 41 if not cell.get('metadata', None):
9 42 break
43
44 #Get the slide type. If type is start of subslide or slide,
45 #end the last subslide/slide.
10 46 cell.metadata.slide_type = cell.metadata.get('slideshow', {}).get('slide_type', None)
11 47 if cell.metadata.slide_type is None:
12 48 cell.metadata.slide_type = '-'
13 49 if cell.metadata.slide_type in ['slide']:
14 50 worksheet.cells[i - 1].metadata.slide_helper = 'slide_end'
15 51 if cell.metadata.slide_type in ['subslide']:
16 52 worksheet.cells[i - 1].metadata.slide_helper = 'subslide_end'
17 return nb, other No newline at end of file
53
54 return nb, resources
55 No newline at end of file
@@ -1,287 +1,282 b''
1 1 """Module that allows custom Sphinx parameters to be set on the notebook and
2 on the 'other' object passed into Jinja.
2 on the 'other' object passed into Jinja. Called prior to Jinja conversion
3 process.
3 4 """
4 5 #-----------------------------------------------------------------------------
5 6 # Copyright (c) 2013, the IPython Development Team.
6 7 #
7 8 # Distributed under the terms of the Modified BSD License.
8 9 #
9 10 # The full license is in the file COPYING.txt, distributed with this software.
10 11 #-----------------------------------------------------------------------------
11 12
12 13 #-----------------------------------------------------------------------------
13 14 # Imports
14 15 #-----------------------------------------------------------------------------
16
15 17 from __future__ import print_function, absolute_import
16 18
17 19 # Stdlib imports
18 20 # Used to find Sphinx package location
19 21 import sphinx
20 22 import os.path
21 23
22 # Used to determine python version
23 import sys
24
25 24 # Used to set the default date to today's date
26 25 from datetime import date
27 26
28 27 # Third-party imports
29 28 # Needed for Pygments latex definitions.
30 29 from pygments.formatters import LatexFormatter
31 30
32 31 # Our own imports
33 32 # Configurable traitlets
34 33 from IPython.utils.traitlets import Unicode, Bool
35 34
36 35 # Needed to override transformer
37 36 from .activatable import (ActivatableTransformer) #TODO
38 37
38 import nbconvert.utils.console
39
39 40 #-----------------------------------------------------------------------------
40 41 # Classes and functions
41 42 #-----------------------------------------------------------------------------
43
42 44 class SphinxTransformer(ActivatableTransformer):
43 45 """
44 46 Sphinx utility transformer.
45 47
46 48 This transformer is used to set variables needed by the latex to build
47 49 Sphinx stylized templates.
48 50 """
49 51
50 52 interactive = Bool(True, config=True, help="""
51 Allows you to define whether or not the Sphinx exporter will prompt
52 you for input during the conversion process. If this is set to false,
53 the author, version, release, date, and chapter_style traits should
54 be set.
55 """)
53 Allows you to define whether or not the Sphinx exporter will prompt
54 you for input during the conversion process. If this is set to false,
55 the author, version, release, date, and chapter_style traits should
56 be set.
57 """)
56 58
57 59 author = Unicode("Unknown Author", config=True, help="Author name")
58 60
59 version = Unicode("", config=True, help="""Version number
60 You can leave this blank if you do not want to render a version number.
61 Example: "1.0.0"
62 """)
61 version = Unicode("", config=True, help="""
62 Version number
63 You can leave this blank if you do not want to render a version number.
64 Example: "1.0.0"
65 """)
63 66
64 release = Unicode("", config=True, help="""Release name
65 You can leave this blank if you do not want to render a release name.
66 Example: "Rough Draft"
67 """)
67 release = Unicode("", config=True, help="""
68 Release name
69 You can leave this blank if you do not want to render a release name.
70 Example: "Rough Draft"
71 """)
68 72
69 publish_date = Unicode("", config=True, help="""Publish date
70 This is the date to render on the document as the publish date.
71 Leave this blank to default to todays date.
72 Example: "June 12, 1990"
73 """)
73 publish_date = Unicode("", config=True, help="""
74 Publish date
75 This is the date to render on the document as the publish date.
76 Leave this blank to default to todays date.
77 Example: "June 12, 1990"
78 """)
74 79
75 chapter_style = Unicode("Bjarne", config=True, help="""Sphinx chapter style
76 This is the style to use for the chapter headers in the document.
77 You may choose one of the following:
78 "Bjarne" (default)
79 "Lenny"
80 "Glenn"
81 "Conny"
82 "Rejne"
83 "Sonny" (used for international documents)
84 """)
80 chapter_style = Unicode("Bjarne", config=True, help="""
81 Sphinx chapter style
82 This is the style to use for the chapter headers in the document.
83 You may choose one of the following:
84 "Bjarne" (default)
85 "Lenny"
86 "Glenn"
87 "Conny"
88 "Rejne"
89 "Sonny" (used for international documents)
90 """)
85 91
86 output_style = Unicode("notebook", config=True, help="""Nbconvert Ipython
87 notebook input/output formatting style.
88 You may choose one of the following:
89 "simple (recommended for long code segments)"
90 "notebook" (default)
91 """)
92 output_style = Unicode("notebook", config=True, help="""
93 Nbconvert Ipython
94 notebook input/output formatting style.
95 You may choose one of the following:
96 "simple (recommended for long code segments)"
97 "notebook" (default)
98 """)
92 99
93 100 center_output = Bool(False, config=True, help="""
94 Optional attempt to center all output. If this is false, no additional
95 formatting is applied.
96 """)
101 Optional attempt to center all output. If this is false, no additional
102 formatting is applied.
103 """)
97 104
98 105 use_headers = Bool(True, config=True, help="""
99 Whether not a header should be added to the document.
100 """)
106 Whether not a header should be added to the document.
107 """)
101 108
109 #Allow the user to override the title of the notebook (useful for
110 #fancy document titles that the file system doesn't support.)
102 111 overridetitle = Unicode("", config=True, help="")
112
103 113
104 def __call__(self, nb, other):
114 def __call__(self, nb, resources):
105 115 """
106 Entry
116 Entrypoint
107 117 Since we are not interested in any additional manipulation on a cell
108 118 by cell basis, we do not call the base implementation.
109 """
119
120 Parameters
121 ----------
122 nb : NotebookNode
123 Notebook being converted
124 resources : dictionary
125 Additional resources used in the conversion process. Allows
126 transformers to pass variables into the Jinja engine.
127 """
128
110 129 if self.enabled:
111 return self.transform(nb, other)
130 return self.transform(nb, resources)
112 131 else:
113 return nb,other
132 return nb,resources
133
114 134
115 def transform(self, nb, other):
135 def transform(self, nb, resources):
116 136 """
117 137 Sphinx transformation to apply on each notebook.
138
139 Parameters
140 ----------
141 nb : NotebookNode
142 Notebook being converted
143 resources : dictionary
144 Additional resources used in the conversion process. Allows
145 transformers to pass variables into the Jinja engine.
118 146 """
119 147
120 148 # TODO: Add versatile method of additional notebook metadata. Include
121 149 # handling of multiple files. For now use a temporay namespace,
122 150 # '_draft' to signify that this needs to change.
123 151 if not "_draft" in nb.metadata:
124 152 nb.metadata._draft = {}
125 153
126 if not "sphinx" in other:
127 other["sphinx"] = {}
154 if not "sphinx" in resources:
155 resources["sphinx"] = {}
128 156
129 157 if self.interactive:
130 158
131 159 # Prompt the user for additional meta data that doesn't exist currently
132 160 # but would be usefull for Sphinx.
133 161 nb.metadata._draft["author"] = self._prompt_author()
134 162 nb.metadata._draft["version"] = self._prompt_version()
135 163 nb.metadata._draft["release"] = self._prompt_release()
136 164 nb.metadata._draft["date"] = self._prompt_date()
137 165
138 166 # Prompt the user for the document style.
139 other["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
140 other["sphinx"]["outputstyle"] = self._prompt_output_style()
167 resources["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
168 resources["sphinx"]["outputstyle"] = self._prompt_output_style()
141 169
142 170 # Small options
143 other["sphinx"]["centeroutput"] = self._prompt_boolean("Do you want to center the output? (false)", False)
144 other["sphinx"]["header"] = self._prompt_boolean("Should a Sphinx document header be used? (true)", True)
171 resources["sphinx"]["centeroutput"] = nbconvert.utils.console.prompt_boolean("Do you want to center the output? (false)", False)
172 resources["sphinx"]["header"] = nbconvert.utils.console.prompt_boolean("Should a Sphinx document header be used? (true)", True)
145 173 else:
146 174
147 175 # Try to use the traitlets.
148 176 nb.metadata._draft["author"] = self.author
149 177 nb.metadata._draft["version"] = self.version
150 178 nb.metadata._draft["release"] = self.release
151 179
152 180 # Use todays date if none is provided.
153 181 if len(self.publish_date.strip()) == 0:
154 182 nb.metadata._draft["date"] = date.today().strftime("%B %-d, %Y")
155 183 else:
156 184 nb.metadata._draft["date"] = self.publish_date
157 185
158 186 # Sphinx traitlets.
159 other["sphinx"]["chapterstyle"] = self.chapter_style
160 other["sphinx"]["outputstyle"] = self.output_style
161 other["sphinx"]["centeroutput"] = self.center_output
162 other["sphinx"]["header"] = self.use_headers
187 resources["sphinx"]["chapterstyle"] = self.chapter_style
188 resources["sphinx"]["outputstyle"] = self.output_style
189 resources["sphinx"]["centeroutput"] = self.center_output
190 resources["sphinx"]["header"] = self.use_headers
163 191
164 192 # Find and pass in the path to the Sphinx dependencies.
165 other["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs")
193 resources["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs")
166 194
167 195 # Generate Pygments definitions for Latex
168 other["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
196 resources["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
169 197
170 198 if not (self.overridetitle == None or len(self.overridetitle.strip()) == 0):
171 199 nb.metadata.name = self.overridetitle
172 200
173 201 # End
174 return nb, other
202 return nb, resources
203
175 204
176 205 def _generate_pygments_latex_def(self):
206 """
207 Generate the pygments latex definitions that allows pygments
208 to work in latex.
209 """
210
177 211 return LatexFormatter().get_style_defs()
178 212
213
179 214 def _prompt_author(self):
180 return self._input("Author name: ")
215 """
216 Prompt the user to input an Author name
217 """
218 return nbconvert.utils.console.input("Author name: ")
219
181 220
182 221 def _prompt_version(self):
183 return self._input("Version (ie ""1.0.0""): ")
222 """
223 prompt the user to enter a version number
224 """
225 return nbconvert.utils.console.input("Version (ie ""1.0.0""): ")
226
184 227
185 228 def _prompt_release(self):
186 return self._input("Release Name (ie ""Rough draft""): ")
229 """
230 Prompt the user to input a release name
231 """
232
233 return nbconvert.utils.console.input("Release Name (ie ""Rough draft""): ")
234
187 235
188 236 def _prompt_date(self):
237 """
238 Prompt the user to enter a date
239 """
240
189 241 default_date = date.today().strftime("%B %-d, %Y")
190 user_date = self._input("Date (deafults to \"" + default_date + "\"): ")
242 user_date = nbconvert.utils.console.input("Date (deafults to \"" + default_date + "\"): ")
191 243 if len(user_date.strip()) == 0:
192 244 user_date = default_date
193 245 return user_date
194 246
195 def _prompt_boolean(self, prompt, default=False):
196 response = self._input(prompt)
197 response = response.strip().lower()
198
199 #Catch 1, true, yes as True
200 if len(response) > 0 and (response == "1" or response[0] == "t" or response[0] == "y"):
201 return True
202
203 #Catch 0, false, no as False
204 elif len(response) > 0 and (response == "0" or response[0] == "f" or response[0] == "n"):
205 return False
206
207 else:
208 return default
209
247
210 248 def _prompt_output_style(self):
249 """
250 Prompts the user to pick an iPython output style.
251 """
211 252
212 253 # Dictionary of available output styles
213 254 styles = {1: "simple",
214 255 2: "notebook"}
215 256
216 257 #Append comments to the menu when displaying it to the user.
217 258 comments = {1: "(recommended for long code segments)",
218 259 2: "(default)"}
219 260
220 return self._prompt_dictionary(styles, default_style=2, menu_comments=comments)
261 return nbconvert.utils.console.prompt_dictionary(styles, default_style=2, menu_comments=comments)
262
221 263
222 264 def _prompt_chapter_title_style(self):
265 """
266 Prompts the user to pick a Sphinx chapter style
267 """
223 268
224 269 # Dictionary of available Sphinx styles
225 270 styles = {1: "Bjarne",
226 271 2: "Lenny",
227 272 3: "Glenn",
228 273 4: "Conny",
229 274 5: "Rejne",
230 275 6: "Sonny"}
231 276
232 277 #Append comments to the menu when displaying it to the user.
233 278 comments = {1: "(default)",
234 279 6: "(for international documents)"}
235 280
236 return self._prompt_dictionary(styles, menu_comments=comments)
237
238 def _prompt_dictionary(self, choices, default_style=1, menu_comments={}):
239
240 # Build the menu that will be displayed to the user with
241 # all of the options available.
242 prompt = ""
243 for key, value in choices.iteritems():
244 prompt += "%d %s " % (key, value)
245 if key in menu_comments:
246 prompt += menu_comments[key]
247 prompt += "\n"
248
249 # Continue to ask the user for a style until an appropriate
250 # one is specified.
251 response = -1
252 while (not response in choices):
253 try:
254 text_response = self._input(prompt)
255
256 # Use default option if no input.
257 if len(text_response.strip()) == 0:
258 response = default_style
259 else:
260 response = int(text_response)
261 except:
262 print("Error: Value is not an available option. 0 selects the default.\n")
263 return choices[response]
264
265 def _input(self, prompt_text):
266 """
267 Prompt the user for input.
268
269 The input command will change depending on the version of python
270 installed. To maintain support for 2 and earlier, we must use
271 raw_input in that case. Else use input.
272 """
273
274 # Try to get the python version. This command is only available in
275 # python 2 and later, so it's important that we catch the exception
276 # if the command isn't found.
277 try:
278 majorversion = sys.version_info[0]
279 except:
280 majorversion = 1
281
282 # Use the correct function to prompt the user for input depending on
283 # what python version the code is running in.
284 if majorversion >= 3:
285 return input(prompt_text)
286 else:
287 return raw_input(prompt_text)
281 return nbconvert.utils.console.prompt_dictionary(styles, menu_comments=comments)
282 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now