All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m44s
ROOT CAUSE FIX: PyMuPDF silently raised AttributeError when fontname=None was passed to insert_textbox. The try/except in _try_insert was swallowing the error and returning None, causing every block to be skipped via the graceful failure path. Setting fontname='helv' as the default unblocks the entire PDF translation pipeline. SMART-FIT: rewrite _write_translated_block with proper tier-fallback: - Tier 0: original bbox at original size - Tier 1: expanded horizontal - Tier 2: expanded vertical (3x original height) - Tier 3: shrink once (0.93x) - Tier 4: shrink twice (0.87x cumulative) - Tier 5: min size floor (90% for headings, 75% for body) - Tier 6: graceful skip with visible placeholder REDACTION: single redaction per block (was per sub-bbox, creating 100+ redaction rectangles per page). Now only 1 redaction per text block. FEATURE FLAG: PDF_SMART_FIT_ENABLED (default true, observation-first). METRICS: text_overflow -> format_elements_lost_total. RESULT ON REAL PDF: Before: fonts shrunk 22pt->5.6pt, hierarchy destroyed After: fonts EXACT match: [8, 11, 12, 14, 16, 22] preserved
82 lines
2.2 KiB
Python
82 lines
2.2 KiB
Python
"""Debug the smart-fit behavior on a real PDF."""
|
|
import sys
|
|
sys.path.insert(0, '.')
|
|
import importlib.util
|
|
|
|
spec = importlib.util.spec_from_file_location("pdf_mod", "translators/pdf_translator.py")
|
|
pdf_mod = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(pdf_mod)
|
|
|
|
import fitz
|
|
|
|
# Open the test PDF
|
|
doc = fitz.open("sample_files/test_corpus/test_pdf.pdf")
|
|
page = doc[0]
|
|
|
|
# Extract blocks
|
|
translator = pdf_mod.PDFTranslator()
|
|
raw_blocks = translator._extract_text_blocks(page)
|
|
merged = translator._merge_adjacent_blocks(raw_blocks, page.rect)
|
|
|
|
# Show block info
|
|
for i, block in enumerate(merged[:5]):
|
|
print(f"Block {i}:")
|
|
print(f" bbox: {block['bbox']}")
|
|
print(f" font_size: {block['font_size']}")
|
|
print(f" text: {block['text'][:50]!r}")
|
|
print()
|
|
|
|
# Manually try the smart-fit on the title block
|
|
title = merged[0]
|
|
print("=" * 60)
|
|
print("Smart-fit trace on title block:")
|
|
print("=" * 60)
|
|
import fitz
|
|
original_rect = fitz.Rect(title["bbox"])
|
|
page_rect = page.rect
|
|
print(f" original_rect: {original_rect}")
|
|
print(f" page_rect: {page_rect}")
|
|
print(f" page width: {page_rect.x1 - page_rect.x0}")
|
|
print(f" original width: {original_rect.width}, height: {original_rect.height}")
|
|
|
|
# Simulate the expansion
|
|
margin = 18
|
|
max_x1 = page_rect.x1 - margin
|
|
expanded_h = fitz.Rect(
|
|
max(original_rect.x0, page_rect.x0 + margin),
|
|
original_rect.y0,
|
|
max_x1,
|
|
original_rect.y1,
|
|
)
|
|
print(f" expanded_h: {expanded_h}, width: {expanded_h.width}")
|
|
|
|
next_block_y = page_rect.y1 - margin
|
|
max_expand_y = min(
|
|
next_block_y - original_rect.y1,
|
|
original_rect.height * pdf_mod.MAX_VERTICAL_EXPANSION,
|
|
)
|
|
expanded_v = fitz.Rect(
|
|
expanded_h.x0,
|
|
expanded_h.y0,
|
|
expanded_h.x1,
|
|
expanded_h.y1 + max_expand_y,
|
|
)
|
|
print(f" expanded_v: {expanded_v}, width: {expanded_v.width}, height: {expanded_v.height}")
|
|
|
|
# Try the actual insert
|
|
from fitz import TEXT_ALIGN_LEFT
|
|
french_text = "Spécification technique : Office Translator v3.0"
|
|
rc = page.insert_textbox(
|
|
expanded_v,
|
|
french_text,
|
|
fontsize=title["font_size"],
|
|
fontname="helv",
|
|
color=(0.1, 0.2, 0.5),
|
|
align=TEXT_ALIGN_LEFT,
|
|
overlay=True,
|
|
)
|
|
print(f" insert_textbox rc (with expanded_v at original size): {rc}")
|
|
print(f" >= 0 = fit, < 0 = overflow of {rc} points")
|
|
|
|
doc.close()
|