Here's a TikZ solution without tikzmark
that uses amsmath
's \overset
/\underset
/\overunderset
.
While this doesn't produce a nice cloud yet it is the base of further customization, for example, like the one by Heiko Oberdiek.
For now, I settled on a rounded rectangle, gray color and smaller text.
By default, amsmath
sets the over- and undersets in \scriptstyle
which we could do, too, but I don't think it looks good.
Code
\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\tikzset{
cloud eq/.cd,
edge/.style={rounded corners=+2pt, arrows=Latex[round]-},
c/.style={cloud eq/edge,anchor=north,to path={--++( +0pt,+-2ex)\tikztonodes}},
l/.style={cloud eq/edge,anchor=east, to path={|-++(+-1ex,+-2ex)\tikztonodes}},
r/.style={cloud eq/edge,anchor=west, to path={|-++( +1ex,+-2ex)\tikztonodes}},
node/.style={at end, draw, rounded corners=+1pt}
}
\newcommand*\tikzoverunderInternal[3]{%
\tikz[trim left=+0pt, trim right=+0pt]
\draw[cloud eq/#1, #2] (0,0) to node[cloud eq/node] {$#3$}();}
\NewDocumentCommand\tikzUnderset{ O{l} m }{
\underset{\tikzoverunderInternal{#1}{}{#2}}}
\NewDocumentCommand\tikzOverset { O{l} m }{
\overset{\tikzoverunderInternal{#1}{yscale=-1.2}{#2}}}
\NewDocumentCommand\tikzOverUnder {O{l} m O{r} m}{
\overunderset{
\tikzoverunderInternal{#3}{yscale=-1.2}{#4}}{
\tikzoverunderInternal{#1}{}{#2}}}
\usepackage{blindtext}
\tikzset{
cloud eq/node/.append style={scale=.7},
cloud eq/edge/.append style=gray}
\begin{document}
\blindtext
\begin{align}
a^2 & \tikzUnderset{h = b \cdot \sin\alpha}{=}
(b \cdot \sin \alpha)^2 \tikzOverset[r]{a+b}{+} n^2 \\
c^2 & \tikzUnderset[c]{\vphantom{\int_i} E=mc^2}{=}
a^2 + b^2 \tikzOverUnder[c]{\int_i e^i}
[r, overlay]{a^2 >0, b^2>0}{>} 0
\end{align}
\blindtext
\end{document}
Output
align*
without alignment points?