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 want to box text using TikZ and adjust the box width such that the text is appropriately put on different lines within the box. I also want the text on each to be centered within the box. As this is my first experience using TikZ, I'm a bit lost as to what can and cannot be done. This is what I have tried so far:

\documentclass{book}
\usepackage{tikz}

\begin{document}
\newlength{\myboxwidth}
\newcommand{\MyBox}[3][XXX]{
\settowidth{\myboxwidth}{#1} % THIS DOESN'T WORK
%\setlength{\myboxwidth}{20mm} % THIS WORKS
\draw (#2) 
%\pgfextra{\setlength{\myboxwidth}{20mm}} % THIS WORKS
%\pgfextra{\settowidth{\myboxwidth}{#1}}  % THIS DOESN'T WORK
node 
[rectangle,draw,minimum width=2em,minimum height=2em,
text width=\myboxwidth,
text centered, inner sep=1ex] {#3};
}

\begin{tikzpicture}
\MyBox[animals]{0,0}{animals cats \& dogs}
\MyBox[trees]{3,0}{trees oak aspen}
\end{tikzpicture}
\end{document}

In the left-hand box, I want "animals" on the first line and "cats & dogs" on the next, while in the right-hand box every word must be on its own line. Why is it that specifying \myboxwidth with an explicit length like 20mm works but asking LaTeX, which is what I'm using, to evaluate the word length fails? Each of the lines followed by a THIS WORKS or THIS DOESN'T WORK comment have been tried one at a time.

In addition to the above, I've tried using {\parbox{\myboxwidth}{#3}} instead of just {#3} and I've also tried the obvious line-splitting with \\ without success. Can anyone help please?

Oh, and placing the \settowidth command before \begin{tikzpicture} works too.

share|improve this question
    
If you indent lines by 4 spaces, then they are marked as a code sample. You can also highlight the code and click the "code" button (with "{}" on it). –  Caramdir Jun 9 '11 at 15:13
add comment

3 Answers 3

up vote 6 down vote accepted

PGF math has a width function that measures the width of its parameter. It can be accessed with \pgfmathparse{width("some text")} or \pgfmathwidth{"some text"}. The result is then stored in \pgfmathresult.

I think text centered is a depreciated option. Using align=center instead makes \\ work as expected.

\documentclass{book}
\usepackage{tikz}

\begin{document}
\newcommand{\MyBox}[3][XXX]{
    \pgfmathwidth{"#1"}
    % store the result before it gets overwritten by some internal call to `\pgfmath...`.
    \let\myboxwidth\pgfmathresult
    \draw (#2) 
        node 
        [rectangle,draw,minimum width=2em,minimum height=2em,
        text width=\myboxwidth,
        text centered, inner sep=1ex] {#3};
}

\begin{tikzpicture}
    \MyBox[animals]{0,0}{animals cats \& dogs}
    \MyBox[trees]{3,0}{trees oak aspen}

    \draw (0,-2) node 
        [rectangle, draw, align=center, inner sep=1ex] {animals\\ cats \& dogs};
    \draw (3,-2) node 
        [rectangle, draw, align=center, inner sep=1ex] {trees\\ oak aspen};
\end{tikzpicture}
\end{document}

result

Both of these solutions only work with TikZ/PGF version 2.10 (and higher).

share|improve this answer
    
This work just as I want it to. But why is it that \pgfmathwidth cannot be used directly but has to be passed on to \myboxwidth? –  Luis Costa Jun 9 '11 at 15:39
    
The align=center is even better as now I don't have to evaluate the text width. Brilliant. –  Luis Costa Jun 9 '11 at 15:51
    
@Luis: All the pgf-math macros don't return the value but set \pgfmathresult to the result of the combination. I guess this avoids some potential problems. –  Caramdir Jun 9 '11 at 15:53
    
I noticed the explanatory question to my \pgfmathwidth comment only now.:-) –  Luis Costa Jun 9 '11 at 15:56
add comment

Just a little change in Caramdir's solution. Use text width=\widthof{#1}. The results are the same.

\documentclass{book}
\usepackage{tikz}

\begin{document}
\newcommand{\MyBox}[3][XXX]{
    \draw (#2) 
        node 
        [rectangle,draw,minimum width=2em,minimum height=2em,
        text width=\widthof{#1}, %<---- Change here
        text centered, inner sep=1ex] {#3};
}

\begin{tikzpicture}
    \MyBox[animals]{0,0}{animals cats \& dogs}
    \MyBox[trees]{3,0}{trees oak aspen}

    \draw (0,-2) node 
        [rectangle, draw, align=center, inner sep=1ex] {animals\\ cats \& dogs};
    \draw (3,-2) node 
        [rectangle, draw, align=center, inner sep=1ex] {trees\\ oak aspen};
\end{tikzpicture}
\end{document}
share|improve this answer
    
Thanks, this is a very useful tip. I see that tikz/pgf is very powerful and flexible, to say the least. –  Luis Costa Jun 13 '11 at 7:01
add comment
\documentclass{book}
\usepackage{calc,array}
\newcolumntype{C}[1]{>{\centering}b{\widthof{#1}}}
\newcommand\MyBox[2][XXX]{%
  \fbox{\tabular[b]{C{#1}} #2 \endtabular}}
\begin{document}

foo 
\MyBox[animals]{animals cats \& dogs}\quad
\MyBox[trees]{trees oak aspen} 
bar

\end{document}

enter image description here

share|improve this answer
    
I've done this as well using PSTricks, but I wanted to do this now specifically using tikz. You can do it also by saying \settowidth{\myboxwidth}{some} \fbox{\parbox{\myboxwidth}{some text}}. –  Luis Costa Jun 9 '11 at 16:14
add comment

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.