Show More
@@ -0,0 +1,36 | |||
|
1 | #!/usr/bin/env python | |
|
2 | """ | |
|
3 | Basic post processor | |
|
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 | #----------------------------------------------------------------------------- | |
|
12 | ||
|
13 | #----------------------------------------------------------------------------- | |
|
14 | # Imports | |
|
15 | #----------------------------------------------------------------------------- | |
|
16 | ||
|
17 | from ..utils.base import NbConvertBase | |
|
18 | ||
|
19 | ||
|
20 | #----------------------------------------------------------------------------- | |
|
21 | # Classes | |
|
22 | #----------------------------------------------------------------------------- | |
|
23 | class PostProcessorBase(NbConvertBase): | |
|
24 | ||
|
25 | def __call__(self, input): | |
|
26 | """ | |
|
27 | See def call() ... | |
|
28 | """ | |
|
29 | self.call(input) | |
|
30 | ||
|
31 | ||
|
32 | def call(self, input): | |
|
33 | """ | |
|
34 | Post-process output from a writer. | |
|
35 | """ | |
|
36 | raise NotImplementedError('call') |
@@ -3,4 +3,5 | |||
|
3 | 3 | from .exporters import * |
|
4 | 4 | import filters |
|
5 | 5 | import transformers |
|
6 | import post_processors | |
|
6 | 7 | import writers |
@@ -30,7 +30,7 from IPython.utils.traitlets import ( | |||
|
30 | 30 | from IPython.utils.importstring import import_item |
|
31 | 31 | |
|
32 | 32 | from .exporters.export import export_by_name, get_export_names, ExporterNameError |
|
33 | from IPython.nbconvert import exporters, transformers, writers | |
|
33 | from IPython.nbconvert import exporters, transformers, writers, post_processors | |
|
34 | 34 | from .utils.base import NbConvertBase |
|
35 | 35 | from .utils.exceptions import ConversionException |
|
36 | 36 | |
@@ -38,6 +38,19 from .utils.exceptions import ConversionException | |||
|
38 | 38 | #Classes and functions |
|
39 | 39 | #----------------------------------------------------------------------------- |
|
40 | 40 | |
|
41 | class DottedOrNone(DottedObjectName): | |
|
42 | """ | |
|
43 | A string holding a valid dotted object name in Python, such as A.b3._c | |
|
44 | Also allows for None type.""" | |
|
45 | ||
|
46 | default_value = u'' | |
|
47 | ||
|
48 | def validate(self, obj, value): | |
|
49 | if value is not None and len(value) > 0: | |
|
50 | return super(DottedOrNone, self).validate(obj, value) | |
|
51 | else: | |
|
52 | return value | |
|
53 | ||
|
41 | 54 | nbconvert_aliases = {} |
|
42 | 55 | nbconvert_aliases.update(base_aliases) |
|
43 | 56 | nbconvert_aliases.update({ |
@@ -45,6 +58,7 nbconvert_aliases.update({ | |||
|
45 | 58 | 'template' : 'Exporter.template_file', |
|
46 | 59 | 'notebooks' : 'NbConvertApp.notebooks', |
|
47 | 60 | 'writer' : 'NbConvertApp.writer_class', |
|
61 | 'post': 'NbConvertApp.post_processor_class' | |
|
48 | 62 | }) |
|
49 | 63 | |
|
50 | 64 | nbconvert_flags = {} |
@@ -53,11 +67,6 nbconvert_flags.update({ | |||
|
53 | 67 | 'stdout' : ( |
|
54 | 68 | {'NbConvertApp' : {'writer_class' : "StdoutWriter"}}, |
|
55 | 69 | "Write notebook output to stdout instead of files." |
|
56 | ), | |
|
57 | ||
|
58 | 'pdf' : ( | |
|
59 | {'NbConvertApp' : {'writer_class' : "PDFWriter"}}, | |
|
60 | "Compile notebook output to a PDF (requires `--to latex`)." | |
|
61 | 70 | ) |
|
62 | 71 | }) |
|
63 | 72 | |
@@ -120,6 +129,7 class NbConvertApp(BaseIPythonApplication): | |||
|
120 | 129 | |
|
121 | 130 | > ipython nbconvert --config mycfg.py |
|
122 | 131 | """.format(get_export_names())) |
|
132 | ||
|
123 | 133 | # Writer specific variables |
|
124 | 134 | writer = Instance('IPython.nbconvert.writers.base.WriterBase', |
|
125 | 135 | help="""Instance of the writer class used to write the |
@@ -138,6 +148,23 class NbConvertApp(BaseIPythonApplication): | |||
|
138 | 148 | new = self.writer_aliases[new] |
|
139 | 149 | self.writer_factory = import_item(new) |
|
140 | 150 | |
|
151 | # Post-processor specific variables | |
|
152 | post_processor = Instance('IPython.nbconvert.post_processors.base.PostProcessorBase', | |
|
153 | help="""Instance of the PostProcessor class used to write the | |
|
154 | results of the conversion.""") | |
|
155 | ||
|
156 | post_processor_class = DottedOrNone(config=True, | |
|
157 | help="""PostProcessor class used to write the | |
|
158 | results of the conversion""") | |
|
159 | post_processor_aliases = {'PDF': 'IPython.nbconvert.post_processors.pdf.PDFPostProcessor'} | |
|
160 | post_processor_factory = Type() | |
|
161 | ||
|
162 | def _post_processor_class_changed(self, name, old, new): | |
|
163 | if new in self.post_processor_aliases: | |
|
164 | new = self.post_processor_aliases[new] | |
|
165 | if new: | |
|
166 | self.post_processor_factory = import_item(new) | |
|
167 | ||
|
141 | 168 | |
|
142 | 169 | # Other configurable variables |
|
143 | 170 | export_format = CaselessStrEnum(get_export_names(), |
@@ -157,6 +184,8 class NbConvertApp(BaseIPythonApplication): | |||
|
157 | 184 | self.init_syspath() |
|
158 | 185 | self.init_notebooks() |
|
159 | 186 | self.init_writer() |
|
187 | self.init_post_processor() | |
|
188 | ||
|
160 | 189 | |
|
161 | 190 | |
|
162 | 191 | def init_syspath(self): |
@@ -201,6 +230,15 class NbConvertApp(BaseIPythonApplication): | |||
|
201 | 230 | self._writer_class_changed(None, self.writer_class, self.writer_class) |
|
202 | 231 | self.writer = self.writer_factory(parent=self) |
|
203 | 232 | |
|
233 | def init_post_processor(self): | |
|
234 | """ | |
|
235 | Initialize the post_processor (which is stateless) | |
|
236 | """ | |
|
237 | self._post_processor_class_changed(None, self.post_processor_class, | |
|
238 | self.post_processor_class) | |
|
239 | if self.post_processor_factory: | |
|
240 | self.post_processor = self.post_processor_factory(parent=self) | |
|
241 | ||
|
204 | 242 | def start(self): |
|
205 | 243 | """ |
|
206 | 244 | Ran after initialization completed |
@@ -242,7 +280,11 class NbConvertApp(BaseIPythonApplication): | |||
|
242 | 280 | file=sys.stderr) |
|
243 | 281 | self.exit(1) |
|
244 | 282 | else: |
|
245 | self.writer.write(output, resources, notebook_name=notebook_name) | |
|
283 | write_resultes = self.writer.write(output, resources, notebook_name=notebook_name) | |
|
284 | ||
|
285 | #Post-process if post processor has been defined. | |
|
286 | if hasattr(self, 'post_processor') and self.post_processor: | |
|
287 | self.post_processor(write_resultes) | |
|
246 | 288 | conversion_success += 1 |
|
247 | 289 | |
|
248 | 290 | # If nothing was converted successfully, help the user. |
@@ -17,14 +17,14 Contains writer for writing nbconvert output to PDF. | |||
|
17 | 17 | import subprocess |
|
18 | 18 | import os |
|
19 | 19 | |
|
20 | from IPython.utils.traitlets import Integer, Unicode | |
|
20 | from IPython.utils.traitlets import Integer, Unicode, Bool | |
|
21 | 21 | |
|
22 | from .files import FilesWriter | |
|
22 | from .base import PostProcessorBase | |
|
23 | 23 | |
|
24 | 24 | #----------------------------------------------------------------------------- |
|
25 | 25 | # Classes |
|
26 | 26 | #----------------------------------------------------------------------------- |
|
27 | class PDFWriter(FilesWriter): | |
|
27 | class PDFPostProcessor(PostProcessorBase): | |
|
28 | 28 | """Writer designed to write to PDF files""" |
|
29 | 29 | |
|
30 | 30 | iteration_count = Integer(3, config=True, help=""" |
@@ -34,14 +34,19 class PDFWriter(FilesWriter): | |||
|
34 | 34 | compiler = Unicode(u'pdflatex {0}', config=True, help=""" |
|
35 | 35 | Shell command used to compile PDF.""") |
|
36 | 36 | |
|
37 | def write(self, output, resources, notebook_name=None, **kw): | |
|
37 | verbose = Bool(False, config=True, help=""" | |
|
38 | Whether or not to display the output of the compile call. | |
|
39 | """) | |
|
40 | ||
|
41 | def call(self, input): | |
|
38 | 42 | """ |
|
39 | 43 | Consume and write Jinja output a PDF. |
|
40 | 44 | See files.py for more... |
|
41 | 45 | """ |
|
42 | dest = super(PDFWriter, self).write(output, resources, | |
|
43 | notebook_name=notebook_name, **kw) | |
|
44 | command = self.compiler.format(dest) | |
|
45 | ||
|
46 | command = self.compiler.format(input) | |
|
46 | 47 | for index in range(self.iteration_count): |
|
47 | subprocess.Popen(command, shell=True, stdout=open(os.devnull, 'wb')) | |
|
48 | if self.verbose: | |
|
49 | subprocess.Popen(command, shell=True) | |
|
50 | else: | |
|
51 | with open(os.devnull, 'wb') as null: | |
|
52 | subprocess.Popen(command, shell=True, stdout=null) |
@@ -17,6 +17,7 import os | |||
|
17 | 17 | from .base import TestsBase |
|
18 | 18 | |
|
19 | 19 | from IPython.utils import py3compat |
|
20 | from IPython.testing import decorators as dec | |
|
20 | 21 | |
|
21 | 22 | |
|
22 | 23 | #----------------------------------------------------------------------------- |
@@ -80,6 +81,19 class TestNbConvertApp(TestsBase): | |||
|
80 | 81 | assert os.path.isfile('notebook2.py') |
|
81 | 82 | |
|
82 | 83 | |
|
84 | #@dec.skip_known_failure | |
|
85 | def test_post_processor(self): | |
|
86 | """ | |
|
87 | Do post processors work? | |
|
88 | """ | |
|
89 | with self.create_temp_cwd(['notebook1.ipynb']): | |
|
90 | assert not 'error' in self.call([IPYTHON, 'nbconvert', '--to="latex"', | |
|
91 | 'notebook1', '--post="PDF"', 'PDFPostProcessor.verbose=True']).lower() | |
|
92 | assert os.path.isfile('notebook1.tex') | |
|
93 | print("\n\n\t" + "\n\t".join([f for f in os.listdir('.') if os.path.isfile(f)]) + "\n\n") | |
|
94 | assert os.path.isfile('notebook1.pdf') | |
|
95 | ||
|
96 | ||
|
83 | 97 | def test_template(self): |
|
84 | 98 | """ |
|
85 | 99 | Do export templates work? |
General Comments 0
You need to be logged in to leave comments.
Login now