Latex: use color without defining a new color

colortabularraytikz-pgf

Is it possible to use a new color without defining a new color like \definecolor{mycolor}{HTML}{a65dbd}? It is indeed cumbersome to use when the color is used only once, and can easily lead to conflicts if multiple parts of the file use the same color name for different colors (in particular, no error is given if we use \definecolor{mycolor} twice, so the colors only appears to be wrong for no apparent reason).

As HTML colors are easy to copy/paste between programs, I'd love to be able to do something like:

\textcolor{HTML(00AA00)}{\textbf{This is not working}}

MWE:

enter image description here

\documentclass{article}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{verbatim}
\definecolor{mycolor}{HTML}{a65dbd} % Equal to RGB(166,93,189).
\begin{document}
\noindent
\textcolor{mycolor}{\textbf{This is my color but annoying to use.}}\\
\textcolor{red!65!green!36!blue!74!}{\textbf{This is better but not accurate nor easily copy/pastable.}}\\
\textcolor[HTML]{a65dbd}{\textbf{This is working, but not generalizable (tikz, tabularray\dots).}}\\
\verb|\tikz \node[text=[HTML]{a65dbd]{This is not working};|
\end{document}

EDIT

Phelype proposed in comments to use \textcolor[HTML]{00AA00}{...}, unfortunately it does not generalize to other commands. For instance, this is not working in tikz, nor in tabularray cell colors:

\tikz \node[text=[HTML]{a65dbd]{This is not working};

Wouldn't it be possible to define a generic color taking arguments (like green!50!white which works for both tikz, tabularray, textcolor…) but taking as input an HTML color description?

EDIT

I created a feature request here https://github.com/latex3/xcolor/issues/13 but if someone has a solution is the meantime, I'd be interested to hear it.

Best Answer

Although I'm not a big fan of @L.J.R.'s approach, the example below extends his/her answer to gain support for tikz.

Notable improvements:

  • By patching internal of \colorlet, it now supports tikz.
  • Skipping patching when the color expression doesn't contain |.
\documentclass{article}
\usepackage{xpatch}
\usepackage{tikz}
\usepackage{tabularray}

\usepackage{unravel}
\unravelsetup{max-action=1000, max-input=1000, max-output=1000}
\long\def\beginunravel#1\endunravel{\unravel{#1}}
\providecommand\beginunravel{}
\def\endunravel{}

\makeatletter

% The following set of ugly patches based on
%   https://tex.stackexchange.com/a/629719
% extend xcolor <expr> (see `texdoc xcolor`, Table 4) to
%   <expr> ::= <mode> "|" <spec>
%            | <original expr>
% and add constraint that a (user-defined) color name must NOT contaion `|`

% for \color, \textcolor, etc.
\xpretocmd\@declaredcolor
  {\my@hack@definetempcolor{#1}}
  {}{\PatchFailed}

\def\my@hack@color{\xglobal\definecolor}

% for \colorlet (used by tikz)
\xpretocmd\XC@col@rlet
  {\my@hack@definetempcolor{#4}}
  {}{\PatchFailed}

% shared inner helper macros

% if color expression #1 contains `|` and is an undefined color name, execute
%   \xglobal\definecolor{#1}{<#1 pre |>}{<#1 post |>}
\def\my@hack@definetempcolor#1{%
  % a bit normalization: remove all spaces from #1
  \expanded{\my@hack@@definetempcolor{\zap@space#1 \@empty}}}%
\protected\def\my@hack@@definetempcolor#1{%
  \in@|{#1}%
  \ifin@
    \@ifundefinedcolor{#1}{\my@hack@splitcolor#1\@nil{\xglobal\definecolor}}{}%
  \fi
}

\def\my@hack@splitcolor#1|#2\@nil#3{#3{#1|#2}{#1}{#2}}
\makeatother

\begin{document}
{ \color{rgb|0.5,0.7,0.9}TEXT }

\textcolor{HTML|a65dbd}{TEXT}

\begin{tblr}{row{1} = {bg={HTML|11AA33}}}
  Alpha & Beta & Gamma
\end{tblr}

\tikz[line width=3pt]
  \draw[{HTML|a65dbd}, fill={rgb|0.5,0.7,0.9}] (0,0) rectangle (1,1);
\end{document}

enter image description here