##// END OF EJS Templates
Removed ActivatableTransformer and moved enabled key into base.
Jonathan Frederic -
Show More
@@ -1,12 +1,11
1 1 # Class base Transformers
2 from .activatable import ActivatableTransformer
3 2 from .base import ConfigurableTransformer
4 3 from .convertfigures import ConvertFiguresTransformer
5 4 from .svg2pdf import Svg2PdfTransformer
6 5 from .extractfigure import ExtractFigureTransformer
7 6 from .revealhelp import RevealHelpTransformer
8 7 from .latex import LatexTransformer
9 8 from .sphinx import SphinxTransformer
10 9
11 10 # decorated function Transformers
12 11 from .coalescestreams import coalesce_streams
@@ -1,101 +1,109
1 1 """
2 2 Module that re-groups transformer that would be applied to ipynb files
3 3 before going through the templating machinery.
4 4
5 5 It exposes a convenient class to inherit from to access configurability.
6 6 """
7 7 #-----------------------------------------------------------------------------
8 8 # Copyright (c) 2013, the IPython Development Team.
9 9 #
10 10 # Distributed under the terms of the Modified BSD License.
11 11 #
12 12 # The full license is in the file COPYING.txt, distributed with this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 from ..utils.config import GlobalConfigurable
20 from IPython.utils.traitlets import Bool
20 21
21 22 #-----------------------------------------------------------------------------
22 23 # Classes and Functions
23 24 #-----------------------------------------------------------------------------
24 25
25 26 class ConfigurableTransformer(GlobalConfigurable):
26 27 """ A configurable transformer
27 28
28 29 Inherit from this class if you wish to have configurability for your
29 30 transformer.
30 31
31 32 Any configurable traitlets this class exposed will be configurable in profiles
32 33 using c.SubClassName.atribute=value
33 34
34 35 you can overwrite transform_cell to apply a transformation independently on each cell
35 36 or __call__ if you prefer your own logic. See corresponding docstring for informations.
37
38 Disabled by default and can be enabled via the config by
39 'c.YourTransformerName.enabled = True'
36 40 """
37 41
38 42 enabled = Bool(False, config=True)
39 43
40 44 def __init__(self, **kw):
41 45 """
42 46 Public constructor
43 47
44 48 Parameters
45 49 ----------
46 50 config : Config
47 51 Configuration file structure
48 52 **kw : misc
49 53 Additional arguments
50 54 """
51 55
52 56 super(ConfigurableTransformer, self).__init__(**kw)
53 57
54 58
55 59 def __call__(self, nb, resources):
60 if self.enabled:
56 61 return self.call(nb,resources)
62 else:
63 return nb, resources
64
57 65
58 66 def call(self, nb, resources):
59 67 """
60 68 Transformation to apply on each notebook.
61 69
62 70 You should return modified nb, resources.
63 71 If you wish to apply your transform on each cell, you might want to
64 72 overwrite transform_cell method instead.
65 73
66 74 Parameters
67 75 ----------
68 76 nb : NotebookNode
69 77 Notebook being converted
70 78 resources : dictionary
71 79 Additional resources used in the conversion process. Allows
72 80 transformers to pass variables into the Jinja engine.
73 81 """
74 82 try :
75 83 for worksheet in nb.worksheets :
76 84 for index, cell in enumerate(worksheet.cells):
77 85 worksheet.cells[index], resources = self.transform_cell(cell, resources, index)
78 86 return nb, resources
79 87 except NotImplementedError:
80 88 raise NotImplementedError('should be implemented by subclass')
81 89
82 90
83 91 def transform_cell(self, cell, resources, index):
84 92 """
85 93 Overwrite if you want to apply a transformation on each cell. You
86 94 should return modified cell and resource dictionary.
87 95
88 96 Parameters
89 97 ----------
90 98 cell : NotebookNode cell
91 99 Notebook cell being processed
92 100 resources : dictionary
93 101 Additional resources used in the conversion process. Allows
94 102 transformers to pass variables into the Jinja engine.
95 103 index : int
96 104 Index of the cell being processed
97 105 """
98 106
99 107 raise NotImplementedError('should be implemented by subclass')
100 108 return cell, resources
101 109
@@ -1,77 +1,77
1 1 """Module containing a transformer that converts outputs in the notebook from
2 2 one format to another.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2013, the IPython Development Team.
6 6 #
7 7 # Distributed under the terms of the Modified BSD License.
8 8 #
9 9 # The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #TODO: Come after extract
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 from .activatable import ActivatableTransformer
18 from .base import ConfigurableTransformer
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Classes
22 22 #-----------------------------------------------------------------------------
23 23
24 class ConvertFiguresTransformer(ActivatableTransformer):
24 class ConvertFiguresTransformer(ConfigurableTransformer):
25 25 """
26 26 Converts all of the outputs in a notebook from one format to another.
27 27 """
28 28
29 29
30 30 def __init__(self, from_formats, to_format, **kw):
31 31 """
32 32 Public constructor
33 33
34 34 Parameters
35 35 ----------
36 36 from_formats : list [of string]
37 37 Formats that the converter can convert from
38 38 to_format : string
39 39 Format that the converter converts to
40 40 config : Config
41 41 Configuration file structure
42 42 **kw : misc
43 43 Additional arguments
44 44 """
45 45 super(ConvertFiguresTransformer, self).__init__(**kw)
46 46
47 47 #TODO: Configurable, singular
48 48 self._from_formats = from_formats
49 49 self._to_format = to_format
50 50
51 51
52 52 def convert_figure(self, data_format, data):
53 53 raise NotImplementedError()
54 54
55 55
56 56 def transform_cell(self, cell, resources, cell_index):
57 57 """
58 58 Apply a transformation on each cell,
59 59
60 60 See base.py
61 61 """
62 62
63 63 #Loop through all of the datatypes of the outputs in the cell.
64 64 for index, cell_out in enumerate(cell.get('outputs', [])):
65 65 for data_type, data in cell_out.items():
66 66 self._convert_figure(cell_out, data_type, data)
67 67 return cell, resources
68 68
69 69
70 70 def _convert_figure(self, cell_out, data_type, data):
71 71 """
72 72 Convert a figure and output the results to the cell output
73 73 """
74 74
75 75 if not self._to_format in cell_out:
76 76 if data_type in self._from_formats:
77 77 cell_out[self._to_format] = self.convert_figure(data_type, data)
@@ -1,106 +1,106
1 1 """Module that pre-processes the notebook for export to HTML.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2013, the IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 import os
16 16 import io
17 17
18 18 from pygments.formatters import HtmlFormatter
19 19
20 20 from IPython.utils import path
21 21
22 from .activatable import ActivatableTransformer
22 from .base import ConfigurableTransformer
23 23
24 24 from IPython.utils.traitlets import Unicode
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Classes and functions
28 28 #-----------------------------------------------------------------------------
29 29
30 class CSSHTMLHeaderTransformer(ActivatableTransformer):
30 class CSSHTMLHeaderTransformer(ConfigurableTransformer):
31 31 """
32 32 Transformer used to pre-process notebook for HTML output. Adds IPython notebook
33 33 front-end CSS and Pygments CSS to HTML output.
34 34 """
35 35
36 36 header = []
37 37
38 38 highlight_class = Unicode('.highlight', config=True,
39 39 help="CSS highlight class identifier")
40 40
41 41 def __init__(self, config=None, **kw):
42 42 """
43 43 Public constructor
44 44
45 45 Parameters
46 46 ----------
47 47 config : Config
48 48 Configuration file structure
49 49 **kw : misc
50 50 Additional arguments
51 51 """
52 52
53 53 super(CSSHTMLHeaderTransformer, self).__init__(config=config, **kw)
54 54
55 55 if self.enabled :
56 56 self._regen_header()
57 57
58 58
59 59 def __call__(self, nb, resources):
60 60 """Fetch and add CSS to the resource dictionary
61 61
62 62 Fetch CSS from IPython and Pygments to add at the beginning
63 63 of the html files. Add this css in resources in the
64 64 "inlining.css" key
65 65
66 66 Parameters
67 67 ----------
68 68 nb : NotebookNode
69 69 Notebook being converted
70 70 resources : dictionary
71 71 Additional resources used in the conversion process. Allows
72 72 transformers to pass variables into the Jinja engine.
73 73 """
74 74
75 75 resources['inlining'] = {}
76 76 resources['inlining']['css'] = self.header
77 77
78 78 return nb, resources
79 79
80 80
81 81 def _regen_header(self):
82 82 """
83 83 Fills self.header with lines of CSS extracted from IPython
84 84 and Pygments.
85 85 """
86 86
87 87 #Clear existing header.
88 88 header = []
89 89
90 90 #Construct path to IPy CSS
91 91 sheet_filename = os.path.join(path.get_ipython_package_dir(),
92 92 'html', 'static', 'style', 'style.min.css')
93 93
94 94 #Load style CSS file.
95 95 with io.open(sheet_filename, encoding='utf-8') as file:
96 96 file_text = file.read()
97 97 header.append(file_text)
98 98
99 99 #Add pygments CSS
100 100 formatter = HtmlFormatter()
101 101 pygments_css = formatter.get_style_defs(self.highlight_class)
102 102 header.append(pygments_css)
103 103
104 104 #Set header
105 105 self.header = header
106 106
@@ -1,91 +1,91
1 1 """Module containing a transformer that extracts all of the figures from the
2 2 notebook file. The extracted figures are returned in the 'resources' dictionary.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2013, the IPython Development Team.
6 6 #
7 7 # Distributed under the terms of the Modified BSD License.
8 8 #
9 9 # The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15
16 16 import sys
17 17 from IPython.utils.traitlets import Dict, Unicode
18 from .activatable import ActivatableTransformer
18 from .base import ConfigurableTransformer
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Classes
22 22 #-----------------------------------------------------------------------------
23 23
24 class ExtractFigureTransformer(ActivatableTransformer):
24 class ExtractFigureTransformer(ConfigurableTransformer):
25 25 """
26 26 Extracts all of the figures from the notebook file. The extracted
27 27 figures are returned in the 'resources' dictionary.
28 28 """
29 29
30 30
31 31 figure_filename_template = Unicode(
32 32 "{unique_key}_{cell_index}_{index}.{extension}", config=True)
33 33
34 34
35 35 def transform_cell(self, cell, resources, cell_index):
36 36 """
37 37 Apply a transformation on each cell,
38 38
39 39 Parameters
40 40 ----------
41 41 cell : NotebookNode cell
42 42 Notebook cell being processed
43 43 resources : dictionary
44 44 Additional resources used in the conversion process. Allows
45 45 transformers to pass variables into the Jinja engine.
46 46 cell_index : int
47 47 Index of the cell being processed (see base.py)
48 48 """
49 49
50 50 #Get the unique key from the resource dict if it exists. If it does not
51 51 #exist, use 'figure' as the default.
52 52 unique_key = resources.get('unique_key', 'figure')
53 53
54 54 #Make sure figures key exists
55 55 if not 'figures' in resources:
56 56 resources['figures'] = {}
57 57
58 58 #Loop through all of the outputs in the cell
59 59 for index, out in enumerate(cell.get('outputs', [])):
60 60
61 61 #Get the output in data formats that the template is interested in.
62 62 for out_type in self.display_data_priority:
63 63 if out.hasattr(out_type):
64 64 data = out[out_type]
65 65
66 66 #Binary files are base64-encoded, SVG is already XML
67 67 if out_type in ('png', 'jpg', 'pdf'):
68 68 data = data.decode('base64')
69 69 elif sys.platform == 'win32':
70 70 data = data.replace('\n', '\r\n').encode("UTF-8")
71 71 else:
72 72 data = data.encode("UTF-8")
73 73
74 74 #Build a figure name
75 75 figure_name = self.figure_filename_template.format(
76 76 unique_key=unique_key,
77 77 cell_index=cell_index,
78 78 index=index,
79 79 extension=out_type)
80 80
81 81 #On the cell, make the figure available via
82 82 # cell.outputs[i].svg_filename ... etc (svg in example)
83 83 # Where
84 84 # cell.outputs[i].svg contains the data
85 85 out[out_type + '_filename'] = figure_name
86 86
87 87 #In the resources, make the figure available via
88 88 # resources['figures']['filename'] = data
89 89 resources['figures'][figure_name] = data
90 90
91 91 return cell, resources
@@ -1,53 +1,53
1 1 """Module that allows latex output notebooks to be conditioned before
2 2 they are converted.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2013, the IPython Development Team.
6 6 #
7 7 # Distributed under the terms of the Modified BSD License.
8 8 #
9 9 # The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15
16 16 from __future__ import print_function, absolute_import
17 17
18 18 # Our own imports
19 19 # Needed to override transformer
20 from .activatable import (ActivatableTransformer)
20 from .base import (ConfigurableTransformer)
21 21 from IPython.nbconvert import filters
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Classes
25 25 #-----------------------------------------------------------------------------
26 26
27 class LatexTransformer(ActivatableTransformer):
27 class LatexTransformer(ConfigurableTransformer):
28 28 """
29 29 Converter for latex destined documents.
30 30 """
31 31
32 32 def transform_cell(self, cell, resources, index):
33 33 """
34 34 Apply a transformation on each cell,
35 35
36 36 Parameters
37 37 ----------
38 38 cell : NotebookNode cell
39 39 Notebook cell being processed
40 40 resources : dictionary
41 41 Additional resources used in the conversion process. Allows
42 42 transformers to pass variables into the Jinja engine.
43 43 index : int
44 44 Modified index of the cell being processed (see base.py)
45 45 """
46 46
47 47 #If the cell is a markdown cell, preprocess the ampersands used to
48 48 #remove the space between them and their contents. Latex will complain
49 49 #if spaces exist between the ampersands and the math content.
50 50 #See filters.latex.rm_math_space for more information.
51 51 if hasattr(cell, "source") and cell.cell_type == "markdown":
52 52 cell.source = filters.rm_math_space(cell.source)
53 53 return cell, resources
@@ -1,264 +1,264
1 1 """Module that allows custom Sphinx parameters to be set on the notebook and
2 2 on the 'other' object passed into Jinja. Called prior to Jinja conversion
3 3 process.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from __future__ import print_function, absolute_import
18 18
19 19 # Stdlib imports
20 20 # Used to find Sphinx package location
21 21 import sphinx
22 22 import os.path
23 23
24 24 # Used to set the default date to today's date
25 25 from datetime import date
26 26
27 27 # Third-party imports
28 28 # Needed for Pygments latex definitions.
29 29 from pygments.formatters import LatexFormatter
30 30
31 31 # Our own imports
32 32 # Configurable traitlets
33 33 from IPython.utils.traitlets import Unicode, Bool
34 34
35 35 # Needed to override transformer
36 from .activatable import (ActivatableTransformer) #TODO
36 from .base import (ConfigurableTransformer)
37 37
38 38 from IPython.nbconvert.utils import console
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Classes and functions
42 42 #-----------------------------------------------------------------------------
43 43
44 class SphinxTransformer(ActivatableTransformer):
44 class SphinxTransformer(ConfigurableTransformer):
45 45 """
46 46 Sphinx utility transformer.
47 47
48 48 This transformer is used to set variables needed by the latex to build
49 49 Sphinx stylized templates.
50 50 """
51 51
52 52 interactive = Bool(False, config=True, help="""
53 53 Allows you to define whether or not the Sphinx exporter will prompt
54 54 you for input during the conversion process. If this is set to false,
55 55 the author, version, release, date, and chapter_style traits should
56 56 be set.
57 57 """)
58 58
59 59 author = Unicode("Unknown Author", config=True, help="Author name")
60 60
61 61 version = Unicode("", config=True, help="""
62 62 Version number
63 63 You can leave this blank if you do not want to render a version number.
64 64 Example: "1.0.0"
65 65 """)
66 66
67 67 release = Unicode("", config=True, help="""
68 68 Release name
69 69 You can leave this blank if you do not want to render a release name.
70 70 Example: "Rough Draft"
71 71 """)
72 72
73 73 publish_date = Unicode("", config=True, help="""
74 74 Publish date
75 75 This is the date to render on the document as the publish date.
76 76 Leave this blank to default to todays date.
77 77 Example: "June 12, 1990"
78 78 """)
79 79
80 80 chapter_style = Unicode("Bjarne", config=True, help="""
81 81 Sphinx chapter style
82 82 This is the style to use for the chapter headers in the document.
83 83 You may choose one of the following:
84 84 "Bjarne" (default)
85 85 "Lenny"
86 86 "Glenn"
87 87 "Conny"
88 88 "Rejne"
89 89 "Sonny" (used for international documents)
90 90 """)
91 91
92 92 output_style = Unicode("notebook", config=True, help="""
93 93 Nbconvert Ipython
94 94 notebook input/output formatting style.
95 95 You may choose one of the following:
96 96 "simple (recommended for long code segments)"
97 97 "notebook" (default)
98 98 """)
99 99
100 100 center_output = Bool(False, config=True, help="""
101 101 Optional attempt to center all output. If this is false, no additional
102 102 formatting is applied.
103 103 """)
104 104
105 105 use_headers = Bool(True, config=True, help="""
106 106 Whether not a header should be added to the document.
107 107 """)
108 108
109 109 #Allow the user to override the title of the notebook (useful for
110 110 #fancy document titles that the file system doesn't support.)
111 111 overridetitle = Unicode("", config=True, help="")
112 112
113 113
114 114 def call(self, nb, resources):
115 115 """
116 116 Sphinx transformation to apply on each notebook.
117 117
118 118 Parameters
119 119 ----------
120 120 nb : NotebookNode
121 121 Notebook being converted
122 122 resources : dictionary
123 123 Additional resources used in the conversion process. Allows
124 124 transformers to pass variables into the Jinja engine.
125 125 """
126 126
127 127 # TODO: Add versatile method of additional notebook metadata. Include
128 128 # handling of multiple files. For now use a temporay namespace,
129 129 # '_draft' to signify that this needs to change.
130 130 if not "sphinx" in resources:
131 131 resources["sphinx"] = {}
132 132
133 133 if self.interactive:
134 134
135 135 # Prompt the user for additional meta data that doesn't exist currently
136 136 # but would be usefull for Sphinx.
137 137 resources["sphinx"]["author"] = self._prompt_author()
138 138 resources["sphinx"]["version"] = self._prompt_version()
139 139 resources["sphinx"]["release"] = self._prompt_release()
140 140 resources["sphinx"]["date"] = self._prompt_date()
141 141
142 142 # Prompt the user for the document style.
143 143 resources["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
144 144 resources["sphinx"]["outputstyle"] = self._prompt_output_style()
145 145
146 146 # Small options
147 147 resources["sphinx"]["centeroutput"] = console.prompt_boolean("Do you want to center the output? (false)", False)
148 148 resources["sphinx"]["header"] = console.prompt_boolean("Should a Sphinx document header be used? (true)", True)
149 149 else:
150 150
151 151 # Try to use the traitlets.
152 152 resources["sphinx"]["author"] = self.author
153 153 resources["sphinx"]["version"] = self.version
154 154 resources["sphinx"]["release"] = self.release
155 155
156 156 # Use todays date if none is provided.
157 157 if self.publish_date:
158 158 resources["sphinx"]["date"] = self.publish_date
159 159 elif len(resources['metadata']['modified_date'].strip()) == 0:
160 160 resources["sphinx"]["date"] = date.today().strftime("%B %-d, %Y")
161 161 else:
162 162 resources["sphinx"]["date"] = resources['metadata']['modified_date']
163 163
164 164 # Sphinx traitlets.
165 165 resources["sphinx"]["chapterstyle"] = self.chapter_style
166 166 resources["sphinx"]["outputstyle"] = self.output_style
167 167 resources["sphinx"]["centeroutput"] = self.center_output
168 168 resources["sphinx"]["header"] = self.use_headers
169 169
170 170 # Find and pass in the path to the Sphinx dependencies.
171 171 resources["sphinx"]["texinputs"] = os.path.realpath(os.path.join(sphinx.__file__, "..", "texinputs"))
172 172
173 173 # Generate Pygments definitions for Latex
174 174 resources["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
175 175
176 176 if not (self.overridetitle == None or len(self.overridetitle.strip()) == 0):
177 177 resources['metadata']['name'] = self.overridetitle
178 178
179 179 # End
180 180 return nb, resources
181 181
182 182
183 183 def _generate_pygments_latex_def(self):
184 184 """
185 185 Generate the pygments latex definitions that allows pygments
186 186 to work in latex.
187 187 """
188 188
189 189 return LatexFormatter().get_style_defs()
190 190
191 191
192 192 def _prompt_author(self):
193 193 """
194 194 Prompt the user to input an Author name
195 195 """
196 196 return console.input("Author name: ")
197 197
198 198
199 199 def _prompt_version(self):
200 200 """
201 201 prompt the user to enter a version number
202 202 """
203 203 return console.input("Version (ie ""1.0.0""): ")
204 204
205 205
206 206 def _prompt_release(self):
207 207 """
208 208 Prompt the user to input a release name
209 209 """
210 210
211 211 return console.input("Release Name (ie ""Rough draft""): ")
212 212
213 213
214 214 def _prompt_date(self, resources):
215 215 """
216 216 Prompt the user to enter a date
217 217 """
218 218
219 219 if resources['metadata']['modified_date']:
220 220 default_date = resources['metadata']['modified_date']
221 221 else:
222 222 default_date = date.today().strftime("%B %-d, %Y")
223 223
224 224 user_date = console.input("Date (deafults to \"" + default_date + "\"): ")
225 225 if len(user_date.strip()) == 0:
226 226 user_date = default_date
227 227 return user_date
228 228
229 229
230 230 def _prompt_output_style(self):
231 231 """
232 232 Prompts the user to pick an IPython output style.
233 233 """
234 234
235 235 # Dictionary of available output styles
236 236 styles = {1: "simple",
237 237 2: "notebook"}
238 238
239 239 #Append comments to the menu when displaying it to the user.
240 240 comments = {1: "(recommended for long code segments)",
241 241 2: "(default)"}
242 242
243 243 return console.prompt_dictionary(styles, default_style=2, menu_comments=comments)
244 244
245 245
246 246 def _prompt_chapter_title_style(self):
247 247 """
248 248 Prompts the user to pick a Sphinx chapter style
249 249 """
250 250
251 251 # Dictionary of available Sphinx styles
252 252 styles = {1: "Bjarne",
253 253 2: "Lenny",
254 254 3: "Glenn",
255 255 4: "Conny",
256 256 5: "Rejne",
257 257 6: "Sonny"}
258 258
259 259 #Append comments to the menu when displaying it to the user.
260 260 comments = {1: "(default)",
261 261 6: "(for international documents)"}
262 262
263 263 return console.prompt_dictionary(styles, menu_comments=comments)
264 264
General Comments 0
You need to be logged in to leave comments. Login now