summaryrefslogtreecommitdiff
path: root/library/src/math
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-03-19 22:28:49 +0100
committerLaurenz <laurmaedje@gmail.com>2023-03-19 22:39:19 +0100
commitab43bd802eafe33977a91893907e67553e099569 (patch)
treeaf4dead92b143348f52e2e8f869df3f7dfd7322a /library/src/math
parentd6aaae0cea1e79eecd85dc94ab85b9ad8eff48e8 (diff)
Renaming and refactoring
Diffstat (limited to 'library/src/math')
-rw-r--r--library/src/math/accent.rs14
-rw-r--r--library/src/math/align.rs6
-rw-r--r--library/src/math/attach.rs26
-rw-r--r--library/src/math/ctx.rs50
-rw-r--r--library/src/math/delimited.rs29
-rw-r--r--library/src/math/frac.rs16
-rw-r--r--library/src/math/fragment.rs8
-rw-r--r--library/src/math/matrix.rs22
-rw-r--r--library/src/math/mod.rs137
-rw-r--r--library/src/math/op.rs14
-rw-r--r--library/src/math/root.rs40
-rw-r--r--library/src/math/row.rs6
-rw-r--r--library/src/math/spacing.rs8
-rw-r--r--library/src/math/style.rs213
-rw-r--r--library/src/math/underover.rs36
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,