summaryrefslogtreecommitdiff
path: root/library/src/layout/list.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-07-02 19:59:52 +0200
committerLaurenz <laurmaedje@gmail.com>2023-07-02 20:07:43 +0200
commitebfdb1dafa430786db10dad2ef7d5467c1bdbed1 (patch)
tree2bbc24ddb4124c4bb14dec0e536129d4de37b056 /library/src/layout/list.rs
parent3ab19185093d7709f824b95b979060ce125389d8 (diff)
Move everything into `crates/` directory
Diffstat (limited to 'library/src/layout/list.rs')
-rw-r--r--library/src/layout/list.rs239
1 files changed, 0 insertions, 239 deletions
diff --git a/library/src/layout/list.rs b/library/src/layout/list.rs
deleted file mode 100644
index e39ec3f5..00000000
--- a/library/src/layout/list.rs
+++ /dev/null
@@ -1,239 +0,0 @@
-use crate::layout::{BlockElem, ParElem, Sizing, Spacing};
-use crate::prelude::*;
-use crate::text::TextElem;
-
-use super::GridLayouter;
-
-/// A bullet list.
-///
-/// Displays a sequence of items vertically, with each item introduced by a
-/// marker.
-///
-/// ## Example { #example }
-/// ```example
-/// - *Content*
-/// - Text
-/// - Math
-/// - Layout
-/// - Visualize
-/// - Meta
-/// - Symbols
-///
-/// - *Compute*
-/// #list(
-/// [Foundations],
-/// [Calculate],
-/// [Construct],
-/// [Data Loading],
-/// )
-/// ```
-///
-/// ## Syntax { #syntax }
-/// This functions also has dedicated syntax: Start a line with a hyphen,
-/// followed by a space to create a list item. A list item can contain multiple
-/// paragraphs and other block-level content. All content that is indented
-/// more than an item's hyphen becomes part of that item.
-///
-/// Display: Bullet List
-/// Category: layout
-#[element(Layout)]
-#[scope(
- scope.define("item", ListItem::func());
- scope
-)]
-pub struct ListElem {
- /// If this is `{false}`, the items are spaced apart with [list
- /// spacing]($func/list.spacing). If it is `{true}`, they use normal
- /// [leading]($func/par.leading) instead. This makes the list more compact,
- /// which can look better if the items are short.
- ///
- /// In markup mode, the value of this parameter is determined based on
- /// whether items are separated with a blank line. If items directly follow
- /// each other, this is set to `{true}`; if items are separated by a blank
- /// line, this is set to `{false}`.
- ///
- /// ```example
- /// - If a list has a lot of text, and
- /// maybe other inline content, it
- /// should not be tight anymore.
- ///
- /// - To make a list wide, simply insert
- /// a blank line between the items.
- /// ```
- #[default(true)]
- pub tight: bool,
-
- /// The marker which introduces each item.
- ///
- /// Instead of plain content, you can also pass an array with multiple
- /// markers that should be used for nested lists. If the list nesting depth
- /// exceeds the number of markers, the last one is repeated. For total
- /// control, you may pass a function that maps the list's nesting depth
- /// (starting from `{0}`) to a desired marker.
- ///
- /// ```example
- /// #set list(marker: [--])
- /// - A more classic list
- /// - With en-dashes
- ///
- /// #set list(marker: ([•], [--]))
- /// - Top-level
- /// - Nested
- /// - Items
- /// - Items
- /// ```
- #[default(ListMarker::Content(vec![TextElem::packed('•')]))]
- pub marker: ListMarker,
-
- /// The indent of each item.
- #[resolve]
- pub indent: Length,
-
- /// The spacing between the marker and the body of each item.
- #[resolve]
- #[default(Em::new(0.5).into())]
- pub body_indent: Length,
-
- /// The spacing between the items of a wide (non-tight) list.
- ///
- /// If set to `{auto}`, uses the spacing [below blocks]($func/block.below).
- pub spacing: Smart<Spacing>,
-
- /// The bullet list's children.
- ///
- /// When using the list syntax, adjacent items are automatically collected
- /// into lists, even through constructs like for loops.
- ///
- /// ```example
- /// #for letter in "ABC" [
- /// - Letter #letter
- /// ]
- /// ```
- #[variadic]
- pub children: Vec<ListItem>,
-
- /// The nesting depth.
- #[internal]
- #[fold]
- depth: Depth,
-}
-
-impl Layout for ListElem {
- #[tracing::instrument(name = "ListElem::layout", skip_all)]
- fn layout(
- &self,
- vt: &mut Vt,
- styles: StyleChain,
- regions: Regions,
- ) -> SourceResult<Fragment> {
- let indent = self.indent(styles);
- let body_indent = self.body_indent(styles);
- let gutter = if self.tight(styles) {
- ParElem::leading_in(styles).into()
- } else {
- self.spacing(styles)
- .unwrap_or_else(|| BlockElem::below_in(styles).amount())
- };
-
- let depth = self.depth(styles);
- let marker = self
- .marker(styles)
- .resolve(vt, depth)?
- // avoid '#set align' interference with the list
- .aligned(Align::LEFT_TOP.into());
-
- let mut cells = vec![];
- for item in self.children() {
- cells.push(Content::empty());
- cells.push(marker.clone());
- cells.push(Content::empty());
- cells.push(item.body().styled(Self::set_depth(Depth)));
- }
-
- let layouter = GridLayouter::new(
- Axes::with_x(&[
- Sizing::Rel(indent.into()),
- Sizing::Auto,
- Sizing::Rel(body_indent.into()),
- Sizing::Auto,
- ]),
- Axes::with_y(&[gutter.into()]),
- &cells,
- regions,
- styles,
- );
-
- Ok(layouter.layout(vt)?.fragment)
- }
-}
-
-/// A bullet list item.
-///
-/// Display: Bullet List Item
-/// Category: layout
-#[element]
-pub struct ListItem {
- /// The item's body.
- #[required]
- pub body: Content,
-}
-
-cast! {
- ListItem,
- v: Content => v.to::<Self>().cloned().unwrap_or_else(|| Self::new(v.clone())),
-}
-
-/// A list's marker.
-#[derive(Debug, Clone, Hash)]
-pub enum ListMarker {
- Content(Vec<Content>),
- Func(Func),
-}
-
-impl ListMarker {
- /// Resolve the marker for the given depth.
- fn resolve(&self, vt: &mut Vt, depth: usize) -> SourceResult<Content> {
- Ok(match self {
- Self::Content(list) => {
- list.get(depth).or(list.last()).cloned().unwrap_or_default()
- }
- Self::Func(func) => func.call_vt(vt, [depth])?.display(),
- })
- }
-}
-
-cast! {
- ListMarker,
- self => match self {
- Self::Content(vec) => if vec.len() == 1 {
- vec.into_iter().next().unwrap().into_value()
- } else {
- vec.into_value()
- },
- Self::Func(func) => func.into_value(),
- },
- v: Content => Self::Content(vec![v]),
- array: Array => {
- if array.is_empty() {
- bail!("array must contain at least one marker");
- }
- Self::Content(array.into_iter().map(Value::display).collect())
- },
- v: Func => Self::Func(v),
-}
-
-struct Depth;
-
-cast! {
- Depth,
- self => Value::None,
- _: Value => Self,
-}
-
-impl Fold for Depth {
- type Output = usize;
-
- fn fold(self, outer: Self::Output) -> Self::Output {
- outer + 1
- }
-}