[Tex/LaTex] \underbrace at a strange place, spanning array columns

arrayshorizontal alignmentmath-mode

Take a look at the following code:

$$\begin{array}{rr|r|c|l}
vd_2:&\raisebox{0pt}[0pt]{\makebox[0pt][l]{$\overbrace{\phantom{b_1\dots b_{n-l_{k-1}-2k}\hspace{2\arraycolsep}b_{n-l_{k-1}-2k+1}\dots b_{n-k-1}b_{n-k}\hspace{2\arraycolsep}c^k}}^v$}}b_1\dots b_{n-l_{k-1}-2k}&b_{n-l_{k-1}-2k+1}\dots b_{n-k-1}b_{n-k}&c^k&d_2\\
\mathrm{PW}(w):&\dots w_r c^{r+1-k}&c^k\raisebox{0pt}[0pt][0pt]{\makebox[0pt][l]{$\underbrace{\phantom{w_{k-1}\hspace{4.17em}\hspace{2\arraycolsep}c^k\hspace{2\arraycolsep}\widetilde{w_{k-1}}\dots}}_{w_r}$}}w_{k-1}\hspace{4.17em}&c^k&\widetilde{w_{k-1}}\dots\dots
\end{array}$$

I would like to draw the \underbrace in a more elegant way. The main problem is how to make sure that $c^kw_{k-1}$ is in the dead center of the column. In the proposed code, it has been done artifically: the empty space of length 4.17em is added to the right of $c^kw_{k-1}$, where the value 4.17em is obtained by trial-and-error. This works nicely in 12pt, but if the font size is changed, it slides off the center. Even if there were not a problem with changing the font size, it would seem logical that there is a nicer way to accomplish this effect, instead of guessing the value 4.17em (or whichever works for the particular font size) until a good enough pixel-precision is reached.

Best Answer

This is fairly straight forward to do using the savepos module from the zref package. It allows you to place markers (or labels) in the text and retrieve their coordinates (x and y) in small point (or sp) units. The code is also much cleaner without the box adjustments you used.

Taking your code, I've defined the labels L to denote the left-most entry in your array (as a frame of reference), TL and TR to be the left and right \overbrace coordinate in the top row, and BL and BR to be the left and right \underbrace coordinate in the bottom row.

Then I construct an invisible table before typesetting the actual table. The invisible is overlapped by the actual table using \mathrlap (to produce a right overlap in math mode) from the mathtools package. Finally, spacing is obtained by \hspaces as needed. Vertical alignment is rectified using \strut, since there is otherwise no content to adjust the height/depth above/below the \overbrace/\underbrace. Using \mathstrut instead results in slightly weaker vertical alignment:

enter image description here

\documentclass{article}
\usepackage{mathtools}% http://ctan.org/pkg/mathtools
\usepackage[savepos]{zref}% http://ctan.org/pkg/zref
\begin{document}
\[
  \mathrlap{\begin{array}{l}
    \hspace{\dimexpr\zposx{TL}sp-\zposx{L}sp\relax}\overbrace{\strut\hspace{\dimexpr\zposx{TR}sp-\zposx{TL}sp\relax}}^v \\
    \hspace{\dimexpr\zposx{BL}sp-\zposx{L}sp\relax}\underbrace{\strut\hspace{\dimexpr\zposx{BR}sp-\zposx{BL}sp\relax}}_{w_r}
  \end{array}}%
  \begin{array}{rr|c|c|l}
    vd_2: & \zsavepos{TL}b_1\dots b_{n-l_{k-1}-2k} & b_{n-l_{k-1}-2k+1}\dots b_{n-k-1}b_{n-k} & c^k\zsavepos{TR} & d_2 \\
    \zsavepos{L}\mathrm{PW}(w): & \dots w_r c^{r+1-k} & c^k\zsavepos{BL}w_{k-1} & c^k & \widetilde{w_{k-1}}\dots\zsavepos{BR}\dots
  \end{array}
\]

\[
  \begin{array}{rr|r|c|l}
    vd_2:&\raisebox{0pt}[0pt]{\makebox[0pt][l]{$\overbrace{\phantom{b_1\dots b_{n-l_{k-1}-2k}\hspace{2\arraycolsep}b_{n-l_{k-1}-2k+1}\dots b_{n-k-1}b_{n-k}\hspace{2\arraycolsep}c^k}}^v$}}
      b_1\dots b_{n-l_{k-1}-2k}&b_{n-l_{k-1}-2k+1}\dots b_{n-k-1}b_{n-k}&c^k&d_2\\
    \mathrm{PW}(w):&\dots w_r c^{r+1-k}&c^k\raisebox{0pt}[0pt][0pt]{\makebox[0pt][l]{$\underbrace{\phantom{w_{k-1}\hspace{4.17em}\hspace{2\arraycolsep}c^k\hspace{2\arraycolsep}\widetilde{w_{k-1}}\dots}}_{w_r}$}}
      w_{k-1}\hspace{4.17em}&c^k&\widetilde{w_{k-1}}\dots\dots
\end{array}
\]
\end{document}​

Above is new zref version, while your original construction is given below. Since this uses zref and positioning labels, you have to compile (at least) twice for the referencing to be correct.