Package: jinjang
ThePythonmodulejinjaNGI 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.AboutjinjaNGThis small project tries to ameliorate the workflow when working with the template engineJinja.Structured specifications for tags to be used in a template.Filler data inJSON,YAML, orPythonfiles.Work with either files or strings.Use of pre and post-processing.Working with filesOur goalSuppose we want to type the followingLaTeXcode. This corresponds to a file with extensionTEX.\documentclass{article}\begin{document}One example.\begin{enumerate}\itemValue nb. 1: "one".\itemValue nb. 2: "two".\itemValue nb. 3: "three".\itemValue nb. 4: "four".\itemValue 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 wherejinjaNGcan help us.What we really typeThe first thing we can do is to define the repetitive content. Let's use aYAMLfile (aJSONfile can be used, but it's less fun to type). If we need to go further into the numbers in theLaTeXfile, we just have to add new names to the list in theYAMLfile.txt_exa:examplevalues:-one-two-three-four-fiveNext, let's type a minimalistLaTeXcode using special instructions and tags. Explanations are given below.\documentclass{article}%: if False\usepackage{jnglatex}%: endif\begin{document}One\JNGVALOF{txt_exa}.\begin{enumerate}%: for oneval in values\itemValue nb.\JNGVALOF{loop.index}: "\JNGVALOF{oneval}".%: endfor\end{enumerate}\end{document}This is how the previous template was typed.Let's start with the content after the\begin{document}. With\JNGVALOF{txt_exa}, we indicate to use the value associated with thetxt_exavariable in theYAMLdata file. In our case,\JNGVALOF{txt_exa}corresponds toexample.At the begining of the template, the lines between%: if Falseand%: endifwill not be in the final output. Here we use%: some Jinja instructionswith an always-false condition which causes the block to be ignored when making the final file. This allows thejnglatexpackage to be used only in the template file, but not in the final output. This package allowsjinjaNGvariables to be clearly highlighted after theLaTeXtemplate is compiled: this small feature greatly simplifies template design.For now, thejngutils.styfile must be in the same folder as theLaTeXtemplate, or it must be installed by hand in yourLaTeXdistribution: you will find it in thejngutilsfolder.Building the output via aPythoncodeUsing aPythonfile, it is easy to produce the desired output. Here are the instructions to use where we assume that thecdcommand has been used beforehand, so that running thePythonscripts is done from the folder containing ourPython,YAMLandLaTeXfiles.fromjinjangimport*mybuilder=JNGBuilder()mybuilder.render(data="data.yaml",template="template.tex",output="output.tex")This code uses one useful default behaviour:jinjaNGassociates automatically theLaTeXdialect, or flavour because the template has the extensionTEX. The flavours available are given in the last section of this document.Building the output via command linesThe commands below have the same effect as thePythoncode in the previous section.> cd path/to/the/good/folder
> jinjang data.yaml template.tex output.tex
File successfully built:
  + output.texBuilding the data via aPythonscriptIn our case, by knowing the existence ofcvnum, for example, we can be more efficient in constructing the data. Here is one possibledata.pyfile whereJNGDATAis a reserved name for the data thatjinjaNGwill use. We'll see next that producing the final output can no longer be done using the default behaviour of an instance of theJNGBuilderclass.fromcvnum.textifyimport*nameof=IntName().nameofJNGDATA={'txt_exa':"example",'values':[nameof(x)forxinrange(1,6)]}ThePythoncode producing the final output becomes the following one, wherepydata = Trueallows the classJNGBuilderto execute thePythonfile.This choice can be dangerous with untrustedPythonscripts!fromjinjangimport*mybuilder=JNGBuilder(pydata=True)mybuilder.render(data="data.py",template="template.tex",output="output.tex")To work with aPythondata file from the terminal, you must use the tag--unsafebecauseit can be dangerous to launch aPythondata file, sojinjaNGmust know that you really want to do this. The commands below have the same effect as thePythoncode above.> cd path/to/the/good/folder
