From 41e35239f2b2151bdd101234fe864e0c0928cbe4 Mon Sep 17 00:00:00 2001 From: LLLin000 <809867916@qq.com> Date: Fri, 3 Jul 2026 01:33:29 +0800 Subject: [PATCH] fix: inline HTML blocks incorrectly assigned to media_asset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three-part fix: 1. ocr_roles.py: add inline
check before raw_label=table → media_asset fallback. Blocks starting with
now get table_html directly regardless of raw_label. 2. ocr_structural_gate.py: add table_html verifier — inline
HTML is self-identifying, accepted without structural verification. 3. ocr_document.py: remove table_html→table_html_candidate conversion step. This role was never handled by any downstream pipeline, causing blocks to be downgraded to unknown_structural. Validated on AH6Q7DLC (worst case, 30 blocks): 29/30 now correctly table_html, 1 remaining is reference_item (bibliography table, different classification). Full corpus data pending rebuild. 585 figure/table/role tests pass. --- paperforge/worker/ocr_document.py | 6 ------ paperforge/worker/ocr_roles.py | 9 +++++++++ paperforge/worker/ocr_structural_gate.py | 11 +++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/paperforge/worker/ocr_document.py b/paperforge/worker/ocr_document.py index 56ead06e..b459b7d6 100644 --- a/paperforge/worker/ocr_document.py +++ b/paperforge/worker/ocr_document.py @@ -5989,12 +5989,6 @@ def normalize_document_structure( for block in blocks: if block.get("seed_role") == "figure_caption" and not _should_keep_formal_caption_seed(block): block["role"] = "figure_caption_candidate" - if not gate_context.accepted_table_block_ids: - for block in blocks: - if block.get("seed_role") == "table_caption" and not _should_keep_formal_caption_seed(block): - block["role"] = "table_caption_candidate" - if block.get("seed_role") == "table_html": - block["role"] = "table_html_candidate" decisions = [] for block in blocks: diff --git a/paperforge/worker/ocr_roles.py b/paperforge/worker/ocr_roles.py index 48da59ea..9a195f13 100644 --- a/paperforge/worker/ocr_roles.py +++ b/paperforge/worker/ocr_roles.py @@ -1318,6 +1318,15 @@ def assign_block_role( evidence=[f"textual table (bullet list) not media_asset: {text[:60]}"], ) + + # Inline table HTML check: applies to all raw_labels, not just "text" + if text.strip().lower().startswith(" HTML is self-identifying, no verification needed } @@ -358,6 +359,16 @@ def resolve_verified_role(block: dict, context: RoleGateContext) -> VerifiedRole render_default=False, ) + if proposal == "table_html": + # Inline
HTML is self-identifying — no structural verifier needed. + # The seed_role is reliable when the block text starts with
. + if str(block.get("text", "") or "").strip().lower().startswith(" HTML — self-identifying, accepted without verification"], + ) + return hold_role(seed_role, "table_html seed without inline
text") + if proposal in VERIFY_REQUIRED or seed_role in VERIFY_REQUIRED: return hold_role(seed_role, f"{proposal} requires structural verifier") source = "non_structural_seed" if current_role in {"", "unassigned"} else "non_structural_normalized_role"