-
Notifications
You must be signed in to change notification settings - Fork 511
/
Copy pathstoutput.py
86 lines (66 loc) · 2.26 KB
/
stoutput.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
"""RST directive to insert an iframe into a doc.
"""
from docutils import nodes
from docutils.parsers.rst import Directive
import re
class StOutput(Directive):
"""Convert the ".. output" directive into a <Cloud> component.
The ".. output::" directive looks like this:
.. output::
URL
STYLE
And it outputs something like:
<Cloud name="SUBDOMAIN" path="SUBPATH" query="QUERYPARAMS" stylePlaceholder="STYLE" />
...where every attribute is guaranteed to be present (even when empty) and there's always
exactly one space before/after each attribute.
Parameters
----------
URL
The full path of the Streamlit app to embed, including protocol.
STYLE (optional)
A string of inline styles.
Examples
--------
.. output::
https://foo.bar.baz
<Cloud name="foo" path="" query="" stylePlaceholder="" />
.. output::
https://foo.bar.baz/bleep/bloop?plim=plom
height: 5rem; border: 1px solid red;
<Cloud name="foo" path="bleep/bloop" query="plim=plom" stylePlaceholder="height: 5rem; border: 1px solid red;" />
"""
has_content = True
required_arguments = 1
optional_arguments = 1
final_argument_whitespace = True
def run(self):
src = self.arguments[0]
if not src.startswith("https://"):
raise ValueError(
f"Please use HTTPS in '.. output::' directives\n--> Culprit: {src}"
)
if len(self.arguments) > 1:
additional_styles = self.arguments[1]
else:
additional_styles = ""
name, path, query = re.findall(
r'https:\/\/([^\/\s]+)\.streamlit\.app\/?([^?\s]+)?\??([\S]+)?', src)[0]
if name=="":
raise ValueError(
f"Custom subdomain was not recognized.\n--> Culprit: {src}"
)
component = (
'<Cloud'
f' name="{name}"'
f' path="{path}"'
f' query="{query}"'
f' stylePlaceholder="{additional_styles}"'
' />')
node = nodes.raw(
format="html",
text=component,
rawsource=component
)
return [node]
def setup(app):
app.add_directive("output", StOutput)