5

I created an if true/false \newif\ifdetail with the hope of using this inside a \begin{align}...\end{align} environment. The goal is, I'm converting my old hand-written derivations to tex, and wanted to be able to flip a macro in order to show or hide all the intermediate steps of the derivation (example, hide details in main text and put all the details in an appendix by changing the true/false declaration either in different files, or when putting the details in an appendix etc).

My attempt so far fails (below). Does anyone have a working solution to such a set up? The use of align and/or eqnarray are essential for multi-line equations.

When I try to get this to work inside an align, I can either get the false or true version to work (by wrapping the conditional with {} in the former case, but not both simultaneously. It seems align is doing some things that conflict with this simplistic \newif as it causes compilation errors. I have two minimal-working-examples (MWEs) that demonstrate these two cases.

% This MWE compiles 
% true:  compiles
% false: fails
\documentclass{article}
\usepackage{amsmath}

% new if true/false
\newif\ifdetail
% set it to true, this works
%\let\ifdetail\iftrue

% set it to false, this fails
\let\ifdetail\iffalse

\begin{document}

\begin{align}
a &=b 
\ifdetail
\nonumber\\&=
\textrm{intermediate step}
\fi
\nonumber\\&=
\textrm{final answer}
\end{align}


\end{document}
% This MWE compiles  - notice the extra {} surrounding the {\ifdetail...\fi}
% true:  fails
% false: compiles
\documentclass{article}
\usepackage{amsmath}

% new if true/false
\newif\ifdetail
% set it to true, this works
\let\ifdetail\iftrue

% set it to false, this fails
%\let\ifdetail\iffalse

\begin{document}

\begin{align}
a &=b
{\ifdetail
\nonumber\\&=
\textrm{intermediate step}
\fi}
\nonumber\\&=
\textrm{final answer}
\end{align}


\end{document}
4

I have to hide the conditional code from align by keeping it in a group (argument), until the last minute.

So in the align block, I call on \testifdetail with the conditional code as an argument (key: in braces). Then \testifdetail performs the \if test, but still shields the argument by invoking a call to \testifdetailaux only \ifdetail is true, and then by way of argument (again, in braces).

Finally, clear of the align search logic, \testifdetailaux is able to spit out the result directly into the align block.

% This MWE compiles 
% true:  compiles
% false: fails
\documentclass{article}
\usepackage{amsmath}

% new if true/false
\newif\ifdetail
% set it to true, this works
\detailtrue

% set it to false, this fails
%\detailfalse

\newcommand\testifdetail[1]{\ifdetail\testifdetailaux{#1}\fi}
\newcommand\testifdetailaux[1]{#1}

\begin{document}

\begin{align}
a &=b 
\testifdetail
{\nonumber\\&=
\textrm{intermediate step}
}
\nonumber\\&=
\textrm{final answer}
\end{align}

\detailfalse

\begin{align}
a &=b 
\testifdetail
{\nonumber\\&=
\textrm{intermediate step}
}
\nonumber\\&=
\textrm{final answer}
\end{align}


\end{document}

enter image description here

2
  • I'm impressed how quickly you answered also :) Tested and accepted as correct! – walkloud Apr 13 at 19:58
  • @walkloud Thanks, though in honesty, it took several attempts to get it to work properly. Welcome to the site. You now have enough reputation to upvote. Congratulations! – Steven B. Segletes Apr 13 at 20:02
3

This has something to do with where you put the line breaks. Additionally, this is not a align specific problem: if you do a similar version of your code using straight-up tabular, you get exactly the same error message. But if you move the line breaks the way I do, you are okay.

The following code works for both \detailtrue and \detailfalse; all I did is move the \nonumber\\ around.

\documentclass{article}
\usepackage{amsmath}

% new if true/false
\newif\ifdetail
\detailtrue

\begin{document}

\begin{align}
a &=b \nonumber \\
\ifdetail
&=
\textrm{intermediate step} \nonumber\\
\fi
&=
\textrm{final answer}
\end{align}
\end{document}

For the benefit of smarter wizards: the same problem as reported by the OP shows up in

\documentclass{article}

\newif\ifdetails
\detailstrue

\begin{document}
\begin{tabular}{cc}
        a & 1 
        \ifdetails
        \\ b & 2 \\
        c & 3 \\
        d & 4 
        \fi
        \\ e & 5
\end{tabular}
\end{document}

but all works well with

\documentclass{article}

\newif\ifdetails
\detailsfalse

\begin{document}
\begin{tabular}{cc}
        a & 1 \\
        \ifdetails
        b & 2 \\
        c & 3 \\
        d & 4 \\
        \fi
        e & 5
\end{tabular}
\end{document}
1
  • 1
    TeX keeps track of the unbraced & tokens. – egreg Apr 13 at 21:02
3

When a conditional (\ifdetails in your example) starts inside the \halign item after first non-expadable token, then following tokens are put to the input queue until the & or \cr (in LaTeX it is \\) occurs. Then the input queue follows by the second part of column declaration data finalized by \endtemplate which is un-skippable by \if...\fi couple, so error arises. This is your example which can be simplify by this example:

\halign{x#y\cr
   a\iffalse b \cr
   c\fi \cr
}

The \iffalse here skips b but then \cr is replaced by the second part of column data (i.e. y) followed by \endtemplate, so we have error.

The working examples shown by Steven Segletes is based on the fact, that his conditionals start at the beginning of the template (spaces are ignored and tokens are expanded at this state, because TeX tries to find the \omit primitive). The & and \cr are not replaced by the second part of column data in this state. So, they are skipable by the conditional. The example can be simplify by:

\halign{x#y\cr
  \iffalse b \cr
  \fi c \cr
}

Universal principle, how to skip a part of table data, is based on the fact, that TeX allow to read \cr or & into a macro parameter (without replacing them by second part of the column data), if it is processed at inside-braces level. This feature is implemented because TeX allows to do \matrix{} in \matrix{}, for example. It means that this works:

\def\ignore#1{}
\halign{x#y\cr
  a\ignore{ b \cr
  c} \cr
}

Your example should be solved by following code:

\def\ignore#1{} \def\use#1{#1}
\let\process=\ignore   %
%\let\process=\use     % select, what you want

and use it in your aligning macro (which is nothing other than \halign primitive):

\begin{align}
a &=b 
\process{%
   \nonumber\\&=
   \textrm{intermediate step}
}
\nonumber\\&=
\textrm{final answer}
\end{align}

See also TeXbook, page 248.

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.