> jinjang --unsafe data.py template.tex output.tex
WARNING: Using a Python file can be dangerous.
File successfully built:
  + output.texScripts likedata.pycan do relative imports.Hooks: doing pre and post-processingWhat we need?In the previous section, we saw how to produce aLaTeXfile by feeding a template. It would be handy to be able to compile the resulting file inPDFformat to make it readable by anyone. To do this easily,jinjaNGoffers the possibility to work with pre and post-processing, or "hooks".How to do this?We need to work with aYAMLconfiguration file. For simplicity, we use the default settings by working in a directory that looks like this.+ myfolder
    * cfg.jng.yaml
    * data.json
    * template.texWriting external commands is done in thecfg.jng.yamlfile. Here, we just use thepostblock for post-processing, but we could also use apreblock for pre-processing. Note the use of{output}which will be replaced by the path of the file built byjinjaNG.hooks:post:-latexmk -interaction=nonstopmode -pdf "{output}"-latexmk -interaction=nonstopmode -c   "{output}"One important thing to know is that the commands must be written relative to the parent folder of the template.Once thecfg.jng.yamlfile has been built, it is sufficient to do the following on the command line (we have omitted the output). Theautovalue of the--configoption indicates that the configurations are in thecfg.jng.yamlfile.> cd path/to/the/myfolder
> jinjang --config auto data.json template.tex output.tex
[...]The contents ofmyfolderhave been changed as follows.+ myfolder
    * cfg.jng.yaml
    * data.json
    * output.pdf
    * output.tex
    * template.texIf there are multiple templates in a folder, or to use test configurations, it is useful to be able to choose the configuration file explicitly.
In this type of situation, it is sufficient to proceed viajinjang --config path/to/speconfig.yaml ...for example.Working withPythonvariablesTo work directly fromPythonwithout 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.fromjinjangimport*mydata={'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(data=mydata,template=mytemplate)The content of the stringoutputwill be the following one.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 flavoursTo indicate a dialect for templates, a flavour must be given. Here are the minimalist technical descriptions of each of these flavours.FlavourasciiShort description:generic behaviour ofjinjaNG.Extensions for the auto-detection.Any extension not associated with another flavour is associated with that flavour (which is like a default one).Tools to assist in typing templates.Nothing available.Variables,jinjainstructions and comments.Here is a fictivehow-tocode.In our templates, we use {{variable}} .

It is always possible to work with block jinja instructions,
and comments.##_ Comments: one basic loop. _####: for i in range(5) :##We can use {{i + 4}} .##: endfor :##Most of flavours propose inline jinja instructions,
and comments.#_ Comments: the same loop as above.#: for i in range(5)We can use {{i + 4}} .#: endforFlavourhtmlShort description:useful settings and tools for HTML templating.Extension for the auto-detection.HTMLTools to assist in typing templates.See the folderjngutils/html.Variables,jinjainstructions and comments.Here is a fictivehow-tocode.In our templates, we use {{variable}} .

It is always possible to work with block jinja instructions,
and comments.

<!--_ Comments: one basic loop. _-->

<!--: for i in range(5) :-->
We can use {{i + 4}} .
<!--: endfor :-->

This flavour doesn't propose neither inline jinja instructions,
nor inline comments.FlavourlatexShort description:useful settings and tools for LaTeX templating.Extensions for the auto-detection.STYTEXTKZTools to assist in typing templates.See the folderjngutils/latex.Variables,jinjainstructions and comments.Here is a fictivehow-tocode.In our templates, we use\JNGVALOF{variable}.

It is always possible to work with block jinja instructions,
and comments.%%_ Comments: one basic loop. _%%%%: for i in range(5) :%%We can use\JNGVALOF{i + 4}.%%: endfor :%%Most of flavours propose inline jinja instructions,
and comments.%_ Comments: the same loop as above.%: for i in range(5)We can use\JNGVALOF{i + 4}.%: endforFlavourmdShort description:useful settings for Markdown templating.Extension for the auto-detection.MDTools to assist in typing templates.Nothing available.Variables,jinjainstructions and comments.Here is a fictivehow-tocode.In our templates, we use {{variable}} .

It is always possible to work with block jinja instructions,
and comments.

<!--_ Comments: one basic loop. _-->

<!--: for i in range(5) :-->
We can use {{i + 4}} .
<!--: endfor :-->

This flavour doesn't propose neither inline jinja instructions,
nor inline comments.