# Is it possible to create a \newcolumntype-like macro accepting more than one arguments where one of them is an optional argument?

Is it possible to create a \newcolumntype-like macro accepting more than one argument and one of them is an optional argument?

I want to create a column type A that can accept more than 1 argument such that I can create a tabular as follows:

\begin{tabular}{|A[2cm]{1cm}{5cm}|c|l|r|}
...
\end{tabular}


Note: the column type A accepts 3 arguments in this example.

• Perhaps a bit more detail on what is wanted might be useful! I'm not sure if it is the macro \newcolumntype itself or the resulting letter that you want to alter. – Joseph Wright Dec 30 '10 at 18:51
• @Joseph, please see my new edit. – xport Dec 30 '10 at 19:00

Herbert has explained how to do mandatory arguments. Optional arguments is doable but requires some low-level hackery, auxiliary functions and is not for the faint-hearted. You can see two versions of the same approach in numprint and siunitx (the later is an adaptation of the former).

\makeatletter
\newtoks\mytoks
\mytoks\expandafter{\the\NC@list}
\newcolumntype{A}{}
\NC@list\expandafter{\the\mytoks \NC@do A}
\renewcommand*{\NC@rewrite@A}[3][]{%
\@temptokena\expandafter{%
\the\@temptokena
% INSERT DEFINITION HERE!
}%
\NC@find
}
\makeatother

• Is there a reason for using \csname NC@rewrite@A\endcsname (and the \expandafters) rather than \NC@rewrite@A? – cgnieder Jan 26 '13 at 21:28
• @cgnieder Not here, but there is where I've copied it from! I'll edit. – Joseph Wright Jan 26 '13 at 21:59

not with an optional argument, only with mandatory ones:

\documentclass{article}
\usepackage{array}

\newcolumntype{A}[3]{@{\vrule\kern#1\vrule}p{#2}@{\vrule\kern#3\vrule}}
\begin{document}

\begin{tabular}{|A{2cm}{1cm}{5cm}|c|l|r|}
foo & bar & baz & foobar
\end{tabular}

\end{document}

• first of all thanks. However, if I define an optional argument as follow \newcolumntype{A}[3][1cm] and \begin{tabular}{|A[2cm]{1cm}{5cm}|c|l|r|}, I got compilation errors. – xport Dec 30 '10 at 19:12
• I wrote "not" with an optional argument! – user2478 Dec 30 '10 at 19:18

starting off with Joseph Wright's answer I have developed a hack which allows to define new column types with an optional parameter with the \newcolumntype command:

\documentclass{article}
\usepackage{array}
\usepackage{booktabs}

% ---------- hack to allow optional parameters with \newcolumntype ----------
\makeatletter
% newcommand with default value for optional parameter but without test whether command exists
% because array package has a different policy: warning instead of error if column type is already defined
\def\@xargdef@withoutcheck#1[#2][#3]#4{%
% copied from \show\@xargdef without \@ifdefinable
% also see The LaTeX 2e Sources (2014/05/01 p24f)
\expandafter \def \expandafter #1\expandafter {%
\expandafter \@protected@testopt \expandafter #1\csname \string #1\endcsname {#3}%
}%
\expandafter \@yargdef \csname \string #1\endcsname \tw@ {#2}{#4}%
}

% save a backup of original command which I am going to override
\let\original@newcol@\newcol@

% redefine a command which is internally called by \newcolumntype.
% check whether column type is already existing has already been done
% and existence of first optional argument (number of parameters) has been confirmed,
% see array package documentation (November 3, 2014 p21f).
% check whether 2nd optional argument is given:
\def\newcol@#1[#2]{%
\@ifnextchar[%
{\my@newcol@#1[#2]}%
{\original@newcol@#1[#2]}%
}

% custom command which handles 2nd optional argument (default value of optional parameter)
\def\my@newcol@#1[#2][#3]#4{\expandafter\@xargdef@withoutcheck\csname NC@rewrite@#1\endcsname[#2][#3]{\NC@find#4}}
\makeatother

% ---------- example usage ----------
\newcolumntype{m}[1][c]{>{$} #1 <{$}}
\newcolumntype{M}[1][c]{>{\displaystyle}m[#1]}

\newcolumntype{A}[3][0em]{>{\typeout{opt: #1}\rule[#1]{#2}{#3}} l <{\rule[#1]{#2}{#3}}}

% ---------- test document ----------
\begin{document}
\begin{center}
\begin{tabular}{M[l] M M[r]}
\toprule
a+b=c & a+b=c & a+b=c \\
1 & 2 & 3 \\
\bottomrule
\end{tabular}
\end{center}
\bigskip

Please note that in this case it is necessary to add curley braces around the optional argument because otherwise the m' of the unit would be interpreted as a column specifier:
\begin{center}
\begin{tabular}{A{1em}{.5pt} A[{.3em}]{1em}{.5pt}}
\toprule
1 & a\\
2 & b\\
3 & c\\
hello & world \\
\bottomrule
\end{tabular}
\end{center}
\end{document}
`