2

How to balance the columns of such declaration:

\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}

Obviously the values 0.4 and 1.6 have to be adjusted automatically at build time...

Example:

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

Where the odd column have size A and the even ones a size B? With this I guarantee that column 1 and 3 have always the same size, and column 2 and 4 are equally distributed in space.

In other words, the min width of the columns are determined as follow:

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]))

Then everything is stretch to fit in the \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)

Good parameters for such feature would be:

- 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
  • 1
    It is not very clear (to me) , what you like to have ... but see if you looking for something like this: \documentclass{article} \usepackage{tabularx} \begin{document} \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} \end{document} – Zarko Aug 5 '19 at 13:30
  • I have added an example – nowox Aug 5 '19 at 13:41
  • 2
    Why do you want to use tabularx for this? You could simply set the column type to p{some-calculated-width}. – Ulrike Fischer Aug 5 '19 at 13:45
  • Because the table should have the width \linewidth – nowox Aug 5 '19 at 13:46
  • 1
    The X column type is nothing but a p-type column for which LaTeX takes on the job of calculating the absolute width of the column should be, given information about the overall width of the tabularx environment, the number of X-type columns, and the number and width of any other columns. Since X columns, like p columns, are set up to allow automatic line breaking, it's not clear to me if there's enough information contained in the setup you've described to perform the required relative and absolute width calculations. – Mico Aug 5 '19 at 13:58
2

As I understand the question, tables should have a width equal to the width of the text. So, I don't see any advantages (maybe due to my vacation?) why not to use tabularx as I suggested in my comment below question:

\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}

enter image description here

(red lines indicate text borders)

| improve this answer | |
  • I agree with you that both tabularx and tabulary is a better choice than messing around with complicated calculation of column width. However, OP was of the opinion that he needed tabularx to typeset a tabular of specific width. In addition, standard tabular has some advantages. – Sveinung Aug 6 '19 at 11:48
  • @Sveinung, oh, now I see OP's confusion about purpose of the tabularx. – Zarko Aug 6 '19 at 11:52
  • And if you have to use multicolumn (and multirow?), section 4.3 in the tabularx-manual has a warning. However, I have, as far as I can remember, never run into any issues. I were the OP, I would have chosen to use tabularx as you describe, but defining new columntypes (as I have done). – Sveinung Aug 6 '19 at 12:01
  • @Sveinung, with the recent multirow you can use = option and with it preserve column specification, with \multicolumn you should be aware how the column widths are determined (about this you can find many answers on this site) – Zarko Aug 6 '19 at 12:09
  • @Sveinung, thank you very much for editing of my answer. Now MWE is complete and language improved! – Zarko Aug 6 '19 at 21:09
2

EDIT 20190807 At the end of the answer, I have included the code I recommend, an amalgamation of Zarko’s and my answer.

You may have a tabular to use the whole linewidth by calculating the width of p{}-columns as fractions of the linewidth. Just ensure that the total number of column widths accumulate to the linewidth. You have to subtract the correct number of tabcolseps, which is two per column (total eight for four columns). If you have vertical rules, you also have to subtract the correct numbers of arrayrulewidths.

I have ‘improved’ the previous example. If you look at the definition of an A-column, it now reads:

\newcolumntype{A}{>{\RaggedRight\arraybackslash}p{\dimexpr(1\textwidth)*25/100/2-1.5\tabcolsep\relax}}
  1. If you prefer centred or right aligned columns, you change \RaggedRight to \Centering or \RaggedLeft.
  2. If you need a tabular where the total width is less than the full linewidth, you change (1\linewidth) to the correct fraction. For example, if you need a tabular 80 per cent of the linewidth, you use (0.8\linewidth).
  3. The formula 25/100/2 is the relative width of the A-column, here 25%. This number is meant to be set so that the total of the newcolumntype is 100. Therefore, the B-column use 75/100. The last digit is the number of A-or B-columns.
  4. If you remove the left and right side bearings, (@{}), the number of tabcolseps to subtract will be two less than the total number of tabcolsepts. If you have four columns, you have to subtract six, if you have six columns, you have so subtract ten, etc. The formula will be -(2\tabcolsep-(\tabcolsep/<no. col.type>)). If you have three A-columns, you have to subtract -(2\tabcolsep-(\tabcolsep/3)).
  5. If you use vertical rules, you have to distribute the number of arrayruleswidth correctly, too. I leave it to you as an exercise to do that.

Above, I have assumed you will use equal number of each column types (ABAB, ABBA, ABBBAA etc.). In an automated calculation you have to take into consideration that the number of column types will be not equal (ABBAA, ABABA, etc.). So you will easily end up in a very complicated package. Probably it is better to use a calculator, pen and paper to fix the column width. Obviously, it is much faster.

NB! I emphasise that tabularx and tabulary already do all the maths for you. However, have a look at section 4.3 in the tabularx-manual.

Below I have enclosed code for a tabular with six columns:

enter image description here

\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}

Recommended example code

\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}
| improve this answer | |

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.