Equilibrar colunas tabulares automaticamente?

Equilibrar colunas tabulares automaticamente?

Como equilibrar as colunas dessa declaração:

\begin{tabularx}{\linewidth}{
  >{\hsize=0.4\hsize}X% 10% of 4\hsize
  >{\hsize=1.6\hsize}X% 30% of 4\hsize
  >{\hsize=0.4\hsize}X% 10% of 4\hsize
  >{\hsize=1.6\hsize}X% 30% of 4\hsize
  }
\end{tabularx}

Obviamente os valores 0.4devem 1.6ser ajustados automaticamente no momento da construção...

Exemplo:

     .--------- Same width ---------------.
     |                                    |
<----+--->                            <---+---->    
┌────────┬────────────────────────────┬────────┬───────────────────────────┐
│ A      │ B                          │ A      │ B                         │
├────────┼────────────────────────────┼────────┼───────────────────────────┤
│ 132132 │ Sed rutrum elit quis neque │ 42     │ Cras porta                │
└────────┴────────────────────────────┴────────┴───────────────────────────┘
         <------------+--------------->        <-------------+------------->
                      |                                      |
                      '------------- Same width -------------'

Onde as colunas ímpares têm tamanho Ae as pares têm tamanho B? Com isso garanto que as colunas 1 e 3 têm sempre o mesmo tamanho, e as colunas 2 e 4 estão igualmente distribuídas no espaço.

Em outras palavras, a largura mínima das colunas é determinada da seguinte forma:

min_widths[0] = min_widths[2] = max(map(width, columns[0] + columns[2]))
min_widths[1] = min_widths[3] = max(map(width, columns[1] + columns[3]))

Então tudo é esticado para caber em \linewidth:

if sum(min_widths) > \linewidth: 
    % Attempts to wrap some text and reduce the column sizes
