6

Suppose I want to build a table which looks as follows:

\begin{tabular}{ccc}  
 1.23 & 2.98 & Apple \\  
-3.78 & 4.01 & Banana \\  
\end{tabular}

However, the numbers in the table are given in a separate text file, say "file.txt", with the content

1.23 & 2.98
-3.78 & 4.01

Is there a simple way to input the cells from "file.txt" into a larger table? I tried

\begin{tabular}{ccc}
\input{file.txt} & \multirow{2}{*}{Apple \\ Banana} \\
\end{tabular}

but this fails (unsurprisingly). I also tried to use minipages - this works in the above toy example but fails in more realistic ones (most importantly, I could not align inputs from different files).

Any comments/suggestions welcome!

EDIT Here's a MWE. The file "file.txt" is as mentioned above. "file2.txt" has the following contents:

1.23 & 2.98 \\
-3.78 & 4.01 \\

(obviously, both "file.txt" and "file2.txt" should be saved in the directory of the tex file). Code for MWE:

\documentclass{article}
\usepackage{multirow}

\begin{document}

% Approach using minipage (works, but looks ugly)
\begin{minipage}{0.4\textwidth}
\begin{tabular}{cc}
\input{file2.txt} 
\end{tabular}
\end{minipage}
\begin{minipage}{0.2\textwidth}
\begin{tabular}{c}
Apple \\ Banana
\end{tabular}
\end{minipage}

% Approach mentioned above (fails)
\begin{tabular}{ccc}
\input{file.txt} & \multirow{2}{*}{Apple \\ Banana} \\
\end{tabular}

