19

I have a row of a table (tabular) that has small text (tiny). I would like to make this (first) row shorter, either automatically (automatic height) o̶r̶ ̶m̶a̶n̶u̶a̶l̶l̶y̶ ̶(̶s̶e̶t̶ ̶a̶ ̶n̶o̶n̶-̶d̶e̶f̶a̶u̶l̶t̶ ̶h̶e̶i̶g̶h̶t̶ ̶f̶o̶r̶ ̶t̶h̶a̶t̶ ̶p̶a̶r̶t̶i̶c̶u̶l̶a̶r̶ ̶r̶o̶w̶)̶.̶

I tried different tricks (like using \\[shift]) with no success.

MWE:

enter image description here

\documentclass[]{article}
\begin{document}
\begin{tabular}
{|c|c|c|c|}
{\tiny0}&{\tiny1}&{\tiny2}&{\tiny3}\\[-1mm]
\hline 0 & 4.94066e-323 & 22 & 9.78381e+199\\
\hline 
\end{tabular}
\end{document}

A simple solution using tabular is preferred but elegant solutions using pgfplotstables is also welcomed; specially since I have in mind the enumeration of columns (and eventually of rows).

Note that similar questions, like How can I reduce table row height? deal with uniform row heights adjustments.

David Carlisle
  • 757,742
alfC
  • 14,350

4 Answers4

23

