2

Problem description

I am trying to create an environment that produces boxed paragraphs with different styles.

So I tried to implement some "if"-"elif"-"else" blocks, that will compare the arguments passed to the environment to some given keywords to decide which style will be applied to a paragraph.

Unfortunately, implementing such an idea was far from being as simple as it sounds, since all the methods I tried (here), in order to compare an argument with a string did not give correct results.

MWE

Here is what I have tried (I got my inspiration from here):

\documentclass{article}
\usepackage{xcolor}
\usepackage[most]{tcolorbox}
\usepackage{ifthen}
%#################################
\newtcolorbox{mybox}[2][]{colback=black!5!white,colframe=black!45!white,fonttitle=\bfseries,enhanced,breakable,attach boxed title to top left={yshift*=-\tcboxedtitleheight/2},title={#2}}
%#################################
\makeatletter
\newcommand*\BEGININGcommands{}
\newcommand*\ENDINGcommands{}

\newenvironment{myENV}[1][] {% \ifthenelse{\equal{#1}{keyword}} { % if '#1' == 'keyword' then apply the 'mybox' style to the selected paragraph \textcolor{green!35!white}{ \textbf{Seeing this means that:} \fbox{#1} and \fbox{keyword} represent the same string, which means that the content will be formatted by surrounding it with \textbf{mybox}.}\par\vspace{1em} \def\BEGININGcommands{\begin{mybox}[#1]} \def\ENDINGcommands{\end{mybox}} } { % else dont apply anything \textcolor{red!35!white}{\textbf{Seeing this means that:} \fbox{#1} is not the same as \fbox{keyword}, which means that no formating will be applied.}\par\vspace{1em} \def\BEGININGcommands{} \def\ENDINGcommands{} } \BEGININGcommands } {% \ENDINGcommands% } \makeatother %################################# \begin{document} \begin{myENV}{keywordA} This paragraph \textbf{should be formatted} as the \textbf{keywordA} is \textbf{specified}. \end{myENV} \par\vspace{2em}\noindent\rule{\textwidth}{1pt}\vspace{2em} \begin{myENV}{keywordB} This paragraph \textbf{should not be formatted} as the \textbf{keywordA} is \textbf{not specified}. \end{myENV} \end{document}

Output

enter image description here

Desired output

enter image description here

  • \newenvironment{myENV}[1][] defined myENV with an optional argument so \begin{myENV}[keyword]not\begin{myENV}{keyword}` – David Carlisle Nov 10 '22 at 00:55
  • \def\BEGININGcommands{\begin{myENV}[#1]} is programming an infinite loop if #1 is keyword – David Carlisle Nov 10 '22 at 00:58
  • 1
    What is the main aim here? Have an environment myENV format its contents depending on what you supply as the first argument? That doesn't seem to be the case in the example code, since the argument (keyword) is not used really. – Werner Nov 10 '22 at 01:22
  • @Werner yeah that's exactly what I'm aiming for, (i.e. create an environment that formats its content according to the argument supplied to it) I modified the code to make the idea clearer. – Mycroft_47 Nov 10 '22 at 13:14
  • @DavidCarlisle you are right, \def\BEGININGcommands{\begin{myENV}[#1]} will produce an infinite loop of tests, I rather intended to write \def\BEGININGcommands{\begin{mybox}[#1]} – Mycroft_47 Nov 10 '22 at 13:23
  • do you want the argument to be optional? if so use [keyword] if not remove the [] from the definition – David Carlisle Nov 10 '22 at 13:27
  • @DavidCarlisle Yes I want it to be optional, as it will be used as 'a title' within the tcolorbox that I called mybox – Mycroft_47 Nov 10 '22 at 13:33
  • ok so just change { to [ when you use the environment – David Carlisle Nov 10 '22 at 13:37

2 Answers2

2

You're using the wrong type and number of arguments.

For more than one choice, \ifthenelse becomes very cumbersome. I propose an expl3 solution with which it's easy to accommodate any number of choices for the keywords.


\documentclass{article}
\usepackage{xcolor}
\usepackage[most]{tcolorbox}

\newtcolorbox{myboxA}[1]{ colback=black!5!white, colframe=black!45!white, fonttitle=\bfseries, enhanced, breakable, attach boxed title to top left={yshift=-\tcboxedtitleheight/2}, title={#1} } \newtcolorbox{myboxB}[1]{ colback=red!5!white, colframe=red!45!white, fonttitle=\bfseries, enhanced, breakable, attach boxed title to top left={yshift=-\tcboxedtitleheight/2}, title={#1} }

\ExplSyntaxOn

\NewDocumentEnvironment{myENV}{O{}} { \str_case:nn { #1 } { {keywordA}{\begin{myboxA}{#1}} {keywordB}{\begin{myboxB}{#1}} } } { \str_case:nn { #1 } { {keywordA}{\end{myboxA}} {keywordB}{\end{myboxB}} } }

\ExplSyntaxOff

\begin{document}

\begin{myENV}[keywordA] This paragraph \textbf{should be formatted} as the \textbf{keywordA} is \textbf{specified}. \end{myENV}

\begin{myENV}[keywordB] This paragraph \textbf{should be formatted} as the \textbf{keywordB} is \textbf{specified}. \end{myENV}

\begin{myENV}[foo] No formatting here. \end{myENV}

\end{document}

enter image description here

egreg
  • 1,121,712
1

Instead of creating separate tcolorbox environments for each possibility, create a style. Each style holds the key-value options associated with the formatting, that you can then pass via environment options.

enter image description here

\documentclass{article}

\usepackage{xcolor} \usepackage[most]{tcolorbox}

\tcbset{ % Define base style common to all boxes base/.style = { fonttitle = \bfseries, enhanced, breakable, attach boxed title to top left={yshift*=-\tcboxedtitleheight/2} }, % Define keywordA-specific box style additions/overrides keywordA/.style = { colback = black!5!white, colframe = black!45!white, }, % Define keywordB-specific box style additions/overrides keywordB/.style = { colback = red!5!white, colframe = red!45!white } }

\NewDocumentEnvironment{myENV}{ O{} m }{% \begin{tcolorbox}[ base, % load base style #1, % load additional style based on optional argument title = {#2} % Title in second (mandatory) argument ] }{% \end{tcolorbox} }

\begin{document}

\begin{myENV}[keywordA]{Something A} This paragraph \textbf{should be formatted} as the \textbf{keywordA} is \textbf{specified}. \end{myENV}

\begin{myENV}[keywordB]{Something B} This paragraph \textbf{should be formatted} as the \textbf{keywordB} is \textbf{specified}. \end{myENV}

\end{document}

Werner
  • 603,163