11diff --git a/asciinema.py b/asciinema.py
2- index 8644220..44dad26 100644
2+ index 8644220..0b73d80 100644
33--- a/asciinema.py
44+++ b/asciinema.py
55@@ -2,20 +2,20 @@ import os
6-
6+
77 from docutils import nodes
88 from docutils.parsers.rst import directives
99- from sphinx.util.fileutil import copy_asset
1010- from sphinx.util.docutils import SphinxDirective
1111 from sphinx.util import logging
1212+ from sphinx.util.docutils import SphinxDirective
1313+ from sphinx.util.fileutil import copy_asset
14-
14+
1515 logger = logging.getLogger(__name__)
16-
17-
16+
17+
1818 def copy_asset_files(app, exc):
1919- asset_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
2020- '_static')
@@ -26,56 +26,34 @@ index 8644220..44dad26 100644
2626+ copy_asset(
2727+ os.path.join(asset_dir, file), os.path.join(app.outdir, "_static")
2828+ )
29-
30-
29+
30+
3131 class Asciinema(nodes.General, nodes.Element):
32- @@ -24,22 +24,37 @@ class Asciinema(nodes.General, nodes.Element):
33-
34- def visit_html(self, node):
35- rst_to_js_option_names: dict[str, str] = {
36- + "autoplay": "autoPlay",
37- + "idle-time-limit": "idleTimeLimit",
38- "terminalfontsize": "terminalFontSize",
39- - "terminallineheigth": "terminalLineHeigth",
40- + "terminallineheight": "terminalLineHeight",
41- "terminalfontfamily": "terminalFontFamily",
32+ @@ -30,16 +30,17 @@ def visit_html(self, node):
4233 "audiourl": "audioUrl",
4334 }
44-
35+
4536- options_raw = ['markers']
46- -
37+ + options_raw = ["markers"]
38+
4739- gen = ((rst_option_name, js_option_name)
4840- for (rst_option_name,
4941- js_option_name) in rst_to_js_option_names.items()
5042- if rst_option_name in node["options"])
51- + options_raw = [
52- + "markers",
53- + "loop",
54- + "autoPlay",
55- + "preload",
56- + "pauseOnMarkers",
57- + "cols",
58- + "rows",
59- + "speed",
60- + ]
61- +
62- + for option, value in node["options"].items():
63- + node["options"][option] = ASCIINemaDirective.option_spec[option](value)
64- +
6543+ gen = (
6644+ (rst_option_name, js_option_name)
6745+ for (rst_option_name, js_option_name) in rst_to_js_option_names.items()
6846+ if rst_option_name in node["options"]
6947+ )
7048 for rst_option_name, js_option_name in gen:
7149 node["options"][js_option_name] = node["options"].pop(rst_option_name)
72-
50+
7351- if node['type'] == 'local':
7452+ if node["type"] == "local":
7553 template = """<div id="asciicast-{id}"></div>
7654 <script>
7755 document.addEventListener("DOMContentLoaded", function() {{
78- @@ -50,7 +65 ,7 @@ def visit_html(self, node):
56+ @@ -50,7 +51 ,7 @@ def visit_html(self, node):
7957 }});
8058 </script>"""
8159 option_template = '{}: "{}", '
@@ -84,7 +62,7 @@ index 8644220..44dad26 100644
8462 else:
8563 template = """<script async id="asciicast-{src}" {options}
8664 src="https://asciinema.org/a/{src}.js"></script>"""
87- @@ -58,14 +73 ,17 @@ def visit_html(self, node):
65+ @@ -58,14 +59 ,17 @@ def visit_html(self, node):
8866 option_template_raw = 'data-{}="{}" '
8967 options = ""
9068 for n, v in node["options"].items():
@@ -97,64 +75,16 @@ index 8644220..44dad26 100644
9775+ )
9876 tag = template.format(options=options, src=node["content"], id=node["id"])
9977 self.body.append(tag)
100-
101-
78+
79+
10280 def visit_unsupported(self, node):
10381- logger.warning('asciinema: unsupported output format (node skipped)')
10482+ logger.warning("asciinema: unsupported output format (node skipped)")
10583 raise nodes.SkipNode
106-
107-
108- @@ -73,15 +91,35 @@ def depart(self, node):
109- pass
110-
111-
112- + def bool_parse(argument):
113- + """Parse the option as boolean."""
114- + if argument is None:
115- + raise ValueError("Boolean option must have a value")
116- +
117- + val = str(argument).strip().lower()
118- +
119- + if val in ("true", "false"):
120- + return val
121- + raise ValueError("Must be boolean; True or False")
122- +
123- +
124- + def bool_or_positive_int(argument):
125- + """Parse the option as boolean or positive integer."""
126- + try:
127- + return bool_parse(argument)
128- + except ValueError:
129- + return directives.positive_int(argument)
130- +
131- +
132- class ASCIINemaDirective(SphinxDirective):
133- has_content = True
134- final_argument_whitespace = False
135- option_spec = {
136- "cols": directives.positive_int,
137- "rows": directives.positive_int,
138- - "autoplay": directives.unchanged,
139- - "preload": directives.unchanged,
140- - "loop": directives.unchanged,
141- + "autoplay": bool_parse,
142- + "preload": bool_parse,
143- + "loop": bool_or_positive_int,
144- "start-at": directives.unchanged,
145- "speed": directives.unchanged,
146- "idle-time-limit": directives.unchanged,
147- @@ -90,7 +128,7 @@ class ASCIINemaDirective(SphinxDirective):
148- "fit": directives.unchanged,
149- "controls": directives.unchanged,
150- "markers": directives.unchanged,
151- - "pauseOnMarkers": directives.unchanged,
152- + "pauseOnMarkers": bool_parse,
153- "terminalfontsize": directives.unchanged,
154- "terminalfontfamily": directives.unchanged,
155- "terminallineheight": directives.unchanged,
156- @@ -102,25 +140,25 @@ class ASCIINemaDirective(SphinxDirective):
157-
84+
85+
86+ @@ -102,25 +106,25 @@ class ASCIINemaDirective(SphinxDirective):
87+
15888 def run(self):
15989 arg = self.arguments[0]
16090- options = dict(self.env.config['sphinxcontrib_asciinema_defaults'])
@@ -193,10 +123,10 @@ index 8644220..44dad26 100644
193123+ if "path" in kw["options"]:
194124+ del kw["options"]["path"]
195125 return [Asciinema(**kw)]
196-
126+
197127 def is_file(self, rel_file):
198- @@ -129,17 +167 ,18 @@ class ASCIINemaDirective(SphinxDirective):
199-
128+ @@ -129,17 +133 ,18 @@ class ASCIINemaDirective(SphinxDirective):
129+
200130 def to_b64(self, filename):
201131 import base64
202132+
@@ -206,8 +136,8 @@ index 8644220..44dad26 100644
206136 content = file.read()
207137 b64encoded = base64.b64encode(content)
208138 return b64encoded.decode()
209-
210-
139+
140+
211141 _NODE_VISITORS = {
212142- 'html': (visit_html, depart),
213143- 'latex': (visit_unsupported, None),
0 commit comments