diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-19 22:28:49 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-19 22:39:19 +0100 |
| commit | ab43bd802eafe33977a91893907e67553e099569 (patch) | |
| tree | af4dead92b143348f52e2e8f869df3f7dfd7322a /library/src/math | |
| parent | d6aaae0cea1e79eecd85dc94ab85b9ad8eff48e8 (diff) | |
Renaming and refactoring
Diffstat (limited to 'library/src/math')
| -rw-r--r-- | library/src/math/accent.rs | 14 | ||||
| -rw-r--r-- | library/src/math/align.rs | 6 | ||||
| -rw-r--r-- | library/src/math/attach.rs | 26 | ||||
| -rw-r--r-- | library/src/math/ctx.rs | 50 | ||||
| -rw-r--r-- | library/src/math/delimited.rs | 29 | ||||
| -rw-r--r-- | library/src/math/frac.rs | 16 | ||||
| -rw-r--r-- | library/src/math/fragment.rs | 8 | ||||
| -rw-r--r-- | library/src/math/matrix.rs | 22 | ||||
| -rw-r--r-- | library/src/math/mod.rs | 137 | ||||
| -rw-r--r-- | library/src/math/op.rs | 14 | ||||
| -rw-r--r-- | library/src/math/root.rs | 40 | ||||
| -rw-r--r-- | library/src/math/row.rs | 6 | ||||
| -rw-r--r-- | library/src/math/spacing.rs | 8 | ||||
| -rw-r--r-- | library/src/math/style.rs | 213 | ||||
| -rw-r--r-- | library/src/math/underover.rs | 36 |
15 files changed, 305 insertions, 320 deletions
diff --git a/library/src/math/accent.rs b/library/src/math/accent.rs index 9ef76279..471507c5 100644 --- a/library/src/math/accent.rs +++ b/library/src/math/accent.rs @@ -1,5 +1,3 @@ -use typst::eval::combining_accent; - use super::*; /// How much the accent can be shorter than the base. @@ -16,8 +14,8 @@ const ACCENT_SHORT_FALL: Em = Em::new(0.5); /// /// Display: Accent /// Category: math -#[node(LayoutMath)] -pub struct AccentNode { +#[element(LayoutMath)] +pub struct AccentElem { /// The base to which the accent is applied. /// May consist of multiple letters. /// @@ -50,7 +48,7 @@ pub struct AccentNode { pub accent: Accent, } -impl LayoutMath for AccentNode { +impl LayoutMath for AccentElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { ctx.style(ctx.style.with_cramped(true)); let base = ctx.layout_fragment(&self.base())?; @@ -116,15 +114,15 @@ pub struct Accent(char); impl Accent { /// Normalize a character into an accent. pub fn new(c: char) -> Self { - Self(combining_accent(c).unwrap_or(c)) + Self(Symbol::combining_accent(c).unwrap_or(c)) } } cast_from_value! { Accent, v: char => Self::new(v), - v: Content => match v.to::<TextNode>() { - Some(node) => Value::Str(node.text().into()).cast()?, + v: Content => match v.to::<TextElem>() { + Some(elem) => Value::Str(elem.text().into()).cast()?, None => Err("expected text")?, }, } diff --git a/library/src/math/align.rs b/library/src/math/align.rs index 6cf13a0f..d34379e2 100644 --- a/library/src/math/align.rs +++ b/library/src/math/align.rs @@ -4,10 +4,10 @@ use super::*; /// /// Display: Alignment Point /// Category: math -#[node(LayoutMath)] -pub struct AlignPointNode {} +#[element(LayoutMath)] +pub struct AlignPointElem {} -impl LayoutMath for AlignPointNode { +impl LayoutMath for AlignPointElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { ctx.push(MathFragment::Align); Ok(()) diff --git a/library/src/math/attach.rs b/library/src/math/attach.rs index 7d8749f2..1b315f77 100644 --- a/library/src/math/attach.rs +++ b/library/src/math/attach.rs @@ -13,8 +13,8 @@ use super::*; /// /// Display: Attachment /// Category: math -#[node(LayoutMath)] -pub struct AttachNode { +#[element(LayoutMath)] +pub struct AttachElem { /// The base to which things are attached. #[required] pub base: Content, @@ -26,25 +26,25 @@ pub struct AttachNode { pub bottom: Option<Content>, } -impl LayoutMath for AttachNode { +impl LayoutMath for AttachElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let base = self.base(); - let display_limits = base.is::<LimitsNode>(); - let display_scripts = base.is::<ScriptsNode>(); + let display_limits = base.is::<LimitsElem>(); + let display_scripts = base.is::<ScriptsElem>(); let base = ctx.layout_fragment(&base)?; ctx.style(ctx.style.for_subscript()); let top = self .top(ctx.styles()) - .map(|node| ctx.layout_fragment(&node)) + .map(|elem| ctx.layout_fragment(&elem)) .transpose()?; ctx.unstyle(); ctx.style(ctx.style.for_superscript()); let bottom = self .bottom(ctx.styles()) - .map(|node| ctx.layout_fragment(&node)) + .map(|elem| ctx.layout_fragment(&elem)) .transpose()?; ctx.unstyle(); @@ -75,14 +75,14 @@ impl LayoutMath for AttachNode { /// /// Display: Scripts /// Category: math -#[node(LayoutMath)] -pub struct ScriptsNode { +#[element(LayoutMath)] +pub struct ScriptsElem { /// The base to attach the scripts to. #[required] pub body: Content, } -impl LayoutMath for ScriptsNode { +impl LayoutMath for ScriptsElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { self.body().layout_math(ctx) } @@ -97,14 +97,14 @@ impl LayoutMath for ScriptsNode { /// /// Display: Limits /// Category: math -#[node(LayoutMath)] -pub struct LimitsNode { +#[element(LayoutMath)] +pub struct LimitsElem { /// The base to attach the limits to. #[required] pub body: Content, } -impl LayoutMath for LimitsNode { +impl LayoutMath for LimitsElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { self.body().layout_math(ctx) } diff --git a/library/src/math/ctx.rs b/library/src/math/ctx.rs index bd44546d..aed826b5 100644 --- a/library/src/math/ctx.rs +++ b/library/src/math/ctx.rs @@ -32,7 +32,7 @@ pub struct MathContext<'a, 'b, 'v> { pub constants: ttf_parser::math::Constants<'a>, pub space_width: Em, pub fragments: Vec<MathFragment>, - pub map: StyleMap, + pub local: Styles, pub style: MathStyle, pub size: Abs, outer: StyleChain<'a>, @@ -49,7 +49,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { ) -> Self { let table = font.ttf().tables().math.unwrap(); let constants = table.constants.unwrap(); - let size = TextNode::size_in(styles); + let size = TextElem::size_in(styles); let ttf = font.ttf(); let space_width = ttf .glyph_index(' ') @@ -67,7 +67,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { constants, space_width, fragments: vec![], - map: StyleMap::new(), + local: Styles::new(), style: MathStyle { variant: MathVariant::Serif, size: if block { MathSize::Display } else { MathSize::Text }, @@ -94,39 +94,39 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { pub fn layout_fragment( &mut self, - node: &dyn LayoutMath, + elem: &dyn LayoutMath, ) -> SourceResult<MathFragment> { - let row = self.layout_fragments(node)?; + let row = self.layout_fragments(elem)?; Ok(MathRow::new(row).to_fragment(self)) } pub fn layout_fragments( &mut self, - node: &dyn LayoutMath, + elem: &dyn LayoutMath, ) -> SourceResult<Vec<MathFragment>> { let prev = std::mem::take(&mut self.fragments); - node.layout_math(self)?; + elem.layout_math(self)?; Ok(std::mem::replace(&mut self.fragments, prev)) } - pub fn layout_row(&mut self, node: &dyn LayoutMath) -> SourceResult<MathRow> { - let fragments = self.layout_fragments(node)?; + pub fn layout_row(&mut self, elem: &dyn LayoutMath) -> SourceResult<MathRow> { + let fragments = self.layout_fragments(elem)?; Ok(MathRow::new(fragments)) } - pub fn layout_frame(&mut self, node: &dyn LayoutMath) -> SourceResult<Frame> { - Ok(self.layout_fragment(node)?.to_frame()) + pub fn layout_frame(&mut self, elem: &dyn LayoutMath) -> SourceResult<Frame> { + Ok(self.layout_fragment(elem)?.to_frame()) } pub fn layout_content(&mut self, content: &Content) -> SourceResult<Frame> { Ok(content - .layout(&mut self.vt, self.outer.chain(&self.map), self.regions)? + .layout(&mut self.vt, self.outer.chain(&self.local), self.regions)? .into_frame()) } - pub fn layout_text(&mut self, node: &TextNode) -> SourceResult<()> { - let text = node.text(); - let span = node.span(); + pub fn layout_text(&mut self, elem: &TextElem) -> SourceResult<()> { + let text = elem.text(); + let span = elem.span(); let mut chars = text.chars(); if let Some(glyph) = chars .next() @@ -160,7 +160,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { style = style.with_italic(false); } let text: EcoString = text.chars().map(|c| style.styled_char(c)).collect(); - let frame = self.layout_content(&TextNode::packed(text).spanned(span))?; + let frame = self.layout_content(&TextElem::packed(text).spanned(span))?; self.push( FrameFragment::new(self, frame) .with_class(MathClass::Alphabetic) @@ -172,21 +172,21 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { } pub fn styles(&self) -> StyleChain { - self.outer.chain(&self.map) + self.outer.chain(&self.local) } pub fn style(&mut self, style: MathStyle) { self.style_stack.push((self.style, self.size)); - let base_size = TextNode::size_in(self.styles()) / self.style.size.factor(self); + let base_size = TextElem::size_in(self.styles()) / self.style.size.factor(self); self.size = base_size * style.size.factor(self); - self.map.set(TextNode::set_size(TextSize(self.size.into()))); - self.map - .set(TextNode::set_style(if style.italic == Smart::Custom(true) { + self.local.set(TextElem::set_size(TextSize(self.size.into()))); + self.local + .set(TextElem::set_style(if style.italic == Smart::Custom(true) { FontStyle::Italic } else { FontStyle::Normal })); - self.map.set(TextNode::set_weight(if style.bold { + self.local.set(TextElem::set_weight(if style.bold { FontWeight::BOLD } else { FontWeight::REGULAR @@ -196,9 +196,9 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { pub fn unstyle(&mut self) { (self.style, self.size) = self.style_stack.pop().unwrap(); - self.map.unset(); - self.map.unset(); - self.map.unset(); + self.local.unset(); + self.local.unset(); + self.local.unset(); } } diff --git a/library/src/math/delimited.rs b/library/src/math/delimited.rs index 2b9ee5ed..3be17eae 100644 --- a/library/src/math/delimited.rs +++ b/library/src/math/delimited.rs @@ -16,8 +16,8 @@ pub(super) const DELIM_SHORT_FALL: Em = Em::new(0.1); /// /// Display: Left/Right /// Category: math -#[node(LayoutMath)] -pub struct LrNode { +#[element(LayoutMath)] +pub struct LrElem { /// The size of the brackets, relative to the height of the wrapped content. /// /// Defaults to `{100%}`. @@ -29,7 +29,7 @@ pub struct LrNode { let mut body = Content::empty(); for (i, arg) in args.all::<Content>()?.into_iter().enumerate() { if i > 0 { - body += TextNode::packed(','); + body += TextElem::packed(','); } body += arg; } @@ -38,12 +38,12 @@ pub struct LrNode { pub body: Content, } -impl LayoutMath for LrNode { +impl LayoutMath for LrElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let mut body = self.body(); - if let Some(node) = body.to::<LrNode>() { - if node.size(ctx.styles()).is_auto() { - body = node.body(); + if let Some(elem) = body.to::<LrElem>() { + if elem.size(ctx.styles()).is_auto() { + body = elem.body(); } } @@ -179,12 +179,11 @@ pub fn norm( } fn delimited(body: Content, left: char, right: char) -> Value { - Value::Content( - LrNode::new(Content::sequence(vec![ - TextNode::packed(left), - body, - TextNode::packed(right), - ])) - .pack(), - ) + LrElem::new(Content::sequence([ + TextElem::packed(left), + body, + TextElem::packed(right), + ])) + .pack() + .into() } diff --git a/library/src/math/frac.rs b/library/src/math/frac.rs index 90bc69b3..f19fb32e 100644 --- a/library/src/math/frac.rs +++ b/library/src/math/frac.rs @@ -19,8 +19,8 @@ const FRAC_AROUND: Em = Em::new(0.1); /// /// Display: Fraction /// Category: math -#[node(LayoutMath)] -pub struct FracNode { +#[element(LayoutMath)] +pub struct FracElem { /// The fraction's numerator. #[required] pub num: Content, @@ -30,7 +30,7 @@ pub struct FracNode { pub denom: Content, } -impl LayoutMath for FracNode { +impl LayoutMath for FracElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { layout(ctx, &self.num(), &self.denom(), false, self.span()) } @@ -45,8 +45,8 @@ impl LayoutMath for FracNode { /// /// Display: Binomial /// Category: math -#[node(LayoutMath)] -pub struct BinomNode { +#[element(LayoutMath)] +pub struct BinomElem { /// The binomial's upper index. #[required] pub upper: Content, @@ -56,7 +56,7 @@ pub struct BinomNode { pub lower: Content, } -impl LayoutMath for BinomNode { +impl LayoutMath for BinomElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { layout(ctx, &self.upper(), &self.lower(), true, self.span()) } @@ -132,9 +132,9 @@ fn layout( } else { frame.push( line_pos, - Element::Shape( + FrameItem::Shape( Geometry::Line(Point::with_x(line_width)).stroked(Stroke { - paint: TextNode::fill_in(ctx.styles()), + paint: TextElem::fill_in(ctx.styles()), thickness, }), span, diff --git a/library/src/math/fragment.rs b/library/src/math/fragment.rs index 87e28555..0d663d3f 100644 --- a/library/src/math/fragment.rs +++ b/library/src/math/fragment.rs @@ -181,8 +181,8 @@ impl GlyphFragment { id, c, font: ctx.font.clone(), - lang: TextNode::lang_in(ctx.styles()), - fill: TextNode::fill_in(ctx.styles()), + lang: TextElem::lang_in(ctx.styles()), + fill: TextElem::fill_in(ctx.styles()), style: ctx.style, font_size: ctx.size, width, @@ -215,7 +215,7 @@ impl GlyphFragment { } pub fn to_frame(&self) -> Frame { - let text = Text { + let item = TextItem { font: self.font.clone(), size: self.font_size, fill: self.fill, @@ -232,7 +232,7 @@ impl GlyphFragment { let size = Size::new(self.width, self.ascent + self.descent); let mut frame = Frame::new(size); frame.set_baseline(self.ascent); - frame.push(Point::with_y(self.ascent), Element::Text(text)); + frame.push(Point::with_y(self.ascent), FrameItem::Text(item)); frame } } diff --git a/library/src/math/matrix.rs b/library/src/math/matrix.rs index d79c7ca5..8fba10e7 100644 --- a/library/src/math/matrix.rs +++ b/library/src/math/matrix.rs @@ -16,8 +16,8 @@ const VERTICAL_PADDING: Ratio = Ratio::new(0.1); /// /// Display: Vector /// Category: math -#[node(LayoutMath)] -pub struct VecNode { +#[element(LayoutMath)] +pub struct VecElem { /// The delimiter to use. /// /// ```example @@ -32,7 +32,7 @@ pub struct VecNode { pub children: Vec<Content>, } -impl LayoutMath for VecNode { +impl LayoutMath for VecElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = self.delim(ctx.styles()); let frame = layout_vec_body(ctx, &self.children(), Align::Center)?; @@ -68,8 +68,8 @@ impl LayoutMath for VecNode { /// /// Display: Matrix /// Category: math -#[node(LayoutMath)] -pub struct MatNode { +#[element(LayoutMath)] +pub struct MatElem { /// The delimiter to use. /// /// ```example @@ -114,7 +114,7 @@ pub struct MatNode { pub rows: Vec<Vec<Content>>, } -impl LayoutMath for MatNode { +impl LayoutMath for MatElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = self.delim(ctx.styles()); let frame = layout_mat_body(ctx, &self.rows())?; @@ -144,8 +144,8 @@ impl LayoutMath for MatNode { /// /// Display: Cases /// Category: math -#[node(LayoutMath)] -pub struct CasesNode { +#[element(LayoutMath)] +pub struct CasesElem { /// The delimiter to use. /// /// ```example @@ -160,7 +160,7 @@ pub struct CasesNode { pub children: Vec<Content>, } -impl LayoutMath for CasesNode { +impl LayoutMath for CasesElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = self.delim(ctx.styles()); let frame = layout_vec_body(ctx, &self.children(), Align::Left)?; @@ -221,8 +221,8 @@ fn layout_vec_body( let gap = ROW_GAP.scaled(ctx); ctx.style(ctx.style.for_denominator()); let mut flat = vec![]; - for element in column { - flat.push(ctx.layout_row(element)?); + for child in column { + flat.push(ctx.layout_row(child)?); } ctx.unstyle(); Ok(stack(ctx, flat, align, gap, 0)) diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs index 7fb1aadf..cf665203 100644 --- a/library/src/math/mod.rs +++ b/library/src/math/mod.rs @@ -31,69 +31,69 @@ pub use self::underover::*; use ttf_parser::{GlyphId, Rect}; use typst::eval::{Module, Scope}; use typst::font::{Font, FontWeight}; -use typst::model::{Guard, SequenceNode, StyledNode}; +use typst::model::Guard; use unicode_math_class::MathClass; use self::ctx::*; use self::fragment::*; use self::row::*; use self::spacing::*; -use crate::layout::{HNode, ParNode, Spacing}; +use crate::layout::{HElem, ParElem, Spacing}; use crate::meta::{Count, Counter, CounterUpdate, LocalName, Numbering}; use crate::prelude::*; use crate::text::{ - families, variant, FontFamily, FontList, LinebreakNode, SpaceNode, TextNode, TextSize, + families, variant, FontFamily, FontList, LinebreakElem, SpaceElem, TextElem, TextSize, }; /// Create a module with all math definitions. pub fn module() -> Module { let mut math = Scope::deduplicating(); - math.define("equation", EquationNode::id()); - math.define("text", TextNode::id()); + math.define("equation", EquationElem::func()); + math.define("text", TextElem::func()); // Grouping. - math.define("lr", LrNode::id()); + math.define("lr", LrElem::func()); math.define("abs", abs); math.define("norm", norm); math.define("floor", floor); math.define("ceil", ceil); // Attachments and accents. - math.define("attach", AttachNode::id()); - math.define("scripts", ScriptsNode::id()); - math.define("limits", LimitsNode::id()); - math.define("accent", AccentNode::id()); - math.define("underline", UnderlineNode::id()); - math.define("overline", OverlineNode::id()); - math.define("underbrace", UnderbraceNode::id()); - math.define("overbrace", OverbraceNode::id()); - math.define("underbracket", UnderbracketNode::id()); - math.define("overbracket", OverbracketNode::id()); + math.define("attach", AttachElem::func()); + math.define("scripts", ScriptsElem::func()); + math.define("limits", LimitsElem::func()); + math.define("accent", AccentElem::func()); + math.define("underline", UnderlineElem::func()); + math.define("overline", OverlineElem::func()); + math.define("underbrace", UnderbraceElem::func()); + math.define("overbrace", OverbraceElem::func()); + math.define("underbracket", UnderbracketElem::func()); + math.define("overbracket", OverbracketElem::func()); // Fractions and matrix-likes. - math.define("frac", FracNode::id()); - math.define("binom", BinomNode::id()); - math.define("vec", VecNode::id()); - math.define("mat", MatNode::id()); - math.define("cases", CasesNode::id()); + math.define("frac", FracElem::func()); + math.define("binom", BinomElem::func()); + math.define("vec", VecElem::func()); + math.define("mat", MatElem::func()); + math.define("cases", CasesElem::func()); // Roots. - math.define("sqrt", SqrtNode::id()); - math.define("root", RootNode::id()); + math.define("sqrt", sqrt); + math.define("root", RootElem::func()); // Styles. - math.define("upright", UprightNode::id()); - math.define("bold", BoldNode::id()); - math.define("italic", ItalicNode::id()); - math.define("serif", SerifNode::id()); - math.define("sans", SansNode::id()); - math.define("cal", CalNode::id()); - math.define("frak", FrakNode::id()); - math.define("mono", MonoNode::id()); - math.define("bb", BbNode::id()); + math.define("upright", upright); + math.define("bold", bold); + math.define("italic", italic); + math.define("serif", serif); + math.define("sans", sans); + math.define("cal", cal); + math.define("frak", frak); + math.define("mono", mono); + math.define("bb", bb); // Text operators. - math.define("op", OpNode::id()); + math.define("op", OpElem::func()); op::define(&mut math); // Spacings. @@ -133,8 +133,8 @@ pub fn module() -> Module { /// /// Display: Equation /// Category: math -#[node(Locatable, Synthesize, Show, Finalize, Layout, LayoutMath, Count, LocalName)] -pub struct EquationNode { +#[element(Locatable, Synthesize, Show, Finalize, Layout, LayoutMath, Count, LocalName)] +pub struct EquationElem { /// Whether the equation is displayed as a separate block. #[default(false)] pub block: bool, @@ -157,16 +157,16 @@ pub struct EquationNode { pub body: Content, } -impl Synthesize for EquationNode { +impl Synthesize for EquationElem { fn synthesize(&mut self, _: &Vt, styles: StyleChain) { self.push_block(self.block(styles)); self.push_numbering(self.numbering(styles)); } } -impl Show for EquationNode { +impl Show for EquationElem { fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> { - let mut realized = self.clone().pack().guarded(Guard::Base(NodeId::of::<Self>())); + let mut realized = self.clone().pack().guarded(Guard::Base(Self::func())); if self.block(styles) { realized = realized.aligned(Axes::with_x(Some(Align::Center.into()))) } @@ -174,17 +174,17 @@ impl Show for EquationNode { } } -impl Finalize for EquationNode { +impl Finalize for EquationElem { fn finalize(&self, realized: Content, _: StyleChain) -> Content { realized - .styled(TextNode::set_weight(FontWeight::from_number(450))) - .styled(TextNode::set_font(FontList(vec![FontFamily::new( + .styled(TextElem::set_weight(FontWeight::from_number(450))) + .styled(TextElem::set_font(FontList(vec![FontFamily::new( "New Computer Modern Math", )]))) } } -impl Layout for EquationNode { +impl Layout for EquationElem { fn layout( &self, vt: &mut Vt, @@ -215,7 +215,7 @@ impl Layout for EquationNode { if block { if let Some(numbering) = self.numbering(styles) { let pod = Regions::one(regions.base(), Axes::splat(false)); - let counter = Counter::of(Self::id()) + let counter = Counter::of(Self::func()) .display(numbering, false) .layout(vt, styles, pod)? .into_frame(); @@ -230,7 +230,7 @@ impl Layout for EquationNode { let height = frame.height().max(counter.height()); frame.resize(Size::new(width, height), Align::CENTER_HORIZON); - let x = if TextNode::dir_in(styles).is_positive() { + let x = if TextElem::dir_in(styles).is_positive() { frame.width() - counter.width() } else { Abs::zero() @@ -240,10 +240,10 @@ impl Layout for EquationNode { frame.push_frame(Point::new(x, y), counter) } } else { - let slack = ParNode::leading_in(styles) * 0.7; - let top_edge = TextNode::top_edge_in(styles).resolve(styles, font.metrics()); + let slack = ParElem::leading_in(styles) * 0.7; + let top_edge = TextElem::top_edge_in(styles).resolve(styles, font.metrics()); let bottom_edge = - -TextNode::bottom_edge_in(styles).resolve(styles, font.metrics()); + -TextElem::bottom_edge_in(styles).resolve(styles, font.metrics()); let ascent = top_edge.max(frame.ascent() - slack); let descent = bottom_edge.max(frame.descent() - slack); @@ -255,7 +255,7 @@ impl Layout for EquationNode { } } -impl Count for EquationNode { +impl Count for EquationElem { fn update(&self) -> Option<CounterUpdate> { (self.block(StyleChain::default()) && self.numbering(StyleChain::default()).is_some()) @@ -263,7 +263,7 @@ impl Count for EquationNode { } } -impl LocalName for EquationNode { +impl LocalName for EquationElem { fn local_name(&self, lang: Lang) -> &'static str { match lang { Lang::GERMAN => "Gleichung", @@ -276,7 +276,7 @@ pub trait LayoutMath { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()>; } -impl LayoutMath for EquationNode { +impl LayoutMath for EquationElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { self.body().layout_math(ctx) } @@ -284,45 +284,44 @@ impl LayoutMath for EquationNode { impl LayoutMath for Content { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - if let Some(node) = self.to::<SequenceNode>() { - for child in node.children() { + if let Some(children) = self.to_sequence() { + for child in children { child.layout_math(ctx)?; } return Ok(()); } - if let Some(styled) = self.to::<StyledNode>() { - let map = styled.styles(); - if TextNode::font_in(ctx.styles().chain(&map)) - != TextNode::font_in(ctx.styles()) + if let Some((elem, styles)) = self.to_styled() { + if TextElem::font_in(ctx.styles().chain(&styles)) + != TextElem::font_in(ctx.styles()) { let frame = ctx.layout_content(self)?; ctx.push(FrameFragment::new(ctx, frame).with_spaced(true)); return Ok(()); } - let prev_map = std::mem::replace(&mut ctx.map, map); + let prev_map = std::mem::replace(&mut ctx.local, styles.clone()); let prev_size = ctx.size; - ctx.map.apply(prev_map.clone()); - ctx.size = TextNode::size_in(ctx.styles()); - styled.body().layout_math(ctx)?; + ctx.local.apply(prev_map.clone()); + ctx.size = TextElem::size_in(ctx.styles()); + elem.layout_math(ctx)?; ctx.size = prev_size; - ctx.map = prev_map; + ctx.local = prev_map; return Ok(()); } - if self.is::<SpaceNode>() { + if self.is::<SpaceElem>() { ctx.push(MathFragment::Space(ctx.space_width.scaled(ctx))); return Ok(()); } - if self.is::<LinebreakNode>() { + if self.is::<LinebreakElem>() { ctx.push(MathFragment::Linebreak); return Ok(()); } - if let Some(node) = self.to::<HNode>() { - if let Spacing::Rel(rel) = node.amount() { + if let Some(elem) = self.to::<HElem>() { + if let Spacing::Rel(rel) = elem.amount() { if rel.rel.is_zero() { ctx.push(MathFragment::Spacing(rel.abs.resolve(ctx.styles()))); } @@ -330,13 +329,13 @@ impl LayoutMath for Content { return Ok(()); } - if let Some(node) = self.to::<TextNode>() { - ctx.layout_text(node)?; + if let Some(elem) = self.to::<TextElem>() { + ctx.layout_text(elem)?; return Ok(()); } - if let Some(node) = self.with::<dyn LayoutMath>() { - return node.layout_math(ctx); + if let Some(elem) = self.with::<dyn LayoutMath>() { + return elem.layout_math(ctx); } let mut frame = ctx.layout_content(self)?; diff --git a/library/src/math/op.rs b/library/src/math/op.rs index dae43c3a..e8db0c5d 100644 --- a/library/src/math/op.rs +++ b/library/src/math/op.rs @@ -20,8 +20,8 @@ use super::*; /// /// Display: Text Operator /// Category: math -#[node(LayoutMath)] -pub struct OpNode { +#[element(LayoutMath)] +pub struct OpElem { /// The operator's text. #[required] pub text: EcoString, @@ -33,9 +33,9 @@ pub struct OpNode { pub limits: bool, } -impl LayoutMath for OpNode { +impl LayoutMath for OpElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - let frame = ctx.layout_content(&TextNode::packed(self.text()))?; + let frame = ctx.layout_content(&TextElem::packed(self.text()))?; ctx.push( FrameFragment::new(ctx, frame) .with_class(MathClass::Large) @@ -50,14 +50,14 @@ macro_rules! ops { pub(super) fn define(math: &mut Scope) { $(math.define( stringify!($name), - OpNode::new(ops!(@name $name $(: $value)?).into()) + OpElem::new(ops!(@name $name $(: $value)?).into()) .with_limits(ops!(@limit $($tts)*)) .pack() );)* let dif = |d| { - HNode::new(THIN.into()).pack() - + UprightNode::new(TextNode::packed(d)).pack() + HElem::new(THIN.into()).pack() + + MathStyleElem::new(TextElem::packed(d)).with_italic(Some(false)).pack() }; math.define("dif", dif('d')); math.define("Dif", dif('D')); diff --git a/library/src/math/root.rs b/library/src/math/root.rs index b4756b9d..037c6ce7 100644 --- a/library/src/math/root.rs +++ b/library/src/math/root.rs @@ -9,17 +9,13 @@ use super::*; /// /// Display: Square Root /// Category: math -#[node(LayoutMath)] -pub struct SqrtNode { +/// Returns: content +#[func] +pub fn sqrt( /// The expression to take the square root of. - #[required] - pub radicand: Content, -} - -impl LayoutMath for SqrtNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, None, &self.radicand(), self.span()) - } + radicand: Content, +) -> Value { + RootElem::new(radicand).pack().into() } /// A general root. @@ -31,20 +27,20 @@ impl LayoutMath for SqrtNode { /// /// Display: Root /// Category: math -#[node(LayoutMath)] -pub struct RootNode { +#[element(LayoutMath)] +pub struct RootElem { /// Which root of the radicand to take. - #[required] - index: Content, + #[positional] + index: Option<Content>, /// The expression to take the root of. #[required] radicand: Content, } -impl LayoutMath for RootNode { +impl LayoutMath for RootElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, Some(&self.index()), &self.radicand(), self.span()) + layout(ctx, self.index(ctx.styles()).as_ref(), &self.radicand(), self.span()) } } @@ -88,7 +84,7 @@ fn layout( // Layout the index. // Script-script style looks too small, we use Script style instead. ctx.style(ctx.style.with_size(MathSize::Script)); - let index = index.map(|node| ctx.layout_frame(node)).transpose()?; + let index = index.map(|elem| ctx.layout_frame(elem)).transpose()?; ctx.unstyle(); let gap = gap.max((sqrt.height() - radicand.height() - thickness) / 2.0); @@ -124,9 +120,9 @@ fn layout( frame.push_frame(sqrt_pos, sqrt); frame.push( line_pos, - Element::Shape( + FrameItem::Shape( Geometry::Line(Point::with_x(radicand.width())) - .stroked(Stroke { paint: TextNode::fill_in(ctx.styles()), thickness }), + .stroked(Stroke { paint: TextElem::fill_in(ctx.styles()), thickness }), span, ), ); @@ -139,15 +135,15 @@ fn layout( /// Select a precomposed radical, if the font has it. fn precomposed(ctx: &MathContext, index: Option<&Content>, target: Abs) -> Option<Frame> { - let node = index?.to::<TextNode>()?; - let c = match node.text().as_str() { + let elem = index?.to::<TextElem>()?; + let c = match elem.text().as_str() { "3" => '∛', "4" => '∜', _ => return None, }; ctx.ttf.glyph_index(c)?; - let glyph = GlyphFragment::new(ctx, c, node.span()); + let glyph = GlyphFragment::new(ctx, c, elem.span()); let variant = glyph.stretch_vertical(ctx, target, Abs::zero()).frame; if variant.height() < target { return None; diff --git a/library/src/math/row.rs b/library/src/math/row.rs index ecb2e31e..67d9eeaf 100644 --- a/library/src/math/row.rs +++ b/library/src/math/row.rs @@ -1,4 +1,4 @@ -use crate::layout::AlignNode; +use crate::layout::AlignElem; use super::*; @@ -103,7 +103,7 @@ impl MathRow { pub fn to_frame(self, ctx: &MathContext) -> Frame { let styles = ctx.styles(); - let align = AlignNode::alignment_in(styles).x.resolve(styles); + let align = AlignElem::alignment_in(styles).x.resolve(styles); self.to_aligned_frame(ctx, &[], align) } @@ -124,7 +124,7 @@ impl MathRow { if self.iter().any(|frag| matches!(frag, MathFragment::Linebreak)) { let fragments: Vec<_> = std::mem::take(&mut self.0); let leading = if ctx.style.size >= MathSize::Text { - ParNode::leading_in(ctx.styles()) + ParElem::leading_in(ctx.styles()) } else { TIGHT_LEADING.scaled(ctx) }; diff --git a/library/src/math/spacing.rs b/library/src/math/spacing.rs index e1b9d408..848aca78 100644 --- a/library/src/math/spacing.rs +++ b/library/src/math/spacing.rs @@ -7,10 +7,10 @@ pub(super) const QUAD: Em = Em::new(1.0); /// Hook up all spacings. pub(super) fn define(math: &mut Scope) { - math.define("thin", HNode::new(THIN.into()).pack()); - math.define("med", HNode::new(MEDIUM.into()).pack()); - math.define("thick", HNode::new(THICK.into()).pack()); - math.define("quad", HNode::new(QUAD.into()).pack()); + math.define("thin", HElem::new(THIN.into()).pack()); + math.define("med", HElem::new(MEDIUM.into()).pack()); + math.define("thick", HElem::new(THICK.into()).pack()); + math.define("quad", HElem::new(QUAD.into()).pack()); } /// Create the spacing between two fragments in a given style. diff --git a/library/src/math/style.rs b/library/src/math/style.rs index a3383a0c..7a911a0a 100644 --- a/library/src/math/style.rs +++ b/library/src/math/style.rs @@ -9,20 +9,13 @@ use super::*; /// /// Display: Bold /// Category: math -#[node(LayoutMath)] -pub struct BoldNode { +/// Returns: content +#[func] +pub fn bold( /// The content to style. - #[required] - pub body: Content, -} - -impl LayoutMath for BoldNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_bold(true)); - self.body().layout_math(ctx)?; - ctx.unstyle(); - Ok(()) - } + body: Content, +) -> Value { + MathStyleElem::new(body).with_bold(Some(true)).pack().into() } /// Upright (non-italic) font style in math. @@ -34,20 +27,13 @@ impl LayoutMath for BoldNode { /// /// Display: Upright /// Category: math -#[node(LayoutMath)] -pub struct UprightNode { +/// Returns: content +#[func] +pub fn upright( /// The content to style. - #[required] - pub body: Content, -} - -impl LayoutMath for UprightNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_italic(false)); - self.body().layout_math(ctx)?; - ctx.unstyle(); - Ok(()) - } + body: Content, +) -> Value { + MathStyleElem::new(body).with_italic(Some(false)).pack().into() } /// Italic font style in math. @@ -56,42 +42,30 @@ impl LayoutMath for UprightNode { /// /// Display: Italic /// Category: math -#[node(LayoutMath)] -pub struct ItalicNode { +/// Returns: content +#[func] +pub fn italic( /// The content to style. - #[required] - pub body: Content, -} - -impl LayoutMath for ItalicNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_italic(true)); - self.body().layout_math(ctx)?; - ctx.unstyle(); - Ok(()) - } + body: Content, +) -> Value { + MathStyleElem::new(body).with_italic(Some(true)).pack().into() } - /// Serif (roman) font style in math. /// /// This is already the default. /// /// Display: Serif /// Category: math -#[node(LayoutMath)] -pub struct SerifNode { +/// Returns: content +#[func] +pub fn serif( /// The content to style. - #[required] - pub body: Content, -} - -impl LayoutMath for SerifNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_variant(MathVariant::Serif)); - self.body().layout_math(ctx)?; - ctx.unstyle(); - Ok(()) - } + body: Content, +) -> Value { + MathStyleElem::new(body) + .with_variant(Some(MathVariant::Serif)) + .pack() + .into() } /// Sans-serif font style in math. @@ -103,20 +77,16 @@ impl LayoutMath for SerifNode { /// /// Display: Sans-serif /// Category: math -#[node(LayoutMath)] -pub struct SansNode { +/// Returns: content +#[func] +pub fn sans( /// The content to style. - #[required] - pub body: Content, -} - -impl LayoutMath for SansNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_variant(MathVariant::Sans)); - self.body().layout_math(ctx)?; - ctx.unstyle(); - Ok(()) - } + body: Content, +) -> Value { + MathStyleElem::new(body) + .with_variant(Some(MathVariant::Sans)) + .pack() + .into() } /// Calligraphic font style in math. @@ -128,20 +98,16 @@ impl LayoutMath for SansNode { /// /// Display: Calligraphic /// Category: math -#[node(LayoutMath)] -pub struct CalNode { +/// Returns: content +#[func] +pub fn cal( /// The content to style. - #[required] - pub body: Content, -} - -impl LayoutMath for CalNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_variant(MathVariant::Cal)); - self.body().layout_math(ctx)?; - ctx.unstyle(); - Ok(()) - } + body: Content, +) -> Value { + MathStyleElem::new(body) + .with_variant(Some(MathVariant::Cal)) + .pack() + .into() } /// Fraktur font style in math. @@ -153,20 +119,16 @@ impl LayoutMath for CalNode { /// /// Display: Fraktur /// Category: math -#[node(LayoutMath)] -pub struct FrakNode { +/// Returns: content +#[func] +pub fn frak( /// The content to style. - #[required] - pub body: Content, -} - -impl LayoutMath for FrakNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_variant(MathVariant::Frak)); - self.body().layout_math(ctx)?; - ctx.unstyle(); - Ok(()) - } + body: Content, +) -> Value { + MathStyleElem::new(body) + .with_variant(Some(MathVariant::Frak)) + .pack() + .into() } /// Monospace font style in math. @@ -178,20 +140,16 @@ impl LayoutMath for FrakNode { /// /// Display: Monospace /// Category: math -#[node(LayoutMath)] -pub struct MonoNode { +/// Returns: content +#[func] +pub fn mono( /// The content to style. - #[required] - pub body: Content, -} - -impl LayoutMath for MonoNode { - fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_variant(MathVariant::Mono)); - self.body().layout_math(ctx)?; - ctx.unstyle(); - Ok(()) - } + body: Content, +) -> Value { + MathStyleElem::new(body) + .with_variant(Some(MathVariant::Mono)) + .pack() + .into() } /// Blackboard bold (double-struck) font style in math. @@ -208,16 +166,51 @@ impl LayoutMath for MonoNode { /// /// Display: Blackboard Bold /// Category: math -#[node(LayoutMath)] -pub struct BbNode { +/// Returns: content +#[func] +pub fn bb( + /// The content to style. + body: Content, +) -> Value { + MathStyleElem::new(body) + .with_variant(Some(MathVariant::Bb)) + .pack() + .into() +} + +/// A font variant in math. +/// +/// Display: Bold +/// Category: math +#[element(LayoutMath)] +pub struct MathStyleElem { /// The content to style. #[required] pub body: Content, + + /// The variant to select. + pub variant: Option<MathVariant>, + + /// Whether to use bold glyphs. + pub bold: Option<bool>, + + /// Whether to use italic glyphs. + pub italic: Option<bool>, } -impl LayoutMath for BbNode { +impl LayoutMath for MathStyleElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - ctx.style(ctx.style.with_variant(MathVariant::Bb)); + let mut style = ctx.style; + if let Some(variant) = self.variant(StyleChain::default()) { + style = style.with_variant(variant); + } + if let Some(bold) = self.bold(StyleChain::default()) { + style = style.with_bold(bold); + } + if let Some(italic) = self.italic(StyleChain::default()) { + style = style.with_italic(italic); + } + ctx.style(style); self.body().layout_math(ctx)?; ctx.unstyle(); Ok(()) @@ -324,7 +317,7 @@ impl MathSize { } /// A mathematical style variant, as defined by Unicode. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Cast)] pub enum MathVariant { Serif, Sans, diff --git a/library/src/math/underover.rs b/library/src/math/underover.rs index cfbb30b6..654da354 100644 --- a/library/src/math/underover.rs +++ b/library/src/math/underover.rs @@ -13,14 +13,14 @@ const BRACKET_GAP: Em = Em::new(0.25); /// /// Display: Underline /// Category: math -#[node(LayoutMath)] -pub struct UnderlineNode { +#[element(LayoutMath)] +pub struct UnderlineElem { /// The content above the line. #[required] pub body: Content, } -impl LayoutMath for UnderlineNode { +impl LayoutMath for UnderlineElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { layout(ctx, &self.body(), &None, '\u{305}', LINE_GAP, false, self.span()) } @@ -35,14 +35,14 @@ impl LayoutMath for UnderlineNode { /// /// Display: Overline /// Category: math -#[node(LayoutMath)] -pub struct OverlineNode { +#[element(LayoutMath)] +pub struct OverlineElem { /// The content below the line. #[required] pub body: Content, } -impl LayoutMath for OverlineNode { +impl LayoutMath for OverlineElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { layout(ctx, &self.body(), &None, '\u{332}', LINE_GAP, true, self.span()) } @@ -57,8 +57,8 @@ impl LayoutMath for OverlineNode { /// /// Display: Underbrace /// Category: math -#[node(LayoutMath)] -pub struct UnderbraceNode { +#[element(LayoutMath)] +pub struct UnderbraceElem { /// The content above the brace. #[required] pub body: Content, @@ -68,7 +68,7 @@ pub struct UnderbraceNode { pub annotation: Option<Content>, } -impl LayoutMath for UnderbraceNode { +impl LayoutMath for UnderbraceElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { layout( ctx, @@ -91,8 +91,8 @@ impl LayoutMath for UnderbraceNode { /// /// Display: Overbrace /// Category: math -#[node(LayoutMath)] -pub struct OverbraceNode { +#[element(LayoutMath)] +pub struct OverbraceElem { /// The content below the brace. #[required] pub body: Content, @@ -102,7 +102,7 @@ pub struct OverbraceNode { pub annotation: Option<Content>, } -impl LayoutMath for OverbraceNode { +impl LayoutMath for OverbraceElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { layout( ctx, @@ -125,8 +125,8 @@ impl LayoutMath for OverbraceNode { /// /// Display: Underbracket /// Category: math -#[node(LayoutMath)] -pub struct UnderbracketNode { +#[element(LayoutMath)] +pub struct UnderbracketElem { /// The content above the bracket. #[required] pub body: Content, @@ -136,7 +136,7 @@ pub struct UnderbracketNode { pub annotation: Option<Content>, } -impl LayoutMath for UnderbracketNode { +impl LayoutMath for UnderbracketElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { layout( ctx, @@ -159,8 +159,8 @@ impl LayoutMath for UnderbracketNode { /// /// Display: Overbracket /// Category: math -#[node(LayoutMath)] -pub struct OverbracketNode { +#[element(LayoutMath)] +pub struct OverbracketElem { /// The content below the bracket. #[required] pub body: Content, @@ -170,7 +170,7 @@ pub struct OverbracketNode { pub annotation: Option<Content>, } -impl LayoutMath for OverbracketNode { +impl LayoutMath for OverbracketElem { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { layout( ctx, |
