| 1 | #!/usr/bin/env python |
| 2 | |
| 3 | import os |
| 4 | import pathlib |
| 5 | import subprocess |
| 6 | |
| 7 | import yaml |
| 8 | |
| 9 | import ninja_syntax |
| 10 | |
| 11 | DEVMODE="" |
| 12 | |
| 13 | if os.environ.get("DEVMODE"): |
| 14 | DEVMODE = "-devmode" |
| 15 | |
| 16 | def _nth(n): |
| 17 | return f"$$(echo $in | cut -d' ' -f{n})" |
| 18 | |
| 19 | |
| 20 | def _render_rule(w: ninja_syntax.Writer, name, link): |
| 21 | w.rule( |
| 22 | f"render_{name}", |
| 23 | " ".join( |
| 24 | [ |
| 25 | "./render.py", |
| 26 | DEVMODE, |
| 27 | "-stylesheet", |
| 28 | "gen/main.css", |
| 29 | "-template", |
| 30 | _nth(1), |
| 31 | "-sitemap", |
| 32 | "sitemap.yaml", |
| 33 | "-link", |
| 34 | link, |
| 35 | "-content", |
| 36 | _nth(2) + "| minhtml > $out", |
| 37 | ] |
| 38 | ), |
| 39 | ) |
| 40 | return f"render_{name}" |
| 41 | |
| 42 | |
| 43 | def _render_rss_rule(w: ninja_syntax.Writer): |
| 44 | w.rule(f"render_rss", " ".join(["./render.py", "-rss", "> $out"])) |
| 45 | return f"render_rss" |
| 46 | |
| 47 | |
| 48 | def _compile_sm(w: ninja_syntax.Writer, entries: list, path: pathlib.Path): |
| 49 | entries = list( |
| 50 | filter(lambda entry: "enabled" not in entry or entry["enabled"], entries) |
| 51 | ) |
| 52 | for entry in entries: |
| 53 | next_path = path.joinpath(entry["name"]) |
| 54 | if "others" in entry and entry["others"]: # its a dir |
| 55 | w.build(str(next_path), "mkdir") |
| 56 | _compile_sm(w, entry["others"], next_path) |
| 57 | else: |
| 58 | source = list(next_path.glob("README.md")) |
| 59 | if len(source) == 1: |
| 60 | source = str(source[0]) |
| 61 | link = source.replace("content/", "", 1) |
| 62 | link = source.replace("/README.md", "", 1) |
| 63 | target = source.replace("content/", "", 1) |
| 64 | target_dir = target.replace("/README.md", "", 1) |
| 65 | w.build(target_dir, "mkdir") |
| 66 | target = target.replace("README.md", "index.html", 1) |
| 67 | target = "gen/" + target |
| 68 | cmd = _render_rule(w, source.replace("/", "_", -1), link) |
| 69 | w.build( |
| 70 | target, |
| 71 | cmd, |
| 72 | inputs=["index.html.jinja", source, "sitemap.yaml", "render.py"], |
| 73 | ) |
| 74 | |
| 75 | |
| 76 | if __name__ == "__main__": |
| 77 | with open("sitemap.yaml", "r") as fp: |
| 78 | sitemap = yaml.safe_load(fp.read()) |
| 79 | with open("build.ninja", "w") as fp: |
| 80 | w = ninja_syntax.Writer(fp) |
| 81 | w.comment("automatically generated, do not edit.") |
| 82 | w.variable("sass_flags", "--style compressed") |
| 83 | w.rule("mkdir", command="mkdir -p $out") |
| 84 | w.rule("make_qr_code", command="cat $in | qrencode -o $out") |
| 85 | w.rule("copy", command="cp $in $out") |
| 86 | w.build("index.html.jinja", "phony") |
| 87 | w.build("render.py", "phony") |
| 88 | w.build("sitemap.yaml", "phony") |
| 89 | w.build("gen", "mkdir") |
| 90 | w.build("gen/contact.png", "make_qr_code", inputs=["contact.txt"]) |
| 91 | w.build("gen/ks_stylized.png", "copy", inputs=["assets/ks_stylized.png"]) |
| 92 | w.build("gen/favicon.ico", "copy", inputs=["assets/favicon.ico"]) |
| 93 | w.build("gen/style.xsl", "copy", inputs=["assets/style.xsl"]) |
| 94 | w.build("gen/main.css", "copy", inputs=["main.css"]) |
| 95 | cmd = _render_rule(w, "index", "/") |
| 96 | w.build( |
| 97 | "gen/index.html", |
| 98 | cmd, |
| 99 | inputs=[ |
| 100 | "index.html.jinja", |
| 101 | "content/index.md", |
| 102 | "sitemap.yaml", |
| 103 | "render.py", |
| 104 | ], |
| 105 | ) |
| 106 | cmd = _render_rss_rule(w) |
| 107 | w.build("gen/index.xml", cmd) |
| 108 | if sitemap["enabled"]: |
| 109 | _compile_sm(w, sitemap["entries"], pathlib.Path("./content")) |
| 110 | w.close() |
| 111 | |
| 112 | subprocess.call(args=["ninja"]) |