1

I'm trying to put a option through another macro in a tcolorbox environment like this:

\documentclass{article} \usepackage[many]{tcolorbox} \usepackage{lipsum} \newcommand{\tcboption}{colback=blue} \newcommand{\bubble}[1]{% \begin{tcolorbox}[% \tcboption] #1 \end{tcolorbox} } \begin{document} \bubble{\lipsum[1][1-2]} \end{document} 

that doesn't work, it says: ! Package pgfkeys Error: I do not know the key '/tcb/colback=blue' and I am going to ignore it. Perhaps you misspelled it. This might be a common mistake but so far i've found no solution, even in #latex in freenode.

UPDATE here i upgrade my example to something closer to my real macro. Following is one of the solution provided by others put in practice into it.

\usepackage{xargs} %[ ... ] \newcommand{\myoption}[1][]{% \ifthenelse{\equal{#1}{line}}{% skin=enhanced, finish={\draw[blue, thin,-] (0,0) -- +(0,-10); }, }{} } \newcommandx{\bubblex}[4][1=20em, 2=, usedefault]{% \begin{tcolorbox}[ width=#1, \myoption{#2}, title=3,fonttitle=\bfseries] #4 \end{tcolorbox} } 

Solution:

\tcbset{ tcboption/.style={skin=enhanced, finish={\draw[blue, thin,-] (0,0) -- +(0,-10); }}, } \newcommandx{\bubblex}[4][1=20em, 2=, usedefault]{% \begin{tcolorbox}[ width=#1, #2, title=3,fonttitle=\bfseries] #4 \end{tcolorbox} } \begin{document} \bubble[][tcboption]{\lipsum[1][1-2]} \end{document} 

It works even when when i leave the the second optional arg. of \bubblex empty, which is what i wanted. I though the comma after #2 in the macro definition would cause an error.

3 Answers 3

2

You can't use macros expanding to options. But you can use styles:

\documentclass{article} \usepackage[many]{tcolorbox} \usepackage{lipsum} \tcbset{myoption/.style={colback=blue!20}} \newcommand{\bubble}[1]{% \begin{tcolorbox}[myoption] #1 \end{tcolorbox} } \begin{document} \bubble{\lipsum[1][1-2]} \end{document} 

enter image description here

A slightly different approach:

\documentclass{article} \usepackage[many]{tcolorbox} \usepackage{lipsum} \tcbset{ tcboption/.is choice, tcboption/line/.style={skin=enhanced, finish={\draw[blue, thin,-] (0,0) -- +(0,-10); }}, tcboption/back/.style={colback=blue!20}, } \newcommand{\bubble}[2][]{% \begin{tcolorbox}[#1] #2 \end{tcolorbox} } \begin{document} \bubble[tcboption=back]{\lipsum[1][1-2]} \bubble[tcboption=line]{\lipsum[1][1-2]} \end{document} 

You can also combine the two by using tcboption=line,tcboption=back.

5
  • yes it seems to work but in a very limited context. For example, if it is one option among many in \bubble[2] ...{tcolobox}[myoption, title=title] and that i want to put like this \ifthenelse{\equal{#1}{colourise}}{myoption, }{} title=... This does not work Commented Mar 7, 2021 at 17:12
  • @user1850133 Sorry, but I can only answer what's asked. Please, make a new question with as much details as needed to clearly understand your aim. And the problem is most likely solved with styles and not via macros. Commented Mar 7, 2021 at 17:15
  • my real macro (named tcboption instead of myoption for this exemple) was rather like this: \newcommand{\tcboption}[1][]{ \ifthenelse{\equal{#1}{line}}{skin=enhanced, finish={\draw[blue, thin,-] (0,0) -- +(0,-10); }, }{} } Note the comma at the end of the 'finish' definition. Commented Mar 7, 2021 at 17:18
  • @user1850133 A command with an optional argument would not even work with wipet's approach and would bomb out. Commented Mar 7, 2021 at 17:21
  • @user1850133 I added a different version that you can try. Commented Mar 7, 2021 at 17:31
2

You must expand the parameter before \begin{tcolorbox} is processed. I don't know how but it is fact.

\def\tcboption{colback=yellow} \def\bubble#1{% \edef\tmp{\noexpand\begin{tcolorbox}[\tcboption]}\tmp #1 \end{tcolorbox} } 
0

In order to see how \expandafter can be applied for obtaining \tcboption's toplevel-expansion you can do:

\documentclass{article} \usepackage[many]{tcolorbox} \usepackage{lipsum} \newcommand{\tcboption}{colback=blue} \newcommand{\bubble}[1]{% \expandafter\begin\expandafter{\expandafter t\expandafter c\expandafter o% \expandafter l\expandafter o\expandafter r\expandafter b\expandafter o% \expandafter x\expandafter}\expandafter[\expandafter{\tcboption}]% #1% \end{tcolorbox}% } \begin{document} \bubble{\lipsum[1][1-2]} \end{document} 

Shorter is:

\documentclass{article} \usepackage[many]{tcolorbox} \usepackage{lipsum} \newcommand\exchange[2]{#2#1} \newcommand{\tcboption}{colback=blue} \newcommand{\bubble}[1]{% \expandafter\exchange\expandafter{\expandafter[\expandafter{\tcboption}]}{\begin{tcolorbox}}% #1% \end{tcolorbox}% } \begin{document} \bubble{\lipsum[1][1-2]} \end{document} 

Both examples are for demonstration-purposes only and are focussed at obtaining only the toplevel-expansion of \tcboption.

wipet's approach leads to expanding everything that comes from \tcboption until remaining tokens are either unexpandable or were not expanded due to \unexpanded/\noexpand being provided or due to being defined in terms of \protected.

Except that with LaTeX I'd probably use \protected@edef instead of \edef I prefer wipet's approach to my two examples.

The "royal road" in this matter, namely the defining of styles, has been shown by egreg.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.