diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-06-06 21:13:59 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-06-06 22:06:16 +0200 |
| commit | fd417da04f7ca4b995de7f6510abafd3e9c31307 (patch) | |
| tree | 3675529c75ca7363701ac8ea306de2cc1d3cbcb3 /library/src/text | |
| parent | 168bdf35bd773e67343c965cb473492cc5cae9e7 (diff) | |
Improve value casting infrastructure
Diffstat (limited to 'library/src/text')
| -rw-r--r-- | library/src/text/deco.rs | 4 | ||||
| -rw-r--r-- | library/src/text/misc.rs | 52 | ||||
| -rw-r--r-- | library/src/text/mod.rs | 96 | ||||
| -rw-r--r-- | library/src/text/shaping.rs | 5 |
4 files changed, 64 insertions, 93 deletions
diff --git a/library/src/text/deco.rs b/library/src/text/deco.rs index cfb06956..329d3f85 100644 --- a/library/src/text/deco.rs +++ b/library/src/text/deco.rs @@ -251,8 +251,8 @@ impl Fold for Decoration { } } -cast_from_value! { - Decoration: "decoration", +cast! { + type Decoration: "decoration", } /// A kind of decorative line. diff --git a/library/src/text/misc.rs b/library/src/text/misc.rs index 5dafe4ac..2af7a212 100644 --- a/library/src/text/misc.rs +++ b/library/src/text/misc.rs @@ -115,15 +115,12 @@ impl Show for StrongElem { #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct Delta(pub i64); -cast_from_value! { +cast! { Delta, + self => self.0.into_value(), v: i64 => Self(v), } -cast_to_value! { - v: Delta => v.0.into() -} - impl Fold for Delta { type Output = i64; @@ -176,15 +173,12 @@ impl Show for EmphElem { #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct Toggle; -cast_from_value! { +cast! { Toggle, + self => Value::None, _: Value => Self, } -cast_to_value! { - _: Toggle => Value::None -} - impl Fold for Toggle { type Output = bool; @@ -204,12 +198,11 @@ impl Fold for Toggle { /// /// Display: Lowercase /// Category: text -/// Returns: string or content #[func] pub fn lower( /// The text to convert to lowercase. - text: ToCase, -) -> Value { + text: Caseable, +) -> Caseable { case(text, Case::Lower) } @@ -224,31 +217,36 @@ pub fn lower( /// /// Display: Uppercase /// Category: text -/// Returns: string or content #[func] pub fn upper( /// The text to convert to uppercase. - text: ToCase, -) -> Value { + text: Caseable, +) -> Caseable { case(text, Case::Upper) } /// Change the case of text. -fn case(text: ToCase, case: Case) -> Value { +fn case(text: Caseable, case: Case) -> Caseable { match text { - ToCase::Str(v) => Value::Str(case.apply(&v).into()), - ToCase::Content(v) => Value::Content(v.styled(TextElem::set_case(Some(case)))), + Caseable::Str(v) => Caseable::Str(case.apply(&v).into()), + Caseable::Content(v) => { + Caseable::Content(v.styled(TextElem::set_case(Some(case)))) + } } } /// A value whose case can be changed. -enum ToCase { +pub enum Caseable { Str(Str), Content(Content), } -cast_from_value! { - ToCase, +cast! { + Caseable, + self => match self { + Self::Str(v) => v.into_value(), + Self::Content(v) => v.into_value(), + }, v: Str => Self::Str(v), v: Content => Self::Content(v), } @@ -297,13 +295,12 @@ impl Case { /// /// Display: Small Capitals /// Category: text -/// Returns: content #[func] pub fn smallcaps( /// The text to display to small capitals. body: Content, -) -> Value { - Value::Content(body.styled(TextElem::set_smallcaps(true))) +) -> Content { + body.styled(TextElem::set_smallcaps(true)) } /// Create blind text. @@ -324,11 +321,10 @@ pub fn smallcaps( /// /// Display: Blind Text /// Category: text -/// Returns: string #[func] pub fn lorem( /// The length of the blind text in words. words: usize, -) -> Value { - Value::Str(lipsum::lipsum(words).replace("--", "–").into()) +) -> Str { + lipsum::lipsum(words).replace("--", "–").into() } diff --git a/library/src/text/mod.rs b/library/src/text/mod.rs index e86bc168..6090094a 100644 --- a/library/src/text/mod.rs +++ b/library/src/text/mod.rs @@ -14,8 +14,6 @@ pub use self::raw::*; pub use self::shaping::*; pub use self::shift::*; -use std::borrow::Cow; - use rustybuzz::Tag; use typst::font::{FontMetrics, FontStretch, FontStyle, FontWeight, VerticalFontMetric}; @@ -29,16 +27,16 @@ pub(super) fn define(global: &mut Scope) { global.define("smartquote", SmartQuoteElem::func()); global.define("strong", StrongElem::func()); global.define("emph", EmphElem::func()); - global.define("lower", lower); - global.define("upper", upper); - global.define("smallcaps", smallcaps); + global.define("lower", lower_func()); + global.define("upper", upper_func()); + global.define("smallcaps", smallcaps_func()); global.define("sub", SubElem::func()); global.define("super", SuperElem::func()); global.define("underline", UnderlineElem::func()); global.define("strike", StrikeElem::func()); global.define("overline", OverlineElem::func()); global.define("raw", RawElem::func()); - global.define("lorem", lorem); + global.define("lorem", lorem_func()); } /// Customize the look and layout of text in a variety of ways. @@ -560,15 +558,12 @@ impl Debug for FontFamily { } } -cast_from_value! { +cast! { FontFamily, + self => self.0.into_value(), string: EcoString => Self::new(&string), } -cast_to_value! { - v: FontFamily => v.0.into() -} - /// Font family fallback list. #[derive(Debug, Default, Clone, Eq, PartialEq, Hash)] pub struct FontList(pub Vec<FontFamily>); @@ -582,20 +577,17 @@ impl IntoIterator for FontList { } } -cast_from_value! { +cast! { FontList, + self => if self.0.len() == 1 { + self.0.into_iter().next().unwrap().0.into_value() + } else { + self.0.into_value() + }, family: FontFamily => Self(vec![family]), values: Array => Self(values.into_iter().map(|v| v.cast()).collect::<StrResult<_>>()?), } -cast_to_value! { - v: FontList => if v.0.len() == 1 { - v.0.into_iter().next().unwrap().0.into() - } else { - v.0.into() - } -} - /// The size of text. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct TextSize(pub Length); @@ -608,15 +600,12 @@ impl Fold for TextSize { } } -cast_from_value! { +cast! { TextSize, + self => self.0.into_value(), v: Length => Self(v), } -cast_to_value! { - v: TextSize => v.0.into() -} - /// Specifies the bottom or top edge of text. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum TextEdge { @@ -636,25 +625,23 @@ impl TextEdge { } } -cast_from_value! { +cast! { TextEdge, + self => match self { + Self::Metric(metric) => metric.into_value(), + Self::Length(length) => length.into_value(), + }, v: VerticalFontMetric => Self::Metric(v), v: Length => Self::Length(v), } -cast_to_value! { - v: TextEdge => match v { - TextEdge::Metric(metric) => metric.into(), - TextEdge::Length(length) => length.into(), - } -} - /// The direction of text and inline objects in their line. #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)] pub struct TextDir(pub Smart<Dir>); -cast_from_value! { +cast! { TextDir, + self => self.0.into_value(), v: Smart<Dir> => { if v.map_or(false, |dir| dir.axis() == Axis::Y) { Err("text direction must be horizontal")?; @@ -663,10 +650,6 @@ cast_from_value! { }, } -cast_to_value! { - v: TextDir => v.0.into() -} - impl Resolve for TextDir { type Output = Dir; @@ -682,15 +665,12 @@ impl Resolve for TextDir { #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)] pub struct Hyphenate(pub Smart<bool>); -cast_from_value! { +cast! { Hyphenate, + self => self.0.into_value(), v: Smart<bool> => Self(v), } -cast_to_value! { - v: Hyphenate => v.0.into() -} - impl Resolve for Hyphenate { type Output = bool; @@ -718,18 +698,15 @@ impl StylisticSet { } } -cast_from_value! { +cast! { StylisticSet, + self => self.0.into_value(), v: i64 => match v { 1 ..= 20 => Self::new(v as u8), _ => Err("stylistic set must be between 1 and 20")?, }, } -cast_to_value! { - v: StylisticSet => v.0.into() -} - /// Which kind of numbers / figures to select. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Cast)] pub enum NumberType { @@ -754,8 +731,17 @@ pub enum NumberWidth { #[derive(Debug, Default, Clone, Eq, PartialEq, Hash)] pub struct FontFeatures(pub Vec<(Tag, u32)>); -cast_from_value! { +cast! { FontFeatures, + self => self.0 + .into_iter() + .map(|(tag, num)| { + let bytes = tag.to_bytes(); + let key = std::str::from_utf8(&bytes).unwrap_or_default(); + (key.into(), num.into_value()) + }) + .collect::<Dict>() + .into_value(), values: Array => Self(values .into_iter() .map(|v| { @@ -773,18 +759,6 @@ cast_from_value! { .collect::<StrResult<_>>()?), } -cast_to_value! { - v: FontFeatures => Value::Dict( - v.0.into_iter() - .map(|(tag, num)| { - let bytes = tag.to_bytes(); - let key = std::str::from_utf8(&bytes).unwrap_or_default(); - (key.into(), num.into()) - }) - .collect(), - ) -} - impl Fold for FontFeatures { type Output = Self; diff --git a/library/src/text/shaping.rs b/library/src/text/shaping.rs index 3610e0c0..5a1724ab 100644 --- a/library/src/text/shaping.rs +++ b/library/src/text/shaping.rs @@ -1,13 +1,14 @@ +use std::borrow::Cow; use std::ops::Range; use std::str::FromStr; use az::SaturatingAs; use rustybuzz::{Feature, Tag, UnicodeBuffer}; -use typst::font::{Font, FontVariant}; +use typst::font::{Font, FontStyle, FontVariant}; use typst::util::SliceExt; use unicode_script::{Script, UnicodeScript}; -use super::*; +use super::{decorate, FontFamily, NumberType, NumberWidth, TextElem}; use crate::layout::SpanMapper; use crate::prelude::*; |
