Jinja2 autoescape overload for (La) TeX

Is it possible to overload Jinja2 autoescape so that it accelerates something in a user-defined way (for example, something like HTML, for example LaTeX)?

Here is an example trying to avoid TeX .

 import jinja2 class MyEnv(jinja2.Environment): def __init__(self, filters={}, globals={}, tests={}, loader=None, extensions=[], **kwargs): super(MyEnv, self).__init__( autoescape = True, ) template = MyEnv().from_string("""\documentclass[{{ class }}] \\begin{document} {{ content }} \end{document} """) print template.render({ 'class':'memoir', 'content': '{bob} <-- is escaped', }) 

When you run above, you get:

  \documentclass[memoir] \begin{document} {bob} &lt;-- is escaped \end{document} 

The problem is that HTML escaping is used. Therefore, { and } must be escaped, but it is not, and < converted to &lt; but it should not be.

I would like to overload the escape function that Jinja2 uses to remove variables.

My first thought is to overload finalize and disable autoescape . eg.

 import jinja2 class MyEnv(jinja2.Environment): def __init__(self, filters={}, globals={}, tests={}, loader=None, extensions=[], **kwargs): super(MyEnv, self).__init__( autoescape = False, # turn off autoescape finalize = self.finalize, ) def finalize(self, s): import re if isinstance(s, jinja2.Markup): return s s = s.replace('\\', '') s = s.replace('~', '\\textasciitilde') s = re.sub(r'([#|^|$|&|%|{|}])', r'\\\1', s) s = re.sub(r'_', r'\\_', s) return jinja2.Markup(s) template = MyEnv().from_string("""\documentclass[{{ class }}] \\begin{document} {{ content }} \end{document} """) print template.render({ 'class':'memoir', 'content': '{bob} <-- is escaped', }) 

The result is incorrect, because the main text is not enclosed in Markup (i.e. the line is marked as safe):

 documentclass[memoir] begin\{document\} \{bob\} <-- is escaped end\{document\} 

If I set autoescape to True and go into finalization, it almost works (and in this example it works):

 \documentclass[memoir] \begin{document} \{bob\} <-- is escaped \end{document} 

Rotating autoescape works because it makes the body of the text for the Markup template (i.e. safe).

However, here is where the problem is if I change the entry to the list that join ed:

 template = MyEnv().from_string("""\documentclass[{{ class }}] \\begin{document} {{ content|join(" > a & b > "|safe) }} \end{document} """) print template.render({ 'class':'memoir', 'content': ['A&B', 'C<D'], }) 

When I run this, I get:

 \documentclass[memoir] \begin{document} A&amp;B > a & b > C&lt;D \end{document} 

It would seem that HTML autoescape is executed for "content" elements, not finalize . The simplest solution, provided that Jinja2 and its auto-security are loosely coupled, would seem to overload the autoescape function. I can't figure it out, and the best I came up with is the finalize function.

Is there a better way to handle TeX escaping than overloading the finalize function? Can I reload autoescape ?

For example, is it possible to install a custom markup package? (a choice I'd rather avoid)

Thanks for reading.

+8
markup jinja2
source share

No one has answered this question yet.

See related questions:

257
Get list length in jinja2 template
164
How do I format a date in Jinja2?
97
Python jinja2 abbreviated conditional
94
In Jinja2, how do you check if a variable is undefined?
12
Unable to disable autoescape in jinja2
2
Getting translation strings for jinja2 templates integrated with django 1.x?
one
Jinja2 autostart extension not working
0
Disable autoescaping in jinja2 on Appengine
0
Is Autoescape the default in jinja2 (Flask)?
0
Jinja2 autoescape

All Articles