我以以下方式将颜色存储在宏中
\newcommand{\mycolor}{{rgb}{0,0,1}}
例如。有没有办法用宏定义相同的颜色
\colordefine{maincolor}{rgb}{0,0,1}
并用它替换最后的代码?
答案1
有可能的:
\documentclass{article}
\usepackage{color}% or xcolor
\newcommand*{\colordefine}[2]{%
\expandafter\colordefineAux#2{#1}%
}
\newcommand*{\colordefineAux}[3]{%
\definecolor{#3}{#1}{#2}%
}
\newcommand{\mycolor}{{rgb}{0,0,1}}
\colordefine{maincolor}\mycolor
\begin{document}
The main color is \textcolor{maincolor}{blue}.
\end{document}
但为了清楚起见,我会坚持使用官方接口\definecolor
和/或\colorlet
(后者由包提供)。xcolor
答案2
这个天真的想法\definecolor{maincolor}\mycolor
行不通,因为在这种情况下\mycolor
不会扩展为{rgb}{0,0,1}
成为的第二个和第三个参数\definecolor
,但仍然是的单个(第二个)参数\definecolor
。因此,主要问题是:在 TeX 读取的第二个参数之前,如何完全扩展\mycolor
或至少扩展一步\definecolor
?
当然,也可以这么写:
\documentclass{article}
\usepackage{color}
\newcommand{\mycolor}{{rgb}{0,0,1}}
\expandafter\definecolor\expandafter{\expandafter m\expandafter a\expandafter i\expandafter n\expandafter c\expandafter o\expandafter l\expandafter o\expandafter r\expandafter }\mycolor
\begin{document}
Example \textcolor{maincolor}{example} example.
\end{document}
使用此代码,扩展\definecolor
(以及读取参数)将延迟,直到读取{
完毕,将延迟,直到m
读取完毕,将延迟,直到}
读取完毕。因此 TeX 将不再扩展/执行,\definecolor{maincolor}\mycolor
但\definecolor{maincolor}{rgb}{0,0,1}
。
然而这样的解决方案并不实用。所以我们需要一个解决方案,它不需要显式的\expandafter
队列来解决扩展延迟问题。Herbert 已经展示了一个隐藏参数重新排序的解决方案。
另一个建议是扩展类似于 LaTeX 内核的参数\@expandtwoargs
,但没有第二个参数的参数括号:
\documentclass{article}
\usepackage{color}
\newcommand{\mycolor}{{rgb}{0,0,1}}
\makeatletter
\newcommand*{\expandsecondargtoseveralargs}[3]{%
\edef\reserved@a{\noexpand#1{#2}#3}%
\reserved@a
}
\makeatother
\expandsecondargtoseveralargs\definecolor{maincolor}\mycolor
\begin{document}
Example \textcolor{maincolor}{example} example.
\end{document}
或者不进行扩展,而只使用 ε-TeX{maincolor}
进行一级扩展:\mycolor
\documentclass{article}
\usepackage{color}
\newcommand{\mycolor}{{rgb}{0,0,1}}
\makeatletter
\newcommand*{\expandsecondargtoseveralargs}[3]{%
\edef\reserved@a{\unexpanded{#1{#2}}\unexpanded\expandafter{#3}}%
\reserved@a
}
\makeatother
\expandsecondargtoseveralargs\definecolor{maincolor}\mycolor
\begin{document}
Example \textcolor{maincolor}{example} example.
\end{document}
两者的结果是:
如果您不想要前缀命令而是新命令,您可以使用以下定义之一\expandsecondargtoseveralargs
来定义您的\colordefine
:
\documentclass{article}
\usepackage{color}
\newcommand{\mycolor}{{rgb}{0,0,1}}
\makeatletter
\newcommand*{\expandsecondargtoseveralargs}[3]{%
\edef\reserved@a{\unexpanded{#1{#2}}\unexpanded\expandafter{#3}}%
\reserved@a
}
\makeatother
\newcommand*{\colordefine}{\expandsecondargtoseveralargs\definecolor}
\colordefine{maincolor}\mycolor
\begin{document}
Example \textcolor{maincolor}{example} example.
\end{document}
但是,我不明白为什么您要以这种方式在宏中存储颜色。所以也许这并不能真正解决您的问题。