##// END OF EJS Templates
Fixed blank response handling
Jonathan Frederic -
Show More
@@ -1,266 +1,266 b''
1 """
1 """
2 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.
3 on the 'other' object passed into Jinja.
4 """
4 """
5 from __future__ import absolute_import
5 from __future__ import absolute_import
6
6
7 # Used to find Sphinx package location
7 # Used to find Sphinx package location
8 import sphinx
8 import sphinx
9 import os.path
9 import os.path
10
10
11 # Used to determine python version
11 # Used to determine python version
12 import sys
12 import sys
13
13
14 # Used to set the default date to today's date
14 # Used to set the default date to today's date
15 from datetime import date
15 from datetime import date
16
16
17 # Configurable traitlets
17 # Configurable traitlets
18 from IPython.utils.traitlets import Unicode, Bool
18 from IPython.utils.traitlets import Unicode, Bool
19
19
20 # Needed for Pygments latex definitions.
20 # Needed for Pygments latex definitions.
21 from pygments.formatters import LatexFormatter
21 from pygments.formatters import LatexFormatter
22
22
23 # Needed to override transformer
23 # Needed to override transformer
24 from .transformers import (ActivatableTransformer)
24 from .transformers import (ActivatableTransformer)
25
25
26 class SphinxTransformer(ActivatableTransformer):
26 class SphinxTransformer(ActivatableTransformer):
27 """
27 """
28 Sphinx utility transformer.
28 Sphinx utility transformer.
29
29
30 This transformer is used to set variables needed by the latex to build
30 This transformer is used to set variables needed by the latex to build
31 Sphinx stylized templates.
31 Sphinx stylized templates.
32 """
32 """
33
33
34 interactive = Bool(True, config=True, help="""
34 interactive = Bool(True, config=True, help="""
35 Allows you to define whether or not the Sphinx exporter will prompt
35 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,
36 you for input during the conversion process. If this is set to false,
37 the author, version, release, date, and chapter_style traits should
37 the author, version, release, date, and chapter_style traits should
38 be set.
38 be set.
39 """)
39 """)
40
40
41 author = Unicode("Unknown Author", config=True, help="Author name")
41 author = Unicode("Unknown Author", config=True, help="Author name")
42
42
43 version = Unicode("", config=True, help="""Version number
43 version = Unicode("", config=True, help="""Version number
44 You can leave this blank if you do not want to render a version number.
44 You can leave this blank if you do not want to render a version number.
45 Example: "1.0.0"
45 Example: "1.0.0"
46 """)
46 """)
47
47
48 release = Unicode("", config=True, help="""Release name
48 release = Unicode("", config=True, help="""Release name
49 You can leave this blank if you do not want to render a release name.
49 You can leave this blank if you do not want to render a release name.
50 Example: "Rough Draft"
50 Example: "Rough Draft"
51 """)
51 """)
52
52
53 publish_date = Unicode("", config=True, help="""Publish date
53 publish_date = Unicode("", config=True, help="""Publish date
54 This is the date to render on the document as the publish date.
54 This is the date to render on the document as the publish date.
55 Leave this blank to default to todays date.
55 Leave this blank to default to todays date.
56 Example: "June 12, 1990"
56 Example: "June 12, 1990"
57 """)
57 """)
58
58
59 chapter_style = Unicode("Bjarne", config=True, help="""Sphinx chapter style
59 chapter_style = Unicode("Bjarne", config=True, help="""Sphinx chapter style
60 This is the style to use for the chapter headers in the document.
60 This is the style to use for the chapter headers in the document.
61 You may choose one of the following:
61 You may choose one of the following:
62 "Bjarne" (default)
62 "Bjarne" (default)
63 "Lenny"
63 "Lenny"
64 "Glenn"
64 "Glenn"
65 "Conny"
65 "Conny"
66 "Rejne"
66 "Rejne"
67 "Sonny" (used for international documents)
67 "Sonny" (used for international documents)
68 """)
68 """)
69
69
70 output_style = Unicode("notebook", config=True, help="""Nbconvert Ipython
70 output_style = Unicode("notebook", config=True, help="""Nbconvert Ipython
71 notebook input/output formatting style.
71 notebook input/output formatting style.
72 You may choose one of the following:
72 You may choose one of the following:
73 "simple (recommended for long code segments)"
73 "simple (recommended for long code segments)"
74 "notebook" (default)
74 "notebook" (default)
75 """)
75 """)
76
76
77 center_output = Bool(False, config=True, help="""
77 center_output = Bool(False, config=True, help="""
78 Optional attempt to center all output. If this is false, no additional
78 Optional attempt to center all output. If this is false, no additional
79 formatting is applied.
79 formatting is applied.
80 """)
80 """)
81
81
82 use_headers = Bool(True, config=True, help="""
82 use_headers = Bool(True, config=True, help="""
83 Whether not a header should be added to the document.
83 Whether not a header should be added to the document.
84 """)
84 """)
85
85
86 def __call__(self, nb, other):
86 def __call__(self, nb, other):
87 """
87 """
88 Entry
88 Entry
89 Since we are not interested in any additional manipulation on a cell
89 Since we are not interested in any additional manipulation on a cell
90 by cell basis, we do not call the base implementation.
90 by cell basis, we do not call the base implementation.
91 """
91 """
92 if self.enabled:
92 if self.enabled:
93 return self.transform(nb, other)
93 return self.transform(nb, other)
94 else:
94 else:
95 return nb,other
95 return nb,other
96
96
97 def transform(self, nb, other):
97 def transform(self, nb, other):
98 """
98 """
99 Sphinx transformation to apply on each notebook.
99 Sphinx transformation to apply on each notebook.
100 """
100 """
101
101
102 # TODO: Add versatile method of additional notebook metadata. Include
102 # TODO: Add versatile method of additional notebook metadata. Include
103 # handling of multiple files. For now use a temporay namespace,
103 # handling of multiple files. For now use a temporay namespace,
104 # '_draft' to signify that this needs to change.
104 # '_draft' to signify that this needs to change.
105 if not "_draft" in nb.metadata:
105 if not "_draft" in nb.metadata:
106 nb.metadata._draft = {}
106 nb.metadata._draft = {}
107
107
108 if not "sphinx" in other:
108 if not "sphinx" in other:
109 other["sphinx"] = {}
109 other["sphinx"] = {}
110
110
111 if self.interactive:
111 if self.interactive:
112
112
113 # Prompt the user for additional meta data that doesn't exist currently
113 # Prompt the user for additional meta data that doesn't exist currently
114 # but would be usefull for Sphinx.
114 # but would be usefull for Sphinx.
115 nb.metadata._draft["author"] = self._prompt_author()
115 nb.metadata._draft["author"] = self._prompt_author()
116 nb.metadata._draft["version"] = self._prompt_version()
116 nb.metadata._draft["version"] = self._prompt_version()
117 nb.metadata._draft["release"] = self._prompt_release()
117 nb.metadata._draft["release"] = self._prompt_release()
118 nb.metadata._draft["date"] = self._prompt_date()
118 nb.metadata._draft["date"] = self._prompt_date()
119
119
120 # Prompt the user for the document style.
120 # Prompt the user for the document style.
121 other["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
121 other["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
122 other["sphinx"]["outputstyle"] = self._prompt_output_style()
122 other["sphinx"]["outputstyle"] = self._prompt_output_style()
123
123
124 # Small options
124 # Small options
125 other["sphinx"]["centeroutput"] = self._prompt_boolean("Do you want to center the output? (false)", False)
125 other["sphinx"]["centeroutput"] = self._prompt_boolean("Do you want to center the output? (false)", False)
126 other["sphinx"]["header"] = self._prompt_boolean("Should a Sphinx document header be used? (true)", True)
126 other["sphinx"]["header"] = self._prompt_boolean("Should a Sphinx document header be used? (true)", True)
127 else:
127 else:
128
128
129 # Try to use the traitlets.
129 # Try to use the traitlets.
130 nb.metadata._draft["author"] = self.author
130 nb.metadata._draft["author"] = self.author
131 nb.metadata._draft["version"] = self.version
131 nb.metadata._draft["version"] = self.version
132 nb.metadata._draft["release"] = self.release
132 nb.metadata._draft["release"] = self.release
133
133
134 # Use todays date if none is provided.
134 # Use todays date if none is provided.
135 if len(self.publish_date.strip()) == 0:
135 if len(self.publish_date.strip()) == 0:
136 nb.metadata._draft["date"] = date.today().strftime("%B %-d, %Y")
136 nb.metadata._draft["date"] = date.today().strftime("%B %-d, %Y")
137 else:
137 else:
138 nb.metadata._draft["date"] = self.publish_date
138 nb.metadata._draft["date"] = self.publish_date
139
139
140 # Sphinx traitlets.
140 # Sphinx traitlets.
141 other["sphinx"]["chapterstyle"] = self.chapter_style
141 other["sphinx"]["chapterstyle"] = self.chapter_style
142 other["sphinx"]["outputstyle"] = self.output_style
142 other["sphinx"]["outputstyle"] = self.output_style
143 other["sphinx"]["centeroutput"] = self.center_output
143 other["sphinx"]["centeroutput"] = self.center_output
144 other["sphinx"]["header"] = self.use_headers
144 other["sphinx"]["header"] = self.use_headers
145
145
146 # Find and pass in the path to the Sphinx dependencies.
146 # Find and pass in the path to the Sphinx dependencies.
147 other["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs")
147 other["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs")
148
148
149 # Generate Pygments definitions for Latex
149 # Generate Pygments definitions for Latex
150 other["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
150 other["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
151
151
152 # End
152 # End
153 return nb, other
153 return nb, other
154
154
155 def _generate_pygments_latex_def(self):
155 def _generate_pygments_latex_def(self):
156 return LatexFormatter().get_style_defs()
156 return LatexFormatter().get_style_defs()
157
157
158 def _prompt_author(self):
158 def _prompt_author(self):
159 return self._input("Author name: ")
159 return self._input("Author name: ")
160
160
161 def _prompt_version(self):
161 def _prompt_version(self):
162 return self._input("Version (ie ""1.0.0""): ")
162 return self._input("Version (ie ""1.0.0""): ")
163
163
164 def _prompt_release(self):
164 def _prompt_release(self):
165 return self._input("Release Name (ie ""Rough draft""): ")
165 return self._input("Release Name (ie ""Rough draft""): ")
166
166
167 def _prompt_date(self):
167 def _prompt_date(self):
168 default_date = date.today().strftime("%B %-d, %Y")
168 default_date = date.today().strftime("%B %-d, %Y")
169 user_date = self._input("Date (deafults to \"" + default_date + "\"): ")
169 user_date = self._input("Date (deafults to \"" + default_date + "\"): ")
170 if len(user_date.strip()) == 0:
170 if len(user_date.strip()) == 0:
171 user_date = default_date
171 user_date = default_date
172 return user_date
172 return user_date
173
173
174 def _prompt_boolean(self, prompt, default=False):
174 def _prompt_boolean(self, prompt, default=False):
175 response = self._input(prompt)
175 response = self._input(prompt)
176 response = response.strip().lower()
176 response = response.strip().lower()
177
177
178 #Catch 1, true, yes as True
178 #Catch 1, true, yes as True
179 if (response == "1" or response[0] == "t" or response[0] == "y"):
179 if len(response) > 0 and (response == "1" or response[0] == "t" or response[0] == "y"):
180 return True
180 return True
181
181
182 #Catch 0, false, no as False
182 #Catch 0, false, no as False
183 elif (response == "0" or response[0] == "f" or response[0] == "n"):
183 elif len(response) > 0 and (response == "0" or response[0] == "f" or response[0] == "n"):
184 return False
184 return False
185
185
186 else:
186 else:
187 return Default
187 return default
188
188
189 def _prompt_output_style(self):
189 def _prompt_output_style(self):
190
190
191 # Dictionary of available output styles
191 # Dictionary of available output styles
192 styles = {1: "simple",
192 styles = {1: "simple",
193 2: "notebook"}
193 2: "notebook"}
194
194
195 #Append comments to the menu when displaying it to the user.
195 #Append comments to the menu when displaying it to the user.
196 comments = {1: "(recommended for long code segments)",
196 comments = {1: "(recommended for long code segments)",
197 2: "(default)"}
197 2: "(default)"}
198
198
199 return self._prompt_dictionary(styles, default_style=2, menu_comments=comments)
199 return self._prompt_dictionary(styles, default_style=2, menu_comments=comments)
200
200
201 def _prompt_chapter_title_style(self):
201 def _prompt_chapter_title_style(self):
202
202
203 # Dictionary of available Sphinx styles
203 # Dictionary of available Sphinx styles
204 styles = {1: "Bjarne",
204 styles = {1: "Bjarne",
205 2: "Lenny",
205 2: "Lenny",
206 3: "Glenn",
206 3: "Glenn",
207 4: "Conny",
207 4: "Conny",
208 5: "Rejne",
208 5: "Rejne",
209 6: "Sonny"}
209 6: "Sonny"}
210
210
211 #Append comments to the menu when displaying it to the user.
211 #Append comments to the menu when displaying it to the user.
212 comments = {1: "(default)",
212 comments = {1: "(default)",
213 6: "(for international documents)"}
213 6: "(for international documents)"}
214
214
215 return self._prompt_dictionary(styles, menu_comments=comments)
215 return self._prompt_dictionary(styles, menu_comments=comments)
216
216
217 def _prompt_dictionary(self, choices, default_style=1, menu_comments={}):
217 def _prompt_dictionary(self, choices, default_style=1, menu_comments={}):
218
218
219 # Build the menu that will be displayed to the user with
219 # Build the menu that will be displayed to the user with
220 # all of the options available.
220 # all of the options available.
221 prompt = ""
221 prompt = ""
222 for key, value in choices.iteritems():
222 for key, value in choices.iteritems():
223 prompt += "%d %s " % (key, value)
223 prompt += "%d %s " % (key, value)
224 if key in menu_comments:
224 if key in menu_comments:
225 prompt += menu_comments[key]
225 prompt += menu_comments[key]
226 prompt += "\n"
226 prompt += "\n"
227
227
228 # Continue to ask the user for a style until an appropriate
228 # Continue to ask the user for a style until an appropriate
229 # one is specified.
229 # one is specified.
230 response = -1
230 response = -1
231 while (not response in choices):
231 while (not response in choices):
232 try:
232 try:
233 text_response = self._input(prompt)
233 text_response = self._input(prompt)
234
234
235 # Use default option if no input.
235 # Use default option if no input.
236 if len(text_response.strip()) == 0:
236 if len(text_response.strip()) == 0:
237 response = default_style
237 response = default_style
238 else:
238 else:
239 response = int(text_response)
239 response = int(text_response)
240 except:
240 except:
241 print("Error: Value is not an available option. 0 selects the default.\n")
241 print("Error: Value is not an available option. 0 selects the default.\n")
242 return choices[response]
242 return choices[response]
243
243
244 def _input(self, prompt_text):
244 def _input(self, prompt_text):
245 """
245 """
246 Prompt the user for input.
246 Prompt the user for input.
247
247
248 The input command will change depending on the version of python
248 The input command will change depending on the version of python
249 installed. To maintain support for 2 and earlier, we must use
249 installed. To maintain support for 2 and earlier, we must use
250 raw_input in that case. Else use input.
250 raw_input in that case. Else use input.
251 """
251 """
252
252
253 # Try to get the python version. This command is only available in
253 # Try to get the python version. This command is only available in
254 # python 2 and later, so it's important that we catch the exception
254 # python 2 and later, so it's important that we catch the exception
255 # if the command isn't found.
255 # if the command isn't found.
256 try:
256 try:
257 majorversion = sys.version_info[0]
257 majorversion = sys.version_info[0]
258 except:
258 except:
259 majorversion = 1
259 majorversion = 1
260
260
261 # Use the correct function to prompt the user for input depending on
261 # Use the correct function to prompt the user for input depending on
262 # what python version the code is running in.
262 # what python version the code is running in.
263 if majorversion >= 3:
263 if majorversion >= 3:
264 return input(prompt_text)
264 return input(prompt_text)
265 else:
265 else:
266 return raw_input(prompt_text)
266 return raw_input(prompt_text)
General Comments 0
You need to be logged in to leave comments. Login now