<commit_before>Jefferson <img src="logo.png" width="48" height="48"></img> 
===========================================================
[<img src="http://img.shields.io/nuget/v/Jefferson.svg"></img>](https://www.nuget.org/packages/Jefferson/)

Jefferson is a tiny little "variable replacer" or more often called a "template engine".

```
$$#if Today = Monday$$
   Hello $$#each Users['active']$$, how is $$Name.Capitalize()$$ on this fine Monday$$/each$$?
$$/if$$
```

Strings in between `$$` signs are compiled to Linq expression trees, and the entire template itself is compiled as an expression tree, all while preserving type safety.
Expressions are compiled relative to a context value, often called a model. Names are resolved by first looking for properties and fields of this context and otherwise seeing if these are dynamically declared (e.g. using a dictionary).

Further, as in other template engines, there is support for *directives* and the ability to define new directives.
Provided directives are

`$$#if ...$$` and `$$#each ...$$`

We use this in configuration files for things like

* `$$if(IS_PROD) IncludeFile('foobar')$$`
* `<plugin active='$$IS_DEV and Blah()$$' />`
* etc.

but as output is abstracted through an `IOutputWriter` (and one that implements this using a `TextWriter` is provided) it is very easy to use this to output, say, directly to an HTTP output stream.

## Design philosophy:
* expressions are simple (but powerful), so we stop at assignment, in fact `=` is an alias for `==`
* expression syntax follows C# but extends this, e.g. it adds a Perl like regex match `=~`, "overloads" `&&` with `and` (as this is much nicer to use from xml) and more
* if anything more complex is required, add a method to the context class (aka the model)
* expressions are type safe
* errors are descriptive, helpful and provide accurate source location information
* the focus is runtime performance not compile performance

## Supported expression and template syntax
Some of the following is supported (list not exhaustive):
* arithmetic
* boolean operators
* + as string concatenation
* `?` and `??` and `if else`
* regex support `=~` and `!~` and `/regex/`
* method calls (no fancy overload resolution, however, at the moment)
* indexers (currently restricted to single argument indexers)

In template expressions the *namespaces* `$x` where `x` is a digit can be used to move up the "scope chain". Here `$0 == this`, `$1` is the parent scope etc. Note that whenever any name `foo` is resolved the context/scope chain is always walked from current to top level until a binding is found. If that is not possible an error is thrown *unless* the `except` argument was set to `false` in which case it evaluates to the empty string `""`.

## Supported Directives

### `$$#if$$`
The if directive can be used for conditional output. If the given expression evaluates to true its contents are output. Otherwise if there is an elif statement or an else statement these are executed and otherwise nothing is output.

Syntax is

```
$$#if <expr>$$
   ...
$$#elif <expr>$$
   ...
$$#else$$
   ...
$$/if$$
```<commit_msg>Update README to reflect removal of default values.<commit_after>Jefferson <img src="logo.png" width="48" height="48"></img> 
===========================================================
[<img src="http://img.shields.io/nuget/v/Jefferson.svg"></img>](https://www.nuget.org/packages/Jefferson/)

Jefferson is a tiny little "variable replacer" or more often called a "template engine".

```
$$#if Today = Monday$$
   Hello $$#each Users['active']$$, how is $$Name.Capitalize()$$ on this fine Monday$$/each$$?
$$/if$$
```

Strings in between `$$` signs are compiled to Linq expression trees, and the entire template itself is compiled as an expression tree, all while preserving type safety.
Expressions are compiled relative to a context value, often called a model. Names are resolved by first looking for properties and fields of this context and otherwise seeing if these are dynamically declared (e.g. using a dictionary).

Further, as in other template engines, there is support for *directives* and the ability to define new directives.
Provided directives are

`$$#if ...$$` and `$$#each ...$$`

We use this in configuration files for things like

* `$$if(IS_PROD) IncludeFile('foobar')$$`
* `<plugin active='$$IS_DEV and Blah()$$' />`
* etc.

but as output is abstracted through an `IOutputWriter` (and one that implements this using a `TextWriter` is provided) it is very easy to use this to output, say, directly to an HTTP output stream.

## Design philosophy:
* expressions are simple (but powerful), so we stop at assignment, in fact `=` is an alias for `==`
* expression syntax follows C# but extends this, e.g. it adds a Perl like regex match `=~`, "overloads" `&&` with `and` (as this is much nicer to use from xml) and more
* if anything more complex is required, add a method to the context class (aka the model)
* expressions are type safe
* errors are descriptive, helpful and provide accurate source location information
* the focus is runtime performance not compile performance

## Supported expression and template syntax
Some of the following is supported (list not exhaustive):
* arithmetic
* boolean operators
* + as string concatenation
* `?` and `??` and `if else`
* regex support `=~` and `!~` and `/regex/`
* method calls (no fancy overload resolution, however, at the moment)
* indexers (currently restricted to single argument indexers)

In template expressions the *namespaces* `$x` where `x` is a digit can be used to move up the "scope chain". Here `$0 == this`, `$1` is the parent scope etc. Note that whenever any name `foo` is resolved the context/scope chain is always walked from current to top level until a binding is found. If that is not possible an error is thrown.

## Supported Directives

### `$$#if$$`
The if directive can be used for conditional output. If the given expression evaluates to true its contents are output. Otherwise if there is an elif statement or an else statement these are executed and otherwise nothing is output.

Syntax is

```
$$#if <expr>$$
   ...
$$#elif <expr>$$
   ...
$$#else$$
   ...
$$/if$$
```
{'fraction_non_alphanumeric': 0.12773840206185566, 'fraction_numerical': 0.0019329896907216496, 'mean_word_length': 4.568609865470852, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '391187', 'n_tokens_mistral': 1700, 'n_tokens_neox': 1629, 'n_words': 854}