-
-
Notifications
You must be signed in to change notification settings - Fork 324
/
Copy pathwidget_example.py
118 lines (93 loc) · 2.91 KB
/
widget_example.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from pathlib import Path
from sphinx.application import Sphinx
from docutils.parsers.rst import Directive, directives
from docutils.statemachine import StringList
from sphinx_panels.tabs import TabbedDirective
here = Path(__file__).parent
examples = here.parent / "examples"
class WidgetExample(Directive):
has_content = False
required_arguments = 1
_next_id = 0
option_spec = {"linenos": directives.flag}
def run(self):
example_name = self.arguments[0]
show_linenos = "linenos" in self.options
py_ex_path = examples / f"{example_name}.py"
if not py_ex_path.exists():
raise ValueError(f"No example file named {py_ex_path}")
py_code_tab = TabbedDirective(
"WidgetExample",
["Python Code"],
{},
_literal_include_py_lines(
name=example_name,
linenos=show_linenos,
),
self.lineno - 1,
self.content_offset,
"",
self.state,
self.state_machine,
).run()
if (examples / f"{example_name}.js").exists():
js_code_tab = TabbedDirective(
"WidgetExample",
["Javascript Code"],
{},
_literal_include_js_lines(
name=example_name,
linenos=show_linenos,
),
self.lineno - 1,
self.content_offset,
"",
self.state,
self.state_machine,
).run()
else:
js_code_tab = []
example_tab = TabbedDirective(
"WidgetExample",
["Live Example"],
{},
_string_to_nested_lines(
_interactive_widget_template.format(name=example_name)
),
self.lineno - 1,
self.content_offset,
"",
self.state,
self.state_machine,
).run()
return py_code_tab + js_code_tab + example_tab
def _literal_include_py_lines(name, linenos):
return _string_to_nested_lines(
_literal_include_template.format(
name=name,
ext="py",
language="python",
linenos=":linenos:" if linenos else "",
)
)
def _literal_include_js_lines(name, linenos):
return _string_to_nested_lines(
_literal_include_template.format(
name=name,
ext="js",
language="javascript",
linenos=":linenos:" if linenos else "",
)
)
_interactive_widget_template = """
.. interactive-widget:: {name}
"""
_literal_include_template = """
.. literalinclude:: /examples/{name}.{ext}
:language: {language}
{linenos}
"""
def _string_to_nested_lines(content):
return StringList(content.split("\n"))
def setup(app: Sphinx) -> None:
app.add_directive("example", WidgetExample)