5

I defined a command to draw a box around a text and, optionally, put another character inside this box.

The command is this (along with MWE):

\documentclass{minimal}

\newlength{\xboxh} % Sets a macro for the height
\newlength{\xboxw} % and for the width

\newcommand{\putbox}[2][]{
\settoheight{\xboxh}{#2}% Gets the height
\settowidth{\xboxw}{#2}% and width of the input
\frame{\phantom{\rule{\xboxw}{\xboxh}}}% And draws a frame around it
\setbox0=\hbox{#1\unskip}\ifdim\wd0=0pt% And if the optional argument is not empty
  \relax
\else
  \hspace{-\xboxw}#1% Prints it too
\fi\relax
}

\begin{document}
  Some text to \putbox{Z} fill up space \par

  Some text to \putbox[Z]{Z} fill up space \par

  Some text to \(\putbox{Z}\) fill up space

  Some text to \(\putbox[Z]{Z}\) fill up space
\end{document}

The command is supposed to have the same behavior in text and math mode. But that's not what happens. When used in text mode the command outputs an unwanted space before and after the box, and also misplaces the content of the box (if any):

enter image description here

How do I fix the spacing issue with the command?

4

You have a spurious space in your definition of \putbox:

enter image description here

\documentclass{article}

\newlength{\xboxh} % Sets a macro for the height
\newlength{\xboxw} % and for the width

\newcommand{\putbox}[2][]{% <------------------- spurious space
  \settoheight{\xboxh}{#2}% Gets the height
  \settowidth{\xboxw}{#2}% and width of the input
  \frame{\phantom{\rule{\xboxw}{\xboxh}}}% And draws a frame around it
  \setbox0=\hbox{#1\unskip}\ifdim\wd0=0pt% And if the optional argument is not empty
    \relax
  \else
    \hspace{-\xboxw}#1% Prints it too
  \fi\relax
}

\begin{document}

Some text to \putbox{Z} fill up space

Some text to \putbox[Z]{Z} fill up space

Some text to \(\putbox{Z}\) fill up space

Some text to \(\putbox[Z]{Z}\) fill up space

Width of Z: \setbox0=\hbox{Z}\the\wd0

Width of $Z$: \setbox0=\hbox{$Z$}\the\wd0

\end{document}

Note that \hbox sets its content in text mode.

2

You need no measuring; besides, you're forgetting the depth.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\makeatletter
\NewDocumentCommand{\putbox}{sm}{%
  \begingroup
  \ifmmode\@tempswatrue\else\@tempswafalse\fi
  \setlength{\fboxsep}{-\fboxrule}%
  \fbox{\IfBooleanTF{#1}{\po@math{#2}}{\po@math{\phantom{#2}}}}%
  \endgroup
}
\newcommand{\po@math}[1]{\if@tempswa\ensuremath{#1}\else#1\fi}
\makeatother

\begin{document}

Some text to \putbox{Z} fill up space

Some text to \putbox*{Z} fill up space

Some text to \putbox*{g} fill up space

Some text to \(\putbox{Z}\) fill up space

Some text to \(\putbox*{Z}\) fill up space

Some text to \(\putbox*{g}\) fill up space

\end{document}

As you see, if the macro is called in math mode, the argument is typeset in math mode as well. The *-variant prints the symbol.

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.