From: dbucklin@sdf.org
Date: 2018-03-25
Subject: Simple Templates with Awk

At  the  end  of each sprint, I send a status report to about fifty
people in my organization.  The report is  distributed  as  a  Word
document.   I  could, of course, just use Word to create and manage
these status reports, but I would prefer to do all  my  editing  in
vim and automate the formatting.

My  first  iteration of this process was to create my status report
content in markdown and then pipe it through pandoc [4] to create a
docx file.

      pandoc -f markdown -t docx statusreport.mdown -o statusreport.docx

This  worked  great,  but I was still making a copy of the previous
status report and editing certain parts of it to create  each  suc-
cessive status report.  I wanted to separate the static information
from the dynamic information.  This would make the job of gathering
sprint-specific  data  more  straightforward, and the resulting re-
ports should be more consistent.  I would need some  way  to  merge
the sprint data into the template.  A template engine should do the
trick.

I'm working in a very constrained environment,  MinGW*  [1],  so  I
needed  a lightweight template engine composed of GNU coreutils.  I
have to admit that I cheated.  I figured this was  a  problem  that
Awk could handle, but I wasn't sure where to start.  After a little
searching, I found a blog post [2] at AwkCoder [3] that demonstrat-
ed how to build a simple template engine with Awk.  The trick is to
use NR==FNR to determine whether the first file is being processed.
This  little  template  engine  processes  the  data file first and
builds a hash containing  my  keys  and  their  associated  values.
Next,  it  processes  the  template and substitutes my placeholders
with actual data.

Now, after I gather my sprint-specific information into a  file,  I
can run one command to generate my docx file:

     awk -f tengine.awk sprintNN.dat statusReportTemplate.mdown | pandoc -f markdown -t docx - -o StatusNN.docx

I set this up in a bash script so that I can pass the sprint number
in as an argument.

     #!/bin/bash
     awk -f tengine.awk sprint${1}.dat statusReportTemplate.mdown | pandoc -f markdown -t docx - -o Status${1}.docx

Right now I'm gathering a lot of information manually.  I'd like to
automate  some of this, but I would need to get authentication fig-
ured out using curl, and then I would need  parse  the  information
out  of  JSON  or OData or, gasp, HTML.  I think I might leave well
enough alone.  Maybe.

References:

1. http://mingw.org
2. http://www.awkcoder.com/making-a-simple-template-engine-with-awk.html
3. http://www.awkcoder.com
4. http://pandoc.org

* I get my MinGW environment by installing git-bash.