4

I want to redefine the minipage environment which has several optional parameters. The default renewenvironment allows only a single optional argument. Therefore, I try to use the xparse package which offers \RenewDocumentEnvironment:

MWE:

\documentclass{standalone}
\usepackage{xparse}
\RenewDocumentEnvironment{minipage}{O{} O{} O{} m}{\begin{minipage}[#1][#2][#3]{#4}}{\end{minipage}}
\begin{document}
\begin{minipage}{\linewidth}
  hello world
\end{minipage}
\end{document}

However, this document does not compile successfully:

 ! TeX capacity exceeded, sorry [grouping levels=255].
 \__xparse_grab_arg:w ...e_args_tl }}\group_begin: 
                                                   \token_if_eq_catcode:NNTF ...
 l.5 \begin{minipage}{\linewidth}

 !  ==> Fatal error occurred, no output PDF file produced!
 Transcript written on demo-xparse-minipage.log.
  • 1
    You have to \let\originalminipage\minipage and \let\originalendminipage\endminipage and then \RenewDocumentEnvironment{minipage}{..}{\originalminipage[#1][#2][#3]{#4}}{\originalendminipage}. – Manuel Aug 5 '15 at 13:56
  • Thanks. It successfully compiles now. However, my MWE creates an empty minipage. Do you see what is wrong? Currently, the output should be the same (with or without renewenvironemnt). I have not added my modifications. – Hotschke Aug 5 '15 at 14:03
  • Apparently, I have to take care for different numbers of arguments. Answer by egreg shows how it can be done. – Hotschke Aug 5 '15 at 14:08
7

You can't redefine minipage in terms of itself; you have also to parse carefully the optional arguments, as LaTeX cannot comply with empty optional arguments to the original minipage.

\documentclass[border=2pt]{standalone}
\usepackage{xparse}

% save the old commands
\let\latexminipage\minipage
\let\latexendminipage\endminipage

\RenewDocumentEnvironment{minipage}{ooom}
 {%
  \IfNoValueTF{#1}
   {\latexminipage{#4}}
   {%
    \IfNoValueTF{#2}
     {\latexminipage[#1]{#4}}
     {%
      \IfNoValueTF{#3}
       {\latexminipage[#1][#2]{#4}}
       {\latexminipage[#1][#2][#3]{#4}}%
     }%
   }%
 }
 {\latexendminipage}

\begin{document}
\begin{minipage}{3cm}
  hello world
\end{minipage}

\begin{minipage}[b]{3cm}
  hello world\\
  hello world
\end{minipage}

\begin{minipage}[b][4cm]{3cm}
  hello world\\
  hello world
\end{minipage}

\begin{minipage}[b][4cm][s]{3cm}
  hello world

  \vfill

  hello world
\end{minipage}

\end{document}

enter image description here

  • 6
    I know you don't like these kind of comments, but this time I don't mind... My congratulations for yours 400k reputation and my best wishes for the next step: 1/2 million! Grande Enrico. And thanks for all the knowledge you share with us in the site! – karlkoeller Aug 5 '15 at 14:08
  • 3
    @karlkoeller: – Paulo Cereda Aug 5 '15 at 14:12
  • Wouldn't using \LetLtxMacro instead of \let be better because it does not need the fiddling with optional arguments? – stefanct Jul 9 at 13:27
  • @stefanct \minipage doesn't have an optional argument in its current implemetation. It is defined with \@ifnextchar. – egreg Jul 9 at 14:28

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.