Skip to content

Commit

Permalink
output.RenderLaTeX no longer accepts filters, but an Environment. out…
Browse files Browse the repository at this point in the history
…put.jinja_syntax_latex made public (to be used during custom environment initialisation). Adds an example of a user-defined environment.
  • Loading branch information
ynikitenko committed Sep 9, 2023
1 parent fbf40a6 commit 39e7323
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 30 deletions.
3 changes: 2 additions & 1 deletion lena/output/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ def stub(*args, **kwargs):
# (in classes' parents)
try:
# will raise if jinja2 is not installed
from lena.output.render_latex import RenderLaTeX #, Template, Environment
from lena.output.render_latex import RenderLaTeX, jinja_syntax_latex
#, Template, Environment
except ImportError:
RenderLaTeX = raise_on_usage("RenderLaTeX", "jinja2")

Expand Down
85 changes: 59 additions & 26 deletions lena/output/render_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
from lena.context import get_recursively as _get_recursively


_ljinja_env = {
"block_start_string": r'\BLOCK{',
"block_end_string": '}',
"variable_start_string": r'\VAR{',
"variable_end_string": '}',
"comment_start_string": r'\#{',
"comment_end_string": '}',
"line_statement_prefix": '%-',
"line_comment_prefix": '%#',
"trim_blocks": True,
"lstrip_blocks": True,
"autoescape": False,
jinja_syntax_latex = {
"block_start_string": r'\BLOCK{',
"block_end_string": '}',
"variable_start_string": r'\VAR{',
"variable_end_string": '}',
"comment_start_string": r'\#{',
"comment_end_string": '}',
"line_statement_prefix": '%-',
"line_comment_prefix": '%#',
"trim_blocks": True,
"lstrip_blocks": True,
"autoescape": False,
}


Expand All @@ -38,7 +38,9 @@ class _Template(jinja2.Template):
def __new__(cls, *args, **jkws):
# Jinja Template uses not __init__(), but __new__().
kws = jkws.copy()
kws.update(_ljinja_env)
# todo: maybe remove this class,
# or update jinja env with kwargs here (see _Environment)
kws.update(jinja_syntax_latex)
# how to efficiently merge two dicts: https://stackoverflow.com/a/26853961/952234
# print kws
sucls = super(_Template, cls)
Expand All @@ -49,8 +51,10 @@ class _Environment(jinja2.Environment):
"""Jinja environment."""

def __init__(self, *args, **jkws):
kws = jkws.copy()
kws.update(_ljinja_env)
# kws = jkws.copy()
# kws.update(_ljinja_env)
kws = jinja_syntax_latex.copy()
kws.update(jkws)
super(_Environment, self).__init__(*args, **kws)
# Python 3
# super().__init__(*args, **kws)
Expand Down Expand Up @@ -81,7 +85,7 @@ class RenderLaTeX(object):
"""Create LaTeX from templates and data."""

def __init__(self, select_template="", template_dir=".", select_data=None,
filters={}, verbose=0):
environment=None, verbose=0):
"""*select_template* is a string or a callable.
If a string, it is the name of the template to be used
(unless *context.output.template* overwrites that).
Expand All @@ -99,10 +103,34 @@ def __init__(self, select_template="", template_dir=".", select_data=None,
It should accept a value from flow and return boolean.
By default CSV files are selected (see :meth:`run`).
*filters* allow adding user-defined filters.
See jinja
`custom filters <https://jinja.palletsprojects.com/en/latest/api/#writing-filters>`_
for more details.
*environment* allows user-defined initialisation of
jinja Environment. One can use that to add custom
`filters <https://jinja.palletsprojects.com/en/latest/api/#writing-filters>`_,
tests, global functions, etc.
In that case one must set *template_dir*
for that environment manually. Example user initialisation:
.. code-block:: python
import jinja2
from lena.output import RenderLaTeX, jinja_syntax_latex
# import user settings, filters and globals
def render_latex():
\"\"\"Construct RenderLaTeX to be used in analysis sequences.\"\"\"
loader = jinja2.FileSystemLoader(TEMPLATE_PATH)
environment = jinja2.Environment(
loader=loader,
**jinja_syntax_latex
)
environment.filters.update(FILTERS)
environment.globals.update(GLOBALS)
return RenderLaTeX(
select_template=select_template,
environment=environment
)
*verbose* controls the verbosity of output.
If it is 1, selected values are printed during :meth:`run`.
Expand Down Expand Up @@ -130,13 +158,18 @@ def __init__(self, select_template="", template_dir=".", select_data=None,
"select_template must be a string or a callable, "
"{} provided".format(select_template)
)
self._loader = jinja2.FileSystemLoader(template_dir)
self._environment = _Environment(loader=self._loader)
if filters:
# since we don't modify filters, a mutable kwarg is fine
self._environment.filters.update(filters)
if environment is None:
loader = jinja2.FileSystemLoader(template_dir)
self._environment = _Environment(loader=loader)
else:
if template_dir != '.':
raise lena.core.LenaValueError(
"only one of template_dir or environment "
"must be provided, not both"
)
self._environment = environment

self._verbose = verbose
# print("templates:", self._environment.list_templates())

def run(self, flow):
"""Render values from *flow* to LaTeX.
Expand Down
18 changes: 15 additions & 3 deletions tests/output/test_render_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

import lena
from lena.output.render_latex import (
RenderLaTeX, _Template, _Environment, _select_template_or_default
RenderLaTeX, jinja_syntax_latex,
_Template, _Environment, _select_template_or_default,
)
from lena.context import get_recursively, update_recursively

Expand Down Expand Up @@ -107,11 +108,22 @@ def test_render_latex():
# not selected data passes unchanged
assert list(renderer.run([("output.csv", {})])) == [("output.csv", {})]

# filters work

def test_custom_environment():
# custom environment works in RenderLaTeX
def fancy(s):
return "fancy({})".format(s)
filters = {"fancy": fancy}
renderf = RenderLaTeX("with_filter.tex", template_dir, filters=filters,

loader = jinja2.FileSystemLoader(template_dir)
environment = jinja2.Environment(
loader=loader,
**jinja_syntax_latex
)
environment.filters.update(filters)

renderf = RenderLaTeX("with_filter.tex",
environment=environment,
select_data=lambda _: True)
data = [(0, {"val": "value"})]
results = list(renderf.run(data))
Expand Down

0 comments on commit 39e7323

Please sign in to comment.