1

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}

Thanks in advance.

1

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:

Output associated to code above

0

@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.

  • 1
    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
  • 1
    For example, I might declare \newcommand{\tcbat@ho@default}{0} outside the pgfkeys (and environment) and also create \newcommand{\setdefaultho}[1]{\renewcommand{\tcbat@ho@default}{#1}}. This value could then be used inside the tcolorboxat definition I have provided by using \pgfkeys{/tcbat, ho=\tcbat@ho@default, vo=0, #1}. The ho/.initial = 0 key therefore becomes useless (not needed), but you have to add a ho/.code to compensate... – feculededentier Sep 16 '15 at 13:44
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.