A template engine that allows you to have powershell expressions in your templates is a very powerful thing: http://weblogs.asp.net/soever/archive/2006/12/31/a-templating-engine-using-powershell-expressions.aspx
Example Input:
Multi Line Expression:[[ get-date1..20]] Define function [[ function get-theanswer {42;} ]] Single Line: [[ theanswer ]] EOF
Multi Line Expression:[[ get-date1..20]]
Define function [[ function get-theanswer {42;} ]]
Single Line: [[ theanswer ]]
EOF
Example Output:
Multi Line Expression:03/14/2007 22:38:09 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Define function Single Line: 42 EOF
Multi Line Expression:03/14/2007 22:38:09 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Define function
Single Line: 42
The implementation uses dynamic code generation to build an assembly in order to have a delegate to pass to regex.replace.
Using code generation felt a bit over complicated, and I wondered if it could be simpler.
Some thinking and tinkering later, I arrived at a working implementation.
Getting the multiline regex expression working correctly caused me some difficulty; as it only seems to correctly handle \R as a line separator.
I also added the ability to pipe text to the script, since I like to use the syntax: gc file.txt | expand-template
Now as with any powerful tool you'll need to be careful, and be sure that you fully trust the template file (other wise you'll be vulnerable to a code injection attack)
Expand-Template.ps1:
param ($text="",$BeginTag='[[',$EndTag=']]') $begintag = [regex]::escape($begintag) $endtag = [regex]::escape($endtag) $output="" $input | %{$text+=[string]$_ + "`r"} while ($text -match "(?m)(?<pre>.*?)$begintag(?<exp>.*?)$endtag(?<post>.*)") { $text = $matches.post $output += $matches.pre $output += invoke-expression $matches.exp } $output += $text $output -replace "`r", [environment]::newline