Stacking thick bars below a symbol
An implementation without stacks. The optional argument is for fine adjustment of the bar width.
\documentclass{article}
\usepackage{amsmath}
\usepackage{expl3} % for \prg_replicate:nn
\makeatletter
\newcommand{\xbarsbelow}[3][1]{%
% #1 = kerning
% #2 = repetitions
% #3 = symbol to underbar
\sbox\z@{$\m@th\mkern-#1mu #3\mkern-#1mu$}%
\mkern#1mu
\vtop{\box\z@\replicate{#2}{\kern0.7pt\hrule height 0.7pt\relax}}
\mkern#1mu
}
\makeatother
\ExplSyntaxOn
\cs_new_eq:NN \replicate \prg_replicate:nn
\ExplSyntaxOff
\begin{document}
\begin{gather*}
A+\mathrm{A} \\
\xbarsbelow{5}{A}+\xbarsbelow[0]{3}{\mathrm{A}}
\end{gather*}
\end{document}
Your problem was a very simple one. The vertical height of \bar
(6.77774pt) and \xbar
(3.28333pt) are different. Thus, when you \stackunder
them, the gap size necessary to achieve your look needs to be different. Thus, simply changing the [-5pt]
gap in the \xbarsbelow
definition to [-1.65pt]
fixed the result.
Using [-5pt]
as the stacking gap for \bar
squeezed out some of the excess vertical space that comes with 6.77774pt \bar
. However, \xbar
takes up a lesser vertical footprint, indeed, less than 5pt. So using a [-5pt]
vertical gap for successive \xbarsbelow
eats up too much vertical space. In essence, you were laying each successive \xbarbelow
atop the prior one.
\documentclass[prb,preprint]{revtex4-1}
\usepackage{stackengine}
\stackMath
\newcommand*\xbar[1]{% this command creates a specialized, thick bar
\hbox{%
\vbox{%
\hrule height 0.7pt %
\kern0.5ex%
\hbox{%
\kern-0.3em%
\ensuremath{#1}%
\kern-0.3em%
}%
}%
}%
}
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\def\useanchorwidth{T}
\ifnum#1>1
\stackunder[-1.65pt]{\xbarsbelow[\numexpr#1-1\relax]{#2}}{\xbar{\,\,\quad}}
\else
\stackunder[2pt]{#2}{\xbar{\,\,\quad}}
\fi
}
\newcommand\simplebars[2][1]{% same as \xbarsbelow, but uses the \bar symbol
\def\useanchorwidth{T}
\ifnum#1>1
\stackunder[-5pt]{\simplebars[\numexpr#1-1\relax]{#2}}{\bar{}}
\else
\stackunder[2pt]{#2}{\bar{}}
\fi
}
\begin{document}
$\xbarsbelow[5]{A}$, $\simplebars[5]{A}$
\end{document}
I am not entirely sure why your \xbarsbelow
macro does not work given that it is almost exactly the same as \simplebars
, which does work. I suspect that the problem is in the way that you are using \numexpr
because, as I'll show below, everything is being expanded quite late.
One way to trouble shoot what is happening is to add commands like:
\typeout{xbarsbelow: 1=#1, 2=#2.}
to your macros. In this case you will see things like
xbarsbelow: 1=\numexpr \numexpr \numexpr 5-1\relax -1\relax -1\relax, 2=A.
in your log file (or on the command line), which is probably not what you want. Using \the\numexpr#1-1\relax
produces better results in terms of the output from \typeout{...}
but it does not fix the problem.
Instead, I suggest using \stackunder
to control your recursion:
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\def\useanchorwidth{T}% not sure what this does?
\ifnum#1>1%
\rlap{\stackunder[\the\dimexpr2pt*#1\relax]{\phantom{#2}}{\xbar{\,\,\quad}}}%
\xbarsbelow[\the\numexpr#1-1\relax]{#2}
\else%
\stackunder[2pt]{#2}{\xbar{\,\,\quad}}%
\fi%
}
This produces the desired output. The trick is to use \rlap{...}
that, roughly speaking, prints something "without moving the cursor". In fact, if you take this approach you do not even need to use stackengine
and can instead just use \rule
to draw your lines:
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\ifnum#1>0%
\rlap{\rule[\the\dimexpr-2pt*#1\relax]{1em}{0.8pt}}%
\xbarsbelow[\the\numexpr#1-1\relax]{#2}% recursion
\else%
\rlap{\hbox to 1em{\hfil$#2$\hfil}}%
\hspace*{1em}%
\fi%
}
Another option is to use tikz
, which is what my \newbars
macro in the code below does. This command takes a second optional argument that specifies the width of the bars. Still, the version of \xbarsbelow
based on \rule
is simpler and hence probably preferable -- and you could add an optional width command to it in exctly the same way.
With this is place you can produce:
using the MWE:
\documentclass[prb,preprint]{revtex4-1}
\usepackage{stackengine}
\stackMath
\newcommand*\xbar[1]{% this command creates a specialized, thick bar
\hbox{%
\vbox{%
\hrule height 0.7pt %
\kern0.5ex%
\hbox{%
\kern-0.3em%
\ensuremath{#1}%
\kern-0.3em%
}%
}%
}%
}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{tikz}
% usage: \newbar{A} or \newbar[3]{A} or \newbar[3](2em){A} or \newbar(2em){A}
\NewDocumentCommand\newbar{ O{1} D(){1.0em} m }{%
\tikz[baseline=(text.base)]{\node (text) at (0,0){#3};
\foreach \li [evaluate=\li as \y using (-0.1-0.08*\li)] in {1,...,#1}{
\draw[thick](-#2/2,\y)--++(#2,0);
}
}%
}
\newcommand\xbarsbelow[2][1]{% draws n \xbar's below the given symbol
\ifnum#1>0%
\rlap{\rule[\the\dimexpr-2pt*#1\relax]{1em}{0.8pt}}%
\xbarsbelow[\the\numexpr#1-1\relax]{#2}% recursion
\else%
\rlap{\hbox to 1em{\hfil$#2$\hfil}}%
\hspace*{1em}%
\fi%
}
\newcommand\simplebars[2][1]{% same as \xbarsbelow, but uses the \bar symbol
\def\useanchorwidth{T}%
\ifnum#1>1%
\stackunder[-5pt]{\simplebars[\the\numexpr#1-1\relax]{#2}}{\bar{}}%
\else%
\stackunder[2pt]{#2}{\bar{}}%
\fi%
}
\begin{document}
$\xbarsbelow[5]{A}$, $\simplebars[5]{A}$
$\newbar[5]{A}$
$\newbar[5](2em){A}$
\end{document}
Btw, I am not sure what adding \def\useanchorwidth{T}
does inside your macros, perhaps it is some stackengine
magic? It is also a good idea to add %
at the end of every line of your macros as this helps to prevent unwanted space from creeping in.
In fact, rather han hard-wiring in the width of the lines it is probably better to set these automatically using the text:
\documentclass[prb,preprint]{revtex4-1}
\usepackage{xparse}
\newlength\barlength
\newcommand\xbarsbelowrecursion[1]{%
\ifnum#1>0%
\rlap{\rule[\the\dimexpr-2pt*#1\relax]{\barlength}{0.7pt}}
\xbarsbelowrecursion{\the\numexpr#1-1\relax}
\fi%
}
\NewDocumentCommand\xbarsbelow{O{1} d() m}{% draws n \xbar's below the given symbol
\IfNoValueTF{#2}{\settowidth\barlength{\,#3}}{\setlength\barlength{#2}}%
\xbarsbelowrecursion{#1}%
\rlap{\hbox to \barlength{\hfil$#3$\hfil}}%
\hspace*{\barlength}%
}
\begin{document}
$\xbarsbelow[5]{A}$
$\xbarsbelow[3]{Hello}$
$\xbarsbelow[3](4em){Hello}$
\end{document}
Again, there is an optional ()
-delimited argument for over-riding the length. Here's the output: