colo-new.tex / last modification: 2008-04-01 11:53
%D \module
%D   [       file=colo-ini,
%D        version=2007.08.08,
%D          title=\CONTEXT\ Color Macros,
%D       subtitle=Initialization,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D We need to clean this up further but first we hav eto make sure that mkiv
%D code works ok.

\writestatus{loading}{Context Color Macros / initialization}

%D This module implements color. Since \MKII\ and \MKIV\ use a completely
%D different approach, this module only implements a few generic mechanisms.

\startmessages  dutch  library: colors
  title: kleur
      1: systeem -- is globaal actief
      2: systeem -- is lokaal actief
      3: -- is niet gedefinieerd --
      4: systeem -- wordt geladen
      5: onbekend systeem --
      6: palet -- is beschikbaar
      7: palet -- is niet beschikbaar
      8: specificatie -- bij -- wordt zwart
      9: -- kleurruimte wordt niet ondersteund
     10: -- kleurruimte wordt ondersteund
     11: kleur wordt vertaald in grijs
     12: -- is geregistreerd
\stopmessages

\startmessages  english  library: colors
  title: color
      1: system -- is global activated
      2: system -- is local activated
      3: -- is not defined --
      4: system -- is loaded
      5: unknown system --
      6: palette -- is available
      7: palette -- is not available
      8: specification -- at color -- becomes black
      9: -- color space is not supported
     10: -- color space is supported
     11: color is converted to gray
     12: -- is registered
\stopmessages

\startmessages  german  library: colors
  title: farbe
      1: system -- ist global aktiviert
      2: system -- ist lokal aktiviert
      3: -- ist undefiniert --
      4: system -- ist geladen
      5: unbekanntes System --
      6: palette -- ist verfuegbar
      7: palette -- ist nicht verfuegbar
      8: Spezifikation -- bei Farbe -- wird schwarz
      9: -- Farbraum wird nicht unterstuetzt
     10: -- Farbraum wird unterstuetzt
     11: Farbe wird in Grau umgewandelt
     12: -- is registered
\stopmessages

\startmessages  czech  library: colors
  title: barva
      1: system -- je globalne aktivovana
      2: system -- je lokalne activovana
      3: -- neni definovana --
      4: system -- je nacten
      5: neznamy system --
      6: palette -- je k dispozici
      7: palette -- neni k dispozici
      8: specifikace -- v barve -- bude cerna
      9: -- prostor barev neni podporovan
     10: -- prostor barev je podporovan
     11: barva je prevedena na sed
     12: -- is registered
\stopmessages

\startmessages  italian  library: colors
  title: colore
      1: sistema -- attivato globalmente
      2: sistema -- attivato localmente
      3: -- non definito --
      4: sistema -- caricato
      5: sistema -- sconosciuto
      6: tavolozza -- resa disponibile
      7: tavolozza -- non disponibile
      8: specifica -- del colore -- convertita in nero
      9: spazio dei colori -- non supportato
     10: spazio dei colori -- supportato
     11: il colore ø convertito in grigio
     12: -- is registered
\stopmessages

\startmessages  norwegian  library: colors
  title: farge
      1: system -- er aktivert globalt
      2: system -- er aktivert lokalt
      3: -- er udefinert --
      4: system -- er lest inn
      5: ukjent system --
      6: palett -- er tilgjengelig
      7: palett -- er ikke tilgjengelig
      8: spesifikasjon -- for farge -- gir kun svart
      9: -- fargerom er ikke støttet
     10: -- fargerom er støttet
     11: fargen vil bli vist som grø
     12: -- is registered
\stopmessages

\startmessages  romanian  library: colors
  title: culori
      1: sistem -- este activata global
      2: sistem -- este activata local
      3: -- nu este definita --
      4: sistem -- este incarcata
      5: sistem -- necunoscuta
      6: paleta -- este disponibila
      7: palette -- nu este disponibila
      8: specificatia -- la culoarea -- devine neagra
      9: spatiul de culoare -- nu este suportat
     10: spatiul de culoare -- este suportat
     11: culoarea este convertita la gri
     12: -- is registered
\stopmessages

\startmessages  french  library: colors
  title: couleurs
      1: le système -- est globalement activé
      2: le système -- est localement activé
      3: -- n'est pas défini --
      4: le système -- est chargé
      5: système -- inconnu
      6: la palette -- est disponible
      7: le palette -- n'est pas disponible
      8: la spécification -- de la couleur -- devient noire
      9: l'espace de couleur -- n'est pas supporté
     10: -- l'espace de couleur est supporté
     11: la couleur est convertie en niveau de gris
     12: -- est enregistré
\stopmessages

\unprotect

\chardef\colorversion=1 % temp, needed for tracing purposes, mkiv transition

%D We use a couple of local registers. That way we don't have
%D to group when converting colors. By the way, this is not
%D really faster. We can sqeeze half a second runtime for 50K
%D switches on a 1G machine, but the macros will become rather
%D ugly then. To mention one such improvement: no colon
%D after the key character (.25 sec).

\newdimen\colordimen
\newcount\colorcount

%D When typesetting for paper, we prefer using the \cap{CMYK}
%D color space, but for on||screen viewing we prefer \cap{RGB}
%D (the previous implementation supported only this scheme).
%D Independant of such specifications, we support some automatic
%D conversions:
%D
%D \startitemize[packed]
%D \item  convert all colors to \cap{RGB}
%D \item  convert all colors to \cap{CMYK}
%D \item  convert all colors to gray scales
%D \stopitemize
%D
%D We also support optimization of colors to gray scales.
%D
%D \startitemize[continue]
%D \item  reduce gray colors to gray scales
%D \item  reduce \cap{CMY} components to \cap{K}
%D \stopitemize
%D
%D These options are communicated by means of:

\newif\ifRGBsupported
\newif\ifCMYKsupported
\newif\ifSPOTsupported
\newif\ifpreferGRAY
\newif\ifGRAYprefered
\newif\ifreduceCMYK
\newif\ifconverttoGRAY
\newif\ifweightGRAY       \weightGRAYtrue

\newif\ifconvertMPcolors
\newif\ifreduceMPcolors
\newif\ifforcegrayMPcolors

%D The last boolean controls reduction of \cap{CMYK} to
%D \cap{CMY} colors. When set to true, the black component
%D is added to the other ones.
%D
%D Prefering gray is not the same as converting to gray.
%D Conversion treats each color components in a different way,
%D while prefering is just a reduction and thus a
%D space||saving option.

\newif\iffreezecolors  \freezecolorsfalse
\newif\ifincolor                          % true if colors enabled
\newif\iflocalcolor

\let\colorlist        \empty
\let\currentspotcolor \empty
\let\allspotcolors    \empty
\let\usedspotcolors   \empty
\let\usedcolorchannels\empty
\let\currentpalet     \empty

%D \macros
%D   {definecolor,defineglobalcolor,definenamedcolor,definespotcolor,definemultitonecolor}
%D
%D \startbuffer
%D \definecolor [blue]   [c=1,m=.38,y=0,k=.64] % pantone pms 2965 uncoated m
%D \definecolor [yellow] [c=0,m=.28,y=1,k=.06] % pantone pms  124 uncoated m
%D
%D \definespotcolor [blue-100]   [blue]   [p=1]
%D \definespotcolor [yellow-100] [yellow] [p=1]
%D
%D \definemultitonecolor [pdftoolscolor] [blue=.12,yellow=.28] [c=.1,m=.1,y=.3,k=.1]
%D
%D \useexternalfigure[demofig][mill.png][object=no]
%D
%D \startcombination[4*1]
%D   {\externalfigure[demofig]}                      {no color}
%D   {\externalfigure[demofig][color=pdftoolscolor]} {indexed duotone}
%D   {\externalfigure[demofig][color=blue-100]}      {spot color}
%D   {\externalfigure[demofig][color=yellow-100]}    {spot color}
%D \stopcombination
%D \stopbuffer
%D
%D \getbuffer \typebuffer

\def\definecolor         {\dodoubleargument\dodefinecolor}
\def\defineglobalcolor   {\dodoubleargument\dodefineglobalcolor}
\def\definenamedcolor    {\dodoubleargument\dodefinenamedcolor}
\def\definespotcolor     {\dotripleargument\dodefinespotcolor}
\def\definemultitonecolor{\doquadrupleempty\dodefinemultitonecolor}

% check: registerusedspotcolors
% check: registerusedcolorchannels

%D \macros
%D   {doifcolorelse, doifcolor}
%D
%D Switching to a color is done by means of the following
%D command. Later on we will explain the use of palets.  We
%D define ourselves a color conditional first.

\ifx\doifcolorelse\undefined
    \let\doifcolorelse\secondoftwoarguments
    \let\doifcolor    \gobbleoneargument
\fi

%D \macros
%D   {localstartcolor,localstopcolor}
%D
%D Simple color support, that is without nesting, is provided
%D by:

\ifx\localstartcolor\undefined
    \let\localstartcolor\undefined
    \let\localstopcolor \undefined
\fi

%D \macros
%D   {faststartcolor,faststopcolor}
%D
%D No checking for arguments and such:

\ifx\faststartcolor\undefined
    \def\faststartcolor[#1]{}
    \def\faststopcolor     {}
\fi

%D These local ones may go away in future versions.

%D \macros
%D   {startcolor,stopcolor}
%D
%D The more save method, the one that saves the current color
%D state and returns to this state afterward, is activated by:
%D
%D \showsetup{startcolor}

\ifx\startcolor\undefined
    \let\startcolor\undefined
    \let\stopcolor \undefined
\fi

%D \macros
%D   {startcurrentcolor,stopcurrentcolor}

\def\startcurrentcolor{\startcolor[\outercolorname]}
\def\stopcurrentcolor {\stopcolor}

%D \macros
%D   {color,graycolor}
%D
%D This leaves the simple color command:
%D
%D \showsetup{color}
%D \showsetup{graycolor}

\ifx\color\undefined
    \def\color    [#1]{}
    \def\graycolor[#1]{}
    \def\gray         {\graycolor}
\fi

%D \macros
%D   {localstartraster,localstopraster,
%D    startraster,stopraster,raster}
%D
%D The previous conversions are not linear and treat each color
%D component according to human perception curves. Pure gray
%D (we call them rasters) has equal color components. In
%D \CONTEXT\ rasters are only used as backgrounds and these
%D don't cross page boundaries in the way color does. Therefore
%D we don't need stacks and marks. Just to be compatible with
%D color support we offer both 'global' and 'local' commands.

\ifx\startraster\undefined
    \def\startraster     [#1]{}
    \def\stopraster          {}
    \def\raster          [#1]{}
    \def\localstartraster[#1]{}
    \def\localstopraster     {}
\fi

%D \macros
%D   {colorvalue, grayvalue}
%D
%D We can typeset the color components using \type{\colorvalue} and
%D \type{\grayvalue}. The commands:
%D
%D \startbuffer
%D color value of SomeKindOfRed: \colorvalue{SomeKindOfRed} \crlf
%D gray value of SomeKindOfRed: \grayvalue{SomeKindOfRed}
%D \stopbuffer
%D
%D \typebuffer
%D
%D show us:
%D
%D \startvoorbeeld
%D \getbuffer
%D \stopvoorbeeld

\def\colorformatseparator{ }

\ifx\colorvalue\undefined
    \let\colorvalue\gobbleoneargument
    \let\grayvalue \gobbleoneargument
\fi

% check: \currentcolorname
% check: \outercolorname

%D \macros
%D   {setupcolor}
%D
%D Color definitions can be grouped in files with the name:
%D
%D \starttyping
%D \f!colorprefix-identifier.tex
%D \stoptyping
%D
%D where \type{\f!colorprefix} is \unprotect {\tttf \f!colorprefix}.
%D Loading such a file is done by \protect
%D
%D \showsetup{setupcolor}
%D
%D Some default colors are specified in \type{colo-rgb.tex},
%D which is loaded into the format by:
%D
%D \starttyping
%D \setupcolor[rgb]
%D \stoptyping

\let\colorstyle\empty

\def\setupcolor
  {\dosingleargument\dosetupcolor}

\def\dosetupcolor[#1]%
  {\doifnot{#1}\colorstyle
     {\def\colorstyle{#1}%
      \processcommalist[#1]\dodosetupcolor}}

\def\dodosetupcolor#1%
  {\makeshortfilename[\truefilename{\f!colorprefix#1}]%
   \startreadingfile
     \readsysfile\shortfilename
       {\showmessage\m!colors4\colorstyle}
       {\showmessage\m!colors5\colorstyle}%
   \stopreadingfile}

\let\usecolors\setupcolor

% check: \chardef\currentcolorchannel=0
% check: \startcolormode
% check: \newif\iffilterspotcolor \filterspotcolorfalse
% check: \newif\ifdoingspotcolor  \doingspotcolorfalse
% check: \registercolorchannel

%D \macros
%D   {definetransparency}
%D
%D This command numbers to names:

\def\definetransparency
  {\dodoubleargument\dodefinetransparency}

\def\setupcolors
  {\dosingleargument\dosetupcolors}

\def\resetcolorsplitting
  {\chardef\currentcolorchannel\zerocount
   \let\currentspotcolor\empty
   \filterspotcolorfalse}

\def\colorsplitsuffix{\ifcase\currentcolorchannel\else-\@@clsplit\fi}
\def\colorsplitprefix{\ifcase\currentcolorchannel\else\@@clsplit-\fi}

\def\setcolorsplitting
  {\resetsystemmode{\v!color\colorsplitsuffix}%
   \resetcolorsplitting
   \processaction
     [\@@clsplit]
     [         c=>\chardef\currentcolorchannel1,%
               m=>\chardef\currentcolorchannel2,%
               y=>\chardef\currentcolorchannel3,%
               k=>\chardef\currentcolorchannel4,%
               r=>\chardef\currentcolorchannel5,%
               g=>\chardef\currentcolorchannel6,%
               b=>\chardef\currentcolorchannel7,%
               s=>\chardef\currentcolorchannel8,%
           \v!no=>,%      \currentcolorchannel0,% all colors
      \s!default=>,%      \currentcolorchannel0,% all colors
      \s!unknown=>\filterspotcolortrue
                  \edef\currentspotcolor{\commalistelement}]%
   \setsystemmode{\v!color\colorsplitsuffix}%
   \iffilterspotcolor \let\@@clrgb\v!no \fi}

\ifx\dosetupcolormodel\undefined
    \let\dosetupcolormodel\relax
\fi

\def\dosetupcolors[#1]% some no longer make sense in MkIV
  {\getparameters[\??cl][#1]%
   \doifelse\@@clspot\v!yes
     \SPOTsupportedtrue
     \SPOTsupportedfalse
   \doifelsenothing\@@clsplit
     \resetcolorsplitting
     \setcolorsplitting
   \doifelse\@@clreduction\v!yes
     \reduceCMYKtrue
     \reduceCMYKfalse
   \doifelse\@@clexpansion\v!yes
     \freezecolorstrue
     \freezecolorsfalse
   \doifelse\@@clcriterium\v!all
     \hidesplitcolortrue
     \hidesplitcolorfalse
   \doifelse\@@clrgb\v!no
     {\ifRGBsupported     \showmessage\m!colors {9}\v!rgb\RGBsupportedfalse\fi}
     {\ifRGBsupported\else\showmessage\m!colors{10}\v!rgb\RGBsupportedtrue \fi}%
   \doifelse\@@clcmyk\v!no
     {\ifCMYKsupported     \showmessage\m!colors {9}\v!cmyk\CMYKsupportedfalse\fi}
     {\ifCMYKsupported\else\showmessage\m!colors{10}\v!cmyk\CMYKsupportedtrue \fi}%
   \doifelse\@@clmpcmyk\v!no
     {\ifMPcmykcolors     \showmessage\m!colors {9}{\v!mp\v!cmyk}\MPcmykcolorsfalse\fi}
     {\ifMPcmykcolors\else\showmessage\m!colors{10}{\v!mp\v!cmyk}\MPcmykcolorstrue \fi}%
   \doifelse\@@clmpspot\v!no
     {\ifMPspotcolors     \showmessage\m!colors {9}{\v!mp\v!spot}\MPspotcolorsfalse\fi}
     {\ifMPspotcolors\else\showmessage\m!colors{10}{\v!mp\v!spot}\MPspotcolorstrue \fi}%
   \preferGRAYfalse
   \processaction
     [\@@clconversion]
     [    \v!yes=>\preferGRAYtrue,
       \v!always=>\preferGRAYtrue\RGBsupportedfalse\CMYKsupportedfalse]%
   \ifRGBsupported
     \converttoGRAYfalse
     \forcegrayMPcolorsfalse
   \else\ifCMYKsupported
     \converttoGRAYfalse
     \forcegrayMPcolorsfalse
     \convertMPcolorstrue
     \ifreduceCMYK
       \reduceMPcolorstrue
     \fi
   \else
     \ifconverttoGRAY\else\showmessage\m!colors{11}\empty\fi
     \converttoGRAYtrue
     \forcegrayMPcolorstrue
     \convertMPcolorsfalse
     \reduceMPcolorsfalse
   \fi\fi
   \processaction
     [\@@clstate]
     [ \v!global=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi
                  \incolortrue\localcolorfalse,
        \v!local=>\ifincolor\else\showmessage\m!colors2\colorstyle\fi
                  \incolortrue\localcolortrue,
        \v!start=>\ifincolor\else\showmessage\m!colors1\colorstyle\fi
                  \incolortrue\localcolorfalse
                  \let\@@clstate\v!global,
         \v!stop=>\incolorfalse\localcolorfalse
                  \forcegrayMPcolorstrue]%
   \dosetupcolormodel
   \initializemaintextcolor}

%D \macros
%D   {startregistercolor,stopregistercolor,permitcolormode}
%D
%D If you only want to register a color, the switch \type
%D {\ifpermitcolormode} can be used. That way the nested
%D colors know where to go back to.

\ifx\startregistercolor\undefined
    \def\startregistercolor[#1]{}
    \def\stopregistercolor     {}
\fi

%D We use these macros for implementing text colors
%D (actually, the first application was in foreground
%D colors).
%D
%D \starttyping
%D \starttextcolor[red]
%D   \dorecurse{10}{\input tufte \color[green]{oeps} \par}
%D \stoptextcolor
%D \stoptyping
%D
%D This is more efficient than the alternative:
%D
%D \starttyping
%D \setupbackgrounds[text][foregroundcolor=red]
%D \startregistercolor[red]
%D   \dorecurse{10}{\input tufte \color[green]{oeps} \par}
%D \stopregistercolor
%D \stoptyping

\def\maintextcolor     {}
\def\defaulttextcolor  {black}
\def\@@themaintextcolor{themaintextcolor}

\ifx\initializemaintextcolor\undefined
    \def\starttextcolor       [#1]{}
    \def\stoptextcolor            {}
    \def\initializemaintextcolor  {}
\fi

\ifx\restoretextcolor\undefined % to be redone
    \let\restoretextcolor   \firstofoneargument
    \let\localstarttextcolor\relax
    \let\localstoptextcolor \relax
\fi

%D In this documentation we will not go into too much details
%D on palets. Curious users can find more information on this
%D topic in \from[use of color].
%D
%D At the moment we implemented color in \CONTEXT\ color
%D printing was not yet on the desktop. In spite of this lack our
%D graphics designer made colorfull illustrations. When printed
%D on a black and white printer, distinctive colors can come
%D out equally gray. We therefore decided to use only colors
%D that were distinctive in colors as well as in black and
%D white print.
%D
%D Although none of the graphic packages we used supported
%D logical colors and global color redefition, we build this
%D support into \CONTEXT. This enabled us to experiment and
%D also prepared us for the future.

%D \macros
%D   {definepalet}
%D
%D Colors are grouped in palets. The colors in such a palet can
%D have colorful names, but best is to use names that specify
%D their use, like {\em important} or {\em danger}. As a sort
%D of example \CONTEXT\ has some palets predefined,
%D like:\footnote{At the time I wrote the palet support, I was
%D reading 'A hort history of time' of S.~Hawkins, so that's
%D why we stuck to quarks.}
%D
%D \starttyping
%D \definepalet
%D   [alfa]
%D   [     top=rood:7,
%D      bottom=groen:6,
%D          up=blauw:5,
%D        down=cyaan:4,
%D     strange=magenta:3,
%D       charm=geel:2]
%D \stoptyping
%D
%D It's formal definition is:
%D
%D \showsetup{definepalet}
%D
%D Visualized, such a palet looks like:
%D
%D \startbuffer[palet]
%D \showpalet [alfa] [horizontal,name,number,value]
%D \stopbuffer
%D
%D \startlinecorrection
%D \getbuffer[palet]
%D \stoplinecorrection
%D
%D This bar shows both the color and gray alternatives of the
%D palet components (not visible in black and white print).
%D
%D When needed, one can copy a palet by saying:
%D
%D \starttyping
%D \definepalet [TEXcolorpretty] [colorpretty]
%D \stoptyping
%D
%D This saves us some typing in for instance the modules that
%D deal with pretty verbatim typesetting.

\def\definepalet
  {\dodoubleargument\dodefinepalet}

\def\dodefinepalet[#1][#2]%
  {\doifassignmentelse{#2}
     {%\showmessage\m!colors6{#1}%
      \letvalue{\??pa#1}\empty
      \setevalue{\??pa\??pa#1}{#2}%
      \def\dodododefinepalet[##1=##2]%
        {\doifvaluesomething{\??pa#1}
           {\setevalue{\??pa#1}{\csname\??pa#1\endcsname,}}%
         \setevalue{\??pa#1}{\csname\??pa#1\endcsname##1}%
         \dodefinepaletcolor{#1}{##1}{##2}}%
      \def\dododefinepalet##1%
        {\dodododefinepalet[##1]}%
      \processcommalist[#2]\dododefinepalet}
     {\doifdefined{\??pa#2}
        {\expanded{\dodefinepalet[#1][\csname\??pa\??pa#2\endcsname]}}}}

\ifx\dodefinepaletcolor\undefined
    \let\dodefinepaletcolor\gobblethreearguments
\fi

\let\paletsize\!!zerocount

\def\getpaletsize[#1]%
  {\getcommacommandsize[\csname\??pa\??pa#1\endcsname]%
   \edef\paletsize{\number\commalistsize}}

%D Instead of refering to colors, one can also directly specify
%D a color:
%D
%D \starttyping
%D \definepalet[test][xx=green]
%D \definepalet[test][xx={y=.4}]
%D \stoptyping

%D \macros
%D   {setuppalet}
%D
%D Colors are taken from the current palet, if defined.
%D Setting the current palet is done by:
%D
%D \showsetup{setuppalet}

\let\currentpalet\empty

\def\setuppalet
  {\dosingleempty\dosetuppalet}

\def\dosetuppalet[#1]%
  {\edef\currentpalet{#1}%
   \ifx\currentpalet\empty
     % seems to be a reset
   \else\ifcsname\??pa\currentpalet\endcsname
     \edef\currentpalet{#1:}%
   \else
     \showmessage\m!colors7\currentpalet
     \let\currentpalet\empty
   \fi\fi}

%D \macros
%D   {showpalet}
%D
%D The previous visualization was typeset with:
%D
%D \typebuffer[palet]
%D
%D This commands is defined as:
%D
%D \showsetup{showpalet}

\fetchruntimecommand \showpalet {\f!colorprefix\s!run}

%D \macros
%D   {showcolorcomponents}
%D
%D \starttyping
%D \showcolorcomponents[color-1,color-2]
%D \stoptyping

\fetchruntimecommand \showcolorcomponents {\f!colorprefix\s!run}

%D \macros
%D   {definecolorgroup}
%D
%D The naming of the colors in this palet suggests some
%D ordening, which in turn is suported by color grouping.
%D
%D \starttyping
%D \definecolorgroup
%D   [red]
%D   [1.00:0.90:0.90,
%D    1.00:0.80:0.80,
%D    1.00:0.70:0.70,
%D    1.00:0.55:0.55,
%D    1.00:0.40:0.40,
%D    1.00:0.25:0.25,
%D    1.00:0.15:0.15,
%D    0.90:0.00:0.00]
%D \stoptyping
%D
%D In such a color group colors are numbered from~$1$ to~$n$.
%D
%D \showsetup{definecolorgroup}
%D
%D This kind of specification is not only more compact than
%D defining each color separate, it also loads faster and takes
%D less bytes.

\def\definecolorgroup
  {\dotripleempty\dodefinecolorgroup}

\def\dododefinecolorgroupgray         [#1][#2:#3]{\definecolor   [#1:\the\colorcount][s=#2]}
\def\dododefinecolorgrouprgb    [#1][#2:#3:#4:#5]{\definecolor   [#1:\the\colorcount][r=#2,g=#3,b=#4]}
\def\dododefinecolorgroupcmyk[#1][#2:#3:#4:#5:#6]{\definecolor   [#1:\the\colorcount][c=#2,m=#3=,y=#4,k=#5]}
\def\dododefinecolorgroupspot      [#1][#2:#3:#4]{\definespotolor[#1:\the\colorcount][#2][p=#3]}

\def\dododefinecolorgroup#1#2%
  {\advance\colorcount\plusone
   \getvalue{dododefinecolorgroup\currentcolorspace}[#1][#2:0:0:0:0]}

\def\dodefinecolorgroup[#1][#2][#3]% obsolete, just use palets
  {\ifthirdargument
     \doifelsenothing{#2}{\let\currentcolorspace\v!rgb}{\def\currentcolorspace{#2}}%
     \colorcount\zerocount
     \processcommalist[#3]{\dododefinecolorgroup{#1}}%
   \else
     \doifinstringelse{:}{#2}
       {\definecolorgroup[#1][\v!rgb][#2]}
       {\doloop
          {\doifdefinedelse{\??cr#2:\recurselevel}
             {\setevalue{\??cr#1:\recurselevel}{\csname\??cr#2:\recurselevel\endcsname}}
             {\exitloop}}}%
   \fi}

%D \macros
%D   {showcolorgroup}
%D
%D We can show the group by:
%D
%D \startbuffer
%D \showcolorgroup [blue] [horizontal,name,number,value]
%D \stopbuffer
%D
%D \typebuffer
%D
%D or in color:
%D
%D \startlinecorrection
%D \getbuffer
%D \stoplinecorrection
%D
%D which uses:
%D
%D \showsetup{showcolorgroup}

\fetchruntimecommand \showcolorgroup {\f!colorprefix\s!run}

%D There are ten predefined color groups, like
%D \color[green]{\em groen}, \color[red]{\em rood},
%D \color[blue]{\em blauw}, \color[cyan]{\em cyaan},
%D \color[magenta]{\em magenta} and \color[yellow]{\em geel}.
%D
%D \startlinecorrection
%D \hbox to \hsize
%D   {\hss
%D    \showcolorgroup [red]    [vertical,name,number]\hss
%D    \showcolorgroup [green]  [vertical,name]\hss
%D    \showcolorgroup [blue]   [vertical,name]\hss
%D    \showcolorgroup [cyan]   [vertical,name]\hss
%D    \showcolorgroup [magenta][vertical,name]\hss
%D    \showcolorgroup [yellow] [vertical,name]\hss}
%D \stoplinecorrection
%D
%D These groups are used to define palets {\em alfa} upto {\em
%D zeta}. As long as we don't use colors from the same row, we
%D get ourselves distinctive palets. By activating such a palet
%D one gains access to its members {\em top} to {\em charm} (of
%D course one should use more suitable names than these).
%D
%D \startlinecorrection
%D \hbox to \hsize
%D   {\showpalet [alfa]    [vertical,name,number]\hss
%D    \showpalet [beta]    [vertical,name]\hss
%D    \showpalet [gamma]   [vertical,name]\hss
%D    \showpalet [delta]   [vertical,name]\hss
%D    \showpalet [epsilon] [vertical,name]\hss
%D    \showpalet [zeta]    [vertical,name]}
%D \stoplinecorrection
%D
%D By using the keyword \type {value} the individual color
%D components are shown too. When printed in color, these
%D showcases show both the colors and the gray value.

%D \macros
%D   {comparepalet}
%D
%D There are some more testing macros available:
%D
%D \startbuffer
%D \comparepalet [alfa]
%D \stopbuffer
%D
%D \typebuffer
%D
%D shows the palet colors against a background:
%D
%D \startlinecorrection
%D \getbuffer
%D \stoplinecorrection
%D
%D The formal definition is:
%D
%D \showsetup{comparepalet}

\fetchruntimecommand \comparepalet {\f!colorprefix\s!run}

%D \macros
%D   {comparecolorgroup}
%D
%D The similar command:
%D
%D \startbuffer
%D \comparecolorgroup [blue]
%D \stopbuffer
%D
%D \typebuffer
%D
%D shows color groups:
%D
%D \startlinecorrection
%D \getbuffer
%D \stoplinecorrection
%D
%D this commands are defined as:
%D
%D \showsetup{comparecolorgroup}

\fetchruntimecommand \comparecolorgroup {\f!colorprefix\s!run}

%D \macros
%D   {showcolor}
%D
%D But let's not forget that we also have the more traditional
%D non||related colors. These show up after:
%D
%D \starttyping
%D \showcolor [name]
%D \stoptyping
%D
%D Where \type{name} for instance can be \type{rgb}.
%D
%D \showsetup{showcolor}

\fetchruntimecommand \showcolor {\f!colorprefix\s!run}

%D It would make sense to put the following code in \type
%D {colo-mps}, but it it rather low level.

%D \macros
%D   {negatecolorcomponent,negatedcolorcomponent}
%D
%D These speak for themselves. See \type {colo-ext} for usage.

\def\negatecolorcomponent#1% #1 = \macro
  {\scratchdimen\onepoint\advance\scratchdimen-#1\onepoint
   \ifdim\scratchdimen<\zeropoint\scratchdimen\zeropoint\fi
   \edef#1{\withoutpt\the\scratchdimen}}

\let\negatedcolorcomponent\firstofoneargument

\def\negatedcolorcomponent#1%
  {\ifdim\dimexpr\onepoint-#1\onepoint\relax<\zeropoint
     \!!zerocount
   \else
     \expandafter\withoutpt\the\dimexpr\onepoint-#1\onepoint\relax
   \fi}

\def\negatecolorcomponent#1% #1 = \macro
  {\edef#1{\negatedcolorcomponent{#1}}}

%D \macros
%D   {ifMPgraphics, ifMPcmykcolors, MPcolor}
%D
%D A very special macro is \type{\MPcolor}. This one can be
%D used to pass a \CONTEXT\ color to \METAPOST.
%D
%D \starttyping
%D \MPcolor{my own red}
%D \stoptyping
%D
%D This macro returns a \METAPOST\ triplet \type{(R,G,B)}.
%D Unless \CMYK\ color support is turned on with \type
%D {MPcmyk}, only \cap{RGB} colors and gray scales are
%D supported.

\newif\ifMPcmykcolors % \MPcmykcolorsfalse
\newif\ifMPspotcolors % \MPspotcolorsfalse

\ifx\MPcolor\undefined
    \def\MPcolor#1{(0,0,0)}
\fi

%D \macros
%D   {PDFcolor,FDFcolor}
%D
%D Similar alternatives are avaliable for \PDF:

%D For the moment we keep the next downward compatibility
%D switch, i.e.\ expanded colors. However, predefined colors
%D and palets are no longer expanded (which is what I wanted
%D in the first place).
%D
%D Well, in case we want to do color separation and use CMYK
%D colors only, this is dangerous since unwanted remapping may
%D take place. Especially when we redefine already defined
%D colors in another color space (e.g. darkgreen is
%D predefined in RGB color space, so a redefinition in CMYK
%D coordinates before RGB mode is disabled, would give
%D unexpected results due to the already frozen color spec.)
%D
%D So, from now on, colors are not frozen any more!

% \appendtoks\setupcolors[\c!expansie=\v!ja]\to\everyjob

\chardef\currentcolorchannel=0

\newif\iffilterspotcolor \filterspotcolorfalse
\newif\ifdoingspotcolor  \doingspotcolorfalse

\def\registercolorchannel#1%
  {\ifdoingspotcolor \else
     \global\expandafter\chardef\csname\??cs#1\endcsname\zerocount
   \fi}

\newif\ifhidesplitcolor \hidesplitcolortrue

%D The next macro is for instance used in figure splitting:

\def\doifseparatingcolorselse
  {\iffilterspotcolor
     \@EA\firstoftwoarguments
   \else\ifcase\currentcolorchannel
     \@EAEAEA\secondoftwoarguments
   \else
     \@EAEAEA\firstoftwoarguments
   \fi\fi}

\def\doifcolorchannelelse#1%
  {\doifseparatingcolorselse
     {\doifelsenothing{#1}
        \secondoftwoarguments
        {\doifelse{#1}\@@clsplit
           \firstoftwoarguments
           \secondoftwoarguments}}
     \secondoftwoarguments}

\def\resetcolorseparation
  {\filterspotcolorfalse
   \chardef\currentcolorchannel\zerocount}

%D These can be used in selecting specific files (like
%D figuredatabases).

% we already have:
%
% \def\colorsplitsuffix{\ifcase\currentcolorchannel\else-\@@clsplitsen\fi}
% \def\colorsplitprefix{\ifcase\currentcolorchannel\else\@@clsplitsen-\fi}

\def\colorchannelp