Coverage for pyquickhelper/sphinxext/revealjs/directives.py: 100%
152 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
1# -*- coding: utf-8 -*-
2"""
3 sphinxjp.themes.revealjs.directives
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 :author: tell-k <ffk2005@gmail.com>
7 :copyright: tell-k. All Rights Reserved.
8"""
9from docutils import nodes
10from docutils.parsers.rst import directives
11from docutils.parsers.rst.roles import set_classes
12from docutils.parsers.rst import Directive
13from . import compat
15__docformat__ = 'reStructuredText'
18class revealjs(nodes.General, nodes.Element):
19 """ node for revealjs """
22class rv_code(nodes.General, nodes.Element):
23 """ node for revealjs code section """
26class rv_small(nodes.General, nodes.Element):
27 """ node for revealjs small text section """
30class rv_note(nodes.General, nodes.Element):
31 """ node for revealjs presentation note """
34def heading(argument):
35 """ directives choices for heading tag """
36 return directives.choice(argument, ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))
39class RevealjsDirective(Directive):
40 """ Reveal.JS slide entry """
42 has_content = True
43 required_arguments = 0
44 optional_arguments = 100
45 final_argument_whitespace = False
47 option_spec = {
48 'id': directives.unchanged,
49 'class': directives.class_option,
50 'noheading': directives.flag,
51 'title-heading': heading,
52 'subtitle': directives.unchanged,
53 'subtitle-heading': directives.unchanged,
54 'data-autoslide': directives.unchanged,
55 'data-markdown': directives.unchanged,
56 'data-transition': directives.unchanged,
57 'data-transition-speed': directives.unchanged,
58 'data-background': directives.unchanged,
59 'data-background-repeat': directives.unchanged,
60 'data-background-size': directives.unchanged,
61 'data-background-transition': directives.unchanged,
62 'data-state': directives.unchanged,
63 'data-separator': directives.unchanged,
64 'data-separator-vertical': directives.unchanged,
65 'data-separator-notes': directives.unchanged,
66 'data-charset': directives.unchanged,
67 }
69 node_class = revealjs
71 def run(self):
72 """ build revealjs node """
74 set_classes(self.options)
76 text = '\n'.join(self.content)
77 node = self.node_class(text, **self.options)
79 self.add_name(node)
81 if "data-markdown" not in self.options:
82 self.state.nested_parse(self.content, self.content_offset, node)
84 if self.arguments:
85 node['title'] = " ".join(self.arguments)
87 node['noheading'] = ('noheading' in self.options)
89 options_list = (
90 'id',
91 'title-heading',
92 'subtitle-heading',
93 'data-autoslide',
94 'data-transition',
95 'data-transition-speed',
96 'data-background',
97 'data-background-repeat',
98 'data-background-size',
99 'data-background-transition',
100 'data-state',
101 'data-markdown',
102 'data-separator',
103 'data-separator-vertical',
104 'data-separator-notes',
105 'data-charset',
106 )
107 for option in options_list:
108 if option in self.options:
109 node[option] = self.options.get(option)
110 return [node]
113class RvSmallDirective(Directive):
114 """
115 Create small text tag.
116 """
117 has_content = True
118 required_arguments = 0
119 optional_arguments = 0
120 final_argument_whitespace = False
122 option_spec = {
123 'class': directives.class_option,
124 }
125 node_class = rv_small
127 def run(self):
128 """ build rv_small node """
130 set_classes(self.options)
131 self.assert_has_content()
132 text = '\n'.join(self.content)
133 node = self.node_class(text, **self.options)
134 self.add_name(node)
135 self.state.nested_parse(self.content, self.content_offset, node)
136 return [node]
139class RvNoteDirective(Directive):
140 """
141 Directive for a notes tag.
142 """
143 has_content = True
144 required_arguments = 0
145 optional_arguments = 0
146 final_argument_whitespace = False
148 option_spec = {
149 'class': directives.class_option,
150 }
151 node_class = rv_note
153 def run(self):
154 """ build rv_note node """
155 set_classes(self.options)
156 self.assert_has_content()
157 text = '\n'.join(self.content)
158 node = self.node_class(text, **self.options)
159 self.add_name(node)
160 self.state.nested_parse(self.content, self.content_offset, node)
161 return [node]
164class RvCodeDirective(Directive):
165 """
166 Directive for a code block with highlight.js
167 """
169 has_content = True
170 required_arguments = 0
171 optional_arguments = 0
172 final_argument_whitespace = False
173 option_spec = {
174 'id': directives.unchanged,
175 'class': directives.class_option,
176 }
177 node_class = rv_code
179 def run(self):
180 """ build rv_code node """
181 set_classes(self.options)
182 self.assert_has_content()
183 node = self.node_class('\n'.join(self.content), **self.options)
184 return [node]
187def visit_revealjs(self, node):
188 """ build start tag for revealjs """
189 section_attr = {}
190 markdown_headings = {"h1": "#", "h2": "##", "h3": "###",
191 "h4": "####", "h5": "#####", "h6": "######"}
193 if node.get("id"):
194 section_attr.update({"ids": [node.get("id")]})
196 attr_list = (
197 'data-autoslide',
198 'data-transition',
199 'data-transition-speed',
200 'data-background',
201 'data-background-repeat',
202 'data-background-size',
203 'data-background-transition',
204 'data-state',
205 'data-markdown',
206 'data-separator',
207 'data-separator-vertical',
208 'data-separator-notes',
209 'data-charset',
210 )
211 for attr in attr_list:
212 if node.get(attr) is not None:
213 section_attr.update({attr: node.get(attr)})
215 title = None
216 if node.get("title") and not node.get('noheading'):
217 title = node.get("title")
219 title_heading = node.get('title-heading', 'h2')
220 subtitle = node.get("subtitle")
221 subtitle_heading = node.get('subtitle-heading', 'h3')
222 if node.get("data-markdown") is not None:
224 title_base = compat.text("%(heading)s %(title)s \n")
225 title_text = None
226 if title:
227 title_text = title_base % dict(
228 heading=markdown_headings.get(title_heading),
229 title=title
230 )
232 subtitle_text = None
233 if subtitle:
234 subtitle_text = title_base % dict(
235 heading=markdown_headings.get(subtitle_heading),
236 title=subtitle
237 )
238 else:
239 title_base = compat.text("<%(heading)s>%(title)s</%(heading)s>\n")
240 title_text = None
241 if title:
242 title_text = title_base % dict(
243 title=title,
244 heading=title_heading)
246 subtitle_text = None
247 if subtitle:
248 subtitle_text = title_base % dict(
249 title=subtitle,
250 heading=subtitle_heading)
252 if node.get("data-markdown") is not None:
253 self.body.append(self.starttag(node, 'section', **section_attr))
254 if node.get("data-markdown") == compat.text(""):
255 self.body.append("<script type='text/template'>\n")
256 if title_text:
257 self.body.append(title_text)
258 if subtitle_text:
259 self.body.append(subtitle_text)
260 self.body.append(node.rawsource)
261 self.body.append("</script>\n")
262 else:
263 self.body.append(self.starttag(node, 'section', **section_attr))
264 if title_text:
265 self.body.append(title_text)
266 if subtitle_text:
267 self.body.append(subtitle_text)
268 self.set_first_last(node)
271def depart_revealjs(self, node=None):
272 """ build end tag for revealjs """
273 self.body.append('</section>\n')
276def visit_rv_code(self, node):
277 """ build start tag for rv_code """
279 self.body.append(self.starttag(node, 'pre'))
280 self.body.append("<code data-trim contenteditable>")
281 self.body.append(compat.escape_html(node.rawsource))
284def depart_rv_code(self, node=None):
285 """ build end tag for rv_code """
287 self.body.append("</code>")
288 self.body.append("</pre>\n")
291def visit_rv_small(self, node):
292 """ build start tag for rv_small """
293 self.body.append(self.starttag(node, 'small'))
294 self.set_first_last(node)
297def depart_rv_small(self, node=None):
298 """ build end tag for rv_small"""
299 self.body.append("</small>\n")
302def visit_rv_note(self, node):
303 """ build start tag for rv_note """
304 self.body.append(self.starttag(node, 'aside', **{'class': 'notes'}))
305 self.set_first_last(node)
308def depart_rv_note(self, node=None):
309 """ build end tag for rv_note """
310 self.body.append("</aside>\n")
313def setup(app):
314 """Initialize """
315 app.add_node(revealjs, html=(visit_revealjs, depart_revealjs))
316 app.add_node(rv_code, html=(visit_rv_code, depart_rv_code))
317 app.add_node(rv_note, html=(visit_rv_note, depart_rv_note))
318 app.add_node(rv_small, html=(visit_rv_small, depart_rv_small))
319 app.add_directive('revealjs', RevealjsDirective)
320 app.add_directive('rv_code', RvCodeDirective)
321 app.add_directive('rv_note', RvNoteDirective)
322 app.add_directive('rv_small', RvSmallDirective)
323 return app