[Tex/LaTex] Too long/short pipe (absolute value) in math mode with certain letters

math-modesymbolsvector

In the question Absolute Value Symbols I read about the best ways to write absolute values. I found the accepted answer pretty good and it works in almost all cases. Sadly, only in almost. For example on the letter "k" the pipes are drawn far under the lower end of the letter "k" in the PDF output. Why is this and what to do about it?

The bad thing is: I can not just skip the macro on all "k" vectors and use the regular pipes |\vec{k}| or the starred version of the abs* operator because as you will see from the last two lines in the minimal example, the regular pipes on the "k" are drawn to short at the top (not around the vector arrow). The "x" is drawn like expected by a reader, however.

The following is a minimal example that shows the problem (letter "x" works fine, letter "k" has to big/small pipes). In my real world document I also have T1 fontenc, and font packages loaded (libertine, fouriernc and inconsolata), so this behavior seems to be independent of all the font/math-related packages.

\documentclass{article}

\usepackage{mathtools}

%define abs
\DeclarePairedDelimiter\abs{\lvert}{\rvert}%

%switch starred and non-starred (auto-size)
\makeatletter
\let\oldabs\abs
\def\abs{\@ifstar{\oldabs}{\oldabs*}}
\makeatother

\begin{document}
  \[ \abs{\vec{x}} \]
  \[ \abs{\vec{k}} \]
  \[ |\vec{x}| \]
  \[ |\vec{k}| \]
\end{document}

The output:

enter image description here

I know about the nath package, but it always gives me a lot of errors and seems to be unmaintained. Also, to me it always feels a bit "strange" if things are auto-done to my document that can't be "looked inside" (without investing tons of non-available time to work through the nath package code). So, I'd rather like to not use it.

Best Answer

I was able to use my scalerel package to hopefully give you what you want (scalerel was just sent to CTAN today, so until it propagates, you can find the style listing at How to horizontally merge two symbols?).

Using that package's features, my first cut was to create a command \myabs, which places abs bars around anything. It will stretch the size of the bars exactly to the argument. The downside of this first attempt is that you may have preferred the bars to extend a bit above and below the object being surrounded (addressed later in this answer). Here's the code for the first approach:

\documentclass{article}
\usepackage{scalerel}
\usepackage{mathtools}

\begin{document}
% [METHOD USED IN ORIGINAL QUESTION CODE HERE, REMOVED FROM THIS LISTING]
\newcommand\myabs[1]{%
  \setbox1\hbox{$#1$}%
  \stretchrel{\lvert}{\usebox1}\stretchrel*{\lvert}{\usebox1}%
}

\[ \myabs{\vec{k}}~~\myabs{\vec{x}}~~\myabs{\vec{A}}~~\myabs{\vec{q}} \]

\end{document}

and here's the output, as compared to your original

enter image description here

However, to answer ralfix's request to extend the vertical line a bit above and below the surrounding object, I just used the \addvbuffer routine from the verbatimbox package, setting the top and bottom add-on to 2pt:

\documentclass{article}
\usepackage{scalerel}
\usepackage{mathtools}
\usepackage{verbatimbox}

\setlength\boxtopsep{2pt}
\setlength\boxbottomsep{2pt}
\newcommand\myabs[1]{%
  \setbox1\hbox{$#1$}%
  \setbox2\hbox{\addvbuffer{\usebox1}}%
  \stretchrel{\lvert}{\usebox2}\stretchrel*{\lvert}{\usebox2}%
}

\begin{document}
\[ \myabs{\vec{k}}~~\myabs{\vec{x}}~~\myabs{\vec{A}}~~\myabs{\vec{q}} \]
\end{document}

enter image description here

But egreg commented that the height of the abs bar should not change with the argument. If that is the preferred embodiment of abs, then scalerel can fix that too:

\documentclass{article}
\usepackage{scalerel}

\def\lvert{|}
\begin{document}
METHOD 2: FIXED EXTENT
\newsavebox\mybox
\savebox{\mybox}{$\stretchrel*{|}{\rule[-.6ex]{0ex}{3ex}}$}
\def\myabs#1{\usebox\mybox#1\usebox\mybox}

\[ \myabs{\vec{k}}~~\myabs{\vec{x}}~~\myabs{\vec{A}}~~\myabs{\vec{q}} \]
\end{document}

enter image description here

Related Question