LaTeX adds struts inside the table rows/cells. Each update of the font size/\baselineskip (\size@update) sets \strutbox (a box with height 0.7\baselineskip and depth 0.3\baselineskip. At the start of a tabular/array the box \@arstrutbox is set that uses the current \strutbox and scales it with factor \arraystretch.

The following example defines \setarstrut{...} that sets the table strut before the next row:

  • The argument allows font size commands, in the example: \tiny. Alternatively \arraystretch can be changed:

    \setarstrut{\renewcommand*{\arraystretch}{0.5}}%
    
  • Internally \nolign is used. Therefore \setarstrut must be at the start of the row. Otherwise it would be to late to set smaller struts anyway.
  • The old strutbox is remembered in \saved@arstrutbox.
  • Small disadvantage is the global settings of the strut box to skip the grouping levels. Thus some care is needed, if the table is nested inside another table.

Macro \saved@arstrutbox restores the saved strut box.

Example file:

\documentclass[]{article}

\makeatletter
\newsavebox\saved@arstrutbox
\newcommand*{\setarstrut}[1]{%
  \noalign{%
    \begingroup
      \global\setbox\saved@arstrutbox\copy\@arstrutbox
      #1%
      \global\setbox\@arstrutbox\hbox{%
        \vrule \@height\arraystretch\ht\strutbox
               \@depth\arraystretch \dp\strutbox
               \@width\z@
      }%
    \endgroup
  }%
}
\newcommand*{\restorearstrut}{%
  \noalign{%
    \global\setbox\@arstrutbox\copy\saved@arstrutbox
  }%
}
\makeatother

\begin{document}
  \begin{tabular}{|c|c|c|c|}
    \setarstrut{\tiny}%
    {\tiny0}&{\tiny1}&{\tiny2}&{\tiny3}\\
    \restorearstrut
    \hline
    0 & 4.94066e-323 & 22 & 9.78381e+199\\
    \hline
  \end{tabular}
\end{document}

Result

David Carlisle
  • 757,742
Heiko Oberdiek
  • 271,626
  • Incredible, absolutely incredible. – azetina Nov 27 '12 at 19:10
  • Perfect results. But it looks like the tabular is not made for this. I'll take a look at pgfplotstable to see if it is easier. – alfC Nov 27 '12 at 22:46
  • This is marvelous, It helped me with reducing the spacing of "blocks" of a tabular environment. Instead of leaving a full blank line, I inserted a \tiny blank line. – AlexR Nov 20 '14 at 19:42
10

This isn't pretty, but it works:

enter image description here

\documentclass{article}
\newlength{\mylen}
\settoheight{\mylen}{\tiny 1}
\newcommand{\myheading}[1]{%
  \raisebox{\dimexpr\normalbaselineskip-\mylen}{\tiny #1}}
\begin{document}
\begin{tabular}
{|c|c|c|c|}
\myheading{0} & \myheading{1} & \myheading{2} & \myheading{3} \\[\dimexpr-\normalbaselineskip+\mylen]
\hline 0 & 4.94066e-323 & 22 & 9.78381e+199 \\
\hline 
\end{tabular}
\end{document}

This assumes you'll only use similar-height elements in the first row (using the length \mylen set to the height of {\tiny 1}).

Moriambar
  • 11,466
Werner
  • 603,163
  • 1
    +1. It looks too cumbersome, is there an automatic way? – alfC Nov 27 '12 at 18:36
  • Note that this will cause artifacts in some viewers (evince), and if the "short" row is the last, the vertical lines continue below the table (i.e. they are drawn the same height, it's just the next row that is moved up and covers them). – Suzanne Soy Apr 27 '16 at 12:46
10

Given the complexity of the LaTeX solution, I have no option but to post a ConTeXt solution ;-)

Like LaTeX, ConTeXt also inserts a \strut in each row of a table. However, rather than fighting the strut, we can simply ask ConTeXt not to add the strut by saying strut=no.

\startsetups table:size
  \setupTABLE[row][1][style=\tfxx, strut=no]
  \setupTABLE[align=middle]
\stopsetups

\starttext
\startTABLE[setups={table:size}]
  \NC 0 \NC 1 \NC 2 \NC 3 \NC \NR
  \NC 0 \NC 4.94066e-323 \NC 22 \NC 9.78381e+199  \NC \NR
\stopTABLE
\stoptext

enter image description here

Aditya
  • 62,301
  • I never used ConTeXt, but I see it here and there really doing things that LaTeX has a hard time doing. Why is ConTeXt so powerful and yet it has an unpleasant syntax (personal opinion). – alfC Nov 28 '12 at 00:23
  • Just curious. What do you find unpleasant about ConTeXt's syntax? To me, ConTeXt's syntax is one of its nicer parts. – Aditya Nov 28 '12 at 01:13
  • not to start a language war but since you ask. This is all personal taste and even can sound silly. All taken from you own example: 1) \star* \stop* blocks don't separate the environment name from the fact that they start or end (\begin{}\end{} looks more structured, 2) mixed lower-capital case 'startTABLE', 3) \NC, a command to separate columns? '&' looks more elegant. See, it is all taste. – alfC Nov 28 '12 at 22:03
  • Thanks for your explanation. I understand your point of view, but, as you say, it is matter of personal taste. FWIW, you can use \start[...] and \stop[...] if you prefer. Mixed lower case for tables is because ConTeXt already has \starttable and \starttabular, and \startlinetable, so after a while you just run out of names;). Most environments are lower case. \NC is a conscious design decision. ConTeXt tends to avoid exposing low level TeX primitives: there were even discussion about getting rid of $! See http://randomdeterminism.wordpress.com/?p=767 for my view on this. – Aditya Nov 28 '12 at 22:25
2

An alternative solution with tblr environment of tabularray package: since there is default rowsep for a tblr table, you are free to set stretch=0 to remove the strut.

\documentclass{article}

\usepackage{tabularray}

\begin{document}

\begin{tblr}{ colspec = {|c|c|c|c|}, hlines, row{1} = {font=\tiny}, stretch = 0, } 0 & 1 & 2 & 3 \ 0 & 4.94066e-323 & 22 & 9.78381e+199 \ \end{tblr}

\end{document}

enter image description here

L.J.R.
  • 10,932
  • Although these needs to use a different package, it seems to be the most elegant solution of all. – alfC Sep 05 '21 at 08:44