2

The following gets me this error

! Incomplete \iffalse; all text was ignored after line 26.

So, how to make \if work inside the table stored in the macro \MyTable?

\newif\ifShowRow
\ShowRowfalse

\begin{filecontents*}[overwrite]{mytable.tex}
    1  &   2  \\
    3  &   4  \\
    \ifShowRow
    5  &   6  \\
    \fi
    7  &   8  \\
    9  &  10  \\
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile, tabularray}
\UseTblrLibrary{siunitx}

\begin{document}
    
    \CatchFileDef{\MyTable}{mytable.tex}{}
    
    \begin{tblr}[ long, expand = \MyTable ]{ colspec = {X S} }
        One & {{{Two}}}  \\
        \MyTable
    \end{tblr}
    
\end{document}

Update

Adopting this answer, I couldn't manage to make the code below work


\newif\ifShowRow
\ShowRowfalse

\begin{filecontents*}[overwrite]{mytable.tex}
    1  &   2  \\
    % https://tex.stackexchange.com/a/58627/2288
    \ifthenelse{\boolean{ShowRow}}{ 3 & 4 \\ 5 & 6 \\ }{ 7 & 8 \\ 9 & 10 \\}
    9  &  10  \\
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile, tabularray, xifthen}
\UseTblrLibrary{siunitx}

\begin{document}
    
    \CatchFileDef{\MyTable}{mytable.tex}{}
    
    \begin{tblr}[ long, expand = \MyTable ]{ colspec = {X S} }
        One & {{{Two}}}  \\
        \MyTable
    \end{tblr}
    
\end{document}
4
  • catchfile has no role whatsoever. Just define \MyTable normally and you'll see the same behavior.
    – egreg
    Nov 15, 2021 at 23:21
  • I have quite a bit of conditionals in my tables and eventually gave up on this kind of approach (using conditionals in the body of tabular). I now create the tabular content conditionally via \AddTableTokens and \eAddTableTokens as mentioned at Build tabular content via \foreach. This may be overkill for your situation do didn't want to post an answer using that. If you are interested in that approach and have difficulty adapting the macros in the linked question, I can post an answer here. Nov 16, 2021 at 6:27
  • @PeterGrill I would be grateful if you showed me how to do so for a chunk of multiple rows but in the simplest :) and the closest possible way to my MWE since I am just a regular user not TeXpert. Thanks
    – Diaa
    Nov 16, 2021 at 7:44
  • @user202729 Thanks for the suggestion; done
    – Diaa
    Nov 18, 2021 at 4:28

2 Answers 2

3

Environments coming from the package tabularray parse their "bodies" for the scaffold/the framework of the table. Seems the parsing-routines "expect" the tokens forming the scaffold/framework of the table to be present in the environment-body as is. Seems the parsing-routines "expect" not to need to obtain these tokens by having carried out in whatsoever way things that come from the "bodies" of these environments.

Expansion is one way/one concept of carrying out things in TeX.

In order to have a bit of expansion-support while that parsing is done, with recent releases of the tabularray-package the expand=...-key is provided, but that in turn implies that tokens provided as value of that key must be fully expandable.
But \ifthenelse is not fully expandable.
\ifthenelse is a macro which, beneath other things, yields tokens that are intended to trigger the performing of temporary assignments/to trigger the (re)defining of temporary macros/scratch-macros.
TeX does not carry out assignments in the stage of expansion but it does so in a later stage of its "digestive processes".
Using Donald E. Knuth's analogy of TeX being a beast with eyes and a digestive tract, expansion takes place in the gullet and assignments are carried out in the stomach, when expansion is already done.

With environments coming from the package tabularray a lot of parsing-work for detecting the scaffold/framework of the table is done by means of "internal" routines provided by the package. Tokens coming from the body of the environment and forming arguments of these internal routines do not get expanded for further examination. They are not carried out in whatsoever way. Unless they occur as value of the expand=...-key. Seems in this case triggering one step of expansion is the only way of "carrying out" which is possible. Performing assignments is not possible.

