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 encounter various problems when i want to control the display of a table with a ifthenelse test. For example, consider the following M(non)WE :

\documentclass{article}
\usepackage{multirow}
\usepackage{ifthen}
\newcommand{\essai}[1]{
\begin{tabular}{cc}
    a&b \\ \hline
    \ifthenelse{\equal{#1}{coucou}}{\multicolumn{2}{|c|}{oui - #1} \\ \hline}{non&#1 \\ \hline} 
\end{tabular}
}
\begin{document}
  \essai{coucou}
\end{document}

If i call \essai{hallo}, then the ifthenelse test is false, and it compiles : the second line of the table has 2 columns, as expected. If i call \essai{coucou}, then the test is true and i would expect to have a multicolumn line. But it gives a compilation error Misplaced \omit...

share|improve this question

2 Answers 2

up vote 4 down vote accepted

\multicolumn must be the first thing TeX sees in a table cell, after expanding commands; unfortunately, the workings of \ifthenelse leave something before \multicolumn when the test is computed false.

Use a different test making command: in this case, \ifboolexpe from etoolbox (notice the final "e"), might seem promising.

Unfortunately, also the way etoolbox implements the string equality test leads to unexpandable commands before TeX can see \multicolumn, so a direct approach must be used:

\documentclass{article}
\makeatletter
\newcommand{\roystreqtest}[2]{%
  \ifnum\pdfstrcmp{#1}{#2}=\z@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\makeatother
\newcommand{\essai}[1]{%
  \begin{tabular}{cc}
  a&b \\ \hline
  \roystreqtest{#1}{coucou}%
    {\multicolumn{2}{|c|}{oui - #1} \\ \hline}
    {non&#1 \\ \hline} 
  \end{tabular}%
}

\begin{document}
\essai{coucou}

\essai{noncoucou}
\end{document}

If you have to compare strings that are not made only of ASCII printable characters, it's safer to say

\newcommand{\roystreqtest}[2]{%
  \ifnum\pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=\z@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}

If you're bold, you can use an already defined infrastructure: LaTeX3 provides an expandable equality test for strings: the definition of \roystreqtest can be

\usepackage{expl3}
\ExplSyntaxOn
\cs_set_eq:NN \roystreqtest \str_if_eq:nnTF
\ExplSyntaxOff

and the rest would be the same.

share|improve this answer
    
I always wanted to learn how to use etoolbox, by i was scarred by the number of different commands, and the lack of examples in the documentation. It would help me if you could give me the synthaxe for my example (the test #1 = coucou) –  nicolas roy Jan 26 '12 at 8:20
    
thanks. Could you explain what the \z@ does ? –  nicolas roy Jan 26 '12 at 11:26
1  
After \makeatletter, one can use \z@ to represent either the constant 0 or the length 0pt. –  egreg Jan 26 '12 at 11:40
1  
It's a habit; writing 0 is good, provided a space (or end-of-line) follows it: \ifnum...=0\@firstoftwo...\fi might give unexpected results. Conversely, \z@\@firstoftwo would be safe. –  egreg Jan 26 '12 at 12:45
3  
\z@ is quicker than 0 as it's a token that is already a number and so doesn't scan ahead. "0 " scans ahead and consumes the space "0foo" scans ahead and re-inserts the f into the input. Probably these days it's not noticeable but in 1980's it could save you enough time to go for a coffee:-) –  David Carlisle Jan 26 '12 at 13:26

If you are an old timer and not using e* tools then you need to hide the conditionals from TeX's alignment scanner. This is tricky in general but if you know your test is always the first thing in a row (ie always in the first cell in a row) then you can do the tests in a \noalign and come out with a suitably defined temporary macro.

This seems to work for your example

\documentclass{article}
\usepackage{multirow}
\usepackage{ifthen}
\newcommand{\essai}[1]{
\begin{tabular}{cc}
    a&b \\ \hline
\noalign{%
    \ifthenelse{\equal{#1}{coucou}}%
        {\gdef\hmm{\multicolumn{2}{|c|}{oui - #1} \\ \hline}}%
        {\gdef\hmm{non&#1 \\ \hline}}%
}\hmm 
\end{tabular}
}
\begin{document}

  \essai{coucou}

  \essai{xoucou}


\end{document}
share|improve this answer
    
thanks you for this interesting solution. What does \noalign do exactly ? –  nicolas roy Jan 26 '12 at 12:40
2  
\noalign is a TeX primitive designed so that you can put in some vertical matter for example a paragraph that does not take part in the table, and then the table rows continue afterwards. The amsmath alignments have a command that uses noalign in this way but if you search for noalign in the latex sources (eg latex.ltx) you'll see it is used all over the place for the reason given here. It is used in processing ` \\ ` so it can handle looking for optional arguments, it's used in \hline to hide the code that looks for a following \hline again so that \multicolumn works. etc... –  David Carlisle Jan 26 '12 at 13:13

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.