From 64915aa3f2a6ddeb23fc69b3d84b2fa326c445f3 Mon Sep 17 00:00:00 2001 From: Research Assistant Date: Mon, 8 Jun 2026 12:13:02 +0800 Subject: [PATCH] fix(ocr): prevent empty wikilinks for unresolved clusters in renderer --- paperforge/worker/ocr_render.py | 4 +-- tests/test_ocr_rendering.py | 61 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/paperforge/worker/ocr_render.py b/paperforge/worker/ocr_render.py index 3d8a1ff8..eee97a0a 100644 --- a/paperforge/worker/ocr_render.py +++ b/paperforge/worker/ocr_render.py @@ -695,8 +695,8 @@ def render_fulltext_markdown( tables_by_page.setdefault(page, []).append(tbl_id) unresolved_clusters_by_page: dict[int, list[str]] = {} - for cluster in figure_inventory.get("unresolved_clusters", []): - cluster_id = cluster.get("cluster_id", "") + for idx, cluster in enumerate(figure_inventory.get("unresolved_clusters", [])): + cluster_id = cluster.get("cluster_id") or f"unresolved_cluster_{idx + 1:03d}" page = cluster.get("page", 0) or 1 unresolved_clusters_by_page.setdefault(page, []).append(cluster_id) diff --git a/tests/test_ocr_rendering.py b/tests/test_ocr_rendering.py index 61f80c36..8b8870ee 100644 --- a/tests/test_ocr_rendering.py +++ b/tests/test_ocr_rendering.py @@ -2089,3 +2089,64 @@ def test_unresolved_cluster_appears_in_fulltext() -> None: ) assert "![[render/figures/cluster_001.md]]" in md + + +def test_unresolved_cluster_link_with_unresolved_cluster_id() -> None: + """Unresolved cluster with valid cluster_id produces correct wikilink.""" + from paperforge.worker.ocr_render import render_fulltext_markdown + + md = render_fulltext_markdown( + structured_blocks=[ + { + "role": "body_paragraph", + "text": "Body text on page 1.", + "render_default": True, + "page": 1, + }, + ], + resolved_metadata={}, + figure_inventory={ + "unresolved_clusters": [ + { + "cluster_id": "unresolved_cluster_001", + "page": 1, + "cluster_bbox": [363, 237, 1075, 1016], + "media_block_ids": [1, 2], + } + ] + }, + table_inventory={}, + ) + + assert "![[render/figures/unresolved_cluster_001.md]]" in md + assert "![[render/figures/.md]]" not in md + + +def test_unresolved_cluster_link_with_missing_id_is_defensive() -> None: + """When cluster_id is omitted, no empty wikilink is emitted.""" + from paperforge.worker.ocr_render import render_fulltext_markdown + + md = render_fulltext_markdown( + structured_blocks=[ + { + "role": "body_paragraph", + "text": "Body text on page 1.", + "render_default": True, + "page": 1, + }, + ], + resolved_metadata={}, + figure_inventory={ + "unresolved_clusters": [ + { + "page": 1, + "cluster_bbox": [363, 237, 1075, 1016], + "media_block_ids": [1, 2], + } + ] + }, + table_inventory={}, + ) + + assert "![[render/figures/.md]]" not in md + assert "![[render/figures/unresolved_cluster_001.md]]" in md