I used the phrase "one step of expansion" because usually in TeX's gullet expansion is a "process of regurgitation". I.e., if expanding an expandable token yields another expandable token now being the first token of the token-stream, that other expandable token will be expanded, too. Seems with the expand=...-key that regurgitation does not take place. You just get that other expandable token and that's it.

But you can easily establish "regurgitation":

As a trick you can trigger expansion of \romannumeral using expand = \romannumeral and (ab?)use \romannumeral-expansion for triggering a lot of expansion-work.

The gist of \romannumeral-expansion is:

\romannumeral gathers tokens until (either) having gathered a set of tokens that form a valid TeX-⟨number⟩-quantity (or seeing the need of raising an error-message). Expandable tokens are expanded while gathering.
In case the TeX-⟨number⟩-quantity does denote an integer which is positive, you get explicit character-tokens of category 12(other) that form the representation in lowercase roman numerals of the value currently represented by that TeX-⟨number⟩-quantity.
In case the TeX-⟨number⟩-quantity does denote an integer which is not positive, the tokens forming that TeX-⟨number⟩-quantity are silently discarded without whatsoever (disturbing error-)message and without TeX returning any tokens.

The latter case is more interesting for our purposes:
You can (ab?)use \romannumeral for triggering TeX to do a lot of (macro-)expansion-work (="token-replacing"-work) and "exchanging-tokens-in-the-token-stream"-work/"flipping-tokens-around-in-the-token-stream"-work as long as it is ensured that after all this expansion- and exchanging-/flipping-work the very next token in the token-stream is a TeX-⟨number⟩-quantity denoting an integer whose value is not positive.

In the example below for providing the TeX-⟨number⟩-quantity denoting an integer whose value is not positive I use the token \stopexpansion, defined as \chardef\stopexpansion=`\^^00. \stopexpansion is a \chardef-token and in the context of gathering a TeX-⟨number⟩-quantity is assumed to denote the value "0" which is not positive. TeX's rules for gathering a TeX-⟨number⟩-quantity say that no optional trailing spaces or whatever will be discarded when the TeX-⟨number⟩-quantity in question is formed by a \chardef-token. Besides this \stopexpansion is also a control-word-token and therefore is not affected by things like \uppercase or \lowercase.

In the example below, for triggering expansion I actually use \romannumeral. But I use it as a token \startexpansion which via \let is made equal to \romannumeral.

Besides this with tables in general you need to ensure that things like & and \\ are nested in curly braces until the very last step of expansion is done, whereafter only those tokens remain that should actually form the framework/scaffold of the table.
Otherwise TeX's own mechanisms for parsing/detecting the framework/scaffold of a table might intercept expansion and take things for the content of a table-cell that actually should be removed by expansion.
You can do this, e.g., by passing things as brace-nested macro-arguments, e.g., for \@firstoftwo or \@secondoftwo.
(\@firstoftwo is a macro of the LaTeX 2ε-kernel which picks the first of two undelimited/brace-nested arguments.
\@secondoftwo is a macro of the LaTeX 2ε-kernel which picks the second of two undelimited/brace-nested arguments.)

\makeatletter
\@ifdefinable\startexpansion{\let\startexpansion=\romannumeral}%
\@ifdefinable\stopexpansion{\chardef\stopexpansion=`\^^00}%
\newcommand\ExpandableConditionCheckTrueFalse[1]{%
  \csname if#1\endcsname\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}%
\makeatother

\newif\ifShowRow
\ShowRowfalse
%\ShowRowtrue


\begin{filecontents*}[overwrite]{mytable.tex}
    1  &  2  \\
    \startexpansion
    \ExpandableConditionCheckTrueFalse{ShowRow}%
                                      {\stopexpansion 3 & 4 \\ 5 & 6 \\ }%
                                      {\stopexpansion 7 & 8 \\ 9 & 10 \\}%
    11  &  12  \\
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile, tabularray}

\UseTblrLibrary{siunitx}

