From ea987ef4a3cb1e16b73e9d97f4a736f3a611b275 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 19 Nov 2023 15:53:24 +0100 Subject: Fix linebreaking at the end of links Fixes #2689 --- crates/typst-library/src/text/linebreak.rs | 35 +++++++++++++----------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'crates/typst-library') diff --git a/crates/typst-library/src/text/linebreak.rs b/crates/typst-library/src/text/linebreak.rs index 8fd48df1..3992d54d 100644 --- a/crates/typst-library/src/text/linebreak.rs +++ b/crates/typst-library/src/text/linebreak.rs @@ -101,7 +101,7 @@ pub(crate) fn breakpoints<'a>( let (link, _) = link_prefix(tail); let end = last + link.len(); linebreak_link(link, |i| f(last + i, Breakpoint::Normal)); - while iter.peek().map_or(false, |&p| p <= end) { + while iter.peek().map_or(false, |&p| p < end) { iter.next(); } } @@ -206,23 +206,8 @@ fn linebreak_link(link: &str, mut f: impl FnMut(usize)) { } let mut offset = 0; - let mut emit = |end: usize| { - let piece = &link[offset..end]; - if piece.len() < 16 { - // For bearably long segments, emit them as one. - offset = end; - f(offset); - } else { - // If it gets very long (e.g. a hash in the URL), just allow a - // break at every char. - for c in piece.chars() { - offset += c.len_utf8(); - f(offset); - } - } - }; - let mut prev = Class::Other; + for (end, c) in link.char_indices() { let class = Class::of(c); @@ -235,13 +220,23 @@ fn linebreak_link(link: &str, mut f: impl FnMut(usize)) { && prev != Class::Open && if class == Class::Other { prev == Class::Other } else { class != prev } { - emit(end); + let piece = &link[offset..end]; + if piece.len() < 16 { + // For bearably long segments, emit them as one. + offset = end; + f(offset); + } else { + // If it gets very long (e.g. a hash in the URL), just allow a + // break at every char. + for c in piece.chars() { + offset += c.len_utf8(); + f(offset); + } + } } prev = class; } - - emit(link.len()); } /// Whether hyphenation is enabled at the given offset. -- cgit v1.2.3