From 094462cbdda15f19d2dc071b18201f656b8ddcd4 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 12 Feb 2021 23:11:47 +0100 Subject: [PATCH] =?UTF-8?q?Make=20templates=20and=20strings=20summable=20?= =?UTF-8?q?=F0=9F=A5=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/eval/ops.rs | 12 +++++++++++- src/eval/value.rs | 2 ++ src/exec/mod.rs | 1 + src/pretty.rs | 3 ++- tests/lang/typ/for-value.typ | 4 ++-- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/eval/ops.rs b/src/eval/ops.rs index c52a62ca7..c4adf5873 100644 --- a/src/eval/ops.rs +++ b/src/eval/ops.rs @@ -30,6 +30,7 @@ pub fn neg(value: Value) -> Value { /// Compute the sum of two values. pub fn add(lhs: Value, rhs: Value) -> Value { match (lhs, rhs) { + // Math. (Int(a), Int(b)) => Int(a + b), (Int(a), Float(b)) => Float(a as f64 + b), (Float(a), Int(b)) => Float(a + b as f64), @@ -45,14 +46,23 @@ pub fn add(lhs: Value, rhs: Value) -> Value { (Linear(a), Relative(b)) => Linear(a + b), (Linear(a), Linear(b)) => Linear(a + b), + // Collections. (Str(a), Str(b)) => Str(a + &b), (Array(a), Array(b)) => Array(concat(a, b)), (Dict(a), Dict(b)) => Dict(concat(a, b)), - // TODO: Add string and template. + // Templates. (Template(a), Template(b)) => Template(concat(a, b)), (Template(a), None) => Template(a), (None, Template(b)) => Template(b), + (Template(mut a), Str(b)) => Template({ + a.push(TemplateNode::Str(b)); + a + }), + (Str(a), Template(mut b)) => Template({ + b.insert(0, TemplateNode::Str(a)); + b + }), _ => Error, } diff --git a/src/eval/value.rs b/src/eval/value.rs index 2879e6d65..e175b9ffc 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -119,6 +119,8 @@ pub enum TemplateNode { /// The evaluated expressions for the `tree`. map: ExprMap, }, + /// A template that was converted from a string. + Str(String), /// A template that can implement custom behaviour. Any(TemplateAny), } diff --git a/src/exec/mod.rs b/src/exec/mod.rs index 57fe81383..a9a44c109 100644 --- a/src/exec/mod.rs +++ b/src/exec/mod.rs @@ -155,6 +155,7 @@ impl Exec for TemplateNode { fn exec(&self, ctx: &mut ExecContext) { match self { Self::Tree { tree, map } => tree.exec_with_map(ctx, &map), + Self::Str(s) => ctx.push_text(s), Self::Any(any) => any.exec(ctx), } } diff --git a/src/pretty.rs b/src/pretty.rs index 2e16a9143..41fd6d78e 100644 --- a/src/pretty.rs +++ b/src/pretty.rs @@ -120,7 +120,7 @@ impl PrettyWithMap for Node { Self::Linebreak => p.push_str(r"\"), Self::Parbreak => p.push_str("\n\n"), // TODO: Handle escaping. - Self::Text(text) => p.push_str(&text), + Self::Text(text) => p.push_str(text), Self::Heading(heading) => heading.pretty_with_map(p, map), Self::Raw(raw) => raw.pretty(p), Self::Expr(expr) => { @@ -538,6 +538,7 @@ impl Pretty for TemplateNode { fn pretty(&self, p: &mut Printer) { match self { Self::Tree { tree, map } => tree.pretty_with_map(p, Some(map)), + Self::Str(s) => p.push_str(s), Self::Any(any) => any.pretty(p), } } diff --git a/tests/lang/typ/for-value.typ b/tests/lang/typ/for-value.typ index f0705fc5f..1813787d2 100644 --- a/tests/lang/typ/for-value.typ +++ b/tests/lang/typ/for-value.typ @@ -9,12 +9,12 @@ // Block body yields template. // Should output `[1st, 2nd, 3rd, 4th, 5th, 6th]`. { - [\[] + #for v #in (1, 2, 3, 4, 5, 6) { + "[" + #for v #in (1, 2, 3, 4, 5, 6) { (#if v > 1 [, ] + [{v}] + #if v == 1 [st] + #if v == 2 [nd] + #if v == 3 [rd] + #if v >= 4 [th]) - } + [\]] + } + "]" }