I'd like to bot a square box around some text. I'd like to denote a labelled object of size 1, in combinatorics this is often symbolised by something like \boxed{1}. It would be nicer if the box was a square. Is there an adequate command for this?
-
So even if your text is not "square", you want to place a square box around it? – Werner Jan 26 '12 at 21:08
-
Short answer: yes. Long answer: You are right, that's a problem for beauty. But the square is used in graph theory for leaves of trees and I want to adopt this. – lumbric Jan 26 '12 at 21:22
6 Answers
Here is the mandatory overkill tikz version. Since it is uses tikz all the flexibility inherent in tikz is available to customize the square:

Notes:
- Will not work if the text is very long unless it is placed in a
\parbox.
Code:
\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{shapes}
\makeatletter
\newdimen@myBoxHeight%
\newdimen@myBoxDepth%
\newdimen@myBoxWidth%
\newdimen@myBoxSize%
\newcommand{\SquareBox}[2][]{%
\settoheight{@myBoxHeight}{#2}% Record height of box
\settodepth{@myBoxDepth}{#2}% Record depth of box
\settowidth{@myBoxWidth}{#2}% Record width of box
\pgfmathsetlength{@myBoxSize}{max(@myBoxWidth,(@myBoxHeight+@myBoxDepth))}%
\tikz \node [shape=rectangle, shape aspect=1,draw=red,inner sep=2\pgflinewidth, minimum size=@myBoxSize,#1] {#2};%
}%
\makeatother
\begin{document}
\SquareBox{I}
\SquareBox{y}
\SquareBox[thick, dashed]{long text}
\SquareBox[draw=blue]{longer text}
\SquareBox[draw=blue, thick, fill=yellow]{$e = mc^2$}
\SquareBox[draw=black, thick, fill=yellow!10, rounded corners=2pt]{$\displaystyle \int_{-\dfrac{\pi}{2}}^{\dfrac{\pi}{2}} dx $}
\end{document}
- 223,288
-
looks nice, you just need to do the vertical correction (the "raise value" is
-0.5*(myBoxSize-1.2*myBoxHeight+1.2*myBoxDepth)) – yo' Jan 26 '12 at 23:17 -
@tohecz: not sure what you mean. Is that related to why I needed the
1.2fudge factor? – Peter Grill Jan 26 '12 at 23:19 -
I think that it is better to align the boxes by their baseline and not by their bottom. Check the line
\setlength{\@tempdimb}{(\@tempdima-\ht1+\dp1)/2}in my code, it deals with the vertical correction. I was just suggesting you the same correction, because obviously your answer usestikzwith all its features ;) – yo' Jan 26 '12 at 23:28 -
@tohecz: It does not appear as if it is necessary, the contents appeared to be centered already. – Peter Grill Jan 27 '12 at 02:15
-
@PeterGrill: You can set the key
text width. In this case you don't need a\parbox. – Marco Daniel Jan 27 '12 at 09:53
Here a solution based on my collectbox package. This makes it support verbatim and other special text.
It doesn't change the baseline of the content, which is what you normally want.
\documentclass{article}
\usepackage{collectbox}
\makeatletter
\newcommand{\sqbox}{%
\collectbox{%
\@tempdima=\dimexpr\width-\totalheight\relax
\ifdim\@tempdima<\z@
\fbox{\hbox{\hspace{-.5\@tempdima}\BOXCONTENT\hspace{-.5\@tempdima}}}%
\else
\ht\collectedbox=\dimexpr\ht\collectedbox+.5\@tempdima\relax
\dp\collectedbox=\dimexpr\dp\collectedbox+.5\@tempdima\relax
\fbox{\BOXCONTENT}%
\fi
}%
}
\makeatother
\usepackage{graphicx}% just for the example text
\begin{document}
.. \sqbox{Text} .. \sqbox{Very very long Text} .. \sqbox{\scalebox{.1}[10]{Stretched}} .. \sqbox{$\sum\limits_{k=0}^{10} x_k = i$} .. \sqbox{\verb+$%^&+}
\end{document}

Alternatively you can avoid the package and box the content directly:
\documentclass{article}
\makeatletter
\newcommand{\sqbox}[1]{%
\@begin@tempboxa\hbox{#1}%
\@tempdima=\dimexpr\width-\totalheight\relax
\ifdim\@tempdima<\z@
\fbox{\hbox{\hspace{-.5\@tempdima}\usebox\@tempboxa\hspace{-.5\@tempdima}}}%
\else
\ht\@tempboxa=\dimexpr\ht\@tempboxa+.5\@tempdima\relax
\dp\@tempboxa=\dimexpr\dp\@tempboxa+.5\@tempdima\relax
\fbox{\usebox\@tempboxa}%
\fi
\@end@tempboxa
}
\makeatother
\usepackage{graphicx}% For example only
\begin{document}
\noindent
.. \sqbox{Text} .. \sqbox{Very very long Text} .. \sqbox{\scalebox{.1}[10]{Stretched}} .. \sqbox{$\sum\limits_{k=0}^{10} x_k = i$} ..
\end{document}
- 262,582
-
You can really change the box dimensions with
\ht,\dp,\wdcommands? Please confirm that I read your code correctly, because it would turn boxes into even more powerful weapon! – yo' Jan 27 '12 at 22:38 -
1@tohecz: yes, you can change the box dimensions! However
\advance\ht\mybox by <somevalue>, aka.\addtolengthdoesn't work, just straight assignments. You need to pay attention if you change the width because you only add (or remove) space from the right. It is better to re-box the content with added horizontal space like above. Check the code of myadjustboxpackage especially\marginboxand\trimboxif you want to see more. – Martin Scharrer Jan 27 '12 at 22:50
This should work for you. It does the necessary vertical corrections so that the text is on a baseline (the same vertical level as the surrounding text). You can change the \fboxsep line to get more or less tight box.
Edit: I removed the \smash command, now even constructions like $\left(\Sq{12345}^n\right)$ work.
Edit 2: Added \textSq for text-mode contents and modified \Sq to accept math-mode.
\documentclass{article}
\usepackage{calc}
\makeatletter
\def\textSq#1{%
\begingroup% make boxes and lengths local
\setlength{\fboxsep}{0.3ex}% SET ANY DESIRED PADDING HERE
\setbox1=\hbox{#1}% save the contents
\setlength{\@tempdima}{\maxof{\wd1}{\ht1+\dp1}}% size of the box
\setlength{\@tempdimb}{(\@tempdima-\ht1+\dp1)/2}% vertical raise
\raise-\@tempdimb\hbox{\fbox{\vbox to \@tempdima{%
\vfil\hbox to \@tempdima{\hfil\copy1\hfil}\vfil}}}%
\endgroup%
}
\def\Sq#1{\textSq{\ensuremath{#1}}}%
\makeatother
\begin{document}
Hello \textSq{1} world! $f(x):=\Sq1+\Sq2$.
\end{document}

-
Needs a slight tweak: It should be
\setbox1=\hbox{\ensuremath{#1}}to be able to handle the case of$f(x):=\Sq1+\Sq{x^2}$. – Peter Grill Jan 27 '12 at 01:57 -
@PeterGrill Thanks. As I'm really not a fan of
\ensuremath(it is somehow a "non-predictable" command), so I made it into 2 commands. – yo' Jan 27 '12 at 22:36 -
You're solution is good. Don't know what you mean by "non-predictable". Maybe you have been hanging around @egreg? :-) – Peter Grill Jan 27 '12 at 22:52
-
@PeterGrill Well, I want a macro that produces text in text-mode and math in math-mode. The command
\ensuremathdoes something you should never need, because you---the typesetter---is the one who controls the code, and you should not give this control to such commands. – yo' Jan 27 '12 at 23:18 -
@PeterGrill To a specific example: If I defined
\Squsing\ensuremath, then someone can come, write\Sq{x^2}+\Sq{y^2}and he would think what a nice math-mode construction he made, however, it is not a math-mode, but two math-modes with a text-mode+in-between. – yo' Jan 27 '12 at 23:34
tohecz just beat me to it. Here is an alternative version:
\documentclass[letterpaper,11pt]{article}
\usepackage{calc}
\newlength{\spacer}
\newsavebox{\mybox}
\newcommand{\squarebox}[1]{%
\sbox\mybox{#1}%
\setlength{\spacer}{0.5\wd\mybox-0.5\ht\mybox}%
\fbox{\parbox{\wd\mybox}{\vspace{\spacer}\usebox\mybox\vspace{\spacer}}}%
}
\begin{document}
\squarebox{does this look great or what?}
\end{document}

- 3,665
-
the text in the box is a bit vertically mal-positioned:
\squarebox{boxed text \_\_}\_\_ baseline– yo' Jan 26 '12 at 22:31
This is a solution that uses pstricks the great Herbert Voss offered some years ago:
\documentclass[12pt]{article}
\usepackage{pstricks}
\usepackage{auto-pst-pdf} % for easy pdf-output - otherwise comment this out
\def\bBox#1#2{\makebox[#1]{#2}}
\def\bhBox#1#2{\parbox[c][#1][c]{#1}{\makebox[#1]{#2}}}
\def\bhpBox#1#2{\parbox[c][#1][c]{#1}{\centering #2}}
\begin{document}
%\psset{framesep=0}
\psframebox{\bBox{1.3cm}{A}} und \psframebox{\bBox{1.3cm}{BBBBB}}
\psframebox{\bhBox{1.3cm}{A}} und \psframebox{\bhBox{1.3cm}{BBBBB}}
\psframebox{\bhpBox{1.3cm}{A}} und \psframebox{\bhpBox{1.3cm}{BBBBB}}
\end{document}
- 891
Below is a solution based on ConTeXt. I define a special \framed for the task, so all the options of \framed work:
\unprotect
\newdimen\d_square_size
\defineframed[squared_box]
[
\c!location=\v!lohi,
\c!width=\d_square_size,
\c!height=\d_square_size,
]
\def\squared_and_framed_box
{\ifdim\wd\nextbox>\dimexpr(\ht\nextbox+\dp\nextbox)\relax
\d_square_size=\wd\nextbox
\else
\d_square_size=\dimexpr\ht\nextbox+\dp\nextbox\relax
\fi
\squared_box{\box\nextbox}%
\endgroup
}
\def\squarebox
{\dosingleargument\squarebox_indeed}
\def\squarebox_indeed[#1]%
{\begingroup
\setupframed[squared_box][#1]%
\dowithnextbox\squared_and_framed_box\hbox}
\protect
\starttext
\unknown\squarebox{ABCDEF}
\unknown\squarebox[framecolor=red]{A very long text}
\unknown\squarebox[corner=round]{$\displaystyle\sum_{i=1}^n$}
\stoptext
which gives

You can add a offset=<dimen> to the \defineframed command to have some offset between the text and the frame.
- 62,301