Team Ai
Apppublic

dwrswr/cpp-module-06-guide

sourceHugging Facemitupdated 2mo agoView on Hugging Face
0likes
build.py97 linesDownload Raw Back to tools
1# -*- coding: utf-8 -*-2"""Build index.html from tools/index.src.html, injecting the REAL cpp06 sources.3 4Placeholders:  {{CODE relative/path|dom-id|flags}}5  flags: comma list, any of  tall  plain6Language is inferred from the file name. Because the code blocks are read from7../cpp06 at build time, the published guide can never drift from the project.8"""9import html10import os11import shutil12import sys13 14HERE = os.path.dirname(os.path.abspath(__file__))15GUIDE = os.path.dirname(HERE)16SRC = os.path.abspath(os.path.join(GUIDE, os.pardir, "cpp06"))17TMPL = os.path.join(HERE, "index.src.html")18OUT = os.path.join(GUIDE, "index.html")19MIRROR = os.path.join(GUIDE, "code")20 21LANG = {".cpp": ("cpp", "C++98"), ".hpp": ("cpp", "C++98"), ".sh": ("sh", "shell")}22 23 24def lang_of(path):25    base = os.path.basename(path)26    if base == "Makefile":27        return "make", "make"28    return LANG.get(os.path.splitext(base)[1], ("cpp", "C++98"))29 30 31def block(spec):32    parts = [p.strip() for p in spec.split("|")]33    rel = parts[0]34    dom = parts[1] if len(parts) > 1 and parts[1] else "code-" + rel.replace("/", "-").replace(".", "-")35    flags = [f for f in (parts[2].split(",") if len(parts) > 2 and parts[2] else []) if f]36    full = os.path.join(SRC, rel.replace("/", os.sep))37    with open(full, "r", encoding="utf-8", newline="") as fh:38        text = fh.read().replace("\r\n", "\n").rstrip("\n")39    lang, tag = lang_of(rel)40    n = text.count("\n") + 141    cls = "code" + (" tall" if "tall" in flags else "") + (" plain" if "plain" in flags else "")42    return (43        '<div class="%s" id="%s">\n'44        '  <div class="code-head"><span class="dot" aria-hidden="true"></span>'45        '<span class="fn">cpp06/%s</span>'46        '<span class="tag">%s &middot; %d lines</span>'47        '<button class="copy" type="button">copy</button></div>\n'48        '  <div class="code-body"><pre data-lang="%s">%s</pre></div>\n'49        "</div>"50    ) % (cls, dom, rel, tag, n, lang, html.escape(text, quote=False))51 52 53def main():54    with open(TMPL, "r", encoding="utf-8") as fh:55        page = fh.read()56    out, i, used = [], 0, []57    while True:58        a = page.find("{{CODE ", i)59        if a < 0:60            out.append(page[i:])61            break62        b = page.find("}}", a)63        if b < 0:64            raise SystemExit("unterminated placeholder at %d" % a)65        out.append(page[i:a])66        spec = page[a + 7:b]67        out.append(block(spec))68        used.append(spec.split("|")[0].strip())69        i = b + 270    with open(OUT, "w", encoding="utf-8", newline="\n") as fh:71        fh.write("".join(out))72 73    if os.path.isdir(MIRROR):74        shutil.rmtree(MIRROR)75    shutil.copytree(SRC, MIRROR)76    for root, _dirs, files in os.walk(MIRROR):77        for f in files:78            p = os.path.join(root, f)79            with open(p, "rb") as fh:80                data = fh.read()81            with open(p, "wb") as fh:82                fh.write(data.replace(b"\r\n", b"\n"))83 84    every = []85    for root, _dirs, files in os.walk(SRC):86        for f in files:87            every.append(os.path.relpath(os.path.join(root, f), SRC).replace(os.sep, "/"))88    missing = sorted(set(every) - set(used))89    sys.stdout.write("built %s  (%d bytes)\n" % (OUT, os.path.getsize(OUT)))90    sys.stdout.write("code blocks injected: %d of %d project files\n" % (len(set(used)), len(every)))91    if missing:92        sys.stdout.write("NOT shown in the guide: %s\n" % ", ".join(missing))93 94 95if __name__ == "__main__":96    main()97