Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to systematically have some indentation in \parboxes and minipage environments. To do this, I add the following code in the preambule of my LaTeX file:

\makeatletter
\g@addto@macro\@parboxrestore{\setlength{\parindent}{1.5em}}
\makeatother

It works, except when I load the calc package. I get then

! Missing number, treated as zero.
<to be read again> 

etc. It seems \g@addto@macro does not like the way \setlength is redefined in calc. How could one solve this problem?

Here is a minimal working example:

\documentclass{article}
\makeatletter
\g@addto@macro\@parboxrestore{\setlength{\parindent}{1.5em}}
\makeatother
\usepackage{calc}
\begin{document}
\begin{minipage}{\textwidth}
\end{minipage}
\end{document}
share|improve this question
1  
\g@addto@macro doesn't care about the definitions of the added macro code, it just adds them to the macro. –  Martin Scharrer Apr 26 '12 at 15:14
add comment

1 Answer 1

up vote 10 down vote accepted

You can remove the minipage actually

\documentclass{article}
\makeatletter
\g@addto@macro\@parboxrestore{\setlength{\parindent}{1.5em}}
\makeatother
\usepackage{calc}


\begin{document}

a
\end{document}

The problem occurs during the output routine where \protect is set to protect things rather than allow them to work, but it is \noexpand which is the wrong sort of protection.

The simplest thing to do is just avoid the problem

 \g@addto@macro\@parboxrestore{\parindent=1.5em\relax}

unless you really need calc-syntax setlength here


Note that \@parboxrestore changes a lot more than just parbox and minipage. As well as the output routine (for page head and foot) which was the case that failed, footnotes, figures tables and any other floats will pick up the redefinition.


In case you were wondering.....

the latex sources say

% 
%    The setting of |\protect| immediately before the |\shipout|
%    is needed so that protected commands within |\write|s are
%    handled correctly.
% 
%    Within shipout's vbox it is reset to its default value, |\relax|.
% 
%    Resetting it to its default value after the shipout has been 
%    completed (and the contents of the writes have been expanded)
%    must be done by use of |\aftergroup|.
%    This is because it must have the value |\relax|
%    before macros coming from other uses of |\aftergroup| within
%    this box are expanded.
%
%    Putting this into the |\aftergroup| token list does not affect
%    the definition used in expanding the |\write|s because the
%    aftergroup token list is only constructed when popping the
%    save-stack, it is not expanded until after the shipout is
%    completed.
%
%    Question: should things from an |\aftergroup| within the shipped
%    out box be executed in the environment set up for the writes, or
%    after it finishes?
%

followed by the code

\def\@outputpage{%
\begingroup           % the \endgroup is put in by \aftergroup
  \let \protect \noexpand
  \@resetactivechars
  \global\let\@@if@newlist\if@newlist
  \global\@newlistfalse
  \@parboxrestore
  \shipout \vbox{%
    \set@typeset@protect

If \@parboxrestore were moved down 2 lines after the \set@typeset@protect then things would work but this is deeply embedded latex code and this would be affecting the typesetting of every page on every latex document. Something bad would happen to someone somewhere (most likely because they were using a package that patched this command in unexpected ways....

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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