宏 \newcommand{mymacro}{option=value} 在 tcolorbox 环境中失败

宏 \newcommand{mymacro}{option=value} 在 tcolorbox 环境中失败

我正在尝试在 tcolorbox 环境中通过另一个宏放置一个选项,如下所示:

\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}

不起作用,它说:!软件包 pgfkeys 错误:我不知道密钥“/tcb/colback=blue”,我将忽略它。也许你拼错了。这可能是一个常见的错误,但到目前为止我还没有找到解决方案,即使在 freenode 中的 #latex 中也是如此。

更新 这里我将我的示例升级为更接近我的真实宏。以下是其他人提供的解决方案之一,并付诸实践。

\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}
}

解决方案:

\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}

即使我将 \bubblex 的第二个可选参数留空,它也能正常工作,这正是我想要的。我以为宏定义中 #2 后面的逗号会导致错误。

答案1

您不能使用扩展选项的宏。但您可以使用样式

\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}

在此处输入图片描述

稍微不同的方法:

\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}

您还可以使用 将两者结合起来tcboption=line,tcboption=back

答案2

您必须先扩展参数,然后才能\begin{tcolorbox}进行处理。我不知道该怎么做,但这是事实。

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

答案3

为了了解如何\expandafter应用获取的\tcboption顶层扩展,您可以执行以下操作:

\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}

更短的是:

\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}

这两个例子仅用于演示目的,并且仅专注于获取的顶层扩展\tcboption

wipet 的方法会导致扩展来自的所有内容,\tcboption直到剩余的标记不可扩展或者由于\unexpanded/\noexpand被提供或由于根据 被定义而没有扩展\protected

除了使用 LaTeX 时我可能会使用wipet 的方法来解决我的两个例子\protected@edef之外,我更喜欢使用 wipet 的方法。\edef

这事儿的“王道”,也就是风格的定义,已经被egreg展现出来了。

相关内容