我想创建(或更新)几个 LaTeX 命令和环境,并了解其工作原理。我的一个新环境相当于\begin{quotation}
。所以,想象一下我的\begin{foo}
环境。我希望它继承引用环境的所有功能,但想添加一个\Writinghand
字形并恢复为\singlespacing
。然后在引用文本的末尾,我将在最后一句的末尾放置一个字形,并在发出后\ding{47}
恢复到我通常的状态\onehalfspacing
(实际上是一个加半行间距) 。\end{foo}
那应该怎么写?并且,解释如何获取\renewenvironment
和\renewcommand
继承原始命令的所有功能,因为我知道“ \renew...
”基本上会删除 LaTeX 宏,您必须从头开始添加回原始功能。但在所有情况下,我只想为我的环境的参数、行距选项添加额外的格式符号和文本格式。
答案1
团契\newenvironment
和\renewenvironment
命令
是的,\renew...
将删除或重新定义先前的定义(如果之前没有定义过,则会弹出错误消息。)
在很多情况下,创建一个包装环境更为合适,它不会攻击原始环境。
\newenvironment{foo}{%
%startup code, i.e the \WritingHand and `\singlespacing`
\begin{quotation}
}{%
% end code
\ding{...}
\end{quotation}
}
由于环境使用组,在 内更改行距在foo
外是安全的,无需明确切换回\onehalfspacing
。这适用于所有长度/跳过和颜色设置。
\documentclass{article}
\usepackage{setspace}
\usepackage{pifont}
\usepackage{marvosym}
\onehalfspacing
\newenvironment{foo}{%
\singlespacing
\begin{quotation}
\WritingHand
}{%
\ding{47}
\end{quotation}
}
\begin{document}
% Compare the spacing outside and inside of foo environment
Three Rings for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone,
Nine for Mortal Men doomed to die,
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
One Ring to rule them all, One Ring to find them,
One Ring to bring them all and in the darkness bind them
In the Land of Mordor where the Shadows lie.
\begin{foo}
Three Rings for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone,
Nine for Mortal Men doomed to die,
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
One Ring to rule them all, One Ring to find them,
One Ring to bring them all and in the darkness bind them
In the Land of Mordor where the Shadows lie.
\end{foo}
\end{document}
版本renewenvironment
renewenvironment
基本相似,但也必须牢记设计问题:
- 环境是否应该扩展/改进 --> 使用旧定义
- 完全放弃旧的行为 --> 不要使用旧的定义(当然)
我认为旧的行为应该仍然可用,因此我尝试了第一种方法:
- 首先将旧的环境启动代码(即命令)存储
\quotation
为某个东西,比如说\latex@quotation
。 - 将环境结束代码(即 )存储
\endquotation
至\latex@endquotation
。 - 基本上按照版本进行,
\newenvironment
并用\begin{quotation}
和替换。\latex@quotation
\end{quotation}
\latex@endquotation
输出是一样的。
重要提示:如果环境有可选参数,最好使用\LetLtxMacro
而不是\let
,那么您就需要letltxmacro
包。
\documentclass{article}
\usepackage{setspace}
\usepackage{pifont}
\usepackage{marvosym}
\onehalfspacing % for this document ....
\makeatletter
\let\latex@quotation\quotation
\let\latex@endquotation\endquotation
\renewenvironment{quotation}{%
\singlespacing
\latex@quotation
\WritingHand
}{%
\ding{47}
\latex@endquotation%
}
\makeatletter
\begin{document}
% Compare the spacing outside and inside of foo environment
Three Rings for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone,
Nine for Mortal Men doomed to die,
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
One Ring to rule them all, One Ring to find them,
One Ring to bring them all and in the darkness bind them
In the Land of Mordor where the Shadows lie.
\begin{quotation}
Three Rings for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone,
Nine for Mortal Men doomed to die,
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
One Ring to rule them all, One Ring to find them,
One Ring to bring them all and in the darkness bind them
In the Land of Mordor where the Shadows lie.
\end{quotation}
% And once again
Three Rings for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone,
Nine for Mortal Men doomed to die,
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
One Ring to rule them all, One Ring to find them,
One Ring to bring them all and in the darkness bind them
In the Land of Mordor where the Shadows lie.
\end{document}
编辑最短的版本:使用xpatch
命令及其\xpretocmd
宏\xapptocmd
。
\documentclass{article}
\usepackage{setspace}
\usepackage{pifont}
\usepackage{marvosym}
\usepackage{xpatch}
\onehalfspacing % for this document ....
\newcommand{\lotrtext}{%
Three Rings for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone,
Nine for Mortal Men doomed to die,
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.
One Ring to rule them all, One Ring to find them,
One Ring to bring them all and in the darkness bind them
In the Land of Mordor where the Shadows lie.
}
% Append the `\singlespacing` etc. after the `\quotation` startup is called
\xapptocmd{\quotation}{\singlespacing%
\WritingHand%
}{}{}
% Prepend `\ding{47}` before `\endquotation` comes into action.
\xpretocmd{\endquotation}{\ding{47}}{}{}
\begin{document}
% Compare the spacing outside and inside of foo environment
\lotrtext
\begin{quotation}
\lotrtext
\end{quotation}
% And once again
\lotrtext
\end{document}
最后(?)评论——您的可能性:
- 使用以下方法优化包装器
\newenvironment
- 更改或完全删除先前的定义
\renewenvironment
\xpretocmd
使用,\xapptocmd
或\xpatchcmd
介于第一种和第二种方式之间的某种方式来修补命令。
一切都取决于所要求的设计,没有一般规则。(如果重新定义或新定义,我建议使用\NewDocumentEnvironment
或\RenewDocumentEnvironment
来自非常强大的xparse
包。
更新
Mico 发表了重要评论:
该包etoolbox
提供了命令\AtBeginEnvironment
和\AtEndEnvironment
,\BeforeBeginEnvironment
和\AfterEndEnvironment
它们的作用基本上与我用\xpretocmd
和\xapptocmd
或显式所做的相同\renewenvironment
,但是,仅针对现有环境——etoolbox
应该使用哪个命令取决于精确的要求,应该在组开始/结束之前或之后做什么。
作为替代方案,可以NewEnviron
从environ
包中将环境主体保存到\Body
宏中。