5

If I have a very wide table, how do I let LaTeX line-break it automatically so it won't fall off the page?

I expect it will be split into parts which will be shown on top of each other.

My table is

\documentclass{article}

\begin{document}
    \begin{tabular}{*{26}{l}}
        a&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z\\ \hline
        z&y&x&w&v&u&t&s&r&q&p&o&n&m&l&k&j&i&h&g&f&e&d&c&b&a \\
        one&two&three&four&five&six&seven&eight&nine&ten&eleven&twelve&
        thirteen&fourteen&fifteen&sixteen&seventeen&eighteen&nineteen&twenty&twenty-one&twenty-two&twenty-three&twenty-four&twenty-five&twenty-six
    \end{tabular}
\end{document}

table

Relevant questions

David Carlisle
  • 757,742
PHPirate
  • 1,775
  • 1
  • 21
  • 37
  • 1
    The structure of the material you’re looking to typeset doesn’t make it look like the material is suitable to be rendered in tabular form. A simple list, with lots of list items that contain three subitems each, may be more suitable. – Mico Jan 01 '18 at 20:53
  • See https://tex.stackexchange.com/a/387210/2388 – Ulrike Fischer Jan 01 '18 at 23:08
  • @Mico Good point, I see David already executed it, thanks! – PHPirate Jan 02 '18 at 12:22
  • @UlrikeFischer Yeah I should have mentioned something obvious like that, but I was specifically looking to automatically wrap a table instead of manually needing to split during typesetting (not convenient when having to alter it afterwards, for example). – PHPirate Jan 02 '18 at 12:22

3 Answers3

5

The best thing I could find was not automatically, by adapting Werner's answer to how I would apply it in practice.

\documentclass{article}
\usepackage{lipsum}

\usepackage{array} % Used for table wrapping
\usepackage{tabularx} % Used for table wrapping
% Define a new command to hide certain columns of a table
\newcolumntype{H}{>{\setbox0=\hbox\bgroup}c<{\egroup}@{}}

\begin{document}

    \lipsum[42]

    \newcommand{\hidetableone}[1]{
    \begin{tabular}{#1}
        a & b & c & d & e & f & g & h & i & j & k & l & m & n & o & p & q & r & s & t & u & v & w & x & y & z\\ \hline
        z & y & x & w & v & u & t & s & r & q & p & o & n & m & l & k & j & i & h & g & f & e & d & c & b & a \\
        one & two & three & four & five & six & seven & eight & nine & ten & eleven & twelve &
        thirteen & fourteen & fifteen & sixteen & seventeen & eighteen & nineteen & twenty &
        twenty-one & twenty-two & twenty-three & twenty-four & twenty-five & twenty-six
    \end{tabular}
    }

    \begin{figure}
        \centering
        \hidetableone{*{0}{H} l | *{9}{l} *{16}{H}}
        \hidetableone{*{10}{H} *{7}{l} *{9}{H}}
        \hidetableone{*{17}{H} *{6}{l} *{3}{H}}
        \hidetableone{*{23}{H} *{3}{l} *{0}{H}}
        \caption{This is a caption for a large table.}
    \end{figure}

\end{document}

table

PHPirate
  • 1,775
  • 1
  • 21
  • 37
5

This is essentially an implementation of Mico's comment

enter image description here

\documentclass{article}

\def\zz#1#2#3{\begin{tabular}[t]{l}#1\\\hline#2\\#3\end{tabular}\linebreak[0]\ignorespaces}
\begin{document}

\begin{center}\setlength\lineskip{10pt}
 \zz{a}{z}{one}
\zz{b}{y}{two}
\zz{c}{x}{three}
\zz{d}{w}{four}
\zz{e}{v}{five}
\zz{f}{u}{six}
\zz{g}{t}{seven}
\zz{h}{s}{eight}
\zz{i}{r}{nine}
\zz{j}{q}{ten}
\zz{k}{p}{eleven}
\zz{l}{o}{twelve}
\zz{m}{n}{thirteen}
\zz{n}{m}{fourteen}
\zz{o}{l}{fifteen}
\zz{p}{k}{sixteen}
\zz{q}{j}{seventeen}
\zz{r}{i}{eighteen}
\zz{s}{h}{nineteen}%:-)
\zz{t}{g}{twenty}
\zz{u}{f}{twenty-one}
\zz{v}{e}{twenty-two}
\zz{w}{d}{twenty-three}
\zz{x}{c}{twenty-four}
\zz{y}{b}{twenty-five}
\zz{z}{a}{twenty-six}
\end{center}
\end{document}
David Carlisle
  • 757,742
  • Bright one, I had not realised it would be easy to add the \hline there! The only thing I need to remember from now on is to write the table in this way when I know it's going to be long :) This is also much better readable with very wide tables. PS Thanks for counting, lol – PHPirate Jan 02 '18 at 12:25
