TeX 错误信息从何而来?

TeX 错误信息从何而来?

无论我使用 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在参数中永远不会引发显示的错误。

相关内容