diff --git a/IPython/nbconvert/exporters/exporter.py b/IPython/nbconvert/exporters/exporter.py index 0e25964..49f1a0d 100755 --- a/IPython/nbconvert/exporters/exporter.py +++ b/IPython/nbconvert/exporters/exporter.py @@ -92,12 +92,15 @@ class Exporter(Configurable): __doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys())) - flavor = Unicode(config=True, help="""Flavor of the data format to use. - I.E. 'full' or 'basic'""") - - template_file = Unicode( + template_file = Unicode(u'default', config=True, help="Name of the template file to use") + def _template_file_changed(self, name, old, new): + if new=='default': + self.template_file = self.default_template + else: + self.template_file = new + default_template = Unicode(u'') file_extension = Unicode( 'txt', config=True, @@ -156,9 +159,8 @@ class Exporter(Configurable): extra_loaders : list[of Jinja Loaders] ordered list of Jinja loder to find templates. Will be tried in order before the default FileSysteme ones. - flavor : str - Flavor to use when exporting. This determines what template to use - if one hasn't been specifically provided. + template : str (optional, kw arg) + Template to use when exporting. """ #Call the base class constructor @@ -194,12 +196,29 @@ class Exporter(Configurable): nb_copy = copy.deepcopy(nb) resources = self._init_resources(resources) - #Preprocess + # Preprocess nb_copy, resources = self._transform(nb_copy, resources) - #Convert - self.template = self.environment.get_template(self.template_file + self.template_extension) - output = self.template.render(nb=nb_copy, resources=resources) + # Try different template names during conversion. First try to load the + # template by name with extension added, then try loading the template + # as if the name is explicitly specified, then try the name as a + # 'flavor', and lastly just try to load the template by module name. + module_name = self.__module__.split('.')[-1] + try_names = [self.template_file + self.template_extension, + self.template_file, + module_name + '_' + self.template_file + self.template_extension, + module_name + self.template_extension] + for try_name in try_names: + try: + self.template = self.environment.get_template(try_name) + break + except: + pass + + if hasattr(self, 'template'): + output = self.template.render(nb=nb_copy, resources=resources) + else: + raise IOError('template file "%s" could not be found' % self.template_file) return output, resources @@ -339,19 +358,9 @@ class Exporter(Configurable): Make sure a template name is specified. If one isn't specified, try to build one from the information we know. """ - - # Set the template_file if it has not been set explicitly. - if not self.template_file: - - # Build the template file name from the name of the exporter and the - # flavor (if available). The flavor can be set on the traitlet - # or passed in as a kw arg. The flavor specified in kw overrides - # what is set in the flavor traitlet. - module_name = self.__module__.split('.')[-1] - if self.flavor or 'flavor' in kw: - self.template_file = module_name + '_' + kw.get('flavor', self.flavor) - else: - self.template_file = module_name + self._template_file_changed('template_file', self.template_file, self.template_file) + if 'template' in kw: + self.template_file = kw['template'] def _init_environment(self, extra_loaders=None): diff --git a/IPython/nbconvert/exporters/html.py b/IPython/nbconvert/exporters/html.py index 6046cc2..f79193d 100644 --- a/IPython/nbconvert/exporters/html.py +++ b/IPython/nbconvert/exporters/html.py @@ -38,18 +38,15 @@ class HTMLExporter(Exporter): help="Extension of the file that should be written to disk" ) - flavor = Unicode('full', config=True, help="""Flavor of the data format to - use. I.E. 'full' or 'basic'""") + default_template = Unicode('full', config=True, help="""Flavor of the data + format to use. I.E. 'full' or 'basic'""") @property def default_config(self): c = Config({ 'CSSHTMLHeaderTransformer':{ 'enabled':True - }, - 'RevealHelpTransformer':{ - 'enabled':True, - }, + } }) c.merge(super(HTMLExporter,self).default_config) return c diff --git a/IPython/nbconvert/exporters/latex.py b/IPython/nbconvert/exporters/latex.py index b844362..453f95b 100755 --- a/IPython/nbconvert/exporters/latex.py +++ b/IPython/nbconvert/exporters/latex.py @@ -44,8 +44,8 @@ class LatexExporter(Exporter): 'tex', config=True, help="Extension of the file that should be written to disk") - flavor = Unicode('article', config=True, help="""Flavor of the data format to - use. I.E. 'full' or 'basic'""") + default_template = Unicode('article', config=True, help="""Template of the + data format to use. I.E. 'full' or 'basic'""") #Latex constants default_template_path = Unicode( diff --git a/IPython/nbconvert/exporters/slides.py b/IPython/nbconvert/exporters/slides.py index 58f7900..e035351 100644 --- a/IPython/nbconvert/exporters/slides.py +++ b/IPython/nbconvert/exporters/slides.py @@ -35,8 +35,8 @@ class SlidesExporter(Exporter): help="Extension of the file that should be written to disk" ) - flavor = Unicode('reveal', config=True, help="""Flavor of the data format to - use. I.E. 'reveal'""") + default_template = Unicode('reveal', config=True, help="""Template of the + data format to use. I.E. 'reveal'""") @property def default_config(self): diff --git a/IPython/nbconvert/exporters/tests/test_html.py b/IPython/nbconvert/exporters/tests/test_html.py index e6542bb..290bf72 100644 --- a/IPython/nbconvert/exporters/tests/test_html.py +++ b/IPython/nbconvert/exporters/tests/test_html.py @@ -42,15 +42,15 @@ class TestHTMLExporter(ExportersTestsBase): def test_export_basic(self): """ - Can a HTMLExporter export using the 'basic' flavor? + Can a HTMLExporter export using the 'basic' template? """ - (output, resources) = HTMLExporter(flavor='basic').from_filename(self._get_notebook()) + (output, resources) = HTMLExporter(template='basic').from_filename(self._get_notebook()) assert len(output) > 0 def test_export_full(self): """ - Can a HTMLExporter export using the 'full' flavor? + Can a HTMLExporter export using the 'full' template? """ - (output, resources) = HTMLExporter(flavor='full').from_filename(self._get_notebook()) + (output, resources) = HTMLExporter(template='full').from_filename(self._get_notebook()) assert len(output) > 0 diff --git a/IPython/nbconvert/exporters/tests/test_latex.py b/IPython/nbconvert/exporters/tests/test_latex.py index 9fc885f..8ef8527 100644 --- a/IPython/nbconvert/exporters/tests/test_latex.py +++ b/IPython/nbconvert/exporters/tests/test_latex.py @@ -43,23 +43,23 @@ class TestLatexExporter(ExportersTestsBase): def test_export_book(self): """ - Can a LatexExporter export using 'book' flavor? + Can a LatexExporter export using 'book' template? """ - (output, resources) = LatexExporter(flavor='book').from_filename(self._get_notebook()) + (output, resources) = LatexExporter(template='book').from_filename(self._get_notebook()) assert len(output) > 0 def test_export_basic(self): """ - Can a LatexExporter export using 'basic' flavor? + Can a LatexExporter export using 'basic' template? """ - (output, resources) = LatexExporter(flavor='basic').from_filename(self._get_notebook()) + (output, resources) = LatexExporter(template='basic').from_filename(self._get_notebook()) assert len(output) > 0 def test_export_article(self): """ - Can a LatexExporter export using 'article' flavor? + Can a LatexExporter export using 'article' template? """ - (output, resources) = LatexExporter(flavor='article').from_filename(self._get_notebook()) + (output, resources) = LatexExporter(template='article').from_filename(self._get_notebook()) assert len(output) > 0 \ No newline at end of file diff --git a/IPython/nbconvert/exporters/tests/test_slides.py b/IPython/nbconvert/exporters/tests/test_slides.py index 6131845..06443a6 100644 --- a/IPython/nbconvert/exporters/tests/test_slides.py +++ b/IPython/nbconvert/exporters/tests/test_slides.py @@ -41,7 +41,7 @@ class TestSlidesExporter(ExportersTestsBase): def test_export_reveal(self): """ - Can a SlidesExporter export using the 'reveal' flavor? + Can a SlidesExporter export using the 'reveal' template? """ - (output, resources) = SlidesExporter(flavor='reveal').from_filename(self._get_notebook()) + (output, resources) = SlidesExporter(template='reveal').from_filename(self._get_notebook()) assert len(output) > 0 diff --git a/IPython/nbconvert/nbconvertapp.py b/IPython/nbconvert/nbconvertapp.py index 75ab356..eec4732 100755 --- a/IPython/nbconvert/nbconvertapp.py +++ b/IPython/nbconvert/nbconvertapp.py @@ -42,7 +42,6 @@ nbconvert_aliases = {} nbconvert_aliases.update(base_aliases) nbconvert_aliases.update({ 'to' : 'NbConvertApp.export_format', - 'flavor' : 'Exporter.flavor', 'template' : 'Exporter.template_file', 'notebooks' : 'NbConvertApp.notebooks', 'writer' : 'NbConvertApp.writer_class', @@ -58,7 +57,7 @@ nbconvert_flags.update({ 'pdf' : ( {'NbConvertApp' : {'writer_class' : "PDFWriter"}}, - "Compile notebook output to a PDF." + "Compile notebook output to a PDF (requires `--to latex`)." ) }) @@ -95,11 +94,11 @@ class NbConvertApp(BaseIPythonApplication): > ipython nbconvert --to latex mynotebook.ipnynb - Both HTML and LaTeX support multiple flavors of output. LaTeX includes + Both HTML and LaTeX support multiple output templates. LaTeX includes 'basic', 'book', and 'article'. HTML includes 'basic' and 'full'. You can specify the flavor of the format used. - > ipython nbconvert --to html --flavor reveal mynotebook.ipnynb + > ipython nbconvert --to html --template reveal mynotebook.ipnynb You can also pipe the output to stdout, rather than a file @@ -107,7 +106,7 @@ class NbConvertApp(BaseIPythonApplication): or to a PDF - > ipython nbconvert mynotebook.ipynb --pdf + > ipython nbconvert mynotebook.ipynb --to latex --pdf Multiple notebooks can be given at the command line in a couple of different ways: diff --git a/IPython/nbconvert/tests/test_nbconvertapp.py b/IPython/nbconvert/tests/test_nbconvertapp.py index 35f8b01..f3548e9 100644 --- a/IPython/nbconvert/tests/test_nbconvertapp.py +++ b/IPython/nbconvert/tests/test_nbconvertapp.py @@ -80,13 +80,13 @@ class TestNbConvertApp(TestsBase): assert os.path.isfile('notebook2.py') - def test_flavor(self): + def test_template(self): """ - Do export flavors work? + Do export templates work? """ with self.create_temp_cwd(['notebook*.ipynb']): assert not 'error' in self.call([IPYTHON, 'nbconvert', '--to="slides"', - '--notebooks=["notebook2.ipynb"]', '--flavor="reveal"']).lower() + '--notebooks=["notebook2.ipynb"]', '--template="reveal"']).lower() assert os.path.isfile('notebook2.html') with open('notebook2.html') as f: assert '/reveal.css' in f.read() diff --git a/IPython/nbconvert/writers/pdf.py b/IPython/nbconvert/writers/pdf.py index d6cb5fa..4224a8a 100644 --- a/IPython/nbconvert/writers/pdf.py +++ b/IPython/nbconvert/writers/pdf.py @@ -17,7 +17,7 @@ Contains writer for writing nbconvert output to PDF. import subprocess import os -from IPython.utils.traitlets import Integer +from IPython.utils.traitlets import Integer, Unicode from .files import FilesWriter @@ -31,12 +31,17 @@ class PDFWriter(FilesWriter): How many times pdflatex will be called. """) + compiler = Unicode(u'pdflatex {0}', config=True, help=""" + Shell command used to compile PDF.""") + def write(self, output, resources, notebook_name=None, **kw): """ Consume and write Jinja output a PDF. See files.py for more... """ - dest = super(PDFWriter, self).write(output, resources, notebook_name=notebook_name, **kw) - command = 'pdflatex ' + dest + dest = super(PDFWriter, self).write(output, resources, + notebook_name=notebook_name, **kw) + command = self.compiler.format(dest) + for index in range(self.iteration_count): subprocess.Popen(command, shell=True, stdout=open(os.devnull, 'wb'))