23

How can I get a linebreak inside a matrix node? The following gives the error:

Package tikz Error: Giving up on this path. Did you forget a semicolon?.

unless I remove the linebreak.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{chains}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
    \matrix (m) [
        matrix of nodes
    ] {
         {some text} &
         {this node \\ does not work} \\
         {other text} &
         {more text} \\
    };
\end{tikzpicture}
\end{document}
Troy
  • 13,741
Tim N
  • 10,219
  • 13
  • 63
  • 88
  • 1
    @alfred-m I just tested it (using Sharelatex online service, which uses pdflatex and a recent tex distribution), and the answer by T.Verron works without problem. – JLDiaz Nov 18 '15 at 11:42
  • @JLDiaz: I can also compile the example (I updated pgf in the mean time). However, it requires the specification of the text width. I would like to break lines only using explicit line breaks and let the dimensions of the nodes be automatically fixed otherwise. – M. Toya Nov 18 '15 at 14:47
  • @AlfredM. If you wanted to get my attention on this problem, posting a comment to the answer would have been safer. ;) As far as I know, there is no easy way to get rid of the text width option. If I remember correctly, the reason for this option is that a node with a line break is implemented as a minipage, and this requires setting the width explicitely. However, if you aren't interested in doing that in a matrix cell, you can use two nodes aligned in a matrix to emulate the linebreak behavior. – T. Verron Nov 18 '15 at 15:16
  • or nodes={align=center} – percusse Nov 19 '15 at 00:32
  • @percusse I guess then the anchors (m-3-5) break, would they? – Symbol 1 Nov 19 '15 at 01:00
  • @Symbol1 Why would they? – T. Verron Nov 19 '15 at 07:13
  • @percusse What do you mean? It doesn't compile with align=center and no text width specification. – T. Verron Nov 19 '15 at 07:15
  • @T.Verron Because for general nodes if you set text width to a large value and align the text at center, the text will be at the center but the node is still large. Therefore anchors like (X.south east) would be far away from the expected position. (In case of matrix, it would first produce an even larger matrix... so my comment did not make sense) – Symbol 1 Nov 19 '15 at 07:23
  • @Symbol1 Oh I see, even the default anchor at center is off (well, it's not, but a path drawn towards it will be clipped prematurely). This is mainly caused by the text width, not the alignment. Anyway, I hadn't thought of that, I editted my answer. Thanks! – T. Verron Nov 19 '15 at 07:38
  • @T.Verron most of them are here http://tex.stackexchange.com/questions/123671/manual-automatic-line-breaks-and-text-alignment-in-tikz-nodes – percusse Nov 19 '15 at 10:23
  • @percusse According to this link, setting align without text width should be enough. If you look at the revisions of my answer, you'll see that I used to believe that too, back in may 2013. However, apparently it was no longer the case in sept. 2013, if it ever was (it was long ago... I think I tested before posting, but...) It seems that you tested it back in july 2013 as well, based on the comments in the linked thread. Do you know what changed exactly in summer 2013 on this matter? – T. Verron Nov 19 '15 at 13:58
  • @percusse (Too late for editting) Apparently, align is enough for a node, not for a matrix cell. --- And reading back the whole conversation, I guess that it is what you meant from the start. Sorry! – T. Verron Nov 19 '15 at 14:03
  • @T.Verron I'll try to check later. Can you try with double braces on the node contents in the meantime? It should work as is though I am just guessing. It's been a while for me – percusse Nov 19 '15 at 14:25
  • @percusse No, it's not better. Specifying the node manually does work though. – T. Verron Nov 19 '15 at 14:53

3 Answers3

23

Just like in any node, you need to specify the alignment in order to break the line.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{chains}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
    \matrix (m) [
        matrix of nodes, 
        nodes={align=left, text width=3cm} % New!
    ] {
         {some text} &
         {text with \\ linebreak} \\
         {other text} &
         {more text} \\
    };
\end{tikzpicture}
\end{document}

For some reason, for a node in a matrix, you also need to specify the width of the node text.

Any value larger than the actual width should work, but when finalizing your document, you should try to get the value as close as possible to the actual width of the text, so that the node anchors stand where they are expected to.

--- Edit ---

If one wants to avoid the text width specification, it is possible to draw the node manually:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{chains}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
    \matrix (m) [
        matrix of nodes%, 
        %nodes={align=left, text width=3cm} % Not needed now
    ] {
         {some text} &
         \node[align=left] {text with \\ linebreak}; \\      
         {other text} &
         {more text} \\
    };
\end{tikzpicture}
\end{document}
Moriambar
  • 11,466
T. Verron
  • 13,552
  • 5
    I still get ! Package tikz Error: Giving up on this path. Did you forget a semicolon?. when compiling your example, without any modification. What version of tikz or other is required for this to work? – Suzanne Soy Sep 16 '13 at 11:55
  • 1
    Hmf. It doesn't work here either. I'm pretty sure I tested it back then, and I think the OP wouldn't have accepted it if it didn't work, but I also don't think I updated any tikz package since then. So no idea what's happening. Anyway, I'm adding a fix to the answer. Thanks for the notification! – T. Verron Sep 16 '13 at 14:38
10

Here's an alternative which wraps the contents of each of the nodes within the matrix in the variable-width \pbox defined by the pbox package using the execute at begin cell option. You could selectively apply the \pbox to the offending material, but this approach allows the syntax of the question to be used. The \linewidth is the maximum width for the node. As the nodes are sized individually, the default left-alignment of the \pbox looks strange in my opinion, hence the regexpatch to center the contents.

Edit: As pointed out by @cfr in the comments, \usetikzlibrary{chains} from the MWE in the original question is not necessary.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}

\usepackage{pbox}
\usepackage{regexpatch}
\makeatletter
    \xpatchcmd{\pb@xiii}{{\parbox[\pb@xargi]{\pb@xlen}{#2}}}{{\parbox[\pb@xargi]{\pb@xlen}{\centering#2}}}{}{fail}%
\makeatother

\begin{document}
\begin{tikzpicture}
    \matrix (m) [
        matrix of nodes,
        execute at begin cell = {\pbox[t]{\linewidth}},
    ] {
         {some text to test} &
         {really long text with\\ linebreak}\\
         {other text} &
         {more text} \\
    };
\end{tikzpicture}
\end{document}

enter image description here

Guho
  • 6,115
2

I do not know why. But this works.

\makeatletter
\def\tikz@lib@matrix@smuggle{%
  \bgroup%
  \def\\{\egroup\tikz@lib@matrix@saved@eol\bgroup}%
}
\tikz{
    \matrix(m)[matrix of nodes,nodes={anchor=center,align=center}]{
        some text  & {this node \\ now works}& \\
        other text & more text                 \\
    };
}

P.S. the original definition is in /tikzlibrarymatrix.code.tex line 60:

\def\tikz@lib@matrix@smuggle{%
  \bgroup%
  \let\\=\tikz@lib@matrix@saved@eol%
}

This suggests that the TikZ stopped because it reached something like

 \node{{this node \\ does not work}};

And the new definition leads to

 \node{{this node }\\{ now works}};

P.S.2. This is not widely tested.

Symbol 1
  • 36,855