summaryrefslogtreecommitdiff
path: root/library/src/text
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-06-06 21:13:59 +0200
committerLaurenz <laurmaedje@gmail.com>2023-06-06 22:06:16 +0200
commitfd417da04f7ca4b995de7f6510abafd3e9c31307 (patch)
tree3675529c75ca7363701ac8ea306de2cc1d3cbcb3 /library/src/text
parent168bdf35bd773e67343c965cb473492cc5cae9e7 (diff)
Improve value casting infrastructure
Diffstat (limited to 'library/src/text')
-rw-r--r--library/src/text/deco.rs4
-rw-r--r--library/src/text/misc.rs52
-rw-r--r--library/src/text/mod.rs96
-rw-r--r--library/src/text/shaping.rs5
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::*;