6

When I try to make either \intertext or \shortintertext conditional I get excess vertical spacing prior to the conditional text as per the MWE below. Note the excess vertical spacing prior to "Albert insisted that" and "but we know".

The minipage on the right represents the correct spacing as it does not have the \ConditionalText{} macro applied.

enter image description here

However, when the conditional is disabled, via the \toggletrue{}, the text is suppressed and the spacing is fine:

enter image description here

Notes:

  • It seems that with

    \NewDocumentCommand{\ConditionalText}{O{red} +m}{#2}%
    

    the spacing problem is still there. However, the problem is resolved if I use the \iftoggle directly within the align environment as:

    \newcommand{\TextWithConditional}{%
        \hfill\textbf{Intertext with Conditionals}\hfill%
        Newton said:
        \begin{align*}
            F &= ma \\
            \iftoggle{SupressConditionalText}{}{\intertext{Albert insisted that}}
            E &=mc^2 \\
            \iftoggle{SupressConditionalText}{}{\shortintertext{but we know}}
            E &=\frac{1}{2}mv^2
        \end{align*}
        Text after a conditional display math formula.%
    }%
    

Failed Solution:

  • Well, I had what I thought was a brilliant fix, but it seems that all I can do is to quote Edison and say "I have discovered a method that does not work". Not sure why it does not work though.

    \NewDocumentCommand{\ConditionalText}{O{red} +m}{%
        \ignorespaces%
        \iftoggle{SupressConditionalText}{}{%
            \ifmmode%
                \let\OldIntertext\intertext%
                \let\OldShortIntertext\shortintertext%
                \def\intertext{\vspace*{\baselineskip}\OldIntertext}%
                \def\shortintertext{\vspace*{-\baselineskip}\OldShortIntertext}%            
                #2% Don't underline if in math mode
            \else%
                %\UnderlineText[#1]{#2}% This case not used in this MWE.
            \fi%
        }%
        \ignorespacesafterend%
    }%
    

Code:

\documentclass{article}
\usepackage{xparse}% Not essential for this problem.
\usepackage{xcolor}
\usepackage{etoolbox}
\usepackage{mathtools}
\usepackage{soul}
\usepackage{parskip}% Eliminate need for \noindent
%\usepackage{showframe}

\newtoggle{SupressConditionalText}%

\togglefalse{SupressConditionalText}% This has too much space BEFORE the conditional \intertext.


\NewDocumentCommand{\UnderlineText}{O{red} +m}{%
    \setulcolor{#1}\ul{#2}%
}%

\NewDocumentCommand{\ConditionalText}{O{red} +m}{%
    \ignorespaces%
    \iftoggle{SupressConditionalText}{}{%
        \ifmmode%
            #2% Don't underline if in math mode
        \else%
            \UnderlineText[#1]{#2}%
        \fi%
    }%
    \ignorespacesafterend%
}%

\newcommand{\TextWithConditional}{%
    \hfill\textbf{Intertext with Conditionals}\hfill%
    Newton \ConditionalText{often} said:
    \begin{align*}
        F &= ma \\
        \intertext{Albert \ConditionalText{awkwardly} insisted that}
        E &=mc^2 \\
        \ConditionalText{\shortintertext{but we know}}
        E &=\frac{1}{2}mv^2 \\
        \ConditionalText{\intertext{But, equating the two we obtain.}}    
        mc^2 &= \frac{1}{2}mv^2
        \shortintertext{from which \ConditionalText{we obtain}}
        v &= \sqrt{2}c
    \end{align*}
    Text after a conditional display math formula.%
}%


\newcommand{\TextWithoutConditional}{%
    \hfill\textbf{Intertext without Conditionals}\hfill%
    Newton said:
    \begin{align*}
        F &= ma \\
        \intertext{Albert awkwardly insisted that}
        E &=mc^2 \\
        \shortintertext{but we know}
        E &=\frac{1}{2}mv^2
    \end{align*}
    Text after a conditional display math formula.%
}%
\newcommand{\TextWithoutConditionalWithoutInterText}{%
    \hfill\textbf{No Intertext, No Conditionals}\hfill%
    Newton said:
    \begin{align*}
        F &= ma \\
        E &=mc^2 \\
        E &=\frac{1}{2}mv^2
    \end{align*}
    Text after a conditional display math formula.%
}%

\begin{document}
\begin{minipage}[t]{0.45\linewidth}
    \TextWithConditional
\end{minipage}
\hfill\vrule\hfill% 
\begin{minipage}[t]{0.45\linewidth}
    \TextWithoutConditional
\end{minipage}

\bigskip\hrule
\toggletrue{SupressConditionalText}%  Disable conditional text
%
With conditional text supressed, things work fine:

\begin{minipage}[t]{0.45\linewidth}
    \TextWithConditional
\end{minipage}%
\hfill\vrule\hfill% 
\begin{minipage}[t]{0.45\linewidth}
    \TextWithoutConditionalWithoutInterText
\end{minipage}%
\end{document}
Moriambar
  • 11,466
Peter Grill
  • 223,288
  • 7
    This is an expandability issue. \intertext uses the TeX primitive \noalign to insert text which is not aligned with the rest. This primitive may only appear just after \\ (well, after the underlying \cr primitive). More precisely, TeX expands what follows (and ignores spaces) until finding a non-expandable token. If that token is \noalign, then it prepares to put stuff out of the alignment. Now, \intertext is clever, and does some (expandable) tests to make sure that it is preceeded by \\, adding it if needed. Since your condition is non-expandable, \\ gets inserted. – Bruno Le Floch Feb 23 '13 at 03:22
  • So the solution is: use \DeclareExpandableDocumentCommand (make sure that all arguments are either long or short) and remove \ignorespaces from the beginning of the definition of \ConditionalText – cgnieder Mar 11 '13 at 11:30
  • @cgnieder: Can you post an answer? When I use \DeclareExpandableDocumentCommand{\ConditionalText}{O{red} m} and comment out \ignorespaces it seems as if the value of the toggle is completely ignored, which I don't get at all. This has to be something obvious, but I am not seeing it at the moment. – Peter Grill Mar 11 '13 at 18:55
  • @PeterGrill I believe you get the empty branch of the \ifmmode conditional... – cgnieder Mar 11 '13 at 18:58
  • @cgnieder: Duh!!! Yeah that makes sense. But that means that I am not in math mode at that point so should be able to use the \UnderlineText, but that yields Misplaced \noalign (if I un-comment the related code). Can't wait until the day that expansion makes sense to me... – Peter Grill Mar 11 '13 at 19:25
  • @PeterGrill as Bruno said: you cannot use anything in \ConditionalText that is not expandable before \intertext. Since you supply \intertext as argument you get \setulcolor{red}\ul{\intertext{<text>}} while it should be \intertext{\setulcolor{red}\ul{<text>}}. Every assignment (like \setulcolor{red}) is not expandable. – cgnieder Mar 11 '13 at 20:27
  • @PeterGrill You are not in math mode when tex scans ahead looking for omit and the \ifmmode is expanded at that point, but then if it doesn't find \noalign or \omit it inserts the halign preamble which in this case is from align so that starts math mode and then TeX re-processes the tokens. Normal way to stop that is to make your command robust so that it doesn't expand in the initial scan, but you can't do that as then \intertext won't be seen. – David Carlisle Mar 13 '13 at 21:54
  • @DavidCarlisle: So, are you saying that there is not a way to get conditional \intertext? That seems very unlikely, must have misunderstood. – Peter Grill Mar 13 '13 at 21:56
  • 1
    No I'm just saying you need to step carefully to avoid waking sleeping dragons. – David Carlisle Mar 13 '13 at 21:58
  • In particular where do you want ConditionalText to be used? If it is only in align then it's easy: just don't test for \ifmmode If it is always used at the start of some kind of alignment row you can hide teh non expandable tests in \noalign if it needs to work both in alignments and normal texts it's a bit harder but not impossible – David Carlisle Mar 13 '13 at 22:09

1 Answers1

4

This does what I think you want and keeps the tests expandable, it takes the math branch if you are in align* or ifmmode is true. It would need extending for other environmants.

enter image description here

\documentclass{article}
\usepackage{xparse}% Not essential for this problem.
%\usepackage{xcolor}
\usepackage{etoolbox}
\usepackage{mathtools}
%\usepackage{soul}
\usepackage{parskip}% Eliminate need for \noindent
%\usepackage{showframe}

\makeatletter \newtoggle{SupressConditionalText}%

\togglefalse{SupressConditionalText}% This has too much space BEFORE the conditional \intertext.

% Not used in this paritcular example \NewDocumentCommand{\UnderlineText}{O{red} +m}{% \setulcolor{#1}\ul{#2}% }%

\def\xaligns{align*} \def\ConditionalText#1{% \iftoggle{SupressConditionalText}{}{% \ifx@currenvir\xaligns #1% \else\ifmmode #1% Don't underline if in math mode \else% \UnderlineText[red]{#1}% This case not used in this MWE. \fi \fi }% \ignorespacesafterend% }%

\newcommand{\TextWithConditional}{% \hfill\textbf{Intertext with Conditionals}\hfill% Newton said: \begin{align} F &= ma \ \ConditionalText{\intertext{Albert insisted that}} E &=mc^2 \ \ConditionalText{\shortintertext{but we know}} E &=\frac{1}{2}mv^2 \end{align} Text after a conditional display math formula.% }%

\newcommand{\TextWithoutConditional}{% \hfill\textbf{Intertext without Conditionals}\hfill% Newton said: \begin{align} F &= ma \ \intertext{Albert insisted that} E &=mc^2 \ \shortintertext{but we know} E &=\frac{1}{2}mv^2 \end{align} Text after a conditional display math formula.% }% \newcommand{\TextWithoutConditionalWithoutInterText}{% \hfill\textbf{No Intertext, No Conditionals}\hfill% Newton said: \begin{align} F &= ma \ E &=mc^2 \ E &=\frac{1}{2}mv^2 \end{align} Text after a conditional display math formula.% }%

\begin{document} \begin{minipage}[t]{0.45\linewidth} \TextWithConditional \end{minipage} \hfill\vrule\hfill% \begin{minipage}[t]{0.45\linewidth} \TextWithoutConditional \end{minipage}

\bigskip\hrule \toggletrue{SupressConditionalText}% Disable conditional text % With conditional text supressed, things work fine:

\begin{minipage}[t]{0.45\linewidth} \TextWithConditional \end{minipage}% \hfill\vrule\hfill% \begin{minipage}[t]{0.45\linewidth} \TextWithoutConditionalWithoutInterText \end{minipage}% \end{document}

David Carlisle
  • 757,742
  • This seems to work pretty good. But, there an extra space if used as \intertext{Albert \ConditionalText{insisted} that} for the case where the conditional text is suppressed. I will update the MWE to include this test. – Peter Grill Mar 13 '13 at 22:47
  • 1
    hmph am I allowed to patch \intertext so it resets the current environment? – David Carlisle Mar 13 '13 at 22:48
  • 1
    Huh? You are asking me? I'd say of course, but is there a reason why that should not be done? – Peter Grill Mar 13 '13 at 22:51