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.

I would like to be able to define a macro that can be used in the tabular definition. How can I do this?

This does not work:

\documentclass{article}

\begin{document}
\gdef\buildtabularhead{|||}

\begin{tabular}{\buildtabularhead}
1 & 2 &3\\
\end{tabular}
\end{document}
share|improve this question

6 Answers 6

up vote 7 down vote accepted

This is probably not practical but it's a nice demonstration of \expandafter and gets around the problem of macros in the table preamble with the array package.

\documentclass{article}
\usepackage{array}
\begin{document}
\def\buildtabularhead{|c|c|c|}
\expandafter\tabular\expandafter{\buildtabularhead}
1 & 2 &3\\
\endtabular
\end{document}

The two \expandafters make sure that the macro \buildtabularhead is expanded before LaTeX knows it should be expecting a tabular preamble. Notice also that instead of \begin{tabular}...\end{tabular} I had to use \tabular...\endtabular. Internally the former does the same as the latter but surrounding it with a group and doing important checks, including proper nesting (See source2e Section 54.1).

share|improve this answer

Better define it as a new column type using the array package:

\documentclass{article}
\usepackage{array}
\newcolumntype{L}{|l|l|l|}
\begin{document}

\begin{tabular}{L}
1 & 2 &3\\
\end{tabular}
\end{document}
share|improve this answer

It does work when you correct your tabular header.

\documentclass{article}

\def\buildtabularhead{|c|c|c|}

\begin{document}
\begin{tabular}{\buildtabularhead}
  1 & 2 & 3 \\
\end{tabular}
\end{document}
share|improve this answer
1  
Note that this solution won't work if you are using the array package or any other package that loads it. –  Alan Munn Feb 27 '11 at 18:06
    
@Alan @Christian I am using the array package! Is their a way to by-pass the issue? –  Yiannis Lazarides Feb 27 '11 at 18:13
3  
@salty Yes, use Martin's solution of defining a new column type. It achieves exactly the same aim but just slightly differently. –  Alan Munn Feb 27 '11 at 18:15

The column definition, you are using as an example is invalid. It only specifies lines and no real columns. If you change it to something like \gdef\buildtabularhead{|c|c|c|} it works as expected.

share|improve this answer
    
still gives me an error Illegal pream-token –  Yiannis Lazarides Feb 27 '11 at 18:07
    
@saltypen: At Alan Munn pointed out above this doesn't work when the array package is loaded (which is loaded by many other tabular related packages ...) –  Martin Scharrer Feb 27 '11 at 18:09

I had a very dirty answer, but I found theneater solution below while reading the documentation of the array package. In particular, this is inspired from how the * column specifier is defined there.

The idea is to introduce the new column type \expand (\newcolumntype sets up most of the necessary ingredients), and then redefine \NC@rewrite@\expand to expand the next token with \expandafter, and then continue the action that array is doing at that time (namely finding user-defined column types and replacing them by their definition).

\documentclass{article}
\usepackage{array}

\makeatletter
\newcolumntype{\expand}{}
\long\@namedef{NC@rewrite@\string\expand}{\expandafter\NC@find}
\makeatother

\begin{document}
\def\mypream{c|*{2}{c|||}}
\begin{tabular}{c\expand\mypream cc}
    a   & b   & d     &e   & f     & apsdoi \\
    cde & def & erasd &arp & sefoi & wp     
\end{tabular}
\end{document}
share|improve this answer

You can use the array package and still be able to specify the column specifiers through a macro as follows:

\documentclass{article}
\usepackage{array}
\begin{document}


\def\test#1{\newcolumntype{L}{#1}}
\test{clr}

\begin{tabular}{L}
1 & 2 &3\\
\end{tabular}
\end{document}

This can be useful, if you automating table generation through scripts.

share|improve this answer
2  
Good answer (sorry out of votes for today), but X is a bad choice because it will collide with the tabularx package once loaded. –  Martin Scharrer Feb 27 '11 at 18:42
    
@Martin you right edited to `L', thanks. –  Yiannis Lazarides Feb 27 '11 at 19:04
    
@Yiannis: Can you explain why you wrap the \newcolumntype in a macro? –  Hendrik Vogt Mar 1 '11 at 14:10
    
@Hendrik Essentially because I wanted to pass a parameter. Lamport's original definition allowed the following \newcommand{\X}{clr} \begin{tabular}{\X} . . . The array package takes great care not to expand the preamble. By defining another macro you can make sure that the argument is expanded. In a more realistic application the \test macro would be used to set-up the tabular head programmatically. Another approach is to use expandafter as Mathew's fine answer demonstrates. –  Yiannis Lazarides Mar 1 '11 at 19:52
    
@Yiannis: I'm not sure if I can follow. Would \test{\X} be any different from \newcolumntype{L}{\X}? –  Hendrik Vogt Mar 1 '11 at 21:09

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.