1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
|
\documentclass{article}
\usepackage{vcell,url,booktabs,multirow,tabularx,listings,ragged2e,color,colortbl}
\lstloadlanguages{[LaTeX]TeX}
\lstset{
basicstyle=\ttfamily,
columns=fullflexible,
backgroundcolor=\color[rgb]{0.82,0.82,0.82},
language=[LaTeX]TeX}
\begin{document}
\title{The package \texttt{vcell} : Vertical alignment for cells}
\author{Xavier Dionne\thanks{The author wrote this package for its online table generator (\texttt{https://latex-tables.com}). You can contact him at info [at] latex-tables [dot] com.}}
\date{April 30, 2021}
\maketitle
\section{Introduction}
This package offers a serie of low-level macros to align vertically the content of a cell, whether it has a fixed height or a variable height.
\section{Using \texttt{vcell}}
The idea behind \texttt{vcell} is to measure the height of cells to calculate the height of the row and then to print the cells in another row. This second row will be printed over the first one\footnote{Which can be understand as ``cheating'' for some.}. This process is not automated.
In a row where cells are vertically-aligned, all cells must be vertically-aligned. Each cells can have a different alignment however.
The commands available are those :
\begin{center}
\noindent\begin{tabularx}{\textwidth}{rX}
\verb|\savecellbox{<content>}|&Measure and save a cell that is vertically aligned. It will have to be printed in a second row.\\
\verb|\vcell{<content>}|&Shortcut for \verb|\savecellbox|\\
\verb|\printcelltop|&Print a top-aligned cell\\
\verb|\printcellmiddle|&Print a middle-aligned cell\\
\verb|\printcellbottom|&Print a bottom-aligned cell\\
\verb|\resetcellcount|&Reset the measurement of cells. This will be done automatically once you print all saved cells\\
\end{tabularx}
\end{center}
Once your cells are measured, the following lengths will be available :
\begin{center}
\noindent\begin{tabular}{rl}
\verb|\rowht|&The height of the row\\
\verb|\rowdp|&The depth of the row\\
\verb|\rowheight|&The total height of the row\\
\end{tabular}
\end{center}
\section{Basic example}
The following table :
\begin{center}
\noindent\begin{tabular}{@{}c@{}lcr@{}}
\toprule
& Top cell & Middle cell & Bottom cell\\\midrule
\vcell{\rule{0pt}{40pt}}&\savecellbox{Top}&\savecellbox{Middle}&\savecellbox{Bottom}\\[-\rowheight]
\printcellmiddle&\printcelltop&\printcellmiddle&\printcellbottom\\\bottomrule
\end{tabular}
\end{center}
can be created with the following code :
\begin{lstlisting}[breaklines]
\begin{tabular}{@{}c@{}lcr@{}}
\toprule
& Top cell
& Middle cell
& Bottom cell
\\ \midrule
\savecellbox{\rule{0pt}{40pt}}
& \savecellbox{Top}
& \savecellbox{Middle}
& \savecellbox{Bottom}
\\[-\rowheight]
\printcellmiddle
& \printcelltop
& \printcellmiddle
& \printcellbottom
\\ \bottomrule
\end{tabular}
\end{lstlisting}
To ensure the height of the table, an invisible strut is used. However, any content could be used instead, even content with variable height. You can see the alignment of the table with this figure :
\begin{center}
\noindent\begin{tabular}{@{}clcr@{}}
\toprule
& Top cell & Middle cell & Bottom cell\\\midrule
\savecellbox{\rule{10pt}{40pt}}&\savecellbox{\rule{10pt}{20pt}}&\savecellbox{\rule{10pt}{20pt}}&\savecellbox{\rule{10pt}{20pt}}\\[-\rowheight]
\printcellmiddle&\printcelltop&\printcellmiddle&\printcellbottom\\\bottomrule
\end{tabular}
\end{center}
The commands works even if all the cells have the same height, as shown in the following table :
\begin{center}
\noindent\begin{tabular}{lcr@{}}
\toprule
Top cell & Middle cell & Bottom cell\\\midrule
\savecellbox{Top}&\savecellbox{Middle}&\savecellbox{Bottom}\\[-\rowheight]
\printcelltop&\printcellmiddle&\printcellbottom\\\bottomrule
\end{tabular}
\end{center}
\section{Special cases}
\subsection{Usage of \texttt{multicolumn}}
Whenever you want to use the command \verb|\multicolumn| because you want to change the alignment of your cell or because you want your cell to span several column, you have to repeat the command in the second row.
\begin{center}
\noindent\begin{tabular}{@{}c@{}lcr@{}}
\toprule
& Top cell & Top cell & Bottom cell\\\midrule
\savecellbox{\rule{0pt}{40pt}}&\multicolumn{2}{c}{\savecellbox{Top (2 cols)}}&\savecellbox{Bottom}\\[-\rowheight]
\printcellmiddle&\multicolumn{2}{c}{\printcelltop}&\printcellbottom\\\bottomrule
\end{tabular}
\end{center}
The previous table can be created with the following code :
\begin{lstlisting}[breaklines]
\begin{tabular}{@{}c@{}lcr@{}}
\toprule
& Top cell
& Top cell
& Bottom cell
\\ \midrule
\savecellbox{\rule{0pt}{40pt}}
& \multicolumn{2}{c}{\savecellbox{Top (2 cols)}}
& \savecellbox{Bottom}
\\ [-\rowheight]
\printcellmiddle
& \multicolumn{2}{c}{\printcelltop}
& \printcellbottom
\\ \bottomrule
\end{tabular}
\end{lstlisting}
\subsection{Paragraph columns}
A frequent case is the use of paragraph columns (i.e. \verb|p|, \verb|m| or \verb|b| columns). The only rule is to use \verb|p| columns (or \verb|X| columns from the \texttt{tabularx} package) and avoid \verb|m| columns, otherwise it will mess with the alignment.
\begin{center}
\newdimen\rrowheight
\noindent\begin{tabular}{@{}p{80pt}p{45pt}p{90pt}p{45pt}c@{}}
\toprule
Middle-p cell & Top-p cell & Bottom-p cell&Bottom-p cell & Middle cell\\\midrule
\savecellbox{This is a paragraph that starts at the center and keeps continuing}&\savecellbox{Paragraph from top}&\savecellbox{This is the biggest paragraph. It is aligned from the bottom but you can't notice that.}&\savecellbox{Paragraph from bottom}&\savecellbox{Middle}\\\noalign{\global\setlength{\rrowheight}{\rowheight}\vspace{-\rowheight}}
\printcellmiddle&\printcelltop&\printcellbottom&\printcellbottom&\printcellmiddle\\\bottomrule\noalign{\vspace{2pt}\verb|\rowheight=|\the\rrowheight}
\end{tabular}
\end{center}
It can be produced by this code :
\begin{lstlisting}[breaklines]
\begin{tabular}{@{}p{80pt}p{45pt}p{90pt}p{45pt}c@{}}
\toprule
Middle-p cell
& Top-p cell
& Bottom-p cell
& Bottom-p cell
& Middle cell
\\ \midrule
\savecellbox{This is a paragraph that starts at the center and keeps continuing}
& \savecellbox{Paragraph from top}
& \savecellbox{This is the biggest paragraph. It is aligned from the bottom but you can't notice that.}
& \savecellbox{Paragraph from bottom}
& \savecellbox{Middle}
\\ [-\rowheight]
\printcellmiddle
& \printcelltop
& \printcellbottom
& \printcellbottom
& \printcellmiddle
\\ \bottomrule
\end{tabular}
\end{lstlisting}
\subsection{Usage with \texttt{colortbl}}
You can use coloured cells with \texttt{colortbl}. However, the color declaration must be repeated before \verb|\printcellmiddle|, \verb|\printcelltop| or \verb|\printcellbottom| commands.
\begin{center}
\noindent\begin{tabular}{|>{\columncolor{red}}p{60pt}|c|}
\hline
Middle-p cell & \cellcolor{yellow}Bottom cell\\\hline
\savecellbox{This is a paragraph that starts at the center and keeps continuing}&\cellcolor{green}\savecellbox{Paragraph from bottom}\\[-\rowheight]
\printcellmiddle&\cellcolor{green}\printcellbottom\\\hline
\end{tabular}
\end{center}
\begin{lstlisting}[breaklines]
\begin{tabular}{|>{\columncolor{red}}p{60pt}|c|}
\hline
Middle-p cell
& \cellcolor{yellow} Bottom cell
\\ \hline
\savecellbox{This is a paragraph that starts at the center and keeps continuing}
& \cellcolor{green}\savecellbox{Paragraph from bottom}
\\ [-\rowheight]
\printcellmiddle
& \cellcolor{green}\printcellbottom
\\ \hline
\end{tabular}
\end{lstlisting}
\subsection{Usage with \texttt{multirow}}
\texttt{vcell} does not support cells that spans several rows. If you want to use \verb|\multirow| in the same row as vertically-aligned cells, just use \verb|multirow| as you would normally do and skip it in the second row. You don't have to adjust the first argument of \verb|multirow|. You might want to use the optional argument of \verb|multirow| to get the vertical alignment that you want.
\begin{center}
\noindent\begin{tabular}{|c|>{\centering}p{60pt}|c|}
\hline
Multirow cell & Middle-p cell & Bottom cell\\\hline
\multirow{2}{*}[-3.5em]{Two rows}&\savecellbox{ This is a paragraph that starts at the center and keeps continuing}&\savecellbox{Paragraph from bottom}\\[-\rowheight]
&\printcellmiddle&\printcellbottom\\\cline{2-3}
&\savecellbox{This is another paragraph that starts at the center and keeps continuing}&\savecellbox{Second paragraph from bottom}\\[-\rowheight]
&\printcellmiddle&\printcellbottom\\\hline
\end{tabular}
\end{center}
\begin{lstlisting}[breaklines]
\begin{tabular}{|c|>{\centering}p{60pt}|c|}
\hline
Multirow cell
& Middle-p cell
& Bottom cell
\\ \hline
\multirow{2}{*}[-3.5em]{Two rows}
& \savecellbox{This is a paragraph that starts at the center and keeps continuing}
& \savecellbox{Paragraph from bottom}
\\ [-\rowheight]
% We skip for the multirow
& \printcellmiddle
& \printcellbottom
\\ \cline{2-3}
& \savecellbox{This is another paragraph that starts at the center and keeps continuing}
& \savecellbox{Second paragraph from bottom}
\\ [-\rowheight]
% We skip for the multirow
& \printcellmiddle
& \printcellbottom
\\ \hline
\end{tabular}
\end{lstlisting}
\section{Issues and limitations}
This is a list of known issues and limitations from this package :
\begin{itemize}
\item Content generated by \verb|>{...}| or \verb|<{...}| in the preamble are not measured and may produce errors in some cases.
\item \verb!m! columns will mess with vertical alignment.
\item Glues such as \verb|\dotfill| or \verb|\hrulefill| are not supported in cells
\item \verb|\verb| command is not supported in cells
\end{itemize}
However, we took great care to ensure that the content of the cell is only evaluated once, that no driver-specific commands were used and that selection in PDFs was not broken.
\section{Licence}
The contents of this package are distributed under the \LaTeX{} Project
Public License,
version 1.3c or later.
\end{document}
|