The `Python` module `jinjaNG`
=============================

> **I beg your pardon for my english...**
>
> English is not my native language, so be nice if you notice misunderstandings, misspellings, or grammatical errors in my documents and codes.


About `jinjaNG`
---------------

This small project tries to ameliorate the workflow when working with the template engine [Jinja](https://palletsprojects.com/p/jinja/).

  1. Structured specifications for tags to be used in a template.

  1. Filler data in `JSON`, `YAML`, or `Python` files.

  1. Work with either files or strings.


Working with files
------------------

### Our goal

Suppose we want to type the following `LaTeX` code. This corresponds to a file with extension `TEX`.

~~~latex
\documentclass{article}

\begin{document}

One example.

\begin{enumerate}
    \item Value nb. 1: "one".
    \item Value nb. 2: "two".
    \item Value nb. 3: "three".
    \item Value nb. 4: "four".
    \item Value nb. 5: "five".
\end{enumerate}

\end{document}
~~~

As you can see, most of the content follows a repetitive logic. So it may be a good idea to automate the typing. Here is where `jinjaNG` can help us.


### What we really type

The first thing we can do is to define the repetitive content. Let's use a `YAML` file (a `JSON` file can be used, but it's less fun to type). If we need to go further into the numbers in the `LaTeX` file, we just have to add new names to the list in the `YAML` file.

~~~yaml
txt_exa: example
values :
  - one
  - two
  - three
  - four
  - five
~~~


Next, let's type a minimalist `LaTeX` code using special instructions and tags. Explanations are given below.

~~~latex
\documentclass{article}
%: if False
\usepackage{jnglatex}
%: endif

\begin{document}

One \JNGVAR{txt_exa}.

\begin{enumerate}
%: for oneval in values
    \item Value nb. \JNGVAR{loop.index}: "\JNGVAR{oneval}".
%: endfor
\end{enumerate}

\end{document}
~~~

This is how the previous template was typed.

  1. Let's start with the content after the `begin{document}`. With `JNGVAR{txt_exa}`, we indicate to use the value associated with the `txt_exa` variable in the `YAML` data file. In our case, `JNGVAR{txt_exa}` corresponds to `example`.

  1. At the begining of the template, the lines between `%: if False` and `%: endif` will not be in the final output. Here we use `%: some Jinja instructions` with an always-false condition which causes the block to be ignored when making the final file. This allows the `jnglatex` package to be used only in the template file, but not in the final output. This package allows `jinjaNG` variables to be clearly highlighted after the `LaTeX` template is compiled: this small feature greatly simplifies template design.


>  For now, the `jnglatex.sty` file must be in the same folder as the `LaTeX` template, or it must be installed by hand in your `LaTeX` distribution: you will find it in the `jng-extra-tools` folder.


### Building the output via a `Python` code

Using a `Python` file, it is easy to produce the desired output. Here are the instructions to use where we assume that the `cd` command has been used beforehand, so that running the `Python` scripts is done from the folder containing our `Python`, `YAML` and `LaTeX` files.

~~~python
from jinjang import *

mybuilder = JNGBuilder()

mybuilder.render(
    datas    = "datas.yaml",
    template = "template.tex",
    output   = "output.tex"
)
~~~

This code uses one useful default behaviour: `jinjaNG` associates automatically the `LaTeX` dialect, or flavour because the template has the extension `TEX`. The flavours available are given in the last section of this document.


### Building the output via command lines

The commands below have the same effect as the `Python` code in the previous section.

~~~
> cd path/to/the/good/folder
> python -m jinjang --dto datas.yaml template.tex output.tex
File successfully built:
  + output.tex
~~~



### Building the data via a `Python` script

