#!/usr/bin/awk -f # Copyright (c) 2026 Benjamin Linskey # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # tpl: An extremely simple general-purpose templating tool. # # Version 1.0.0 # # Usage: tpl [variable file] [template file...] # # More info: https://git.linskey.org/tpl BEGIN { FS = "[[:space:]]*=[[:space:]]*" } FILENAME == ARGV[1] && /^#/ { next } FILENAME == ARGV[1] && NF == 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) # Even though matched_text contains the { and } regex # metacharacters, we don't need to escape them because they're # not used in a way that matches the (r){m,n} syntax. # (We don't need to escape them elsewhere in this program # either, but we do so for maximum clarity.) sub(matched_text, vals[var_name], $2) } vals[$1] = $2 } FILENAME == ARGV[1] { next } /\{\{[[:space:]]*[^\{\}[:space:]]+[[:space:]]*\}\}/ { for (key in vals) { gsub("\{\{[[:space:]]*" key "[[:space:]]*\}\}", vals[key]) } } { print }