Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
996962d344 |
@@ -1158,14 +1158,19 @@ fn propagate_merged_cells(
|
|||||||
|
|
||||||
// Find first and last grid rows that the rect spans.
|
// Find first and last grid rows that the rect spans.
|
||||||
//
|
//
|
||||||
// A merged-cell rect CONTAINS the rows it spans — its bottom sits
|
// Require a rect to actually overlap the row by more than `tol`
|
||||||
// at or below the row bottom and its top sits at or above the row
|
// to count as a span. A "rect bottom ≤ row top + tol AND rect
|
||||||
// top (within tol). A pure overlap check (any overlap within tol)
|
// top ≥ row bottom − tol" check gives false positives at shared
|
||||||
// gives false positives at shared row boundaries: a rect whose
|
// row boundaries — a rect whose top equals row N's bottom lies
|
||||||
// top equals row N's bottom would be considered to span row N
|
// entirely below the row but still passes the tolerance-slack
|
||||||
// even though it lies entirely below, cascading body text from
|
// check, cascading body text from unrelated rows into one
|
||||||
// unrelated rows into a single header cell.
|
// merged cell.
|
||||||
let spans = |r: usize| ry <= row_edges[r + 1] + tol && (ry + rh) >= row_edges[r] - tol;
|
let spans = |r: usize| {
|
||||||
|
let row_top = row_edges[r];
|
||||||
|
let row_bot = row_edges[r + 1];
|
||||||
|
let overlap = (row_top.min(ry + rh) - row_bot.max(ry)).max(0.0);
|
||||||
|
overlap > tol
|
||||||
|
};
|
||||||
let first_row = (0..num_rows).find(|&r| spans(r));
|
let first_row = (0..num_rows).find(|&r| spans(r));
|
||||||
let last_row = (0..num_rows).rfind(|&r| spans(r));
|
let last_row = (0..num_rows).rfind(|&r| spans(r));
|
||||||
|
|
||||||
@@ -1674,6 +1679,49 @@ fn detect_row_stripe_table_from_cell_rects(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reject "tables" that are actually prose in a framed region.
|
||||||
|
// Columns here come from text X-position clustering; when prose wraps
|
||||||
|
// inside a bounding-box rect (e.g. chat-transcript figures) the
|
||||||
|
// word-boundary gaps cluster into many spurious columns, and the
|
||||||
|
// resulting cells hold sentence fragments riddled with common English
|
||||||
|
// function words. Count cells with any such word and reject when
|
||||||
|
// 20%+ of non-empty cells match — real tabular data (labels, units,
|
||||||
|
// numbers) rarely contains these words.
|
||||||
|
if num_cols >= 4 {
|
||||||
|
const PROSE_WORDS: &[&str] = &[
|
||||||
|
"a", "an", "the", "of", "to", "is", "was", "are", "were", "be", "been", "in", "on",
|
||||||
|
"at", "with", "for", "by", "as", "and", "or", "but", "this", "that", "these", "those",
|
||||||
|
"from", "into", "has", "have", "had", "not", "don't", "doesn't", "it's", "its", "it",
|
||||||
|
"i", "me", "my", "we", "our", "us", "you", "your", "they", "them", "their", "he",
|
||||||
|
"she", "his", "her",
|
||||||
|
];
|
||||||
|
let mut prose_cells = 0usize;
|
||||||
|
let mut counted = 0usize;
|
||||||
|
for row in &cells {
|
||||||
|
for cell in row {
|
||||||
|
let t = cell.trim();
|
||||||
|
if t.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
counted += 1;
|
||||||
|
let lower = t.to_ascii_lowercase();
|
||||||
|
let has_prose_word = lower
|
||||||
|
.split(|c: char| !c.is_ascii_alphabetic() && c != '\'')
|
||||||
|
.any(|w| PROSE_WORDS.contains(&w));
|
||||||
|
if has_prose_word {
|
||||||
|
prose_cells += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if counted > 0 && prose_cells * 5 >= counted {
|
||||||
|
debug!(
|
||||||
|
" cell-rect rejected: {}/{} cells contain prose function words — likely prose",
|
||||||
|
prose_cells, counted
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let column_centers: Vec<f32> = (0..num_cols)
|
let column_centers: Vec<f32> = (0..num_cols)
|
||||||
.map(|c| (col_edges[c] + col_edges[c + 1]) / 2.0)
|
.map(|c| (col_edges[c] + col_edges[c + 1]) / 2.0)
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@@ -157,14 +157,33 @@ section and paragraph
|
|||||||
|§1.6043-2(a)|or 1.1081-11|3T(a), or §1.1081-11T|
|
|§1.6043-2(a)|or 1.1081-11|3T(a), or §1.1081-11T|
|
||||||
|The first sentence of §301.6011-5T(a) (twice)|§1.6012-2|paragraphs (a), (b) and (d) through (j) of §1.6012- 2, and paragraph (c) of §1.6012-2T|
|
|The first sentence of §301.6011-5T(a) (twice)|§1.6012-2|paragraphs (a), (b) and (d) through (j) of §1.6012- 2, and paragraph (c) of §1.6012-2T|
|
||||||
|
|
||||||
|||PART 602--OMB CONTROL NUMBERS UNDER THE PAPERWORK||
|
PART 602--OMB CONTROL NUMBERS UNDER THE PAPERWORK REDUCTION ACT Par. 54. The authority citation for part 602 continues to read as follows: Authority: 26 U.S.C. 7805. Par. 55. In §602.101, paragraph (b) is amended to read as follows:
|
||||||
|---|---|---|---|
|
|
||||||
||REDUCTION ACT Authority: 26 U.S.C. 7805. 1. The following entries to the table are removed: §602.101 OMB Control numbers.|Par. 54. The authority citation for part 602 continues to read as follows: Par. 55. In §602.101, paragraph (b) is amended to read as follows:||
|
1. The following entries to the table are removed:
|
||||||
|* * * * *|(b) * * * CFR part or section where identified or described||Current OMB control No.|
|
§602.101 OMB Control numbers.
|
||||||
|* * * * *|1.332-6………………………………………………………………….|1.382-11……………………………………………………………….. 1545-2019 1.351-3…………………………………………………………………. 1545-2019 1.355-5…………………………………………………………………. 1545-2019 1.368-3…………………………………………………………………. 1545-2019 1.1081-11………………………………………………………………. 1545-2019|1545-2019|
|
|
||||||
|* * * * *|§602.101 OMB Control numbers.|______________________________________________________________ 2. The following entries are added in numerical order to the table:||
|
* * * * *
|
||||||
|* * * * *|(b) * * * CFR part or section where identified or described||Current OMB control No.|
|
(b) * * *
|
||||||
|* * * * *|1.302-2T………………………………………………………………… 1545 1.302-4T………………………………………………………………… 1545||-2019 -2019|
|
CFR part or section where Current OMB identified or described control No.
|
||||||
|
|
||||||
|
* * * * *
|
||||||
|
1.332-6…………………………………………………………………. 1545-2019
|
||||||
|
1.382-11……………………………………………………………….. 1545-2019
|
||||||
|
1.351-3…………………………………………………………………. 1545-2019
|
||||||
|
1.355-5…………………………………………………………………. 1545-2019
|
||||||
|
1.368-3…………………………………………………………………. 1545-2019
|
||||||
|
1.1081-11………………………………………………………………. 1545-2019
|
||||||
|
* * * * * **______________________________________________________________**
|
||||||
|
2. The following entries are added in numerical order to the table:
|
||||||
|
§602.101 OMB Control numbers.
|
||||||
|
|
||||||
|
* * * * *
|
||||||
|
(b) * * *
|
||||||
|
CFR part or section where Current OMB identified or described control No.
|
||||||
|
|
||||||
|
* * * * *
|
||||||
|
1.302-2T………………………………………………………………… 1545-2019
|
||||||
|
1.302-4T………………………………………………………………… 1545-2019
|
||||||
|
|
||||||
|1.331-1T………………………………………………………………… 1545|-2019|
|
|1.331-1T………………………………………………………………… 1545|-2019|
|
||||||
|---|---|
|
|---|---|
|
||||||
|
|||||||
Reference in New Issue
Block a user