3

This also supports booktabs rules with a handy syntax.

Limitation. The cells in each row should have the same height. Double rules are not supported.

\documentclass{article}
\usepackage{xparse,environ,booktabs}

\ExplSyntaxOn

\NewEnviron{splittabular}[1]
 {
  \dim_set:Nn \lineskip { 2ex }
  \phpirate_splittabular:nV { #1 } \BODY
  \par
 }

\int_new:N \l__phpirate_rows_int
\seq_new:N \l__phpirate_body_seq
\cs_generate_variant:Nn \seq_set_split:Nnn { c }

\cs_new_protected:Nn \phpirate_splittabular:nn
 {
  \seq_set_split:Nnn \l__phpirate_body_seq { \\ } { #2 }
  \int_zero:N \l__phpirate_rows_int
  \seq_map_inline:Nn \l__phpirate_body_seq
   {
    \int_incr:N \l__phpirate_rows_int
    \seq_clear_new:c { \__phpirate_row:n { \l__phpirate_rows_int } }
    \seq_set_split:cnn { \__phpirate_row:n { \l__phpirate_rows_int } } { & } { ##1 }
    % check for \hline
    \tl_clear_new:c { \__phpirate_hline:n { \l__phpirate_rows_int } }
    \seq_pop_left:cN { \__phpirate_row:n { \l__phpirate_rows_int } } \l_tmpa_tl
    \tl_set_eq:NN \l_tmpb_tl \l_tmpa_tl
    \regex_replace_once:nnN { \c{hline|toprule|midrule|bottomrule} } { } \l_tmpa_tl
    \seq_put_left:cV { \__phpirate_row:n { \l__phpirate_rows_int } } \l_tmpa_tl
    \regex_replace_once:nnN { (\c{hline|toprule|midrule|bottomrule}+).* } { \1 } \l_tmpb_tl
    \tl_set_eq:cN { \__phpirate_hline:n { \l__phpirate_rows_int } } \l_tmpb_tl
    % end code for \hline
   }
  \int_step_inline:nnnn { 1 } { 1 } { \seq_count:c { \__phpirate_row:n { 1 } } }
   {
    \__phpirate_column:nn { #1 } { ##1 }
   }
 }
\cs_generate_variant:Nn \phpirate_splittabular:nn { nV }

\cs_new_protected:Nn \__phpirate_column:nn
 {
  \seq_clear:N \l__phpirate_column_seq
  \int_step_inline:nnnn { 1 } { 1 } { \l__phpirate_rows_int }
   {
    \seq_put_right:Nx \l__phpirate_column_seq
     {
      \exp_not:v { \__phpirate_hline:n { ##1 } }
      \seq_item:cn { \__phpirate_row:n { ##1 } } { #2 }
     }
   }
  \begin{tabular}[t]{#1}
  \seq_use:Nn \l__phpirate_column_seq { \\ }
  \end{tabular}
  \linebreak[0]
 }

\cs_new:Nn \__phpirate_row:n
 {
  l__phpirate_row_ \int_eval:n { #1 } _seq
 }

\cs_new:Nn \__phpirate_hline:n
 {
  l__phpirate_hline_ \int_eval:n { #1 } _tl
 }

\ExplSyntaxOff

\begin{document}

\begin{center}

\begin{splittabular}{c}
\toprule
a&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z\\
\midrule
z&y&x&w&v&u&t&s&r&q&p&o&n&m&l&k&j&i&h&g&f&e&d&c&b&a \\
one&two&three&four&five&six&seven&eight&nine&ten&eleven&twelve&
  thirteen&fourteen&fifteen&sixteen&seventeen&eighteen&nineteen&
  twenty&twenty-one&twenty-two&twenty-three&twenty-four&twenty-five&twenty-six \\
\bottomrule
\end{splittabular}

\end{center}

\end{document}

It works also with \hline.

enter image description here

egreg
  • 1,121,712
  • 1
    Whoa, the complexity boggles me! You proved it can be done, chapeau. But the effects when removing the \toprule leave me deep in thought, currently... PS Interesting way of counting from 11 to 126 ;) – PHPirate Jan 02 '18 at 12:34