I'd like to create (or renew) several LaTeX commands and environments, and understand how it works. One of my new environments would be equivalent to \begin{quotation}
. So, imagine my \begin{foo}
environment. I want it to inherit all the functionality of quotation environments, but would like to add a \Writinghand
glyph and revert to \singlespacing
. Then at the end of the quotation text I will place a \ding{47}
glyph at the end of the last sentence, plus revert back to my usual \onehalfspacing
(that's actually one plus a half line spacing) after the \end{foo}
is issued.
How would that be written? And, explain how to get \renewenvironment
and \renewcommand
to inherit all the functionality of the original command, because I understand "\renew...
" basically erases the LaTeX macro, and you have to start from the beginning to add back the original functionality. But in all my cases I just want to add extra formatting glyphs and text formatting to arguments, linespacing options for my environments.
Best Answer
The fellowship of
\newenvironment
and\renewenvironment
commandsYes,
\renew...
will erase or redefine the previous definition (or eject an error message, if this has not been defined before.)In many cases it's more suitable to make a wrapper environment, which does not attack the original environment.
Since environments use groups, the change of the line spacing within of
foo
is safe outside, there is no need to explicitly switch back to\onehalfspacing
. This is true for all lengths/skips and colour settings.The
renewenvironment
versionrenewenvironment
is basically similar, but one has to keep in mind too design issues:I assume that the old behaviour should be available still, so I tried the first approach:
\quotation
, to something, say\latex@quotation
.\endquotation
then, to\latex@endquotation
.\newenvironment
version and replace\begin{quotation}
with\latex@quotation
and\end{quotation}
with\latex@endquotation
.The output is the same.
Important note: If the environment has optional arguments, it's better to use
\LetLtxMacro
instead of\let
, you need theletltxmacro
package then.Edit The shortest version: Use the
xpatch
command and its\xpretocmd
and\xapptocmd
macros.And the final (?) remark -- your possibilities:
\newenvironment
\renewenvironment
\xpretocmd
,\xapptocmd
or\xpatchcmd
which is something between the 1st and 2nd. way.All depends on the requested design, there is no general rule. (And if redefinition or new definition, I suggest to use
\NewDocumentEnvironment
or\RenewDocumentEnvironment
from the very powerfulxparse
package.Update
Mico made an important comment:
The package
etoolbox
provides the commands\AtBeginEnvironment
and\AtEndEnvironment
,\BeforeBeginEnvironment
and\AfterEndEnvironment
which do basically the same what I've done with\xpretocmd
and\xapptocmd
or the explicit\renewenvironment
, however, to an existing environment only -- which of theetoolbox
commands should be used depends on the precise requirements, what should be done before or after the group begins/ends.As an alternative, there is
NewEnviron
from theenviron
package, which allows for the saving of the environment body into\Body
macro.