7

I'm trying to redo my CV in latex, and I'm running into a minor issue with the placement of \hrule. I define a category environment for each section via

\newenvironment{category}[1]
{%                                                                                                                            
{\bf{#1}}                                                                                                                     
  \medskip                                                                                                            
  \hrule % Horizontal line                                                                                                    
  \medskip                                                                                                            
\begin{itemize}[label={$-$},itemsep=0.15cm]                                                                                   
}
{%                                                                                                                            
\end{itemize}                                                                                                                 
\bigskip                                                                                                                      
}

When I have a \begin{category}{XXX}, the space between the bottom line of the text and the hrule gets bigger if XXX has descenders. I'd rather it just stay constant and have the descenders be closer to the line. Is there any way to do this?

3

3 Answers 3

9

The \hrule in the vertical material breaks the baselineskip-grid because it resets the internal \prevdepth register. But you can save the value of the register to a variable, print \hrule and restore this register. Then the baselineskip-grid can be kept.

Normal behavior:

Previous line
\hrule     % this rule is printed immediately below the line without space.
Next line  % this line is printed without space because \prevdepth is reset.

Keeping \prevdepth:

Previous line
\par \dimen0=\prevdepth  % the \prevdepth value is saved
\hrule     % this rule is printed immediately below the line without space.
\prevdepth=\dimen0   % restoring \prevdepth
Next line  % this line keeps the baselineskip-grid
           % but .4pt is added (the rule thickness)

Shifting \hrule to the grid:

Previous line
\par \dimen0=\prevdepth  % the \prevdepth value is saved
\kern \dimexpr 3pt-\prevdepth  % the space 3pt from baseline
\hrule     % hrule 3pt from previous baseline
\prevdepth=\dimen0   % restoring \prevdepth
\kern \dimexpr \prevdepth-3pt-.4pt \relax % space correction
Next line % Next line fits to baselineskip-grid.

So, you can define \myhrule and do this:

\newdimen\tmpdim
\def\myhrule{\par
   \tmpdim=\prevdepth
   \kern\dimexpr 3pt-\prevdepth
   \hrule
   \prevdepth=\tmpdim
   \kern\dimexpr \prevdepth-3pt-.4pt \relax
}

Previous line.
\myhrule
Next line.

\bye
7

TeX inserts no interline glue before and after \hrule, so you have to teach it that you want to respect distances independently of ascenders and descenders. The simplest way is to use struts:

\documentclass{article}
\usepackage{enumitem}

\newenvironment{category}[1]
 {\par\noindent\textbf{\strut#1\strut}
  \medskip % <-------- adjust here
  \hrule % Horizontal line
  \medskip
  \begin{itemize}[label={--},itemsep=0.15cm]
  \prevdepth=\dp\strutbox
 }
 {\end{itemize}
  \bigskip
 }

\begin{document}

\hrule height 4pt % just to see the two boxes
\noindent
\begin{minipage}[t]{0.45\textwidth}
\vspace{0pt}% to set the alignment point
Some text before
\begin{category}{abcd}
\item acer
\end{category}
Some text after
\end{minipage}
\begin{minipage}[t]{0.45\textwidth}
\vspace{0pt}% to set the alignment point
Some text before
\begin{category}{ghij}
\item dgf
\end{category}
Some text after
\end{minipage}

\hrule height 4pt % just to see that the two boxes 
\end{document}

The “category” is surrounded by struts and, just before the first item is printed, we pretend that the line before it had a depth equal to that of a strut (\prevdepth=\dp\strutbox).

I typeset the two examples in minipages in order to better see that the vertical alignment is as desired. The two heavy rules just mark the boundaries. The \vspace{0pt} at the start of the minipages is again just for the example, it will set the alignment point of the two boxes.

enter image description here

6

You can remove the descender-depth by using \raisebox. The following definition of \raisebox is contained in source2e.pdf:

\raisebox{⟨distance⟩}[⟨height⟩][⟨depth⟩]{⟨box⟩}

Raises ⟨box⟩ up by ⟨distance⟩ length (down if ⟨distance⟩ negative). Makes TeX think that the new box extends ⟨height⟩ above the line and ⟨depth⟩ below, for a total vertical length of ⟨height⟩+⟨depth⟩. Default values of ⟨height⟩ & ⟨depth⟩ = actual height and depth of box in new position.

So, consider using \raisebox{0pt}[\height][0pt]{<stuff>} (\height is the natural height of <stuff>):

enter image description here

\documentclass{article}

\usepackage{enumitem}

\newenvironment{category}[1]{%
    \par\noindent% No paragraph indent
    \raisebox{0pt}[\height][0pt]{\textbf{#1}}\par
    \medskip
    \hrule% Horizontal rule
    \medskip
    \begin{itemize}[label={--},itemsep=.5em]
  }{%
    \end{itemize}
    \bigskip
  }

\begin{document}

Here is some content
\begin{category}{abcdef}
  \item something
  \item something else
\end{category}

Some more content
\begin{category}{ghijkl}
  \item something
  \item something else
\end{category}

\end{document}

Note the use of \par to enter vertical mode. Otherwise the (first) use of \medskip is superfluous and only issued later (once in vertical mode through some other means).

More extreme might be to \smash the content so it takes up no vertical height/depth at all (similar to \raisebox{0pt}[0pt][0pt]{<stuff>}).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .