7

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.

2
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Joseph Wright
    Jan 10, 2022 at 14:47
  • Even the HTML color code doesn't get real HTML colors. Dec 16, 2022 at 17:13

4 Answers 4

1

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

2
  • Great, thanks, this should be merged upstream!
    – tobiasBora
    Jan 5 at 14:05
  • 1
    @tobiasBora Current patch is still brute. Another set of patch entrances is when xcolor wants to raise error Undefined color `xxx'. Also active-char handling need to be added, to live with the world if the newly introduced reserved character in color expr (here |) is active. Also I've find a perhaps better way: provide a new color function, so one can use \color{.>rgb,.1,.5,.9} (need one new function per color model) or \color{.>raw,rgb,.1,.5,.9} (need only one new function). Any expr before > will be parsed but dropped. Need time to try and implement all these. Jan 10 at 0:59
5

At least the following dirty code works for tabularray package :-)

\documentclass{article}

\usepackage{xcolor}
\usepackage{etoolbox}
\usepackage{tikz}
\usepackage{tabularray}

\makeatletter
\ExplSyntaxOn

\pretocmd{\@declaredcolor}{\my@hack@color{#1}}{}{}

\def\my@hack@color#1{\@ifundefined{\@backslashchar color@#1}{\MyDefineColor{#1}}{\relax}}

\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }

\NewDocumentCommand \MyDefineColor { m } {
  \seq_set_split:Nnx \l_tmpa_seq {|} {#1}
  %\seq_show:N \l_tmpa_seq
  \exp_args:Nnxx \definecolor{#1} { \seq_item:Nn \l_tmpa_seq {1} } { \seq_item:Nn \l_tmpa_seq {2} }
}

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

%% This is not working:
%\tikz \path[draw={HTML|012acd}] (0,0) -- (1,1);

\end{document}

enter image description here

9
  • Looks really cool, thanks! To bad it fails with tikz. I'll just put a +1 so far, hoping to see a solution that also works with tikz!
    – tobiasBora
    Jan 10, 2022 at 14:48
  • @tobiasBora: why do you want to use a hammersledge like TiKZ for such a simple layout?
    – Bernard
    Jan 10, 2022 at 16:09
  • @Bernard Of course I don't plan to use tikz to color a simple text. But I do like to use multiple colors for my tikz drawings. For the sake of simplicity I include some MWE, but in real life my diagram will certainly be more complex than \tikz \path[draw={HTML+012acd}] (0,0) -- (1,1);
    – tobiasBora
    Jan 10, 2022 at 16:43
  • @tobiasBora: It can be done with a simple table and \rowcolor Other than that, you can use colors by name with xcolor and find already existing colour names corresponding to what you want.
    – Bernard
    Jan 10, 2022 at 16:52
  • @Bernard I doubt you can make any tikz drawing with a simple table and \rowcolor, just try to create a gradient-filled ellipse with \rowcolor... Concerning colors by name, as already explained they describe only 0.03% of all the colors you can get with the HTML notation. And when I use a palette or gimp to find a precise color I like, I don't want to spend hours trying to find equivalent names, I just want to use its HTML name.
    – tobiasBora
    Jan 10, 2022 at 18:08
2

For tikz and packages based on it (and pgfkeys), the following new key handler /.raw color may help.

Usages:

  • \draw[<color>] -> \draw[.raw color={<color model>}{<color spec>}]
  • key=<color> -> key/.raw color={<color model>}{<color spec>}

To support \draw[<extended color spec>] and/or key=<extended color spec>, one has to patch several places of tikz, and maybe even pgf, which I doubt it's worth.

\documentclass{article}
\usepackage{tikz}
\usepackage{tcolorbox}

\makeatletter
\newcount\pgfutil@colorcnt

%   \pgfkeys{key/.raw color={rgb}{1,0,0}}
% is equivalent to
%   \definecolor{<name>}{rgb}{1,0,0}
%   \pgfkeys{key=<name>}
% where <name> is `pgf@color@rgb@1,0,0`
\pgfkeys{/handlers/.raw color/.code 2 args={%
  \expandafter\pgfkeys@rawcolor\expanded{{pgf@color@\pgfkeys@zap@space #1@#2 \@empty}}{#1}{#2}%
}}

% #1 = (internal) color name, #2 = color model, #3 = color spec
\def\pgfkeys@rawcolor#1#2#3{%
  \expandafter\xglobal % for efficiency concerns, define the color globally
                       % note \xglobal is provided by `xcolor`, hence importable
  \pgfutil@definecolor{#1}{#2}{#3}%
  \edef\pgf@expanded@path{\pgfkeyscurrentpath}% was `\the\pgfkeys@pathtoks`
  % Note `/tikz/<name>` is different from `tikz/.cd, <name>`. Only the latter 
  % will be directed to `/tikz/.unknown` hence parse color name correctly.
  \ifx\pgf@expanded@path\pgfkeys@defaultpath@tikz@text
    \pgfkeysalso{{#1}}%
  \else
    \pgfkeysalso{\pgfkeyscurrentpath={#1}}%
  \fi
}

% helper, the same as \zep@space in latex2e
\def\pgfkeys@zap@space#1 #2{%
  #1%
  \ifx#2\@empty\else\expandafter\pgfkeys@zap@space\fi
  #2}

\def\pgfkeys@defaultpath@tikz@text{/tikz}
\makeatother


\begin{document}
\begin{tikzpicture}[line width=2pt]
  \draw[red, fill=blue]
    (0,0) rectangle +(1,1) node[text=black!30] {node text};
  \draw[.raw color={rgb}{1,0,0}, fill/.raw color={HTML}{0000FF}]
    (2,0) rectangle +(1,1) node[text/.raw color={cmyk}{0,0,0,.3}] {node text};
\end{tikzpicture}

\tcbset{nobeforeafter}
\tcbox[colback=green!50]{tcbox content}\qquad
\tcbox[colback/.raw color={rgb}{.5,1,.5}]{tcbox content}
\end{document}

enter image description here

2
  • Looks super cool, thanks a lot! This should be integrated in tikz ;-) By any chance, I guess you don't know how to improve the answer from L.J.R so that it also works with tikz without a need for the new .raw color key? This way I don't need to think about which answer I should accept :-P
    – tobiasBora
    Jan 17, 2022 at 14:56
  • @tobiasBora I think it's possible, but a more robust way (that is fully backward-compatible) to extend xcolor's color expression parser is needed. Jan 18, 2022 at 9:16
1

As I said, it also can be done with very simple tools: xcolor, cellspace and a tabular environment:

\documentclass[12pt]{article}
\usepackage[svgnames, table]{xcolor}
\usepackage{cellspace}
\setlength{\cellspacetoplimit}{18pt}
\setlength{\cellspacebottomlimit}{18pt}

\begin{document}

{\centering \Huge\bfseries
\begin{tabular}{llSl}
\color{PowderBlue} TEXT \\
\color{MediumOrchid} TEXT \\
\rowcolor{MediumSeaGreen!60!OliveDrab} \enspace Alpha\enspace &\enspace Beta\enspace &\enspace Gamma\enspace
\end{tabular}
}
\end{document} 

enter image description here

3
  • 1
    Thanks, but I'm sorry I can't find any relation with my initial question… The whole point of the work started by L.J.R is to provide a syntax HTML+a65dbd so that we can use this in place of any color without using definecolor. Here you try to use a combinaison of existing colors, but as explained in the question in has many troubles. In particular it can't be copy/pasted from other softwares and it is hard to produce a precise color that way. For instance your green seems darker than LJR's one.
    – tobiasBora
    Jan 10, 2022 at 22:10
  • As you've deleted the image from your initial post, I tried to make the colour from memory. Anyway, with xcolor, it's easy to adjust a colour close to what you have in mind to something quite close.
    – Bernard
    Jan 10, 2022 at 22:37
  • I agree with the OP's question: color names are silly and a waste of time. I want to be able to write \color{HTML+abcdef} instead of defining a color name. Dec 16, 2022 at 13:23

You must log in to answer this question.

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