# How to fix bad output of a custom overline macro?

For changing the vertical position of \overline I have found the following macro:

\newcommand*\oline[1]{%
\vbox{%
\hrule height 0.5pt%                  % Line above with certain width
\kern0.4ex%                          % Distance between line and content
\hbox{%
\kern-0.1em%                        % Distance between content and left side of box, negative values for lines shorter than content
\ifmmode#1\else\ensuremath{#1}\fi%  % The content, typeset in dependence of mode
\kern-0.1em%                        % Distance between content and left side of box, negative values for lines shorter than content
}% end of hbox
}% end of vbox
}


But it has bad effect in sub-/superscripts. E.g. see the following MWE:

\documentclass[12pt,a4paper]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\newcommand*\oline[1]{%
\vbox{%
\hrule height 0.5pt%                  % Line above with certain width
\kern0.4ex%                          % Distance between line and content
\hbox{%
\kern-0.1em%                        % Distance between content and left side of box, negative values for lines shorter than content
\ifmmode#1\else\ensuremath{#1}\fi%  % The content, typeset in dependence of mode
\kern-0.1em%                        % Distance between content and left side of box, negative values for lines shorter than content
}% end of hbox
}% end of vbox
}
\begin{document}
\section{title}
$\overline{h},\overline{h_t},\overline{h_{t_1}},\overline{h}_{t_1}$

$\oline{h}, \oline{h_t}, \oline{h_{t_1}}, \oline{h}_{t_1}$
\end{document}


and its output:

How to fix this bad output of \oline?

The bad effect isn't limited to subscripts:

\documentclass[12pt,a4paper]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\newcommand*\oline[1]{%
\vbox{%
\hrule height 0.5pt%                  % Line above with certain width
\kern0.4ex%                          % Distance between line and content
\hbox{%
\kern-0.1em%                        % Distance between content and left side of box, negative values for lines shorter than content
\ifmmode#1\else\ensuremath{#1}\fi%  % The content, typeset in dependence of mode
\kern-0.1em%                        % Distance between content and left side of box, negative values for lines shorter than content
}% end of hbox
}% end of vbox
}
\begin{document}

$a\oline{h}b$

\end{document}


The problem is that you don't cancel the negative kerns you apply to fool the overline into being shorter than the character it should be above.

\documentclass[12pt,a4paper]{article}
\usepackage{amsmath}
\usepackage{amssymb}

\newcommand*\oline[1]{%
\kern0.1em            % Counteract the inner kern
\vbox{%
\hrule height 0.5pt % Line above with certain width
\kern0.4ex          % Distance between line and content
\hbox{%
\kern-0.1em       % Shorten the content on the left
$#1$%             % The content, typeset math mode
\kern-0.1em       % Shorten the content on the right
}% end of hbox
}% end of vbox
\kern0.1em            % Counteract the inner kern
}

\begin{document}

$a\oline{h}b+\oline{h}_{t}+\oline{h_t}$

$ahb+h_t+h_t$

\end{document}


The \ifmmode conditional in your code does nothing at all, because it appears inside \hbox, where the mode is not math: TeX does not carry over the mode when starting a \vbox or a \hbox: it starts them in inner vertical mode and restricted horizontal mode respectively. Thus you just need to start math mode.

The % just after pt, ex and em are wrong: TeX looks for (and ignores) a space token after required units of measure. Leaving out the space can cause problems of untimely expansion. For instance, your \ifmmode is expanded before the kern is actually placed; in this case it's not really a problem, because the conditional is evaluated to false.