# Separate \arraystretch value for every table

\arraystretch defines vertical spacing of tables. If I have several tables, how can I define a separate value of \arraystretch for every table? In my case, the last defined \arraystretch works for all tables.

• I would suggest accepting answers to some of the questions you have asked. Feb 13, 2011 at 14:18

The presented solutions have a limitation in that they disallow the vertical alignment optional argument to tabular.

Here is a version much more flexible that supports tabular, tabular*, array and also longtable (if the relative package is loaded).

If the width key is set, tabular* is used. Otherwise the type of tabular is determined by the type key (default tabular). Note that the stretch is reset to 1 at each call. It would be possible to define a “inherit” key so the stretch factor is preserved in nested tables.

\documentclass{article}
\usepackage{longtable}
%\usepackage{xparse} % only needed for LaTeX prior to 2020-10-01

\ExplSyntaxOn
\NewDocumentEnvironment{flexitab}{m}
{
\keys_set:nn { flexitab }
{
% default value for type
type = tabular,
% default value for stretch
stretch = 1,
% default value for alignment
align = c,
% default value for width
width = -1000pt,
#1
}
\dim_compare:nTF { \l_flexitab_width_dim > -1pt }
{
\tl_set:Nn \l_flexitab_type_tl { tabular* }
\tl_set:Nn \l_flexitab_start_tl { \begin{tabular*}{\l_flexitab_width_dim} }
}
{
\tl_set:Nn \l_flexitab_start_tl { \begin{\l_flexitab_type_tl} }
}
\tl_put_right:Nx \l_flexitab_start_tl
{
[\l_flexitab_align_tl]{\exp_not:V \l_flexitab_columns_tl}
}
\tl_set_eq:NN \arraystretch \l_flexitab_stretch_tl
\tl_use:N \l_flexitab_start_tl
}
{
\str_if_eq:eeTF {\l_flexitab_type_tl}{tabular*}
{ \end{tabular*} }
{ \end{\l_flexitab_type_tl} }
}

\keys_define:nn { flexitab }
{
type    .tl_set:N  = \l_flexitab_type_tl,
align   .tl_set:N  = \l_flexitab_align_tl,
width   .dim_set:N = \l_flexitab_width_dim,
columns .tl_set:N  = \l_flexitab_columns_tl,
stretch .tl_set:N  = \l_flexitab_stretch_tl,
}
\tl_new:N \l_flexitab_start_tl
\ExplSyntaxOff

\begin{document}

\begin{flexitab}{
stretch=2,
columns=cc,
}
AA & BBB \\
AA & BBB \\
C  & \begin{flexitab}{columns=@{}l@{},align=t}D\\D\\D\end{flexitab}
\end{flexitab}

\bigskip

\bigskip
\begin{flexitab}{ type=array, columns=cc, } aa & bb \\ cc & \begin{flexitab}{stretch=2,columns=l,align=b}aa \\ bb \\ccc\end{flexitab} \\ d & d \end{flexitab}

\noindent
\begin{flexitab}{
stretch=2,
width=\textwidth,
columns=@{\extracolsep{\fill}}ll@{},
}
AAAA & BBBB \\
CC   & DDD
\end{flexitab}

\bigskip

\begin{flexitab}{
type=longtable,
columns=cc
}
aa & bb \\
\hline
cc & dd \\
cc & dd \\
cc & dd \\
cc & dd \\
\end{flexitab}

\end{document}


• It has a deprecated used of str_if_eq_x_nnTF', I think (but I don't know much LaTeX3). Oct 27, 2021 at 7:16
• @BenjaminMcKay Thanks, I’ll replace the deprecated function. Oct 27, 2021 at 7:46

If you define \arraystretch direct before the table (i.e. tabular) inside a group it should only be active for this table.

\begingroup
\renewcommand*{\arraystretch}{<value>}
\begin{tabular}{...}
...
\end{tabular}
\endgroup


\renewenvironment{mytabular}[1][1]{%
\renewcommand*{\arraystretch}{#1}%
\tabular%
}{%
\endtabular
}

% ...

\begin{mytabular}[<stretch value>]{...}
...
\end{mytabular}

• @MartinScharrer why do you use the * with the \renewcommand? Apr 24, 2013 at 12:52
• @MarioS.E.: The starred version defines a "normal" macro, while the normal version defines a "long" macro which may contain \par. This is not required for \arraystretch so I used the starred version. This however is just a very minor difference and does not have a real impact here. Apr 24, 2013 at 15:08
• could you restore the old value after the table? So that the following tables are not affected. Dec 4, 2020 at 22:51
• @FrederickNord: As the changes are done inside a group they will not be valid afterwards. All changes in a group (which are not done globally) are automatically restored at the end of the group by TeX. Dec 8, 2020 at 8:03
\documentclass{article}

\newenvironment{Tabular}[2][1]
{\def\arraystretch{#1}\tabular{#2}}
{\endtabular}

\begin{document}

\begin{Tabular}{ccc}
c & c & C\\
c & c & C
\end{Tabular}

\begin{Tabular}[3]{ccc}
c & c & C\\
c & c & C
\end{Tabular}

\end{document}

• it worked. thank you. another question, e.g., how can i define a new command to use the new environment Tabular in the above example? i want to know how i can transfer parameters of \newcommand to \newenvironment. Feb 14, 2011 at 9:02
• @warem: there is no difference to the above example where I passed an argument from the environment to a command. However, to give a more explicitly answer, create an example of what you really want to do. Maybe as a new question.
– user2478
Feb 14, 2011 at 9:08
• i mean create a new command to use the Tabular environmet. e.g., \newcommand{\test}[2]{\begin{Tabular}[2]...\end{Tabular}}. it didn't work. it seemed that the parameters of test command can't be transferred to Tabular correctly. Feb 14, 2011 at 9:22
• @warem: \newcommand{\test}[2]{\begin{Tabular}{#1}#2\end{Tabular}} It depends to the menaing of #1 and #2
– user2478
Feb 14, 2011 at 9:27
• @warem consider accept the answer if so Jun 15, 2018 at 15:50

If you are using the table enviroment to place your tables floats you can just redefine arraystretch within that environment without affecting other tables:

\documentclass{article}

\begin{document}
\begin{table}
\centering
\renewcommand*{\arraystretch}{0.95}
\caption{table 1}
\begin{tabular}{ccc}
c & c & C\\
c & c & C
\end{tabular}
\end{table}

\begin{table}
\centering
\caption{table 2}
\begin{tabular}[3]{ccc}
c & c & C\\
c & c & C
\end{tabular}
\end{table}

\end{document}
`