summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-04-07 10:50:39 +0200
committerLaurenz <laurmaedje@gmail.com>2022-04-07 11:07:00 +0200
commit3d52387eea321e94c13b61666f7a758052b20c5d (patch)
tree5c55c51ca7e4b53dee61d280c39b7f664b8b9d6b /src/library
parent20b4d590b3efbd9b7a44fd6d3a658e7b84d21b99 (diff)
Rework style chains
Diffstat (limited to 'src/library')
-rw-r--r--src/library/graphics/image.rs2
-rw-r--r--src/library/graphics/shape.rs2
-rw-r--r--src/library/layout/flow.rs4
-rw-r--r--src/library/layout/page.rs6
-rw-r--r--src/library/math/mod.rs11
-rw-r--r--src/library/prelude.rs4
-rw-r--r--src/library/structure/heading.rs42
-rw-r--r--src/library/structure/list.rs12
-rw-r--r--src/library/structure/table.rs7
-rw-r--r--src/library/text/deco.rs10
-rw-r--r--src/library/text/link.rs13
-rw-r--r--src/library/text/mod.rs162
-rw-r--r--src/library/text/par.rs9
-rw-r--r--src/library/text/raw.rs20
-rw-r--r--src/library/text/shaping.rs16
15 files changed, 188 insertions, 132 deletions
diff --git a/src/library/graphics/image.rs b/src/library/graphics/image.rs
index d11de9d1..23ad52ab 100644
--- a/src/library/graphics/image.rs
+++ b/src/library/graphics/image.rs
@@ -82,7 +82,7 @@ impl Layout for ImageNode {
}
// Apply link if it exists.
- if let Some(url) = styles.get_ref(TextNode::LINK) {
+ if let Some(url) = styles.get(TextNode::LINK) {
frame.link(url);
}
diff --git a/src/library/graphics/shape.rs b/src/library/graphics/shape.rs
index 9f9ff889..177f466e 100644
--- a/src/library/graphics/shape.rs
+++ b/src/library/graphics/shape.rs
@@ -132,7 +132,7 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> {
}
// Apply link if it exists.
- if let Some(url) = styles.get_ref(TextNode::LINK) {
+ if let Some(url) = styles.get(TextNode::LINK) {
frame.link(url);
}
diff --git a/src/library/layout/flow.rs b/src/library/layout/flow.rs
index 3602bea6..9f398277 100644
--- a/src/library/layout/flow.rs
+++ b/src/library/layout/flow.rs
@@ -37,12 +37,12 @@ impl Layout for FlowNode {
let styles = map.chain(&styles);
match child {
FlowChild::Leading => {
- let em = styles.get(TextNode::SIZE).abs;
+ let em = styles.get(TextNode::SIZE);
let amount = styles.get(ParNode::LEADING).resolve(em);
layouter.layout_spacing(amount.into());
}
FlowChild::Parbreak => {
- let em = styles.get(TextNode::SIZE).abs;
+ let em = styles.get(TextNode::SIZE);
let leading = styles.get(ParNode::LEADING);
let spacing = styles.get(ParNode::SPACING);
let amount = (leading + spacing).resolve(em);
diff --git a/src/library/layout/page.rs b/src/library/layout/page.rs
index b1008feb..c8af4843 100644
--- a/src/library/layout/page.rs
+++ b/src/library/layout/page.rs
@@ -28,8 +28,10 @@ impl PageNode {
/// How many columns the page has.
pub const COLUMNS: NonZeroUsize = NonZeroUsize::new(1).unwrap();
/// The page's header.
+ #[property(referenced)]
pub const HEADER: Marginal = Marginal::None;
/// The page's footer.
+ #[property(referenced)]
pub const FOOTER: Marginal = Marginal::None;
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
@@ -116,8 +118,8 @@ impl PageNode {
let regions = Regions::repeat(size, size, size.map(Length::is_finite));
let mut frames = child.layout(ctx, &regions, styles)?;
- let header = styles.get_ref(Self::HEADER);
- let footer = styles.get_ref(Self::FOOTER);
+ let header = styles.get(Self::HEADER);
+ let footer = styles.get(Self::FOOTER);
// Realize header and footer.
for frame in &mut frames {
diff --git a/src/library/math/mod.rs b/src/library/math/mod.rs
index ddd80435..e6548438 100644
--- a/src/library/math/mod.rs
+++ b/src/library/math/mod.rs
@@ -15,6 +15,7 @@ pub struct MathNode {
#[node(showable)]
impl MathNode {
/// The raw text's font family. Just the normal text family if `auto`.
+ #[property(referenced)]
pub const FAMILY: Smart<FontFamily> =
Smart::Custom(FontFamily::new("Latin Modern Math"));
@@ -28,16 +29,14 @@ impl MathNode {
impl Show for MathNode {
fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
+ let args = [Value::Str(self.formula.clone()), Value::Bool(self.display)];
let mut content = styles
- .show(self, ctx, [
- Value::Str(self.formula.clone()),
- Value::Bool(self.display),
- ])?
+ .show::<Self, _>(ctx, args)?
.unwrap_or_else(|| Content::Text(self.formula.trim().into()));
let mut map = StyleMap::new();
- if let Smart::Custom(family) = styles.get_cloned(Self::FAMILY) {
- map.set_family(family, styles);
+ if let Smart::Custom(family) = styles.get(Self::FAMILY) {
+ map.set_family(family.clone(), styles);
}
content = content.styled_with_map(map);
diff --git a/src/library/prelude.rs b/src/library/prelude.rs
index 39be5994..a2e296fa 100644
--- a/src/library/prelude.rs
+++ b/src/library/prelude.rs
@@ -9,8 +9,8 @@ pub use typst_macros::node;
pub use crate::diag::{with_alternative, At, Error, StrResult, TypError, TypResult};
pub use crate::eval::{
- Arg, Args, Array, Cast, Content, Dict, Func, Key, Layout, LayoutNode, Merge, Node,
- Regions, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value,
+ Arg, Args, Array, Cast, Content, Dict, Fold, Func, Key, Layout, LayoutNode, Merge,
+ Node, Regions, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value,
};
pub use crate::frame::*;
pub use crate::geom::*;
diff --git a/src/library/structure/heading.rs b/src/library/structure/heading.rs
index 7d3273f5..7b00c643 100644
--- a/src/library/structure/heading.rs
+++ b/src/library/structure/heading.rs
@@ -1,5 +1,5 @@
use crate::library::prelude::*;
-use crate::library::text::{FontFamily, TextNode};
+use crate::library::text::{FontFamily, FontSize, TextNode, Toggle};
/// A section heading.
#[derive(Debug, Hash)]
@@ -14,25 +14,34 @@ pub struct HeadingNode {
#[node(showable)]
impl HeadingNode {
/// The heading's font family. Just the normal text family if `auto`.
+ #[property(referenced)]
pub const FAMILY: Leveled<Smart<FontFamily>> = Leveled::Value(Smart::Auto);
/// The color of text in the heading. Just the normal text color if `auto`.
+ #[property(referenced)]
pub const FILL: Leveled<Smart<Paint>> = Leveled::Value(Smart::Auto);
/// The size of text in the heading.
- pub const SIZE: Leveled<Linear> = Leveled::Mapping(|level| {
+ #[property(referenced)]
+ pub const SIZE: Leveled<FontSize> = Leveled::Mapping(|level| {
let upscale = (1.6 - 0.1 * level as f64).max(0.75);
- Relative::new(upscale).into()
+ FontSize(Relative::new(upscale).into())
});
/// Whether text in the heading is strengthend.
+ #[property(referenced)]
pub const STRONG: Leveled<bool> = Leveled::Value(true);
/// Whether text in the heading is emphasized.
+ #[property(referenced)]
pub const EMPH: Leveled<bool> = Leveled::Value(false);
/// Whether the heading is underlined.
+ #[property(referenced)]
pub const UNDERLINE: Leveled<bool> = Leveled::Value(false);
/// The extra padding above the heading.
+ #[property(referenced)]
pub const ABOVE: Leveled<Length> = Leveled::Value(Length::zero());
/// The extra padding below the heading.
+ #[property(referenced)]
pub const BELOW: Leveled<Length> = Leveled::Value(Length::zero());
/// Whether the heading is block-level.
+ #[property(referenced)]
pub const BLOCK: Leveled<bool> = Leveled::Value(true);
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
@@ -47,16 +56,17 @@ impl Show for HeadingNode {
fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
macro_rules! resolve {
($key:expr) => {
- styles.get_cloned($key).resolve(ctx, self.level)?
+ styles.get($key).resolve(ctx, self.level)?
};
}
- // Resolve the user recipe.
+ let args = [
+ Value::Int(self.level as i64),
+ Value::Content(self.body.clone()),
+ ];
+
let mut body = styles
- .show(self, ctx, [
- Value::Int(self.level as i64),
- Value::Content(self.body.clone()),
- ])?
+ .show::<Self, _>(ctx, args)?
.unwrap_or_else(|| self.body.clone());
let mut map = StyleMap::new();
@@ -71,11 +81,11 @@ impl Show for HeadingNode {
}
if resolve!(Self::STRONG) {
- map.set(TextNode::STRONG, true);
+ map.set(TextNode::STRONG, Toggle);
}
if resolve!(Self::EMPH) {
- map.set(TextNode::EMPH, true);
+ map.set(TextNode::EMPH, Toggle);
}
let mut seq = vec![];
@@ -116,15 +126,15 @@ pub enum Leveled<T> {
Func(Func, Span),
}
-impl<T: Cast> Leveled<T> {
+impl<T: Cast + Clone> Leveled<T> {
/// Resolve the value based on the level.
- pub fn resolve(self, ctx: &mut Context, level: usize) -> TypResult<T> {
+ pub fn resolve(&self, ctx: &mut Context, level: usize) -> TypResult<T> {
Ok(match self {
- Self::Value(value) => value,
+ Self::Value(value) => value.clone(),
Self::Mapping(mapping) => mapping(level),
Self::Func(func, span) => {
- let args = Args::from_values(span, [Value::Int(level as i64)]);
- func.call(ctx, args)?.cast().at(span)?
+ let args = Args::from_values(*span, [Value::Int(level as i64)]);
+ func.call(ctx, args)?.cast().at(*span)?
}
})
}
diff --git a/src/library/structure/list.rs b/src/library/structure/list.rs
index 414f601e..1b22e166 100644
--- a/src/library/structure/list.rs
+++ b/src/library/structure/list.rs
@@ -31,6 +31,7 @@ pub type EnumNode = ListNode<ORDERED>;
#[node(showable)]
impl<const L: ListKind> ListNode<L> {
/// How the list is labelled.
+ #[property(referenced)]
pub const LABEL: Label = Label::Default;
/// The spacing between the list items of a non-wide list.
pub const SPACING: Linear = Linear::zero();
@@ -58,17 +59,14 @@ impl<const L: ListKind> ListNode<L> {
impl<const L: ListKind> Show for ListNode<L> {
fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
- let content = if let Some(content) = styles.show(
- self,
- ctx,
- self.items.iter().map(|item| Value::Content((*item.body).clone())),
- )? {
+ let args = self.items.iter().map(|item| Value::Content((*item.body).clone()));
+ let content = if let Some(content) = styles.show::<Self, _>(ctx, args)? {
content
} else {
let mut children = vec![];
let mut number = self.start;
- let label = styles.get_ref(Self::LABEL);
+ let label = styles.get(Self::LABEL);
for item in &self.items {
number = item.number.unwrap_or(number);
@@ -79,7 +77,7 @@ impl<const L: ListKind> Show for ListNode<L> {
number += 1;
}
- let em = styles.get(TextNode::SIZE).abs;
+ let em = styles.get(TextNode::SIZE);
let leading = styles.get(ParNode::LEADING);
let spacing = if self.wide {
styles.get(ParNode::SPACING)
diff --git a/src/library/structure/table.rs b/src/library/structure/table.rs
index 0e455ead..64785006 100644
--- a/src/library/structure/table.rs
+++ b/src/library/structure/table.rs
@@ -55,11 +55,8 @@ impl TableNode {
impl Show for TableNode {
fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
- if let Some(content) = styles.show(
- self,
- ctx,
- self.children.iter().map(|child| Value::Content(child.clone())),
- )? {
+ let args = self.children.iter().map(|child| Value::Content(child.clone()));
+ if let Some(content) = styles.show::<Self, _>(ctx, args)? {
return Ok(content);
}
diff --git a/src/library/text/deco.rs b/src/library/text/deco.rs
index b98eb0b2..a6375e4e 100644
--- a/src/library/text/deco.rs
+++ b/src/library/text/deco.rs
@@ -21,11 +21,11 @@ pub type OverlineNode = DecoNode<OVERLINE>;
#[node(showable)]
impl<const L: DecoLine> DecoNode<L> {
/// Stroke color of the line, defaults to the text color if `None`.
- #[shorthand]
+ #[property(shorthand)]
pub const STROKE: Option<Paint> = None;
/// Thickness of the line's strokes (dependent on scaled font size), read
/// from the font tables if `None`.
- #[shorthand]
+ #[property(shorthand)]
pub const THICKNESS: Option<Linear> = None;
/// Position of the line relative to the baseline (dependent on scaled font
/// size), read from the font tables if `None`.
@@ -45,16 +45,16 @@ impl<const L: DecoLine> DecoNode<L> {
impl<const L: DecoLine> Show for DecoNode<L> {
fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
Ok(styles
- .show(self, ctx, [Value::Content(self.0.clone())])?
+ .show::<Self, _>(ctx, [Value::Content(self.0.clone())])?
.unwrap_or_else(|| {
- self.0.clone().styled(TextNode::LINES, vec![Decoration {
+ self.0.clone().styled(TextNode::DECO, Decoration {
line: L,
stroke: styles.get(Self::STROKE),
thickness: styles.get(Self::THICKNESS),
offset: styles.get(Self::OFFSET),
extent: styles.get(Self::EXTENT),
evade: styles.get(Self::EVADE),
- }])
+ })
}))
}
}
diff --git a/src/library/text/link.rs b/src/library/text/link.rs
index 4c2b5e7b..3ef7011d 100644
--- a/src/library/text/link.rs
+++ b/src/library/text/link.rs
@@ -29,14 +29,13 @@ impl LinkNode {
impl Show for LinkNode {
fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
+ let args = [Value::Str(self.url.clone()), match &self.body {
+ Some(body) => Value::Content(body.clone()),
+ None => Value::None,
+ }];
+
let mut body = styles
- .show(self, ctx, [
- Value::Str(self.url.clone()),
- match &self.body {
- Some(body) => Value::Content(body.clone()),
- None => Value::None,
- },
- ])?
+ .show::<Self, _>(ctx, args)?
.or_else(|| self.body.clone())
.unwrap_or_else(|| {
let url = &self.url;
diff --git a/src/library/text/mod.rs b/src/library/text/mod.rs
index 2c163a59..64994136 100644
--- a/src/library/text/mod.rs
+++ b/src/library/text/mod.rs
@@ -13,7 +13,6 @@ pub use raw::*;
pub use shaping::*;
use std::borrow::Cow;
-use std::ops::BitXor;
use ttf_parser::Tag;
@@ -28,7 +27,7 @@ pub struct TextNode;
#[node]
impl TextNode {
/// A prioritized sequence of font families.
- #[variadic]
+ #[property(referenced, variadic)]
pub const FAMILY: Vec<FontFamily> = vec![FontFamily::new("IBM Plex Sans")];
/// Whether to allow font fallback when the primary font list contains no
/// match.
@@ -40,14 +39,13 @@ impl TextNode {
pub const WEIGHT: FontWeight = FontWeight::REGULAR;
/// The width of the glyphs.
pub const STRETCH: FontStretch = FontStretch::NORMAL;
+ /// The size of the glyphs.
+ #[property(shorthand, fold)]
+ pub const SIZE: FontSize = Length::pt(11.0);
/// The glyph fill color.
- #[shorthand]
+ #[property(shorthand)]
pub const FILL: Paint = Color::BLACK.into();
- /// The size of the glyphs.
- #[shorthand]
- #[fold(Linear::compose)]
- pub const SIZE: Linear = Length::pt(11.0).into();
/// The amount of space that should be added between characters.
pub const TRACKING: Em = Em::zero();
/// The ratio by which spaces should be stretched.
@@ -84,26 +82,24 @@ impl TextNode {
/// Whether to convert fractions. ("frac")
pub const FRACTIONS: bool = false;
/// Raw OpenType features to apply.
+ #[property(fold)]
pub const FEATURES: Vec<(Tag, u32)> = vec![];
/// Whether the font weight should be increased by 300.
- #[skip]
- #[fold(bool::bitxor)]
- pub const STRONG: bool = false;
+ #[property(hidden, fold)]
+ pub const STRONG: Toggle = false;
/// Whether the the font style should be inverted.
- #[skip]
- #[fold(bool::bitxor)]
- pub const EMPH: bool = false;
- /// The case transformation that should be applied to the next.
- #[skip]
+ #[property(hidden, fold)]
+ pub const EMPH: Toggle = false;
+ /// A case transformation that should be applied to the text.
+ #[property(hidden)]
pub const CASE: Option<Case> = None;
- /// Decorative lines.
- #[skip]
- #[fold(|a, b| a.into_iter().chain(b).collect())]
- pub const LINES: Vec<Decoration> = vec![];
/// An URL the text should link to.
- #[skip]
+ #[property(hidden, referenced)]
pub const LINK: Option<EcoString> = None;
+ /// Decorative lines.
+ #[property(hidden, fold)]
+ pub const DECO: Decoration = vec![];
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
// The text constructor is special: It doesn't create a text node.
@@ -113,44 +109,6 @@ impl TextNode {
}
}
-/// Strong text, rendered in boldface.
-#[derive(Debug, Hash)]
-pub struct StrongNode(pub Content);
-
-#[node(showable)]
-impl StrongNode {
- fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
- Ok(Content::show(Self(args.expect("body")?)))
- }
-}
-
-impl Show for StrongNode {
- fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
- Ok(styles
- .show(self, ctx, [Value::Content(self.0.clone())])?
- .unwrap_or_else(|| self.0.clone().styled(TextNode::STRONG, true)))
- }
-}
-
-/// Emphasized text, rendered with an italic face.
-#[derive(Debug, Hash)]
-pub struct EmphNode(pub Content);
-
-#[node(showable)]
-impl EmphNode {
- fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
- Ok(Content::show(Self(args.expect("body")?)))
- }
-}
-
-impl Show for EmphNode {
- fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
- Ok(styles
- .show(self, ctx, [Value::Content(self.0.clone())])?
- .unwrap_or_else(|| self.0.clone().styled(TextNode::EMPH, true)))
- }
-}
-
/// A font family like "Arial".
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct FontFamily(EcoString);
@@ -228,6 +186,26 @@ castable! {
Value::Relative(v) => Self::from_ratio(v.get() as f32),
}
+/// The size of text.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct FontSize(pub Linear);
+
+impl Fold for FontSize {
+ type Output = Length;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ self.0.rel.resolve(outer) + self.0.abs
+ }
+}
+
+castable! {
+ FontSize,
+ Expected: "linear",
+ Value::Length(v) => Self(v.into()),
+ Value::Relative(v) => Self(v.into()),
+ Value::Linear(v) => Self(v),
+}
+
castable! {
Em,
Expected: "float",
@@ -353,6 +331,15 @@ castable! {
.collect(),
}
+impl Fold for Vec<(Tag, u32)> {
+ type Output = Self;
+
+ fn fold(mut self, outer: Self::Output) -> Self::Output {
+ self.extend(outer);
+ self
+ }
+}
+
/// A case transformation on text.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Case {
@@ -371,3 +358,62 @@ impl Case {
}
}
}
+
+/// A toggle that turns on and off alternatingly if folded.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct Toggle;
+
+impl Fold for Toggle {
+ type Output = bool;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ !outer
+ }
+}
+
+impl Fold for Decoration {
+ type Output = Vec<Self>;
+
+ fn fold(self, mut outer: Self::Output) -> Self::Output {
+ outer.insert(0, self);
+ outer
+ }
+}
+
+/// Strong text, rendered in boldface.
+#[derive(Debug, Hash)]
+pub struct StrongNode(pub Content);
+
+#[node(showable)]
+impl StrongNode {
+ fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
+ Ok(Content::show(Self(args.expect("body")?)))
+ }
+}
+
+impl Show for StrongNode {
+ fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
+ Ok(styles
+ .show::<Self, _>(ctx, [Value::Content(self.0.clone())])?
+ .unwrap_or_else(|| self.0.clone().styled(TextNode::STRONG, Toggle)))
+ }
+}
+
+/// Emphasized text, rendered with an italic face.
+#[derive(Debug, Hash)]
+pub struct EmphNode(pub Content);
+
+#[node(showable)]
+impl EmphNode {
+ fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
+ Ok(Content::show(Self(args.expect("body")?)))
+ }
+}
+
+impl Show for EmphNode {
+ fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
+ Ok(styles
+ .show::<Self, _>(ctx, [Value::Content(self.0.clone())])?
+ .unwrap_or_else(|| self.0.clone().styled(TextNode::EMPH, Toggle)))
+ }
+}
diff --git a/src/library/text/par.rs b/src/library/text/par.rs
index 97e5a3f5..67357135 100644
--- a/src/library/text/par.rs
+++ b/src/library/text/par.rs
@@ -28,6 +28,7 @@ pub enum ParChild {
#[node]
impl ParNode {
/// An ISO 639-1 language code.
+ #[property(referenced)]
pub const LANG: Option<EcoString> = None;
/// The direction for text and inline objects.
pub const DIR: Dir = Dir::LTR;
@@ -611,7 +612,7 @@ fn breakpoints<'a>(
let mut lang = None;
if styles.get(ParNode::HYPHENATE).unwrap_or(styles.get(ParNode::JUSTIFY)) {
lang = styles
- .get_ref(ParNode::LANG)
+ .get(ParNode::LANG)
.as_ref()
.and_then(|iso| iso.as_bytes().try_into().ok())
.and_then(hypher::Lang::from_iso);
@@ -768,7 +769,7 @@ fn stack(
regions: &Regions,
styles: StyleChain,
) -> Vec<Arc<Frame>> {
- let em = styles.get(TextNode::SIZE).abs;
+ let em = styles.get(TextNode::SIZE);
let leading = styles.get(ParNode::LEADING).resolve(em);
let align = styles.get(ParNode::ALIGN);
let justify = styles.get(ParNode::JUSTIFY);
@@ -832,7 +833,7 @@ fn commit(
if let Some(glyph) = text.glyphs.first() {
if text.styles.get(TextNode::OVERHANG) {
let start = text.dir.is_positive();
- let em = text.styles.get(TextNode::SIZE).abs;
+ let em = text.styles.get(TextNode::SIZE);
let amount = overhang(glyph.c, start) * glyph.x_advance.resolve(em);
offset -= amount;
remaining += amount;
@@ -847,7 +848,7 @@ fn commit(
&& (reordered.len() > 1 || text.glyphs.len() > 1)
{
let start = !text.dir.is_positive();
- let em = text.styles.get(TextNode::SIZE).abs;
+ let em = text.styles.get(TextNode::SIZE);
let amount = overhang(glyph.c, start) * glyph.x_advance.resolve(em);
remaining += amount;
}
diff --git a/src/library/text/raw.rs b/src/library/text/raw.rs
index 5c2133c2..f09bc1d0 100644
--- a/src/library/text/raw.rs
+++ b/src/library/text/raw.rs
@@ -3,7 +3,7 @@ use syntect::easy::HighlightLines;
use syntect::highlighting::{FontStyle, Highlighter, Style, Theme, ThemeSet};
use syntect::parsing::SyntaxSet;
-use super::{FontFamily, TextNode};
+use super::{FontFamily, TextNode, Toggle};
use crate::library::prelude::*;
use crate::source::SourceId;
use crate::syntax::{self, RedNode};
@@ -27,8 +27,10 @@ pub struct RawNode {
#[node(showable)]
impl RawNode {
/// The raw text's font family. Just the normal text family if `none`.
+ #[property(referenced)]
pub const FAMILY: Smart<FontFamily> = Smart::Custom(FontFamily::new("IBM Plex Mono"));
/// The language to syntax-highlight in.
+ #[property(referenced)]
pub const LANG: Option<EcoString> = None;
fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> {
@@ -41,7 +43,7 @@ impl RawNode {
impl Show for RawNode {
fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> {
- let lang = styles.get_ref(Self::LANG).as_ref();
+ let lang = styles.get(Self::LANG).as_ref();
let foreground = THEME
.settings
.foreground
@@ -49,14 +51,16 @@ impl Show for RawNode {
.unwrap_or(Color::BLACK)
.into();
- let mut content = if let Some(content) = styles.show(self, ctx, [
+ let args = [
Value::Str(self.text.clone()),
match lang {
Some(lang) => Value::Str(lang.clone()),
None => Value::None,
},
Value::Bool(self.block),
- ])? {
+ ];
+
+ let mut content = if let Some(content) = styles.show::<Self, _>(ctx, args)? {
content
} else if matches!(
lang.map(|s| s.to_lowercase()).as_deref(),
@@ -93,8 +97,8 @@ impl Show for RawNode {
};
let mut map = StyleMap::new();
- if let Smart::Custom(family) = styles.get_cloned(Self::FAMILY) {
- map.set_family(family, styles);
+ if let Smart::Custom(family) = styles.get(Self::FAMILY) {
+ map.set_family(family.clone(), styles);
}
content = content.styled_with_map(map);
@@ -118,11 +122,11 @@ fn styled(piece: &str, foreground: Paint, style: Style) -> Content {
}
if style.font_style.contains(FontStyle::BOLD) {
- styles.set(TextNode::STRONG, true);
+ styles.set(TextNode::STRONG, Toggle);
}
if style.font_style.contains(FontStyle::ITALIC) {
- styles.set(TextNode::EMPH, true);
+ styles.set(TextNode::EMPH, Toggle);
}
if style.font_style.contains(FontStyle::UNDERLINE) {
diff --git a/src/library/text/shaping.rs b/src/library/text/shaping.rs
index 6087032f..66936792 100644
--- a/src/library/text/shaping.rs
+++ b/src/library/text/shaping.rs
@@ -77,7 +77,7 @@ impl<'a> ShapedText<'a> {
for (face_id, group) in self.glyphs.as_ref().group_by_key(|g| g.face_id) {
let pos = Point::new(offset, self.baseline);
- let size = self.styles.get(TextNode::SIZE).abs;
+ let size = self.styles.get(TextNode::SIZE);
let fill = self.styles.get(TextNode::FILL);
let glyphs = group
.iter()
@@ -99,7 +99,7 @@ impl<'a> ShapedText<'a> {
let width = text.width();
// Apply line decorations.
- for deco in self.styles.get_cloned(TextNode::LINES) {
+ for deco in self.styles.get(TextNode::DECO) {
decorate(&mut frame, &deco, fonts, &text, pos, width);
}
@@ -108,7 +108,7 @@ impl<'a> ShapedText<'a> {
}
// Apply link if it exists.
- if let Some(url) = self.styles.get_ref(TextNode::LINK) {
+ if let Some(url) = self.styles.get(TextNode::LINK) {
frame.link(url);
}
@@ -127,7 +127,7 @@ impl<'a> ShapedText<'a> {
.filter(|g| g.is_space())
.map(|g| g.x_advance)
.sum::<Em>()
- .resolve(self.styles.get(TextNode::SIZE).abs)
+ .resolve(self.styles.get(TextNode::SIZE))
}
/// Reshape a range of the shaped text, reusing information from this
@@ -154,7 +154,7 @@ impl<'a> ShapedText<'a> {
/// Push a hyphen to end of the text.
pub fn push_hyphen(&mut self, fonts: &mut FontStore) {
- let size = self.styles.get(TextNode::SIZE).abs;
+ let size = self.styles.get(TextNode::SIZE);
let variant = variant(self.styles);
families(self.styles).find_map(|family| {
let face_id = fonts.select(family, variant)?;
@@ -467,7 +467,7 @@ fn measure(
let mut top = Length::zero();
let mut bottom = Length::zero();
- let size = styles.get(TextNode::SIZE).abs;
+ let size = styles.get(TextNode::SIZE);
let top_edge = styles.get(TextNode::TOP_EDGE);
let bottom_edge = styles.get(TextNode::BOTTOM_EDGE);
@@ -537,7 +537,7 @@ fn families(styles: StyleChain) -> impl Iterator<Item = &str> + Clone {
let tail = if styles.get(TextNode::FALLBACK) { FALLBACKS } else { &[] };
styles
- .get_ref(TextNode::FAMILY)
+ .get(TextNode::FAMILY)
.iter()
.map(|family| family.as_str())
.chain(tail.iter().copied())
@@ -609,7 +609,7 @@ fn tags(styles: StyleChain) -> Vec<Feature> {
feat(b"frac", 1);
}
- for &(tag, value) in styles.get_ref(TextNode::FEATURES).iter() {
+ for (tag, value) in styles.get(TextNode::FEATURES) {
tags.push(Feature::new(tag, value, ..))
}