diff --git a/crates/typst-library/src/text/linebreak.rs b/crates/typst-library/src/text/linebreak.rs index 8fd48df1e..3992d54d2 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. diff --git a/tests/ref/text/linebreak-link.png b/tests/ref/text/linebreak-link.png index ab4e580f9..ffe39caa3 100644 Binary files a/tests/ref/text/linebreak-link.png and b/tests/ref/text/linebreak-link.png differ diff --git a/tests/typ/text/linebreak-link.typ b/tests/typ/text/linebreak-link.typ index 18b6d936b..9f6407fae 100644 --- a/tests/typ/text/linebreak-link.typ +++ b/tests/typ/text/linebreak-link.typ @@ -14,3 +14,10 @@ Here's a link https://url.com/data/extern12840%data_urlenc and then there are more links #link("www.url.com/data/extern12840%data_urlenc") in my text of links http://mydataurl/hash/12098541029831025981024980124124214/incremental/progress%linkdata_information_setup_my_link_just_never_stops_going/on?query=false + +--- +// Ensure that there's no unconditional break at the end of a link. +#set page(width: 180pt, height: auto, margin: auto) +#set text(11pt) + +For info see #link("https://myhost.tld").