# Custom textoverset, align letter bases

I try to render chords above text using the help of the leadsheets package. The leadsheets package provides a high-level command \chord{A#} which I avoid for reasons I forgot (does not matter much, it turns out the question is independent of leadsheets). So I use a custom \overset{A#}{foo} command (approximately copied from here Creating non-math mode substitutes for \overset and \underset not dependent on the amsmath package):

\documentclass{book}

% print chord over the line spanning several characters
\newcommand\textoverset[2]{%
\leavevmode
\vbox{\offinterlineskip
\halign{%
##\hfil\cr
\vphantom{A}#1\cr
\noalign{}
\strut#2\cr
}%
}%
}

\begin{document}

% \writechord from leadsheets package, \textoverset defined above
appar\textoverset{\writechord{Dm}}{ence}s\textoverset{\writechord{A\#}}{} \textoverset{\writechord{C}}{} ...

% EDIT: Inside song environment, sharp can be written without slash
\begin{song}{title=Foo}, interpret={F.Oo}\index{Foosong}

appar\textoverset{\writechord{Dm}}{ence}s\textoverset{\writechord{A#}}{} \textoverset{\writechord{C}}{} ...

\end{song}

\end{document}


Run with latexmk -xelatex.

Rendering:

The problem is that the chord letters D, A and C in the example are not vertically aligned. I assume that's due to the rendering of the sharp symbol ♯ in the leadsheets package which has a vertical lower bound that is lower than letters, though the rendering of the sharp symbol seems very special (maybe to make it larger), not sure what magic is used there. The \chord command from leadsheets does not have that flaw, but I do not understand low-level latex enough to copy that approach.

What's the best way to get the letters vertically aligned (for me it would be acceptable if the sharp symbol could overlap with text below). It would also be acceptable to change the leadsheet way of rendering the sharp symbol, if that's easier, though it looks pretty the way it is.

(EDIT: Actually the same vertical misalign can be reproduced without leadsheets, just using overset test Aj and Ax. Ideally the bases of the as should be verticaly aligned. But for this question, only a solution for the sharp symbol in leadsheets is required, as the general solution might be harder, and luckily music notation does not have many other symbols with low hanging bases.)

• You can probably change the way, \chord behaves which is likely to be an easier way than trying to reimplement it. You should give an example of how it “unduly spreads text” and ask how to prevent it. – cgnieder Aug 26 '20 at 9:20
• The example text you're already showing is easy with \chord so I need to see an example where it actually fails... – cgnieder Aug 26 '20 at 11:10
• @cgnieder: Sorry, I actually cannot remember why I avoid \chord (changed in question). Generally I am trying to auto-convert plain txt format (utimate-guitar-style) to latex. Maybe \chord was too strict, or I could not figure out by algorithm whether to use \chord or \chord*, or how to mix chords and non-chords above the lyrics. If you're curious, my project is at gitlab.com/tkruse/repertoire, current PDF at gitlab.com/tkruse/repertoire/-/blob/leadsheets/dist/…. Most songs are plain, but in some I have weird chord notation or rhythm above the lyrics line. – tkruse Aug 26 '20 at 12:49

You seem to have redefined \#, because your code produces a # and not a sharp sign. Just smash it.

\documentclass{book}

% print chord over the line spanning several characters
\newcommand\textoverset[2]{%
\leavevmode
\vbox{\offinterlineskip
\halign{%
##\hfil\cr
\vphantom{A}#1\cr
\noalign{}
\strut#2\cr
}%
}%
}
\DeclareRobustCommand{\#}{\smash{$\sharp$}}

\begin{document}

\show\#

% \writechord from leadsheets package, \textoverset defined above
appar\textoverset{\writechord{Dm}}{ence}s\textoverset{\writechord{A\#}}{} \textoverset{\writechord{C}}{} ...

\end{document}


• Ah, inside a \begin{song} environment of leadsheet I can actually write A# instead of A\#, but then your solution wont work. Is it ok if I change the question to reproduce that' I assume I would have to do the smashing inside the song environment? I just added more lines. – tkruse Aug 26 '20 at 10:12
• In this case, I believe this might work: \DeclareRobustCommand{\#}{\smash{$\sharp$}} \setchords{sharp = {\#}}, using the leadsheet function to redefine the sharp command, and your smashing. If you change your answer like that, I will accept. The more general problem with letters like j,y and g can be discussed in the comments of your other answer tex.stackexchange.com/questions/42456 – tkruse Aug 26 '20 at 10:27
• Anyway, I confirm this works with leadsheet song environment for my full document with the change from my previous comment. – tkruse Aug 26 '20 at 10:29

With some help from @egreg based on whose answer I had made the custom \textoverset, I came up with this variation, which provides more stable alignment of all oversets:

\newcommand\textoverset[2]{%
\leavevmode
\vbox{\offinterlineskip
\halign{%
##\hfil\cr % center
\strut#1\cr
\vphantom{(/Aj}#2\cr
}%
}%
}


I cannot explain well what goes on here in contrast to the original (anyone may modify the answer to explain), but this seems to work robustly for various characters, aligning oversets.