3

This might be asking a lot, but I would love to have a way to automatically scale multiple tables with similar content by the same factor such that the widest table fits to a particular width (e.g., textwidth), without having to manually manage the scale factor.


As an example:

\documentclass[12pt]{article}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{showframe}

\begin{document}


\newlength{\cell}
\setlength{\cell}{3cm}

\begin{table}
    \caption{Wide}
    \resizebox{\textwidth}{!}{
        \begin{tabular}{lll}
            \toprule
            \textbf{Column 1} & \textbf{Column 2} & \textbf{Column 3} \\
            \midrule
            \rule{\cell}{1ex} & \rule{\cell}{1ex} & \rule{\cell}{1ex} \\
            \rule{\cell}{1ex} & \rule{\cell}{1ex} & \rule{\cell}{1ex} \\
            \bottomrule
    \end{tabular}
    }
\end{table}

\setlength{\cell}{4cm}

\begin{table}
    \caption{Wider}
    \resizebox{\textwidth}{!}{
        \begin{tabular}{lll}
            \toprule
            \textbf{Column 1} & \textbf{Column 2} & \textbf{Column 3} \\
            \midrule
            \rule{\cell}{1ex} & \rule{\cell}{1ex} & \rule{\cell}{1ex} \\
            \rule{\cell}{1ex} & \rule{\cell}{1ex} & \rule{\cell}{1ex} \\
            \bottomrule
        \end{tabular}
    }
\end{table}

\setlength{\cell}{5cm}

\begin{table}
    \caption{Widest}
    \resizebox{\textwidth}{!}{
        \begin{tabular}{lll}
            \toprule
            \textbf{Column 1} & \textbf{Column 2} & \textbf{Column 3} \\
            \midrule
            \rule{\cell}{1ex} & \rule{\cell}{1ex} & \rule{\cell}{1ex} \\
            \rule{\cell}{1ex} & \rule{\cell}{1ex} & \rule{\cell}{1ex} \\
            \bottomrule
        \end{tabular}
    }
\end{table}
\end{document}     

enter image description here

All tables fit within \textwidth using resizebox. But I would like to automatically scale all by the same factor such that the widest table fits \textwidth. The goal is for all tables to fit the page but also to have a consistent appearance (in terms of font sizes, etc.).

  • 1
    Because of the issue regarding changing font sizes whan using resizebox on a table, I'd suggest to not use that method. Instead you can manually change the font site (suing \small...), or adjust the \tabcolsep. Depending on the table you could also introduce linebreaks in the contents of the cells. tabularx or tabular* might also come in handy. – leandriis Sep 3 '19 at 20:57
3

Please, please, don't do this. Please :-)

If the table is too large you should change the font size or rearrange the table to make it fit. Even if you scale all the tables by the same amount, the best you can get is a consistent inconsistency.

However, should you insist on this, here's a \ScaleorResize command, which takes two arguments: #1, the width of the widest thing and #2, a thing. The command typesets the thing and steals its scale factor from \resizebox (which is a \scalebox in disguise). The command then checks that stolen scale factor against the largest known scale factor, conveniently called \PleaseDontSF (SF stands for Scale Factor :-). If that scale factor is larger, \PleaseDontSF is updated and the thing is typeset. Otherwise the thing is rescaled to \PleaseDontSF. Since the widest thing might happen at the end of the document, \PleaseDontSF is saved to the .aux file to be updated in the next LaTeX run, so you need at least two runs to ensure that the scaling is right less wrong.

Here it goes. Put everything from \makeatletter and \makeatother in your document and replace all \resizebox{<something>}{!} by \ScaleorResize{<something>}. I put your table in a command, for brevity, but in your document you don't need that:

\documentclass[12pt]{article}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{showframe}

\makeatletter
\edef\scalefactor{\strip@pt\maxdimen}
\edef\PleaseDontSF{\strip@pt\maxdimen}
\edef\PleaseDontCHK{\strip@pt\maxdimen}
\let\graphicx@Gscale@box\Gscale@box
\long\def\Gscale@box#1{%
  \xdef\scalefactor{#1}%
  \graphicx@Gscale@box{#1}}
\AtEndDocument{%
  \immediate\write\@auxout
    {\gdef\noexpand\PleaseDontSF{\PleaseDontCHK}}}%
\newsavebox\@weirdbox@a
\newsavebox\@weirdbox@b
\protected\long\def\ScaleorResize#1#2{%
  \sbox\@weirdbox@a{#2}%
  \sbox\@weirdbox@b{\resizebox{#1}{!}{\usebox\@weirdbox@a}}%
  \ifdim\scalefactor\p@<\PleaseDontCHK\p@
    \xdef\PleaseDontCHK{\scalefactor}%
  \fi
  \ifdim\scalefactor\p@<\PleaseDontSF\p@
    \xdef\PleaseDontSF{\scalefactor}%
    \usebox\@weirdbox@b
  \else
    \scalebox{\PleaseDontSF}{\usebox\@weirdbox@a}%
  \fi}
\makeatother

\def\weirdtable#1{%
  \begin{tabular}{lll}
    \toprule
      \textbf{Column 1} & \textbf{Column 2} & \textbf{Column 3} \\
    \midrule
      \rule{#1}{1ex} & \rule{#1}{1ex} & \rule{#1}{1ex} \\
      \rule{#1}{1ex} & \rule{#1}{1ex} & \rule{#1}{1ex} \\
    \bottomrule
  \end{tabular}}

\begin{document}
\begin{table}
  \caption{Wide}
  \centering
  \ScaleorResize{\textwidth}{\weirdtable{3cm}}
\end{table}
\begin{table}
  \caption{Wider}
  \centering
  \ScaleorResize{\textwidth}{\weirdtable{4cm}}
\end{table}
\begin{table}
  \caption{Widest}
  \centering
  \ScaleorResize{\textwidth}{\weirdtable{5cm}}
\end{table}
\end{document}

Behold:

enter image description here

| improve this answer | |
  • Thanks! I'm heading off to do this now. :) – badroit Sep 3 '19 at 22:38
  • 2
    @badroit You've been warned ;-) – Phelype Oleinik Sep 3 '19 at 22:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.