summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eval/ops.rs12
-rw-r--r--src/eval/value.rs2
-rw-r--r--src/exec/mod.rs1
-rw-r--r--src/pretty.rs3
-rw-r--r--tests/lang/typ/for-value.typ4
5 files changed, 18 insertions, 4 deletions
diff --git a/src/eval/ops.rs b/src/eval/ops.rs
index c52a62ca..c4adf587 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 2879e6d6..e175b9ff 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 57fe8138..a9a44c10 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 2e16a914..41fd6d78 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 f0705fc5..1813787d 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])
- } + [\]]
+ } + "]"
}