Skip to content

Commit

Permalink
Merge pull request #69 from takluyver/simplify-slides-export
Browse files Browse the repository at this point in the history
Rehash and simplify slide export
  • Loading branch information
minrk committed Jul 30, 2015
2 parents 0ce3a9a + 08a5c12 commit ffa69c7
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 209 deletions.
1 change: 0 additions & 1 deletion nbconvert/exporters/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ class Exporter(LoggingConfigurable):
'nbconvert.preprocessors.coalesce_streams',
'nbconvert.preprocessors.SVG2PDFPreprocessor',
'nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
'nbconvert.preprocessors.RevealHelpPreprocessor',
'nbconvert.preprocessors.LatexPreprocessor',
'nbconvert.preprocessors.HighlightMagicsPreprocessor',
'nbconvert.preprocessors.ExtractOutputPreprocessor',
Expand Down
113 changes: 91 additions & 22 deletions nbconvert/exporters/slides.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,97 @@
"""HTML slide show Exporter class"""

#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from copy import deepcopy
from warnings import warn

from nbconvert import preprocessors
from traitlets.config import Config
from traitlets import Unicode

from .html import HTMLExporter

#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
def prepare(nb):
"""Add some convenenience metadata on cells for the slide template.
"""
nb = deepcopy(nb)

for cell in nb.cells:
# Make sure every cell has a slide_type
cell.metadata.slide_type = cell.metadata.get('slideshow', {}).get('slide_type', '-')

# Find the first visible cell
for index, cell in enumerate(nb.cells):
if cell.metadata.slide_type not in {'notes', 'skip'}:
cell.metadata.slide_type = 'slide'
cell.metadata.slide_start = True
cell.metadata.subslide_start = True
first_slide_ix = index
break
else:
raise ValueError("All cells are hidden, cannot create slideshow")

in_fragment = False

for index, cell in enumerate(nb.cells[first_slide_ix+1:],
start=(first_slide_ix+1)):

previous_cell = nb.cells[index - 1]

# Slides are <section> elements in the HTML, subslides (the vertically
# stacked slides) are also <section> elements inside the slides,
# and fragments are <div>s within subslides. Subslide and fragment
# elements can contain content:
# <section>
# <section>
# (content)
# <div class="fragment">(content)</div>
# </section>
# </section>

# Get the slide type. If type is subslide or slide,
# end the last slide/subslide/fragment as applicable.
if cell.metadata.slide_type == 'slide':
previous_cell.metadata.slide_end = True
cell.metadata.slide_start = True
if cell.metadata.slide_type in {'subslide', 'slide'}:
previous_cell.metadata.fragment_end = in_fragment
previous_cell.metadata.subslide_end = True
cell.metadata.subslide_start = True
in_fragment = False

elif cell.metadata.slide_type == 'fragment':
cell.metadata.fragment_start = True
if in_fragment:
previous_cell.metadata.fragment_end = True
else:
in_fragment = True

# The last cell will always be the end of a slide
nb.cells[-1].metadata.fragment_end = in_fragment
nb.cells[-1].metadata.subslide_end = True
nb.cells[-1].metadata.slide_end = True

return nb

class SlidesExporter(HTMLExporter):
"""Exports HTML slides with reveal.js"""

reveal_url_prefix = Unicode(config=True,
help="""The URL prefix for reveal.js.
This can be a a relative URL for a local copy of reveal.js,
or point to a CDN.
For speaker notes to work, a local reveal.js prefix must be used.
"""
)

def _reveal_url_prefix_default(self):
if 'RevealHelpPreprocessor.url_prefix' in self.config:
warn("Please update RevealHelpPreprocessor.url_prefix to "
"SlidesExporter.reveal_url_prefix in config files.")
return self.config.RevealHelpPreprocessor.url_prefix
return 'reveal.js'

def _file_extension_default(self):
return '.slides.html'
Expand All @@ -32,12 +101,12 @@ def _template_file_default(self):

output_mimetype = 'text/html'

