Skip to content

Commit 14f763e

Browse files
📝 Add docstrings to dev-from-macmini
Docstrings generation was requested by @myoshi2891. * #308 (comment) The following files were modified: * `generate_index.py`
1 parent d6f6fc9 commit 14f763e

1 file changed

Lines changed: 51 additions & 24 deletions

File tree

generate_index.py

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -77,36 +77,56 @@ def copy_vendor_files(self, output_dir: str) -> None:
7777

7878
def rewrite_html_content(self, content: str) -> str:
7979
"""
80-
Rewrite known CDN asset URLs in an HTML document to their corresponding local vendor paths.
81-
82-
Replaces specific external CDN links (React, Babel, Tailwind, PrismJS, FontAwesome, etc.) with local /vendor/... paths so the returned HTML references vendored assets.
83-
80+
Rewrite CDN asset URLs in HTML to local /vendor/ paths.
81+
82+
Replaces known external CDN links (React, Babel, Tailwind, PrismJS, FontAwesome, etc.) with corresponding /vendor/... paths and removes `integrity` and `crossorigin` attributes from `<link>` and `<script>` tags that reference those local vendor files.
83+
84+
Parameters:
85+
content (str): HTML document content to rewrite.
86+
8487
Returns:
85-
The input HTML string with matched CDN URLs substituted by local vendor URLs.
88+
str: The HTML content with matching CDN URLs substituted by local vendor URLs and SRI/crossorigin attributes stripped for vendored assets.
8689
"""
8790
replacements = [
8891
# React
89-
('https://unpkg.com/react@18/umd/react.development.js', '/vendor/react/react.development.js'),
90-
('https://unpkg.com/react@18/umd/react.production.min.js', '/vendor/react/react.production.min.js'),
91-
('https://unpkg.com/react-dom@18/umd/react-dom.development.js', '/vendor/react-dom/react-dom.development.js'),
92-
('https://unpkg.com/react-dom@18/umd/react-dom.production.min.js', '/vendor/react-dom/react-dom.production.min.js'),
92+
(r'https://unpkg\.com/react@[^/]+/umd/react\.development\.js', '/vendor/react/react.development.js'),
93+
(r'https://unpkg\.com/react@[^/]+/umd/react\.production\.min\.js', '/vendor/react/react.production.min.js'),
94+
(r'https://unpkg\.com/react-dom@[^/]+/umd/react-dom\.development\.js', '/vendor/react-dom/react-dom.development.js'),
95+
(r'https://unpkg\.com/react-dom@[^/]+/umd/react-dom\.production\.min\.js', '/vendor/react-dom/react-dom.production.min.js'),
9396
# Babel
94-
('https://unpkg.com/@babel/standalone/babel.min.js', '/vendor/babel/babel.min.js'),
95-
('https://unpkg.com/@babel/standalone/babel.js', '/vendor/babel/babel.min.js'),
97+
(r'https://unpkg\.com/@babel/standalone(?:@[^/]+)?/babel\.min\.js', '/vendor/babel/babel.min.js'),
98+
(r'https://unpkg\.com/@babel/standalone(?:@[^/]+)?/babel\.js', '/vendor/babel/babel.min.js'),
9699
# Tailwind
97-
('https://cdn.tailwindcss.com', '/vendor/tailwindcss/script.js'),
100+
(r'https://cdn\.tailwindcss\.com(?:@[^/]+)?', '/vendor/tailwindcss/script.js'),
98101
# PrismJS
99-
# Handle minified vs unminified mapping. Node modules usually has unminified.
100-
# We map the CDN .min.css requests to our local .css files (which we copied from node_modules)
101-
('https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css', '/vendor/prismjs/themes/prism.css'),
102-
('https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.css', '/vendor/prismjs/plugins/line-numbers/prism-line-numbers.css'),
103-
('https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/toolbar/prism-toolbar.min.css', '/vendor/prismjs/plugins/toolbar/prism-toolbar.css'),
102+
(r'https://cdnjs\.cloudflare\.com/ajax/libs/prism/[^/]+/themes/prism\.min\.css', '/vendor/prismjs/themes/prism.css'),
103+
(r'https://cdnjs\.cloudflare\.com/ajax/libs/prism/[^/]+/plugins/line-numbers/prism-line-numbers\.min\.css', '/vendor/prismjs/plugins/line-numbers/prism-line-numbers.css'),
104+
(r'https://cdnjs\.cloudflare\.com/ajax/libs/prism/[^/]+/plugins/toolbar/prism-toolbar\.min\.css', '/vendor/prismjs/plugins/toolbar/prism-toolbar.css'),
104105
# FontAwesome
105-
('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css', '/vendor/fontawesome/css/all.min.css'),
106+
(r'https://cdnjs\.cloudflare\.com/ajax/libs/font-awesome/[^/]+/css/all\.min\.css', '/vendor/fontawesome/css/all.min.css'),
106107
]
107108

