rst2revealjs 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
rst2revealjs/cli.py ADDED
@@ -0,0 +1,10 @@
1
+ """CLI Entrypoint."""
2
+
3
+ from docutils.core import publish_cmdline
4
+
5
+ from .reader import RevealjsReader
6
+ from .writer import RevealjsWriter
7
+
8
+
9
+ def main():
10
+ publish_cmdline(reader=RevealjsReader(), writer=RevealjsWriter())
rst2revealjs/engine.py ADDED
@@ -0,0 +1,58 @@
1
+ """Revealjs.js handler."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import asdict, dataclass
6
+
7
+ from jinja2 import Template
8
+
9
+ DEFAULT_VERSION = "5.2.1"
10
+
11
+ DEFAULT_INIT_SCRIPT = """
12
+ {% for name, url in imports|items -%}
13
+ import {{name}} from "{{url}}";
14
+ {% endfor %}
15
+
16
+ let deck = new Reveal({{arguments}});
17
+ deck.initialize();
18
+ """
19
+
20
+
21
+ @dataclass
22
+ class RevealjsEngine:
23
+ styles: list[str]
24
+ imports: dict[str, str]
25
+ arguments: str = ""
26
+
27
+ def build_stylesheet(self) -> list[str]:
28
+ return [f'<link rel="stylesheet" href="{url}">' for url in self.styles]
29
+
30
+ def build_script(self) -> str:
31
+ tmpl = Template(DEFAULT_INIT_SCRIPT)
32
+ return f"""
33
+ <script type="module">
34
+ {tmpl.render(**asdict(self))}
35
+ </script>
36
+ """
37
+
38
+ @classmethod
39
+ def from_cdn(
40
+ cls, version: str, theme: str = "black", code_theme: str = "monokai"
41
+ ) -> RevealjsEngine:
42
+ styles = [
43
+ f"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/{version}/reveal.min.css",
44
+ f"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/{version}/theme/{theme}.min.css",
45
+ f"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/{code_theme}.min.css",
46
+ ]
47
+ imports = {
48
+ "Reveal": f"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/{version}/reveal.esm.min.js",
49
+ "RevealHighlight": f"https://cdnjs.cloudflare.com/ajax/libs/reveal.js/{version}/plugin/highlight/highlight.esm.min.js",
50
+ }
51
+ arguments = """
52
+ {plugins: [RevealHighlight]}
53
+ """
54
+ return cls(
55
+ styles=styles,
56
+ imports=imports,
57
+ arguments=arguments,
58
+ )
rst2revealjs/nodes.py ADDED
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TypedDict
4
+
5
+ from docutils import nodes
6
+
7
+ from .engine import RevealjsEngine
8
+
9
+
10
+ class revealjs_deck(nodes.General, nodes.Element):
11
+ class Attributes(TypedDict):
12
+ engine: RevealjsEngine
13
+
14
+ attributes: Attributes
rst2revealjs/py.typed ADDED
File without changes
rst2revealjs/reader.py ADDED
@@ -0,0 +1,39 @@
1
+ from docutils.readers.standalone import Reader
2
+
3
+ from . import transforms
4
+ from .engine import DEFAULT_VERSION
5
+
6
+
7
+ class RevealjsReader(Reader):
8
+ settings_spec = Reader.settings_spec + (
9
+ "Reveal.js Support Options",
10
+ None,
11
+ (
12
+ (
13
+ "Using version of Reveal.js (set latest by default).",
14
+ ["--revealjs-version"],
15
+ {"dest": "revealjs_version", "default": DEFAULT_VERSION},
16
+ ),
17
+ (
18
+ "Reveal.js theme",
19
+ ["--revealjs-theme"],
20
+ {"dest": "revealjs_theme", "default": "black"},
21
+ ),
22
+ (
23
+ "Highlight.js theme used in code highlighting.",
24
+ ["--highlightjs-theme"],
25
+ {"dest": "highlightjs_theme", "default": "monokai"},
26
+ ),
27
+ ),
28
+ )
29
+
30
+ def read(self, source, parser, settings):
31
+ settings.doctitle_xform = False # To force setting
32
+ return super().read(source, parser, settings)
33
+
34
+ def get_transforms(self):
35
+ return super().get_transforms() + [
36
+ transforms.RevealjsSectionizeTransform,
37
+ transforms.RevealjsEngineTransform,
38
+ transforms.TitleTransform,
39
+ ]
@@ -0,0 +1,76 @@
1
+ from docutils import nodes
2
+ from docutils.transforms import Transform
3
+
4
+ from .engine import RevealjsEngine
5
+ from .nodes import revealjs_deck
6
+
7
+
8
+ class RevealjsEngineTransform(Transform):
9
+ """docutils transform to bind Reveal.js engine object."""
10
+
11
+ default_priority = 250
12
+
13
+ def apply(self, **kwargs):
14
+ settings = self.document.settings
15
+ data = {
16
+ "version": settings.revealjs_version,
17
+ "theme": settings.revealjs_theme,
18
+ "code_theme": settings.highlightjs_theme,
19
+ }
20
+ engine = RevealjsEngine.from_cdn(**data)
21
+ node = revealjs_deck(engine=engine)
22
+ self.document.append(node)
23
+
24
+
25
+ class RevealjsSectionizeTransform(Transform):
26
+ """docutils transform to Reveal.js style section structure."""
27
+
28
+ default_priority = 350
29
+
30
+ def apply(self, **kwargs):
31
+ decks = list(self.document.findall(revealjs_deck))
32
+ if not decks or len(decks) > 1:
33
+ raise ValueError("Required only one <revealjs_deck> element to apply it.")
34
+ deck = decks[0]
35
+ deck.parent.remove(deck)
36
+
37
+ def _rebuild(root: nodes.section):
38
+ new_root = nodes.section()
39
+ sub_sections = []
40
+ for child in list(root.findall(nodes.section, include_self=False)):
41
+ if child.parent == root:
42
+ child["revealjs_section_level"] = 3
43
+ root.remove(child)
44
+ sub_sections.append(child)
45
+ new_root.children = [root] + sub_sections
46
+ return new_root
47
+
48
+ idx = self.document.first_child_matching_class(nodes.section)
49
+ if idx is None:
50
+ raise ValueError("Invalid document for revealjs")
51
+ sections = [self.document[idx]]
52
+ sections[0]["revealjs_section_level"] = 1
53
+ for node in self.document.children[:idx]:
54
+ self.document.remove(node)
55
+ sections[0].insert(0, node)
56
+ self.document.remove(sections[0])
57
+ for node in list(sections[0].findall(nodes.section, include_self=False)):
58
+ if node.parent == sections[0]:
59
+ node["revealjs_section_level"] = 2
60
+ sections[0].remove(node)
61
+ sections.append(node)
62
+ for vertical in sections:
63
+ deck.append(_rebuild(vertical))
64
+
65
+ self.document.children = [deck] + self.document.children
66
+
67
+
68
+ class TitleTransform(Transform):
69
+ default_priority = 351
70
+
71
+ def apply(self, **kwargs):
72
+ for node in self.document.findall(nodes.title):
73
+ self.document["title"] = node.astext()
74
+ break
75
+ else:
76
+ raise ValueError("Title is not found.")
rst2revealjs/writer.py ADDED
@@ -0,0 +1,98 @@
1
+ """Writer for docutils."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ from docutils import nodes
8
+ from docutils.writers import html5_polyglot as base_writer
9
+
10
+ from .nodes import revealjs_deck
11
+
12
+
13
+ class RevealjsTranslator(base_writer.HTMLTranslator):
14
+ """Custom translator to render body that is Reveal.js presentation.
15
+
16
+ It requires having nested section in doctree.
17
+ We recommend to override settings that ``doctitle_xform`` is ``False``
18
+ when source is simple content.
19
+ """
20
+
21
+ documenttag_args = {"tagname": "main", "class": "reveal"}
22
+
23
+ def visit_section(self, node: nodes.section):
24
+ if "revealjs_section_level" in node:
25
+ self.section_level = node["revealjs_section_level"]
26
+ super().visit_section(node)
27
+
28
+ def visit_literal_block(self, node: nodes.Element):
29
+ """Begin ``literal_block`` .
30
+
31
+ Override base method to open ``pre`` and ``code`` tags simply.
32
+
33
+ :ref: https://github.com/attakei/sphinx-revealjs/blob/master/sphinx_revealjs/writers.py
34
+ """
35
+
36
+ def _starttag(tagname: str, suffix: str = "\n", **attributes):
37
+ """Build start tag to avoide override classes."""
38
+ text = [f"<{tagname}"]
39
+ for key, value in attributes.items():
40
+ if value is None:
41
+ text.append(key.lower())
42
+ else:
43
+ text.append(f'{key}="{value}"')
44
+ text[-1] += f">{suffix}"
45
+ return " ".join(text)
46
+
47
+ # Detect language
48
+ if len(node["classes"]) < 2:
49
+ return super().visit_literal_block(node)
50
+ lang = node["classes"][1]
51
+ # Build <pre> tag
52
+ attrs_pre = {}
53
+ if "data-id" in node:
54
+ attrs_pre["data-id"] = node["data-id"]
55
+ elif isinstance(node.parent, nodes.section) and len(node.parent["ids"]):
56
+ attrs_pre["data-id"] = node.parent["ids"][0]
57
+ self.body.append(_starttag("pre", **attrs_pre))
58
+ # Build <code> tag
59
+ attrs_code = {
60
+ "class": f"language-{lang}",
61
+ "data-trim": None,
62
+ "data-noescape": None,
63
+ }
64
+ if "data-line-numbers" in node:
65
+ attrs_code["data-line-numbers"] = node["data-line-numbers"]
66
+ elif "linenos" in node:
67
+ attrs_code["data-line-numbers"] = "data-line-numbers"
68
+ if "data-ln-start-from" in node:
69
+ attrs_code["data-ln-start-from"] = node["data-ln-start-from"]
70
+ if "data-line-numbers" not in attrs_code:
71
+ attrs_code["data-line-numbers"] = "data-line-numbers"
72
+ self.body.append(_starttag("code", suffix="", **attrs_code))
73
+ # Write code content and close tags.
74
+ self.body.append(node.astext())
75
+ self.body.append("</code></pre>\n")
76
+ # It doesn't walk children, because code content has already been appended.
77
+ raise nodes.SkipNode
78
+
79
+ def visit_revealjs_deck(self, node: revealjs_deck):
80
+ self.body.append(self.starttag(node, "div", CLASS="slides"))
81
+
82
+ def depart_revealjs_deck(self, node: revealjs_deck):
83
+ engine = node.attributes["engine"]
84
+ self.stylesheet = engine.build_stylesheet()
85
+ self.body.append("</div>")
86
+ self.body.append(engine.build_script())
87
+
88
+
89
+ class RevealjsWriter(base_writer.Writer):
90
+ default_template = Path(__file__).parent / "template.txt"
91
+
92
+ def __init__(self):
93
+ super().__init__()
94
+ self.translator_class = RevealjsTranslator
95
+
96
+ def write(self, document, destination):
97
+ document.settings.initial_header_level = 0 # To force setting
98
+ return super().write(document, destination)
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.3
2
+ Name: rst2revealjs
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author: Kazuya Takei
6
+ Author-email: Kazuya Takei <myself@attakei.net>
7
+ Requires-Dist: docutils>=0.21.2
8
+ Requires-Dist: jinja2>=3.1.6
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/x-rst
11
+
12
+ ============
13
+ rst2revealjs
14
+ ============
15
+
16
+ Simple converter from docutils AST to Reveal.js presentation.
17
+
18
+ Overview
19
+ ========
20
+
21
+ This is docutils adapter to write Reveal.js presentation by reStructuredText and other formats.
22
+ You can write presentation by plain text using many expression of reStructuredText.
23
+
24
+ Usage
25
+ =====
26
+
27
+ .. warning:: This section is included plan and it is not availabled yet.
28
+
29
+ .. code:: console
30
+
31
+ pip install rst2revealjs
32
+
33
+ .. code:: rst
34
+
35
+ Title
36
+ =====
37
+
38
+ Section 1
39
+ =========
40
+
41
+ Section 1-1
42
+ -----------
43
+
44
+ .. code:: console
45
+
46
+ rst2revealjs presentation.rst
47
+
48
+ You can see `presentation.html` by your browser.
49
+
50
+ Features
51
+ ========
52
+
53
+ This provides some features to realize overview.
54
+
55
+ * Custom directives for specify behaviors about Reveal.js.
56
+ * Writer to generate HTML file using Reveal.js presentation.
57
+
58
+ Motivation
59
+ ==========
60
+
61
+ This is re-implement from core features of sphinx-revealjs.
62
+ Because I want to write Reveal.js presentation on Web front-end using Pyodide. [#]_
63
+
64
+ As first goal, I will provide playground website to convert from reStructuredText to presentation using this.
65
+
66
+ License
67
+ =======
68
+
69
+ Apache-2.0 license. Please see LICENSE on repository.
70
+
71
+ .. rubric:: Footnotes
72
+
73
+ .. [#] docutils is registered on Pyodided built-in packages, but Sphinx is not registered.
@@ -0,0 +1,12 @@
1
+ rst2revealjs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ rst2revealjs/cli.py,sha256=HChh5TOYmf-B33Sokhv_IOP-uxl9vjUMeSyutyGYjG8,220
3
+ rst2revealjs/engine.py,sha256=LepabBNOedOi2lMxlCTKlfQ8MRUNwhYQ0BY0GDYWcV4,1684
4
+ rst2revealjs/nodes.py,sha256=eMacHzQc5Q6Zl_hWi9V253vd50O-nOpsplDwydFX7xc,274
5
+ rst2revealjs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ rst2revealjs/reader.py,sha256=_0SX-1eoU1CxuTJr1UfbeVN8lfOnJm-odjaDhBAF2S0,1233
7
+ rst2revealjs/transforms.py,sha256=mZpebJvUOj3ZqVAiLcCDFYUdhDhOD1QA_nJcTkc0V5U,2629
8
+ rst2revealjs/writer.py,sha256=VJU9px68afrXfFA8zbrReQtXeD4mL91ASNRHDP7EEbo,3625
9
+ rst2revealjs-0.1.0.dist-info/WHEEL,sha256=eycQt0QpYmJMLKpE3X9iDk8R04v2ZF0x82ogq-zP6bQ,79
10
+ rst2revealjs-0.1.0.dist-info/entry_points.txt,sha256=WDWR2xbO5la36gT_FFYwU9qeL-RuLxX3NNai9vxSdcA,56
11
+ rst2revealjs-0.1.0.dist-info/METADATA,sha256=bzWZYQeeLSeB_gYRa4p1GWVCO8kge_OQJmoH3m-oFs0,1571
12
+ rst2revealjs-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.24
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ rst2revealjs = rst2revealjs.cli:main
3
+