From 009be8c9584100d2e85fd8b3ad0a554e0a8a89e2 Mon Sep 17 00:00:00 2001 From: Research Assistant Date: Fri, 5 Jun 2026 15:02:00 +0800 Subject: [PATCH] fix: stop paper_title pollution, text-to-heading, table HTML leak, author recovery --- paperforge/worker/ocr_blocks.py | 2 +- paperforge/worker/ocr_metadata.py | 20 ++++++++--------- paperforge/worker/ocr_render.py | 4 +++- paperforge/worker/ocr_roles.py | 36 ++++++++++++++++++++++++++----- tests/test_ocr_roles.py | 2 +- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/paperforge/worker/ocr_blocks.py b/paperforge/worker/ocr_blocks.py index abd6552f..4821d999 100644 --- a/paperforge/worker/ocr_blocks.py +++ b/paperforge/worker/ocr_blocks.py @@ -25,7 +25,7 @@ def build_structured_blocks(raw_blocks: list[dict]) -> list[dict]: index_default = True if role.role in {"noise", "page_header", "page_footer", "frontmatter_noise"}: render_default = False - if role.role in {"noise", "frontmatter_noise"}: + if role.role in {"noise", "frontmatter_noise", "table_html"}: index_default = False row = { "paper_id": block["paper_id"], diff --git a/paperforge/worker/ocr_metadata.py b/paperforge/worker/ocr_metadata.py index cdb634f6..6d8a6143 100644 --- a/paperforge/worker/ocr_metadata.py +++ b/paperforge/worker/ocr_metadata.py @@ -78,29 +78,27 @@ def resolve_metadata( # --- authors --- zotero_authors = source_metadata.get("authors", []) + ocr_authors_text = frontmatter_candidates.get("authors_text", "") + ocr_author_list = [a.strip() for a in ocr_authors_text.split(",") if a.strip()] if ocr_authors_text else [] + if isinstance(zotero_authors, list) and len(zotero_authors) > 0: resolved["authors"] = { "value": zotero_authors, "source": "zotero", "confidence": 0.99, } + elif ocr_author_list: + resolved["authors"] = { + "value": ocr_author_list, + "source": "ocr_frontmatter", + "confidence": 0.6, + } else: resolved["authors"] = { "value": [], "source": "unknown", "confidence": 0.3, } - ocr_authors_text = frontmatter_candidates.get("authors_text", "") - if ocr_authors_text: - ocr_author_list = [a.strip() for a in ocr_authors_text.split(",") if a.strip()] - if ocr_author_list and ocr_author_list != zotero_authors: - resolved["authors"]["alternatives"] = [ - { - "value": ocr_author_list, - "source": "ocr_frontmatter", - "confidence": 0.6, - } - ] # --- year --- zotero_year = source_metadata.get("year", 0) diff --git a/paperforge/worker/ocr_render.py b/paperforge/worker/ocr_render.py index 87e6bd1f..ea981ab7 100644 --- a/paperforge/worker/ocr_render.py +++ b/paperforge/worker/ocr_render.py @@ -92,10 +92,12 @@ def render_fulltext_markdown( if not block.get("render_default", True): continue role = block.get("role", "") - if role in ("abstract_heading", "abstract_body", "figure_caption", "table_caption", "frontmatter_noise"): + if role in ("abstract_heading", "abstract_body", "figure_caption", "table_caption", "frontmatter_noise", "table_html"): continue text = _normalize_latex(block.get("text", "")) + if text.strip().lower().startswith(" None: from paperforge.worker.ocr_roles import assign_block_role assignment = assign_block_role( - block={"block_label": "paragraph_title", "block_content": "Test Paper About Science"}, + block={"block_label": "paragraph_title", "block_content": "Test Paper About Science", "page": 1}, page_blocks=[], )