108-
for old, new in replacements:
109-
content = content.replace(old, new)
109+
for pattern_str, new in replacements:
110+
content = re.sub(pattern_str, new, content)
111+
112+
# Strip integrity and crossorigin attributes from tags referencing local /vendor/ files
113+
def strip_sri(match):
114+
"""
115+
Remove Subresource Integrity (`integrity`) and `crossorigin` attributes from an HTML <link> or <script> tag if the tag references a `/vendor/` path.
116+
117+
Parameters:
118+
match (re.Match): A regex match object whose matched text is the full HTML tag.
119+
120+
Returns:
121+
str: The original tag text with `integrity` and `crossorigin` attributes removed when the tag contains `/vendor/`; otherwise the original tag text unchanged.
122+
"""
123+
tag_text = match.group(0)
124+
if '/vendor/' in tag_text:
125+
tag_text = re.sub(r'\s*integrity="[^"]+"', '', tag_text)
126+
tag_text = re.sub(r'\s*crossorigin="[^"]+"', '', tag_text)
127+
return tag_text
128+
129+
content = re.sub(r'<(?:link|script)[^>]+>', strip_sri, content)
110130

111131
return content
112132

@@ -174,6 +194,12 @@ def generate_index(self) -> None:
174194
title = self.get_html_title(filepath)
175195
except Exception:
176196
title = os.path.basename(filepath)
197+
198+
# Append disambiguator if 'detailed' is in the filename
199+
if 'detailed' in filename.lower():
200+
if '(detailed)' not in title.lower():
201+
title += ' (detailed)'
202+
177203
structure[category].append((title, rel_path))
178204

179205
# Sort categories and files
@@ -891,11 +917,11 @@ def generate_index(self) -> None:
891917
def render_category_files(structure, sorted_categories):
892918
"""
893919
Builds HTML fragments for category tabs, per-category file lists, and an aggregated all-files list.
894-
920+
895921
Parameters:
896922
structure (Dict[str, List[Tuple[str, str]]]): Mapping from category name to a list of (title, relative_path) pairs for files in that category.
897923
sorted_categories (List[str]): Ordered list of category names to render; determines the iteration order and tab order.
898-
924+
899925
Returns:
900926
Tuple[str, str, str]: A 3-tuple with:
901927
- tabs_html: HTML for the category tab buttons (includes icon and item count for each category).
@@ -925,7 +951,8 @@ def render_category_files(structure, sorted_categories):
925951
safe_title = html.escape(title)
926952
safe_github_path = html.escape(github_path) # Escape path for display
927953

928-
item_html = f'<li class="file-item" data-category="{css_cat}"><a class="file-link" href="{encoded_path}">' \
954+
safe_encoded_path = html.escape(encoded_path, quote=True)
955+
item_html = f'<li class="file-item" data-category="{css_cat}"><a class="file-link" href="{safe_encoded_path}">' \
929956
f'<span class="card-header"><span class="card-icon">{icon}</span>' \
930957
f'<span class="card-title">{safe_title}</span></span><span class="file-path">{safe_github_path}</span></a></li>\n'
931958
category_files.append(item_html)
@@ -955,4 +982,4 @@ def render_category_files(structure, sorted_categories):
955982
print(f"Successfully updated {output_index_path} with vendored assets at {current_time}")
956983

957984
if __name__ == "__main__":
958-
Solution().generate_index()
985+
Solution().generate_index()

0 commit comments

Comments
 (0)