From c47e4cb4969836e7fb8955361728105555b6d722 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 17 Mar 2023 14:39:30 +0100 Subject: [PATCH] State --- library/src/layout/page.rs | 11 +- library/src/lib.rs | 13 ++- library/src/meta/counter.rs | 183 +++++++++++++++++------------ library/src/meta/figure.rs | 2 +- library/src/meta/heading.rs | 14 +-- library/src/meta/mod.rs | 2 + library/src/meta/outline.rs | 14 ++- library/src/meta/reference.rs | 7 +- library/src/meta/state.rs | 209 ++++++++++++++++++++++++++++++++++ macros/src/node.rs | 6 +- src/eval/library.rs | 5 +- src/eval/methods.rs | 7 +- src/model/content.rs | 7 +- tests/ref/meta/state.png | Bin 0 -> 47353 bytes tests/typ/meta/counter.typ | 1 - tests/typ/meta/state.typ | 24 ++++ 16 files changed, 392 insertions(+), 113 deletions(-) create mode 100644 library/src/meta/state.rs create mode 100644 tests/ref/meta/state.png create mode 100644 tests/typ/meta/state.typ diff --git a/library/src/layout/page.rs b/library/src/layout/page.rs index 8ad76387a..962e8a168 100644 --- a/library/src/layout/page.rs +++ b/library/src/layout/page.rs @@ -2,7 +2,7 @@ use std::ptr; use std::str::FromStr; use super::{AlignNode, ColumnsNode}; -use crate::meta::{Counter, CounterAction, CounterNode, Numbering}; +use crate::meta::{Counter, CounterAction, CounterKey, CounterNode, Numbering}; use crate::prelude::*; /// Layouts its child onto one or multiple pages. @@ -311,9 +311,12 @@ impl PageNode { let header_ascent = self.header_ascent(styles); let footer = self.footer(styles).or_else(|| { self.numbering(styles).map(|numbering| { - CounterNode::new(Counter::Page, CounterAction::Both(numbering)) - .pack() - .aligned(self.number_align(styles)) + CounterNode::new( + Counter::new(CounterKey::Page), + CounterAction::Both(numbering), + ) + .pack() + .aligned(self.number_align(styles)) }) }); let footer_descent = self.footer_descent(styles); diff --git a/library/src/lib.rs b/library/src/lib.rs index b397bfb45..83dbe17aa 100644 --- a/library/src/lib.rs +++ b/library/src/lib.rs @@ -10,6 +10,7 @@ pub mod symbols; pub mod text; pub mod visualize; +use typst::diag::At; use typst::eval::{LangItems, Library, Module, Scope}; use typst::geom::{Align, Color, Dir, GenAlign, Smart}; use typst::model::{Node, NodeId, StyleMap}; @@ -93,6 +94,7 @@ fn global(math: Module, calc: Module) -> Module { global.define("bibliography", meta::BibliographyNode::id()); global.define("counter", meta::counter); global.define("numbering", meta::numbering); + global.define("state", meta::state); // Symbols. global.define("sym", symbols::sym()); @@ -225,6 +227,15 @@ fn items() -> LangItems { math::AccentNode::new(base, math::Accent::new(accent)).pack() }, math_frac: |num, denom| math::FracNode::new(num, denom).pack(), - counter_method: meta::counter_method, + library_method: |dynamic, method, args, span| { + if let Some(counter) = dynamic.downcast().cloned() { + meta::counter_method(counter, method, args, span) + } else if let Some(state) = dynamic.downcast().cloned() { + meta::state_method(state, method, args, span) + } else { + Err(format!("type {} has no method `{method}`", dynamic.type_name())) + .at(span) + } + }, } } diff --git a/library/src/meta/counter.rs b/library/src/meta/counter.rs index ab089d5e4..b8f719ac8 100644 --- a/library/src/meta/counter.rs +++ b/library/src/meta/counter.rs @@ -3,7 +3,6 @@ use std::str::FromStr; use ecow::{eco_vec, EcoVec}; use smallvec::{smallvec, SmallVec}; -use typst::eval::Dynamic; use super::{Numbering, NumberingPattern}; use crate::layout::PageNode; @@ -13,20 +12,65 @@ use crate::prelude::*; /// /// Display: Counter /// Category: meta -/// Returns: content +/// Returns: counter #[func] -pub fn counter(key: Counter) -> Value { - Value::dynamic(key) +pub fn counter( + /// The key that identifies this counter. + key: CounterKey, +) -> Value { + Value::dynamic(Counter::new(key)) +} + +/// Identifies a counter. +#[derive(Clone, PartialEq, Hash)] +pub enum CounterKey { + /// The page counter. + Page, + /// Counts elements matching the given selectors. Only works for locatable + /// elements or labels. + Selector(Selector), + /// Counts through manual counters with the same key. + Str(Str), +} + +cast_from_value! { + CounterKey, + v: Str => Self::Str(v), + label: Label => Self::Selector(Selector::Label(label)), + func: Func => { + let Some(id) = func.id() else { + return Err("this function is not selectable".into()); + }; + + if id == NodeId::of::() { + return Ok(Self::Page); + } + + if !Content::new(id).can::() { + Err(eco_format!("cannot count through {}s", id.name))?; + } + + Self::Selector(Selector::Node(id, None)) + } +} + +impl Debug for CounterKey { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + Self::Page => f.pad("page"), + Self::Selector(selector) => selector.fmt(f), + Self::Str(str) => str.fmt(f), + } + } } /// Call a method on counter. pub fn counter_method( - dynamic: &Dynamic, + counter: Counter, method: &str, mut args: Args, span: Span, ) -> SourceResult { - let counter = dynamic.downcast::().unwrap(); let pattern = |s| NumberingPattern::from_str(s).unwrap().into(); let action = match method { "get" => CounterAction::Get(args.eat()?.unwrap_or_else(|| pattern("1.1"))), @@ -41,7 +85,7 @@ pub fn counter_method( args.finish()?; - let content = CounterNode::new(counter.clone(), action).pack(); + let content = CounterNode::new(counter, action).pack(); Ok(Value::Content(content)) } @@ -53,7 +97,7 @@ pub fn counter_method( pub struct CounterNode { /// The counter key. #[required] - pub key: Counter, + pub counter: Counter, /// The action. #[required] @@ -64,24 +108,30 @@ impl Show for CounterNode { fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult { match self.action() { CounterAction::Get(numbering) => { - self.key().resolve(vt, self.0.stable_id(), &numbering) + self.counter().resolve(vt, self.0.stable_id(), &numbering) + } + CounterAction::Final(numbering) => { + self.counter().resolve(vt, None, &numbering) } - CounterAction::Final(numbering) => self.key().resolve(vt, None, &numbering), CounterAction::Both(numbering) => { let both = match &numbering { Numbering::Pattern(pattern) => pattern.pieces() >= 2, _ => false, }; - let key = self.key(); + let counter = self.counter(); let id = self.0.stable_id(); if !both { - return key.resolve(vt, id, &numbering); + return counter.resolve(vt, id, &numbering); } - let sequence = key.sequence(vt.world, vt.introspector)?; - let numbers = [sequence.single(id), sequence.single(None)]; - Ok(numbering.apply(vt.world, &numbers)?.display()) + let sequence = counter.sequence(vt.world, vt.introspector)?; + Ok(match (sequence.single(id), sequence.single(None)) { + (Some(current), Some(total)) => { + numbering.apply(vt.world, &[current, total])?.display() + } + _ => Content::empty(), + }) } CounterAction::Update(_) => Ok(Content::empty()), } @@ -109,7 +159,12 @@ cast_from_value! { impl Debug for CounterAction { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.pad("..") + match self { + Self::Get(_) => f.pad("get(..)"), + Self::Final(_) => f.pad("final(..)"), + Self::Both(_) => f.pad("both(..)"), + Self::Update(_) => f.pad("update(..)"), + } } } @@ -138,17 +193,22 @@ pub trait Count { /// Counts through pages, elements, and more. #[derive(Clone, PartialEq, Hash)] -pub enum Counter { - /// The page counter. - Page, - /// Counts elements matching the given selectors. Only works for locatable - /// elements or labels. - Selector(Selector), - /// Counts through manual counters with the same key. - Str(Str), +pub struct Counter { + /// The key that identifies the counter. + pub key: CounterKey, } impl Counter { + /// Create a new counter from a key. + pub fn new(key: CounterKey) -> Self { + Self { key } + } + + /// The counter for the given node. + pub fn of(id: NodeId) -> Self { + Self::new(CounterKey::Selector(Selector::Node(id, None))) + } + /// Display the value of the counter at the postition of the given stable /// id. pub fn resolve( @@ -157,9 +217,15 @@ impl Counter { stop: Option, numbering: &Numbering, ) -> SourceResult { + if !vt.introspector.init() { + return Ok(Content::empty()); + } + let sequence = self.sequence(vt.world, vt.introspector)?; - let numbers = sequence.at(stop).0; - Ok(numbering.apply(vt.world, &numbers)?.display()) + Ok(match sequence.at(stop) { + Some(state) => numbering.apply(vt.world, &state.0)?.display(), + None => Content::empty(), + }) } /// Produce the whole sequence of counter states. @@ -174,21 +240,21 @@ impl Counter { ) -> SourceResult { let mut search = Selector::Node( NodeId::of::(), - Some(dict! { "key" => self.clone() }), + Some(dict! { "counter" => self.clone() }), ); - if let Counter::Selector(selector) = self { + if let CounterKey::Selector(selector) = &self.key { search = Selector::Any(eco_vec![search, selector.clone()]); } - let mut state = CounterState::new(); let mut stops = EcoVec::new(); + let mut state = CounterState(match &self.key { + CounterKey::Selector(_) => smallvec![], + _ => smallvec![NonZeroUsize::ONE], + }); + let is_page = self.key == CounterKey::Page; let mut prev_page = NonZeroUsize::ONE; - let is_page = *self == Self::Page; - if is_page { - state.0.push(prev_page); - } for node in introspector.query(search) { let id = node.stable_id().unwrap(); @@ -221,40 +287,18 @@ impl Counter { } } -cast_from_value! { - Counter: "counter", - v: Str => Self::Str(v), - v: Selector => { - match v { - Selector::Node(id, _) => { - if id == NodeId::of::() { - return Ok(Self::Page); - } - - if !Content::new_of(id).can::() { - Err(eco_format!("cannot count through {}s", id.name))?; - } - } - Selector::Label(_) => {} - Selector::Regex(_) => Err("cannot count through text")?, - Selector::Any(_) => {} - } - Self::Selector(v) - } -} - impl Debug for Counter { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.write_str("counter(")?; - match self { - Self::Page => f.pad("page")?, - Self::Selector(selector) => selector.fmt(f)?, - Self::Str(str) => str.fmt(f)?, - } + self.key.fmt(f)?; f.write_char(')') } } +cast_from_value! { + Counter: "counter", +} + /// A sequence of counter values. #[derive(Debug, Clone)] struct CounterSequence { @@ -263,38 +307,33 @@ struct CounterSequence { } impl CounterSequence { - fn at(&self, stop: Option) -> CounterState { + fn at(&self, stop: Option) -> Option { let entry = match stop { Some(stop) => self.stops.iter().find(|&&(id, _)| id == stop), None => self.stops.last(), }; if let Some((_, state)) = entry { - return state.clone(); + return Some(state.clone()); } if self.is_page { - return CounterState(smallvec![NonZeroUsize::ONE]); + return Some(CounterState(smallvec![NonZeroUsize::ONE])); } - CounterState::default() + None } - fn single(&self, stop: Option) -> NonZeroUsize { - self.at(stop).0.first().copied().unwrap_or(NonZeroUsize::ONE) + fn single(&self, stop: Option) -> Option { + Some(*self.at(stop)?.0.first()?) } } /// Counts through elements with different levels. -#[derive(Debug, Default, Clone, PartialEq, Hash)] +#[derive(Debug, Clone, PartialEq, Hash)] pub struct CounterState(pub SmallVec<[NonZeroUsize; 3]>); impl CounterState { - /// Create a new levelled counter. - pub fn new() -> Self { - Self::default() - } - /// Advance the counter and return the numbers for the given heading. pub fn update( &mut self, diff --git a/library/src/meta/figure.rs b/library/src/meta/figure.rs index 3c3f6361b..a92ff5e71 100644 --- a/library/src/meta/figure.rs +++ b/library/src/meta/figure.rs @@ -60,7 +60,7 @@ impl Show for FigureNode { let name = self.local_name(TextNode::lang_in(styles)); caption = TextNode::packed(eco_format!("{name}\u{a0}")) + CounterNode::new( - Counter::Selector(Selector::node::()), + Counter::of(Self::id()), CounterAction::Get(numbering), ) .pack() diff --git a/library/src/meta/heading.rs b/library/src/meta/heading.rs index 614200b83..833421557 100644 --- a/library/src/meta/heading.rs +++ b/library/src/meta/heading.rs @@ -91,14 +91,12 @@ impl Show for HeadingNode { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult { let mut realized = self.body(); if let Some(numbering) = self.numbering(styles) { - realized = CounterNode::new( - Counter::Selector(Selector::node::()), - CounterAction::Get(numbering), - ) - .pack() - .spanned(self.span()) - + HNode::new(Em::new(0.3).into()).with_weak(true).pack() - + realized; + realized = + CounterNode::new(Counter::of(Self::id()), CounterAction::Get(numbering)) + .pack() + .spanned(self.span()) + + HNode::new(Em::new(0.3).into()).with_weak(true).pack() + + realized; } Ok(BlockNode::new().with_body(Some(realized)).pack()) } diff --git a/library/src/meta/mod.rs b/library/src/meta/mod.rs index a7de2dad6..1d7740580 100644 --- a/library/src/meta/mod.rs +++ b/library/src/meta/mod.rs @@ -9,6 +9,7 @@ mod link; mod numbering; mod outline; mod reference; +mod state; pub use self::bibliography::*; pub use self::counter::*; @@ -19,6 +20,7 @@ pub use self::link::*; pub use self::numbering::*; pub use self::outline::*; pub use self::reference::*; +pub use self::state::*; use typst::doc::Lang; diff --git a/library/src/meta/outline.rs b/library/src/meta/outline.rs index 933119ece..976110360 100644 --- a/library/src/meta/outline.rs +++ b/library/src/meta/outline.rs @@ -118,8 +118,11 @@ impl Show for OutlineNode { let mut hidden = Content::empty(); for ancestor in &ancestors { if let Some(numbering) = ancestor.numbering(StyleChain::default()) { - let numbers = Counter::Selector(Selector::node::()) - .resolve(vt, ancestor.0.stable_id(), &numbering)?; + let numbers = Counter::of(HeadingNode::id()).resolve( + vt, + ancestor.0.stable_id(), + &numbering, + )?; hidden += numbers + SpaceNode::new().pack(); }; } @@ -133,8 +136,11 @@ impl Show for OutlineNode { // Format the numbering. let mut start = heading.body(); if let Some(numbering) = heading.numbering(StyleChain::default()) { - let numbers = Counter::Selector(Selector::node::()) - .resolve(vt, Some(stable_id), &numbering)?; + let numbers = Counter::of(HeadingNode::id()).resolve( + vt, + Some(stable_id), + &numbering, + )?; start = numbers + SpaceNode::new().pack() + start; }; diff --git a/library/src/meta/reference.rs b/library/src/meta/reference.rs index 095a846c2..f05692dd3 100644 --- a/library/src/meta/reference.rs +++ b/library/src/meta/reference.rs @@ -115,11 +115,8 @@ impl Show for RefNode { bail!(self.span(), "only numbered elements can be referenced"); }; - let numbers = Counter::Selector(Selector::Node(node.id(), None)).resolve( - vt, - node.stable_id(), - &numbering.trimmed(), - )?; + let numbers = + Counter::of(node.id()).resolve(vt, node.stable_id(), &numbering.trimmed())?; Ok((supplement + numbers).linked(Link::Node(node.stable_id().unwrap()))) } diff --git a/library/src/meta/state.rs b/library/src/meta/state.rs new file mode 100644 index 000000000..8b0a0aa64 --- /dev/null +++ b/library/src/meta/state.rs @@ -0,0 +1,209 @@ +use std::fmt::{self, Debug, Formatter, Write}; + +use ecow::EcoVec; + +use crate::prelude::*; + +/// Handle stateful tasks. +/// +/// Display: State +/// Category: meta +/// Returns: state +#[func] +pub fn state( + /// The key that identifies this state. + key: Str, + /// The initial value of the state. + #[default] + init: Value, +) -> Value { + Value::dynamic(State { key, init }) +} + +/// Call a method on a state. +pub fn state_method( + state: State, + method: &str, + mut args: Args, + span: Span, +) -> SourceResult { + let action = match method { + "get" => StateAction::Get(args.eat()?), + "final" => StateAction::Final(args.eat()?), + "update" => StateAction::Update(args.expect("value or function")?), + _ => bail!(span, "type state has no method `{}`", method), + }; + + args.finish()?; + + let content = StateNode::new(state, action).pack(); + Ok(Value::Content(content)) +} + +/// Executes an action on a state. +/// +/// Display: State +/// Category: special +#[node(Locatable, Show)] +pub struct StateNode { + /// The state. + #[required] + pub state: State, + + /// The action. + #[required] + pub action: StateAction, +} + +impl Show for StateNode { + fn show(&self, vt: &mut Vt, _: StyleChain) -> SourceResult { + match self.action() { + StateAction::Get(func) => self.state().resolve(vt, self.0.stable_id(), func), + StateAction::Final(func) => self.state().resolve(vt, None, func), + StateAction::Update(_) => Ok(Content::empty()), + } + } +} + +/// The action to perform on the state. +#[derive(Clone, PartialEq, Hash)] +pub enum StateAction { + /// Displays the current state. + Get(Option), + /// Displays the final state. + Final(Option), + /// Updates the state, possibly based on the previous one. + Update(StateUpdate), +} + +cast_from_value! { + StateAction: "state action", +} + +impl Debug for StateAction { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + Self::Get(_) => f.pad("get(..)"), + Self::Final(_) => f.pad("final(..)"), + Self::Update(_) => f.pad("update(..)"), + } + } +} + +/// An update to perform on a state. +#[derive(Debug, Clone, PartialEq, Hash)] +pub enum StateUpdate { + /// Set the state to the specified value. + Set(Value), + /// Apply the given function to the state. + Func(Func), +} + +cast_from_value! { + StateUpdate, + v: Func => Self::Func(v), + v: Value => Self::Set(v), +} + +/// A state. +#[derive(Clone, PartialEq, Hash)] +pub struct State { + /// The key that identifies the state. + key: Str, + /// The initial value of the state. + init: Value, +} + +impl State { + /// Display the state at the postition of the given stable id. + fn resolve( + &self, + vt: &Vt, + stop: Option, + func: Option, + ) -> SourceResult { + if !vt.introspector.init() { + return Ok(Content::empty()); + } + + let sequence = self.sequence(vt.world, vt.introspector)?; + Ok(match sequence.at(stop) { + Some(value) => { + if let Some(func) = func { + let args = Args::new(func.span(), [value]); + func.call_detached(vt.world, args)?.display() + } else { + value.display() + } + } + None => Content::empty(), + }) + } + + /// Produce the whole sequence of states. + /// + /// This has to happen just once for all states, cutting down the number + /// of state updates from quadratic to linear. + #[comemo::memoize] + fn sequence( + &self, + world: Tracked, + introspector: Tracked, + ) -> SourceResult { + let search = Selector::Node( + NodeId::of::(), + Some(dict! { "state" => self.clone() }), + ); + + let mut stops = EcoVec::new(); + let mut state = self.init.clone(); + + for node in introspector.query(search) { + let id = node.stable_id().unwrap(); + let node = node.to::().unwrap(); + + if let StateAction::Update(update) = node.action() { + match update { + StateUpdate::Set(value) => state = value, + StateUpdate::Func(func) => { + let args = Args::new(func.span(), [state]); + state = func.call_detached(world, args)?; + } + } + } + + stops.push((id, state.clone())); + } + + Ok(StateSequence(stops)) + } +} + +impl Debug for State { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + f.write_str("state(")?; + self.key.fmt(f)?; + f.write_str(", ")?; + self.init.fmt(f)?; + f.write_char(')') + } +} + +cast_from_value! { + State: "state", +} + +/// A sequence of state values. +#[derive(Debug, Clone)] +struct StateSequence(EcoVec<(StableId, Value)>); + +impl StateSequence { + fn at(&self, stop: Option) -> Option { + let entry = match stop { + Some(stop) => self.0.iter().find(|&&(id, _)| id == stop), + None => self.0.last(), + }; + + entry.map(|(_, value)| value.clone()) + } +} diff --git a/macros/src/node.rs b/macros/src/node.rs index 1d05b9a6d..68d43d9c6 100644 --- a/macros/src/node.rs +++ b/macros/src/node.rs @@ -234,7 +234,7 @@ fn create_new_func(node: &Node) -> TokenStream { quote! { /// Create a new node. pub fn new(#(#params),*) -> Self { - Self(::typst::model::Content::new::()) + Self(::typst::model::Content::new(::id())) #(#builder_calls)* } } @@ -388,7 +388,7 @@ fn create_vtable_func(node: &Node) -> TokenStream { quote! { |id| { - let null = Self(::typst::model::Content::new::<#ident>()); + let null = Self(::typst::model::Content::new(<#ident as ::typst::model::Node>::id())); #(#checks)* None } @@ -456,7 +456,7 @@ fn create_construct_impl(node: &Node) -> TokenStream { vm: &::typst::eval::Vm, args: &mut ::typst::eval::Args, ) -> ::typst::diag::SourceResult<::typst::model::Content> { - let mut node = Self(::typst::model::Content::new::()); + let mut node = Self(::typst::model::Content::new(::id())); #(#handlers)* Ok(node.0) } diff --git a/src/eval/library.rs b/src/eval/library.rs index 45c23d170..0e0b38aa5 100644 --- a/src/eval/library.rs +++ b/src/eval/library.rs @@ -90,9 +90,8 @@ pub struct LangItems { pub math_accent: fn(base: Content, accent: char) -> Content, /// A fraction in a formula: `x/2`. pub math_frac: fn(num: Content, denom: Content) -> Content, - /// Dispatch a method on a counter. This is hacky and should be superseded - /// by more dynamic method dispatch. - pub counter_method: fn( + /// Dispatch a method on a library value. + pub library_method: fn( dynamic: &Dynamic, method: &str, args: Args, diff --git a/src/eval/methods.rs b/src/eval/methods.rs index a449ac166..036f7ba22 100644 --- a/src/eval/methods.rs +++ b/src/eval/methods.rs @@ -135,11 +135,7 @@ pub fn call( }, Value::Dyn(dynamic) => { - if dynamic.type_name() == "counter" { - return (vm.items.counter_method)(&dynamic, method, args, span); - } - - return missing(); + return (vm.items.library_method)(&dynamic, method, args, span); } _ => return missing(), @@ -296,6 +292,7 @@ pub fn methods_on(type_name: &str) -> &[(&'static str, bool)] { ("step", true), ("update", true), ], + "state" => &[("get", true), ("final", true), ("update", true)], _ => &[], } } diff --git a/src/model/content.rs b/src/model/content.rs index 11ad635fc..bd24829dc 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -40,12 +40,7 @@ enum Modifier { impl Content { /// Create a content of the given node kind. - pub fn new() -> Self { - Self::new_of(T::id()) - } - - /// Create a content of the given node kind. - pub fn new_of(id: NodeId) -> Self { + pub fn new(id: NodeId) -> Self { Self { id, span: Span::detached(), diff --git a/tests/ref/meta/state.png b/tests/ref/meta/state.png new file mode 100644 index 0000000000000000000000000000000000000000..d48e1dc3c088ef6f39f6b3ec250dfdfccc6a1181 GIT binary patch literal 47353 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 R0x-~zlAOA1le9&|{{?%UyG;N9 literal 0 HcmV?d00001 diff --git a/tests/typ/meta/counter.typ b/tests/typ/meta/counter.typ index 9f6f4c8a0..539af6b90 100644 --- a/tests/typ/meta/counter.typ +++ b/tests/typ/meta/counter.typ @@ -6,7 +6,6 @@ Final: #mine.final() \ #mine.step() -#mine.step() First: #mine.get() \ #mine.update(7) #mine.both("1 of 1") \ diff --git a/tests/typ/meta/state.typ b/tests/typ/meta/state.typ new file mode 100644 index 000000000..dd34deac2 --- /dev/null +++ b/tests/typ/meta/state.typ @@ -0,0 +1,24 @@ +// Test state. + +--- +#set page(width: 200pt) +#set text(8pt) + +#let ls = state("lorem", lorem(1000).split(".")) +#let loremum(count) = { + ls.get(list => list.slice(0, count).join(".").trim() + ".") + ls.update(list => list.slice(count)) +} + +#let fs = state("fader", red) +#let trait(title) = block[ + #fs.get(color => text(fill: color)[ + *#title:* #loremum(1) + ]) + #fs.update(color => color.lighten(30%)) +] + +#trait[Boldness] +#trait[Adventure] +#trait[Fear] +#trait[Anger]