Creating non-trivial documents

In the previous article we've established that basic building
block of Templater is context detection and mapping.
Context can be simple such as whole document, a single row
in a table or list, but it can be a lot more complex, like
multiple rows in a table, nested range inside nested range and etc.

The other two basic elements of Templater are formatters and
data processors. Let's look more closely at formatters.

Formatters are used for runtime formatting of
data and conditional look and feel of document.
The simplest example of formatter is :format(XX) metadata.
This formatter is useful when you want to pass XX argument
to ToString function for currently processed property.

For example: tag [[Item.Price]] can be displayed
in Templater with two decimals in multiple ways:

If available it's probably best to use document formatting
features to format this number with two decimals. While Excel
has such formatting features, they can only be used when single
tag is used per cell.

Using format(N2) in .NET or format(2f) in JVM metadata on tag.
This would make tag look like: [[Item.Price]:format(N2)]

By preformatting data in object model. If we add GetPrice2()
method which returns Price field with two decimals we can use it with [[Item.GetPrice2]] tag.

This option should be last resort to formatting.
If we find ourselves constantly using this option for same feature,
this indicates a missing feature in Templater which
you can build yourself. Smaller features can be added as plugins,
while more complicated can be done with source code licensing.

Another kind of formatter (besides redirecting method call) is
conditional look and feel of document. Let's say that we have
a collection of objects and wan't to display them in a table.
But we wan't to hide the table if it's empty.
For this collapse formatter is available. When collapse metadata
is found it will inspect provided value and if it's null, empty
collection or None it will invoke collapsing of it's context.

How this works in practice?
Let's say that we have this model of Loan with Applicant and CoApplicant
where Applicant is mandatory, but CoApplicant is optional.
Our model looks like:

From the model we can recognize our context.
Since CoApplicant is optional we will add it to resizable object (like table)
and add collapse metadata inside it.
Here is an example of template for this model:

So when we run Templater with out data it will populate or remove table
for CoApplicant depending on wheater it exists or not.

Templater evolved in .NET so it levreges it's strong points like reification.
Since JVM uses erasure Templater can't implement all the features on JVM and some
hacks are required when building documents in JVM.
If we have a table which we wan't to expand or shirnk depending on the provided data,
everything works fine when provided collection has data in it, but when it's empty
erasure starts making problems.
In .NET Templater can detect tags in a table even when provided collection is empty,
but in JVM when empty collection is provided Templater will leave tags unmodified.

We have two options to fix this problem: we can resize this table manually by using low level api
ITemplater.resize(int) or we can provide helper tag with collapse metadata which will
remove this row.

Let's take a look when it would be useful to add new formatters.
Templater supports pictures which means that if you have Image as your property it
can replace that tag with provided picture. But what if we have pictures as urls
in our model. Let's say that our model looks like:

public class Player
{
public string Name;
public Uri RemotePicture;
}

If we wan't to download and insert this picture when we proces our template document we have
two options. One is to extend our model and add an Image Picture property in it.
This is probably the preferred way in this case. But we could also add link to picture
formatter which would read the Uri value and return an Image object from the downloaded
stream. In our document tags would look (depending on how we implemented our formatter)
like [[RemotePicture]:linkToPicture].