无论我使用 lualatex 还是 pdflatex 都没关系。MWE:
\documentclass{article}
\begin{document}
\textit{Hello\par World.}
\end{document}
正如预期的那样,上面提供了一条错误消息Runaway argument
,内容为:Paragraph ended before \text@command was complete
。这是因为\textit
不能包含段落分隔符。我知道{\itshape ... }
可以包含段落分隔符,但这不是我的问题。
现在,有人可能会问,“\text@command
你在说什么?我没有输入任何内容”。但当然,原因是其中有的定义\text@command
。\textit
\text@command
我进入 texmf-dist 并 grep 查找“ended before”。没有用。我还尝试了“ended~before”。没有用。因此,错误消息一定源自二进制文件中的某个地方(不在我的 texmf-dist 目录中)。
但是,如果我搜索代码\textit
和它调用的各种其他宏(以及它们调用的宏等等),我找不到任何明确要求错误的东西。
我的问题是:TeX 究竟如何知道它应该在那里抛出错误?更具体地说,如何使用我自己的宏代码重新定义该错误消息?
我为什么问这个问题:如果可能的话,我喜欢在处理用户输入之前对其进行预筛选。例如,\setlength
我有一个宏,而不是用户级的宏,例如,\somesize
它存储参数,检查(作为字符串)是否可以解释为长度值,检查其界限,如果成功则设置长度。如果不成功,它会收到我发送的错误消息,具体情况具体分析,并且长度保持不变(不为零)。所以我想预先筛选\textit
。目前,我重新定义\textit
以便它可以接受\par
,但这是蛮力。
答案1
tex 的 web(pascal)源位于 texlive 源中,但默认不分发。
该消息来自tex.web
@<Report a runaway argument and abort@>=
begin if long_state=call then
begin runaway; print_err("Paragraph ended before ");
@.Paragraph ended before...@>
sprint_cs(warning_index); print(" was complete");
help3("I suspect you've forgotten a `}', causing me to apply this")@/
("control sequence to too much text. How can we recover?")@/
("My plan is to forget the whole thing and hope for the best.");
back_error;
end;
https://github.com/TeX-Live/texlive-source/blob/trunk/texk/web2c/tex.web#L8085
它不能通过 TeX 宏(或其他任何东西)进行自定义。文本在编译后的程序中,因此只能通过使用更改文件更改源来更改(这意味着您将无法通过旅行测试并且无法将生成的程序称为“TeX”)。
如果你使用 lualatex 你可以设置
\suppresslongerror = 1
任何非零值都会导致不检查此错误情况,因此宏仍然存在\long
或不存在\long
,但\par
在参数中永远不会引发显示的错误。