else: 
    widths = map(lambda x: x * (\linewidth / sum(min_widths), min_widths)

Bons parâmetros para tal recurso seriam:

- Column alignment: left, center, right, raggedleft, raggedright
- Maximum width: e.g. 10em
- Minimum width: e.g. 0em
- Desired width ratio: 1
- Automatic wrapping: yes, no

Responder1

Aqui está uma solução com {NiceTabular}( nicematrix≥ 6,25a). Nesse ambiente, você tem uma chave columns-width=autoque exige que todas as colunas tenham a mesma largura, exceto as Xcolunas (que são semelhantes às Xcolunas de tabularx).

\documentclass{article}
\usepackage{nicematrix}
\usepackage{lipsum} % for dummy text

\begin{document}

\lipsum[1]
\begin{center}
\begin{NiceTabular}{lXlX}[columns-width=auto,hvlines]
A & B & A & B \\
132132 & Sed rutrum elit quis neque & 42 & Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna
fringilla ultrices. 
\end{NiceTabular}
\end{center}
\lipsum[2]

\end{document}

Saída do código acima

Responder2

EDITAR 20190807No final da resposta, incluí o código que recomendo, um amálgama da resposta de Zarko e da minha.

Você pode usar tabularo todo linewidthcalculando a largura de p{}-columns como frações de linewidth. Apenas certifique-se de que o número total de larguras de coluna se acumule em linewidth. Você deve subtrair o número correto de tabcolseps, que é dois por coluna (total de oito para quatro colunas). Se você tiver regras verticais, também deverá subtrair os números corretos de arrayrulewidths.

Eu 'melhorei' o exemplo anterior. Se você olhar a definição de uma A-column, agora ela lê:

\newcolumntype{A}{>{\RaggedRight\arraybackslash}p{\dimexpr(1\textwidth)*25/100/2-1.5\tabcolsep\relax}}
  1. Se preferir colunas centralizadas ou alinhadas à direita, altere \RaggedRightpara \Centeringou \RaggedLeft.
  2. Se você precisar de uma tabela onde a largura total seja menor que full linewidth, altere (1\linewidth)para a fração correta. Por exemplo, se você precisar de 80% tabulares de linewidth, use (0.8\linewidth).
  3. A fórmula 25/100/2é a largura relativa da Acoluna, aqui 25%. Este número deve ser definido de forma que o total newcolumntypeseja 100. Portanto, a B-coluna usa 75/100. O último dígito é o número de A-ou B-colunas.
  4. Se você remover os rolamentos do lado esquerdo e direito, ( @{}), o número de tabcolseps a subtrair será dois a menos que o número total de tabcolsepts. Se você tem quatro colunas, você tem que subtrair seis, se você tem seis colunas, você tem que subtrair dez,etc.. A fórmula será -(2\tabcolsep-(\tabcolsep/<no. col.type>)). Se você tiver três Acolunas, deverá subtrair -(2\tabcolsep-(\tabcolsep/3)).
  5. Se você usar regras verticais, também deverá distribuir o número arrayruleswidthcorretamente. Deixo para você um exercício para fazer isso.

Acima, presumi que você usará um número igual de cada tipo de coluna (ABAB, ABBA, ABBBAAetc..). Em um cálculo automatizado você deve levar em consideração que o número de tipos de colunas não necessariamente será o mesmo (você pode ter ABBAA, ABABA,etc..). Então você facilmente acabará com um pacote muito complicado. Provavelmente é melhor usar uma calculadora ou caneta e papel para fixar a largura da coluna. Obviamente, é muito mais rápido do que programá-lo em LaTeX.

Atenção! Enfatizo isso tabularxe tabularyjá faço todas as contas para você. No entanto, dê uma olhada na seção 4.3 do tabularxmanual.

Abaixo, anexei o código para uma tabela com seis colunas:

insira a descrição da imagem aqui

\documentclass{article}
\usepackage{array, booktabs, ragged2e}

\newcolumntype{A}{>{\RaggedRight\arraybackslash}p{\dimexpr(1\textwidth)*25/100/3-(2\tabcolsep-(\tabcolsep/3))\relax}}
\newcolumntype{B}{>{\Centering\arraybackslash}p{\dimexpr(1\textwidth)*75/100/3-(2\tabcolsep-(\tabcolsep/3))\relax}}
\usepackage{showframe}

\renewcommand*\ShowFrameColor{\color{red}}
\renewcommand*\ShowFrameLinethickness{.4pt}

\setlength{\tabcolsep}{2pt}

\begin{document}
{\centering
\begin{tabular}{@{}ABABBA@{}}

\toprule
A   &    B  &   A   &   B &   A   &   B\\
\midrule
Short left alig\-ned column & Wide centered column, which has lots of text & Short left alig\-ned column & Wide centered column, which has lots of text  & Wide centered column, which has lots of text & Short left alig\-ned column  \\
\bottomrule

\end{tabular}%
}
\end{document}

Código de exemplo recomendado

\documentclass{article}
\usepackage{booktabs, ragged2e}
\usepackage{tabularx} 
\newcolumntype{D}{>{\small\RaggedRight\arraybackslash\hsize=0.4\hsize}X}
\newcolumntype{E}{>{\small\Centering\arraybackslash\hsize=1.6\hsize}X}
\setlength{\tabcolsep}{1.5pt}

\begin{document}

\noindent\begin{tabularx}{\linewidth}{@{}DEDEED@{}}
\toprule
D   &    E  &   D   &   E  &   E   &   D\\
\midrule
Short left alig\-ned column & Wide centered column, which has lots of text & Short left alig\-ned column & Wide centered column, which has lots of text  & Wide centered column, which has lots of text & Short left alig\-ned column  \\
\bottomrule
\end{tabularx}
\end{document}

Responder3

Pelo que entendi a pergunta, as tabelas devem ter largura igual à largura do texto. Então, não vejo nenhuma vantagem (talvez devido às minhas férias?) por quenãopara usar tabularxcomo sugeri no meu comentário abaixo da pergunta:

\documentclass{article} 
\usepackage{tabularx} 

\begin{document}
    \begin{table}[ht]
\begin{tabularx}{\linewidth}{|*{2}{>{\hsize=0.4\hsize}X| >{\hsize=1.6\hsize}X|} } 
    \hline 
xxx xxx & xxx xxx xxx xxx xxx xxx xxx xxx 
    & xxx xxx & xxx xxx xxx xxx xxx xxx xxx xxx\\ 
    \hline 
\end{tabularx}
\caption{Four column}
    \end{table}
    \begin{table}[ht]
\begin{tabularx}{\linewidth}{|*{3}{>{\hsize=0.4\hsize}X| >{\hsize=1.6\hsize}X|} }
    \hline 
xxx xxx & xxx xxx xxx xxx xxx xxx xxx xxx 
    & xxx xxx & xxx xxx xxx xxx xxx xxx xxx xxx 
        & xxx xxx & xxx xxx xxx xxx xxx xxx xxx xxx\\
    \hline 
\end{tabularx}
\caption{Sixt column}
    \end{table}
\end{document}

insira a descrição da imagem aqui

(linhas vermelhas indicam bordas do texto)

informação relacionada