summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-07-18 10:49:08 +0200
committerGitHub <noreply@github.com>2024-07-18 08:49:08 +0000
commit42754477886f6a12afbabfd2a64d8c787a57bc03 (patch)
treeaebc0a0de9ac8fb239db372079789d839876f9cd
parent0ea4b1b217b2b5b902dca8e6e6ce11e1890afd40 (diff)
Fix panic in link linebreaking (#4579)
-rw-r--r--crates/typst/src/layout/inline/linebreak.rs12
-rw-r--r--tests/ref/issue-hyphenate-in-link.pngbin0 -> 1200 bytes
-rw-r--r--tests/suite/layout/inline/linebreak.typ8
3 files changed, 13 insertions, 7 deletions
diff --git a/crates/typst/src/layout/inline/linebreak.rs b/crates/typst/src/layout/inline/linebreak.rs
index 075d24b3..1f30bb73 100644
--- a/crates/typst/src/layout/inline/linebreak.rs
+++ b/crates/typst/src/layout/inline/linebreak.rs
@@ -655,9 +655,9 @@ fn breakpoints(p: &Preparation, mut f: impl FnMut(usize, Breakpoint)) {
let (head, tail) = text.split_at(last);
if head.ends_with("://") || tail.starts_with("www.") {
let (link, _) = link_prefix(tail);
- let end = last + link.len();
linebreak_link(link, |i| f(last + i, Breakpoint::Normal));
- while iter.peek().is_some_and(|&p| p < end) {
+ last += link.len();
+ while iter.peek().is_some_and(|&p| p < last) {
iter.next();
}
}
@@ -687,19 +687,17 @@ fn breakpoints(p: &Preparation, mut f: impl FnMut(usize, Breakpoint)) {
};
// Hyphenate between the last and current breakpoint.
- if hyphenate {
- let mut offset = last;
+ if hyphenate && last < point {
for segment in text[last..point].split_word_bounds() {
if !segment.is_empty() && segment.chars().all(char::is_alphabetic) {
- hyphenations(p, &lb, offset, segment, &mut f);
+ hyphenations(p, &lb, last, segment, &mut f);
}
- offset += segment.len();
+ last += segment.len();
}
}
// Call `f` for the UAX #14 break opportunity.
f(point, breakpoint);
-
last = point;
}
}
diff --git a/tests/ref/issue-hyphenate-in-link.png b/tests/ref/issue-hyphenate-in-link.png
new file mode 100644
index 00000000..932c23ae
--- /dev/null
+++ b/tests/ref/issue-hyphenate-in-link.png
Binary files differ
diff --git a/tests/suite/layout/inline/linebreak.typ b/tests/suite/layout/inline/linebreak.typ
index 2fa29b6c..7e959352 100644
--- a/tests/suite/layout/inline/linebreak.typ
+++ b/tests/suite/layout/inline/linebreak.typ
@@ -107,3 +107,11 @@ For info see #link("https://myhost.tld").
#set page(width: 50pt, height: auto)
#h(99%) 🏳️‍🌈
🏳️‍🌈
+
+--- issue-hyphenate-in-link ---
+#set par(justify: true)
+
+// The `linebreak()` function accidentally generated out-of-order breakpoints
+// for links because it now splits on word boundaries. We avoid the link markup
+// syntax because it's show rule interferes.
+#"http://creativecommons.org/licenses/by-nc-sa/4.0/"