2

In this MWE, a command argument is directly passed to an environment. That works fine with empty values:

\documentclass{article}

\newcommand{\minipag}[1]{%
    \begin{minipage}[b][#1][b]{6em}
    One minipage
    \end{minipage}
    }
    
\begin{document}

\minipag{2em}
\minipag{\relax}
\minipag{}

\end{document}

However, when the argument is passed using a macro, and it takes an empty value, it is not recognized by the (minipage) environment:

\documentclass{article}

\newcommand{\minipag}[1]{%
    \def\upto{#1}
    \begin{minipage}[b][\upto][b]{6em}
    One minipage
    \end{minipage}
    }
    
\begin{document}

\minipag{2em}
\minipag{\relax}
\minipag{}

\end{document}

Why does it happens? What is the way to do this?

For me, the underlying question is what are string arguments really: macros, lists of tokens, general text, registers...

2
4

There is no general feature here you are just seeing a lack of error checking in minipage.

In

\begin{minipage}[b][...][b]{6em}

The ... is a length so an empty argument is a syntax error. Unfortunately minipage (as space was tight in 1993 when this argument was added) does not do any real error checking and the empty argument sneaks through then finally ends up at

\ifx \relax #2\else \setlength \@tempdimb {#2}

so the \ifx test is a (overly simple) test to see if that argument was used; and when #2 is empty it does not test #2 against \relax but rather tests \relax against \else which is a nonsense test which just luckily makes it avoid the setlength with an empty length, so avoids an error.

When #2 is (any) commandname other than \relax then the intended test happens, the test is false so the length is set to the expansion of #2 which in this case is empty, so you get an error, the same as for

\setlegth\@tempdima{}
8
  • So, following your explanation, when the argument #1 is empty then "..." is "nothing'". However, \upto seems to be "another kind of nothing''? Is it possible to define \upto to have "the first category of nothing''? Or should I add some code like \ifx\upto\empty\let\upto\relax\fi – e_moro Jun 22 '20 at 22:49
  • @e_moro no the test that is used here is an \ifx test so it does not use expansion at all so it is testing if you put anything in that argument not what it expands to so you can not put anything that is equivalent to nothing, – David Carlisle Jun 22 '20 at 23:12
  • oh sorry I misread your comment: if you use \relax it might accidentally work but not by any tested or intentional code path. Passing anything other than a valid length into that argument of minipage is a user error, you should raise an error if the argument passed to your macro is not a length. – David Carlisle Jun 22 '20 at 23:15
  • I understand the explanation. But my comment (and question) is also about how to deal with such an odd issue. My goal is to write a command that keeps that minipage feature, ie, it can be called with both \minipag {length} or \minipag{}. Sorry for the misunderstanding. – e_moro Jun 23 '20 at 8:50
  • @e_moro no you should not keep it or rely on it working, if you want to allow an empty argument, best would be to make the argument of your command optional and if it is not supplied, call minipage without the length argument. If it is supplied then it should be a length and you can pass it on to minipage. If (although I would not recommend it) you want the argument of your command to be mandatory, then check that it is empty and if it is call minipage without the length argument. – David Carlisle Jun 23 '20 at 8:54

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.