9

I am using the following commands to place an arbitrary number of specialized, thick bars (\xbar) below a letter.

\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[-5pt]{\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}

The commands \xbarsbelow and \simplebars are the same, except that the first uses \xbar, while the latter uses \bar.

When I use \xbarsbelow[5]{A}, however, it draws only 2 bars below the letter A, whereas \simplebars[5]{A} draws all 5.

Bars

4

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}

enter image description here

4

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}

enter image description here

3

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:

enter image description here

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:

enter image description here

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.