syng-site/build.py

74 lines
2.3 KiB
Python

import os
import shutil
from dataclasses import dataclass
import markdown
from jinja2 import Environment, FileSystemLoader
@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",
"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:
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 __name__ == "__main__":
main()