\begin{document}
    
    \CatchFileDef{\MyTable}{mytable.tex}{}

    \begin{tblr}[ long, expand = \startexpansion ]{ colspec = {X S} }
        One & {{{Two}}}  \\
        \startexpansion\expandafter\stopexpansion\MyTable
    \end{tblr}
    
\end{document}

enter image description here



If you like you can place \stopexpansion into the definition-text of \ExpandableConditionCheckTrueFalse.

Then the syntax of \ExpandableConditionCheckTrueFalse in any case, also outside tabularray-environments, is
\startexpansion\ExpandableConditionCheckTrueFalse{<name of \if-switch without leading "if">}{<true code>}{<false code>}.

I.e., \ExpandableConditionCheckTrueFalse must always be preceded by \startexpansion (or by \romannumeral).

(By the way: I decided for ⟨name of \if-switch without leading "if"⟩ instead of providing the \if..-token directly because this way you won't have unbalanced \if..-tokens on toplevel of your code. Otherwise you would have to write things like

\ExpandableConditionCheckTrueFalse{\ifShowRow}{<true code>}{<false code>}%

Here \ifShowRow is not balanced by \fi which can cause trouble when embedded in surrounding \if..-\else-\fi-expressions because \if..-\else-\fi-nesting is independent from any kind of group-nesting, i.e., is independent from brace-group-nesting also.)

