1717from psc .here import HERE
1818from psc .here import PYODIDE
1919
20-
2120EXCLUSIONS = ("pyscript.css" , "pyscript.js" , "favicon.png" )
2221
2322
2423def tag_filter (
25- tag : Tag ,
26- exclusions : tuple [str , ...] = EXCLUSIONS ,
24+ tag : Tag ,
25+ exclusions : tuple [str , ...] = EXCLUSIONS ,
2726) -> bool :
2827 """Filter nodes from example that should not get included."""
2928 attr = "href" if tag .name == "link" else "src"
@@ -81,6 +80,27 @@ class Resource:
8180 extra_head : str = ""
8281
8382
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+
84104@dataclass
85105class Example (Resource ):
86106 """Create an example from an HTML location on disk.
@@ -91,9 +111,10 @@ class Example(Resource):
91111 Meaning, HERE / "examples" / name / "index.html".
92112 """
93113
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 )
97118
98119 def __post_init__ (self ) -> None :
99120 """Extract most of the data from the HTML file."""
@@ -107,13 +128,22 @@ def __post_init__(self) -> None:
107128 self .description = str (md .render (md_fm .content ))
108129
109130 # 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"
111133 if not index_html_file .exists (): # pragma: nocover
112134 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" )
114137 self .extra_head = get_head_nodes (soup )
115138 self .body = get_body_content (soup )
116139
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+
117147
118148@dataclass
119149class Author (Resource ):
0 commit comments