# TikZ multipart nodes: How to set text attributes (opacity) for some/all parts

I am using TikZ with the rectangle split multipart node (detailed on pp 450ff in the PGF 2.1 documentation). I need to influence the text opacity of all parts, but whatever I try seems to work only on the text (=first) part of the multipart node:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}

\begin{document}
\begin{tikzpicture}
\node[rectangle split, rectangle split parts=2, draw, text opacity=0.5]{%
transparent :-)
\nodepart{two}
not transparent :-(
};
\end{tikzpicture}
\end{document}


results in:

I have also tried \nodepart[text opacity=0.5]{two} and even Heiko Oberdiek's transparent package to set the text transparency manually, which, however does not seem to play together with PGF. There also seem to be no every ... styles for the additional parts of the rectangle split node.

I must be overlooking something.

-
The every ... style for the second part is defined by every two node part/.style={...} (see p.179). However that also doesn't help. Seems like a bug to me. –  Caramdir May 27 '12 at 17:50

I submitted a bug report at the Sourceforge page.

A temporary workaround would be to put the following into your preamble:

\makeatletter
\def\tikz@nodepart@continue{%
\global\let\tikz@fig@continue=\tikz@fig@continue@orig%
% Now start new box:
\expandafter\setbox\csname pgfnodepart\tikz@nodepart@name box\endcsname=\hbox%
\bgroup%
\tikzset{every \tikz@nodepart@name\space node part/.try}%
\expandafter\tikzset\expandafter{\tikz@nodepart@options}%
\ifx\tikz@textopacity\pgfutil@empty%
\else%
\pgfsetfillopacity{\tikz@textopacity}%
\pgfsetstrokeopacity{\tikz@textopacity}%
\fi%
\pgfinterruptpicture%
\tikz@textfont%
\ifx\tikz@text@width\pgfutil@empty%
\else%
\begingroup%
\pgfmathsetlength{\pgf@x}{\tikz@text@width}%
\pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}%
\tikz@text@action%
\fi%
\bgroup%
\aftergroup\unskip%
\ifx\tikz@textcolor\pgfutil@empty%
\else%
\pgfutil@colorlet{.}{\tikz@textcolor}%
\fi%
\pgfsetcolor{.}%
\setbox\tikz@figbox=\box\pgfutil@voidb@x%
\tikz@uninstallcommands%
\tikz@atbegin@node%
\aftergroup\tikz@fig@collectresetcolor%
\tikz@halign@check%
\ignorespaces%
}
\makeatother


Everything except for the marked code is copied from tikz.code.tex (the marked code is also from that file, but taken from the definition of \tikz@do@fig).

-
Well, there he is, the hero :-) Many thanks, also for reporting the bug. –  Daniel May 29 '12 at 6:53
Very nice fix indeed. I think now that this question can be handled like this too just after your modification. –  percusse May 29 '12 at 9:47
@percusse: I don't see how this is relevant for the linked question (minimum height is directly used in the node shape code) –  Caramdir May 29 '12 at 16:18
I thought it can be used to increase the \nodeparttwobox and other boxes... –  percusse May 29 '12 at 16:23
@percusse: I tried tracing through the node code. As far as I can tell text hight (not minimum height) is indeed applied at the TikZ level. However I can't figure out where the \nodepart...boxes end and how to set the height there. –  Caramdir May 29 '12 at 16:38

See the edit history for my confusion.

This can be used for changing the color etc. of the parts independently (for which there was a question recently but I couldn't spot it).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}

\begin{document}
\begin{tikzpicture}
\node[rectangle split, rectangle split parts=2, draw,thick,text opacity=0.2]{%
transparent :-)
\nodepart{two}
\begin{pgfinterruptpicture}\pgfsetfillopacity{0.2}
now transparent :-)
\end{pgfinterruptpicture}
};
\end{tikzpicture}
\end{document}


A little bit more automated solution is to make a macro that reads the opacity from the first node part

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\makeatletter
\newcommand{\tnpa}[1]{
\begin{pgfinterruptpicture}\pgfsetfillopacity{\tikz@textopacity}
#1
\end{pgfinterruptpicture}
}
\makeatother

\begin{document}
\begin{tikzpicture}
\node[rectangle split, rectangle split parts=2, draw,thick,text opacity=0.1]{
Transparent \nodepart{two}\tnpa{Together}
};
\end{tikzpicture}
\end{document}


Hence, it needs the second node content to be contained in a macro argument.

-
That is already a lot better than my hack with a nested tikzpicture. Do you see any chance applying this by a style (e.g., every two node part)? –  Daniel May 28 '12 at 5:56
@Daniel I've put things into a macro and more bearable now. I'm afraid of going into the bowels of rectangle split shape. It's indeed too complicated and probably would require more work (at least for me) than is needed by just typing out \tnpa{}. –  percusse May 28 '12 at 7:43
Yeah, that is probably true. The respective PGF code is a "bit" daunting... I can live with the macro; reading the value out of \tikz@textopacity makes it pretty usable. I will neverthelss wait a couple of days for other answers before accepting; maybe some hero feels tempted to delve into pgflibraryshapes.multipart.code.tex :-) –  Daniel May 28 '12 at 8:32
@Daniel: No need to do that; the bug seems to be on the TikZ side of things (specifically, \nodepart forgets to set the stroke opacity). –  Caramdir May 28 '12 at 23:01
For the colour of the parts, the easiest way is to use rectangle split part as in rectangle split part fill={gray!50,green!50,blue!50}. –  Evpok Aug 25 '12 at 20:33

A pretty hacky workaround is to render the text inside a nested tikzpicture. In this case the fact that nesting tikzpictures leads to an (often unexpected) inheritance of settings even serves the actual purpose:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}

\begin{document}
\begin{tikzpicture}[every two node part/.style={text opacity=0.5}]
\node[rectangle split, rectangle split parts=2, draw, text opacity=0.5]{%
transparent :-)
\nodepart{two}
not transparent :-(
};
\end{tikzpicture}
\begin{tikzpicture}[every two node part/.style={text opacity=0.5}]
\node[rectangle split, rectangle split parts=2, draw, text opacity=0.5]{%
transparent :-)
\nodepart{two}
\tikz[]\node[inner sep=0pt, outer sep=0pt, text depth=0pt]{not not transparent :-(};%
};
\end{tikzpicture}
\end{document}


Some more hacking would be necessary to get the size of the node correctly. Well, I certainly would prefer a cleaner solution anyway.

-