Coverage for src / quber / review / annotated.py: 29%

24 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-09-23 22:14 -0400

1"""Annotated PDF: the source pages with each table's final boundary drawn on. 

2 

3Each table's ``content_region`` (the corrected end of the table at its last data 

4row) is drawn onto its page with a small ordinal+title label, so a reviewer can 

5see at a glance which regions were located and how they map onto the source. 

6Falls back to ``som_region`` when ``content_region`` is absent (engines without 

7the Set-of-Mark locator). The tables are supplied already-extracted, so this 

8does no extraction of its own. 

9""" 

10 

11from __future__ import annotations 

12 

13from pathlib import Path 

14from typing import Sequence 

15 

16import fitz 

17 

18from quber.core.extractors import ExtractedTable 

19 

20BOX_RGB = (0.0, 0.32, 0.92) 

21 

22 

23def render_annotated_pdf(tables: Sequence[ExtractedTable], pdf: Path, out_path: Path) -> Path: 

24 """Draw each table's final boundary (``content_region``, else ``som_region``) 

25 onto a copy of ``pdf``. 

26 

27 One box per located table; pages with no tables are left untouched. Tables 

28 with neither region (engines that do not run the locator) are skipped. 

29 Returns ``out_path``. 

30 """ 

31 doc = fitz.open(str(pdf)) 

32 drawn = 0 

33 for t in tables: 

34 region = t.content_region or t.som_region 

35 if not region: 

36 continue 

37 page = doc[t.page - 1] 

38 w, h = page.rect.width, page.rect.height 

39 x0, y0, x1, y1 = region 

40 rect = fitz.Rect(min(x0, x1) * w, min(y0, y1) * h, max(x0, x1) * w, max(y0, y1) * h) 

41 page.draw_rect(rect, color=BOX_RGB, width=1.4) 

42 label = f"{t.page}.{drawn + 1}: {t.title}" if t.title else f"{t.page}.{drawn + 1}" 

43 page.insert_text((rect.x0 + 2, max(8.0, rect.y0 - 3)), label, fontsize=6, color=BOX_RGB) 

44 drawn += 1 

45 out_path.parent.mkdir(parents=True, exist_ok=True) 

46 doc.save(str(out_path)) 

47 return out_path