"""Figures: find every image in the chapters being processed and list it in figures/skipped_figures.md. Figures support the concept only (R7). Nothing is spoken unless a spoken sentence is approved, and none is yet, so every figure is listed as skipped.""" import os import re import pageparts import pdftext import structure def toc_pictures(units, before_unit): """Picture list in the table of contents: [(caption, book_page)].""" lines = [] for u in units[:before_unit]: lines += u["text"].split("\n") out = [] for ln in lines: m = re.match(r"^\s*([A-Z][A-Z .,'\-—]+?)\s*\.{3,}\s*(\d+)(?:\s*-\s*\d+)?\s*$", ln) if m: out.append((m.group(1).strip(), int(m.group(2)))) return out def run(book_dir, book, pdf, chapter_numbers): """Writes figures/skipped_figures.md. Returns warnings.""" units = pdftext.units(pdf) heads = structure.find_headings(units) pages, _ = structure.book_pages(units, book["title"]) toc = toc_pictures(units, heads[0]["unit"]) imgs = pdftext.images(pdf) rows, warnings = [], [] for ch in book["chapters"]: if ch["number"] not in chapter_numbers: continue lo, hi = ch["pdf_pages"] for im in imgs: if not lo <= im["pdf_page"] <= hi: continue ui = next(i for i, u in enumerate(units) if u["pdf_page"] == im["pdf_page"] and u["half"] == im["half"]) caption, source = None, None for u in units: if u["pdf_page"] == im["pdf_page"]: for ln in u["text"].split("\n"): m = pageparts.CAPTION_RE.match(ln) if m: caption, source = m.group(2).title(), "caption printed on the page (%s)" % ln.strip() if caption is None: hit = [c for c, p in toc if p == pages[ui]] if hit: caption, source = hit[0].title(), "table of contents picture list, page %d" % pages[ui] if caption is None: warnings.append(("figure-no-caption", "pdf p.%d%s" % (im["pdf_page"], im["half"] or ""), "no caption found")) rows.append((ch["number"], im, pages[ui], caption, source)) os.makedirs(os.path.join(book_dir, "figures"), exist_ok=True) out = ["# Skipped figures", "", "Figures support the concept only, and nothing in a figure is read aloud unless a spoken sentence is approved.", "No spoken figure sentence is approved for this book yet, so every figure below is skipped.", "", "Scope: chapters %s." % ", ".join(str(n) for n in sorted(chapter_numbers)), ""] for n, im, bp, caption, source in rows: out += ["- Chapter %d, pdf page %d (%s half), book page %s: image %d x %d pt on the page." % ( n, im["pdf_page"], {"L": "left", "R": "right", None: "whole"}[im["half"]], bp if bp and bp >= 1 else "unnumbered", im["width"], im["height"]), " Caption: %s." % (caption or "none found"), " Caption source: %s." % (source or "none"), " Reason skipped: no approved spoken sentence."] if not rows: out.append("No figures found in these chapters.") with open(os.path.join(book_dir, "figures", "skipped_figures.md"), "w", encoding="utf-8") as f: f.write("\n".join(out) + "\n") return warnings