@@ -75,7 +75,7 @@ def get_body_content(s: BeautifulSoup, test_path: Path = PYODIDE) -> str:
75
75
class Resource :
76
76
"""Base dataclass used for all resources."""
77
77
78
- path : PurePath
78
+ name : str
79
79
title : str = ""
80
80
body : str = ""
81
81
extra_head : str = ""
@@ -91,41 +91,55 @@ class Example(Resource):
91
91
Meaning, HERE / "examples" / name / "index.html".
92
92
"""
93
93
94
- description : str = ""
95
94
subtitle : str = ""
95
+ description : str = ""
96
+ author : str | None = None
96
97
97
98
def __post_init__ (self ) -> None :
98
99
"""Extract most of the data from the HTML file."""
99
- # Title, subtitle, description come from the example's MD file.
100
- index_md_file = HERE / "gallery/examples" / self .path / "index.md"
100
+ # Title, subtitle, body come from the example's MD file.
101
+ index_md_file = HERE / "gallery/examples" / self .name / "index.md"
101
102
md_fm = frontmatter .load (index_md_file )
102
103
self .title = md_fm .get ("title" , "" )
104
+ self .author = md_fm .get ("author" , "" )
103
105
self .subtitle = md_fm .get ("subtitle" , "" )
104
106
md = MarkdownIt ()
105
107
self .description = str (md .render (md_fm .content ))
106
108
107
109
# Main, extra head example's HTML file.
108
- index_html_file = HERE / "gallery/examples" / self .path / "index.html"
110
+ index_html_file = HERE / "gallery/examples" / self .name / "index.html"
109
111
if not index_html_file .exists (): # pragma: nocover
110
- raise ValueError (f"No example at { self .path } " )
112
+ raise ValueError (f"No example at { self .name } " )
111
113
soup = BeautifulSoup (index_html_file .read_text (), "html5lib" )
112
114
self .extra_head = get_head_nodes (soup )
113
115
self .body = get_body_content (soup )
114
116
115
117
118
+ @dataclass
119
+ class Author (Resource ):
120
+ """Information about an author, from Markdown."""
121
+
122
+ def __post_init__ (self ) -> None :
123
+ """Initialize the rest of the fields from the Markdown."""
124
+ md_file = HERE / "gallery/authors" / f"{ self .name } .md"
125
+ md_fm = frontmatter .load (md_file )
126
+ self .title = md_fm .get ("title" , "" )
127
+ md = MarkdownIt ()
128
+ self .body = str (md .render (md_fm .content ))
129
+
130
+
116
131
@dataclass
117
132
class Page (Resource ):
118
133
"""A Markdown+frontmatter driven content page."""
119
134
120
135
subtitle : str = ""
121
- body : str = ""
122
136
123
137
def __post_init__ (self ) -> None :
124
138
"""Extract content from either Markdown or HTML file."""
125
- md_file = HERE / "pages" / f"{ self .path } .md"
126
- html_file = HERE / "pages" / f"{ self .path } .html"
139
+ md_file = HERE / "pages" / f"{ self .name } .md"
140
+ html_file = HERE / "pages" / f"{ self .name } .html"
127
141
128
- # If this self.path resolves to a Markdown file, use it first
142
+ # If this self.name resolves to a Markdown file, use it first
129
143
if md_file .exists ():
130
144
md_fm = frontmatter .load (md_file )
131
145
self .title = md_fm .get ("title" , "" )
@@ -146,40 +160,49 @@ def __post_init__(self) -> None:
146
160
if body_node and isinstance (body_node , Tag ):
147
161
self .body = body_node .prettify ()
148
162
else : # pragma: no cover
149
- raise ValueError (f"No page at { self .path } " )
163
+ raise ValueError (f"No page at { self .name } " )
150
164
151
165
152
166
@dataclass
153
167
class Resources :
154
168
"""Container for all resources in site."""
155
169
156
- examples : dict [PurePath , Example ] = field (default_factory = dict )
157
- pages : dict [PurePath , Page ] = field (default_factory = dict )
170
+ authors : dict [str , Author ] = field (default_factory = dict )
171
+ examples : dict [str , Example ] = field (default_factory = dict )
172
+ pages : dict [str , Page ] = field (default_factory = dict )
158
173
159
174
160
- def get_sorted_examples ( ) -> list [PurePath ]:
175
+ def get_sorted_paths ( target_dir : Path , only_dirs : bool = True ) -> list [PurePath ]:
161
176
"""Return an alphabetized listing of the examples."""
162
- examples_dir = HERE / "gallery/examples"
163
- examples = [e for e in examples_dir .iterdir () if e .is_dir ()]
164
- return sorted (examples , key = attrgetter ("name" ))
177
+ if only_dirs :
178
+ paths = [e for e in target_dir .iterdir () if e .is_dir ()]
179
+ else :
180
+ paths = [e for e in target_dir .iterdir ()]
181
+
182
+ return sorted (paths , key = attrgetter ("name" ))
165
183
166
184
167
185
def get_resources () -> Resources :
168
186
"""Factory to construct all the resources in the site."""
169
187
resources = Resources ()
170
188
189
+ # Load the authors
190
+ authors = HERE / "gallery/authors"
191
+ for author in get_sorted_paths (authors , only_dirs = False ):
192
+ this_author = Author (name = author .stem )
193
+ resources .authors [author .stem ] = this_author
194
+
171
195
# Load the examples
172
- for example in get_sorted_examples ():
173
- this_path = PurePath ( example . name )
174
- this_example = Example (path = this_path )
175
- resources .examples [this_path ] = this_example
196
+ examples = HERE / "gallery/examples"
197
+ for example in get_sorted_paths ( examples ):
198
+ this_example = Example (example . stem )
199
+ resources .examples [example . stem ] = this_example
176
200
177
201
# Load the Pages
178
202
pages_dir = HERE / "pages"
179
203
pages = [e for e in pages_dir .iterdir ()]
180
204
for page in pages :
181
- this_path = PurePath (page .stem )
182
- this_page = Page (path = this_path )
183
- resources .pages [this_path ] = this_page
205
+ this_page = Page (name = page .stem )
206
+ resources .pages [page .stem ] = this_page
184
207
185
208
return resources
0 commit comments