diff options
Diffstat (limited to 'library/src/layout')
| -rw-r--r-- | library/src/layout/container.rs | 19 | ||||
| -rw-r--r-- | library/src/layout/enum.rs | 9 | ||||
| -rw-r--r-- | library/src/layout/grid.rs | 7 | ||||
| -rw-r--r-- | library/src/layout/list.rs | 32 | ||||
| -rw-r--r-- | library/src/layout/measure.rs | 7 | ||||
| -rw-r--r-- | library/src/layout/mod.rs | 14 | ||||
| -rw-r--r-- | library/src/layout/page.rs | 24 | ||||
| -rw-r--r-- | library/src/layout/spacing.rs | 25 | ||||
| -rw-r--r-- | library/src/layout/stack.rs | 13 | ||||
| -rw-r--r-- | library/src/layout/table.rs | 51 | ||||
| -rw-r--r-- | library/src/layout/terms.rs | 2 |
11 files changed, 96 insertions, 107 deletions
diff --git a/library/src/layout/container.rs b/library/src/layout/container.rs index b7d0ba2f..d28c8b5e 100644 --- a/library/src/layout/container.rs +++ b/library/src/layout/container.rs @@ -1,3 +1,5 @@ +use typst::eval::AutoValue; + use super::VElem; use crate::layout::Spacing; use crate::prelude::*; @@ -482,17 +484,14 @@ impl<T: Into<Spacing>> From<T> for Sizing { } } -cast_from_value! { +cast! { Sizing, - _: Smart<Never> => Self::Auto, + self => match self { + Self::Auto => Value::Auto, + Self::Rel(rel) => rel.into_value(), + Self::Fr(fr) => fr.into_value(), + }, + _: AutoValue => Self::Auto, v: Rel<Length> => Self::Rel(v), v: Fr => Self::Fr(v), } - -cast_to_value! { - v: Sizing => match v { - Sizing::Auto => Value::Auto, - Sizing::Rel(rel) => Value::Relative(rel), - Sizing::Fr(fr) => Value::Fraction(fr), - } -} diff --git a/library/src/layout/enum.rs b/library/src/layout/enum.rs index 0fd0ebb2..62f4c351 100644 --- a/library/src/layout/enum.rs +++ b/library/src/layout/enum.rs @@ -283,7 +283,7 @@ pub struct EnumItem { pub body: Content, } -cast_from_value! { +cast! { EnumItem, array: Array => { let mut iter = array.into_iter(); @@ -298,15 +298,12 @@ cast_from_value! { struct Parent(usize); -cast_from_value! { +cast! { Parent, + self => self.0.into_value(), v: usize => Self(v), } -cast_to_value! { - v: Parent => v.0.into() -} - impl Fold for Parent { type Output = Vec<usize>; diff --git a/library/src/layout/grid.rs b/library/src/layout/grid.rs index 3c299eb0..ea155acd 100644 --- a/library/src/layout/grid.rs +++ b/library/src/layout/grid.rs @@ -129,17 +129,14 @@ impl Layout for GridElem { #[derive(Debug, Default, Clone, Eq, PartialEq, Hash)] pub struct TrackSizings(pub Vec<Sizing>); -cast_from_value! { +cast! { TrackSizings, + self => self.0.into_value(), sizing: Sizing => Self(vec![sizing]), count: NonZeroUsize => Self(vec![Sizing::Auto; count.get()]), values: Array => Self(values.into_iter().map(Value::cast).collect::<StrResult<_>>()?), } -cast_to_value! { - v: TrackSizings => v.0.into() -} - /// Performs grid layout. pub struct GridLayouter<'a, 'v> { /// The core context. diff --git a/library/src/layout/list.rs b/library/src/layout/list.rs index 1e42d51b..b308c2ce 100644 --- a/library/src/layout/list.rs +++ b/library/src/layout/list.rs @@ -174,7 +174,7 @@ pub struct ListItem { pub body: Content, } -cast_from_value! { +cast! { ListItem, v: Content => v.to::<Self>().cloned().unwrap_or_else(|| Self::new(v.clone())), } @@ -193,13 +193,21 @@ impl ListMarker { Self::Content(list) => { list.get(depth).or(list.last()).cloned().unwrap_or_default() } - Self::Func(func) => func.call_vt(vt, [Value::Int(depth as i64)])?.display(), + Self::Func(func) => func.call_vt(vt, [depth])?.display(), }) } } -cast_from_value! { +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() { @@ -210,28 +218,14 @@ cast_from_value! { v: Func => Self::Func(v), } -cast_to_value! { - v: ListMarker => match v { - ListMarker::Content(vec) => if vec.len() == 1 { - vec.into_iter().next().unwrap().into() - } else { - vec.into() - }, - ListMarker::Func(func) => func.into(), - } -} - struct Depth; -cast_from_value! { +cast! { Depth, + self => Value::None, _: Value => Self, } -cast_to_value! { - _: Depth => Value::None -} - impl Fold for Depth { type Output = usize; diff --git a/library/src/layout/measure.rs b/library/src/layout/measure.rs index c7a19243..4cbd1698 100644 --- a/library/src/layout/measure.rs +++ b/library/src/layout/measure.rs @@ -39,17 +39,18 @@ use crate::prelude::*; /// /// Display: Measure /// Category: layout -/// Returns: dictionary #[func] pub fn measure( /// The content whose size to measure. content: Content, /// The styles with which to layout the content. styles: Styles, -) -> Value { + /// The virtual machine. + vm: &mut Vm, +) -> SourceResult<Dict> { let pod = Regions::one(Axes::splat(Abs::inf()), Axes::splat(false)); let styles = StyleChain::new(&styles); let frame = content.measure(&mut vm.vt, styles, pod)?.into_frame(); let Size { x, y } = frame.size(); - dict! { "width" => x, "height" => y }.into() + Ok(dict! { "width" => x, "height" => y }) } diff --git a/library/src/layout/mod.rs b/library/src/layout/mod.rs index 2d5b18c8..9b6ba204 100644 --- a/library/src/layout/mod.rs +++ b/library/src/layout/mod.rs @@ -87,7 +87,19 @@ pub(super) fn define(global: &mut Scope) { global.define("scale", ScaleElem::func()); global.define("rotate", RotateElem::func()); global.define("hide", HideElem::func()); - global.define("measure", measure); + global.define("measure", measure_func()); + global.define("ltr", Dir::LTR); + global.define("rtl", Dir::RTL); + global.define("ttb", Dir::TTB); + global.define("btt", Dir::BTT); + global.define("start", GenAlign::Start); + global.define("end", GenAlign::End); + global.define("left", GenAlign::Specific(Align::Left)); + global.define("center", GenAlign::Specific(Align::Center)); + global.define("right", GenAlign::Specific(Align::Right)); + global.define("top", GenAlign::Specific(Align::Top)); + global.define("horizon", GenAlign::Specific(Align::Horizon)); + global.define("bottom", GenAlign::Specific(Align::Bottom)); } /// Root-level layout. diff --git a/library/src/layout/page.rs b/library/src/layout/page.rs index 6510bd58..26ebbc53 100644 --- a/library/src/layout/page.rs +++ b/library/src/layout/page.rs @@ -341,7 +341,7 @@ impl PageElem { let footer_descent = self.footer_descent(styles); let numbering_meta = FrameItem::Meta( - Meta::PageNumbering(self.numbering(styles).into()), + Meta::PageNumbering(self.numbering(styles).into_value()), Size::zero(), ); @@ -451,24 +451,21 @@ impl Marginal { pub fn resolve(&self, vt: &mut Vt, page: usize) -> SourceResult<Content> { Ok(match self { Self::Content(content) => content.clone(), - Self::Func(func) => func.call_vt(vt, [Value::Int(page as i64)])?.display(), + Self::Func(func) => func.call_vt(vt, [page])?.display(), }) } } -cast_from_value! { +cast! { Marginal, + self => match self { + Self::Content(v) => v.into_value(), + Self::Func(v) => v.into_value(), + }, v: Content => Self::Content(v), v: Func => Self::Func(v), } -cast_to_value! { - v: Marginal => match v { - Marginal::Content(v) => v.into(), - Marginal::Func(v) => v.into(), - } -} - /// Specification of a paper. #[derive(Debug, Copy, Clone, Hash)] pub struct Paper { @@ -517,17 +514,14 @@ macro_rules! papers { } } - cast_from_value! { + cast! { Paper, + self => self.name.into_value(), $( /// Produces a paper of the respective size. $name => Self::$var, )* } - - cast_to_value! { - v: Paper => v.name.into() - } }; } diff --git a/library/src/layout/spacing.rs b/library/src/layout/spacing.rs index 588f9f29..0cbf6641 100644 --- a/library/src/layout/spacing.rs +++ b/library/src/layout/spacing.rs @@ -157,7 +157,7 @@ impl Behave for VElem { } } -cast_from_value! { +cast! { VElem, v: Content => v.to::<Self>().cloned().ok_or("expected `v` element")?, } @@ -221,23 +221,20 @@ impl PartialOrd for Spacing { } } -cast_from_value! { +cast! { Spacing, - v: Rel<Length> => Self::Rel(v), - v: Fr => Self::Fr(v), -} - -cast_to_value! { - v: Spacing => match v { - Spacing::Rel(rel) => { + self => match self { + Self::Rel(rel) => { if rel.rel.is_zero() { - Value::Length(rel.abs) + rel.abs.into_value() } else if rel.abs.is_zero() { - Value::Ratio(rel.rel) + rel.rel.into_value() } else { - Value::Relative(rel) + rel.into_value() } } - Spacing::Fr(fr) => Value::Fraction(fr), - } + Self::Fr(fr) => fr.into_value(), + }, + v: Rel<Length> => Self::Rel(v), + v: Fr => Self::Fr(v), } diff --git a/library/src/layout/stack.rs b/library/src/layout/stack.rs index 2ce2cc28..f8670026 100644 --- a/library/src/layout/stack.rs +++ b/library/src/layout/stack.rs @@ -90,19 +90,16 @@ impl Debug for StackChild { } } -cast_from_value! { +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), } -cast_to_value! { - v: StackChild => match v { - StackChild::Spacing(spacing) => spacing.into(), - StackChild::Block(content) => content.into(), - } -} - /// Performs stack layout. struct StackLayouter<'a> { /// The stacking direction. diff --git a/library/src/layout/table.rs b/library/src/layout/table.rs index 9d5a83d2..74370cb2 100644 --- a/library/src/layout/table.rs +++ b/library/src/layout/table.rs @@ -1,3 +1,5 @@ +use typst::eval::{CastInfo, Reflect}; + use crate::layout::{AlignElem, GridLayouter, TrackSizings}; use crate::meta::{Figurable, LocalName}; use crate::prelude::*; @@ -243,15 +245,12 @@ pub enum Celled<T> { Array(Vec<T>), } -impl<T: Cast + Clone + Default> Celled<T> { +impl<T: Default + Clone + FromValue> Celled<T> { /// Resolve the value based on the cell position. pub fn resolve(&self, vt: &mut Vt, x: usize, y: usize) -> SourceResult<T> { Ok(match self { Self::Value(value) => value.clone(), - Self::Func(func) => func - .call_vt(vt, [Value::Int(x as i64), Value::Int(y as i64)])? - .cast() - .at(func.span())?, + Self::Func(func) => func.call_vt(vt, [x, y])?.cast().at(func.span())?, Self::Array(array) => x .checked_rem(array.len()) .and_then(|i| array.get(i)) @@ -267,33 +266,35 @@ impl<T: Default> Default for Celled<T> { } } -impl<T: Cast> Cast for Celled<T> { - fn is(value: &Value) -> bool { - matches!(value, Value::Array(_) | Value::Func(_)) || T::is(value) +impl<T: Reflect> Reflect for Celled<T> { + fn describe() -> CastInfo { + T::describe() + Array::describe() + Func::describe() } - fn cast(value: Value) -> StrResult<Self> { - match value { - Value::Func(v) => Ok(Self::Func(v)), - Value::Array(array) => { - Ok(Self::Array(array.into_iter().map(T::cast).collect::<StrResult<_>>()?)) - } - v if T::is(&v) => Ok(Self::Value(T::cast(v)?)), - v => <Self as Cast>::error(v), - } + fn castable(value: &Value) -> bool { + Array::castable(value) || Func::castable(value) || T::castable(value) } +} - fn describe() -> CastInfo { - T::describe() + CastInfo::Type("array") + CastInfo::Type("function") +impl<T: IntoValue> IntoValue for Celled<T> { + fn into_value(self) -> Value { + match self { + Self::Value(value) => value.into_value(), + Self::Func(func) => func.into_value(), + Self::Array(arr) => arr.into_value(), + } } } -impl<T: Into<Value>> From<Celled<T>> for Value { - fn from(celled: Celled<T>) -> Self { - match celled { - Celled::Value(value) => value.into(), - Celled::Func(func) => func.into(), - Celled::Array(arr) => arr.into(), +impl<T: FromValue> FromValue for Celled<T> { + fn from_value(value: Value) -> StrResult<Self> { + match value { + Value::Func(v) => Ok(Self::Func(v)), + Value::Array(array) => Ok(Self::Array( + array.into_iter().map(T::from_value).collect::<StrResult<_>>()?, + )), + v if T::castable(&v) => Ok(Self::Value(T::from_value(v)?)), + v => Err(Self::error(&v)), } } } diff --git a/library/src/layout/terms.rs b/library/src/layout/terms.rs index 43127d97..0cfe98d9 100644 --- a/library/src/layout/terms.rs +++ b/library/src/layout/terms.rs @@ -147,7 +147,7 @@ pub struct TermItem { pub description: Content, } -cast_from_value! { +cast! { TermItem, array: Array => { let mut iter = array.into_iter(); |
