Execute non-expandable code inside a tabular environment
It is possible to put unexpandable code in an \noalign{..}
expression. The closing }
can be added dynamically using a special trick, allowing a macro to insert code after the \noalign
if the test inside it is true.
\noalign
is used for material which should not be aligned with the tabular format, i.e. put into cells. All horizontal lines like \hline
or \toprule
are done using \noalign
. You can use these only between rows, i.e. at the beginning of a row, which is in fact the source of your original problem. However, it is possible to have multiple \noalign
s after each other.
The following defines a \NoAlignInputIfFileExists{<filename>}
which can be used as you intended, but will create an error if not used between tabular rows:
\documentclass{standalone}
\usepackage{booktabs}
\makeatletter
\newcommand*\NoAlignInputIfFileExists[1]{%
\noalign{\ifnum 0=`}\fi
\IfFileExists{#1}
{\ifnum 0=`{\fi }\@@input #1 }%
{\ifnum 0=`{\fi }}%
}
\makeatother
\begin{document}
\begin{tabular}{ll}
% must be used at the beginning of a tabular line, but
% can be mixed with other \noalign commands like \hline etc.
\NoAlignInputIfFileExists{inp}
\end{tabular}
\end{document}
To explain this advanced code a little:
The \noalign
boxes/executes its content while reading it. It doesn't read the {..}
as an argument, so it doesn't look directly for the closing }
.
Here the \noalign{\ifnum 0=`}\fi
trick is used. The }
is actually removed because the \ifnum
is false. However, the \newcommand
sees both an opening {
and closing }
so is happy to have a matching number of them. The actual closing }
for the \noalign
exists twice: once for in each if/else-clause. An \ifnum 0=`{\fi }
is used to remove the {
during the execution of \noalign
, which is again needed to be present to make the \newcommand
definition happy.
I believe that your needs can be accomplished more easily with a command, rather than with the explicit tabular
environment:
\documentclass{article}
\usepackage{booktabs}
\makeatletter
\newcommand{\tabularinput}[2]{%
\IfFileExists{#1}
{\begin{tabular}{#2}
\@@input #1
\end{tabular}}
{INEXISTENT FILE #1}%
}
\makeatother
\begin{document}
\tabularinput{inp}{ll}
\tabularinput{xxx}{ll}
\end{document}
An "environment" version, which I don't recommend, can be a modified version of Martin's code:
\makeatletter
\newcommand{\expinput}[1]{%
\noalign{
\IfFileExists{#1}
{\gdef\expinput@temp{\@@input #1 }}
{\gdef\expinput@temp{INEXISTENT FILE #1}}
}\expinput@temp}
\makeatother
but I can't see how
\begin{tabular}{ll}
\expinput{inp}
\end{tabular}
is preferable to \tabularinput{inp}{ll}
, unless the \input
thing is only part of the tabular.