\end{document}
Fabian
  • 163
  • How does this fails, what is the error? Isn't that question a duplicate of Split table into multiple files with \input ? – Clément Jul 08 '14 at 13:15
  • Thanks for the link -- there, an input file corresponds to a complete table row (e.g. "1.23 & 2.98 & Apple \" in the example above). My case seems more complicated, since the input file spans several rows and columns. PS: The errors I get read 1) "Extra alignment tab has been changed to \cr \input{file.txt} & " and 2) "Something's wrong--perhaps a missing \item. ...e.txt} & \multirow{2}{*}{Apples\Bananas}" – Fabian Jul 08 '14 at 13:30
  • Welcome to TeX.SX! Please help us to help you and add a minimal working example (MWE) that illustrates your problem. It will be much easier for us to reproduce your situation and find out what the issue is when we see compilable code, starting with \documentclass{...} and ending with \end{document}. –  Jul 08 '14 at 13:33
  • Please make a complete document so people can run the code, the error you show is as expected and unrelated to \input it is the error you would get from \begin{tabular}{ccc} 1.23 & 2.98 -3.78 & 4.01 & \multirow{2}{*}{Apple \\ Banana} \\\end{tabular} – David Carlisle Jul 08 '14 at 13:50
  • pgfplotstable can do this stuff out-of-the-box, see http://tex.stackexchange.com/questions/49414/comprehensive-list-of-tools-that-simplify-the-generation-of-latex-tables/49473#49473 – Christian Feuersänger Jul 08 '14 at 15:16

2 Answers2

5

You can define \preparetable macro which prepares data for the table:

\preparetable {file.txt} {Apple, Banana}

and then use this in the table environment:

\begin{tabular}{ccc} \usetable \end{tabular}

The whole example follows:

\documentclass{article}      

\newread\infile
\def\preparetable#1#2{\bgroup \openin\infile=#1
   \let\\=\relax \gdef\usetable{}\preparetableA #2,,}
\def\preparetableA #1,{\if,#1,\egroup \closein\infile \else \read\infile to\tmp
  \xdef\usetable{\usetable \tmp & #1 \\}\expandafter\preparetableA\fi}

\begin{document}

\preparetable {file.txt} {Apple, Banana}
\begin{tabular}{ccc} \usetable \end{tabular}

\end{document}
wipet
  • 74,238
4

A solution similar to wipet's, but using expl3. Longer, but quite readable once one has gotten some practice.

\begin{filecontents*}{\jobname.dat}
 1.23 & 2.98
-3.78 & 4.01
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}
\usepackage{array}
\newcolumntype{C}{>{$}c<{$}}

\ExplSyntaxOn
\NewDocumentCommand{\addcolumn}{mm}
 {
  % #1 is the file to read, #2 the list of items to add, separated by \\
  \fabian_addcolumn:nn { #1 } { #2 }
 }

% some variables
\seq_new:N \l__fabian_additions_seq
\tl_new:N \l__fabian_table_body_tl
\tl_new:N \l__fabian_item_tl
\ior_new:N \g_fabian_import_stream

\cs_new_protected:Npn \fabian_addcolumn:nn #1 #2
 {
  % clear the variable containing the table body
  \tl_clear:N \l__fabian_table_body_tl
  % create a sequence from the second argument
  \seq_set_split:Nnn \l__fabian_additions_seq { \\ } { #2 }
  % start reading the file
  \ior_open:Nn \g_fabian_import_stream { #1 }
  % at each line ...
  \ior_map_inline:Nn \g_fabian_import_stream
   {
    % 1. detach the leftmost item from the sequence
    \seq_pop_left:NN \l__fabian_additions_seq \l__fabian_item_tl
    % 2. add the line and a trailing &
    \tl_put_right:Nn \l__fabian_table_body_tl { ##1 & }
    % 3. add the current item
    \tl_put_right:NV \l__fabian_table_body_tl \l__fabian_item_tl
    % 4. add the trailing \\
    \tl_put_right:Nn \l__fabian_table_body_tl { \\ }
   }
  % deliver the result
  \tl_use:N \l__fabian_table_body_tl
 }

\ExplSyntaxOff

\begin{document}

\begin{tabular}{CCl}
\addcolumn{\jobname.dat}{Apple\\Banana}
\end{tabular}

\end{document}

enter image description here

Here's the version for the case the data file has trailing \\ on each line; instead of adding directly the read line, we first store it into a token list and replace \\ by &.

\begin{filecontents*}{\jobname.dat}
 1.23 & 2.98 \\
-3.78 & 4.01 \\
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}
\usepackage{array}
\newcolumntype{C}{>{$}c<{$}}

\ExplSyntaxOn
\NewDocumentCommand{\addcolumn}{mm}
 {
  \fabian_addcolumn:nn { #1 } { #2 }
 }

\seq_new:N \l__fabian_additions_seq
\tl_new:N \l__fabian_table_body_tl
\tl_new:N \l__fabian_item_tl
\tl_new:N \l__fabian_temp_tl
\ior_new:N \g_fabian_import_stream

\cs_new_protected:Npn \fabian_addcolumn:nn #1 #2
 {
  \tl_clear:N \l__fabian_table_body_tl
  \seq_set_split:Nnn \l__fabian_additions_seq { \\ } { #2 }
  \ior_open:Nn \g_fabian_import_stream { #1 }
  \ior_map_inline:Nn \g_fabian_import_stream
   {
    \seq_pop_left:NN \l__fabian_additions_seq \l__fabian_item_tl
    \tl_set:Nn \l__fabian_temp_tl { ##1 }
    \tl_replace_once:Nnn \l__fabian_temp_tl { \\ } { & }
    \tl_put_right:NV \l__fabian_table_body_tl \l__fabian_temp_tl
    \tl_put_right:NV \l__fabian_table_body_tl \l__fabian_item_tl
    \tl_put_right:Nn \l__fabian_table_body_tl { \\ }
   }
  \tl_use:N \l__fabian_table_body_tl
 }

\ExplSyntaxOff

\begin{document}

\begin{tabular}{CCl}
\addcolumn{\jobname.dat}{Apple\\Banana}
\end{tabular}

\end{document}
egreg
  • 1,121,712