Spaces:
Sleeping
Sleeping
File size: 5,553 Bytes
c6c9042 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #!/usr/bin/env python3
"""
pipeline.py β Full PDF Accessibility Pipeline
==============================================
Runs both parts end-to-end:
Part 1 Β· generate_metadata (Python)
PDF β YOLOv11 + Tesseract + GPT-4o β output/elements.txt
Part 2 Β· embed_metadata (Java / iText)
input.pdf + elements.txt β output/tagged_output.pdf (PDF/UA-1)
Usage
-----
python pipeline.py # uses data/input.pdf
python pipeline.py --pdf path/to/file.pdf
python pipeline.py --pdf file.pdf --latex path/to/latex-project/
python pipeline.py --skip-metadata # only run Java tagger
python pipeline.py --skip-tagging # only run Python analysis
"""
import argparse
import os
import subprocess
import sys
ROOT = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(ROOT, "data")
OUTPUT_DIR = os.path.join(ROOT, "output")
JAR_PATH = os.path.join(ROOT, "pdftagger.jar")
def run(cmd: list, **kwargs):
print(f"\n>>> {' '.join(str(c) for c in cmd)}")
result = subprocess.run(cmd, **kwargs)
if result.returncode != 0:
sys.exit(result.returncode)
return result
def build_jar(force: bool = False):
if os.path.exists(JAR_PATH) and not force:
print(f"[pipeline] JAR already built: {JAR_PATH}")
return
print("[pipeline] Building Java tagger JAR (maven package)β¦")
run(["mvn", "-f", os.path.join(ROOT, "pom.xml"), "package", "-q", "-DskipTests"])
if not os.path.exists(JAR_PATH):
print("[pipeline] ERROR: pdftagger.jar not found after build.", file=sys.stderr)
sys.exit(1)
print(f"[pipeline] JAR built: {JAR_PATH}")
def main():
parser = argparse.ArgumentParser(
description="PDF Accessibility Pipeline β analyse then tag.",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument(
"--pdf",
default=os.path.join(DATA_DIR, "input.pdf"),
help="Input PDF (default: data/input.pdf)",
)
parser.add_argument(
"--latex",
default=DATA_DIR,
metavar="DIR",
help="Directory containing the LaTeX source subfolder (default: data/). "
"Place your .tex project as a subfolder inside data/ and this is detected automatically.",
)
parser.add_argument(
"--output",
default=OUTPUT_DIR,
help="Output directory (default: output/)",
)
parser.add_argument(
"--pages",
type=int,
default=-1,
metavar="N",
help="Limit to first N pages (-1 = all)",
)
parser.add_argument(
"--skip-metadata",
action="store_true",
help="Skip Part 1 (use existing output/elements.txt)",
)
parser.add_argument(
"--skip-tagging",
action="store_true",
help="Skip Part 2 (Java tagger)",
)
parser.add_argument(
"--rebuild-jar",
action="store_true",
help="Force rebuild of pdftagger.jar before tagging",
)
parser.add_argument(
"--no-preflight",
action="store_true",
help="Skip prerequisite checks (for CI/CD environments).",
)
args = parser.parse_args()
from preflight import run_preflight_checks
run_preflight_checks(
skip=args.no_preflight,
need_python_part=not args.skip_metadata,
need_java_part=not args.skip_tagging,
)
pdf_path = os.path.abspath(args.pdf)
output_dir = os.path.abspath(args.output)
elements_out = os.path.join(output_dir, "elements.txt")
tagged_out = os.path.join(output_dir, "tagged_output.pdf")
os.makedirs(output_dir, exist_ok=True)
os.makedirs(os.path.join(output_dir, "visualizations"), exist_ok=True)
if not os.path.exists(pdf_path):
print(f"[pipeline] ERROR: PDF not found: {pdf_path}", file=sys.stderr)
sys.exit(1)
# ----------------------------------------------------------------
# Part 1 β generate_metadata
# ----------------------------------------------------------------
if not args.skip_metadata:
print("\n[pipeline] βββ Part 1: Generate Metadata βββ")
cmd = [
sys.executable, "-m", "generate_metadata.main",
"--pdf", pdf_path,
"--output", output_dir,
"--pages", str(args.pages),
]
cmd += ["--latex", os.path.abspath(args.latex)]
run(cmd, cwd=ROOT)
if not os.path.exists(elements_out):
print(f"[pipeline] ERROR: elements.txt not produced at {elements_out}", file=sys.stderr)
sys.exit(1)
else:
print(f"[pipeline] Skipping Part 1 β using: {elements_out}")
if not os.path.exists(elements_out):
print(
"[pipeline] ERROR: elements.txt not found. Run without --skip-metadata first.",
file=sys.stderr,
)
sys.exit(1)
# ----------------------------------------------------------------
# Part 2 β embed_metadata (Java tagger)
# ----------------------------------------------------------------
if not args.skip_tagging:
print("\n[pipeline] βββ Part 2: Embed Metadata βββ")
build_jar(force=args.rebuild_jar)
run(["java", "-jar", JAR_PATH, pdf_path, elements_out, tagged_out])
print(f"\n[pipeline] Tagged PDF: {tagged_out}")
else:
print("[pipeline] Skipping Part 2 (Java tagger).")
print("\n[pipeline] Done.")
if __name__ == "__main__":
main()
|