4

This document produces a table that mostly looks like I want it to look... except that I can't get the text in the left-hand column to be aligned in the vertical center. What I would really like is for the text in that column to be aligned vertically in the center, and horizontally on the left.

I looked for material about this stuff, but it all suggests that

  • by default things will be top-aligned
  • using the array package and specifying the column using m{width} will yield a middle-aligned column.

Yet this doesn't seem to be borne out by the output I get here. What's happening?

\documentclass[a4paper]{amsart}

\usepackage{array, tikz}
\usetikzlibrary{arrows}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\tikzset{
    s/.style = { font = \ttfamily,
                 anchor = west
                 },
    r/.style = { draw,
                 shape = rectangle,
                 minimum width = 6mm,
                 minimum height = 6mm,
                 font = \ttfamily
                 },
    c/.style = { draw,
                 shape = circle,
                 minimum width = 6mm,
                 minimum height = 6mm,
                 font = \ttfamily
                 },
    arrow/.style = { ->,
                     > = angle 60,
                     thick
                     }
}
\newcommand{\extraSpaceAbove}{\node at (0, -0.4) {\phantom{x}};}
    % Hack alert!
\begin{center}
    \setlength{\tabcolsep}{4mm}
    \renewcommand{\arraystretch}{1.4}
    \begin{tabular}{m{30mm}|l}
             \multicolumn{1}{c|}{Statement}
           & \multicolumn{1}{c}{Symbol table}
        \\ \hline
             \tt{local a := 2;}
           & \begin{tikzpicture} [x = 17.5mm, y = -7.5mm]
                 \extraSpaceAbove
                 \node [r] (a)    at (0, 0) {a};
                 \node [c] (aval) at (1, 0) {2};
                 \draw [arrow] (a.east) -- (aval);
             \end{tikzpicture}
        \\ \hline
             \tt{local b := 3;}
           & \begin{tikzpicture} [x = 17.5mm, y = -7.5mm]
                 \extraSpaceAbove
                 \node [r] (a)    at (0, 0) {a};
                 \node [r] (b)    at (0, 1) {b};
                 \node [c] (aval) at (1, 0) {2};
                 \node [c] (bval) at (1, 1) {3};
                 \draw [arrow] (a.east) -- (aval);
                 \draw [arrow] (b.east) -- (bval);
             \end{tikzpicture}
    \end{tabular}
\end{center}

\end{document}
2

The text on the left is vertically aligned in the center: As far as TeX is concerned, the tikzpicture in the right column is just a single tall line of text, and the base lines of the two columns are aligned correctly.

To get the text on the left to be optically vertically aligned, you can use the baseline option of the tikzpicture, which tells TikZ which y-coordinate in the tikzpicture should correspond to the base line of the surrounding text. In your case, baseline=(current bounding box.center) almost works, but it aligns the base line of the left column with the center of the tikzpicture, instead of aligning the center of the left column with the center of the tikzpicture. You could use baseline={($(current bounding box.center)+(0,-0.5ex)$)}, which uses the calc library to calculate a coordinate that's 0.5ex below the center.

Side note: Instead of your \extraSpaceAbove command, you should use the \path [use as bounding box] syntax (or the equivalent shorthand \useasboundingbox) to redefine the bounding box. To add 1ex at the top and bottom of the picture, use \useasboundingbox (current bounding box.north west) ++(0,1ex) (current bounding box.south east) ++(0,-1ex); at the end of the tikzpicture.

\documentclass[a4paper]{amsart}

\usepackage{array, tikz}
\usetikzlibrary{arrows,calc}

\begin{document}

\tikzset{
    s/.style = { font = \ttfamily,
                 anchor = west
                 },
    r/.style = { draw,
                 shape = rectangle,
                 minimum width = 6mm,
                 minimum height = 6mm,
                 font = \ttfamily
                 },
    c/.style = { draw,
                 shape = circle,
                 minimum width = 6mm,
                 minimum height = 6mm,
                 font = \ttfamily
                 },
    arrow/.style = { ->,
                     > = angle 60,
                     thick
                     }
}
\begin{center}
    \setlength{\tabcolsep}{4mm}
    \renewcommand{\arraystretch}{1.4}
    \begin{tabular}{m{30mm}|l}
             \multicolumn{1}{c|}{Statement}
           & \multicolumn{1}{c}{Symbol table}
        \\ \hline
             \ttfamily local a := 2;
           & \begin{tikzpicture} [x = 17.5mm, y = -7.5mm, baseline={($(current bounding box.center)+(0,-0.5ex)$)}]
                 \node [r] (a)    at (0, 0) {a};
                 \node [c] (aval) at (1, 0) {2};
                 \draw [arrow] (a.east) -- (aval);
                 \useasboundingbox (current bounding box.north west) ++(0,1ex) (current bounding box.south east) ++(0,-1ex);
             \end{tikzpicture}
        \\ \hline
             \ttfamily local b := 3;
           & \begin{tikzpicture} [baseline={($(current bounding box.center)+(0,-0.5ex)$)},x = 17.5mm, y = -7.5mm]
                 \node [r] (a)    at (0, 0) {a};
                 \node [r] (b)    at (0, 1) {b};
                 \node [c] (aval) at (1, 0) {2};
                 \node [c] (bval) at (1, 1) {3};
                 \draw [arrow] (a.east) -- (aval);
                 \draw [arrow] (b.east) -- (bval);
                 \useasboundingbox (current bounding box.north west) ++(0,1ex) rectangle (current bounding box.south east) ++(0,-1ex);

             \end{tikzpicture}
    \end{tabular}
\end{center}

\end{document}

aligning tikzpictures in tables

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.