我现在对 LaTeX 了解不多,但我需要能够使用它通过 C# 生成动态 PDF 文档。
在大多数情况下,一切都很酷并且按照我希望的方式运作。
有人给我一个静态的 LaTeX 文档作为基础模板,我使用 C# 写入来自 Web 服务器和数据库的所有动态数据。
例如,这是我从 LaTeX 开发人员那里得到的信息:
\documentclass[letter,landscape]{report}
\newcommand{\ReportTitle} {Summary Report }
\newcommand{\ReportAuthor}{Mister San }
\pdfinfo{
/Title (\ReportTitle)
/Author (\ReportAuthor)
/Subject (Generated by \ReportAuthor on \today)
}
\begin{document}
\ReportTitle \\
By: \ReportAuthor \\
\end{document}
然后,我将获取该 LaTeX 代码(标记?)并使用 C# / ASP.NET MVC 使其动态化(我使用的技术对于这个问题来说并不重要)。完成后,它最终将看起来像这样:
\documentclass[letter,landscape]{report}
\newcommand{\ReportTitle} {@Model.ReportTitle }
\newcommand{\ReportAuthor}{@Model.ReportAuthor }
\pdfinfo{
/Title (\ReportTitle)
/Author (\ReportAuthor)
/Subject (Generated by \ReportAuthor on \today)
}
\begin{document}
\ReportTitle \\
By: \ReportAuthor \\
\end{document}
现在,\ReportTitle 和 \ReportAuthor 是动态的,并且基于数据库中的内容。这通常按原样工作,但我遇到了一个特定问题,我不知道该怎么做才能解决它。
\ReportTitle 和 \ReportAuthor 字段中的文本来自用户输入的内容,他们可以使用任何他们想要的字符。如果用户输入了类似“~My_$uper_Report~”的 \ReportTitle - LaTeX 标记将变得无效,因为选择了保留字符。
我知道您可以转义保留字符,因此“Standard_Report”的 \ReportTitle 将变成:
\newcommand{\ReportTitle} {Standard\_Report }
我用 C# 编写了一个方法,将所有特殊的 LaTeX 字符替换为它们的转义字符。
这有时会有效(这很奇怪,通常事情要么有效,要么无效)。
好像我有太多这样的转义字符:
\newcommand{\ReportTitle} {\# \$ \% \& \~ \_ \^ \{ \} \backslash}
我收到内存不足错误。
我不知道为什么我无法在 \newcommand 中存储以空格分隔的转义特殊字符列表。
有人知道为什么我无法使前面的示例正常工作吗? 有没有更好的方法可以做到这一点?
是否存在现有的工具可以对用户输入进行编码,这样您不必自己逃避一切并检查 LaTeX 注入攻击?
顺便说一下,这是我收到的错误:
./main.tex:7: TeX capacity exceeded, sorry [input stack size=5000].
\@inmathwarn ...latex@warning {Command \protect #1
invalid in math mode}\fi l.7 /Title (\ReportTitle)
****编辑:**** 一位用户发表了一条评论(但随后删除了)建议使用如下内容:
\detokenize\expandafter{\ReportTitle}
这实际上允许报告编译并显示保留字符,但不幸的是,它还在每个转义字符周围添加了双引号字符,这是不可接受的。不过还是谢谢你。我相信我最终会弄清楚的,或者这里的另一个用户会知道该怎么做。
答案1
\# \$ \% \& \~ \_ \^ \{ \}
是非常不同的命令类型,\%
会产生百分比但\^
不会产生百分比,^
它是一个接受\^{a}
构造重音字母的参数的命令。
您可以使用
\detokenize{@Model.ReportTitle}
那么您基本上只需要引用\(
\}
并\%
确保构造具有平衡的括号。并添加
\usepackage[T1]{fontenc}
这样您就会获得稍微更正常的字体编码,其中的 ascii 字符可以像它们自己一样打印。
如果你永远不会在文档中插入注释,你可以%
全局创建一个普通字符,这样你就不需要\%
只添加
\catcode`\%=12
到序言部分(在任何包加载之后,否则包中的注释将会被破坏)