Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
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 6

up vote 12 down vote accepted

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}

Result


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}
share|improve this answer
    
You can really change the box dimensions with \ht,\dp,\wd commands? 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. \addtolength doesn'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 my adjustbox package especially \marginbox and \trimbox if you want to see more. –  Martin Scharrer Jan 27 '12 at 22:50

Here is the mandatory overkill tikz version. Since it is uses tikz all the flexibility inherent in tikz is available to customize the square:

enter image description here

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}
share|improve this answer
    
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.2 fudge 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 uses tikz with 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 2:15
    
@PeterGrill: You can set the key text width. In this case you don't need a \parbox. –  Marco Daniel Jan 27 '12 at 9:53

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}

enter image description here

share|improve this answer
    
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 1: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 \ensuremath does 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 \Sq using \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}

enter image description here

share|improve this answer
    
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}
share|improve this answer

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

enter image description here

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.