我的一般问题如下。我想将许多 .tex 文件“转换”为其他格式(类似 xml)。我不想修改 tex 文件,我只能构建一个 documentclass。texfiles 通过命令和环境以块(我将它们称为内容块)的形式组织,例如,大致如下:
\begin{document}
\content{blablabla}
\titre{joli titre}
\explanation{i muss explain that...}
\begin{definition}
here some nice text
\end{definition}
....
\end{document}
我现在的方法是捕获命令或环境的内容并将\write
它们写入文件中:
\newwrite\tempfile
\immediate\openout\tempfile="test.xml"
例如(tex文件使用的documentclass中定义如下):
\newcommand{\content}[1]{
\immediate\write\tempfile{<content>}
\immediate\write\tempfile{\content}
\immediate\write\tempfile{</content>}
}
复杂性来自于这样的事实,即中的命令和环境\content
可能包含的不仅仅是文本,例如其他宏。例如:
\content{
some blablabla \textbf{important} etc etc
}
\begin{definition}
consider the following points :
\begin{quote}
quote quote quote
\end{quote}
and so on, and so on...
\end{definition}
在这种形式下,这会导致编译错误,因为\write
无法将其写入文件。另一方面,我知道可以出现在“内容块”中的命令/环境的详尽列表。我想通过重新定义来捕获它们。例如:
\renewcommand{\textbf}[1]{<bold>#1</bold>}
有效,该命令\content
将在文件“test.xml”中生成一行
some blablabla <bold>important</bold> etc etc
问题 1:此策略不适用于环境。我的尝试
\renewenvironment{quote}{<quote>}{</quote>}
彻底失败。
问题 2:我尤其需要这个itemize
环境(而不是quote
)。我知道重新定义\item
可能会产生一些问题
问题 3:在内容块中,我有时会使用带有可选参数的命令,例如:
\content{bla bla \com[opt]{AAA} bla bla}
这里再次失败,因为带有可选参数的命令无法完全扩展。作为解决方法,我可以\com
使用\DeclareExpandableDocumentCommand
包中的命令重新定义该命令xparse
。
\DeclareExpandableDocumentCommand\expandCom{ o m} {<com : #1>#2</com>}
它似乎解决了带有可选参数的命令的问题,但对于带有可选参数的环境,我需要同样的方法。
问题4:我需要处理内容块的内容,以便提取信息。为此,我特别使用\edef
,并且我需要宏(\com
、\texbf
等等)在中正确展开edef
。但我猜这与 的问题完全相同\write
。对于 和 两者\edef
,都\write
需要内部完全可扩展的宏,不是吗?
编辑1关于 Bruno 的问题。我认为 David 的解决方案在某种程度上是安全的,因为它不会重新定义现有的命令/环境,而是创建新的命令/环境(\mwx\begin
等等...)。
尽管如此,按照 Bruno 的建议,我尝试简单地重新定义命令\begin
和\end
我需要的环境(在此示例中为引用和定义)。然而,我的尝试失败了。这可能是因为\ifthenelse
,但另一方面,我始终对 感到不舒服\ifx
:
\documentclass{article}
\usepackage{ifthen}
\let\originalbegin\begin
\let\originalend\end
\def\begin#1{%
\ifthenelse{\equal{#1}{quote}}{<quote:special def for quote>}{
\ifthenelse{\equal{#1}{definition}}{<DEF: another definition>}{\originalbegin{#1}
}
}
}
\def\end#1{%
\ifthenelse{\equal{#1}{quote}}{</quote>}{
\ifthenelse{\equal{#1}{definition}}{</DEF>}{\originalend{#1}
}
}
}
\newwrite\tempfile
\immediate\openout\tempfile="nico.xml"
\begin{document}
\def\content{
some blablabla etc etc
\begin{definition}
consider the following points :
\begin{quote}
quote quote quote
\end{quote}
and so on, and so on...
\end{definition}
}
\immediate\write\tempfile{\content}%
\immediate\closeout\tempfile
\end{document}
答案1
可能是这样的(普通的 TeX 写入终端,但可以进行调整)
\long\def\mywrite{%
\begingroup
\obeyspaces\mywritey}
\long\def\mywritey#1{%
\immediate\write20{\mywritex#1\endmywritex}%
\endgroup}
\long\def\mywritex#1{%
\expandafter\ifx\csname mwx\string#1\endcsname\relax
\string#1%
\expandafter\mywritex
\else
\csname mwx\string#1\expandafter\endcsname
\fi}
\newlinechar=`^^J
\long\def\mywritedef#1{\expandafter\def\csname mwx\string#1\endcsname}
\mywritedef\endmywritex{}
\mywritedef\par{^^J<p/>^^J\mywritex}
\mywritedef\begin#1{<\mywritex{#1}\endmywritex>\mywritex}
\mywritedef\end#1{</\mywritex{#1}\endmywritex>\mywritex}
\mywritedef\textbf#1{<bold>\mywritex#1\endmywritex</bold>\mywritex}
\mywritedef{definition}{DEF\mywritex}
\mywrite{
some blablabla \textbf{important} etc etc
\begin{definition}
consider the following points :
\begin{quote}
quote quote quote
\end{quote}
and so on, and so on...
\end{definition}
}
\bye
它写出:
$ tex write.tex
This is TeX, Version 3.1415926 (TeX Live 2011/Cygwin)
(./write.tex
<p/>
some blablabla <bold>important</bold> etc etc
<p/>
<DEF> consider the following points : <quote> quote quote quote </qu
ote> and so on, and so on...</DEF>
<p/>
<p/>
)
No pages of output.
答案2
潘多克可以将 TeX 翻译成 html。大概只要做一点工作,您就可以使用类似这样的工具来为您进行翻译?我真的认为这将是比让 TeX 为您编写文件更好的解决方案。