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.

As there is no Expandable version of \InputIfFileExists or \IfFileExists, the question arises whether it is possible to execute non-expandable code in a tabular environment after all:

File main.tex:

\documentclass{standalone}
\usepackage{booktabs}

% How to implement this? %
\newcommand\InsideTabularInputIfFileExists[1]{...}
% How to implement this? %

% Do not change anything here %
\begin{document}
  \begin{tabular}{ll}
  \InsideTabularInputIfFileExists{inp.tex}
  \end{tabular}
\end{document}
% Do not change anything here %

File inp.tex:

\toprule
a & b \\
c & d \\
\bottomrule
share|improve this question

2 Answers 2

up vote 11 down vote accepted

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

share|improve this answer
3  
Here you can simply use \noalign\bgroup, and \egroup, rather than the more elaborate \ifnum0=`}\fi. –  Bruno Le Floch Apr 5 '12 at 10:18
    
@BrunoLeFloch: Interesting. Why is \ifnum0=`}\fi then used again in \hline etc.? I think I knew it once, but it eludes me now. –  Martin Scharrer Apr 5 '12 at 10:39
    
@MartinScharrer I guess that one of the reasons is to manage \hline\hline. –  egreg Apr 5 '12 at 10:53
2  
@egreg. Managing \hline\hline requires non-expandable lookahead, but this can be done with \noalign\bgroup... closed by \egroup in \@xhline. The only case where this lookahead is risky is \hline &: with the \bgroup version, the \futurelet picks up \outer endtemplate:, which by chance doesn't break anything. When using the \ifnum trick, TeX's master counter is non-zero when futureletting &, hence we get &, not the end-template command. This is safer (but that safety happens to be useless here). –  Bruno Le Floch Apr 5 '12 at 12:02

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.

share|improve this answer
    
Well. The problem here is that \begin{tabular} is user code and \@@input is package code. So, the % Do not change anything here % is really, really meant to be :-) –  krlmlr Apr 5 '12 at 10:34
    
@user946850 User code is what the package decides it to be. I'm convinced that using \begin{tabular}{ll}\whateverinputcommand{file}\end{tabular} is wrong user code. –  egreg Apr 5 '12 at 10:37
    
Right. But why is this wrong user code? –  krlmlr Apr 5 '12 at 10:39
    
@user946850 Because the \begin{tabular} and \end{tabular} are used where they don't belong. A "command" version allows for easier customization; for example you can redefine it to do nothing at all, which with the tabular version you can't. –  egreg Apr 5 '12 at 10:49

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.