1

I have a color stored in a macro in the following way

\newcommand{\mycolor}{{rgb}{0,0,1}}

for example. Is there any way to define the same color using the macro

\colordefine{maincolor}{rgb}{0,0,1}

and replacing last code with it?

2

2 Answers 2

5

It is possible:

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

Result

But I would stick with the official interfaces \definecolor and/or \colorlet (the latter provided by package xcolor) for clarity.

4

The naive idea \definecolor{maincolor}\mycolor would not work, because in this case \mycolor will not expand to {rgb}{0,0,1} to become argument two and three of \definecolor but is still a single (second) argument of \definecolor. So the main question would be: How to expand \mycolor either completely or at least one step, before TeX reads the second argument of \definecolor?

At sure, one could write:

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

With this code, expansion of \definecolor (and so reading the arguments) will be delays until the { have been read, which will be delayed until m have been read, which will be … until } have been read. So TeX will not longer expand/execute \definecolor{maincolor}\mycolor but \definecolor{maincolor}{rgb}{0,0,1}.

However such a solution is not really practical. So we need a solution, that does the expansion delay with the need of an explicit \expandafter queue. Herbert has already shown one solution with hidden reordering of arguments.

Another suggestion could be to expand the arguments similar to \@expandtwoargs of the LaTeX kernel but without the argument braces for the second argument:

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

or without expansion of {maincolor} and only one level expansion of \mycolor using ε-TeX:

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

Both result in:

enter image description here

And if you do not want a prefix command but a new command, you can use one of these definitions of \expandsecondargtoseveralargs to define your \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}

However, I do not understand why you are storing the colors this way in macros. So maybe this is not really a solution to your problem.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .