# Resize tikzfigure in tcolorbox depending on height of tcolorbox

in my book I got many different type of boxes so I made some macros placing the boxes automatically according to their arguments.

That's one of them. So far I made some boxes that have big "+" and "-" inside and some that have small ones. It'd be nice, if I could manage to adapt the size of the signs according to the height of the box.

\documentclass{book}

\usepackage{xstring}
\usepackage[many]{tcolorbox}
\usepackage{calc}
\usetikzlibrary{calc}

\definecolor{mp}{RGB}{240,240,240}

\newcommand{\bround}{
\draw[rounded corners=15pt,color=mp,line width=1pt,fill=white]
(frame.south west) --
(frame.north west) --
(frame.north east) --
(frame.south east) -- cycle;
}
\newcommand{\sep}{
\draw[color=mp,line width=1pt]
([yshift=10pt]segmentation.south) -- ([yshift=-10pt]segmentation.north);
}

\newcommand{\ds}[1]{
\IfEqCase{#1}{%
{bpl}{\dosign{0.25}{x}{y}{0}{0}{20}{-50}{50}{-60}}%
{bmr}{\dosign{0.75}{x}{x}{0}{0}{20}{-50}{50}{-60}}%
}[\PackageError{ds}{Undefined option to ds: #1}{}]%
}

\newcommand{\dosign}[9]{
\coordinate (xl) at ($(frame.west)!#1!(frame.east)$ );
\coordinate (yl) at ([yshift=#9pt] $(frame.north)$ );
\draw[line width=#6pt,mp]
([#2shift=#7pt,yshift=#4pt]xl|-yl) -- ([#2shift=#8pt,yshift=#4pt]xl|-yl);
\draw[line width=#6pt,mp]
([#3shift=#7pt,yshift=#5pt]xl|-yl) -- ([#3shift=#8pt,yshift=#5pt]xl|-yl);
}

\newcommand{\doibs}[4]{\scantokens{%
\begin{tcolorbox}[
colback=white,
arc=10pt,
colframe=black,
freelance,
sidebyside,
sidebyside align=top,
frame code=\bround,
segmentation code=\sep,
interior code=\ds{#3}\ds{#4}
]
\raggedright #1 \tcblower \raggedright #2
\end{tcolorbox}}}

\begin{document}

\doibs{A\\A\\A\\A}{B}{bpl}{bmr}

\end{document}


As I have every type of combination (+-,++,--,+=,==,..), I wrote those macros keeping the source code as minimal as possible (according to my skills). If I had the possibility to get the height in macro \ds, I could ajust the signs by recalculating their dimensions, coordinates, etc.

Does anyone have a clue?

• Do you want just the height/widht of the symbols to adapt or also the line width used for the symbols? – Gonzalo Medina Apr 14 '14 at 14:39
• they should be stretched proportional, therefore the line width as well – Moldevort Apr 14 '14 at 14:58
• I thought so. The second solution in my answer below also adjusts the line width. – Gonzalo Medina Apr 14 '14 at 14:59

## Updated version:

The first version of the code (see below) had one problem: if the box height was too big, then the signs will protrude their corresponding boxes; this can be solved choosing a maximum value for the length of the signs. The following code shows one such possibility; the length is (approximately) the minimum between the height of the box and half its width:

\documentclass{book}
\usepackage[paperheight=30cm,textheight=25cm]{geometry}% just for the example
\usepackage{xstring}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc}

\definecolor{mp}{RGB}{240,240,240}

% To control the line width for the signs
\def\RuleFactor{0.15}

\newcommand{\bround}{
\draw[rounded corners=15pt,color=mp,line width=1pt,fill=white]
(frame.south west) --
(frame.north west) --
(frame.north east) --
(frame.south east) -- cycle;
}
\newcommand{\sep}{
\draw[color=mp,line width=1pt]
([yshift=10pt]segmentation.south) -- ([yshift=-10pt]segmentation.north);
}

\newcommand{\ds}[1]{
\IfEqCase{#1}{%
{pp}{\dosign{0.25}{plus}\dosign{0.75}{plus}}%
{pm}{\dosign{0.25}{plus}\dosign{0.75}{minus}}%
{pe}{\dosign{0.25}{plus}\dosign{0.75}{equal}}%
{mp}{\dosign{0.25}{minus}\dosign{0.75}{plus}}%
{mm}{\dosign{0.25}{minus}\dosign{0.75}{minus}}%
{me}{\dosign{0.25}{minus}\dosign{0.75}{equal}}%
{ep}{\dosign{0.25}{equal}\dosign{0.75}{plus}}%
{em}{\dosign{0.25}{equal}\dosign{0.75}{minus}}%
{ee}{\dosign{0.25}{equal}\dosign{0.75}{equal}}%
}[\PackageError{ds}{Undefined option to ds: #1}{}]%
}

\newcommand{\dosign}[2]{
\coordinate (xl) at ($(frame.west)!#1!(frame.east)$ );
\IfEq{#2}{plus}{%
\path[mp,draw]
let \p1 = ( $([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south)$ ),
\p2 = ( $([xshift=10pt]frame.west) - ([xshift=-10pt]segmentation.center)$ )
in
([yshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([yshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
([xshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([xshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
;
}{}
\IfEq{#2}{minus}{%
\path[line width=6pt,mp,draw]
let \p1 = ( $([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south)$ ),
\p2 = ( $([xshift=10pt]frame.west) - ([xshift=-10pt]segmentation.center)$ )
in
([xshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([xshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
;
}{}
\IfEq{#2}{equal}{%
\path[line width=6pt,mp,draw]
let \p1 = ( $([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south)$ ),
\p2 = ( $([xshift=10pt]frame.west) - ([xshift=-10pt]segmentation.center)$ )
in
([xshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))},yshift={0.12*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([xshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))},yshift={0.12*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
([xshift=-{0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))},yshift=-{0.12*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
edge[line width={\RuleFactor*min(veclen(\x1,\y1),veclen(\x2,\y2))}]
([xshift={0.5*min(veclen(\x1,\y1),veclen(\x2,\y2))},yshift=-{0.12*min(veclen(\x1,\y1),veclen(\x2,\y2))}]xl)
;
}{}
}

\newcommand{\doibs}[3]{\scantokens{%
\begin{tcolorbox}[
colback=white,
arc=10pt,
colframe=black,
freelance,
sidebyside,
sidebyside align=top,
frame code=\bround,
segmentation code=\sep,
interior code=\ds{#3}
]
\raggedright #1 \tcblower \raggedright #2
\end{tcolorbox}}}

\begin{document}

\doibs{A\\A\\A\\A}{B}{pm}

\doibs{A\\A\\A\\A}{B}{me}

\doibs{A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A}{B}{pe}

\doibs{A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A\\A}{B}{ep}

\end{document}


## First version:

Here's one possibility (see remarks below):

\documentclass{book}
\usepackage{xstring}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc}

\definecolor{mp}{RGB}{240,240,240}

\newcommand{\bround}{
\draw[rounded corners=15pt,color=mp,line width=1pt,fill=white]
(frame.south west) --
(frame.north west) --
(frame.north east) --
(frame.south east) -- cycle;
}
\newcommand{\sep}{
\draw[color=mp,line width=1pt]
([yshift=10pt]segmentation.south) -- ([yshift=-10pt]segmentation.north);
}

\newcommand{\ds}[1]{
\IfEqCase{#1}{%
{pp}{\dosign{0.25}{plus}\dosign{0.75}{plus}}%
{pm}{\dosign{0.25}{plus}\dosign{0.75}{minus}}%
{pe}{\dosign{0.25}{plus}\dosign{0.75}{equal}}%
{mp}{\dosign{0.25}{minus}\dosign{0.75}{plus}}%
{mm}{\dosign{0.25}{minus}\dosign{0.75}{minus}}%
{me}{\dosign{0.25}{minus}\dosign{0.75}{equal}}%
{ep}{\dosign{0.25}{equal}\dosign{0.75}{plus}}%
{em}{\dosign{0.25}{equal}\dosign{0.75}{minus}}%
{ee}{\dosign{0.25}{equal}\dosign{0.75}{equal}}%
}[\PackageError{ds}{Undefined option to ds: #1}{}]%
}

\newcommand{\dosign}[2]{aaa
\coordinate (xl) at ($(frame.west)!#1!(frame.east)$ );
\IfEq{#2}{plus}{%
\path[mp,draw]
let \p1 = ( $([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south)$ )
in
([yshift=-5pt]xl|-frame.north)
edge[line width={0.12*veclen(\x1,\y1)}]
([yshift=5pt]xl|-frame.south)
([xshift=-{0.5*veclen(\x1,\y1)}]xl)
edge[line width={0.12*veclen(\x1,\y1)}]
([xshift={0.5*veclen(\x1,\y1)}]xl)
;
}{}
\IfEq{#2}{minus}{%
\path[line width=6pt,mp,draw]
let \p1 = ( $([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south)$ )
in
([xshift=-{0.5*veclen(\x1,\y1)}]xl)
edge[line width={0.12*veclen(\x1,\y1)}]
([xshift={0.5*veclen(\x1,\y1)}]xl)
;
}{}
\IfEq{#2}{equal}{%
\path[line width=6pt,mp,draw]
let \p1 = ( $([yshift=-5pt]xl|-frame.north) - ([yshift=5pt]xl|-frame.south)$ )
in
([xshift=-{0.5*veclen(\x1,\y1)},yshift={0.1*veclen(\x1,\y1)}]xl)
edge[line width={0.12*veclen(\x1,\y1)}]
([xshift={0.5*veclen(\x1,\y1)},yshift={0.1*veclen(\x1,\y1)}]xl)
([xshift=-{0.5*veclen(\x1,\y1)},yshift=-{0.1*veclen(\x1,\y1)}]xl)
edge[line width={0.12*veclen(\x1,\y1)}]
([xshift={0.5*veclen(\x1,\y1)},yshift=-{0.1*veclen(\x1,\y1)}]xl)
;
}{}
}

\newcommand{\doibs}[3]{\scantokens{%
\begin{tcolorbox}[
colback=white,
arc=10pt,
colframe=black,
freelance,
sidebyside,
sidebyside align=top,
frame code=\bround,
segmentation code=\sep,
interior code=\ds{#3}
]
\raggedright #1 \tcblower \raggedright #2
\end{tcolorbox}}}

\begin{document}

\doibs{A\\A\\A\\A}{B}{pp}

\doibs{A}{B}{me}

\doibs{A\\A\\A\\A\\A\\A\\A\\A}{B}{pe}

\doibs{A\\A\\A}{B}{ep}

\doibs{A\\A}{B}{ee}

\end{document}


## Remarks

1. The size of the shapes and the line width will adjust automatically depending on the height of the box.

2. Notice that now \dosign has just two mandatory arguments (instead of the original nine arguments) and that \doibs has only three arguments.

3. The third argument for \doibs is used to decide which symbols to draw; I implemented nine combinations for "plus" (p), "minus" (m) and "equal" (e). For example using me in the third argument means draw "minus" sign to the left and "equal" sign to the right; using pm in the third argument means draw "plus" sign to the left and "minus" sign to the right.

• Unfortunately that's not what I wanted to achieve. When I follow your source code I will have to build a macro for every box (+-,--,++,-+,=+,+=, etc) and that's what I wanted to prevent by creating \ds and \dosign. Isn't there any way to get the height out of the tcolorbox-environment? – Moldevort Apr 14 '14 at 15:06
• @Moldevort please see my updated answer. – Gonzalo Medina Apr 14 '14 at 16:33
• @Moldevort I've updated my answer with a new version that might be of interest for you. – Gonzalo Medina Apr 16 '14 at 2:45
• The freelance option is deprecated since version 3.00 of tcolorbox, as mentioned in the latest Package Documentation (version 3.05 2014-05-28). The key can simply be removed in @Gonzalo's elaborate answer. – feculededentier Jul 7 '14 at 4:01