A T4-like templating tool with support for F#
Templatus is a templating tool that works (and currently also looks) a lot like T4. The major difference is the fact that blocks that emit text are written in F# instead of C#.
T4 does not support F# :^). Using T4 templates at compile-time is also rather problematic.
Template parsing is implemented using the excellent library FParsec and the execution of text-emitting code is done through the hosting of F# Interactive and F# Compiler Services.
popIndent
, clearIndent
, pushIndent
providing the same functionality as in T4.You can get Templatus as a Nuget package https://www.nuget.org/packages/Templatus/. It resides in the tools
folder under packages\Templatus
.
<#@
and #>
<#@ output filename="..\gen\output.txt" #>
- Specifies the file to generate<#@ include file="sub\include.ttus" #>
- Specifies a nested template whose output will be embedded in place of the directive<#@ assembly name="TestLib.dll" #>
- Specifies an assembly (either in GAC or local to the template) to reference<#= DateTime.Now #>
- Expressions that are evaluated, converted to string (using the %O
format specifier) and printed out<# [1..2] |> List.iter tprintn #>
- Contains arbitrary logic (including function/module declarations that will be available in any control from that point onwards) and can use any of the tprint
functions to print into the output fileNote: Bodies of any control are whitespace-sensitive just like regular F# code, meaning you have to abide by F#'s whitespace rules. Also, tabs are automatically converted to 4 spaces.
tprint
- Takes any object and after calling ToString on it prints the result into the outputtprintn
- The same as above but with a trailing newlinetprintf
- The sprintf
equivalent for printing into the outputtprintfn
- The same as above but with a trailing newlinepushIndent
- Takes a string and puts it on the stack of indent strings. The indent strings are used as a prefix for everything that tprintn
and tprintfn
output.popIndent
- Removes a string from the top of the stack of indent strings. Does not throw an exception when the stack is empty.clearIndent
- Clears the entire stack of indent stringsTemplatus.exe is a command-line template processor that takes a template and an optional list of arguments to make accessible in the template. The following flags are available:
-t "..\..\myTemplate.ttus;anotherTemplate.ttus"
- Specifies the templates to be processed. All of them share the variables that you pass in.-parallelization 2
- The maximum number of templates processed in parallel.-p name=Timmy age=3
- Defines name
and age
variables that you can directly refer to in the template. Note that the variables are always defined as strings. -p
also has to be the last flag used.Suppose I have a folder structure like this:
MySolutionDir
│ MySolutionFile.sln
│
├─lib
│ TestLib.dll
│
├─MyProjectDir
│ include.ttus
│ testTemplate.ttus
│
└─packages
└─Templatus
└─tools
Templatus.exe
The contents of testTemplate.ttus
:
<#@ output filename="output.txt" #>
<#@ assembly name="..\lib\TestLib.dll" #>
Number from TestLib: <#= TestLib.Test.Number () #>
Params: <#= sprintf "Name: %s, Age: %s" name age #>
<#@ include file="include.ttus" #>
Indented numbers:
<#
[1 .. 10]
|> Seq.iter (fun num -> pushIndent " "; tprintfn "%d" num)
[9 .. -1 .. 1]
|> Seq.iter (fun num -> popIndent (); sprintf "%d" num |> tprintn)
clearIndent ()
tprintn "----"
#>
And the template being included:
A line in include
Time in include: <#= DateTime.Now #>
To generate the output file, I just need to execute Templatus.exe
and pass in testTemplate.ttus
:
D:\MySolutionDir> packages\Templatus\tools\Templatus.exe -t MyProjectDir\testTemplate.ttus -p name=Timmy age=3
output.txt
is created and looks like this:
Number from TestLib: 5
Params: Name: Timmy, Age: 3
A line in include
Time in include: 07-Aug-15 10:14:56
Indented numbers:
1
2
3
4
5
6
7
8
9
10
9
8
7
6
5
4
3
2
1
----
<PropertyGroup>
<PackagesFolder>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..\packages'))</PackagesFolder>
</PropertyGroup>
<Target Name="Templates" BeforeTargets="Compile;Build" Inputs="Template.ttus" Outputs="output.txt">
<Exec Command="$(PackagesFolder)\Templatus\tools\Templatus.exe -t "$(MSBuildProjectDirectory)\Template.ttus" -p name=Timmy age=3" Outputs="output.txt" />
</Target>