fix: prevent author bylines from becoming section headings

This commit is contained in:
Research Assistant 2026-06-07 11:45:11 +08:00
parent dcc07140b0
commit 6bdaddb366
2 changed files with 47 additions and 0 deletions

View file

@ -482,6 +482,27 @@ def assign_block_role(
f"backmatter {'boundary heading' if role_name == 'backmatter_boundary_heading' else 'boundary candidate'}: {text[:60]}"
],
)
# Author-like heading guard: prevent bylines from becoming headings
_is_author_byline = (
re.search(r"&|,.*,", text)
and len(text.split()) <= 15
and not _has_heading_numbering(text)
and not any(text.lower().startswith(w) for w in ["abstract", "introduction", "methods", "results", "discussion", "conclusion", "references"])
)
if _is_author_byline and page_num == 1:
return RoleAssignment(
role="frontmatter_noise",
confidence=0.5,
evidence=[f"author byline on page 1, not heading: {text[:60]}"],
)
if re.search(r"(?:correspondence|orcid|@)", text.lower()) and len(text.split()) <= 20 and page_num == 1:
return RoleAssignment(
role="frontmatter_noise",
confidence=0.5,
evidence=[f"correspondence/noise on page 1: {text[:60]}"],
)
if _has_heading_numbering(text):
depth = _heading_number_depth(text)
return RoleAssignment(

View file

@ -490,6 +490,32 @@ def test_weak_backmatter_boundary_signal_emits_candidate():
)
def test_author_byline_not_section_heading():
from paperforge.worker.ocr_roles import assign_block_role
# Author byline with & on page 1
block = {"block_label": "paragraph_title", "block_content": "John Smith & Jane Doe", "block_bbox": [100, 50, 500, 80], "page": 1}
page_blocks = [block,
{"block_label": "text", "block_content": "Some frontmatter", "block_bbox": [100, 100, 500, 130], "page": 1},
{"block_label": "text", "block_content": "Some abstract content", "block_bbox": [100, 200, 500, 230], "page": 1},
]
result = assign_block_role(block, page_blocks=page_blocks, page_width=600, page_height=800)
assert result.role not in ("section_heading", "subsection_heading", "sub_subsection_heading"), (
f"Author byline got heading role: {result.role}"
)
def test_correspondence_marker_not_heading():
from paperforge.worker.ocr_roles import assign_block_role
block = {"block_label": "paragraph_title", "block_content": "*Correspondence: john@example.com", "block_bbox": [100, 500, 500, 530], "page": 1}
page_blocks = [block]
result = assign_block_role(block, page_blocks=page_blocks, page_width=600, page_height=800)
assert result.role in ("frontmatter_noise", "unknown_structural"), (
f"Correspondence got role: {result.role}"
)
def test_backmatter_boundary_detects_on_early_page() -> None:
"""Backmatter boundary should be detectable on papers with fewer
than 8 pages, without a hard page gate."""