9f0a216c5e
- Created index.html template for the homepage with service cards and partner logos. - Added page_from_md.html template for rendering pages from markdown. - Developed services.html template detailing various services offered. - Implemented tests for link handling in markdown, ensuring external links open in new tabs and internal links function correctly. - Enhanced markdown parser tests to validate heading extraction, content rendering, and link safety. - Introduced utility tests for template rendering, HTML minification, and JavaScript minification. Co-authored-by: Copilot <copilot@github.com>
127 lines
3.9 KiB
Python
127 lines
3.9 KiB
Python
import os
|
|
import re
|
|
from typing import Dict, List, Any
|
|
from jinja2 import Environment, FileSystemLoader
|
|
from lib.types import PagesDict
|
|
|
|
DEFAULT_TEMPLATE_DIR = 'templates'
|
|
DEFAULT_OUTPUT_DIR = 'html'
|
|
|
|
|
|
def get_template_files(template_dir: str = DEFAULT_TEMPLATE_DIR) -> List[str]:
|
|
"""Return template filenames from the provided template directory."""
|
|
if not os.path.exists(template_dir):
|
|
return []
|
|
return [
|
|
name
|
|
for name in os.listdir(template_dir)
|
|
if name.endswith('.html') and not name.startswith('_')
|
|
]
|
|
|
|
|
|
def get_css_files(output_dir: str = DEFAULT_OUTPUT_DIR) -> List[str]:
|
|
"""Return CSS file paths contained in the output directory's css folder."""
|
|
css_dir = os.path.join(output_dir, 'css')
|
|
if not os.path.exists(css_dir):
|
|
return []
|
|
return [
|
|
os.path.join(css_dir, name)
|
|
for name in os.listdir(css_dir)
|
|
if name.endswith('.css')
|
|
]
|
|
|
|
|
|
def get_js_files(output_dir: str = DEFAULT_OUTPUT_DIR) -> List[str]:
|
|
"""Return JavaScript file paths contained in the output directory's js folder."""
|
|
js_dir = os.path.join(output_dir, 'js')
|
|
if not os.path.exists(js_dir):
|
|
return []
|
|
return [
|
|
os.path.join(js_dir, name)
|
|
for name in os.listdir(js_dir)
|
|
if name.endswith('.js')
|
|
]
|
|
|
|
|
|
def render_template(
|
|
template_name: str,
|
|
context: Dict[str, Any],
|
|
template_dir: str = DEFAULT_TEMPLATE_DIR) -> str:
|
|
"""Render a Jinja2 template with the provided context."""
|
|
env = Environment(loader=FileSystemLoader(template_dir))
|
|
template = env.get_template(template_name)
|
|
return template.render(context)
|
|
|
|
|
|
def set_active_page_by_url(pages: PagesDict, page_url: str) -> None:
|
|
"""Mutate navigation dictionary to mark the active page."""
|
|
for key, value in pages.items():
|
|
# value is a PageEntry TypedDict
|
|
value['active'] = key == page_url
|
|
|
|
|
|
def minify_js(js: str) -> str:
|
|
"""Minify JavaScript by removing comments and redundant whitespace."""
|
|
js = re.sub(r'//.*?\n|/\*.*?\*/', '', js, flags=re.DOTALL)
|
|
js = re.sub(r'\s+', ' ', js)
|
|
js = re.sub(r';\s+', ';\n', js)
|
|
js = re.sub(r'\n+', ' ', js)
|
|
return js.strip()
|
|
|
|
|
|
def minify_css(css: str) -> str:
|
|
"""Minify CSS by removing comments and redundant whitespace."""
|
|
css = re.sub(r'/\*.*?\*/', '', css, flags=re.DOTALL)
|
|
css = re.sub(r'\s+', ' ', css)
|
|
css = re.sub(r';\s+', ';\n', css)
|
|
css = re.sub(r'\s+([\{\s])', r'\1', css)
|
|
css = re.sub(r'\s+}', '}', css)
|
|
css = re.sub(r'\n+', ' ', css)
|
|
return css.strip()
|
|
|
|
|
|
def minify_html(html: str) -> str:
|
|
"""Minify HTML by removing comments and redundant whitespace."""
|
|
html = re.sub(r'<!--.*?-->', '', html, flags=re.DOTALL)
|
|
html = re.sub(r'\s+', ' ', html)
|
|
html = re.sub(r'>\s+<', '><', html)
|
|
html = re.sub(r'<\s+', '<', html)
|
|
html = re.sub(r'\s+</', '</', html)
|
|
return html.strip()
|
|
|
|
|
|
def css_minifier(output_dir: str = DEFAULT_OUTPUT_DIR) -> None:
|
|
"""Minify all CSS files within the output directory."""
|
|
for css_path in get_css_files(output_dir):
|
|
with open(css_path, 'r', encoding='utf-8') as handle:
|
|
content = handle.read()
|
|
minified = minify_css(content)
|
|
with open(css_path, 'w', encoding='utf-8') as handle:
|
|
handle.write(minified)
|
|
|
|
|
|
def js_minifier(output_dir: str = DEFAULT_OUTPUT_DIR) -> None:
|
|
"""Minify all JavaScript files within the output directory."""
|
|
for js_path in get_js_files(output_dir):
|
|
with open(js_path, 'r', encoding='utf-8') as handle:
|
|
content = handle.read()
|
|
minified = minify_js(content)
|
|
with open(js_path, 'w', encoding='utf-8') as handle:
|
|
handle.write(minified)
|
|
|
|
|
|
__all__ = [
|
|
'DEFAULT_OUTPUT_DIR',
|
|
'DEFAULT_TEMPLATE_DIR',
|
|
'get_template_files',
|
|
'get_css_files',
|
|
'get_js_files',
|
|
'render_template',
|
|
'set_active_page_by_url',
|
|
'minify_js',
|
|
'minify_css',
|
|
'minify_html',
|
|
'css_minifier',
|
|
'js_minifier',
|
|
]
|