##// END OF EJS Templates
Moved PDF logic into Post-Processor class
Jonathan Frederic -
Show More
@@ -0,0 +1,2
1 from .base import PostProcessorBase
2 from .pdf import PDFPostProcessor
@@ -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