import os import shutil from dataclasses import dataclass import markdown from jinja2 import Environment, FileSystemLoader import sys from http.server import SimpleHTTPRequestHandler, HTTPServer @dataclass class Section: name: str type: str content: str = "" def render(self) -> str: """Render the section content based on its type.""" if self.type.lower() == "html": return self.content elif self.type.lower() == "markdown": return markdown.markdown( self.content, extensions=[ "pymdownx.blocks.html", "markdown.extensions.def_list", "sane_lists", "attr_list", "pymdownx.blocks.tab", ], ) else: raise ValueError(f"Unsupported content type: {self.type}") @classmethod def open(cls, filename: str) -> dict[str, "Section"]: """Open a file and return its contents.""" env = {} with open(filename, "r") as file: content = file.readlines() key = None for line in content: if line.startswith("!!section:"): keyline = line[10:].strip().split(",") key = keyline[0].strip() content_type = keyline[1].strip() if len(keyline) > 1 else "HTML" env[key] = cls(name=key, type=content_type, content="") elif key is not None and env[key] is not None: env[key].content += line return env def main() -> None: if sys.argv[1:] and sys.argv[1] == "serve": port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000 os.chdir("dist") print(f"Serving on http://localhost:{port}") httpd = HTTPServer(("localhost", port), SimpleHTTPRequestHandler) try: httpd.serve_forever() except KeyboardInterrupt: print("\nServer stopped.") finally: httpd.server_close() return env = Environment(loader=FileSystemLoader(".")) template = env.get_template("site.template.html") sites = os.listdir("sites") for site in sites: sitename, _ = os.path.splitext(site) print(f"Found site: {sitename}") site_config = {k: v.render() for k, v in Section.open(f"sites/{site}").items()} rendered_html = template.render(site_config) os.makedirs("dist", exist_ok=True) with open(f"dist/{sitename}.html", "w") as f: f.write(rendered_html) static_folders = ["css", "js", "images"] for folder in static_folders: src_folder = os.path.join(folder) dst_folder = os.path.join("dist", folder) shutil.rmtree(dst_folder, ignore_errors=True) shutil.copytree(src_folder, dst_folder) if os.path.exists("favicon.ico"): shutil.copy("favicon.ico", "dist/favicon.ico") if __name__ == "__main__": main()