summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-06-03 12:04:07 +0200
committerGitHub <noreply@github.com>2024-06-03 10:04:07 +0000
commita9b3273a2b49c0df7e1223bfddc98f2df3cee515 (patch)
treef8c9c0616e3738c4ce9e87c0b73cac79c7768692
parent3257efd03a2fbe61b1f50ace47bb52bac9e6d454 (diff)
Clean up list styling (#4324)
-rw-r--r--crates/typst/src/foundations/content.rs13
-rw-r--r--crates/typst/src/model/enum.rs10
-rw-r--r--crates/typst/src/model/list.rs10
-rw-r--r--crates/typst/src/model/terms.rs10
-rw-r--r--crates/typst/src/realize/mod.rs60
5 files changed, 59 insertions, 44 deletions
diff --git a/crates/typst/src/foundations/content.rs b/crates/typst/src/foundations/content.rs
index d072640b..4cae8db7 100644
--- a/crates/typst/src/foundations/content.rs
+++ b/crates/typst/src/foundations/content.rs
@@ -385,6 +385,19 @@ impl Content {
}
}
+ /// Style this content with a full style map in-place.
+ pub fn style_in_place(&mut self, styles: Styles) {
+ if styles.is_empty() {
+ return;
+ }
+
+ if let Some(style_elem) = self.to_packed_mut::<StyledElem>() {
+ style_elem.styles.apply(styles);
+ } else {
+ *self = StyledElem::new(std::mem::take(self), styles).into();
+ }
+ }
+
/// Queries the content tree for all elements that match the given selector.
///
/// Elements produced in `show` rules will not be included in the results.
diff --git a/crates/typst/src/model/enum.rs b/crates/typst/src/model/enum.rs
index 0eb0f773..d03c774c 100644
--- a/crates/typst/src/model/enum.rs
+++ b/crates/typst/src/model/enum.rs
@@ -7,7 +7,7 @@ use crate::diag::{bail, SourceResult};
use crate::engine::Engine;
use crate::foundations::{
cast, elem, scope, Array, Content, Context, NativeElement, Packed, Show, Smart,
- StyleChain,
+ StyleChain, Styles,
};
use crate::layout::{
Alignment, Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment,
@@ -316,6 +316,14 @@ pub struct EnumItem {
pub body: Content,
}
+impl Packed<EnumItem> {
+ /// Apply styles to this enum item.
+ pub fn styled(mut self, styles: Styles) -> Self {
+ self.body.style_in_place(styles);
+ self
+ }
+}
+
cast! {
EnumItem,
array: Array => {
diff --git a/crates/typst/src/model/list.rs b/crates/typst/src/model/list.rs
index 34a4a0b2..ffecc400 100644
--- a/crates/typst/src/model/list.rs
+++ b/crates/typst/src/model/list.rs
@@ -4,7 +4,7 @@ use crate::diag::{bail, SourceResult};
use crate::engine::Engine;
use crate::foundations::{
cast, elem, scope, Array, Content, Context, Depth, Func, NativeElement, Packed, Show,
- Smart, StyleChain, Value,
+ Smart, StyleChain, Styles, Value,
};
use crate::layout::{
Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment, Length,
@@ -206,6 +206,14 @@ pub struct ListItem {
pub body: Content,
}
+impl Packed<ListItem> {
+ /// Apply styles to this list item.
+ pub fn styled(mut self, styles: Styles) -> Self {
+ self.body.style_in_place(styles);
+ self
+ }
+}
+
cast! {
ListItem,
v: Content => v.unpack::<Self>().unwrap_or_else(Self::new)
diff --git a/crates/typst/src/model/terms.rs b/crates/typst/src/model/terms.rs
index da81c2ec..cb88b02d 100644
--- a/crates/typst/src/model/terms.rs
+++ b/crates/typst/src/model/terms.rs
@@ -2,6 +2,7 @@ use crate::diag::{bail, SourceResult};
use crate::engine::Engine;
use crate::foundations::{
cast, elem, scope, Array, Content, NativeElement, Packed, Show, Smart, StyleChain,
+ Styles,
};
use crate::layout::{
BlockElem, Dir, Em, HElem, Length, Sides, Spacing, StackChild, StackElem, VElem,
@@ -168,6 +169,15 @@ pub struct TermItem {
pub description: Content,
}
+impl Packed<TermItem> {
+ /// Apply styles to this term item.
+ pub fn styled(mut self, styles: Styles) -> Self {
+ self.term.style_in_place(styles.clone());
+ self.description.style_in_place(styles);
+ self
+ }
+}
+
cast! {
TermItem,
array: Array => {
diff --git a/crates/typst/src/realize/mod.rs b/crates/typst/src/realize/mod.rs
index 97b39b4a..a21f8faf 100644
--- a/crates/typst/src/realize/mod.rs
+++ b/crates/typst/src/realize/mod.rs
@@ -508,50 +508,26 @@ impl<'a> ListBuilder<'a> {
let mut items = items.into_iter().peekable();
let (first, _) = items.peek().unwrap();
let output = if first.is::<ListItem>() {
- ListElem::new(
- items
- .map(|(item, local)| {
- let mut item = item.to_packed::<ListItem>().unwrap().clone();
- let body = item.body().clone().styled_with_map(local);
- item.push_body(body);
- item
- })
- .collect(),
- )
- .with_tight(self.tight)
- .pack()
- .spanned(span)
+ let children = items
+ .map(|(item, local)| {
+ item.into_packed::<ListItem>().unwrap().styled(local)
+ })
+ .collect();
+ ListElem::new(children).with_tight(self.tight).pack().spanned(span)
} else if first.is::<EnumItem>() {
- EnumElem::new(
- items
- .map(|(item, local)| {
- let mut item = item.to_packed::<EnumItem>().unwrap().clone();
- let body = item.body().clone().styled_with_map(local);
- item.push_body(body);
- item
- })
- .collect(),
- )
- .with_tight(self.tight)
- .pack()
- .spanned(span)
+ let children = items
+ .map(|(item, local)| {
+ item.into_packed::<EnumItem>().unwrap().styled(local)
+ })
+ .collect();
+ EnumElem::new(children).with_tight(self.tight).pack().spanned(span)
} else if first.is::<TermItem>() {
- TermsElem::new(
- items
- .map(|(item, local)| {
- let mut item = item.to_packed::<TermItem>().unwrap().clone();
- let term = item.term().clone().styled_with_map(local.clone());
- let description =
- item.description().clone().styled_with_map(local);
- item.push_term(term);
- item.push_description(description);
- item
- })
- .collect(),
- )
- .with_tight(self.tight)
- .pack()
- .spanned(span)
+ let children = items
+ .map(|(item, local)| {
+ item.into_packed::<TermItem>().unwrap().styled(local)
+ })
+ .collect();
+ TermsElem::new(children).with_tight(self.tight).pack().spanned(span)
} else {
unreachable!()
};