如何重新定义命令和环境,并使它们可以被 `\write` 接受

如何重新定义命令和环境,并使它们可以被 `\write` 接受

我的一般问题如下。我想将许多 .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 为您编写文件更好的解决方案。

相关内容