Estendendo uma tabela horizontalmente pelas páginas sem rotação ou usando paisagem

Estendendo uma tabela horizontalmente pelas páginas sem rotação ou usando paisagem

Eu tenho uma tabela muito larga, que gosto de se estender horizontalmente pelas páginas.

  \documentclass[runnngheads]{book}
    \usepackage{longtable}
    \begin{document}
    \begin{longtable}{*{25}c} 
        \hline 
        $a_1$ & $a_2$ & $a_3$ & $b_1$ & $b_2$ & $c_1$ & $c_2$ & $c_3$ & $d_1$ & $d_2$ & $i_1$ & $i_2$ & $e_1$ & $e_2$ & $h_1$ & $h_2$ &test&test 2&test 3 &test 4 & test 5 & test 6 & test 7 & test 8 & test 9\\ 
        \hline 
    \end{longtable}
    \end{document}

Alguma ideia de como fazer isso? Existem muitos exemplos de abrangência vertical, mas não consegui encontrar nenhum para o meu caso. E também não quero usar o modo paisagem.

Responder1

Aqui está uma solução rapidamente hackeada. Conforme observado por @DavidCarlisle, o \widesplitcomando deesta respostaé provavelmente uma solução melhor.

\documentclass[draft,runnngheads]{book}
\usepackage{mptab}
\begin{document}
\mptab{\the\columnsep}{\textwidth}{
  {$a_1$, $a_2$, $a_3$, $b_1$,                    $b_2$, $c_1$, $c_2$, $c_3$, $d_1$, $d_2$, $i_1$, $i_2$, $e_1$, $e_2$, $h_1$, $h_2$, test,  test22, test33, test 4, test 5, test 6, test 7, test 8, test 9},
  {$x_1$, $x_2$, $x_3$, $y_1$,                    $y_2$, $z_1$, $z_2$, $z_3$, $t_1$, $t_2$, $w_1$, $w_2$, $f_1$, $f_2$, $g_1$, $g_2$, hello, world,  bye,    bye,    lots,   of,     data,   beep,   boop},
  {$x_1$, $x_2$, $x_3$, $y_1$,                    $y_2$, $z_1$, $z_2$, $z_3$, $t_1$, $t_2$, $w_1$, $w_2$, $f_1$, $f_2$, $g_1$, $g_2$, hello, world,  bye,    bye,    lots,   of,     data,   beep,   boop},
  {1,     2,     3,    a rather very long cell,  5,     6,     7,     8,     9,     10,    11,    12,    13,    14,    15,    16,    17,    18,     19,     20,     21,     22,     23,     24,     25},
}
\end{document}

O que dá o seguinte PDF de 3 páginas: Três páginas, com as primeiras colunas na primeira página, as colunas seguintes na segunda página e as últimas colunas na terceira página.

E aqui está mptab.sty:

Provavelmente contém uma quantidade nutritiva de bugs e complexidade desnecessária, usa vírgula em vez de &e colchetes em vez de \\. Ele não suporta \hlinee não fiz isso para que você possa especificar o formato (por exemplo, linhas verticais |não são possíveis). Tudo isso deve ser bastante simples de adicionar ao código, e incluí alguns comentários. A única coisa difícil para mim seria fazê-lo aceitar a sintaxe &and \\, já que não estou familiarizado com a conexão com esses recursos do TeX repletos de catcode de baixo nível. Ele também usa um \newlengthquando provavelmente poderia escapar usando \bgroup…\egroupuma dimensão temporária existente e usa \global em excesso em muitos lugares.

Mas funciona, pelo menos em casos simples.

Qualquer melhoria é bem-vinda, e esse código sujo é de domínio público (CC0, WTFPL, você escolhe). Tentarei adicionar uma alternativa à \hlineespecificação de formato e a possibilidade de misturar pedaços da tabela e do texto, se tiver tempo (sem promessas!).

