aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Linskey2026-06-07 03:45:55 -0400
committerBenjamin Linskey2026-06-07 03:45:55 -0400
commita4ca4afc3ca9181e0c2acc283073549eb7627dea (patch)
tree691c00c32234f6119713b83e788c19775abf7093
parent58b4a2282a2fbd6b0d9183fb654d4c735ec64258 (diff)
downloadtpl-a4ca4afc3ca9181e0c2acc283073549eb7627dea.tar.gz

Improve handling of var references in vars file

Previously, if a previously defined variable was used as a value in a variable assignment, it had to stand alone. This change allows variables to be freely intermixed with text and multiple variables to be used in a single assignment.

-rw-r--r--README.md37
-rw-r--r--example/text.tpl6
-rw-r--r--example/vars11
-rwxr-xr-xtemplate19
4 files changed, 45 insertions, 28 deletions
diff --git a/README.md b/README.md
index 48d0afc..3beb3ed 100644
--- a/README.md
+++ b/README.md
@@ -4,32 +4,37 @@ This is an extremely simple, general-purpose templating script written in awk.
To get started, define a list of variables in a file:
- food = pizza
- beverage = coffee
+ # This is a comment.
+ food = pizza
+ beverage = coffee
+
+ # Previously defined variables can be used in variable definitions.
+ # Whitespace is optional inside braces.
+ dinner = {{ food }} and {{beverage}}
- # Comments look like this, and you can reference previously defined
- # variables like this:
- dinner = {{ food }}
+ # The = character can be surrounded by any number of whitespace
+ # characters.
+ one = 1
+ two = 2
+ three=3
Then reference those variables in your template file by enclosing them in
double braces:
- My favorite food is {{ food }}, and my favorite beverage is {{ coffee }}.
+ My favorite food is {{ food }}, and my favorite beverage is
+ {{ beverage }}. I'm going to have {{ dinner }} for dinner tonight.
+
+ The first three numbers are {{one}}, {{two}}, and {{three}}. {{one}} is
+ the smallest of the three.
Then pass your variable file and template file, in that order, as arguments to
-the `template` script:
+the `template` script. To see the examples above in action, run the following
+command:
- ./template vars favorite-foods.tpl
+ ./template example/vars example/text.tpl
The result will be written to stdout.
-## Example
-
-The `example` directory provides concise sample files that can be processed by
-running the following command from the project directory:
-
- ./template examples/vars examples/text.tpl
-
## Specification
This section describes the behavior of the program in excruciating detail and
@@ -80,7 +85,7 @@ expression metacharacters:
\ ^ $ . [ ] | ( ) * + ? { }
There is one exception to this rule: Variable values may reference variables
-defined earlier in the file, in which case they must use the brace- delimited
+defined earlier in the file, in which case they must use the brace-delimited
variable format described above. Any other use of braces or any other
prohibited character remains illegal when referencing a previously defined
variable. The specified variable name must reference an actual variable
diff --git a/example/text.tpl b/example/text.tpl
index 4b6b5a4..06adb72 100644
--- a/example/text.tpl
+++ b/example/text.tpl
@@ -1,3 +1,5 @@
-The numbers before 3 are {{ one }} and {{two}}. The first number is {{ one }}.
+My favorite food is {{ food }}, and my favorite beverage is {{ beverage }}.
+I'm going to have {{ dinner }} for dinner tonight.
-My favorite color is {{ favorite_color }}. My car is {{ car_color }}.
+The first three numbers are {{one}}, {{two}}, and {{three}}. {{one}} is the
+smallest of the three.
diff --git a/example/vars b/example/vars
index b8182ba..32d59d2 100644
--- a/example/vars
+++ b/example/vars
@@ -1,5 +1,12 @@
# This is a comment.
+food = pizza
+beverage = coffee
+
+# Previously defined variables can be used in variable definitions.
+# Whitespace is optional inside braces.
+dinner = {{ food }} and {{beverage}}
+
+# The = character can be surrounded by any number of whitespace characters.
one = 1
two = 2
-favorite_color=bluish gray
-car_color = {{ favorite_color }}
+three=3
diff --git a/template b/template
index ef1a72e..54f0f6a 100755
--- a/template
+++ b/template
@@ -4,15 +4,18 @@ BEGIN { FS = "[[:space:]]*=[[:space:]]*" }
FILENAME == ARGV[1] && /^#/ { next }
FILENAME == ARGV[1] && NF == 2 {
- # If the value is a template variable that matches a previously defined
- # variable, use that variable's value. Otherwise, use the literal
- # value.
- if (match($2, /\{\{[[:space:]]*[^\{\}[:space:]]+[[:space:]]\}\}/)) {
- match($2, /[^\{\}[:space:]]+/)
- vals[$1] = vals[substr($2, RSTART, RLENGTH)]
- } else {
- vals[$1] = $2
+ # Replace template variables with previously defined values.
+ while (match($2, /\{\{[[:space:]]*[^\{\}[:space:]]+[[:space:]]\}\}/)) {
+ matched_text = substr($2, RSTART, RLENGTH)
+
+ # Extract the actual var name, without braces and space.
+ match(matched_text, /[^\{\}[:space:]]+/)
+ var_name = substr(matched_text, RSTART, RLENGTH)
+
+ sub(matched_text, vals[var_name], $2)
}
+
+ vals[$1] = $2
}
FILENAME == ARGV[1] { next }