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 am trying to transition to using the etoolbox package, but seem to have run into some difficulties and they appear related to the hyperref and bm packages which to me seem totally unrelated. The MWE example compiles since \RemoveEToolbox is defined and shows that there is no apparent problem before etoolbox was used.

Commenting out the \def\RemoveEToolbox{} line produces two problems:

  1. With both the \renewcommand, and the usepackage{hyperref} commented, this results in "Runaway argument? Paragraph ended before \bm@test@token was complete".

  2. Including the usepackage{hyperref} (with \renewcommand commented) results in "Undefined control sequence. \Call@AtVeryEndDocument ...cumentHook \@undefined"

But if uncomment the \renewcommand{\bm}{#1} line (effectively doing without any \bm), then this seems to compile.

I have been using this for a while now and things appeared to have been working fine, but now that I attempt to use etoolbox I seem to run into problems.

\documentclass{standalone}
\def\RemoveEToolbox{}% Shows that this works fine without {etoolbox}

\usepackage{amsmath}
\usepackage{xcolor}
\usepackage{bm}

\ifdefined\RemoveEToolbox
    \newcommand*{\iftoggle}[3]{#2}% Default to true value of "if"
\else
    \usepackage{etoolbox}
    \newtoggle{paper}
    \toggletrue{paper}

    %\renewcommand{\bm}[1]{#1}% Why can't I have a normal \bm with {etoolbox}?
\fi

% \usepackage{hyperref}

\begin{document}

This document is intended for 
\iftoggle{paper}{paper}{electronic}
distribution.

\bm{\textcolor{blue}{Solve $x^2-1=0$}}

\begin{align*}
    a &= b\\
    \iftoggle{paper}{
        c &= d\\
    }{}
    e &= f\\
\end{align*}
\end{document}
share|improve this question
add comment

2 Answers

up vote 7 down vote accepted

The issues is that both the standalone class and the etoolbox package redefine the document environment. This causes a clash. You can avoid this by loading etoolbox before the class using \RequirePackage. I will try to support the normal of this package, but it will take a while until I have to time to release a new version of standalone.

Workaround:

\def\RemoveEToolbox{}% Shows that this works fine without {etoolbox}

\ifdefined\RemoveEToolbox
    \newcommand*{\iftoggle}[3]{#2}% Default to true value of "if"
\else
    \RequirePackage{etoolbox}
    \newtoggle{paper}
    \toggletrue{paper}

    %\renewcommand{\bm}[1]{#1}% Why can't I have a normal \bm with {etoolbox}?
\fi

\documentclass{standalone}

\usepackage{amsmath}
\usepackage{xcolor}
\usepackage{bm}

% \usepackage{hyperref}

\begin{document}

This document is intended for 
\iftoggle{paper}{paper}{electronic}
distribution.

\bm{\textcolor{blue}{Solve $x^2-1=0$}}

\begin{align*}
    a &= b\\
    \iftoggle{paper}{
        c &= d\\
    }{}
    e &= f\\
\end{align*}
\end{document}

Update 2011/12/21

The new version 1.0 of standalone works fine with etoolbox, due to a changed way to patch the document environment. However, the new default settings ignore paragraph breaks, so you will a problem with align*. You can fix easily this by using the varwidth class option.

share|improve this answer
    
Thanks, this seems to work. Wonder if this is related to the other problem with standalone that I emailed you. –  Peter Grill Jul 13 '11 at 19:34
    
@Peter: I changed the package and class code now to patch the document environment differently. This fixes the issue. –  Martin Scharrer Jul 13 '11 at 21:59
add comment

(Martin has posted an answer, but there is a bit more to this!) The problem arises due to an issue with the definition of \@@end. This is where the LaTeX kernel stores the TeX \end primitive (so that \end can be reused for environments). The bm package does various tests for \@@end which rely on it being the primitive. What is happening is that etoolbox does

\patchcmd\enddocument
  {\deadcycles}
  {\let\AfterEndDocument\@firstofone
   \@afterenddocumenthook
   \deadcycles}
  {}
  {\let\etb@@end\@@end
   \def\@@end{%
     \let\AfterEndDocument\@firstofone
     \@afterenddocumenthook
     \etb@@end}}

which tries to patch \enddocument, and if it cannot then alters the definition of \@@end. In the standard classes, the patch works (it looks for \deadcycles), and so all is well. On the other hand, this fails for standalone as it redefines \enddocument as

\def\sa@@enddocument{%
  %\let\document\sa@orig@document
  \let\enddocument\sa@orig@enddocument
  \endinput
}

So in this case, etoolbox does it's 'fall-back' patch, and then the tests in bm fail.

If you do not need the end-document hook, the fix is easy

\makeatletter
\let\@@end\etb@end
\makeatother

Otherwise, you'll need to wait for a fix.

share|improve this answer
    
Under what cases would I need the end-document hook? If this involved I can post a follow up question. –  Peter Grill Jul 13 '11 at 19:26
1  
@Peter It is more likely that some other package might want it than you would yourself. A hook right at the end of the document is useful for some processes which work between LaTeX runs, for example. –  Joseph Wright Jul 13 '11 at 19:27
    
Thanks for the analysis. I will try to support the patch commands. Note that the code you show is from the standalone package, not the class which is used here. However, the class code is quite similar. –  Martin Scharrer Jul 13 '11 at 19:46
    
@Martin: I did a quick read through the code, and assumed that with a class and a package that the 'payload' was in the later, with the class loading the package. –  Joseph Wright Jul 13 '11 at 19:49
    
@Joseph: Used to be the case, but they are now separated. However, you can also load both (if you want to include a standalone inside another). Both patch the document environment and therefore both have this issue anyway. –  Martin Scharrer Jul 13 '11 at 19:51
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.