\usepackage{tikz}
\newlength{\mylen}
%
\newif\iffirstcolumn%
\newif\iffirstline%
\xdef\i{0}% Initialize column counter before first iteration.
\def\mptab#1#2#3{%
  \bgroup%
  \setlength\columnsep{#1}%
  % row counter:
  \xdef\j{0}%
  % Loop over lines:
  \global\firstlinetrue%
  \foreach \y in {#3}{%
    % Increment row counter
    \xdef\oldj{\j}%
    \pgfmathtruncatemacro{\j}{\j+1}%
    \xdef\j{\j}%
    % Column counter:
    \xdef\oldi{\i}%
    \xdef\i{0}%
    \foreach \x in \y{%
      % Increment column counter:
      \pgfmathtruncatemacro{\i}{\i+1}%
      \xdef\i{\i}%
      % Compute width of current column
      \settowidth{\mylen}{\x}%
      \iffirstline%
        \expandafter\xdef\csname column\i maxwidth\endcsname{\the\mylen}%
      \else%
        % Make an alias for the currently computed column max width, for convenient access:
        \expandafter\let\expandafter\currentcolumnmaxwidth\csname column\i maxwidth\endcsname%
        % Compare this cell's width:
        \ifdim\mylen>\currentcolumnmaxwidth\relax%
          % And update the column's max width when the current cell is wider:
          \expandafter\xdef\csname column\i maxwidth\endcsname{\the\mylen}%
        \fi%
      \fi%
      % Remember the contents of this cell:
      \global\expandafter\let\csname cell\i x\j\endcsname\x%
    }%
    \global\firstlinefalse%
  }
  % 
  % Remember last column number:
  % For some reason, the foreach loop from tikz gives the line with an extra
  % pair of braces (which breaks the inner loop, as it sees only one value)
  % when there's no trailing comma after the last line, but gives an empty
  % line when there is a trailing comma. We detect this idiosyncrasy here and
  % revert the last column number and last line:
  \ifnum\i=0\relax%
    \xdef\lastcolumn{\oldi}%
    \xdef\lastline{\oldj}%
  \else%
    % We still keep the "reasonnable" behaviour here, just in case.
    \xdef\lastcolumn{\i}%
    \xdef\lastline{\j}%
  \fi%
  % \message{Last line: \lastline, Last column: \lastcolumn}%
  % 
  %
  % Initialization for the loop which aggregates all cells per page:
  \expandafter\xdef\csname tablepage1\endcsname{}%
  \expandafter\xdef\csname tableformat1\endcsname{}%
  \global\firstlinetrue%
  % Counter for the last page:
  \xdef\maxtablepage{1}%
  %
  % Loop over lines, aggregating each cell in its page.
  \foreach \y in {1,...,\lastline}{%
    \global\setlength{\mylen}{0pt}%
    \xdef\curtablepage{1}
    \global\firstcolumntrue%
    % Loop over the columns, aggregating each cell in its page.
    \foreach \x in {1,...,\lastcolumn}{%
      \global\addtolength{\mylen}{\columnsep}%
      \global\addtolength{\mylen}{\csname column\x maxwidth\endcsname}%
      \global\addtolength{\mylen}{\columnsep}%
      \ifdim\mylen>#2\relax%
        % Push to next page
        % Reset loop variables:
        \global\setlength{\mylen}{0pt}%
        % Re-add current cell width:
        \global\addtolength{\mylen}{\columnsep}%
        \global\addtolength{\mylen}{\csname column\x maxwidth\endcsname}%
        \global\addtolength{\mylen}{\columnsep}%
        % Bump table page number:
        \pgfmathtruncatemacro{\curtablepage}{\curtablepage+1}%
        \xdef\curtablepage{\curtablepage}
        % Initialize new empty page and format:
        \iffirstline
          \expandafter\xdef\csname tablepage\curtablepage\endcsname{}%
          \expandafter\xdef\csname tableformat\curtablepage\endcsname{}%
          % Bump the counter for the last page
          \xdef\maxtablepage{\curtablepage}%
        \fi
        % We're back on the first column:
        \global\firstcolumntrue%
      \fi%
      % Still fits on this page (or we just created a brand new page):
      % Create convenient aliases for the current page, format and cell:
      \expandafter\let\expandafter\thiscell\csname cell\x x\y\endcsname%
      \expandafter\let\expandafter\thistablepage\csname tablepage\curtablepage\endcsname%
      \expandafter\let\expandafter\thistableformat\csname tableformat\curtablepage\endcsname%
      % If we're on the first line, add a new column to the format
      \g@addto@macro\thistableformat{@{\hspace{\the\columnsep}}l@{\hspace{\the\columnsep}}}% THE COLUMN FORMAT HERE
      % Write back to \csname tableformat\curtablepage\endcsname:
      \global\expandafter\let\csname tableformat\curtablepage\endcsname\thistableformat%
      % 
      % The \expandafter and \noexpand tricks
      % are from https://tex.stackexchange.com/a/60976/5699
      % and from https://tex.stackexchange.com/a/67368/5699
      \iffirstcolumn%
      \global\firstcolumnfalse%
      \edef\doit{%
        \noexpand\g@addto@macro\noexpand\thistablepage{%
          % \noexpand\hspace{\noexpand\columnsep}%
          \expandafter\noexpand\thiscell%
          % \noexpand\hspace{\noexpand\columnsep}%
        }%
      }%
      \else%
      \edef\doit{%
        \noexpand\g@addto@macro\noexpand\thistablepage{%
          % \noexpand\hspace{\noexpand\columnsep}%
          & \expandafter\noexpand\thiscell%
          % \noexpand\hspace{\noexpand\columnsep}%
        }%
      }%
      \fi%
      \doit%
      % Write back to \csname tablepage\curtablepage\endcsname:
      \global\expandafter\let\csname tablepage\curtablepage\endcsname\thistablepage%
    }%
    %Add a \\ at the end of the line on each page:
    \foreach \curtablepage in {1,...,\maxtablepage}{%
      % Make an alias
      \expandafter\let\expandafter\thistablepage\csname tablepage\curtablepage\endcsname%
      % Add the "\\"
      \edef\doit{%
        \noexpand\g@addto@macro\noexpand\thistablepage{%
          \noexpand\\%
        }%
      }%
      \doit%
      % Write back to \csname tablepage\curtablepage\endcsname:
      \global\expandafter\let\csname tablepage\curtablepage\endcsname\thistablepage%
    }
    %Finished handling the line:
    \global\firstlinefalse
  }%
  %
  % 
  \foreach \i in {1,...,\curtablepage}{%
    \noindent\begin{tabular}{\csname tableformat\i\endcsname|}%
      \csname tablepage\i\endcsname%
    \end{tabular}%
    \clearpage%
  }%
  %
  \egroup%
}%

informação relacionada