# Nested labeled colored boxes with TikZ

I need nested boxes, as they are shown in this question, but colored ones.

I tried both solutions. Using shapes.multipart I totally failed when tried to generate the nodeparts by a foreach command. If I use multiple \tikz parts in one nodepart, I can use foreach, but I am unable to put them in one column (tried matrix and failed).

Trying drs with xcolor I almost got a correct result, but when I write this:

\documentclass{article}

\usepackage{drs}
\usepackage{xcolor}

\begin{document}

\colorbox{green}
{
\drs{box label}
{
drs box text
}
}

\end{document}


some margin around the drs generated box is colored as well.

What I basically need is to draw a colored box with some label. Then, by a foreach loop, to generate several colored boxes inside it. It is perfectly possible to have them in one column.

Following advice from egreg I wrote this:

\documentclass{article}

\newcommand{\zcolorbox}[2]{{\setlength{\fboxsep}{0pt}\colorbox{#1}{#2}}}
\newcommand{\nestedbox}[3]{\zcolorbox{#1}{\drs{#2}{#3}}}

\usepackage{drs}
\usepackage{xcolor}

\begin{document}

\nestedbox{green}{box label}{\nestedbox{yellow}{inner box label}{inner box text}}

\end{document}


and got this:

How can I get rid of the yellow color there, but not of the space?

-
Can you post a complete minimal document with the code you've tried? Where is the \drs command from, for example? –  Alan Munn Feb 18 '12 at 22:31
Done. Should I post the multipart document as well? It would be maybe better with drs, as the syntax is much cleaner for what I need. –  Dadam Feb 18 '12 at 22:42
The presence of a margin around a box probably means that the dimension \fboxsep is non-zero. –  Peter Flynn Feb 19 '12 at 0:27

I open a small discuss.

Here an approach using LaTeX3 in combination of some features defined in the kernel LaTeX2e.

The input of your colorbox is as follow:

\nestedbox[<options>]{<header>}{<inner box>}


where the inner box is a comma separated list.

The available options are:

• outer-color sets the background color of the whole box
• inner-color sets the background of the inner box
• bgcolor sets inner-color and outer-color
• line-color sets the color of the frame
• margin adds extra space to the widest word
• alignment choose the alignment of the boxes. Available are left, right and center
• header-font sets the font of the header
• label-font sets the font of the inner boxes

Here the complete code.

\documentclass{article}
\usepackage{expl3,xparse}
\usepackage{xcolor}
\ExplSyntaxOn
\keys_define:nn { colorbox }
{
outer-color  .tl_set:N   = \l_colorbox_outercolor_tl,
inner-color  .tl_set:N   = \l_colorbox_innercolor_tl,
line-color    .tl_set:N   = \l_colorbox_linecolor_tl,
bgcolor       .meta:n    = { outer-color = #1 , inner-color = #1 },
margin       .dim_set:N = \l_colorbox_margin_dim,
}
\keys_set:nn { colorbox } { bgcolor = white , line-color = black , margin = 20pt }

\tl_new:N  \l_colorbox_left_align_tl
\tl_new:N  \l_colorbox_right_align_tl
\keys_define:nn { colorbox }
{
alignment .choice:,
alignment / left   .code:n = {
\tl_set:Nn  \l_colorbox_left_align_tl {\null}
\tl_set:Nn  \l_colorbox_right_align_tl {\hfill}
},
alignment / right .code:n = {
\tl_set:Nn  \l_colorbox_left_align_tl {\hfill}
\tl_set:Nn  \l_colorbox_right_align_tl {\null}
},
alignment / center .code:n = {
\tl_set:Nn  \l_colorbox_left_align_tl {\hfill}
\tl_set:Nn  \l_colorbox_right_align_tl {\hfill}
},
}
\keys_set:nn { colorbox } { alignment = center }

\keys_define:nn { colorbox }
{
label-font    .tl_set:N   = \l_colorbox_labelfont_tl,
}
\keys_set:nn { colorbox } { header-font = \bfseries , label-font=\normalfont }
%#1 = options
%#2 = top label
%#3 = inner boxes clist
\clist_new:N \l_colorbox_innerbox_clist
\tl_new:N     \l_colorbox_boxlabel_tl
\dim_new:N \l_colorbox_widthest_label_dim
\NewDocumentCommand \nestedbox { O{} m m }
{
\keys_set:nn { colorbox } {#1}
\tl_set:Nn      \l_colorbox_boxlabel_tl     { #2 }
\clist_set:Nn  \l_colorbox_innerbox_clist { #3 }
\clist_if_empty:NTF \l_colorbox_innerbox_clist
{
\fcolorbox { \l_colorbox_linecolor_tl   }
{ \l_colorbox_outercolor_tl }
{ \tl_use:N  \l_colorbox_boxlabel_tl }
}
{
\colorbox_find_widthest_label:NN \l_colorbox_boxlabel_tl \l_colorbox_innerbox_clist
\colorbox_output_inner_label:NN  \l_colorbox_boxlabel_tl \l_colorbox_innerbox_clist
}
}

\cs_new:Npn \colorbox_find_widthest_label:NN #1#2
{
\hbox_set:Nn \l_tmpa_box { \tl_use:N #1}
\dim_set:Nn   \l_colorbox_widthest_label_dim { \box_wd:N \l_tmpa_box }
\clist_map_inline:Nn #2
{
\hbox_set:Nn \l_tmpa_box { ##1 }
\dim_compare:nNnT
{ \box_wd:N \l_tmpa_box } > { \l_colorbox_widthest_label_dim }
{  \dim_set:Nn   \l_colorbox_widthest_label_dim { \box_wd:N \l_tmpa_box } }
}
%    \dim_use:N \l_colorbox_widthest_label_dim
}

\cs_new:Npn \colorbox_output_inner_label:NN #1#2
{
\fcolorbox { \l_colorbox_linecolor_tl   }
{ \l_colorbox_outercolor_tl }
{
\begin{minipage}
{\dim_eval:w      \l_colorbox_widthest_label_dim
+  \l_colorbox_margin_dim
+  2\fboxsep +2\fboxrule
\dim_eval_end: }
\centering %\offinterlineskip
\hbox_to_wd:nn
{\l_colorbox_widthest_label_dim +  \l_colorbox_margin_dim }
{
\l_colorbox_left_align_tl
\strut \tl_use:N  #1
\l_colorbox_right_align_tl
}
\tex_vrule:D width \linewidth height 0pt \scan_stop:
\clist_map_inline:Nn #2
{ \\\nointerlineskip
\fcolorbox
{ \l_colorbox_innercolor_tl }
{ \l_colorbox_innercolor_tl }
{ \hbox_to_wd:nn
{\l_colorbox_widthest_label_dim +  \l_colorbox_margin_dim }
{
\l_colorbox_left_align_tl
\l_colorbox_labelfont_tl
\strut ##1
\l_colorbox_right_align_tl
}
}
}
\end{minipage}
}
}

\ExplSyntaxOff
\begin{document}

\nestedbox{box label}{inner,foo, long long long text}

\nestedbox[inner-color=yellow,outer-color=green]{box label}{inner,foo, long long long text}

\nestedbox[inner-color=red!20,alignment=left,label-font=\itshape]{box label}{inner,foo, long long long text}
\end{document}


In the final pdf I have no lines between the inner boxes.

-
You, sir, are my hero. Can you please change the default bgcolor to white, remove the lines around inner boxes and add the option for alignment? –  Dadam Feb 19 '12 at 16:12
I see the bgcolor is white, my mistake –  Dadam Feb 19 '12 at 16:26
@Dadam: Please see my edit. –  Marco Daniel Feb 19 '12 at 16:48
Thanks. It works perfectly now. –  Dadam Feb 19 '12 at 17:45

Your code produces the expected result. You have to recall that TeX is a typesetting engine, so spaces are in general not ignored as is the case for most programming languages. End-of-line characters are equivalent to spaces (unless there are two in a row, generating an end-of-paragraph command).

End-of-lines can be masked by % characters, so a first adjustment for you code is

\colorbox{green}
{%
\drs{box label}
{%
drs box text%
}%
}


(Note that spaces at the beginning of a line are ignored, to allow code indentation.) A better way to write this code might be

\colorbox{green}{%
\drs{box label}
{drs box text}%
}


This doesn't cope with another small problem: \colorbox surrounds the box contents with some padding (which in general is what's desired). The padding is \fboxsep wide on all four margins. Thus one can do

{\setlength{\fboxsep}{0pt}\colorbox{green}{%
\drs{box label}
{drs box text}%
}}


and the extra braces will ensure that the setting of \fboxsep will not propagate and be confined in the group.

One can take advantage of TeX and define a command for this:

\newcommand{\zcolorbox}[2]{{\setlength{\fboxsep}{0pt}\colorbox{#1}{#2}}}


and use

\zcolorbox{green}{%
\drs{box label}
{drs box text}%
}


which finally gives the desired result.

For what concerns nesting of colored \drs boxes, the problem lies in the implementation of drs, that keeps into account the nesting level, in order to add a suitable padding above and below the inner box: this is the cause of the yellow stripes you're experimenting.

A hack is to define the inner box beforehand:

\usepackage{drs}
\usepackage{xcolor,array}
\newcommand{\zcolorbox}[2]{{\setlength{\fboxsep}{0pt}\colorbox{#1}{#2}}}
\newcommand{\nestedbox}[3]{\zcolorbox{#1}{\drs{#2}{#3}}}

\newsavebox{\drsboxA}
\newcommand{\innerdrs}[3]{%
\sbox{\drsboxA}{\zcolorbox{#1}{\drs{#2}{#3}}}%
\ht\drsboxA=\dimexpr\ht\drsboxA+2pt\relax
\dp\drsboxA=\dimexpr\dp\drsboxA+2pt\relax}

\begin{document}

\innerdrs{yellow}{inner box label}{inner box text}
\nestedbox{green}{box label}{\usebox\drsboxA}

\end{document}
`

-
It is not working correctly for the nested box, I edited my question. –  Dadam Feb 19 '12 at 10:29