3

I have redefined quote environment to allow me to put author at the end of quotation, but I have a mistake somewhere in my code, could someone check it:

%Add source argument to quote
\let\oldquote\quote
\newsavebox\first
\newsavebox\second
\renewenvironment{quote}[2][0]
  {\savebox\second{#1}
   \savebox\first{#2}
  \begin{oldquote}}
  {\smallskip\par\hfill(\usebox\first ~---~\usebox\second)\bigskip\break
  \end{oldquote}}

If I try to use more than 6 of those I get "Too deeply nested" error, so I assume I don't end the environment correctly, but I can't find the error.

5

When LaTeX finds \end{oldquote} it just ends the group, but not the (original) quote environment, because \endoldquote is not defined.

Add also

\let\endoldquote\endquote

Remove the final \break, whose only effect is to issue an “Underfull \hbox (badness 10000)” warning.


It's not clear why the renewed quote environment has an optional argument: setting the default to 0 would make

\begin{quote}{Somebody}
<text>
\end{quote}

to print “(Somebody — 0)” which doesn't seem wanted.

See also Quote environment with reference at the end right for a very similar problem.


A possible refinement:

\documentclass{article}

\let\oldquote\quote
\let\endoldquote\endquote
\renewenvironment{quote}[2][]
  {\if\relax\detokenize{#1}\relax
     \def\quoteauthor{#2}%
   \else
     \def\quoteauthor{#2~---~#1}%
   \fi
   \oldquote}
  {\par\nobreak\smallskip\hfill(\quoteauthor)%
   \endoldquote\addvspace{\bigskipamount}}

\begin{document}

\begin{quote}{Somebody}
This is a quote This is a quote This is a quote
This is a quote This is a quote This is a quote
This is a quote This is a quote This is a quote
\end{quote}

\begin{quote}[Somewhere]{Somebody}
This is a quote This is a quote This is a quote
This is a quote This is a quote This is a quote
This is a quote This is a quote This is a quote
\end{quote}

\end{document}

Note the inversion between \par and \smallskip, with the addition of \nobreak to avoid a page break between the quote and the attribution. Storing the arguments in boxes is not needed; it's easier to store them in a macro that will contain different things when the optional argument is missing. Also the \bigskip is better placed after closing the (original) quote.

enter image description here

A simpler approach with xparse, where it's possible to use the arguments also in the “end part”:

\documentclass{article}
\usepackage{xparse}

\let\oldquote\quote
\let\endoldquote\endquote

\RenewDocumentEnvironment{quote}{om}
  {\oldquote}
  {\par\nobreak\smallskip
   \hfill(#2\IfValueT{#1}{~---~#1})\endoldquote 
   \addvspace{\bigskipamount}}

\begin{document}

\begin{quote}{Somebody}
This is a quote This is a quote This is a quote
This is a quote This is a quote This is a quote
This is a quote This is a quote This is a quote
\end{quote}

\begin{quote}[Somewhere]{Somebody}
This is a quote This is a quote This is a quote
This is a quote This is a quote This is a quote
This is a quote This is a quote This is a quote
\end{quote}

\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.