[Tex/LaTex] Nested labeled colored boxes with TikZ

colorlabelsnestingtikz-pgf

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:

colored nested drs boxes with fboxsep set to 0

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

Best Answer

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 }
  {
    header-font .tl_set:N   = \l_colorbox_headerfont_tl,
    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
                              \l_colorbox_headerfont_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.