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
88 lines
2.1 KiB
Python
88 lines
2.1 KiB
Python
"""Test if merged blocks (TOC) fit in expanded_v."""
|
|
import sys
|
|
sys.path.insert(0, '.')
|
|
import importlib.util
|
|
import fitz
|
|
|
|
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)
|
|
|
|
doc = fitz.open('sample_files/test_corpus/test_pdf.pdf')
|
|
page = doc[0]
|
|
|
|
# Extract and merge
|
|
raw_blocks = pdf_mod.PDFTranslator()._extract_text_blocks(page)
|
|
merged = pdf_mod.PDFTranslator()._merge_adjacent_blocks(raw_blocks, page.rect)
|
|
|
|
# Find the TOC block (block 3 in our trace)
|
|
toc = merged[3]
|
|
print(f"TOC bbox: {toc['bbox']}")
|
|
print(f"TOC font_size: {toc['font_size']}")
|
|
print(f"TOC text length: {len(toc['text'])}")
|
|
print(f"TOC text preview: {toc['text'][:80]!r}")
|
|
|
|
# Redact
|
|
toc_rect = fitz.Rect(toc['bbox'])
|
|
page.add_redact_annot(toc_rect, fill=(1, 1, 1))
|
|
page.apply_redactions(images=fitz.PDF_REDACT_IMAGE_NONE)
|
|
|
|
# Test insert with expanded_v
|
|
margin = 18
|
|
page_rect = page.rect
|
|
expanded_h = fitz.Rect(
|
|
max(toc_rect.x0, page_rect.x0 + margin),
|
|
toc_rect.y0,
|
|
page_rect.x1 - margin,
|
|
toc_rect.y1,
|
|
)
|
|
max_expand_y = min(
|
|
page_rect.y1 - margin - toc_rect.y1,
|
|
toc_rect.height * 3.0,
|
|
)
|
|
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}x{expanded_v.height}")
|
|
|
|
# Translate the TOC text
|
|
french_toc = """1. Introduction
|
|
.......... 1
|
|
2. Installation et configuration
|
|
.......... 2
|
|
3. Moteur de traduction
|
|
.......... 3
|
|
4. Préservation des formats
|
|
.......... 4
|
|
5. Assurance qualité
|
|
.......... 5
|
|
6. Performances et mise à l'échelle
|
|
.......... 6
|
|
7. Référence API
|
|
.......... 7
|
|
8. Dépannage
|
|
.......... 8"""
|
|
|
|
# Test on original
|
|
rc1 = page.insert_textbox(
|
|
toc_rect, french_toc,
|
|
fontsize=12,
|
|
fontfile='C:/Windows/Fonts/arial.ttf',
|
|
align=fitz.TEXT_ALIGN_LEFT,
|
|
overlay=True,
|
|
)
|
|
print(f"Original rect: rc={rc1}")
|
|
|
|
# Test on expanded_v
|
|
rc2 = page.insert_textbox(
|
|
expanded_v, french_toc,
|
|
fontsize=12,
|
|
fontfile='C:/Windows/Fonts/arial.ttf',
|
|
align=fitz.TEXT_ALIGN_LEFT,
|
|
overlay=True,
|
|
)
|
|
print(f"expanded_v: rc={rc2}")
|
|
|
|
doc.close()
|