是否可以重载Jinja2的autoescape
,以便以用户指定的方式(即除了LaTeX等HTML之外的其他东西)转义某些内容?
以下是试图逃离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',
})
运行上述内容时,输出:
\documentclass[memoir]
\begin{document}
{bob} <-- is escaped
\end{document}
这里的问题是使用HTML转义。因此,{
和}
应该被转义,但它们不会被转义,并且<
会转换为<
,但它不应该转义。
我想重载Jinja2用来转义变量的转义函数。
我的第一个想法是重载finalize
并禁用autoescape
。 e.g。
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',
})
输出不正确,因为主要文本没有成为Markup
(即标记为安全的字符串):
documentclass[memoir]
begin\{document\}
\{bob\} <-- is escaped
end\{document\}
如果我将autoescape
设置为True,并在最终确定几乎工作(并且在此示例中,它确实有效):
\documentclass[memoir]
\begin{document}
\{bob\} <-- is escaped
\end{document}
启用autoescape
有效,因为它使模板的主体文本为Markup
(即安全)。
但是,问题出在哪里,如果我将输入更改为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'],
})
当我跑步时,我得到:
\documentclass[memoir]
\begin{document}
A&B > a & b > C<D
\end{document}
似乎HTML autoescape
正在“内容”的元素上运行,而不是finalize
。最简单的解决方案,如果Jinja2及其自动绑定松散耦合,似乎会使autoescape函数超载。我似乎无法弄清楚这一点,我提出的最好的是finalize
函数。
有没有比重载TeX
函数更好的方法来处理finalize
的转义?可以重载autoescape
吗?
例如,可以安装自定义标记包吗? (我宁愿避免选择)
感谢您的阅读。