If you want to use the same title and alignment for each speaker, it might be a better idea to store that information inside a key you can use as the first mandatory argument to \bubble
. I added an optional argument to \bubble
with which individual customizations can be made.
The following does so using expkv-def
for a key=value interface (of course other packages could be used for this as well).
The box
key can be used to forward additional keys to the tcolorbox
environment (in the example I use this to specify colours for each speaker).
The align
key might take the value center
in which case a center
environment is used, else the used environment will be flush<align>
, so right
and left
are possible values.
\documentclass[]{article}
\usepackage{tcolorbox}
\usepackage{expkv-def}
\makeatletter
% we define new keys here. The `store' type of keys will store the value during
% its usage inside the macros. The `code' type allows own definitions. We use it
% to define a key that will add additional contents to an existing macro
% (\bubble@box) with a comma between the old and new material.
% With `initial' we set initial values for the keys `width` and `align`, all
% other macros are initially empty (title and box).
% The `BOX' key will overwrite any other option passed to `tcolorbox', whereas
% the `box' key will add to the list of options.
\ekvdefinekeys{bubbles}
{
store title = \bubble@title
,store align = \bubble@align
,store BOX = \bubble@box
,code box = \edef\bubble@box{\unexpanded\expandafter{\bubble@box,#1}}
,store width = \bubble@wd
,initial width = .5\textwidth
,initial align = left
}
% we define a shorthand macro to set options of bubbles.
\ekvsetdef\bubbleoptions{bubbles}
% the real macro
\newcommand\bubble[3][]
{%
% contain the definitions done by the key=value interface inside a group so
% that one call can't affect another one.
\begingroup
% test if the macro holding defaults exists, if so call it
\ifcsname bubble@defaults@\detokenize{#2}\endcsname
\csname bubble@defaults@\detokenize{#2}\endcsname
\fi
% parse the additional options with our key=value interface
\bubbleoptions{#1}%
% handle the `center' alignment by comparing the current alignment with a
% temporary macro
\def\bubble@tmp{center}%
\begin{\ifx\bubble@tmp\bubble@align\else flush\fi\bubble@align}
% expand the contents of `\bubble@box' so that the key=value interface
% of tcolorbox can do its job
\expandafter\bubble@startbox\expandafter{\bubble@box}%
#3%
\end{tcolorbox}%
\end{\ifx\bubble@tmp\bubble@align\else flush\fi\bubble@align}
\endgroup
}
% helper macro to expand the contents of `\bubble@box' before calling
% `tcolorbox'.
\newcommand\bubble@startbox[1]
{%
% check if the title is empty, if so, don't use the title key of tcolorbox.
\ifx\bubble@title\@empty
\begin{tcolorbox}[width=\bubble@wd, #1]
\else
\begin{tcolorbox}[width=\bubble@wd, title=\bubble@title, #1]
\fi
}
% define a default option list. The optional argument is used as is for the
% `tcolorbox' options, the rest is parsed by our key=value interface. Since we
% use it inside of `\edef' the values passed to the keys here are fully
% expanded. This shouldn't be an issue normally.
\newcommand\bubbledef[3][]
{%
\expandafter\edef\csname bubble@defaults@\detokenize{#2}\endcsname
{\unexpanded{\def\bubble@box{#1}}\bubbleoptions{#3}}%
}
\makeatother
% define the two speakers (with short name A and B)
\bubbledef[colframe=red!50!black]{A}{title=Speaker A, align=left}
\bubbledef[colframe=green!50!black]{B}{title=Speaker B, align=right}
\usepackage{duckuments} % just for some dummy text
\begin{document}
\bubble{A}{\blindduck[-]}
\bubble{B}{\blindduck[-]}
\bubble[title=New Speaker]{}{A new speaker shows up.}
\bubble[align=center, width=.7\textwidth]{}{Another fat speaker is here.}
\end{document}
Changes:
2021-02-23, 18:38 (UTC+1)
- added a lot of comments
- added an optional argument to
\bubbledef
to set the default tcolorbox
options in an, imho, nicer way.
- changed the
box
key to add additional options instead of clearing the list
- added the
BOX
key (does what the box
key did previously)
\newcommand
you have to give the name of the macro with a leading backslash, so it should be\newcommand\bubbles...
. Whereas in\begin
you should not use a leading backslash, so correct would be\begin{flushright}
or\begin{flushleft}
, same for\end
. Is the title in#2
to be always the same for the same alignment? How do you intend to use\bubbles
? Can you show a (non-)working minimal example how you intend to use it?