2

I have written a few environments for formatting use cases. For some reason I am having strange alignment issues in my longtable. I think that there is some invisible placeholder in there messing it all up, but after several hours, and after removing all unnecessary spaces, I can't find it.

Here are my environments:

\newenvironment{ucflowofevents}{%
\newcommand{\event}[1]{\item{##1}}%
\begin{enumerate}
}{%
\end{enumerate}
}

\newenvironment{ucentryconditions}{%
\newcommand{\cond}[1]{\item{##1}}%
\begin{itemize}
}{%
\end{itemize}
}

\newenvironment{ucexitconditions}{%
\newcommand{\cond}[1]{\item{##1}}%
\begin{itemize}
}{%
\end{itemize}
}

\newenvironment{ucrequirements}{%
\newcommand{\req}[1]{\item{##1}}%
\begin{itemize}
}{%
\end{itemize}
}

\newenvironment{pcusecase}[1]{%
    \newcommand{\row}[3][\hline]{##2 & ##3 \\ ##1}
    \newcolumntype{L}{>{\vspace{-1.0\baselineskip}\flushleft\arraybackslash}p{4cm}}%
    \newcolumntype{R}{>{\vspace{-1.0\baselineskip}\raggedright\arraybackslash}b{10cm}}%
    \newcommand{\giveninitactors}{REQUIRED!!!}%
    \newcommand{\givenevents}{REQUIRED!!!}%
    \newcommand{\givencommswith}{}%
    \newcommand{\givenentries}{}%
    \newcommand{\givenexits}{}%
    \newcommand{\givenreqs}{}%
    \newcommand{\initactors}[1]{\gdef\giveninitactors{##1}}%
    \newcommand{\commswith}[1]{\gdef\givencommswith{##1}}%
    \newcommand{\events}[1]{\gdef\givenevents{\begin{ucflowofevents}##1\end{ucflowofevents}}}%
    \newcommand{\entries}[1]{\gdef\givenentries{\begin{ucentryconditions}##1\end{ucentryconditions}}}%
    \newcommand{\exits}[1]{\gdef\givenexits{\begin{ucexitconditions}##1\end{ucexitconditions}}}%
    \newcommand{\reqs}[1]{\gdef\givenreqs{\begin{ucrequirements}##1\end{ucrequirements}}}%
    \let\givencommswith\empty%
    \let\givenentries\empty%
    \let\givenexits\empty%
    \let\givenreqs\empty%
    \centering%
    \begin{longtable}{|LR|}\hline %
        \row{Use Case:}{#1}
}{%
        \row{Initiating Actors:}{\giveninitactors}%
        \ifx\givencommswith\empty\else \row[]{Communicates With:}{\givencommswith} \fi %\hline %
        \hline\row{Flow of Events:}{\givenevents} %
        \ifx\empty\givenentries\else \row{Entry Conditions:}{\givenentries} \fi %
        \ifx\empty\givenexits\else \row{Exit Conditions:}{\givenexits} \fi %
        \ifx\empty\givenreqs\else \row{Quality Requirements:}{\givenreqs} \fi%
    \end{longtable}%
}

The first four just set up lists for the flow of events, entry and exit conditions, and quality requirements. But pcusecase sets up the longtable.

Notice the \newcolumntype definitions:

    \newcolumntype{L}{>{\vspace{-1.0\baselineskip}\flushleft\arraybackslash}p{4cm}}%
    \newcolumntype{R}{>{\vspace{-1.0\baselineskip}\raggedright\arraybackslash}b{10cm}}%

What I really want is for them both to be top aligned, but I specified b for the right-hand (R) column because it exaggerates what happens. Here is my use case:

\begin{pcusecase}{TestUseCase}%
    \initactors{Rider, Admin}%
    \commswith{GPSService}%
    \events{\item{Event 1}%
                    \item{Event 2}}%
    \entries{\cond{Entry Condition 1}%
                     \cond{Entry Condition 2}}%
    \exits{\cond{Exit Condition 1}%
                 \cond{Exit Condition 1}}%
    \reqs{\req{Requirement 1}%
                \req{Requirement 2}
                \req{Requirement 3}}%
\end{pcusecase}

which gives this output:

left top-aligned? right bottom aligned?

Notice that for the first three rows, the right-hand cells are bottom-aligned like they should be, but for the remaining rows, the left cells are bottom-aligned and the right cells are top-aligned.

If I specify that left should be bottom-aligned, and the right top-aligned with

    \newcolumntype{L}{>{\vspace{-1.0\baselineskip}\flushleft\arraybackslash}b{4cm}}%
    \newcolumntype{R}{>{\vspace{-1.0\baselineskip}\raggedright\arraybackslash}p{10cm}}%

I get this:

left top-aligned? right bottom-aligned?

The left is somehow top-aligned and the right-bottom aligned, sort of. The weirdest one, and probably the one that is going to clue somebody in, is when I specify that both should be bottom aligned and get this:

WTF?

In all three versions, the alignment in the three upper-left cells didn't change. I've been staring for hours. I need some fresh eyes on this. Your help is greatly appreciated...

  • Welcome to TeX.SX! Is the behavior is reproducible with the article class or do we need to try another one? – egreg May 2 '15 at 8:06
  • @egreg It behaves this way with article, report, and book. – Nathan Milton May 2 '15 at 18:01
  • 1
    Can you make a single example we can copy-paste-compile to reproduce the problem? – cfr May 3 '15 at 2:39
4

Here's a demonstration of how the standard vertical alignment options work:

\documentclass{article}
\usepackage{tikz}
\begin{document}
  \newcommand\demobox[1]{%
  \fbox{%
    \begin{minipage}[#1]{.25\textwidth}
      \tikz[baseline=(n.base)]{%
        \node (n) [inner sep=0pt, outer sep=0pt, text width=\linewidth] {Top};
        \draw [red] (n.west |- n.base) -- (n.east |- n.base);}
      \par
      This is a box with some content which should be longer than can be accommodated on one line.
      \par
      \tikz[baseline=(n.base)]{%
        \node (n) [inner sep=0pt, outer sep=0pt, anchor=base, text width=\linewidth] {Bottom};
        \draw [red] (n.west |- n.base) -- (n.east |- n.base);}
    \end{minipage}}}
\demobox{t}
\demobox{b}
\demobox{c}
\end{document}

alignments

The red lines mark the baselines of the first and final lines of each minipage. Because the first is aligned with t and the second with b, the baseline of the first line of the first and the baseline of the final line of the second are aligned. (c is just there fore comparison.)

The same thing happens if the alignment is with the baseline of a line of regular text:

This is a line of regular text across the page. Here we go\dots\par
and some text \demobox{t}
and some more \demobox{b}\par

alignments with text

The other complication is that enumerate environments, by default, include vertical spacing before the first and after the last item:

\documentclass{article}
\begin{document}
  \fbox{%
    \parbox[t]{.25\textwidth}{%
      \begin{enumerate}
        \item Item
        \item Item
        \item Item
      \end{enumerate}}} and here is the line of text.
  \fbox{%
    \parbox[t]{.25\textwidth}{%
      Top line of text.\par Next line.\par Bottom line.}}

  \fbox{%
    \parbox[b]{.25\textwidth}{%
      \begin{enumerate}
        \item Item
        \item Item
        \item Item
      \end{enumerate}}} and here is the line of text.
  \fbox{%
    \parbox[b]{.25\textwidth}{%
      Top line of text.\par Next line.\par Bottom line.}}
\end{document}

enumeration alignments

  • Thank you very much for spending the time to put up this answer. In my ignorance, I assumed that a table cell was a contained environment, and that the p, m, and b specifications would produce top-, middle-, and bottom-aligned cells. I didn't realize that the positioning would be relative to content in adjacent cells. After reading your answer, the solution became obvious.Thanks again. When I build up enough SE cred, I'll come back and upvote your answer... – Nathan Milton May 4 '15 at 3:00
  • @NathanMilton It is confusing. It is because the alignments are always relative to the baseline and that will be the same, I think, for the entire row. But I kind of thought we needed a visual explanation of this somewhere because a diagram is the only way I've ever been able to grasp it ;). – cfr May 4 '15 at 3:03
  • Apparently a picture is also worth a thousand hours of staring stupidly at your LaTeX code. Hehehe... – Nathan Milton May 4 '15 at 3:07
  • @NathanMilton Always draw boxes around things when in doubt. At least, that's what I do. TeX thinks everything is a box. If you draw the boxes, it is (usually) clearer what is going on. – cfr May 4 '15 at 3:10
  • I provide some related explanations and illustrations in this answer. I answer the question first so scroll down to Explanation if you are not interested in the specific problem ;). – cfr Jul 26 '15 at 22:46

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.