Files
the-testament/build/build.py
Google AI Agent f72ae1737b merge: Chapter validation pipeline
Co-authored-by: Google AI Agent <gemini@hermes.local>
Co-committed-by: Google AI Agent <gemini@hermes.local>
2026-04-11 00:35:12 +00:00

164 lines
4.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""
The Testament — Book Compilation Pipeline
Compiles all chapters into a single manuscript and generates:
- PDF (print-ready)
- EPUB (e-reader)
Requirements:
- pandoc (brew install pandoc / apt install pandoc)
- TeX Live or similar for PDF (brew install --cask mactex / apt install texlive-full)
Usage:
python3 build/build.py # Build all formats
python3 build/build.py --pdf # PDF only
python3 build/build.py --epub # EPUB only
python3 build/build.py --md # Combined markdown only
"""
import subprocess
import sys
import os
from pathlib import Path
ROOT = Path(__file__).parent.parent
BUILD = ROOT / "build"
CHAPTERS_DIR = ROOT / "chapters"
OUTPUT_DIR = BUILD / "output"
def find_chapters():
"""Find all chapter files, sorted by number."""
chapters = sorted(CHAPTERS_DIR.glob("chapter-*.md"))
if not chapters:
print("ERROR: No chapter files found in", CHAPTERS_DIR)
sys.exit(1)
return chapters
def validate_chapters(chapters):
"""Perform basic validation on chapter content."""
print("Validating chapters...")
errors = 0
for ch in chapters:
content = ch.read_text()
# 1. Check for empty chapters
if len(content.strip()) < 100:
print(f" [WARN] {ch.name} seems too short ({len(content)} chars)")
# 2. Check for missing headers
if not content.startswith("# "):
print(f" [ERROR] {ch.name} is missing a primary H1 header")
errors += 1
# 3. Check for broken internal links (e.g. [Link](#missing))
# (Simplified check for now)
if "](#" in content:
print(f" [INFO] {ch.name} contains internal links. Verify anchors manually.")
return errors == 0
def main():
# ... existing logic ...
def combine_markdown(chapters):
"""Combine all parts into a single markdown file."""
parts = []
# Front matter
front = BUILD / "frontmatter.md"
if front.exists():
parts.append(front.read_text())
# Chapters
for ch in chapters:
parts.append(ch.read_text())
# Back matter
back = BUILD / "backmatter.md"
if back.exists():
parts.append(back.read_text())
combined = "\n\n\newpage\n\n".join(parts)
output = BUILD / "the-testament-full.md"
output.write_text(combined)
print(f"Combined markdown: {output} ({len(combined)} chars)")
return output
def build_pdf(md_file):
"""Build PDF using pandoc + LaTeX."""
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
output = OUTPUT_DIR / "the-testament.pdf"
metadata = BUILD / "metadata.yaml"
cmd = [
"pandoc",
str(md_file),
"-o", str(output),
"--metadata-file", str(metadata),
"--pdf-engine=xelatex",
"--highlight-style=tango",
"-V", "colorlinks=true",
"-V", "linkcolor=blue",
"-V", "urlcolor=blue",
]
print("Building PDF...")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"PDF build failed:\n{result.stderr}")
return False
print(f"PDF: {output} ({output.stat().st_size / 1024:.0f} KB)")
return True
def build_epub(md_file):
"""Build EPUB using pandoc."""
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
output = OUTPUT_DIR / "the-testament.epub"
metadata = BUILD / "metadata.yaml"
cmd = [
"pandoc",
str(md_file),
"-o", str(output),
"--metadata-file", str(metadata),
"--toc",
"--epub-chapter-level=1",
]
print("Building EPUB...")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"EPUB build failed:\n{result.stderr}")
return False
print(f"EPUB: {output} ({output.stat().st_size / 1024:.0f} KB)")
return True
def main():
args = set(sys.argv[1:])
build_all = not args or "--all" in args
chapters = find_chapters()
if not validate_chapters(chapters):
print("Validation failed. Aborting build.")
sys.exit(1)
print(f"Found {len(chapters)} chapters")
md_file = combine_markdown(chapters)
if build_all or "--md" in args:
print("Markdown combined successfully.")
if build_all or "--pdf" in args:
if not build_pdf(md_file):
print("PDF build failed (pandoc/LaTeX may not be installed). Skipping.")
if build_all or "--epub" in args:
if not build_epub(md_file):
print("EPUB build failed (pandoc may not be installed). Skipping.")
print("\nDone.")
if __name__ == "__main__":
main()