# PGF keys passing arguments to multiple environments

I'd like to combine both tcolorbox and textpos to place boxes to a specific position in a page.

Here is a MWE:

\documentclass[]{article}

\usepackage{pgfkeys}
\usepackage{tcolorbox}
\usepackage[absolute,overlay]{textpos}

\makeatletter

%% #1: options
%% #2: textblock width
%% #3: textblock position
\newenvironment{tcolorboxat}[3][]{%
\pgfkeys{/tcbat/.is family,
/tcbat/.cd,
ho/.initial = 0,
vo/.initial = 0,
#1,
}%
\begin{textblock*}{#2}[\pgfkeysvalueof{/tcbat/ho},\pgfkeysvalueof{/tcbat/vo}](#3)%
\begin{tcolorbox}[]%
}{\end{tcolorbox}\end{textblock*}}%

\makeatother

\begin{document}
\begin{tcolorboxat}[ho=0.5]{5cm}{3cm,8cm}
This is a tcolorbox placed at 3cm, 8cm from top left corner of the page. Origin point is 1.5cm, 8cm.
\end{tcolorboxat}
\end{document}


This works as expected. Now I would like to add a tcb opts style like option to pass to the tcolorbox environment:

\newenvironment{tcolorboxat}[3][]{%
\pgfkeys{/tcbat/.is family,
/tcbat/.cd,
ho/.initial = 0,
vo/.initial = 0,
tcb opts/.style = { title = box title },
#1,
}%
\begin{textblock*}{#2}[\pgfkeysvalueof{/tcbat/ho},\pgfkeysvalueof{/tcbat/vo}](#3)%
\begin{tcolorbox}[code=\pgfkeysvalueof{/tcbat/tcb opts}]%
}{\end{tcolorbox}\end{textblock*}}%


unfortunately this does not works, the title option does not seem to be passed to tcolorbox.

Is there a way to put all tcolorbox options into a style like key similar to something like that?

\begin{tcolorboxat}[ho=0.4,
tcb opts = {
title = box title,
colback = red,
}]{5cm}{3cm,8cm}
...
\end{tcolorboxat}


• Just a typo : tcp opts is not tcb opts... Then, replace code=\pgfkeysvalueof{/tcbat/tcp opts} by /tcbat/tcb opts. – Paul Gaborit Sep 16 '15 at 6:25
• – Ignasi Sep 16 '15 at 8:29

You can try something like this:

\documentclass[]{article}

\usepackage{pgfkeys}
\usepackage{tcolorbox}
\tcbuselibrary{breakable}
\tcbuselibrary{skins}
\usepackage[absolute,overlay]{textpos}

\makeatletter

\pgfkeys{/tcbat/.is family,
/tcbat/.cd,
ho/.store in = \mytcbat@ho,
vo/.store in = \mytcbat@vo,
tcb opts/.code = {\tcbset{mytcboptions/.style={#1}}},
}%
%

%% #1: options
%% #2: textblock width
%% #3: textblock position
\newenvironment{tcolorboxat}[3][]{%
\tcbset{mytcboptions/.style={}}%  %% Reinitialize new style
%
\pgfkeys{/tcbat, ho=0, vo=0, #1}%  %% Set defaults, whatever you may want them to be...
%
\begin{textblock*}{#2}[\mytcbat@ho, \mytcbat@vo](#3)%
\begin{tcolorbox}[mytcboptions]%
}{\end{tcolorbox}\end{textblock*}}%

\makeatother

\begin{document}
\begin{tcolorboxat}[ho=0.5, tcb opts={unbreakable, enhanced, title={Testing 123}}]{5cm}{3cm,8cm}
This is a tcolorbox placed at 3cm, 8cm from top left corner of the page. Origin point is 1.5cm, 8cm.
\end{tcolorboxat}

\tcbset{%
%% Define a new skin for tcolorbox called title3d
title3d/.style = {%
skin=enhancedlast jigsaw,
tikznode boxed title={inner sep=1mm, align=left},
attach boxed title to top left={xshift=-4mm,yshift=-0.5mm},
fonttitle=\bfseries\sffamily,
colbacktitle=blue!45!white,
colframe=red!50!black,
interior style={top color=blue!10!white,bottom color=red!10!white},
boxed title style={empty,arc=0pt,outer arc=0pt,boxrule=0pt},
underlay boxed title={
\fill[blue!45!white] (title.north west) -- (title.north east)
-- +(\tcboxedtitleheight-1mm,-\tcboxedtitleheight+1mm)
-- ([xshift=4mm,yshift=0.5mm]frame.north east) -- +(0mm,-1mm)
-- (title.south west) -- cycle;
\fill[blue!45!white!50!black] ([yshift=-0.5mm]frame.north west)
-- +(-0.4,0) -- +(0,-0.3) -- cycle;
\fill[blue!45!white!50!black] ([yshift=-0.5mm]frame.north east)
-- +(0,-0.3) -- +(0.4,0) -- cycle; },
},
}

\begin{tcolorboxat}[ho=0.5, tcb opts={unbreakable, enhanced, title3d, title={So pretty}}]{7cm}{6cm,14cm}
This is a tcolorbox placed at 6cm, 14cm from top left corner of the page.
\end{tcolorboxat}
\end{document}


Output:

@feculededentier this solution does the job. Thanks.

Meanwhile I am still wondering what is the best practice to declare PFG keys style options since this code also works:

\newenvironment{tcolorboxat}[3][]{%
\pgfkeys{/tcb/tcbat/.style = {},
/tcbat/.is family,
/tcbat/.cd,
ho/.initial = 0,
vo/.initial = 0,
tcb opts/.code = {\tcbset{tcbat/.style={##1}}},
#1,
ho/.get = \tcbat@ho,
vo/.get = \tcbat@vo,
}
\begin{textblock*}{#2} [\tcbat@ho, \tcbat@vo](#3)
\begin{tcolorbox}[tcbat]%
}{\end{tcolorbox}\end{textblock*}}%


The advantage is that all declarations are in one scope. But many people seem to declare the PGF keys outside of the environment declaration.

• Good question: I can't give a complete answer to it. I don't know if the scoping could cause an issue if you tried to embed a tcolorboxat within another tcolorboxat (this doesn't make any sense in your context anyway). The main reason why I declare my PGF keys outside of my environments is because I often use the same pgfkeys for many different environments and also because I provide macros to globally reset a default value. – feculededentier Sep 16 '15 at 13:42
• Ok. Since this is for a pet project I guess having it locally defined good enough. Thanks again. – renard Sep 16 '15 at 14:15