[Tex/LaTex] Horizontal rule between lines that vertically takes up only its height and that doesn’t close up to surrounding ascenders/descenders

rulesspacing

I would like a command \lineseprule that appears as a horizontal line of customizable width. It should neither take up a full line's height (\linesepruleA below) nor close up the lines above and below (in a way that ascender and descender height affect the spacing between the surrounding lines; \linesepruleB below). Instead it should simply insert between the lines, as if it were its own very thin line.

illustration with shopping list

The vertical spacing for \linesepB depends on ascenders and descenders:
dependence on ascenders and descenders

\documentclass{article}
\usepackage{chancery}

\parindent0pt % disablement of paragraph indentation

\newcommand*{\linesepruleA}[1]{\par \rule{#1}{.4pt}\par}
\newcommand*{\linesepruleB}[1]{\par \hrule width#1 height.4pt}


\begin{document}

{\large\underline{Shopping list}}
\bigskip

toilet paper \par
kitchen rolls \par
detergent \par
\linesepruleA{4em} % too high
toothbrush \par
toothpaste \par
\linesepruleB{4em} % see below
milk \par
cereals \par


\vspace{2\baselineskip}

\hrulefill\par
{\small\verb|The vertical spacing for \linesepruleB depends on ascenders and descenders:|}

\medskip

a \par
\linesepruleB{4em} % much too close
o \par

\medskip

g \par
\linesepruleB{4em} % still too close
b \par

\end{document}

A clarification: I was making an assumption about lines having specific top and bottom boundaries. A meaningful interpretation of my question is: (1) Either pick a meaningful placement (e.g., place the horizontal rule in the middle of "half-x-height above the first row's baseline" and "half-x-height above the second row's baseline" or (2) let the user customize it with a parameter that lets the user pick something like the vertical distance below the first row's baseline or the vertical deviation from the default described in (1) above.

Addendum to clarification: Martin Scharrer tells us that \ht\strutbox and \dp\strutbox are .7\baselineskip and .3\baselineskip, respectively.

(Steven B. Segletes has written a solution covering all I had in mind, using the default of .7\baselineskip above the lower line's baseline.)

Best Answer

This approach uses the stackengine package to place a \rule above the baseline by an amount. The rule length is the mandatory argument, the rule elevation is the optional argument (default .7\baselineskip) The rule is smashed to take up zero height and, using stackengine facilities, has zero width as well.

Per the OP's request I EDITED the solution to do two things: 1) provide a macro to set the rule thickness; and 2) have the optional argument indicate the center (not the bottom) of the rule. The third request of the OP, to increase the line spacing, based on the rule thickness, has been added, using a new macro \lineaddrule, rather than \lineseprule (which handles the first two cases). These two macros are similar enough that one could set up a parameter to do one thing or the other in a single macro, rather than setting up two separate macros.

\documentclass{article}
\usepackage{chancery}
\usepackage{stackengine}
\newlength\rulethickness
\newcommand\setlineseprule[1][.2pt]{%
  \setlength\rulethickness{#1}}
\setlineseprule
\newcommand\lineseprule[2][.7\baselineskip]{%
  \def\useanchorwidth{T}\def\stackalignment{l}\def\stacktype{L}%
  \hspace{0pt}\smash{\stackon[#1]{}{%
  \rule[-.5\rulethickness]{#2}{\rulethickness}}}%
  \ignorespaces}
\newcommand\lineaddrule[2][.7\baselineskip]{%
  \def\useanchorwidth{T}\def\stackalignment{l}\def\stacktype{L}%
  \vspace{\rulethickness}%
  \hspace{0pt}\smash{\stackon[#1]{}{%
  \rule{#2}{\rulethickness}}}%
  \ignorespaces}
\parindent0pt % disablement of paragraph indentation
\begin{document}
{\large\underline{Shopping list}}
\bigskip

toilet paper \par
kitchen rolls \par
detergent \par
\lineseprule{4em}
toothbrush \par
toothpaste \par
\lineseprule{4em}
milk \par
cereals \par
\vspace{2\baselineskip}

\hrulefill\par
{\small\verb|The vertical spacing for \lineseprule can be adjusted|\\
\verb|for ascenders and descenders:|}

\medskip\setlineseprule[2pt]
a \par
\lineseprule[.7\baselineskip]{4em}
o \par\setlineseprule[12pt]
a \par
\lineaddrule[.7\baselineskip]{12em}
o \par
\medskip\setlineseprule
g \par
\lineaddrule[.57\baselineskip]{4em}
o \par
\end{document}

enter image description here