Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nbconvert: Export flavors & PDF writer (ipy dev meeting) #3784

Merged
merged 30 commits into from Jul 27, 2013
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
384d1d8
Deprecate flavor-level subclasses
jdfreder Jul 25, 2013
6f6f75f
Part way through adding 'flavor' support
jdfreder Jul 25, 2013
b827eb4
Reflection of renames in template references
jdfreder Jul 25, 2013
1061301
Added aliases to nbconvert commandline
jdfreder Jul 25, 2013
70fdc33
Small bugfixes
jdfreder Jul 25, 2013
3293d70
Update exporter tests names
jdfreder Jul 25, 2013
c59b47d
Updated tests to try flavors
jdfreder Jul 25, 2013
4324fdc
latex.tplx->latex_basic.tplx & test changes
jdfreder Jul 25, 2013
7eeb476
Fixed tests
jdfreder Jul 25, 2013
522724e
Updated help string
jdfreder Jul 25, 2013
bc5ca51
Fixed errors after testing...
jdfreder Jul 25, 2013
70c2262
Added ability to export to a 'custom' format,
jdfreder Jul 25, 2013
133a6c1
HTML-Slides -> Slides-Reveal
jdfreder Jul 25, 2013
44a5410
flavor=template
jdfreder Jul 26, 2013
f983539
PDF is really a post-processor
jdfreder Jul 26, 2013
f793543
Moved PDF logic into Post-Processor class
jdfreder Jul 26, 2013
ad32d8e
Updated example string for nbconvertapp.py
jdfreder Jul 26, 2013
85f63c6
Add @ivanov 's logic to PANDOC tests
jdfreder Jul 26, 2013
c1aafeb
Fixed, accidental deletion of format string specifier.
jdfreder Jul 26, 2013
a3b13a2
Catch specific error instead of all errors.
jdfreder Jul 26, 2013
441f8da
Fixed tests, broken because of missing pdflatex
jdfreder Jul 26, 2013
cc54e59
Remove executable comments from non-standalone files
jdfreder Jul 26, 2013
d59fec6
Fix tests
jdfreder Jul 26, 2013
d9ef1c7
Added warnings
jdfreder Jul 26, 2013
795cbfe
Removed bash string
jdfreder Jul 26, 2013
d95e89d
Fix docstring
jdfreder Jul 26, 2013
8912859
Make extension more descript
jdfreder Jul 26, 2013
22b9373
Update comment
jdfreder Jul 27, 2013
c1cdf94
Fixed tests (because of reveal extension change)
jdfreder Jul 27, 2013
e974c91
Removed non-existant PDFWriter alias
jdfreder Jul 27, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions IPython/nbconvert/__init__.py
Expand Up @@ -3,4 +3,5 @@
from .exporters import *
import filters
import transformers
import post_processors
import writers
7 changes: 2 additions & 5 deletions IPython/nbconvert/exporters/__init__.py
@@ -1,11 +1,8 @@
from .basichtml import BasicHTMLExporter
from .export import *
from .html import HTMLExporter
from .slides import SlidesExporter
from .exporter import Exporter
from .fullhtml import FullHTMLExporter
from .reveal import RevealExporter
from .latex import LatexExporter
from .markdown import MarkdownExporter
from .python import PythonExporter
from .rst import RSTExporter
from .sphinx_howto import SphinxHowtoExporter
from .sphinx_manual import SphinxManualExporter
59 changes: 22 additions & 37 deletions IPython/nbconvert/exporters/export.py
Expand Up @@ -19,15 +19,12 @@
from IPython.config import Config

from .exporter import Exporter
from .basichtml import BasicHTMLExporter
from .fullhtml import FullHTMLExporter
from .html import HTMLExporter
from .slides import SlidesExporter
from .latex import LatexExporter
from .markdown import MarkdownExporter
from .python import PythonExporter
from .reveal import RevealExporter
from .rst import RSTExporter
from .sphinx_howto import SphinxHowtoExporter
from .sphinx_manual import SphinxManualExporter

