Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/nbconvert/exporters/slides.py: 32%
76 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
1"""HTML slide show Exporter class"""
3# Copyright (c) Jupyter Development Team.
4# Distributed under the terms of the Modified BSD License.
6from copy import deepcopy
7from warnings import warn
9from traitlets import Bool, Unicode, default
11from nbconvert.preprocessors.base import Preprocessor
13from .html import HTMLExporter
16class _RevealMetadataPreprocessor(Preprocessor):
17 # A custom preprocessor adding convenience metadata to cells
19 def preprocess(self, nb, resources=None):
20 nb = deepcopy(nb)
22 for cell in nb.cells:
23 # Make sure every cell has a slide_type
24 try:
25 slide_type = cell.metadata.get("slideshow", {}).get("slide_type", "-")
26 except AttributeError:
27 slide_type = "-"
28 cell.metadata.slide_type = slide_type
30 # Find the first visible cell
31 for index, cell in enumerate(nb.cells):
32 if cell.metadata.slide_type not in {"notes", "skip"}:
33 cell.metadata.slide_type = "slide"
34 cell.metadata.slide_start = True
35 cell.metadata.subslide_start = True
36 first_slide_ix = index
37 break
38 else:
39 msg = "All cells are hidden, cannot create slideshow"
40 raise ValueError(msg)
42 in_fragment = False
44 for index, cell in enumerate(nb.cells[first_slide_ix + 1 :], start=(first_slide_ix + 1)):
45 previous_cell = nb.cells[index - 1]
47 # Slides are <section> elements in the HTML, subslides (the vertically
48 # stacked slides) are also <section> elements inside the slides,
49 # and fragments are <div>s within subslides. Subslide and fragment
50 # elements can contain content:
51 # <section>
52 # <section>
53 # (content)
54 # <div class="fragment">(content)</div>
55 # </section>
56 # </section>
58 # Get the slide type. If type is subslide or slide,
59 # end the last slide/subslide/fragment as applicable.
60 if cell.metadata.slide_type == "slide":
61 previous_cell.metadata.slide_end = True
62 cell.metadata.slide_start = True
63 if cell.metadata.slide_type in {"subslide", "slide"}:
64 previous_cell.metadata.fragment_end = in_fragment
65 previous_cell.metadata.subslide_end = True
66 cell.metadata.subslide_start = True
67 in_fragment = False
69 elif cell.metadata.slide_type == "fragment":
70 cell.metadata.fragment_start = True
71 if in_fragment:
72 previous_cell.metadata.fragment_end = True
73 else:
74 in_fragment = True
76 # The last cell will always be the end of a slide
77 nb.cells[-1].metadata.fragment_end = in_fragment
78 nb.cells[-1].metadata.subslide_end = True
79 nb.cells[-1].metadata.slide_end = True
81 return nb, resources
84class SlidesExporter(HTMLExporter):
85 """Exports HTML slides with reveal.js"""
87 # Overrides from HTMLExporter
88 #################################
89 export_from_notebook = "Reveal.js slides"
91 @default("template_name")
92 def _template_name_default(self):
93 return "reveal"
95 @default("file_extension")
96 def _file_extension_default(self):
97 return ".slides.html"
99 @default("template_extension")
100 def _template_extension_default(self):
101 return ".html.j2"
103 # Extra resources
104 #################################
105 reveal_url_prefix = Unicode(
106 help="""The URL prefix for reveal.js (version 3.x).
107 This defaults to the reveal CDN, but can be any url pointing to a copy
108 of reveal.js.
110 For speaker notes to work, this must be a relative path to a local
111 copy of reveal.js: e.g., "reveal.js".
113 If a relative path is given, it must be a subdirectory of the
114 current directory (from which the server is run).
116 See the usage documentation
117 (https://nbconvert.readthedocs.io/en/latest/usage.html#reveal-js-html-slideshow)
118 for more details.
119 """
120 ).tag(config=True)
122 @default("reveal_url_prefix")
123 def _reveal_url_prefix_default(self):
124 if "RevealHelpPreprocessor.url_prefix" in self.config:
125 warn(
126 "Please update RevealHelpPreprocessor.url_prefix to "
127 "SlidesExporter.reveal_url_prefix in config files.",
128 stacklevel=2,
129 )
130 return self.config.RevealHelpPreprocessor.url_prefix
131 return "https://unpkg.com/reveal.js@4.0.2"
133 reveal_theme = Unicode(
134 "simple",
135 help="""
136 Name of the reveal.js theme to use.
138 We look for a file with this name under
139 ``reveal_url_prefix``/css/theme/``reveal_theme``.css.
141 https://github.com/hakimel/reveal.js/tree/master/css/theme has
142 list of themes that ship by default with reveal.js.
143 """,
144 ).tag(config=True)
146 reveal_transition = Unicode(
147 "slide",
148 help="""
149 Name of the reveal.js transition to use.
151 The list of transitions that ships by default with reveal.js are:
152 none, fade, slide, convex, concave and zoom.
153 """,
154 ).tag(config=True)
156 reveal_scroll = Bool(
157 False,
158 help="""
159 If True, enable scrolling within each slide
160 """,
161 ).tag(config=True)
163 reveal_number = Unicode(
164 "",
165 help="""
166 slide number format (e.g. 'c/t'). Choose from:
167 'c': current, 't': total, 'h': horizontal, 'v': vertical
168 """,
169 ).tag(config=True)
171 font_awesome_url = Unicode(
172 "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css",
173 help="""
174 URL to load font awesome from.
176 Defaults to loading from cdnjs.
177 """,
178 ).tag(config=True)
180 def _init_resources(self, resources):
181 resources = super()._init_resources(resources)
182 if "reveal" not in resources:
183 resources["reveal"] = {}
184 resources["reveal"]["url_prefix"] = self.reveal_url_prefix
185 resources["reveal"]["theme"] = self.reveal_theme
186 resources["reveal"]["transition"] = self.reveal_transition
187 resources["reveal"]["scroll"] = self.reveal_scroll
188 resources["reveal"]["number"] = self.reveal_number
189 return resources