17
17
from psc .here import HERE
18
18
from psc .here import PYODIDE
19
19
20
-
21
20
EXCLUSIONS = ("pyscript.css" , "pyscript.js" , "favicon.png" )
22
21
23
22
24
23
def tag_filter (
25
- tag : Tag ,
26
- exclusions : tuple [str , ...] = EXCLUSIONS ,
24
+ tag : Tag ,
25
+ exclusions : tuple [str , ...] = EXCLUSIONS ,
27
26
) -> bool :
28
27
"""Filter nodes from example that should not get included."""
29
28
attr = "href" if tag .name == "link" else "src"
@@ -81,6 +80,27 @@ class Resource:
81
80
extra_head : str = ""
82
81
83
82
83
+ linked_file_mapping = dict (
84
+ py = "python" ,
85
+ css = "css" ,
86
+ html = "html"
87
+ )
88
+
89
+
90
+ @dataclass
91
+ class LinkedFile :
92
+ """A source file on disk that gets attached to an example."""
93
+
94
+ path : Path
95
+ language : str = field (init = False )
96
+ body : str = field (init = False )
97
+
98
+ def __post_init__ (self ) -> None :
99
+ """Read the file contents into the body."""
100
+ self .language = linked_file_mapping [self .path .suffix [1 :]]
101
+ self .body = self .path .read_text ()
102
+
103
+
84
104
@dataclass
85
105
class Example (Resource ):
86
106
"""Create an example from an HTML location on disk.
@@ -91,9 +111,10 @@ class Example(Resource):
91
111
Meaning, HERE / "examples" / name / "index.html".
92
112
"""
93
113
94
- subtitle : str = ""
95
- description : str = ""
96
- author : str | None = None
114
+ subtitle : str = field (init = False )
115
+ description : str = field (init = False )
116
+ author : str = field (init = False )
117
+ linked_files : list [LinkedFile ] = field (default_factory = list )
97
118
98
119
def __post_init__ (self ) -> None :
99
120
"""Extract most of the data from the HTML file."""
@@ -107,13 +128,22 @@ def __post_init__(self) -> None:
107
128
self .description = str (md .render (md_fm .content ))
108
129
109
130
# Main, extra head example's HTML file.
110
- index_html_file = HERE / "gallery/examples" / self .name / "index.html"
131
+ this_example_path = HERE / "gallery/examples" / self .name
132
+ index_html_file = this_example_path / "index.html"
111
133
if not index_html_file .exists (): # pragma: nocover
112
134
raise ValueError (f"No example at { self .name } " )
113
- soup = BeautifulSoup (index_html_file .read_text (), "html5lib" )
135
+ index_html_text = index_html_file .read_text ()
136
+ soup = BeautifulSoup (index_html_text , "html5lib" )
114
137
self .extra_head = get_head_nodes (soup )
115
138
self .body = get_body_content (soup )
116
139
140
+ # Process any linked files
141
+ linked_paths = [* ["index.html" ], * md_fm .get ("linked_files" , [])]
142
+ for linked_name in linked_paths :
143
+ linked_path = this_example_path / linked_name
144
+ linked_file = LinkedFile (path = linked_path )
145
+ self .linked_files .append (linked_file )
146
+
117
147
118
148
@dataclass
119
149
class Author (Resource ):
0 commit comments