summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-11-19 15:53:24 +0100
committerLaurenz <laurmaedje@gmail.com>2023-11-19 15:53:48 +0100
commitea987ef4a3cb1e16b73e9d97f4a736f3a611b275 (patch)
treef6d75ee593194a5604f1c364fe6fb209158253a0
parent18cb3becb32b1c2424a82ad847d890732ccee878 (diff)
Fix linebreaking at the end of links
Fixes #2689
-rw-r--r--crates/typst-library/src/text/linebreak.rs35
-rw-r--r--tests/ref/text/linebreak-link.pngbin66990 -> 65582 bytes
-rw-r--r--tests/typ/text/linebreak-link.typ7
3 files changed, 22 insertions, 20 deletions
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.
diff --git a/tests/ref/text/linebreak-link.png b/tests/ref/text/linebreak-link.png
index ab4e580f..ffe39caa 100644
--- a/tests/ref/text/linebreak-link.png
+++ b/tests/ref/text/linebreak-link.png
Binary files differ
diff --git a/tests/typ/text/linebreak-link.typ b/tests/typ/text/linebreak-link.typ
index 18b6d936..9f6407fa 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").