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"