宏是否会在编译之前应用于源代码?

宏是否会在编译之前应用于源代码?

我不知道这是不是真的。

  1. Latex 编译器首先运行该文档,并搜索所有的宏声明。

  2. 然后编译器浏览文档,将每个宏应用为字符串替换。

  3. 编译器编译应用了所有宏的文档。

如果这是真的,那么有没有办法得到第二步的输出?

答案1

(La)TeX 编译器只需运行一次即可。(不要将其与多次编译器运行混淆,多次编译器运行可能需要处理文档开头需要但稍后才定义的材料,例如目录中的条目。)

大多数控制序列(事物\name)都是宏,并且包含更多宏。一旦 TeX 看到它们,它们就会简单地扩展为替换文本。然后,替换文本或多或少地被处理为输入文件的一部分,并且包含的​​宏再次被扩展。只要发现不可扩展的东西,例如某些字符或 TeX原始(例如作业\def)必须执行由编译器执行。执行后,编译器继续扩展输入的其余部分,直到再次达到不可扩展的标记。当页面填满并发送出去等时,还会执行其他一些步骤。需要注意的是,所有步骤都在一次传递中发生,即文档的第一部分在文档末尾被读取之前就已经被扩展、执行、排版并刷新到输出文件中。

一本免费的在线书籍提供了更好的解释,其中还描述了 TeX 的“器官”,其中完成了不同的处理步骤“没有耐心的人可以尝试 TEX”,第 16 页:

TEX 的工作原理

为了有效地使用 TEX,了解 TEX 如何将输入转化为输出会有所帮助。你可以将 TEX 想象成一种有“眼睛”、“嘴巴”、“食道”、“胃”和“肠子”的有机体。有机体的每个部分都以某种方式转换其输入,并将转换后的输入传递到下一阶段。眼睛将输入文件转换为字符序列。嘴巴将字符序列转换为标记序列,其中每个标记要么是单个字符,要么是控制序列。食道将标记扩展为原始命令,它们也是标记。胃执行原始命令指定的操作,产生一系列页面。最后,肠将每页转换为 .dvi 文件所需的格式并将其发送到那里。这些操作在第 4 节“TEX 解剖”下有更详细的描述(第 46 页)。

答案2

不,它不是这样工作的。只有一次传递,并且执行宏扩展,直到剩下不可扩展的标记。宏可以是递归的(许多宏确实是递归的),但对于“普通”宏,通常有多个替换(更好的是扩展)。此外,宏甚至可以重新定义其他宏作为其工作的一部分,甚至是它们自己。

答案3

正如 egreg、Martin 和 Bruno 所说,答案是否定的。

有多种方法可以显示宏在 TeX 中如何扩展。

在(普通)TeX 中,你可以设置\tracingcommands\tracingmacros\tracingoutput等来跟踪 TeX 的工作方式。请参阅第 34 章TeX 按主题分类更多解释。例如:

\tracingmacros=1
\tracingcommands=1
\def\foo{foo}
\def\bar{(\foo)}

\bar

\bye

您将在文件中获得以下信息.log

{垂直模式:\def}
{空格处 }
{\def}
{空格处 }
{\par}

\bar ->(\foo )
{人物 (}
{水平模式:字符(}

\foo ->foo
{\par}

\bye ->\par \vfill \supereject \end
{垂直模式:\par}
{\vfill}
......

在 LaTeX 中,你还可以使用trace包。例如:

\documentclass{article}
\usepackage{trace}
\begin{document}
\traceon
\def\foo{foo}
\def\bar{(\foo)}

\bar
\traceoff
\end{document}

您将获得以下输出:

{进入 \tracingonline=1}
{\def}
{更改 \foo=undefined}
{进入 \foo=macro:->foo}
{空格处 }
{\def}
{更改 \bar=macro:->\mathaccent "7016\relax }
{进入 \bar=macro:->(\foo )}
{空格处 }
{\par}

\bar ->(\foo )
{人物 (}
{水平模式:字符(}

\foo ->foo

答案4

这是与其他人给出的相同答案,但是从不同的角度。

作为 LaTeX 的新用户,很自然地会认为 TeX 是一种标记语言,主要由实际文本组成,偶尔会包含格式指令(\textbf、数学模式$...$等)和表示应缩写的长文本的宏。事实上,LaTeX 不遗余力地向用户呈现这种外观。

事实并非如此。诸如这样的指令\mymacro可能被定义为完全转换其后出现的文本,甚至改变 TeX 读取其输入的方式。最好将您编写的所有内容想象为告诉 TeX 如何排版的命令:字母告诉 TeX 排版自身,但宏(以及其他更可怕的东西)可以告诉它排版其他内容,也可以告诉它以完全不同的方式排版内容。

从这个角度来看,TeX 不可能对其输入进行简单的“替换运行”:宏可能意味着比简单的文本替换更为严重的事情,并且在它们被扩展之前无法分辨为了。此外,这种扩展的结果可能是排版命令,例如,\hbox这并不意味着扩展为纯文本,并且永远无法消除。作为一个例子,下面是该命令的含义\TeX

T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX

它是一个“宏”,但它不只是说“写下字母 TeX”,而是描述了它们必须写得有多近(\kern)以及在什么高度(\lower),以便TeX 徽标。这在纯文本文件中没有任何意义。

您可能对以下问题感兴趣能否使 LaTeX 产生文本输出?,尽管我担心答案并不令人鼓舞。

实际上,您的问题的答案是 TeX 文件的“完整扩展”是一个完成的文档,因为这是能够满足输入中表达的要求的最小格式。如果您知道文档仅包含纯文本(没有图片或符号),那么pdftotext可能会为您提供与您想要的合理的近似值。

相关内容