Is color undefined
After \definecolor{foo}{<model>}{<spec>}
or \colorlet{foo}{<color>}
, the new color specification is store in a macro called
\\color@foo
(with a backslash in the name). You accomplish your wish with
\documentclass{article}
\usepackage{xcolor}
\makeatletter
\newcommand{\colorprovide}[2]{%
\@ifundefined{\string\color@#1}{\colorlet{#1}{#2}}{}}
\makeatother
\begin{document}
%Initial Definition
\colorprovide{mycolor}{red}
\textcolor{mycolor}{Test 1}
%Will overwrite
\colorlet{mycolor}{blue}
\textcolor{mycolor}{Test 2}
%Should NOT overwrite as it exists
\colorprovide{mycolor}{red}
\textcolor{mycolor}{Test 3}
\end{document}
Addition suggested by H. Oberdiek
Actually xcolor
already defines a check, but doesn't provide a “public version”:
\def\@ifundefinedcolor#1{\@ifundefined{\string\color@#1}}
so you can say
\makeatletter
\newcommand{\colorprovide}[2]{%
\@ifundefinedcolor{#1}{\colorlet{#1}{#2}}{}}
\makeatother
which is probably clearer and doesn't rely on the internal implementation of the macro holding the color specification.
This is an old question, but the only answer do not mention \providecolor
that is available in xcolor
since version 2.0 (2004/07/04).
This command has three parameters and in this particular case one can use it as \providecolor{<color to provide>}{named}{<existing color>}
.
\documentclass[varwidth,border=7pt]{standalone}
\usepackage{xcolor}
\newcommand{\colorprovide}[2]{\providecolor{#1}{named}{#2}}
\begin{document}
%Initial Definition
\colorprovide{mycolor}{red}
\textcolor{mycolor}{Test 1}
%Will overwrite
\colorlet{mycolor}{green}
\textcolor{mycolor}{Test 2}
%Should NOT overwrite as it exists
\colorprovide{mycolor}{red}
\textcolor{mycolor}{Test 3}
\end{document}