\makeatletter
\@ifdefinable\startexpansion{\let\startexpansion=\romannumeral}%
\@ifdefinable\stopexpansion{\chardef\stopexpansion=`\^^00}%
\newcommand\ExpandableConditionCheckTrueFalse[1]{%
  \csname if#1\endcsname
  \expandafter\expandafter\expandafter\stopexpansion\expandafter\@firstoftwo
  \else
  \expandafter\expandafter\expandafter\stopexpansion\expandafter\@secondoftwo
  \fi
}%
\makeatother

\newif\ifShowRow
\ShowRowfalse
%\ShowRowtrue


\begin{filecontents*}[overwrite]{mytable.tex}
    1  &  2  \\
    \startexpansion
    \ExpandableConditionCheckTrueFalse{ShowRow}%
                                      {3 & 4 \\ 5 & 6 \\ }%
                                      {7 & 8 \\ 9 & 10 \\}%
    11  &  12  \\
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile, tabularray}

\UseTblrLibrary{siunitx}

\begin{document}
    
    \CatchFileDef{\MyTable}{mytable.tex}{}

    \begin{tblr}[ long, expand = \startexpansion ]{ colspec = {X S} }
        One & {{{Two}}}  \\
        \startexpansion\expandafter\stopexpansion\MyTable
    \end{tblr}
    
\end{document}

I cannot recommend "hiding" \startexpansion within another macro.

Currently expand =... will be applied to one token only.

I.e., with \begin{tblr}[expand = \foo, expand = \bar ] the directive expand = \bar will override the directive expand = \foo and only expansion of \bar will be triggered while parsing the body of the environment.

When "hiding" \startexpansion within another macro, then you would need to apply expand=<that other macro-token wherein \startexpansion is hidden> which would

  • leave you with the top-level expansion of that macro not being expanded further and
  • annihilate a preceding expand=\startexpansion. I.e., you could not use \startexpansion any more for triggering expansion of other things. E.g., you would not have means for triggering the expansion of the macro defined via \CatchFileDef.

But I can give you a macro for better expansion-control and avoiding large chains of \expandafter:

%%----------------------------------------------------------------------
%% \startexpansion\Expandsteps{<number K>}<tokens>
%%  ->   <tokens> will be hit by \expandafter K times.
%%----------------------------------------------------------------------
\@ifdefinable\UD@innerdfork{\def\UD@innerdfork#1d#2#3dd{#2}}%
\newcommand*\UD@dfork[1]{%
  \UD@innerdfork#1{\@firstoftwo}d{\@secondoftwo}dd%
}%
\newcommand*\Expandsteps[1]{%
  \expandafter\UD@innerExp\expandafter{\expandafter}%
  \romannumeral\number\number#1 000d%
}%
\newcommand*\UD@innerExp[2]{%
  \UD@dfork{#2}{#1\stopexpansion}{\UD@innerExp{#1#1\expandafter}}%
}%

Here is how it could be integrated into a MWE:

\makeatletter
\@ifdefinable\startexpansion{\let\startexpansion=\romannumeral}%
\@ifdefinable\stopexpansion{\chardef\stopexpansion=`\^^00}%
\newcommand\ExpandableConditionCheckTrueFalse[1]{%
  \csname if#1\endcsname\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}%
%%----------------------------------------------------------------------
%% \startexpansion\Expandsteps{<number K>}<tokens>
%%  ->   <tokens> will be hit by \expandafter K times.
%%----------------------------------------------------------------------
\@ifdefinable\UD@innerdfork{\def\UD@innerdfork#1d#2#3dd{#2}}%
\newcommand*\UD@dfork[1]{%
  \UD@innerdfork#1{\@firstoftwo}d{\@secondoftwo}dd%
}%
\newcommand*\Expandsteps[1]{%
  \expandafter\UD@innerExp\expandafter{\expandafter}%
  \romannumeral\number\number#1 000d%
}%
\newcommand*\UD@innerExp[2]{%
  \UD@dfork{#2}{#1\stopexpansion}{\UD@innerExp{#1#1\expandafter}}%
}%
\makeatother

\newif\ifShowRow
\ShowRowfalse
%\ShowRowtrue


\begin{filecontents*}[overwrite]{mytable.tex}
    1  &  2  \\
    \startexpansion\Expandsteps{5}%
    % 5 expansion-steps are needed:
    %   1st step expands  `\ExpandableConditionCheckTrueFalse`.
    %   2nd step expands  `\csname if<foobar>\endcsname`. This yields a token `\if<foobar>`.
    %   3rd step expands the token `\if<foobar>`.
    %      In case condition is true this leads to removal of 
    %      the token `\if<foobar>`.
    %      In case condition is false this leads to removal of 
    %      the entire true-branch and `\else`.
    %   4th step:
    %      In case condition is true this expands `\expandafter` before 
    %      `\@firstoftwo` which in turn expands `\else` behind `\@firstoftwo` 
    %      which leads to removal of the entire `\else-branch and 
    %      the `\fi`.
    %      In case condition is false this expands `\expandafter` before 
    %      `\@secondoftwo` which in turn expands `\fi` behind `\@secondoftwo`
    %      which leads to removal of `\fi`.
    %   5th step:
    %      In case condition is true this expands the remaining `\@firstoftwo`.
    %      In case condition is false this expands the remaining `\@secondoftwo`.
    \ExpandableConditionCheckTrueFalse{ShowRow}%
                                      {3 & 4 \\ 5 & 6 \\ }%
                                      {7 & 8 \\ 9 & 10 \\}%
    11  &  12  \\
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile, tabularray}

\UseTblrLibrary{siunitx}

\begin{document}
    
    \CatchFileDef{\MyTable}{mytable.tex}{}

    \begin{tblr}[ long, expand = \startexpansion ]{ colspec = {X S} }
        One & {{{Two}}}  \\
        \startexpansion\expandafter\stopexpansion\MyTable
        %\startexpansion\Expandsteps{1}\MyTable
    \end{tblr}
    
\end{document}

If you wish, you can hardcode \Expandsteps into \ExpandableConditionCheckTrueFalse—if you do that, then, like with hardcoding \stopexpansion into \ExpandableConditionCheckTrueFalse, each instance of \ExpandableConditionCheckTrueFalse needs to be preceded by \startexpansion. So when it comes to nesting, a smaller amount of expansion-steps needs to be triggered as each \startexpansion itself will trigger some more, but the token \startexpansion needs to be provided more often:

\makeatletter
\@ifdefinable\startexpansion{\let\startexpansion=\romannumeral}%
\@ifdefinable\stopexpansion{\chardef\stopexpansion=`\^^00}%
\newcommand\ExpandableConditionCheckTrueFalse[1]{%
  \Expandsteps{4}%
      % 4 expansion-steps are needed:
      %   1st step expands  \csname if<foobar>\endcsname. This yields a token \if<foobar>.
      %   2nd step expands the token \if<foobar>.
      %   3rd step expands \expandafter before \@firstoftwo/\@secondoftwo.
      %   4th step expands \@firstoftwo/\@secondoftwo.
  \csname if#1\endcsname\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}%
%%----------------------------------------------------------------------
%% \startexpansion\Expandsteps{<number K>}<tokens>
%%  ->   <tokens> will be hit by \expandafter K times.
%%----------------------------------------------------------------------
\@ifdefinable\UD@innerdfork{\def\UD@innerdfork#1d#2#3dd{#2}}%
\newcommand*\UD@dfork[1]{%
  \UD@innerdfork#1{\@firstoftwo}d{\@secondoftwo}dd%
}%
\newcommand*\Expandsteps[1]{%
  \expandafter\UD@innerExp\expandafter{\expandafter}%
  \romannumeral\number\number#1 000d%
}%
\newcommand*\UD@innerExp[2]{%
  \UD@dfork{#2}{#1\stopexpansion}{\UD@innerExp{#1#1\expandafter}}%
}%
\makeatother

\newif\ifShowRow
\ShowRowfalse
%\ShowRowtrue


\begin{filecontents*}[overwrite]{mytable.tex}
    1  &  2  \\
    \startexpansion % \startexpansion triggers expansion until finding \stopexpansion.
                    % So \startexpansion triggers expansion of \ExpandableConditionCheckTrueFalse
                    % which in turn internally uses `\Expandsteps` which in turn after the amount
                    % of expansion-steps needed delivers \stopexpansion.
    \ExpandableConditionCheckTrueFalse{ShowRow}%
                                      {3 & 4 \\ 5 & 6 \\ }%
                                      {7 & 8 \\ 9 & 10 \\}%
    11  &  12  \\
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile, tabularray}

\UseTblrLibrary{siunitx}

\newif\iffoo\footrue
\newif\ifbar\bartrue

\begin{document}
    
    \CatchFileDef{\MyTable}{mytable.tex}{}

    \begin{tblr}[ long, expand = \startexpansion ]{ colspec = {X S} }
       \startexpansion\Expandsteps{2}% <- Just some example of controlling expansion when nesting \ExpandableConditionCheckTrueFalse:
       \startexpansion\ExpandableConditionCheckTrueFalse{foo}{%
                                                \startexpansion
                                                \ExpandableConditionCheckTrueFalse{bar}{One footrue/bartrue & {{{Two footrue/bartrue}}}}%
                                                                                       {One footrue/barfalse & {{{Two footrue/barfalse}}}}%
                                              }%
                                              {%
                                                \startexpansion
                                                \ExpandableConditionCheckTrueFalse{bar}{One foofalse/bartrue & {{{Two foofalse/bartrue}}}}%
                                                                                       {One foofalse/barfalse & {{{Two foofalse/barfalse}}}}%
                                              }%
        \\
        \startexpansion\Expandsteps{1}\MyTable
    \end{tblr}
    
\end{document}

If you don't hardcode \Expandsteps or \stopexpansion into \ExpandableConditionCheckTrueFalse you need to specify more expansion-steps but you don't need \startexpansion so often:

\makeatletter
\@ifdefinable\startexpansion{\let\startexpansion=\romannumeral}%
\@ifdefinable\stopexpansion{\chardef\stopexpansion=`\^^00}%
\newcommand\ExpandableConditionCheckTrueFalse[1]{%
  \csname if#1\endcsname\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}%
%%----------------------------------------------------------------------
%% \startexpansion\Expandsteps{<number K>}<tokens>
%%  ->   <tokens> will be hit by \expandafter K times.
%%----------------------------------------------------------------------
\@ifdefinable\UD@innerdfork{\def\UD@innerdfork#1d#2#3dd{#2}}%
\newcommand*\UD@dfork[1]{%
  \UD@innerdfork#1{\@firstoftwo}d{\@secondoftwo}dd%
}%
\newcommand*\Expandsteps[1]{%
  \expandafter\UD@innerExp\expandafter{\expandafter}%
  \romannumeral\number\number#1 000d%
}%
\newcommand*\UD@innerExp[2]{%
  \UD@dfork{#2}{#1\stopexpansion}{\UD@innerExp{#1#1\expandafter}}%
}%
\makeatother

\newif\ifShowRow
\ShowRowfalse
%\ShowRowtrue


\begin{filecontents*}[overwrite]{mytable.tex}
    1  &  2  \\
    \startexpansion % \startexpansion triggers expansion until finding \stopexpansion.
    \ExpandableConditionCheckTrueFalse{ShowRow}%
                                      {\stopexpansion 3 & 4 \\ 5 & 6 \\ }%
                                      {\stopexpansion 7 & 8 \\ 9 & 10 \\}%
    11  &  12  \\
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile, tabularray}

\UseTblrLibrary{siunitx}

\newif\iffoo\footrue
\newif\ifbar\bartrue

\begin{document}
    
    \CatchFileDef{\MyTable}{mytable.tex}{}

    \begin{tblr}[ long, expand = \startexpansion ]{ colspec = {X S} }
       \startexpansion\Expandsteps{10}% <- Just some example of controlling expansion when nesting \ExpandableConditionCheckTrueFalse:
       \ExpandableConditionCheckTrueFalse{foo}{%
                                                \ExpandableConditionCheckTrueFalse{bar}{One footrue/bartrue & {{{Two footrue/bartrue}}}}%
                                                                                       {One footrue/barfalse & {{{Two footrue/barfalse}}}}%
                                              }%
                                              {%
                                                \ExpandableConditionCheckTrueFalse{bar}{One foofalse/bartrue & {{{Two foofalse/bartrue}}}}%
                                                                                       {One foofalse/barfalse & {{{Two foofalse/barfalse}}}}%
                                              }%
        \\
        \startexpansion\Expandsteps{1}\MyTable
    \end{tblr}
    
\end{document}

If you don't want to keep track of the amount of expansion-steps just don't hardcode things and instead place \stopexpansion as first token of each final branch:

\makeatletter
\@ifdefinable\startexpansion{\let\startexpansion=\romannumeral}%
\@ifdefinable\stopexpansion{\chardef\stopexpansion=`\^^00}%
\newcommand\ExpandableConditionCheckTrueFalse[1]{%
  \csname if#1\endcsname\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}%

\makeatother

\newif\ifShowRow
\ShowRowfalse
%\ShowRowtrue


\begin{filecontents*}[overwrite]{mytable.tex}
    1  &  2  \\
    \startexpansion % \startexpansion triggers expansion until finding \stopexpansion.
    \ExpandableConditionCheckTrueFalse{ShowRow}%
                                      {\stopexpansion 3 & 4 \\ 5 & 6 \\ }%
                                      {\stopexpansion 7 & 8 \\ 9 & 10 \\}%
    11  &  12  \\
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile, tabularray}

\UseTblrLibrary{siunitx}

\newif\iffoo\footrue
\newif\ifbar\bartrue

\begin{document}
    
    \CatchFileDef{\MyTable}{mytable.tex}{}

    \begin{tblr}[ long, expand = \startexpansion ]{ colspec = {X S} }
       \startexpansion
       \ExpandableConditionCheckTrueFalse{foo}{%
                                                \ExpandableConditionCheckTrueFalse{bar}{\stopexpansion One footrue/bartrue & {{{Two footrue/bartrue}}}}%
                                                                                       {\stopexpansion One footrue/barfalse & {{{Two footrue/barfalse}}}}%
                                              }%
                                              {%
                                                \ExpandableConditionCheckTrueFalse{bar}{\stopexpansion One foofalse/bartrue & {{{Two foofalse/bartrue}}}}%
                                                                                       {\stopexpansion One foofalse/barfalse & {{{Two foofalse/barfalse}}}}%
                                              }%
        \\
        \startexpansion\expandafter\stopexpansion\MyTable
    \end{tblr}
    
\end{document}
16
  • Your answer is so encyclopedic that I need to reread it many times to understand it. Thanks for your time and effort you put into it. I will test it, then get back later.
    – Diaa
    Nov 17, 2021 at 20:36
  • Yes, I did upvote your answer because I tested it quickly, and it did the job perfectly. I just need to reread it many times since I am not familiar at all with what happens under the hood in the tex core domain despite the decade I have been using latex in XD.
    – Diaa
    Nov 17, 2021 at 20:53
  • I am sorry for asking this naive question: is it possible to make \stopexpansion for both true and false cases buried into the definition of \ExpandableConditionCheckTrueFalse (instead of writing it at the start of every case) so that I reduce the code awareness and the visual clutter a little bit for longer tables with more rows? If possible, I hope to do the same with \startexpansion that is written before \Expandable...
    – Diaa
    Nov 17, 2021 at 21:17
  • @Diaa Yes, hiding \stopexpansion is possible. But then -- e.g. outside tabularray-environments-- you can't use \ExpandableConditionCheckTrueFalse without preceding \startexpansion. I just added an example to my answer. But it seems you can't hide \startexpansion because it seems tabularray-environments process/expand only one of the tokens given as expand=.... If you hide \startexpansion, the macro wherein it is hidden needs to be expand=..... But this leaves you with the top-level-expansion of that macro. And you have no means for calling the macro defined via \catchfiledef. Nov 17, 2021 at 22:25
  • I highly appreciate your immaculate edits and the comprehensive explanation. One final question: if the expansion steps are always five, why don't you make the number of expansion steps argument optional with a default value of five in the definition of \Expandable...? Or even why don't you hard-code it in the definition of \Expandable... without asking for the number of expansion steps from the user? Are there cases I need to make it different than five?
    – Diaa
    Nov 18, 2021 at 4:16
4

One way to achive conditional tables is to accumulate the table data separately from typesetting the table:

o \ResetTableTokens to clear any previously defined table,

o \AddTableTokens{} to build that table data based on the appropriate conditions. For instance

\ifShowRow
    \AddTableTokens{5  &  6 \\}%
\fi

o \PrintTableTokens to print the table data in a table.

With \ShowRowfalse, this yields

enter image description here

References:

Notes:

  • The booktabs package as I consider that a must have for tables. If you are not familiar with this pacakge please do have a look.

Code:

\documentclass{article}

\usepackage{booktabs}% Better tabbles

%% Based on:
%%     https://tex.stackexchange.com/q/175568/4301
%%     https://tex.stackexchange.com/q/165126/4301
%%
\newcommand*{\MyTempTableTokens}{}%
\makeatletter
    \newtoks\@tabtoks
    %%% assignments to \@tabtoks must be global, because they are done in \foreach
    \newcommand\AddTableTokens[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
    \newcommand\eAddTableTokens[1]{% 
        \protected@edef\MyTempTableTokens{#1}%
        \expandafter\AddTableTokens\expandafter{\MyTempTableTokens}%
    }
    %%% variable should always be operated on always locally or always globally
    \newcommand*\ResetTableTokens{\global\@tabtoks{}}
    \newcommand*\PrintTableTokens{\the\@tabtoks}
\makeatother

\newif\ifShowRow
\ShowRowfalse


\begin{document}
    % --------------------------- Build Table
    \ResetTableTokens%
    \AddTableTokens{1  &  2 \\}%
    \AddTableTokens{3  &  4 \\}%
    \ifShowRow
        \AddTableTokens{5  &  6 \\}%
    \fi
    \AddTableTokens{7  &  8 \\}%
    \AddTableTokens{9  & 10 \\}%
    % --------------------------- Typeset Table
    \begin{tabular}{cc}
        \multicolumn{2}{c}{Heading} \\
        \cmidrule{1-2}
        \PrintTableTokens
        \bottomrule
    \end{tabular}%
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .