如何从宏中定义颜色?

如何从宏中定义颜色?

我正在尝试定义一种颜色(使用xcolor包),其中颜色由十六进制 HTML 格式的宏提供。我有一个宏\colorGet{#1}{#2},它接受两个参数并以十六进制格式返回颜色,我想将其传递给\definecolor宏。

不幸的是,我简单地将一个宏作为另一个宏的参数传递的简单方法不起作用,我知道这是因为 LaTeX 扩展宏的顺序。但是,我不明白如何确保它们以正确的顺序展开。我尝试修改Heiko Oberdiek 的回答回答了类似的问题,但没有成功。我不太明白\expandafter我错在哪里。下面是我尝试的一个最小(非)工作示例。

\documentclass{article}
%
\usepackage{xcolor}
%
\newcommand{\colorGet}[2]{D3523C} % A macro which returns a different hex-code for each combination of arguments, simplified for this example.
\newcommand{\colordefine}[2]{%
    \expandafter\colordefineAux#2{#1}%
}
\newcommand{\colordefineAux}[2]{%
    \definecolor{#2}{HTML}{#1}%
}
%
\begin{document}
    \colordefine{mycolor}{\colorGet{SchemeName}{ColourName}}
\end{document}

尝试编译此程序会出现以下错误:

! Argument of \xs_newmacro_ has an extra }.
<inserted text>
                \par
l.14 ...rdefine{Accent2}{\colorGet{Bold}{Accent2}}

有没有相对简单的方法来做到这一点?

编辑:正如 Phelype Oleinik 所强调的那样,上述错误消息是xstring由 的原始定义中使用的包引起的\colorGet。自从提出这个问题以来,我意识到这个xstring包是不需要的。

答案1

对于给定的 MWE,首先将\colorGet宏扩展为临时命令,然后将其用作 的参数就足够了。如果用于宏,\definecolor则可能需要扩展解决方案(双关语……) 。xstring\colorGet

\documentclass{article}
\usepackage{xcolor}

\newcommand{\colorGet}[2]{D3523C} % A macro which returns a different hex-code for each combination of arguments, simplified for this example.
\newcommand{\colordefine}[2]{%
    \edef\tmpcolor{#2}%
    \definecolor{#1}{HTML}{\tmpcolor}%
}

\begin{document}
    \colordefine{mycolor}{\colorGet{SchemeName}{ColourName}}
    \textcolor{mycolor}{colored text}
\end{document}

答案2

\documentclass{article}
%
\usepackage{xcolor}
%
\newcommand{\colorGet}[2]{D3523C} % A macro which returns a different hex-code for each combination of arguments, simplified for this example.
\newcommand{\colordefine}[2]{%
    \expandafter\colordefineAux#2{#1}%
}
\newcommand{\colordefineAux}[2]{%
    \definecolor{#2}{HTML}{#1}%
}
%
\begin{document}
    \colordefine{mycolor}{\colorGet{SchemeName}{ColourName}}
\end{document}

\colordefine{mycolor}{\colorGet{SchemeName}{ColourName}}产量:

\expandafter\colordefineAux\colorGet{SchemeName}{ColourName}{mycolor},从而得出:

\colordefineAux D3523C{mycolor},从而得出:

\definecolor{3}{HTML}{D}523C{mycolor}

您可能已经意识到,要么\colorGet应该返回嵌套在括号中的结果,要么\colorGet应该将调用嵌套在括号中。

在任何情况下都\colorGet必须完全可扩展,即,它本身不得产生形成任何临时分配的标记,因此实际上不是 HTML 颜色规范的一部分。

为了解决这个限制,我建议\colorGet采用一个(可选)参数,您可以在其中指定要附加结果以进行进一步处理的标记:

\documentclass{article}
%
\usepackage{xcolor}
%
\makeatletter
\newcommand{\colorGet}[3][\@firstofone]{#1{D3523C}} % A macro which returns a different hex-code for each combination of arguments, simplified for this example.
\makeatother
\begin{document}
\colorGet[\definecolor{mycolor}{HTML}]{SchemeName}{ColourName}
\end{document}

相关内容