mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-10 04:51:37 +00:00
Split edit-text paragraphs at headings and blank lines (#3642)
This commit is contained in:
1 parent
66a44f529e
commit
69571065b9
2 files changed
+27
-1
No files matched your search
@@ -5929,6 +5929,20 @@ fn replacing_a_line_keeps_a_distinct_nearby_line() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_blocks_split_at_headings_and_blank_lines() {
|
||||
let page = |size: u32, gap: u32, words: &[&str], top: u32| -> String {
|
||||
words.iter().enumerate().map(|(i, w)| format!("BT /F1 {size} Tf 40 {} Td ({w}) Tj ET\n", top - i as u32 * gap)).collect()
|
||||
};
|
||||
let count = |content: String| text::text_blocks(&text_page(&content), 0).unwrap().len();
|
||||
let heading = page(12, 14, &["First line of text", "second line here", "third line ends"], 340)
|
||||
+ &page(12, 14, &["HEADING"], 340 - 28 - 24)
|
||||
+ &page(12, 14, &["Next paragraph one", "next two", "next three"], 340 - 28 - 24 - 24);
|
||||
assert_eq!(count(heading), 3);
|
||||
assert_eq!(count(page(12, 14, &["Para one a", "para one b"], 340) + &page(12, 14, &["Para two a", "para two b"], 340 - 42)), 2);
|
||||
assert_eq!(count(page(24, 29, &["VISIBLE", "HIDDEN"], 340)), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn editing_text_keeps_an_overlapping_watermark_and_covered_paragraphs() {
|
||||
let listed = |doc: &Document| text::text_lines(doc, 0).unwrap().into_iter().map(|l| l.text).collect::<Vec<_>>();
|
||||
|
||||
@@ -331,7 +331,19 @@ fn group_layout(lines: &[TextLine], mixed: bool) -> Vec<TextBlock> {
|
||||
let scale = gap.abs().max(ngap.abs());
|
||||
if same && ngap > tol * 0.8 && scale < tol * 4.0 && (ngap - gap).abs() <= scale * 0.08 + 0.5 { Some(gap) } else { None }
|
||||
});
|
||||
let max_gap = own_leading.filter(|lead| *lead > tol * 0.4).or(stated).or(repeated).map_or(tol * 2.05, |lead| lead * 1.5);
|
||||
// A lone row with none of those: the step to the row after it is the leading of the
|
||||
// paragraph it opens, and the gap above it is a heading's or a blank line's when it
|
||||
// is much wider (#3577).
|
||||
let following = rows.get(row_at.saturating_add(1)).and_then(|next| {
|
||||
let nfirst = next.first().and_then(|i| lines.get(*i))?;
|
||||
let ngap = first.frame_origin().1 - nfirst.frame_origin().1;
|
||||
(same_plane(first, nfirst) && ngap > tol * 0.8 && ngap < tol * 2.05).then_some(ngap)
|
||||
});
|
||||
let max_gap = own_leading
|
||||
.filter(|lead| *lead > tol * 0.4)
|
||||
.or(stated)
|
||||
.or(repeated)
|
||||
.map_or_else(|| following.map_or(tol * 2.05, |lead| (lead * 1.35).min(tol * 2.05)), |lead| lead * 1.5);
|
||||
// OCR lines stay apart: the scan fixes where each one is, so they never rewrap together.
|
||||
(!mixed || !(invisible(prev) || invisible(first)))
|
||||
&& (mixed || same_style(prev, first))
|
||||
|
||||
Reference in new issue
Block a user