I am trying to create a macro that improves on \fbox
by working correctly in all cases and by being minimally invasive with respect to padding. What I've got so far works fairly well, but I'm having trouble measuring text width, height, and depth in certain cases. My question is How do I calculate these correctly?
Why I don't like \fbox:
Notice below how
\fbox
gets the bounding boxes correct on the ‘,’ and the ‘l’, but completely messes up the fraction size when invoked as$\frac{\fbox{1}}{\fbox{2}}$
and the superscript size when invoked as$x^{\fbox{2}}$
.\fbox
draws a rule around the bounding box rather than inside it. Thus, no matter how thin the rule, it still alters the dimensions of the text being boxed. In other words,\fbox
is not minimally invasive. Below, the padding and line thickness are set with\setlength\fboxsep{0pt}
and\setlength\fboxrule{0.001pt}
. Setting\fboxrule
to0pt
causes the rule to disappear altogether.
First attempt at a non-invasive box (using \vrule):
My first attempt used a \vrule
. This was good, but it obscured text when the bounding box overlapped another character, for example the ‘r’ below. Worse yet, I didn't see how I could draw a dark rule around the box. So I threw out that idea.
Second attempt (using TikZ):
Next I used TikZ to draw a translucent filled box. The edge is not a stroked path around the box but rather is four very thin filled rectangles inside the bounding box.
Now this is getting somewhere. The problem, however, is in how I’m measuring the width, height, and depth of the bounding box. I'm using \settowidth
, \settoheight
, and \settodepth
and giving these the value #1
passed to the macro. This approach works great for regular text, but once something is in a superscript, subscript, a fraction, or a stacked relation—or in any other font or size for any reason—it breaks down.
Problems:
As you can see, the widths, heights, and depths of certain elements below have been calculated incorrectly. The most egregious of is the \cdot
, whose bounding box appears to its left because my macro doesn't know that it is a binary relational operator needing extra space. I'm not sure if that is fixable, but is there at least some way to fix the superscripts and subscripts? Because although $v_{\fillbox{x}}$
comes out with undisturbed spacing, it's measuring the size of x
’s bounding box based on #1
being x
(normal size and style) and not _x
(subscripted math size and style).
Finally, why does the stacked relation disturb the horizontal spacing?
Minimal working example:
\documentclass{article}
\usepackage{tikz}
\makeatletter
\newlength\fillbox@height%
\newlength\fillbox@depth%
\newlength\fillbox@width%
\newcommand{\fillbox}[1]{%
\ifmmode%
\settoheight{\fillbox@height}{$#1$}%
\settodepth{\fillbox@depth}{$#1$}%
\settowidth{\fillbox@width}{$#1$}%
\else%
\settoheight{\fillbox@height}{#1}%
\settodepth{\fillbox@depth}{#1}%
\settowidth{\fillbox@width}{#1}%
\fi%
\raisebox{-\fillbox@depth}{%
\begin{tikzpicture}[scale=1]
\pgfsetfillcolor{yellow!90!red}
\pgfsetfillopacity{0.5}
\pgfsetrectcap
\fill (0,-\fillbox@depth) rectangle (\fillbox@width,\fillbox@height);
\pgfsetfillcolor{yellow!50!black}
\pgfsetfillopacity{1}
\fill (0,-\fillbox@depth)
rectangle (\fillbox@width,-\fillbox@depth+.1pt);
\fill (0,\fillbox@height)
rectangle (\fillbox@width,\fillbox@height-.1pt);
\fill (0,-\fillbox@depth)
rectangle (.1pt,\fillbox@height);
\fill (\fillbox@width,-\fillbox@depth)
rectangle (\fillbox@width-.1pt,\fillbox@height);
\end{tikzpicture}%
\kern-\fillbox@width%
}%
#1%
}
\makeatother
\begin{document}
\vskip1em
$\fillbox{p}_{\fillbox{x}}
\mathrel{\stackrel{\fillbox{_{~+}}}{\fillbox{\leftarrow}}}
\fillbox{(}\fillbox{\frac{\fillbox{1}}{\fillbox{2}}}\fillbox{\cdot}
\fillbox{a}_{\fillbox{x}}\fillbox{\cdot}%
\fillbox{\Delta}\fillbox{t}^{\fillbox{2}}\fillbox{)} \fillbox{+}
\fillbox{(}\fillbox{v}_{\fillbox{x}}\fillbox{\cdot}%
\fillbox{\Delta}\fillbox{t}\fillbox{)}$\fillbox{;}\par
$\fillbox{v}_{\fillbox{x}}
\mathrel{\stackrel{\fillbox{_{~+}}}{\fillbox{\leftarrow}}}
\fillbox{a}_{\fillbox{x}}\fillbox{\cdot}%
\fillbox{\Delta}\fillbox{t}$\fillbox{;}\par
\vskip1em
$p_x \mathrel{\stackrel{_{~+}}{\leftarrow}}
(\frac{1}{2}\cdot a_x\cdot\Delta t^2) + (v_x\cdot\Delta t)$;\par
$v_x \mathrel{\stackrel{_{~+}}{\leftarrow}} a_x\cdot\Delta t$;\par
\end{document}
(Note: I didn't tag this question with tikz
because even though it uses TikZ, the question is really about spacing and boxing; TikZ just happens to be used.)