\documentclass[letterpaper,10pt]{article}

\usepackage[english]{babel}
\usepackage[T1]{fontenc}
\usepackage[ansinew]{inputenc}

\usepackage[sc]{mathpazo}	% Palatino with math symbols
\usepackage[scaled=.85]{luximono}
\linespread{1.05}	% Palatino needs more leading (space between lines)
\usepackage{microtype}	% micro-typographic enhancements

%\usepackage[active,tightpage,floats]{preview}
%\setlength\PreviewBorder{5pt}

\newcommand{\cmd}[1]{\texttt{#1}}
\renewcommand{\oldstylenums}[1]{{\renewcommand{\rmdefault}{pplj}\rmfamily #1}}
\newcommand{\newstylenums}[1]{{\renewcommand{\rmdefault}{pplx}\rmfamily #1}}

\usepackage{tikz}

\colorlet{bordeaux}{red!80!black}

%----- Nice listings: ------------------------------------------------

\usepackage{listings}
\lstset{basicstyle=\small\ttfamily} % small fixed-width font
\lstset{tabsize=2}
\lstset{gobble=1} % remove 1 leading character (should be the indentation tab)
\lstset{backgroundcolor=\color{gray!10}} % background in a light gray
\lstset{frame=tb} % lines above and below
\lstset{rulecolor=\color{gray!50}} % colored in a slightly darker gray
\lstset{language=[LaTeX]TeX} % all listings are LaTeX code
\lstset{texcsstyle=*\bfseries} % make backslash bold as well
\lstset{moretexcs={toprule,addlinespace,cmidrule,bottomrule,eqparbox,newcolumntype,@ifpackageloaded}}

%----- Nice tables: --------------------------------------------------

\usepackage{booktabs}	% publication-quality tables

\makeatletter % roughly emulate the booktabs look
\@ifpackageloaded{booktabs}{}{
	\newcommand{\toprule}{\hline}
	\newcommand{\addlinespace}{\\[-0.7em]}
	\newcommand{\cmidrule}[5]{\cline{#5}} % this only works if there's always \cmidrule(lr){...}
	\newcommand{\bottomrule}{\hline}
}
\makeatother

\usepackage{eqparbox}	% sub-align table cells
\usepackage{array} % provides \newcolumntype. Already loaded by eqparbox

\newcommand{\eqparboxr}[2]{\eqparbox{#1}{\raggedleft #2}}

\newsavebox{\tempbox}
\makeatletter
\@ifpackageloaded{microtype}
{ % microtype package loaded
	\newcolumntype{A}[1]{%
		>{ \begin{lrbox}{\tempbox} }%
		c%
		<{ \end{lrbox}%
		   \eqparbox{#1}{\microtypesetup{activate=false}%
		                 \strut\raggedright\unhcopy\tempbox}%
		 }%
	}
	\newcolumntype{B}[1]{%
		>{ \begin{lrbox}{\tempbox} }%
		c%
		<{ \end{lrbox}%
		   \eqparbox{#1}{\microtypesetup{activate=false}%
		                 \strut\raggedleft\unhcopy\tempbox}%
		 }%
	}
}{ % microtype package not loaded
	\newcolumntype{A}[1]{%
		>{ \begin{lrbox}{\tempbox} }%
		c%
		<{ \end{lrbox}%
		   \eqparbox{#1}{\strut\raggedright\unhcopy\tempbox}%
		 }%
	}
	\newcolumntype{B}[1]{%
		>{ \begin{lrbox}{\tempbox} }%
		c%
		<{ \end{lrbox}%
		   \eqparbox{#1}{\strut\raggedleft\unhcopy\tempbox}%
		 }%
	}
}
\makeatother

% Three more packages to format figures inside tables:

\usepackage{siunitx}
\usepackage{dcolumn}
\usepackage[rounding]{rccol}	% alternatively use `norounding'

%---------------------------------------------------------------------

\begin{document}

\title{`Block-centered' alignment \\ inside \LaTeX{} tables}
\author{Burkart Lingner}

\maketitle
\vspace{2cm}
\begin{abstract}
By default \LaTeX{} tables allow three basic types of column alignment: Left-aligned, centered, and right-aligned. Sometimes neither of these choices looks very good, particularly if the column header is wider than the contents of the column body. Several packages exist to deal with this issue. However, they are restricted to figures and don't work with text in the table body. Using the \emph{eqparbox} package it's possible to define a new column type which i.e.\ right-aligns the column's contents and then collectively centers the whole block in regard to the column header. After describing the general idea this article also shows how to avoid minor horizontal or vertical misalignments like those introduced by the \emph{microtype} package.
\end{abstract}

\clearpage

\section{The problem} %-----------------------------------------------

When you create \LaTeX{} tables using the \cmd{tabular} environment you have to specify the alignment per column. You can choose between the four specifiers \cmd{l}, \cmd{c}, \cmd{r}, and \cmd{p}. The first three make sure the column is left-aligned, centered, or right-aligned, respectively. The specifier `\cmd{p}' also left-aligns the contents, however in contrast to the `\cmd{l}' specifier it requires an additional parameter that sets the column's width. If the text is wider than the defined column width \LaTeX{} performs automatic line-break and justifies the text to the specified width.

\begin{table}[h]
\centering
\begin{tabular}{l c r p{3cm}}
	\toprule
	\addlinespace
	\cmd{l} & \cmd{c} & \cmd{r} & \cmd{p\{3cm\}} \\
	\cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}
	\addlinespace
	Lorem & Lorem & Lorem & Lorem ipsum dolor sit amet \\ % produces a line-break
%	Lorem & Lorem & Lorem & Lorem \\
	Ipsum & Ipsum & Ipsum & Ipsum \\
	Dolor & Dolor & Dolor & Dolor \\
	Sit   & Sit   & Sit   & Sit   \\
	Amet  & Amet  & Amet  & Amet  \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

Often times the default column types are sufficient to produce good-looking tables. One thing crucial is the width of each column header compared to that of the column body. In the example above the column headers are narrow compared to the text in the body. Take a look at the example below where it's the other way around.

\begin{table}[h]
\centering
\begin{tabular}{l l c A{row-id1}}
	\toprule
	\addlinespace
	&
		\multicolumn{1}{c}{This looks bad} &
		\multicolumn{1}{c}{This looks worse} &
		\multicolumn{1}{c}{This is much better} \\
	\cmidrule(lr){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}
	\addlinespace
	Lorem &Some & Some & Some \\
	Ipsum & short & short & short \\
	Dolor & text & text & text \\
	Sit & to prove & to prove & to prove \\
	Amet & a point & a point & a point \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

As you can see it looks better to have text left-aligned than to have it centered. Even the left-aligned column looks less than favorable though, as the column header is wider than the body which produces a lot of white space to the right of the table body text. One solution might be to break the column header into multiple lines. The other solution is shown in the right column: The text from the various rows is left-aligned relative to each other and that whole block is centered in regards to the column header. The technique to achieve this type of alignment is described below.

\section{Figure-only columns} %---------------------------------------

Some packages exist to create better-looking column alignment than \LaTeX{} offers by default. However, they are restricted to work with figures. This may stem from them being used predominantly inside tables, but it's also just a lot easier to properly align them. This is because in most fonts the width of each digit is the same whereas for letters and other characters that's generally not the case. Therefore, if you know the number of digits you want to typeset you can get the figure's total width through a simple multiplication~-- regardless of what actual digits the figure is made up from.

The table below shows the output generated using the standard `\cmd{l}' column specifier as well as that from the three packages \emph{siunitx}, \emph{dcolumn}, and \emph{rccol}.
\begin{table}[h]
\centering
\begin{tabular}{l S[tabnumalign=centre,tabformat=2.3] D{.}{.}{2.3} R[.]{4}{3}}
	\toprule
	\addlinespace
	\emph{\LaTeX{}:} \cmd{l} &
		{\emph{siunitx:} \cmd{S[\ldots]}} &
		\multicolumn{1}{c}{\emph{dcolumn:} \cmd{D\{.\}\{.\}\{2.3\}}} &
		\multicolumn{1}{c}{\emph{rccol:} \cmd{R[.]\{4\}\{3\}}} \\
	\cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}
	\addlinespace
	3.141 & 3.141 & 3.141 & 3.141 \\
	1.0   & 1.0   & 1.0   & 1.0   \\
	0.05  & 0.05  & 0.05  & 0.05  \\
	23    & 23    & 23    & 23    \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

The \emph{siunitx} package does a lot more than align table contents properly. It is useful when dealing with physical units which is why you may already use it in your document. When dealing with tables you can use the column specifier `S' provided by the package. It can be customized to result in an alignment like the one shown above. It was generated with the column specifier \cmd{S[tabnumalign=centre,tabformat=2.3]}. The `\cmd{2.3}' informs \LaTeX{} that the column width is that of two integer digits plus the decimal point plus three radix digits. You have to make sure this setting matches the column's data, otherwise the alignment will not be proper anymore. In order to exempt the column header---which is usually some text---from the figure alignment, place it inside braces. For more details on the customization options refer to the \emph{siunitx} package documentation.

In cases where your table contains plain figures without any units you can get the same output by using the \emph{dcolumn} package. It also requires you to define the figure format inside the column specification. Additionally, you have to specify the character used as a decimal point in your \TeX{} sources and the one which should be used in the output. This would for instance allow you to process figures with a decimal point in your sources to be displayed with a decimal comma in the output, which is required i.e.\ in a German text. This is achieved through the column specifier \cmd{D\{.\}\{,\}\{2.3\}}. As the column header or any other text part can't be properly formatted when using the `\cmd{D}' column specifier, you have to change the column type for them. To do that, use \cmd{\textbackslash multicolumn\{1\}\{c\}\{Column header text\}}.

Finally, the third solution to properly align figures inside tables comes with the package \emph{rccol}. In its most basic form it produces an output just like that obtained using the \emph{dcolumn} package. The only difference is the column specifier letter `R' and the slightly different syntax to define source and output decimal sign as well as the number of digits before and after the decimal point. One thing special about \emph{rccol} is its ability to round figures to the specified number of digits. Rounding is enabled by loading the package via \cmd{\textbackslash usepackage[rounding]\{rccol\}} and disabled with the parameter \cmd{norounding}. When using text, i.e.\ in the column header, you also have to escape it as \cmd{\textbackslash multicolumn\{1\}\{c\}\{Column header text\}} since \LaTeX{} otherwise complains about a missing number.

The \emph{numprint} package may be another option, particularly when dealing with figures using scientific notation, i.e.\ $1.23 \cdot 10^{45}$. Please refer to the package documentation on how to use it.

When typesetting figures one has to differentiate between old-style figures and lining figures. The latter have a constant height which equals that of upper-case letters that don't extend below the baseline, like `A' but unlike `J' and `Q'. In contrast, old-style figures have varying heights that may be equal to that of a lower-case `x', i.e.\ `\oldstylenums{1}', or have ascenders like `d', i.e.\ `\oldstylenums{6}', or descenders like `p', i.e.\ `\oldstylenums{9}'. This property makes old-style figures mesh well with running text or small-caps whereas lining figures look better in conjunction with upper-case letters.

\begin{table}[h]
\centering
\begin{tabular}{c c}
	\toprule
	\addlinespace
	Old-style figures & Lining figures \\
	\cmidrule(lr){1-1}\cmidrule(lr){2-2}
	\addlinespace
	\oldstylenums{0123456789} & \newstylenums{0123456789} \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

In math mode it's strongly recommended to use lining figures, as the varying height of old-style figures might lead to regular numbers being interpreted as subscripts or superscripts. Apparently this is why the configuration parameter \cmd{[osf]} of the \emph{mathpazo} package enables old-style figures solely in text mode but keeps using lining figures in math mode. This becomes important when using either \emph{siunitx} or \emph{dcolumn} to align table figures. Both packages use math mode to typeset figures which means figures in the respective table columns will be typeset using lining figures. Whether that is a good or a bad thing depends on your personal preferences. When using the \emph{siunitx} package you can switch to old-style figures on a per-column basis by adding the argument \cmd{[valuemode=text]} to the column specifier `\cmd{S}'.

\section{The initial solution} %--------------------------------------

The previous section described how to properly align figures inside tables. Neither of the packages described offers any solution to aligning text, though. The major problem is that in contrast to figures the width of text is variable (aside from fixed-width fonts). Because of that it's impossible to specify the text's width without parsing it first. Unfortunately, for proper alignment you would have to know the width in advance.

A solution comes in the form of the \emph{eqparbox} package. It provides the \cmd{\textbackslash eqparbox\{ID\}\{content\}} command. In a first step the maximum width of all eqparboxes with the same ID is calculated. This requires parsing of the whole document so that the result can be used in a subsequent \LaTeX{} run. Once the maximum width is known, the content of each eqparbox is placed in a regular parbox of said maximum width. Putting these boxes in a centered table column results in an output like the one shown below.

\begin{table}[h]
\centering
\begin{tabular}{l c}
	\toprule
	\addlinespace
	      & Wide column header                  \\
	\cmidrule(lr){2-2}
	\addlinespace
	Lorem & \eqparbox{demo-id}{\strut Some}     \\
	Ipsum & \eqparbox{demo-id}{\strut short}    \\
	Dolor & \eqparbox{demo-id}{\strut text}     \\
	Sit   & \eqparbox{demo-id}{\strut to prove} \\
	Amet  & \eqparbox{demo-id}{\strut a point}  \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

The following source code was used to generate the table above:

\begin{lstlisting}
	\usepackage{booktabs}	% publication-quality tables
	\usepackage{eqparbox}	% sub-align table cells
	
	\begin{tabular}{l c}
		\toprule
		\addlinespace
		      & A wide column header                \\
		\cmidrule(lr){2-2}
		\addlinespace
		Lorem & \eqparbox{demo-id}{\strut Some}     \\
		Ipsum & \eqparbox{demo-id}{\strut short}    \\
		Dolor & \eqparbox{demo-id}{\strut text}     \\
		Sit   & \eqparbox{demo-id}{\strut to prove} \\
		Amet  & \eqparbox{demo-id}{\strut a point}  \\
		\addlinespace
		\bottomrule
	\end{tabular}
\end{lstlisting}

It works but is quite inflexible when it comes to modifying the column layout later on. Having the text right-aligned inside the block could be achieved relatively easy by creating a macro \cmd{\textbackslash eqparboxr} (notice the additional `r') via \cmd{\textbackslash newcommand\{\textbackslash eqparboxr\}[2]\{\textbackslash eqparbox\{\#1\}\{\textbackslash raggedleft \#2\}\}} and then replacing the \cmd{\textbackslash eqparbox} command with it. The major weakness remains though, in that the same modification has to be performed for each line of the table.

Before we move on to the comfortable solution let's examine the importance of the \cmd{\textbackslash strut} commands used in the example above. They advise \TeX{} to increase the height of the box the words are put in so that it would fit both ascenders and descenders. Without an explicit \cmd{\textbackslash strut} the box is made to accurately fit the height of the particular text. Possibly due to a bug in the \cmd{\textbackslash eqparbox} implementation this results in a mismatch of the baseline. The enlarged example below demonstrates the effect.

\begin{table}[h]
\centering
\Large
\begin{tabular}{>{\Huge}l >{\Huge}c >{\Huge}c}
	\toprule
	\addlinespace
	&
		\multicolumn{1}{c}{\enspace Without \cmd{\textbackslash strut}\enspace{} } &
		\multicolumn{1}{c}{\quad With \cmd{\textbackslash strut}\quad{} } \\
	\cmidrule(lr){2-2}\cmidrule(lr){3-3}
	\addlinespace
	\Huge\tikz[overlay]\draw[bordeaux,thick] (0,0) -- (9.85,0);Lorem &
		\eqparbox{no-strut}{Some}     &
		\eqparbox{with-strut}{\strut Some}     \\
	\Huge\tikz[overlay]\draw[bordeaux,thick] (0,0) -- (9.7,0);Ipsum &
		\eqparbox{no-strut}{short}    &
		\eqparbox{with-strut}{\strut short}    \\
	\Huge\tikz[overlay]\draw[bordeaux,thick] (0,0) -- (9.2,0);Dolor &
		\eqparbox{no-strut}{text}     &
		\eqparbox{with-strut}{\strut text}     \\
	\Huge\tikz[overlay]\draw[bordeaux,thick] (0,0) -- (10.9,0);Sit   &
		\eqparbox{no-strut}{to prove} &
		\eqparbox{with-strut}{\strut to prove} \\
	\Huge\tikz[overlay]\draw[bordeaux,thick] (0,0) -- (10.5,0);Amet  &
		\eqparbox{no-strut}{a point}  &
		\eqparbox{with-strut}{\strut a point}  \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

As you can see, text with descenders inside an \cmd{\textbackslash eqparbox} without \cmd{\textbackslash strut} is positioned too high whereas text with ascenders is positioned too low. Adding a \cmd{\textbackslash strut} remedies the problem.

\section{The comfortable solution} %----------------------------------

It is desirable to specify an entire column as `block-centered' instead of doing so for every table entry. Much like the alignment of figure-only columns described earlier, one would want a column specifier that contains all of the alignment details whereas the table body consists solely of the raw data. Fortunately this is possible utilizing the \cmd{\textbackslash newcolumntype} command provided by the \emph{array} package which is automatically loaded by the \emph{eqparbox} package. By writing \cmd{\textbackslash newcolumntype\{i\}[1]\{ >\{\textbackslash itshape\} c <\{\#1\} \}} you could for example create a new column specifier `i\{argument\}' that would produce italic, centered output followed by what's defined as the column specifier's argument. Now you could produce a table like the one below.

\newcolumntype{i}[1]{ >{\itshape} c <{#1} }

\begin{table}[h]
\centering
\begin{tabular}{i{.} i{\,\upshape\scriptsize[latin]}}
	\toprule
	\addlinespace
	\multicolumn{1}{c}{\cmd{i\{.\}}} &
		\multicolumn{1}{c}{\cmd{i\{\textbackslash,\textbackslash upshape\textbackslash scriptsize[latin]\}}} \\
	\cmidrule(lr){1-1}\cmidrule(lr){2-2}
	\addlinespace
	Lorem & Lorem \\
	Ipsum & Ipsum \\
	Dolor & Dolor \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

In trying to apply the same idea to an \cmd{\textbackslash eqparbox} column specifier we encounter a problem. The argument is put in braces and \LaTeX{} has no means to distinguish them from the braces of the \cmd{\textbackslash newcolumntype} command. Thus writing \cmd{\textbackslash newcolumntype\{x\}[1]\{ >\{\textcolor{bordeaux}{\textbackslash eqparbox\{\#1\}\{}\} c <\{\textcolor{bordeaux}{\}}\} \}} results in an error as the red braces inside \cmd{>\{\}} and \cmd{<\{\}} are unbalanced.

Solving this problem requires a more elaborate approach. First, a temporary storage box is defined using \cmd{\textbackslash newsavebox\{\textbackslash tempbox\}}. The storage is filled with what's inside a \cmd{\textbackslash begin\{lrbox\}\{\textbackslash tempbox\}\ \ldots\ \kern-1pt\textbackslash end\{lrbox\}} block. The box can then be typeset using \cmd{\textbackslash unhcopy\textbackslash tempbox}. Putting it all together yields the following \LaTeX{} code:

\begin{lstlisting}
	\newsavebox{\tempbox}
	\newcolumntype{X}[1]{%
		>{ \begin{lrbox}{\tempbox} }%
		c%
		<{ \end{lrbox}%
		   \eqparbox{#1}{\strut\unhcopy\tempbox}%
		 }%
	}
\end{lstlisting}

Using this new column specifier you can now write the previous example more comfortably as

\begin{lstlisting}
	\begin{tabular}{l X{demo-id2}}
		\toprule
		\addlinespace
		      & \multicolumn{1}{c}{A wide column header} \\
		\cmidrule(lr){2-2}
		\addlinespace
		Lorem & Some     \\
		Ipsum & short    \\
		Dolor & text     \\
		Sit   & to prove \\
		Amet  & a point  \\
		\addlinespace
		\bottomrule
	\end{tabular}
\end{lstlisting}

This gives the same result as before, but with less typing and more flexibility regarding modifications at a later time.

\newcolumntype{X}[1]{%
	>{ \begin{lrbox}{\tempbox} }%
	c%
	<{ \end{lrbox}%
	   \eqparbox{#1}{\strut\unhcopy\tempbox}%
	 }%
}
\begin{table}[h]
\centering
\begin{tabular}{l X{demo-id2}}
	\toprule
	\addlinespace
	      & \multicolumn{1}{c}{A wide column header} \\
	\cmidrule(lr){2-2}
	\addlinespace
	Lorem & Some     \\
	Ipsum & short    \\
	Dolor & text     \\
	Sit   & to prove \\
	Amet  & a point  \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

Notice, however, that with the new column specifier the column header has to be encapsulated inside a \cmd{\textbackslash multicolumn} command. In contrast to the alignment of figures using special column specifiers that don't work with text, this time omitting the \cmd{\textbackslash multicolumn} produces only a semantic error. As the wide header would be included in the width calculations the end result would be a left-aligned column much like that generated using the `\cmd{l}' column specifier.

Before we can get to the final solution there's one more issue to be addressed. The \emph{microtype} package by default enables margin kerning which slightly shifts some characters into the page margin in order to produce a margin that looks straight to the human eye. Inside tables with a default \LaTeX{} column specifier like `\cmd{r}' this feature is disabled, but when using the newly defined `\cmd{X}' specifier it is activated again.

\begin{table}[h]
\centering
\Large
\begin{tabular}{>{\Huge}c >{\Huge}c}
	\toprule
	\addlinespace
	\multicolumn{1}{c}{\quad\emph{microtype} enabled\quad{} } &
		\multicolumn{1}{c}{\quad\emph{microtype} disabled\quad{} } \\
	\cmidrule(lr){1-1}\cmidrule(lr){2-2}
	\addlinespace
	\eqparboxr{mutype-on}{\strut173\,\ldots
	\tikz[overlay]\draw[bordeaux,thick] (-0.25em,0.75em) -- (-0.25em,-2.625em)
	;174\tikz[overlay]\draw[bordeaux,thick] (-1pt,0.75em) -- (-1pt,-2.625em);} &
		\eqparboxr{mutype-off}{\microtypesetup{activate=false}\strut173\,\ldots
		\tikz[overlay]\draw[bordeaux,thick] (-0.25em,0.75em) -- (-0.25em,-2.625em)
		;174\tikz[overlay]\draw[bordeaux,thick] (-1pt,0.75em) -- (-1pt,-2.625em);} \\
	\eqparboxr{mutype-on}{\strut175\,\ldots 361} &
		\eqparboxr{mutype-off}{\microtypesetup{activate=false}\strut175\,\ldots 361} \\
	\eqparboxr{mutype-on}{\strut362\,\ldots 598} &
		\eqparboxr{mutype-off}{\microtypesetup{activate=false}\strut362\,\ldots 598} \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

As you can see in the enlarged example above, the middle row gets slightly shifted to the right if \emph{microtype} is loaded and margin kerning is activated. This properly aligns the one in 361 to the four in 174, but it also misaligns the dots. Additionally, the 175 is misaligned relative to the 173. The solution with \emph{microtype} disabled is better-looking as the alignment of the numbers to the left and of the dots is more important than a smooth right border.

The simple solution is to globally disable \emph{microtype} or at least its margin kerning feature. Of course this can only be a last resort, and luckily another option is available. The command \cmd{\textbackslash microtypesetup\{activate=false\}} can be used to selectively disable \emph{microtype}. This command, however, is only defined if the \emph{microtype} package has been loaded. A generally applicable solution is required not to break depending on the packages loaded. Therefore it requires a switch based on \cmd{\textbackslash @ifpackageloaded}. Depending on how that command evaluates the column specifier is defined to either deactivate \emph{microtype} inside the table or not bother because the package isn't loaded.

\begin{lstlisting}
	\newsavebox{\tempbox}
	\makeatletter
	\@ifpackageloaded{microtype}
	{ % microtype package loaded
		\newcolumntype{A}[1]{%
			>{ \begin{lrbox}{\tempbox} }%
			c%
			<{ \end{lrbox}%
			   \eqparbox{#1}{\microtypesetup{activate=false}%
			                 \strut\raggedright\unhcopy\tempbox}%
			 }%
		}
		\newcolumntype{B}[1]{%
			>{ \begin{lrbox}{\tempbox} }%
			c%
			<{ \end{lrbox}%
			   \eqparbox{#1}{\microtypesetup{activate=false}%
			                 \strut\raggedleft\unhcopy\tempbox}%
			 }%
		}
	}{ % microtype package not loaded
		\newcolumntype{A}[1]{%
			>{ \begin{lrbox}{\tempbox} }%
			c%
			<{ \end{lrbox}%
			   \eqparbox{#1}{\strut\raggedright\unhcopy\tempbox}%
			 }%
		}
		\newcolumntype{B}[1]{%
			>{ \begin{lrbox}{\tempbox} }%
			c%
			<{ \end{lrbox}%
			   \eqparbox{#1}{\strut\raggedleft\unhcopy\tempbox}%
			 }%
		}
	}
	\makeatother
\end{lstlisting}

\section{Conclusion} %------------------------------------------------

The solution presented above allows to create `block-aligned' table rows with the contents of the block being either left-aligned or right aligned towards each other using column specifier `A' or `B', respectively. The actual letters can be modified if they conflict with those introduced by other packages. Unless you know what you're doing every column should have a unique identifier defined as part of the column specifier. Column headers or other elements that should be exempt from the alignment are to be encapsulated in a \cmd{\textbackslash multicolumn\{1\}\{c\}\{contents\}} construct. Two \LaTeX{} runs are required to get the maximum width per column identifier and thereby the proper alignment. Both horizontal and vertical alignment of the table data is assured. Now you know how to make tables with columns like the right one in the example below.

\begin{table}[h]
\centering
\begin{tabular}{l r c B{row-id2}}
	\toprule
	\addlinespace
	&
		\multicolumn{1}{c}{This looks bad} &
		\multicolumn{1}{c}{This looks worse} &
		\multicolumn{1}{c}{This is much better} \\
	\cmidrule(lr){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}
	\addlinespace
	Lorem &   1\,\ldots 172 &   1\,\ldots 172 &   1\,\ldots 172 \\
	Ipsum & 173\,\ldots 174 & 173\,\ldots 174 & 173\,\ldots 174 \\
	Dolor & 175\,\ldots 361 & 175\,\ldots 361 & 175\,\ldots 361 \\
	Sit   & 362\,\ldots 598 & 362\,\ldots 598 & 362\,\ldots 598 \\
	\addlinespace
	\bottomrule
\end{tabular}
\end{table}

Honestly this output could have been achieved using the \emph{dcolumn} package and a \cmd{D\{!\}\{\textbackslash,\textbackslash ldots\textbackslash,\}\{3.3\}} column specifier in conjunction with source code data in the form \cmd{1!172} as well. However, \emph{dcolumn} uses math mode to display both digits and separator, so this might restrict its use. If, for example, instead of the dots any kind of text should be used to replace the exclamation mark, it would be in italics.

\end{document}