我需要定义一个环境,在其中我可以简单地处理\begin{some string}some stuff\end{some string}
任意字符串,并让它将这些字符串处理为环境(输出例如\textbf{some string:} somestuff
)。环境还应接受修改其行为的可选参数。
诸如 enumerate 或 itemize 之类的预先存在的环境仍应在我的环境中工作。
我可以使用以下代码实现大部分功能:
\makeatletter
\def\ifEqString#1#2{\def\csa{#1}\def\csb{#2}\ifx\csa\csb }
\def\ifUnDefinedCs#1{\expandafter \ifx\csname#1\endcsname\relax}
\let\old@begin=\begin
\def\new@begin{\ifx[\next \expandafter\newXX@begin \else \expandafter\newX@begin \fi}
\def\newX@begin#1{\ifUnDefinedCs{#1}\newZ@begin{#1}\else\old@begin{#1} \fi}
\def\newZ@begin#1{\head@font{#1}\par\newenvironment{#1}{\let\head@font=\textit}{\relax}\old@begin{#1}}
\def\newXX@begin[#1]#2{\ifEqString{#1}{plain}--\else{#1}\fi {#2}\par\newenvironment{#2}{\let\head@font=\textit}{\relax}\old@begin{#2}}
\newenvironment{myenvironment}{\begingroup%
\let\head@font=\textbf
\def\begin{\futurelet\next\new@begin}
}{\endgroup}
\makeatother
但是,这会破坏tabular
需要提供参数的现有环境。有没有更好的方法来编写代码而不破坏这些?
答案1
我认为你在这里必须做一些繁重的工作。简单的修补\begin
无法完成这项工作,因为\begin
必须能够偶尔读取可选和必需的参数。你最好只是声明一个自定义环境来满足你的需求。你甚至可以通过给它起一个好听的简短名字来保持你的输入简洁,例如(假设xparse
可用):
\NewDocumentEnvironment{||}{ m o }{%
\IfNoValueTF{#2}{%
No optional argument
}%
{%
Optional argument #2
}%
\textbf{#1:}}%
{} % We don't need to do anything at the end
\begin{||}{some string} some stuff \end{||}
但如果您不想这样做,请声明将处理您的特殊环境的命令:
\NewDocumentCommand{\UndeclaredEnvironment}{ m o }{...}
这将把未声明的环境的名称作为其第一个必需参数,然后作为可选参数,您可以像我们上面的环境一样定义它。
现在到了手术时间。在我们进一步讨论之前,让我强调一下,这是一个坏的idea.texdoc source2e
将为您提供带注释的 LaTeX 源代码。 的定义\begin
出现在第 473 页的 D ltmiscen.dtx 部分中:
\DeclareRobustCommand*\begin[1]{%
\UseHook{env/#1/before}%
\@ifundefined{#1}%
{\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% ❶
{\def\reserved@a{\def\@currenvir{#1}%
\edef\@currenvline{\on@line}%
\@execute@begin@hook{#1}%
\csname #1\endcsname}}%
\@ignorefalse
\begingroup\@endpefalse\reserved@a}
我们感兴趣的行是我用 ❶ 标记的行。您需要将上述内容复制到新命令(例如,\BadIdeaBegin
使用\makeatletter
active)并将该行更改为:
{\def\reserved@a{\def\@currenvir{#1}%
\edef\@currenvline{\on@line}%
\@execute@begin@hook{#1}%
\UndeclaredEnvironment{#1}}}%
然后你可以让你的环境
\newenvironment{VeryBadIdea}{\let\begin\BadIdeaBegin}{}
事情就会按照你希望的方式进行。