@property
def default_config(self):
c = Config({
'RevealHelpPreprocessor': {
'enabled': True,
},
})
c.merge(super(SlidesExporter,self).default_config)
return c
def from_notebook_node(self, nb, resources=None, **kw):
self._init_resources(resources)
if 'reveal' not in resources:
resources['reveal'] = {}
resources['reveal']['url_prefix'] = self.reveal_url_prefix

nb = prepare(nb)

return super(SlidesExporter, self).from_notebook_node(nb, resources=resources, **kw)
46 changes: 45 additions & 1 deletion nbconvert/exporters/tests/test_slides.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.

from nbformat import v4 as nbformat
from .base import ExportersTestsBase
from ..slides import SlidesExporter
from ..slides import SlidesExporter, prepare


class TestSlidesExporter(ExportersTestsBase):
Expand Down Expand Up @@ -34,3 +35,46 @@ def test_export_reveal(self):
"""
(output, resources) = SlidesExporter(template_file='slides_reveal').from_filename(self._get_notebook())
assert len(output) > 0

def build_notebook(self):
"""Build a reveal slides notebook in memory for use with tests."""
outputs = [nbformat.new_output(output_type="stream", name="stdout", text="a")]

slide_metadata = {'slideshow' : {'slide_type': 'slide'}}
subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}}
fragment_metadata = {'slideshow' : {'slide_type': 'fragment'}}

cells=[nbformat.new_code_cell(source="", execution_count=1, outputs=outputs),
nbformat.new_markdown_cell(source="", metadata=slide_metadata),
nbformat.new_code_cell(source="", execution_count=2, outputs=outputs),
nbformat.new_markdown_cell(source="", metadata=slide_metadata),
nbformat.new_markdown_cell(source="", metadata=subslide_metadata),
nbformat.new_markdown_cell(source="", metadata=fragment_metadata),
nbformat.new_code_cell(source="", execution_count=1, outputs=outputs)]

return nbformat.new_notebook(cells=cells)

def test_prepare(self):
nb = self.build_notebook()
nb = prepare(nb)
cells = nb.cells

# Make sure correct metadata tags are available on every cell.
for cell in cells:
assert 'slide_type' in cell.metadata

# Make sure slide end is only applied to the cells preceeding slide
# cells.
assert not cells[1].metadata.get('slide_end', False)

# Verify 'slide-end'
assert cells[0].metadata['slide_end']
assert cells[2].metadata['slide_end']
assert cells[2].metadata['subslide_end']

assert not cells[3].metadata.get('slide_end', False)
assert cells[3].metadata['subslide_end']

assert cells[-1].metadata['fragment_end']
assert cells[-1].metadata['subslide_end']
assert cells[-1].metadata['slide_end']
2 changes: 1 addition & 1 deletion nbconvert/nbconvertapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def validate(self, obj, value):
'writer' : 'NbConvertApp.writer_class',
'post': 'NbConvertApp.postprocessor_class',
'output': 'NbConvertApp.output_base',
'reveal-prefix': 'RevealHelpPreprocessor.url_prefix',
'reveal-prefix': 'SlidesExporter.reveal_url_prefix',
'nbformat': 'NotebookExporter.nbformat_version',
})

Expand Down
1 change: 0 additions & 1 deletion nbconvert/preprocessors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from .convertfigures import ConvertFiguresPreprocessor
from .svg2pdf import SVG2PDFPreprocessor
from .extractoutput import ExtractOutputPreprocessor
from .revealhelp import RevealHelpPreprocessor
from .latex import LatexPreprocessor
from .csshtmlheader import CSSHTMLHeaderPreprocessor
from .highlightmagics import HighlightMagicsPreprocessor
Expand Down
70 changes: 0 additions & 70 deletions nbconvert/preprocessors/revealhelp.py

This file was deleted.

81 changes: 0 additions & 81 deletions nbconvert/preprocessors/tests/test_revealhelp.py

This file was deleted.

0 comments on commit ffa69c7

Please sign in to comment.