summaryrefslogtreecommitdiff
path: root/library/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'library/src/layout')
-rw-r--r--library/src/layout/container.rs19
-rw-r--r--library/src/layout/enum.rs9
-rw-r--r--library/src/layout/grid.rs7
-rw-r--r--library/src/layout/list.rs32
-rw-r--r--library/src/layout/measure.rs7
-rw-r--r--library/src/layout/mod.rs14
-rw-r--r--library/src/layout/page.rs24
-rw-r--r--library/src/layout/spacing.rs25
-rw-r--r--library/src/layout/stack.rs13
-rw-r--r--library/src/layout/table.rs51
-rw-r--r--library/src/layout/terms.rs2
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();