TransWikia.com

problem with ifthenelse + multicolumn

TeX - LaTeX Asked by nicolas roy on February 20, 2021

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...

4 Answers

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]{%
  ifnumpdfstrcmp{#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]{%
  ifnumpdfstrcmp{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.

Correct answer by egreg on February 20, 2021

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}}%
        {gdefhmm{multicolumn{2}{|c|}{oui - #1}  hline}}%
        {gdefhmm{non&#1  hline}}%
}hmm 
end{tabular}
}
begin{document}

  essai{coucou}

  essai{xoucou}


end{document}

Answered by David Carlisle on February 20, 2021

You can do your tests outside the table:

ifthenelse{boolean{expr}}
    {gdeftemp{multicolumn{...}}}
    {gdeftemp{something else}}
...
begin{tabular}{..}
...
temp
...

Answered by Yura Polyachenko on February 20, 2021

The environment {NiceTabular} of nicematrix provides a command Block which gives features similar to multicolumn and multirow.

There is no problem using Block inside ifthenelse.

documentclass{article}
usepackage{ifthen}
usepackage{nicematrix}

newcommand{essai}[1]{
begin{NiceTabular}{cc}
    text & text  hline
    ifthenelse{equal{#1}{coucou}}{Block{1-2}{oui - #1}  hline} {non&#1  hline} 
end{NiceTabular}
}
begin{document}
  essai{coucou}
end{document}

Answered by F. Pantigny on February 20, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP