1

Hendrik Vogt provided an excellent alternative to overline.

I am experiencing issues with using widebar in conjunction with bm and mathcal.

A similar question has been asked already. However, the resolution of merely switching to the bm package for the bold symbols does not work in this case, as the following example demonstrates.

\documentclass{article}
\usepackage{amsmath}
\usepackage{bm}
\makeatletter
\let\save@mathaccent\mathaccent
\newcommand*\if@single[3]{%
  \setbox0\hbox{${\mathaccent"0362{#1}}^H$}%
  \setbox2\hbox{${\mathaccent"0362{\kern0pt#1}}^H$}%
  \ifdim\ht0=\ht2 #3\else #2\fi
  }
%The bar will be moved to the right by a half of \macc@kerna, which is computed by amsmath:
\newcommand*\rel@kern[1]{\kern#1\dimexpr\macc@kerna}
%If there's a superscript following the bar, then no negative kern may follow the bar;
%an additional {} makes sure that the superscript is high enough in this case:
\newcommand*\widebar[1]{\@ifnextchar^{{\wide@bar{#1}{0}}}{\wide@bar{#1}{1}}}
%Use a separate algorithm for single symbols:
\newcommand*\wide@bar[2]{\if@single{#1}{\wide@bar@{#1}{#2}{1}}{\wide@bar@{#1}{#2}{2}}}
\newcommand*\wide@bar@[3]{%
  \begingroup
  \def\mathaccent##1##2{%
%Enable nesting of accents:
    \let\mathaccent\save@mathaccent
%If there's more than a single symbol, use the first character instead (see below):
    \if#32 \let\macc@nucleus\first@char \fi
%Determine the italic correction:
    \setbox\z@\hbox{$\macc@style{\macc@nucleus}_{}$}%
    \setbox\tw@\hbox{$\macc@style{\macc@nucleus}{}_{}$}%
    \dimen@\wd\tw@
    \advance\dimen@-\wd\z@
%Now \dimen@ is the italic correction of the symbol.
    \divide\dimen@ 3
    \@tempdima\wd\tw@
    \advance\@tempdima-\scriptspace
%Now \@tempdima is the width of the symbol.
    \divide\@tempdima 10
    \advance\dimen@-\@tempdima
%Now \dimen@ = (italic correction / 3) - (Breite / 10)
    \ifdim\dimen@>\z@ \dimen@0pt\fi
%The bar will be shortened in the case \dimen@<0 !
    \rel@kern{0.6}\kern-\dimen@
    \if#31
      \overline{\rel@kern{-0.6}\kern\dimen@\macc@nucleus\rel@kern{0.4}\kern\dimen@}%
      \advance\dimen@0.4\dimexpr\macc@kerna
%Place the combined final kern (-\dimen@) if it is >0 or if a superscript follows:
      \let\final@kern#2%
      \ifdim\dimen@<\z@ \let\final@kern1\fi
      \if\final@kern1 \kern-\dimen@\fi
    \else
      \overline{\rel@kern{-0.6}\kern\dimen@#1}%
    \fi
  }%
  \macc@depth\@ne
  \let\math@bgroup\@empty \let\math@egroup\macc@set@skewchar
  \mathsurround\z@ \frozen@everymath{\mathgroup\macc@group\relax}%
  \macc@set@skewchar\relax
  \let\mathaccentV\macc@nested@a
%The following initialises \macc@kerna and calls \mathaccent:
  \if#31
    \macc@nested@a\relax111{#1}%
  \else
%If the argument consists of more than one symbol, and if the first token is
%a letter, use that letter for the computations:
    \def\gobble@till@marker##1\endmarker{}%
    \futurelet\first@char\gobble@till@marker#1\endmarker
    \ifcat\noexpand\first@char A\else
      \def\first@char{}%
    \fi
    \macc@nested@a\relax111{\first@char}%
  \fi
  \endgroup
}
\makeatother
\newcommand\test[1]{%
$#1{\bm{A}}$
$#1{\bm{\mathcal A}}$
}

\begin{document}
\test\widebar

\test\overline
\end{document}

Difference between widebar and overline on mathcal

Is there an easy fix for this problem?

1

Cause of the problem

When \bm{A}, \mathcal{A} or \bm{\mathcal{A}} entered into \widebar, they will fail the \if@single test, and thus produce the undesired long bar.

Solution

  1. Typeset the symbol without the accent.
  2. Add the accent over a \phantom version of the symbol, in which we must force a \if@single version to be used.
  3. Fine-tune the position of the accent with \mathllap from the mathtools package, and some negative space \!.

MWE

\documentclass{article}
\usepackage{amsmath}
\usepackage{bm}
% Hendrik Vogt's widebar: https://tex.stackexchange.com/a/60253/164314
\makeatletter
\let\save@mathaccent\mathaccent
\newcommand*\if@single[3]{%
  \setbox0\hbox{${\mathaccent"0362{#1}}^H$}%
  \setbox2\hbox{${\mathaccent"0362{\kern0pt#1}}^H$}%
  \ifdim\ht0=\ht2 #3\else #2\fi
  }
%The bar will be moved to the right by a half of \macc@kerna, which is computed by amsmath:
\newcommand*\rel@kern[1]{\kern#1\dimexpr\macc@kerna}
%If there's a superscript following the bar, then no negative kern may follow the bar;
%an additional {} makes sure that the superscript is high enough in this case:
\newcommand*\widebar[1]{\@ifnextchar^{{\wide@bar{#1}{0}}}{\wide@bar{#1}{1}}}
%Use a separate algorithm for single symbols:
\newcommand*\wide@bar[2]{\if@single{#1}{\wide@bar@{#1}{#2}{1}}{\wide@bar@{#1}{#2}{2}}}
\newcommand*\wide@bar@[3]{%
  \begingroup
  \def\mathaccent##1##2{%
%Enable nesting of accents:
    \let\mathaccent\save@mathaccent
%If there's more than a single symbol, use the first character instead (see below):
    \if#32 \let\macc@nucleus\first@char \fi
%Determine the italic correction:
    \setbox\z@\hbox{$\macc@style{\macc@nucleus}_{}$}%
    \setbox\tw@\hbox{$\macc@style{\macc@nucleus}{}_{}$}%
    \dimen@\wd\tw@
    \advance\dimen@-\wd\z@
%Now \dimen@ is the italic correction of the symbol.
    \divide\dimen@ 3
    \@tempdima\wd\tw@
    \advance\@tempdima-\scriptspace
%Now \@tempdima is the width of the symbol.
    \divide\@tempdima 10
    \advance\dimen@-\@tempdima
%Now \dimen@ = (italic correction / 3) - (Breite / 10)
    \ifdim\dimen@>\z@ \dimen@0pt\fi
%The bar will be shortened in the case \dimen@<0 !
    \rel@kern{0.6}\kern-\dimen@
    \if#31
      \overline{\rel@kern{-0.6}\kern\dimen@\macc@nucleus\rel@kern{0.4}\kern\dimen@}%
      \advance\dimen@0.4\dimexpr\macc@kerna
%Place the combined final kern (-\dimen@) if it is >0 or if a superscript follows:
      \let\final@kern#2%
      \ifdim\dimen@<\z@ \let\final@kern1\fi
      \if\final@kern1 \kern-\dimen@\fi
    \else
      \overline{\rel@kern{-0.6}\kern\dimen@#1}%
    \fi
  }%
  \macc@depth\@ne
  \let\math@bgroup\@empty \let\math@egroup\macc@set@skewchar
  \mathsurround\z@ \frozen@everymath{\mathgroup\macc@group\relax}%
  \macc@set@skewchar\relax
  \let\mathaccentV\macc@nested@a
%The following initialises \macc@kerna and calls \mathaccent:
  \if#31
    \macc@nested@a\relax111{#1}%
  \else
%If the argument consists of more than one symbol, and if the first token is
%a letter, use that letter for the computations:
    \def\gobble@till@marker##1\endmarker{}%
    \futurelet\first@char\gobble@till@marker#1\endmarker
    \ifcat\noexpand\first@char A\else
      \def\first@char{}%
    \fi
    \macc@nested@a\relax111{\first@char}%
  \fi
  \endgroup
}
\makeatother
\newcommand\test[1]{%
$#1{\bm{A}}$
$#1{\bm{\mathcal A}}$
}

% My implementation starts here
\usepackage{mathtools}
\makeatletter
% Forcing a \if@single version but keep the flexibility of a following superscript
\newcommand\widebarbm[1]{%
  \@ifnextchar^{%
    {\bm{#1}\mathllap{\wide@bar@{\phantom{\!\bm{#1}}}{0}{1}}}}%
  {%
    \bm{#1}\mathllap{\wide@bar@{\phantom{\!\bm{#1}}}{1}{1}}}%
}
\newcommand\widebarcal[1]{%
  \@ifnextchar^{%
    {\mathcal{#1}\mathllap{\wide@bar@{\phantom{\!\mathcal{#1}}}{0}{1}}}}%
  {%
    \mathcal{#1}\mathllap{\wide@bar@{\phantom{\!\mathcal{#1}}}{1}{1}}}%
}
\newcommand\widebarbmcal[1]{%
  \@ifnextchar^{%
    {\bm{\mathcal{#1}}\mathllap{\wide@bar@{\phantom{\!\bm{\mathcal{#1}}}}{0}{1}}}}%
  {%
    \bm{\mathcal{#1}}\mathllap{\wide@bar@{\phantom{\!\bm{\mathcal{#1}}}}{1}{1}}}%
}
\makeatother

\begin{document}
\test\widebar

\test\overline

\bigskip

New versions below: 
\begin{center}
\renewcommand\arraystretch{1.3}
\begin{tabular}{l l}
\hline
$\widebarbm{A}$       & by \verb|$\widebarbm{A}$|      \\
\hline
$\widebarbm{B}^a$     & by \verb|$\widebarbm{B}^a$|    \\
\hline
$\widebarcal{A}$      & by \verb|$\widebarcal{A}$|     \\
\hline
$\widebarcal{B}^a$    & by \verb|$\widebarcal{B}^a$|   \\
\hline
$\widebarbmcal{A}$    & by \verb|$\widebarbmcal{A}$|   \\
\hline
$\widebarbmcal{B}^a$  & by \verb|$\widebarbmcal{B}^a$| \\
\hline
\end{tabular}
\end{center}

\end{document}

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.