MCPcopy Create free account
hub / github.com/917Dhj/DeepPaperNote / _find_caption_blocks

Function _find_caption_blocks

scripts/extract_pdf_assets.py:299–368  ·  view source on GitHub ↗

Return caption anchors sorted top-to-bottom by their y0 coordinate. Each anchor contains the full multi-line caption bbox so that the downstream crop includes the entire caption text, not just the first line. Each anchor:: { "label": "Figure 3", "kind":

(page)

Source from the content-addressed store, hash-verified

297# ---------------------------------------------------------------------------
298
299def _find_caption_blocks(page) -> list[dict]:
300 """Return caption anchors sorted top-to-bottom by their y0 coordinate.
301
302 Each anchor contains the full multi-line caption bbox so that the
303 downstream crop includes the entire caption text, not just the first line.
304
305 Each anchor::
306
307 {
308 "label": "Figure 3",
309 "kind": "figure" | "table",
310 "bbox": (x0, y0, x1, y1),
311 "line_text": ...,
312 }
313 """
314 anchors: list[dict] = []
315 blocks = page.get_text("dict", flags=fitz.TEXT_PRESERVE_WHITESPACE)["blocks"]
316 for block in blocks:
317 if block.get("type") != 0:
318 continue
319 lines = block.get("lines", [])
320 for line_idx, line in enumerate(lines):
321 spans = line.get("spans", [])
322 if not spans:
323 continue
324 line_text = "".join(s.get("text", "") for s in spans).strip()
325 match = CAPTION_RE.match(line_text)
326 if not match or _caption_match_is_inline_reference(line_text, match):
327 continue
328 label = normalize_whitespace(match.group(1))
329 kind = _classify_caption_kind(label)
330
331 caption_lines_text = [line_text]
332 first_bbox = line["bbox"]
333 x0, y0, x1, y1 = first_bbox
334 prev_line_bottom = first_bbox[3]
335 line_height = max(first_bbox[3] - first_bbox[1], 6.0)
336
337 for cont_line in lines[line_idx + 1:]:
338 cont_spans = cont_line.get("spans", [])
339 if not cont_spans:
340 break
341 cont_text = "".join(s.get("text", "") for s in cont_spans).strip()
342 if not cont_text:
343 break
344 if CAPTION_RE.match(cont_text):
345 break
346 if _looks_like_data_row(cont_text):
347 break
348 cb = cont_line["bbox"]
349 # Stop merging if the next line is too far below the previous one
350 # (it is then a separate paragraph, not a caption continuation).
351 if cb[1] - prev_line_bottom > line_height * 1.6:
352 break
353 x0 = min(x0, cb[0])
354 y1 = max(y1, cb[3])
355 x1 = max(x1, cb[2])
356 prev_line_bottom = cb[3]

Calls 5

normalize_whitespaceFunction · 0.90
_classify_caption_kindFunction · 0.85
_looks_like_data_rowFunction · 0.85
get_textMethod · 0.45