#-----------------------------------------------------------------------------
# Classes
Expand All @@ -54,7 +51,10 @@ def DocDecorator(f):
exporter_instance : Exporter
Instance of the Exporter class used to export the document. Useful
to caller because it provides a 'file_extension' property which
specifies what extension the output should be saved as."""
specifies what extension the output should be saved as.

WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT
"""

@wraps(f)
def decorator(*args, **kwargs):
Expand All @@ -69,14 +69,12 @@ def decorator(*args, **kwargs):

__all__ = [
'export',
'export_sphinx_manual',
'export_sphinx_howto',
'export_basic_html',
'export_full_html',
'export_html',
'export_custom',
'export_slides',
'export_latex',
'export_markdown',
'export_python',
'export_reveal',
'export_rst',
'export_by_name',
'get_export_names',
Expand Down Expand Up @@ -126,35 +124,27 @@ def export(exporter, nb, **kw):


@DocDecorator
def export_sphinx_manual(nb, **kw):
"""
Export a notebook object to Sphinx Manual LaTeX
"""
return export(SphinxManualExporter, nb, **kw)


@DocDecorator
def export_sphinx_howto(nb, **kw):
def export_custom(nb, **kw):
"""
Export a notebook object to Sphinx HowTo LaTeX
Export a notebook object to a custom format
"""
return export(SphinxHowtoExporter, nb, **kw)
return export(Exporter, nb, **kw)


@DocDecorator
def export_basic_html(nb, **kw):
def export_html(nb, **kw):
"""
Export a notebook object to Basic HTML
Export a notebook object to HTML
"""
return export(BasicHTMLExporter, nb, **kw)
return export(HTMLExporter, nb, **kw)


@DocDecorator
def export_full_html(nb, **kw):
def export_slides(nb, **kw):
"""
Export a notebook object to Full HTML
Export a notebook object to Slides
"""
return export(FullHTMLExporter, nb, **kw)
return export(SlidesExporter, nb, **kw)


@DocDecorator
Expand All @@ -181,14 +171,6 @@ def export_python(nb, **kw):
return export(PythonExporter, nb, **kw)


@DocDecorator
def export_reveal(nb, **kw):
"""
Export a notebook object to a Reveal.js presentation
"""
return export(RevealExporter, nb, **kw)


@DocDecorator
def export_rst(nb, **kw):
"""
Expand Down Expand Up @@ -217,7 +199,10 @@ def export_by_name(format_name, nb, **kw):


def get_export_names():
"Return a list of the currently supported export targets"
"""Return a list of the currently supported export targets

WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT"""

# grab everything after 'export_'
l = [x[len('export_'):] for x in __all__ if x.startswith('export_')]

Expand Down
52 changes: 44 additions & 8 deletions IPython/nbconvert/exporters/exporter.py
Expand Up @@ -25,7 +25,7 @@
import datetime

# other libs/dependencies
from jinja2 import Environment, FileSystemLoader, ChoiceLoader
from jinja2 import Environment, FileSystemLoader, ChoiceLoader, TemplateNotFound

# IPython imports
from IPython.config.configurable import Configurable
Expand Down Expand Up @@ -86,17 +86,23 @@ class Exporter(Configurable):
transformers provided by default suffice, there is no need to inherit from
this class. Instead, override the template_file and file_extension
traits via a config file.

{filters}
"""

# finish the docstring
__doc__ = __doc__.format(filters = '- '+'\n - '.join(default_filters.keys()))


template_file = Unicode(
'', config=True,
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,
Expand Down Expand Up @@ -155,6 +161,8 @@ def __init__(self, config=None, extra_loaders=None, **kw):
extra_loaders : list[of Jinja Loaders]
ordered list of Jinja loder to find templates. Will be tried in order
before the default FileSysteme ones.
template : str (optional, kw arg)
Template to use when exporting.
"""

#Call the base class constructor
Expand All @@ -165,6 +173,7 @@ def __init__(self, config=None, extra_loaders=None, **kw):
super(Exporter, self).__init__(config=c, **kw)

#Init
self._init_template(**kw)
self._init_environment(extra_loaders=extra_loaders)
self._init_transformers()
self._init_filters()
Expand All @@ -189,12 +198,29 @@ def from_notebook_node(self, nb, resources=None, **kw):
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]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you tell me a use case for this last one? maybe I am tired ;-) but I can't figure it out a use case... thanks

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, ipython nbconvert --to rst notebook1.ipynb

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or any other format without flavors

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used for the flavor. When you have a default templates like markdown that don't have flavor like 'markdown_foo.tpl'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thanks to both of you... I was thinking only in "flavored" things... got it!

for try_name in try_names:
try:
self.template = self.environment.get_template(try_name)
break
except TemplateNotFound:
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


Expand Down Expand Up @@ -329,6 +355,16 @@ def register_filter(self, name, jinja_filter):
raise TypeError('filter')


def _init_template(self, **kw):
"""
Make sure a template name is specified. If one isn't specified, try to
build one from the information we know.
"""
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):
"""
Create the Jinja templating environment.
Expand Down
39 changes: 0 additions & 39 deletions IPython/nbconvert/exporters/fullhtml.py

This file was deleted.

Expand Up @@ -17,14 +17,15 @@
from IPython.utils.traitlets import Unicode, List

from IPython.nbconvert import transformers
from IPython.config import Config

from .exporter import Exporter

#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------

class BasicHTMLExporter(Exporter):
class HTMLExporter(Exporter):
"""
Exports a basic HTML document. This exporter assists with the export of
HTML. Inherit from it if you are writing your own HTML template and need
Expand All @@ -37,6 +38,15 @@ class BasicHTMLExporter(Exporter):
help="Extension of the file that should be written to disk"
)

template_file = Unicode(
'basichtml', config=True,
help="Name of the template file to use")
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
}
})
c.merge(super(HTMLExporter,self).default_config)
return c
9 changes: 6 additions & 3 deletions IPython/nbconvert/exporters/latex.py
Expand Up @@ -44,9 +44,8 @@ class LatexExporter(Exporter):
'tex', config=True,
help="Extension of the file that should be written to disk")

template_file = Unicode(
'base', config=True,
help="Name of the template file to use")
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(
Expand All @@ -68,6 +67,7 @@ class LatexExporter(Exporter):
#Extension that the template files use.
template_extension = Unicode(".tplx", config=True)


@property
def default_config(self):
c = Config({
Expand All @@ -82,6 +82,9 @@ def default_config(self):
},
'LatexTransformer': {
'enabled':True
},
'SphinxTransformer': {
'enabled':True
}
})
c.merge(super(LatexExporter,self).default_config)
Expand Down
4 changes: 0 additions & 4 deletions IPython/nbconvert/exporters/markdown.py
Expand Up @@ -29,7 +29,3 @@ class MarkdownExporter(Exporter):
file_extension = Unicode(
'md', config=True,
help="Extension of the file that should be written to disk")

template_file = Unicode(
'markdown', config=True,
help="Name of the template file to use")
4 changes: 0 additions & 4 deletions IPython/nbconvert/exporters/python.py
Expand Up @@ -29,7 +29,3 @@ class PythonExporter(Exporter):
file_extension = Unicode(
'py', config=True,
help="Extension of the file that should be written to disk")

template_file = Unicode(
'python', config=True,
help="Name of the template file to use")
4 changes: 0 additions & 4 deletions IPython/nbconvert/exporters/rst.py
Expand Up @@ -31,10 +31,6 @@ class RSTExporter(Exporter):
'rst', config=True,
help="Extension of the file that should be written to disk")

template_file = Unicode(
'rst', config=True,
help="Name of the template file to use")

@property
def default_config(self):
c = Config({'ExtractOutputTransformer':{'enabled':True}})
Expand Down