From be7cfc85d08c545abfac08098b7b33b4bd71f37e Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 27 Oct 2024 19:04:55 +0100 Subject: Split out four new crates (#5302) --- crates/typst-library/src/layout/stack.rs | 84 ++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 crates/typst-library/src/layout/stack.rs (limited to 'crates/typst-library/src/layout/stack.rs') diff --git a/crates/typst-library/src/layout/stack.rs b/crates/typst-library/src/layout/stack.rs new file mode 100644 index 00000000..5fc78480 --- /dev/null +++ b/crates/typst-library/src/layout/stack.rs @@ -0,0 +1,84 @@ +use std::fmt::{self, Debug, Formatter}; + +use crate::diag::SourceResult; +use crate::engine::Engine; +use crate::foundations::{cast, elem, Content, NativeElement, Packed, Show, StyleChain}; +use crate::layout::{BlockElem, Dir, Spacing}; + +/// Arranges content and spacing horizontally or vertically. +/// +/// The stack places a list of items along an axis, with optional spacing +/// between each item. +/// +/// # Example +/// ```example +/// #stack( +/// dir: ttb, +/// rect(width: 40pt), +/// rect(width: 120pt), +/// rect(width: 90pt), +/// ) +/// ``` +#[elem(Show)] +pub struct StackElem { + /// The direction along which the items are stacked. Possible values are: + /// + /// - `{ltr}`: Left to right. + /// - `{rtl}`: Right to left. + /// - `{ttb}`: Top to bottom. + /// - `{btt}`: Bottom to top. + /// + /// You can use the `start` and `end` methods to obtain the initial and + /// final points (respectively) of a direction, as `alignment`. You can also + /// use the `axis` method to determine whether a direction is + /// `{"horizontal"}` or `{"vertical"}`. The `inv` method returns a + /// direction's inverse direction. + /// + /// For example, `{ttb.start()}` is `top`, `{ttb.end()}` is `bottom`, + /// `{ttb.axis()}` is `{"vertical"}` and `{ttb.inv()}` is equal to `btt`. + #[default(Dir::TTB)] + pub dir: Dir, + + /// Spacing to insert between items where no explicit spacing was provided. + pub spacing: Option, + + /// The children to stack along the axis. + #[variadic] + pub children: Vec, +} + +impl Show for Packed { + fn show(&self, engine: &mut Engine, _: StyleChain) -> SourceResult { + Ok(BlockElem::multi_layouter(self.clone(), engine.routines.layout_stack) + .pack() + .spanned(self.span())) + } +} + +/// A child of a stack element. +#[derive(Clone, PartialEq, Hash)] +pub enum StackChild { + /// Spacing between other children. + Spacing(Spacing), + /// Arbitrary block-level content. + Block(Content), +} + +impl Debug for StackChild { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + Self::Spacing(kind) => kind.fmt(f), + Self::Block(block) => block.fmt(f), + } + } +} + +cast! { + StackChild, + self => match self { + Self::Spacing(spacing) => spacing.into_value(), + Self::Block(content) => content.into_value(), + }, + v: Spacing => Self::Spacing(v), + v: Content => Self::Block(v), +} -- cgit v1.2.3