3

so I have this:

\newcommand{\boxx}[2]{
    \colorbox{white}{\begin{varwidth}{\textwidth}
        % Heading
        \colorbox{green!30}{#1}\\
        % Content
        \fcolorbox{green}{yellow}{\begin{varwidth}{\textwidth}
            #2
        \end{varwidth}}
    \end{varwidth}}
}

Using it looks like this:

\boxx{Heading}{Some \\ fancy \\ content}

I'd like to create a 3th and 4th argument for the border color of my fcolorboy and the backgroundcolor.

So that I can do e.g.:

\boxx{Heading}{Some \\ fancy \\ content}{green}
\boxx{Heading}{Some \\ fancy \\ content}{}{yellow}
\boxx{Heading}{Some \\ fancy \\ content}{blue}{red}

so basically:

 \newcommand{\boxx}[4]{
    % Do something to set #3, #4 a default value
    \colorbox{white}{\begin{varwidth}{\textwidth}
        % Heading
        \colorbox{green!30}{#1}\\
        % Content
        \fcolorbox{#3}{#4}{\begin{varwidth}{\textwidth}
            #2
        \end{varwidth}}
    \end{varwidth}}
}
  • 1
    It's straightforward to set up LaTeX macros with 1 optional argument. (In such macros, the optional argument must come at the beginning, not the end.) I don't think it's possible -- at least not via \newcommand -- to set up a 4-argument macro, of which 2 are optional. – Mico Mar 8 '18 at 11:57
  • Look at xparse, e.g. tex.stackexchange.com/a/29975 – Torbjørn T. Mar 8 '18 at 12:09
  • @xitx, It looks like you have 3 great answers and haven't selected one yet? – PatrickT Mar 10 '18 at 1:06
  • 1
    yeah I was very busy at work, so I had to take my time to look at them all. :) I'm always astouned about the responses on here. – xotix Mar 10 '18 at 13:03
4

Something like a solution using pgffor and some ifs:

\documentclass{article}
\usepackage{varwidth}
\usepackage{xcolor}
\usepackage{pgffor}
\newcommand{\boxx}[3][red,brown]{
  \global\expandafter\let\csname mycol 0\endcsname\undefined
  \global\expandafter\let\csname mycol 1\endcsname\undefined
  \foreach \col[count=\i from 0] in {#1}{\global\expandafter\let\csname mycol \i\endcsname\col}
  \xdef\myfirst{red}
  \xdef\mysecond{brown}
  \ifcsname mycol 0\endcsname\xdef\myfirst{\csname mycol 0\endcsname}\fi
  \ifcsname mycol 1\endcsname\xdef\mysecond{\csname mycol 1\endcsname}\fi
    % Do something to set #3, #4 a default value
    \colorbox{white}{\begin{varwidth}{\textwidth}
        % Heading
        \colorbox{green!30}{#2}\\
        % Content
        \fcolorbox{\myfirst}{\mysecond}{\begin{varwidth}{\textwidth}
            #3
        \end{varwidth}}
    \end{varwidth}}
}
\begin{document}
\boxx[green]{Heading}{Some \\ fancy \\ content}
\boxx[blue,red]{Heading}{Some \\ fancy \\ content}
\boxx[yellow,gray]{Heading}{Some \\ fancy \\ content}
\end{document}

Output:

enter image description here

  • Optional parameter means that can be missing too, and in this case the default colors will be used. (Forgot to run it without parameter) – koleygr Mar 8 '18 at 12:52
3

The following example defines two keys - border and fill, which can be specified in any order. The use of keys provides a contextual reference as to what is set and with what colour.

enter image description here

\documentclass{article}

\usepackage{varwidth,xcolor,xkeyval}

\makeatletter
\define@cmdkey{boxx}[boxx@]{border}{}
\define@cmdkey{boxx}[boxx@]{fill}{}

% \boxx[<options>]{<heading>}{<content>}
\newcommand{\boxx}[3][]{
  \setkeys{boxx}{
    border = yellow, fill = brown, % default settings
    #1} % local changes to default
  \noindent
  \colorbox{white}{\begin{varwidth}{\textwidth}
    % Heading
    \colorbox{green!30}{#2} \\
    % Content
    \fcolorbox{\boxx@border}{\boxx@fill}{\begin{varwidth}{\textwidth}
      #3
    \end{varwidth}}%
  \end{varwidth}}
}
\makeatother

\begin{document}

\boxx[border = green]{Heading}{Some \\ fancy \\ content}
\boxx[border = blue, fill = red]{Heading}{Some \\ fancy \\ content}
\boxx[fill = gray, border = yellow]{Heading}{Some \\ fancy \\ content}

\end{document}

The defaults (border = yellow and fill = brown) are set before it is changed to whatever is specified with the optional argument to \boxx[<options>]{<heading>}{<content>}.

2

With this approach, one can omit both, the second or the first optional paramater.

enter image description here

\documentclass{article}
\usepackage{varwidth}
\usepackage{xcolor}
\usepackage{pgffor}

\usepackage{xstring}
\newcommand{\boxx}[3][]{
\StrCut{#1}{,}{\myfirst}{\mysecond}
\IfEq{\myfirst}{}{\def\myfirst{red}}{}      % first default
\IfEq{\mysecond}{}{\def\mysecond{brown}}{}  % second default
    \colorbox{white}{\begin{varwidth}{\textwidth}
        % Heading
        \colorbox{green!30}{#2}\\
        % Content
        \fcolorbox{\myfirst}{\mysecond}{\begin{varwidth}{\textwidth}
            #3
        \end{varwidth}}
    \end{varwidth}}
}
\begin{document}
\boxx[]{Heading}{Some \\ fancy \\ content}
\boxx[green]{Heading}{Some \\ fancy \\ content}
\boxx[,green]{Heading}{Some \\ fancy \\ content}
\boxx[blue,red]{Heading}{Some \\ fancy \\ content}
\boxx[yellow,gray]{Heading}{Some \\ fancy \\ content}
\end{document}
  • that's an interesting approach I'm gonan try it out. – xotix Mar 10 '18 at 13:04

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.