In our case, by knowing the existence of [cvnum](https://pypi.org/project/cvnum/), for example, we can be more efficient in constructing the data. Here is one possible `datas.py` file where `JNG_DATAS` is a reserved name for the data that `jinjaNG` will use. We'll see next that producing the final output can no longer be done using the default behaviour of an instance of the `JNGBuilder` class.

~~~python
from cvnum.textify import *

nameof = IntName().nameof

JNG_DATAS = {
    'txt_exa': "example",
    'values' : [nameof(x) for x in range(1, 6)]
}
~~~


The `Python` code producing the final output becomes the following one, where `pydatas = True` allows the class `JNGBuilder` to execute the `Python` file. **This choice can be dangerous with untrusted `Python` scripts!**

~~~python
from jinjang import *

mybuilder = JNGBuilder(pydatas = True)

mybuilder.render(
    datas    = "datas.py",
    template = "template.tex",
    output   = "output.tex"
)
~~~


To work with a `Python`data file from the terminal, you must use the tag `--pydto` instead of `--dto`. This is because **it can be dangerous to launch a `Python` data file**, so `jinjaNG` must know that you really want to do this. The commands below have the same effect as the `Python` code above.

~~~
> cd path/to/the/good/folder
> python -m jinjang --pydto datas.py template.tex output.tex
WARNING: Using a Python file can be dangerous.
File successfully built:
  + output.tex
~~~


Working with `Python` variables
-------------------------------

To work directly from `Python` without using any file, you need to produce a dictionary for the data, and a string for the template, so as to get a string for the final output. Let's take an example where the dialect, or flavour, must be specified always.

~~~python
from jinjang import *

mydatas = {
    'txt_exa': "small example",
    'max_i'  : 4
}

mytemplate = """
One {{ txt_exa }} with automatic calculations.
{#: for i in range(1, max_i + 1) :#}
  {{ i }}) I count using squares: {{ i**2 }}.
{#: endfor :#}
""".strip()

mybuilder = JNGBuilder(flavour = FLAVOUR_ASCII)

output = mybuilder.render_frompy(
    datas    = mydatas,
    template = mytemplate
)
~~~


The content of the string `output` will be the following one.

~~~markdown
One small example with automatic calculations.

  1) I count using squares: 1.

  2) I count using squares: 4.

  3) I count using squares: 9.

  4) I count using squares: 16.

~~~


All the flavours
----------------

A flavour indicates a dialect for a templates. Here are the minimalist technical descriptions of each of these flavours.


<!-- FLAVOURS - TECH. DESC. - START -->

---

#### Flavour `ascii`

> **Short description:** generic behaviour of `jinjaNG`.

  1. **Extensions for the auto-detection, and possible tools for the templates.**

      * Any extension not associated to any other flavour is associated to this flavour which is like a default one.

      * No tools are available to assist in typing templates.

  1. **Variables** are typed `{{ one_jinja_var }}`.

  1. **Using `jinja` instructions.**

      * Inline instructions are typed `#: ...` where `...` symbolizes some `Jinja` instructions.

      * Block instructions are typed `{#: ... :#}` where `...` symbolizes some `Jinja` instructions, on several lines if needed.

  1. **Writing comments.**

      * Inline comments are typed `#_ ...` where `...` symbolizes comments only for the template.

      * Block comments are typed `{#_ ... _#}` where `...` symbolizes comments only for the template, on several lines if needed.

---

#### Flavour `html`

> **Short description:** useful settings and tools for HTML templating.

  1. **Extensions for the auto-detection, and possible tools for the templates.**

      * Files having extensions `HTML` are associated to this flavour.

      * Tools to assist in typing templates are available: see the folder `jng-extra-tools/html`.

  1. **Variables** are typed `{{ one_jinja_var }}`.

  1. **Using `jinja` instructions.**

      * No inline instructions are available.

      * Block instructions are typed `<!--: ... :-->` where `...` symbolizes some `Jinja` instructions, on several lines if needed.

  1. **Writing comments.**

      * No inline comments are available.

      * Block comments are typed `<!--_ ... _-->` where `...` symbolizes comments only for the template, on several lines if needed.

---

#### Flavour `latex`

> **Short description:** useful settings and tools for LaTeX templating.

  1. **Extensions for the auto-detection, and possible tools for the templates.**

      * Files having extensions `TEX`, `STY`, or `TKZ` are associated to this flavour.

      * Tools to assist in typing templates are available: see the folder `jng-extra-tools/latex`.

  1. **Variables** are typed `\JNGVAR{ one_jinja_var }`.

  1. **Using `jinja` instructions.**

      * Inline instructions are typed `%: ...` where `...` symbolizes some `Jinja` instructions.

      * Block instructions are typed `%%: ... :%%` where `...` symbolizes some `Jinja` instructions, on several lines if needed.

  1. **Writing comments.**

      * Inline comments are typed `%_ ...` where `...` symbolizes comments only for the template.

      * Block comments are typed `%%_ ... _%%` where `...` symbolizes comments only for the template, on several lines if needed.

<!-- FLAVOURS - TECH. DESC. - END -->