tabularx 中的 if else 语句

tabularx 中的 if else 语句

在下面的 MWE 中,如果语句为真,我尝试构建一个包含 6 列的表。

\documentclass{article}

\usepackage{tabularx}
\newif\iftest
\testtrue

\begin{document}

\begin{table}[t!]
    \caption{foobar}
    \label{tab: foo}

    \iftest
        \begin{tabularx}{\textwidth}{X  >{\centering}m{1.8cm} >{\centering}m{1.11cm} >{\centering}m{1.1cm} >{\centering}m{1.7cm} >{\centering}m{1.7cm}}
    \else
        \begin{tabularx}{\textwidth}{X  >{\centering}m{1.8cm} >{\centering}m{1.11cm} >{\centering}m{1.1cm} >{\centering}m{1.7cm}}
    \fi    
        \end{tabularx}
\end{table}

\end{document}

LaTeX 抱怨说有一个额外的内容。我遗漏了什么?

Extra \else.

<inserted text> ... >{\centering }m{1.7cm}} \else 
                                                  \begin {tabularx}{\textwid...
l.20         \end{tabularx}

I'm ignoring this; it doesn't match any \if.

答案1

环境tabularx实际上设置为将主体读入宏;请参阅此摘录文档(部分tabularx3和之间的区别tabular*):

环境主体tabularx实际上是命令的参数......

原因是表格被多次设置以获得正确的列宽度X,而捕获主体则允许非常轻松地多次处理它。由于主体被捕获,因此最终会得到悬空\else\fis,具体取决于\testtrue\testfalse

解决此问题的一种方法是将tabularx定义存储在宏中,并在\if...\fi构造之外调用它:

\documentclass{article}

\usepackage{tabularx}
\newif\iftest

\begin{document}

\begin{table}
  \caption{foobar}

  \iftest
    \def\begintabularx{\begin{tabularx}{\linewidth}{ X X }}
  \else
    \def\begintabularx{\begin{tabularx}{\linewidth}{ X }}
  \fi
  \begintabularx
    % Your table here
  \end{tabularx}
\end{table}

\end{document}

答案2

环境在开始工作之前tabularx会寻找终止并吸收其间的所有内容。\end{tabularx}

在您的情况下,这会使\else\fi位于表格单元格内,这是不好的,因为条件不能跨越表格单元格。

目前尚不清楚列数不同的原因是什么,但仅出于测试目的,我们假设这是有意义的。

\documentclass{article}

\usepackage{tabularx}

\newif\iftest
\makeatletter
\newcommand{\checktest}{%
  \iftest\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}
\makeatother
\testtrue

\begin{document}

\checktest{%
  \begin{tabularx}{\textwidth}{
    X
    >{\centering}m{1.8cm}
    >{\centering}m{1.11cm}
    >{\centering}m{1.1cm}
    >{\centering}m{1.7cm}
    >{\centering}m{1.7cm}
  }
}{%
  \begin{tabularx}{\textwidth}{
    X
    >{\centering}m{1.8cm}
    >{\centering}m{1.11cm}
    >{\centering}m{1.1cm}
    >{\centering}m{1.7cm}
  }
}
A & B & C & D & E \tabularnewline
A & B & C & D & E \tabularnewline
\end{tabularx}

\testfalse

\checktest{%
  \begin{tabularx}{\textwidth}{
    X
    >{\centering}m{1.8cm}
    >{\centering}m{1.11cm}
    >{\centering}m{1.1cm}
    >{\centering}m{1.7cm}
    >{\centering}m{1.7cm}
  }
}{%
  \begin{tabularx}{\textwidth}{
    X
    >{\centering}m{1.8cm}
    >{\centering}m{1.11cm}
    >{\centering}m{1.1cm}
    >{\centering}m{1.7cm}
  }
}
A & B & C & D & E \tabularnewline
A & B & C & D & E \tabularnewline
\end{tabularx}

\end{document}

这样,条件被评估 tabularx开始工作。

答案3

问题是,在 内tabularx被 ed 的环境也需要在 内被ed 。(将和语句视为括号对:它们需要以正确的顺序匹配“ ”而不是“ ”,如果您明白我的意思……)。\begin\if\end\if\begin{...}...\end{...}\if...\fi([])([)]

为了满足您的额外要求,即实际上只有一个表(而不是两个),在您的例子中,我注意到最后两列的宽度相同。因此,一种解决方案是定义\myval如果为真则值为 2 test,否则值为 1。然后您可以*{\myval}{>{\centering}m{1.7cm}}在规范中使用,tabularx这将生成最后一列的 2 个或 1 个副本。

如果您希望末尾的列宽度不同,则可能需要另一种解决方案。

\documentclass{article}

\usepackage{tabularx}
\newif\iftest
\testtrue

\newcommand\myval{\iftest2\else1\fi}
\begin{document}


\begin{table}[t!]
    \caption{foobar}
    \label{tab: foo}
        \begin{tabularx}{\textwidth}{X  >{\centering}m{1.8cm} >{\centering}m{1.11cm} >{\centering}m{1.1cm} *{\myval}{>{\centering}m{1.7cm}}}  
        1&2&3&4&5&6      
        \end{tabularx}

\end{table}

\end{document}

相关内容