如果我想要一个关于用户定义宏的限制的编译系统(AMS)LaTeX,我该怎么做?

如果我想要一个关于用户定义宏的限制的编译系统(AMS)LaTeX,我该怎么做?

因此,我希望有一个系统,其中某些用户文档完全由 TeX 引擎处理(完整 TeX 引擎!),并且某些数据被收集到某些辅助文件中(说“辅助”只是不会让你认为它是标准.aux文件),然后用于处理原始文档以生成标准 (AMS)LaTeX,该标准 (AMS)LaTeX 可以由无法处理宏的东西处理,例如 latex2html。如果我希望用户能够定义自己的宏,我该怎么办?我可以提供什么界面?对用户宏的哪些限制(即要遵循的规则)是合理的?

答案1

当处理乳胶源时,结构信息会转换成视觉呈现,这绝对不是您想要的(希望您能成功地将 pdf 转换为 html)。

因此,您必须在中间的某个地方停止该过程,此时它仍然是带有演示的 LaTeX 代码,但所有用户宏都在被扩展。

我认为通过展示如何做到这一点并展示该方法的局限性(只能有更少的限制)可以最好地回答你的问题:

\newcommand{\mysamplecommand}[1]{Look at this: \textit{#1}!}

\section{Sec}
Normal text, \textit{italic}, \emph{italic}.

\subsection{sub}
Math works too: $\sum_{x=0}^\infty 1+1$.

\subsubsection{subsub}
\mysamplecommand{It works}

进入

\begin{document}
\par
  \section{Sec}
  Normal text, \textit{italic}, \emph{italic}.
\par
  \subsection{sub}
  Math works too: $\sum _{x=0}^\infty 1+1$.
\par
  \subsubsection{subsub}
  Look at this: \textit{It works}!
\par 
\end{document}

(为了便于阅读,我手动插入了换行符)

这个想法是扩展 tex 标记并将其写入文件。

\usepackage{newfile}
\newoutputstream{markupfile}
\openoutputfile{\jobname.markup}{markupfile}
\addtostream{markupfile}{\fakebackslash begin{document}}
\edef\markuptowrite{   <thecontent>   }
\addtostream{markupfile}{\markuptowrite}
\addtostream{markupfile}{\fakebackslash end{document}}
\closeoutputstream{markupfile}

当然,<thecontent>必须用用户编写的内容替换(如上面的代码)。请注意\edef定义\markuptowrite扩展形式<thecontent>是,它执行所有可能的宏扩展。

现在,问题是大多数宏都会扩展为不相关的 TeX 基元(例如字距调整)并且包含无法显示的字符。

因此,我们需要一组未扩展的原语,如 \textit 或 \section,以便 latex2html 可以将它们转换为和。

\def\fakebackslash{(((fakebackslash)))}
\newcommand{\defmarkupprimitive}[1]{\expandafter\def\csname #1\endcsname{\fakebackslash #1}}
\defmarkupprimitive{textit}
\defmarkupprimitive{emph}

\makeatletter
\def\@startsection#1#2#3#4#5#6{\fakebackslash #1}
\makeatother

您必须为 latex2html(或类似程序)知道的每个宏定义一个原语,并且该原语不是 tex 原语。我猜这可以通过一种聪明的方式来完成,以减少原语的数量,就像我为\@startsectionsection、subsection 和 subsubsection 所做的那样。

我们使用不引入控制序列的\fakebackslashfor \。也许可以有更好的方法,但剩下的只是将 简单替换为(((fakebackslash)))\因此,第一个示例的实际输出是

(((fakebackslash)))begin{document}
 \par (((fakebackslash)))section{Sec} Normal text, (((fakebackslash)))textit{italic}, (((fakebackslash)))emph{italic}. \par (((fakebackslash)))subsection{sub} Math works too: $\sum _{x=0}^\infty 1+1$. \par (((fakebackslash)))subsubsection{subsub} Look at this: (((fakebackslash)))textit{It works}! \par 
(((fakebackslash)))end{document}

然后可以轻松传递sedlatex2html生成最终的 html。

此输出是部分处理过的 latex。扩展已停止在我们自定义的原语上,转换程序应该能够理解这一点。

用户可以编写各种宏(缩写、计数器等);只要它们最终归结为我们的基本元素,一切都可以正常工作。

我们还可以添加一个\rawhtml原语来保护它的输入不被 latex2html 处理,如果允许 -shell-escape,有动机的用户将能够编写宏,将 tikz 图片转换为独立的 tex 文件,将它们转换为 pdf,然后转换为 png,并将 png 包含在内\rawhtml

基本上,使用这种方法对用户没有任何限制。如果你幸运的话,可以选择每个包开箱即用的原语。然而,我怀疑很多原语都会被破坏,因为许多原始格式化命令在 html 中毫无意义。

尽管如此,如果你想亲自尝试,我认为可以提供一个适用于 LaTeX 大多数部分的合理实现。

相关内容