diff --git a/crates/typst-library/src/layout/dir.rs b/crates/typst-library/src/layout/dir.rs index 9a2e77105..699c8c481 100644 --- a/crates/typst-library/src/layout/dir.rs +++ b/crates/typst-library/src/layout/dir.rs @@ -50,6 +50,42 @@ impl Dir { pub const TTB: Self = Self::TTB; pub const BTT: Self = Self::BTT; + /// Returns a direction from a starting point. + /// + /// ```example + /// direction.from(left) \ + /// direction.from(right) \ + /// direction.from(top) \ + /// direction.from(bottom) + /// ``` + #[func] + pub const fn from(side: Side) -> Dir { + match side { + Side::Left => Self::LTR, + Side::Right => Self::RTL, + Side::Top => Self::TTB, + Side::Bottom => Self::BTT, + } + } + + /// Returns a direction from an end point. + /// + /// ```example + /// direction.to(left) \ + /// direction.to(right) \ + /// direction.to(top) \ + /// direction.to(bottom) + /// ``` + #[func] + pub const fn to(side: Side) -> Dir { + match side { + Side::Right => Self::LTR, + Side::Left => Self::RTL, + Side::Bottom => Self::TTB, + Side::Top => Self::BTT, + } + } + /// The axis this direction belongs to, either `{"horizontal"}` or /// `{"vertical"}`. /// @@ -65,6 +101,22 @@ impl Dir { } } + /// The corresponding sign, for use in calculations. + /// + /// ```example + /// #ltr.sign() \ + /// #rtl.sign() \ + /// #ttb.sign() \ + /// #btt.sign() + /// ``` + #[func] + pub const fn sign(self) -> i64 { + match self { + Self::LTR | Self::TTB => 1, + Self::RTL | Self::BTT => -1, + } + } + /// The start point of this direction, as an alignment. /// /// ```example diff --git a/tests/suite/layout/dir.typ b/tests/suite/layout/dir.typ index 139a2285d..e6db54da5 100644 --- a/tests/suite/layout/dir.typ +++ b/tests/suite/layout/dir.typ @@ -1,10 +1,35 @@ +--- dir-from --- +#test(direction.from(left), ltr) +#test(direction.from(right), rtl) +#test(direction.from(top), ttb) +#test(direction.from(bottom), btt) + +--- dir-from-invalid --- +// Error: 17-23 cannot convert this alignment to a side +#direction.from(center) + +--- dir-to --- +#test(direction.to(left), rtl) +#test(direction.to(right), ltr) +#test(direction.to(top), btt) +#test(direction.to(bottom), ttb) + +-- dir-to-invalid --- +// Error: 15-21 cannot convert this alignment to a side +#direction.to(center) + --- dir-axis --- -// Test direction methods. #test(ltr.axis(), "horizontal") #test(rtl.axis(), "horizontal") #test(ttb.axis(), "vertical") #test(btt.axis(), "vertical") +--- dir-sign --- +#test(ltr.sign(), 1) +#test(rtl.sign(), -1) +#test(ttb.sign(), 1) +#test(btt.sign(), -1) + --- dir-start --- #test(ltr.start(), left) #test(rtl.start(), right)