##// END OF EJS Templates
Merge pull request #3948 from minrk/sphinx-dir...
Fernando Perez -
r12057:c293fc54 merge
parent child Browse files
Show More
@@ -1,51 +1,51 b''
1 """
1 """
2 Contains writer for writing nbconvert output to PDF.
2 Contains writer for writing nbconvert output to PDF.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 #Copyright (c) 2013, the IPython Development Team.
5 #Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 #Distributed under the terms of the Modified BSD License.
7 #Distributed under the terms of the Modified BSD License.
8 #
8 #
9 #The full license is in the file COPYING.txt, distributed with this software.
9 #The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 import subprocess
16 import subprocess
17 import os
17 import os
18
18
19 from IPython.utils.traitlets import Integer, List, Bool
19 from IPython.utils.traitlets import Integer, List, Bool
20
20
21 from .base import PostProcessorBase
21 from .base import PostProcessorBase
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Classes
24 # Classes
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 class PDFPostProcessor(PostProcessorBase):
26 class PDFPostProcessor(PostProcessorBase):
27 """Writer designed to write to PDF files"""
27 """Writer designed to write to PDF files"""
28
28
29 iteration_count = Integer(3, config=True, help="""
29 iteration_count = Integer(3, config=True, help="""
30 How many times pdflatex will be called.
30 How many times pdflatex will be called.
31 """)
31 """)
32
32
33 command = List(["pdflatex", "{filename}"], config=True, help="""
33 command = List(["pdflatex", "--interaction=batchmode", "{filename}"], config=True, help="""
34 Shell command used to compile PDF.""")
34 Shell command used to compile PDF.""")
35
35
36 verbose = Bool(False, config=True, help="""
36 verbose = Bool(False, config=True, help="""
37 Whether or not to display the output of the compile call.
37 Whether or not to display the output of the compile call.
38 """)
38 """)
39
39
40 def call(self, input):
40 def call(self, input):
41 """
41 """
42 Consume and write Jinja output a PDF.
42 Consume and write Jinja output a PDF.
43 See files.py for more...
43 See files.py for more...
44 """
44 """
45 command = [c.format(filename=input) for c in self.command]
45 command = [c.format(filename=input) for c in self.command]
46 self.log.info("Building PDF: `%s`", ' '.join(command))
46 self.log.info("Building PDF: `%s`", ' '.join(command))
47 with open(os.devnull, 'wb') as null:
47 with open(os.devnull, 'wb') as null:
48 stdout = null if not self.verbose else None
48 stdout = null if not self.verbose else None
49 for index in range(self.iteration_count):
49 for index in range(self.iteration_count):
50 p = subprocess.Popen(command, stdout=stdout)
50 p = subprocess.Popen(command, stdout=stdout)
51 p.wait()
51 p.wait()
@@ -1,264 +1,264 b''
1 """Module that allows custom Sphinx parameters to be set on the notebook and
1 """Module that allows custom Sphinx parameters to be set on the notebook and
2 on the 'other' object passed into Jinja. Called prior to Jinja conversion
2 on the 'other' object passed into Jinja. Called prior to Jinja conversion
3 process.
3 process.
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import print_function, absolute_import
17 from __future__ import print_function, absolute_import
18
18
19 # Stdlib imports
19 # Stdlib imports
20 # Used to find Sphinx package location
20 # Used to find Sphinx package location
21 import sphinx
21 import sphinx
22 import os.path
22 import os.path
23
23
24 # Used to set the default date to today's date
24 # Used to set the default date to today's date
25 from datetime import date
25 from datetime import date
26
26
27 # Third-party imports
27 # Third-party imports
28 # Needed for Pygments latex definitions.
28 # Needed for Pygments latex definitions.
29 from pygments.formatters import LatexFormatter
29 from pygments.formatters import LatexFormatter
30
30
31 # Our own imports
31 # Our own imports
32 # Configurable traitlets
32 # Configurable traitlets
33 from IPython.utils.traitlets import Unicode, Bool
33 from IPython.utils.traitlets import Unicode, Bool
34
34
35 # Needed to override transformer
35 # Needed to override transformer
36 from .base import (Transformer)
36 from .base import (Transformer)
37
37
38 from IPython.nbconvert.utils import console
38 from IPython.nbconvert.utils import console
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Classes and functions
41 # Classes and functions
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 class SphinxTransformer(Transformer):
44 class SphinxTransformer(Transformer):
45 """
45 """
46 Sphinx utility transformer.
46 Sphinx utility transformer.
47
47
48 This transformer is used to set variables needed by the latex to build
48 This transformer is used to set variables needed by the latex to build
49 Sphinx stylized templates.
49 Sphinx stylized templates.
50 """
50 """
51
51
52 interactive = Bool(False, config=True, help="""
52 interactive = Bool(False, config=True, help="""
53 Allows you to define whether or not the Sphinx exporter will prompt
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,
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
55 the author, version, release, date, and chapter_style traits should
56 be set.
56 be set.
57 """)
57 """)
58
58
59 author = Unicode("Unknown Author", config=True, help="Author name")
59 author = Unicode("Unknown Author", config=True, help="Author name")
60
60
61 version = Unicode("", config=True, help="""
61 version = Unicode("", config=True, help="""
62 Version number
62 Version number
63 You can leave this blank if you do not want to render a version number.
63 You can leave this blank if you do not want to render a version number.
64 Example: "1.0.0"
64 Example: "1.0.0"
65 """)
65 """)
66
66
67 release = Unicode("", config=True, help="""
67 release = Unicode("", config=True, help="""
68 Release name
68 Release name
69 You can leave this blank if you do not want to render a release name.
69 You can leave this blank if you do not want to render a release name.
70 Example: "Rough Draft"
70 Example: "Rough Draft"
71 """)
71 """)
72
72
73 publish_date = Unicode("", config=True, help="""
73 publish_date = Unicode("", config=True, help="""
74 Publish date
74 Publish date
75 This is the date to render on the document as the 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.
76 Leave this blank to default to todays date.
77 Example: "June 12, 1990"
77 Example: "June 12, 1990"
78 """)
78 """)
79
79
80 chapter_style = Unicode("Bjarne", config=True, help="""
80 chapter_style = Unicode("Bjarne", config=True, help="""
81 Sphinx chapter style
81 Sphinx chapter style
82 This is the style to use for the chapter headers in the document.
82 This is the style to use for the chapter headers in the document.
83 You may choose one of the following:
83 You may choose one of the following:
84 "Bjarne" (default)
84 "Bjarne" (default)
85 "Lenny"
85 "Lenny"
86 "Glenn"
86 "Glenn"
87 "Conny"
87 "Conny"
88 "Rejne"
88 "Rejne"
89 "Sonny" (used for international documents)
89 "Sonny" (used for international documents)
90 """)
90 """)
91
91
92 output_style = Unicode("notebook", config=True, help="""
92 output_style = Unicode("notebook", config=True, help="""
93 Nbconvert Ipython
93 Nbconvert Ipython
94 notebook input/output formatting style.
94 notebook input/output formatting style.
95 You may choose one of the following:
95 You may choose one of the following:
96 "simple (recommended for long code segments)"
96 "simple (recommended for long code segments)"
97 "notebook" (default)
97 "notebook" (default)
98 """)
98 """)
99
99
100 center_output = Bool(False, config=True, help="""
100 center_output = Bool(False, config=True, help="""
101 Optional attempt to center all output. If this is false, no additional
101 Optional attempt to center all output. If this is false, no additional
102 formatting is applied.
102 formatting is applied.
103 """)
103 """)
104
104
105 use_headers = Bool(True, config=True, help="""
105 use_headers = Bool(True, config=True, help="""
106 Whether not a header should be added to the document.
106 Whether not a header should be added to the document.
107 """)
107 """)
108
108
109 #Allow the user to override the title of the notebook (useful for
109 #Allow the user to override the title of the notebook (useful for
110 #fancy document titles that the file system doesn't support.)
110 #fancy document titles that the file system doesn't support.)
111 overridetitle = Unicode("", config=True, help="")
111 overridetitle = Unicode("", config=True, help="")
112
112
113
113
114 def call(self, nb, resources):
114 def call(self, nb, resources):
115 """
115 """
116 Sphinx transformation to apply on each notebook.
116 Sphinx transformation to apply on each notebook.
117
117
118 Parameters
118 Parameters
119 ----------
119 ----------
120 nb : NotebookNode
120 nb : NotebookNode
121 Notebook being converted
121 Notebook being converted
122 resources : dictionary
122 resources : dictionary
123 Additional resources used in the conversion process. Allows
123 Additional resources used in the conversion process. Allows
124 transformers to pass variables into the Jinja engine.
124 transformers to pass variables into the Jinja engine.
125 """
125 """
126
126
127 # TODO: Add versatile method of additional notebook metadata. Include
127 # TODO: Add versatile method of additional notebook metadata. Include
128 # handling of multiple files. For now use a temporay namespace,
128 # handling of multiple files. For now use a temporay namespace,
129 # '_draft' to signify that this needs to change.
129 # '_draft' to signify that this needs to change.
130 if not "sphinx" in resources:
130 if not "sphinx" in resources:
131 resources["sphinx"] = {}
131 resources["sphinx"] = {}
132
132
133 if self.interactive:
133 if self.interactive:
134
134
135 # Prompt the user for additional meta data that doesn't exist currently
135 # Prompt the user for additional meta data that doesn't exist currently
136 # but would be usefull for Sphinx.
136 # but would be usefull for Sphinx.
137 resources["sphinx"]["author"] = self._prompt_author()
137 resources["sphinx"]["author"] = self._prompt_author()
138 resources["sphinx"]["version"] = self._prompt_version()
138 resources["sphinx"]["version"] = self._prompt_version()
139 resources["sphinx"]["release"] = self._prompt_release()
139 resources["sphinx"]["release"] = self._prompt_release()
140 resources["sphinx"]["date"] = self._prompt_date()
140 resources["sphinx"]["date"] = self._prompt_date()
141
141
142 # Prompt the user for the document style.
142 # Prompt the user for the document style.
143 resources["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
143 resources["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style()
144 resources["sphinx"]["outputstyle"] = self._prompt_output_style()
144 resources["sphinx"]["outputstyle"] = self._prompt_output_style()
145
145
146 # Small options
146 # Small options
147 resources["sphinx"]["centeroutput"] = console.prompt_boolean("Do you want to center the output? (false)", False)
147 resources["sphinx"]["centeroutput"] = console.prompt_boolean("Do you want to center the output? (false)", False)
148 resources["sphinx"]["header"] = console.prompt_boolean("Should a Sphinx document header be used? (true)", True)
148 resources["sphinx"]["header"] = console.prompt_boolean("Should a Sphinx document header be used? (true)", True)
149 else:
149 else:
150
150
151 # Try to use the traitlets.
151 # Try to use the traitlets.
152 resources["sphinx"]["author"] = self.author
152 resources["sphinx"]["author"] = self.author
153 resources["sphinx"]["version"] = self.version
153 resources["sphinx"]["version"] = self.version
154 resources["sphinx"]["release"] = self.release
154 resources["sphinx"]["release"] = self.release
155
155
156 # Use todays date if none is provided.
156 # Use todays date if none is provided.
157 if self.publish_date:
157 if self.publish_date:
158 resources["sphinx"]["date"] = self.publish_date
158 resources["sphinx"]["date"] = self.publish_date
159 elif len(resources['metadata']['modified_date'].strip()) == 0:
159 elif len(resources['metadata']['modified_date'].strip()) == 0:
160 resources["sphinx"]["date"] = date.today().strftime("%B %-d, %Y")
160 resources["sphinx"]["date"] = date.today().strftime("%B %-d, %Y")
161 else:
161 else:
162 resources["sphinx"]["date"] = resources['metadata']['modified_date']
162 resources["sphinx"]["date"] = resources['metadata']['modified_date']
163
163
164 # Sphinx traitlets.
164 # Sphinx traitlets.
165 resources["sphinx"]["chapterstyle"] = self.chapter_style
165 resources["sphinx"]["chapterstyle"] = self.chapter_style
166 resources["sphinx"]["outputstyle"] = self.output_style
166 resources["sphinx"]["outputstyle"] = self.output_style
167 resources["sphinx"]["centeroutput"] = self.center_output
167 resources["sphinx"]["centeroutput"] = self.center_output
168 resources["sphinx"]["header"] = self.use_headers
168 resources["sphinx"]["header"] = self.use_headers
169
169
170 # Find and pass in the path to the Sphinx dependencies.
170 # Find and pass in the path to the Sphinx dependencies.
171 resources["sphinx"]["texinputs"] = os.path.realpath(os.path.join(sphinx.__file__, "..", "texinputs"))
171 resources["sphinx"]["texinputs"] = os.path.realpath(os.path.join(sphinx.package_dir, "texinputs"))
172
172
173 # Generate Pygments definitions for Latex
173 # Generate Pygments definitions for Latex
174 resources["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
174 resources["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def()
175
175
176 if not (self.overridetitle == None or len(self.overridetitle.strip()) == 0):
176 if not (self.overridetitle == None or len(self.overridetitle.strip()) == 0):
177 resources['metadata']['name'] = self.overridetitle
177 resources['metadata']['name'] = self.overridetitle
178
178
179 # End
179 # End
180 return nb, resources
180 return nb, resources
181
181
182
182
183 def _generate_pygments_latex_def(self):
183 def _generate_pygments_latex_def(self):
184 """
184 """
185 Generate the pygments latex definitions that allows pygments
185 Generate the pygments latex definitions that allows pygments
186 to work in latex.
186 to work in latex.
187 """
187 """
188
188
189 return LatexFormatter().get_style_defs()
189 return LatexFormatter().get_style_defs()
190
190
191
191
192 def _prompt_author(self):
192 def _prompt_author(self):
193 """
193 """
194 Prompt the user to input an Author name
194 Prompt the user to input an Author name
195 """
195 """
196 return console.input("Author name: ")
196 return console.input("Author name: ")
197
197
198
198
199 def _prompt_version(self):
199 def _prompt_version(self):
200 """
200 """
201 prompt the user to enter a version number
201 prompt the user to enter a version number
202 """
202 """
203 return console.input("Version (ie ""1.0.0""): ")
203 return console.input("Version (ie ""1.0.0""): ")
204
204
205
205
206 def _prompt_release(self):
206 def _prompt_release(self):
207 """
207 """
208 Prompt the user to input a release name
208 Prompt the user to input a release name
209 """
209 """
210
210
211 return console.input("Release Name (ie ""Rough draft""): ")
211 return console.input("Release Name (ie ""Rough draft""): ")
212
212
213
213
214 def _prompt_date(self, resources):
214 def _prompt_date(self, resources):
215 """
215 """
216 Prompt the user to enter a date
216 Prompt the user to enter a date
217 """
217 """
218
218
219 if resources['metadata']['modified_date']:
219 if resources['metadata']['modified_date']:
220 default_date = resources['metadata']['modified_date']
220 default_date = resources['metadata']['modified_date']
221 else:
221 else:
222 default_date = date.today().strftime("%B %-d, %Y")
222 default_date = date.today().strftime("%B %-d, %Y")
223
223
224 user_date = console.input("Date (deafults to \"" + default_date + "\"): ")
224 user_date = console.input("Date (deafults to \"" + default_date + "\"): ")
225 if len(user_date.strip()) == 0:
225 if len(user_date.strip()) == 0:
226 user_date = default_date
226 user_date = default_date
227 return user_date
227 return user_date
228
228
229
229
230 def _prompt_output_style(self):
230 def _prompt_output_style(self):
231 """
231 """
232 Prompts the user to pick an IPython output style.
232 Prompts the user to pick an IPython output style.
233 """
233 """
234
234
235 # Dictionary of available output styles
235 # Dictionary of available output styles
236 styles = {1: "simple",
236 styles = {1: "simple",
237 2: "notebook"}
237 2: "notebook"}
238
238
239 #Append comments to the menu when displaying it to the user.
239 #Append comments to the menu when displaying it to the user.
240 comments = {1: "(recommended for long code segments)",
240 comments = {1: "(recommended for long code segments)",
241 2: "(default)"}
241 2: "(default)"}
242
242
243 return console.prompt_dictionary(styles, default_style=2, menu_comments=comments)
243 return console.prompt_dictionary(styles, default_style=2, menu_comments=comments)
244
244
245
245
246 def _prompt_chapter_title_style(self):
246 def _prompt_chapter_title_style(self):
247 """
247 """
248 Prompts the user to pick a Sphinx chapter style
248 Prompts the user to pick a Sphinx chapter style
249 """
249 """
250
250
251 # Dictionary of available Sphinx styles
251 # Dictionary of available Sphinx styles
252 styles = {1: "Bjarne",
252 styles = {1: "Bjarne",
253 2: "Lenny",
253 2: "Lenny",
254 3: "Glenn",
254 3: "Glenn",
255 4: "Conny",
255 4: "Conny",
256 5: "Rejne",
256 5: "Rejne",
257 6: "Sonny"}
257 6: "Sonny"}
258
258
259 #Append comments to the menu when displaying it to the user.
259 #Append comments to the menu when displaying it to the user.
260 comments = {1: "(default)",
260 comments = {1: "(default)",
261 6: "(for international documents)"}
261 6: "(for international documents)"}
262
262
263 return console.prompt_dictionary(styles, menu_comments=comments)
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