From 88116cf2623ea8738723aaef4408ac0c3667aea2 Mon Sep 17 00:00:00 2001 From: Research Assistant Date: Thu, 25 Jun 2026 16:14:32 +0800 Subject: [PATCH] fix: normalize OCR heading newlines and fix single-word heading level --- paperforge/worker/ocr_blocks.py | 5 +++++ paperforge/worker/ocr_roles.py | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/paperforge/worker/ocr_blocks.py b/paperforge/worker/ocr_blocks.py index 3c35d89e..4978e830 100644 --- a/paperforge/worker/ocr_blocks.py +++ b/paperforge/worker/ocr_blocks.py @@ -79,6 +79,11 @@ def _merge_adjacent_headings(rows: list[dict]) -> None: return 0 return m.group(1).count(".") + 1 + # Normalize OCR line breaks within paragraph_title blocks + for row in rows: + if row.get("raw_label") == "paragraph_title": + row["text"] = (row.get("text") or "").replace("\n", " ") + def _case_style(b: dict) -> str: t = str(b.get("text", "") or "") if not t: diff --git a/paperforge/worker/ocr_roles.py b/paperforge/worker/ocr_roles.py index ed27cf39..ef974b6a 100644 --- a/paperforge/worker/ocr_roles.py +++ b/paperforge/worker/ocr_roles.py @@ -461,7 +461,9 @@ def _infer_heading_level( sentence_verbs = {" is ", " are ", " was ", " were ", " have ", " has ", " been "} has_sentence_verb = any(v in text.lower() for v in sentence_verbs) word_count = len(text.split()) - if is_mostly_upper and word_count >= 1 and not has_sentence_verb: + # ponytail: all-caps single-word headings (e.g. "MCUb", "EMRE") are + # sub-subsection headings, not top-level section headings + if is_mostly_upper and word_count >= 2 and not has_sentence_verb: return "section_heading" if word_count >= 2 and not has_sentence_verb: return "subsection_heading"