summaryrefslogtreecommitdiff
path: root/src/library/font.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-08-16 22:14:27 +0200
committerLaurenz <laurmaedje@gmail.com>2020-08-16 22:39:21 +0200
commit30f16bbf6431ca0c174ca0a1abaa6a13ef50ab06 (patch)
treef5a5c0adad15840ebe24b39e77ff467862067c91 /src/library/font.rs
parent9f6137d8a829fe8f34554623495fa620252a0184 (diff)
Add Value type and replace dyn-nodes with call-exprs 🏗
- In addition to syntax trees there are now `Value`s, which syntax trees can be evaluated into (e.g. the tree is `5+5` and the value is `10`) - Parsing is completely pure, function calls are not parsed into nodes, but into simple call expressions, which are resolved later - Functions aren't dynamic nodes anymore, but simply functions which receive their arguments as a table and the layouting context - Functions may return any `Value` - Layouting is powered by functions which return the new `Commands` value, which informs the layouting engine what to do - When a function returns a non-`Commands` value, the layouter simply dumps the value into the document in monospace
Diffstat (limited to 'src/library/font.rs')
-rw-r--r--src/library/font.rs110
1 files changed, 45 insertions, 65 deletions
diff --git a/src/library/font.rs b/src/library/font.rs
index 8787cc91..71e9552f 100644
--- a/src/library/font.rs
+++ b/src/library/font.rs
@@ -18,80 +18,60 @@ use super::*;
/// ```typst
/// serif = ("Source Serif Pro", "Noto Serif")
/// ```
-pub fn font(call: FuncCall, _: &ParseState) -> Pass<SyntaxNode> {
+pub async fn font(mut args: TableValue, ctx: LayoutContext<'_>) -> Pass<Value> {
let mut f = Feedback::new();
- let mut args = call.args;
- let node = FontNode {
- content: args.take::<SyntaxTree>(),
- size: args.take::<ScaleLength>(),
- style: args.take_with_key::<_, FontStyle>("style", &mut f),
- weight: args.take_with_key::<_, FontWeight>("weight", &mut f),
- width: args.take_with_key::<_, FontWidth>("width", &mut f),
- list: args.take_all_num_vals::<StringLike>()
- .map(|s| s.0.to_lowercase())
- .collect(),
- classes: args.take_all_str::<TableExpr>()
- .map(|(class, mut table)| {
- let fallback = table.take_all_num_vals::<StringLike>()
- .map(|s| s.0.to_lowercase())
- .collect();
- (class, fallback)
- })
- .collect()
- };
+ let content = args.take::<SyntaxTree>();
+ let size = args.take::<ScaleLength>();
+ let style = args.take_with_key::<_, FontStyle>("style", &mut f);
+ let weight = args.take_with_key::<_, FontWeight>("weight", &mut f);
+ let width = args.take_with_key::<_, FontWidth>("width", &mut f);
+ let list: Vec<_> = args.take_all_num_vals::<StringLike>()
+ .map(|s| s.0.to_lowercase())
+ .collect();
+ let classes: Vec<(_, Vec<_>)> = args.take_all_str::<TableValue>()
+ .map(|(class, mut table)| {
+ let fallback = table.take_all_num_vals::<StringLike>()
+ .map(|s| s.0.to_lowercase())
+ .collect();
+ (class, fallback)
+ })
+ .collect();
args.unexpected(&mut f);
- Pass::node(node, f)
-}
-
-#[derive(Debug, Clone, PartialEq)]
-struct FontNode {
- content: Option<SyntaxTree>,
- size: Option<ScaleLength>,
- style: Option<FontStyle>,
- weight: Option<FontWeight>,
- width: Option<FontWidth>,
- list: Vec<String>,
- classes: Vec<(String, Vec<String>)>,
-}
-
-#[async_trait(?Send)]
-impl Layout for FontNode {
- async fn layout<'a>(&'a self, ctx: LayoutContext<'_>) -> Pass<Commands<'a>> {
- let mut text = ctx.style.text.clone();
-
- self.size.with(|s| match s {
- ScaleLength::Absolute(length) => {
- text.base_font_size = length.as_raw();
- text.font_scale = 1.0;
- }
- ScaleLength::Scaled(scale) => text.font_scale = scale,
- });
- self.style.with(|s| text.variant.style = s);
- self.weight.with(|w| text.variant.weight = w);
- self.width.with(|w| text.variant.width = w);
+ let mut text = ctx.style.text.clone();
- if !self.list.is_empty() {
- *text.fallback.list_mut() = self.list.iter()
- .map(|s| s.to_lowercase())
- .collect();
+ size.with(|s| match s {
+ ScaleLength::Absolute(length) => {
+ text.base_font_size = length.as_raw();
+ text.font_scale = 1.0;
}
+ ScaleLength::Scaled(scale) => text.font_scale = scale,
+ });
- for (class, fallback) in &self.classes {
- text.fallback.set_class_list(class.clone(), fallback.clone());
- }
+ style.with(|s| text.variant.style = s);
+ weight.with(|w| text.variant.weight = w);
+ width.with(|w| text.variant.width = w);
- text.fallback.flatten();
+ if !list.is_empty() {
+ *text.fallback.list_mut() = list.iter()
+ .map(|s| s.to_lowercase())
+ .collect();
+ }
- Pass::okay(match &self.content {
- Some(tree) => vec![
- SetTextStyle(text),
- LayoutSyntaxTree(tree),
- SetTextStyle(ctx.style.text.clone()),
- ],
- None => vec![SetTextStyle(text)],
- })
+ for (class, fallback) in classes {
+ text.fallback.set_class_list(class.clone(), fallback.clone());
}
+
+ text.fallback.flatten();
+
+ Pass::commands(match content {
+ Some(tree) => vec![
+ SetTextStyle(text),
+ LayoutSyntaxTree(tree),
+ SetTextStyle(ctx.style.text.clone()),
+ ],
+ None => vec![SetTextStyle(text)],
+ }, f)
}