因此,我希望有一个系统,其中某些用户文档完全由 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 原语。我猜这可以通过一种聪明的方式来完成,以减少原语的数量,就像我为\@startsection
section、subsection 和 subsubsection 所做的那样。
我们使用不引入控制序列的\fakebackslash
for \
。也许可以有更好的方法,但剩下的只是将 简单替换为(((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}
然后可以轻松传递sed
并latex2html
生成最终的 html。
此输出是部分处理过的 latex。扩展已停止在我们自定义的原语上,转换程序应该能够理解这一点。
用户可以编写各种宏(缩写、计数器等);只要它们最终归结为我们的基本元素,一切都可以正常工作。
我们还可以添加一个\rawhtml
原语来保护它的输入不被 latex2html 处理,如果允许 -shell-escape,有动机的用户将能够编写宏,将 tikz 图片转换为独立的 tex 文件,将它们转换为 pdf,然后转换为 png,并将 png 包含在内\rawhtml
。
基本上,使用这种方法对用户没有任何限制。如果你幸运的话,可以选择每个包开箱即用的原语。然而,我怀疑很多原语都会被破坏,因为许多原始格式化命令在 html 中毫无意义。
尽管如此,如果你想亲自尝试,我认为可以提供一个适用于 LaTeX 大多数部分的合理实现。