LaTeX Table Generator

7

2

Write a function or program which, given a number of lines and columns, generates a corresponding tabular environment for LaTeX with no data in it.

Table format and tabular Environment

Here is an example of a table with 2 rows and 4 columns:

enter image description here

As you can see, we do not count the first row nor do we count the first column: those are for the labels of the table.

The top left corner is also "missing", in that there is no border around it.

The corresponding LaTeX's code to generate this table is the following:

\begin{tabular}{|c|c|c|c|c|}
    \cline{2-5}
    \multicolumn{1}{c|}{} & & & & \\
    \hline
    & & & & \\
    \hline
    & & & & \\
    \hline
\end{tabular}
  • There are as many c in the first line as there are total columns (that is, 1 more than the number of columns given as input). These c are separated by | (and there are | on both the extreme left and extreme right too).
  • The first horizontal separator is generated by \cline{2-X} where X is the index of the last column (starting from 1).
  • The first element of the first row is always \multicolumn{1}{c|}{} (this removes the borders of the top left corner).
  • Each row has C &, C being the number of columns given as input. Each line ends with \\.
  • Each row is followed by a \hline.

Formatting details

  • You must indent everything between the begin{tabular}{...} and \end{tabular} tags with 4 spaces.
  • The &'s are separated with exactly one space on each row. The first one of the row does not have an extra space before it (since it already has 4 spaces before it). Note that this is not true for the first row, where the first & has a space before it because of the \multicolumn element.
  • \\ is separated from the last & by a space.
  • Each \hline and row description is on its own new line.

Input

Input is a couple of two integers representing the number of columns and the number of rows. Note that this is the number of columns and rows excluding the very first row and very first column.

You may assume that the row and column inputs will always be at least 1, and less than 1024.

Those two numbers can be taken whichever way is most appropriate in your language (two args, a list, etc.).

Output

The output is a string of the LaTeX code that generates a table with the appropriate number of rows and columns. This can be returned from a function or outputted to STDOUT.

A trailing new line is allowed after the \end{tabular}. Trailing spaces are not allowed at the end of any line.

Test cases

Input: (1,1)
Output:
\begin{tabular}{|c|c|}
    \cline{2-2}
    \multicolumn{1}{c|}{} & \\
    \hline
    & \\
    \hline
\end{tabular}


Input: 2 rows, 4 columns
Output:
\begin{tabular}{|c|c|c|c|c|}
    \cline{2-5}
    \multicolumn{1}{c|}{} & & & & \\
    \hline
    & & & & \\
    \hline
    & & & & \\
    \hline
\end{tabular}

Scoring

This is , so the shortest code in bytes \emph{wins}.

Fatalize

Posted 2016-02-23T08:30:15.027

Reputation: 32 976

Answers

2

JavaScript (ES6), 172 170 bytes

a=>b=>`\\begin{tabular}{${'|c'[r='repeat'](++b)}|}
    \\cline{2-${b--}}
    \\multicolumn{1}{c|}{} ${('& '[r](b)+`\\\\
    \\hline
    `)[r](a+1).trim()}
\\end{tabular}`

Called as F(a)(b) (credit to Patrick Roberts for finding this method)

Would have been much messier if not for template strings. Originally came in at 200, when I had a separate repeat for the multicolumn &'s, but cut it down a good amount by combining them and using trim to get rid of the final unneeded indentation.

Mwr247

Posted 2016-02-23T08:30:15.027

Reputation: 3 494

2

Python 2, 197 bytes

This solution uses string formatting to reduce repetition. Each string component is assembled, then placed within the template. It is tricky to use so many backslashes in Python strings. I used the raw string r'\\' and multi-line '''blah \n blah''' string techniques here.

def a(d,e):
 c='c|'*e;b='& '*e+r'\\';g=' '*4+b+'\n    \\hline\n';f=g*d;h='{tabular}'
 return r'''\begin%s{|c|%s}
    \cline{2-%s}
    \multicolumn{1}{c|}{} %s
    \hline
%s\end%s'''%(h,c,e+1,b,f,h)

Before the minifier, it looks like this:

def latextable(height, width):
    columns = 'c|' * width;
    linespec = '& ' * width + r'\\';
    line = ' '*4 + linespec + '\n    \\hline\n';
    block = line * height;
    mode = '{tabular}'
    return r'''\begin%s{|c|%s}
    \cline{2-%s}
    \multicolumn{1}{c|}{} %s
    \hline
%s\end%s''' % (mode, columns, width+1, linespec, block, mode)

print latextable(1, 1)
print latextable(2, 4)

The output tests:

\begin{tabular}{|c|c|}
    \cline{2-2}
    \multicolumn{1}{c|}{} & \\
    \hline
    & \\
    \hline
\end{tabular}
\begin{tabular}{|c|c|c|c|c|}
    \cline{2-5}
    \multicolumn{1}{c|}{} & & & & \\
    \hline
    & & & & \\
    \hline
    & & & & \\
    \hline
\end{tabular}

As a side note, I wrote a latex macro processor like this to format my thesis. I think I spent longer on developing that macro processor than on writing the words...

Logic Knight

Posted 2016-02-23T08:30:15.027

Reputation: 6 622

1You forgot one space between the return and your raw string in your first code block. – Denker – 2016-02-23T09:54:01.960

1Also you can go with g=' '*4 instead of g=' ' to save one byte. – Denker – 2016-02-23T09:56:30.630

@DenkerAffe, thanks for finding that error. My minifier has a bug! – Logic Knight – 2016-02-23T10:01:31.113

1

C#, 248 byte

string t(int r,int c){string i="\r\n    ",d="",q="",m;for(int j=0;j++<c;){d+="c|";q+="& ";}q+=$"\\\\{i}\\hline";m=@"\begin{tabular}{|c|"+d+"}"+i+@"\cline{2-"+(c+1)+"}"+i+@"\multicolumn{1}{c|}{} "+q;for(;r-->0;)m+=i+q;return m+"\r\n\\end{tabular}";}

Tester:

using System;
class Table
{
    static int Main()
    {
        var x = new Table();
        Console.WriteLine(x.t(1,1));
        Console.WriteLine(x.t(2,4));
        Console.Read();
        return 0;
    }
    string t(int r,int c){string i="\r\n    ",d="",q="",m;for(int j=0;j++<c;){d+="c|";q+="& ";}q+=$"\\\\{i}\\hline";m=@"\begin{tabular}{|c|"+d+"}"+i+@"\cline{2-"+(c+1)+"}"+i+@"\multicolumn{1}{c|}{} "+q;for(;r-->0;)m+=i+q;return m+"\r\n\\end{tabular}";}

    string tab(int row, int col){
        string i="\r\n    ",sc="",sr="",msg;
        for(int j=0;j++<col;){sc+="c|";sr+="& ";}
        sr+=$"\\\\{i}\\hline";
        msg=@"\begin{tabular}{|c|"+sc+"}"+i+@"\cline{2-"+(col+1)+"}"+i+@"\multicolumn{1}{c|}{} "+sr;
        for(;row>0;)msg+=i+sr;
        return msg+"\r\n\\end{tabular}";
    }
}

DW.com

Posted 2016-02-23T08:30:15.027

Reputation: 51

I could save 4 bytes when I use "\n" instead of "\r\n" as linebreak. – DW.com – 2016-03-02T12:54:31.223