如何在Django模板中转义LaTeX特殊字符?

18

我有这个Django模板,用于生成LaTeX文件。

\documentclass[11pt]{report}

\begin{document}
\begin{table}
    \centering
    \begin{tabular}{lcr}
    \hline
    {% for col in head %}
        \textbf{ {{col}} }
        {% if not forloop.last %}
           &
        {% endif %}
    {% endfor %} 
    \\
    \hline
    {% for row in table %}
        {% for cell in row %}

            {% if not forloop.last %} 
               &
            {% endif %}
        {% endfor %}
        \\
    {% endfor %}
    \hline
    \end{tabular}
    \caption{Simple Phonebook}
    \label{tab:phonebook}
\end{table}

\end{document}

但是我的列数非常多,所以它们可以包含任何特殊字符。在生成PDF文件时出现错误。

我该如何转义所有列中的文本?

2个回答

30

Alex的回答包括代码建议,如果你想复制粘贴:

import re

def tex_escape(text):
    """
        :param text: a plain text message
        :return: the message escaped to appear correctly in LaTeX
    """
    conv = {
        '&': r'\&',
        '%': r'\%',
        '$': r'\$',
        '#': r'\#',
        '_': r'\_',
        '{': r'\{',
        '}': r'\}',
        '~': r'\textasciitilde{}',
        '^': r'\^{}',
        '\\': r'\textbackslash{}',
        '<': r'\textless{}',
        '>': r'\textgreater{}',
    }
    regex = re.compile('|'.join(re.escape(str(key)) for key in sorted(conv.keys(), key = lambda item: - len(item))))
    return regex.sub(lambda match: conv[match.group()], text)

请参考Easiest way to replace a string using a dictionary of replacements?中提供的替换方法。


1
谢谢您的代码!我认为在\textless\textgreater之后应该还有一个空格。因为<a变成了\textlessa,所以我得到了“未定义的控制序列”的错误提示。 - minhle_r7
使用 r'\textless ' 而不是 r'\textless{}' 有什么原因吗? - Tyilo
如果你认为更好的话,我会改变它。 - Mark
2
请注意:在Python 3中,'unicode'函数已被弃用,请使用'str'函数代替。 - Andrew Magerman
我认为没有必要按键对conv进行排序,因为所有的键都是相同长度的。 - Mitar

5

应该如此:

CHARS = {
    '&':  r'\&',
    '%':  r'\%', 
    '$':  r'\$', 
    '#':  r'\#', 
    '_':  r'\letterunderscore{}', 
    '{':  r'\letteropenbrace{}', 
    '}':  r'\letterclosebrace{}',
    '~':  r'\lettertilde{}', 
    '^':  r'\letterhat{}', 
    '\\': r'\letterbackslash{}',
}

print("".join([CHARS.get(char, char) for char in "&%$#_{}~^\\"]))

创建自己的模板过滤器来过滤您的变量

[编辑]:

这是 ConText 的特殊字符,对于 LaTex,请进行适当调整:

\& \% \$ \# \_ \{ \} \textasciitilde{} \^{} \textbackslash{}

1
不要忘记同时包含 r'\textgreater' 和 r'\textless'。 - blueberryfields
或者 r'\ensuremath{<}' 和 r'\ensuremath{>}' - sastanin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接