diff --git a/crates/typst/src/layout/inline/mod.rs b/crates/typst/src/layout/inline/mod.rs index 667421fd5..cb1afa1e0 100644 --- a/crates/typst/src/layout/inline/mod.rs +++ b/crates/typst/src/layout/inline/mod.rs @@ -432,6 +432,8 @@ fn collect<'a>( segments.push((Segment::Spacing((-hang).into()), *styles)); } + let outer_dir = TextElem::dir_in(*styles); + while let Some(mut child) = iter.next() { let outer = styles; let mut styles = *styles; @@ -445,11 +447,26 @@ fn collect<'a>( Segment::Text(1) } else if let Some(elem) = child.to_packed::() { let prev = full.len(); + let dir = TextElem::dir_in(styles); + if dir != outer_dir { + // Insert "Explicit Directional Isolate". + match dir { + Dir::LTR => full.push('\u{2066}'), + Dir::RTL => full.push('\u{2067}'), + _ => {} + } + } + if let Some(case) = TextElem::case_in(styles) { full.push_str(&case.apply(elem.text())); } else { full.push_str(elem.text()); } + + if dir != outer_dir { + // Insert "Pop Directional Isolate". + full.push('\u{2069}'); + } Segment::Text(full.len() - prev) } else if let Some(elem) = child.to_packed::() { if elem.amount().is_zero() { diff --git a/tests/ref/layout/par-bidi.png b/tests/ref/layout/par-bidi.png index 8b626b2a7..4750ccb88 100644 Binary files a/tests/ref/layout/par-bidi.png and b/tests/ref/layout/par-bidi.png differ diff --git a/tests/typ/layout/par-bidi.typ b/tests/typ/layout/par-bidi.typ index f708df6a8..edbd75e16 100644 --- a/tests/typ/layout/par-bidi.typ +++ b/tests/typ/layout/par-bidi.typ @@ -47,6 +47,13 @@ Lריווח #h(1cm) R // Test whether L1 whitespace resetting destroys stuff. الغالب #h(70pt) ن#" "ة +--- +// Test explicit dir +#set text(dir: rtl) +#text("8:00 - 9:00",dir:ltr) בבוקר +#linebreak() +ב #text("12:00 - 13:00",dir:ltr) בצהריים + --- // Test setting a vertical direction. // Ref: false