/rexx-parser/bin/tools/w3c_colors.cls


[Download source]
#!/usr/bin/env rexx
/**
   Purpose: ease using and converting HTML and SVG color names taking advantage of the
            public class W3C_Colors class methods

   Generated by: parse_and_create_w3c_colors.rex

   Usage 1: require 'w3c_colors.cls' and use its public class .W3C_Colors with the following class methods

            .W3C_Colors~getColorNameFromHex(someHexValue) ... returns mixed case name or .nil, if hex unknown
               someHexValue either "#rrggbb" or "#rgb"

            .W3C_Colors~getColorNameFromRGB(someRgbValue) ... returns mixed case name or .nil, if rgb unknown
               someRgbValue either "rgb(r,g,b)"
            .W3C_Colors~getColorNameFromRGB(r, g, b)      ... returns mixed case name or .nil, if rgb unknown
               r, g, b ... decimal value between 0 and 255 for red, green blue

            .W3C_Colors~getMixedCaseName(someColorName)   ... returns mixed case name or .nil, if name unknown
            .W3C_Colors~getHexValue(someColorName)        ... returns "#rrggbb" or .nil, if name unknown
            .W3C_Colors~getRgbValue(someColorName)        ... returns "rgb(r,g,b)" or .nil, if name unknown
            .W3C_Colors~isSvgColorName(someColorName)     ... returns .true if name is a SVG name,
                                                                      .false if name is not a SVG name ("RebeccaPurple")
                                                                      or .nil, if name unknown

   Usage 2: invoke as a command supplying no, one or two arguments

   @param colorname one of the W3C defined color names
   @param distance optional from colorName, distance a real number between 0 and 1, or a %
   @author  Rony G. Flatscher, Josep Maria Blasco (c) 2025
   @since   2025-06-05 - 2025-06-21
   @version 1.3

   License: AL 2.0
*/

parse source . invocationType .

if invocationType='COMMAND' then    -- invoked e.g. with "rexx w3c_colors.cls [color percentAndDistance]"
do
   if arg()>0 then   -- process arguments
   do
      if wordPos(arg(1)~upper, "? /? -H -HELP")>0 then
      do
         say .resources~usage
         exit
      end

      Parse Arg color number
      if NumberOrPercentage(number) then
      do
         Say "-------------------"
         say ".W3C_Colors~nearest(color="color", distance="number")"
         say
         .W3C_Colors~nearest( color, number )
         exit
      end

      say "usage:"
      say
      say .resources~usage
      say
      parse arg a
      say "Illegal command line argument: '"a"'"
      exit -1
   end

      -- no args supplied, demo mode; duplicate names: aqua=cyan, fuchsia=magenta, LightSlateGray=LightSlateGrey
   do counter c1 val over ('indigo','#4b0082','rgb( 75,  0,130)'), -
                          ('rebeccapurple',"#639"   , "rgb(102, 51,153)"), -
                          ('NavajoWhite', '#ffdead', (255, 222, 173)),      /*
                             the following hex values have duplicate names: */ -
                          ("aqua", "#0ff", "rgb(  0,255,255)")
      name=val[1]
      hex =val[2]
      rgb =val[3]
      if rgb~isA(.array) then strRgb=rgb~toString(,',')
                         else strRgb=rgb
      say "- round #" c1":" "testing color:" name "hex="hex "rgb="strRgb
      say
      hint=""
      if hex~length=4 then hint=" --> note: hex value has only three hex digits"
         -- also accepts single hexadecimal numbers per color: "#rgb" ("#rrggbb" gets looked up)
      sp="  "
      say sp ".W3C_Colors~getColorNameFromHex("""hex""")"hint":"
      say sp "  " hex":" .W3C_Colors~getColorNameFromHex(hex)
      say sp "  " hex~upper":" .W3C_Colors~getColorNameFromHex(hex~upper) "(key: hex~upper)"
      say
         -- either "rgb(r,g,b)" or three arguments of "r,g,b"
      say sp ".W3C_Colors~getColorNameFromRGB("""strRgb"""):"
      if rgb~isA(.array) then
      do
         colorName=.W3C_Colors~getColorNameFromRGB(rgb[1], rgb[2], rgb[3])
         rgb=rgb[1]","rgb[2]","rgb[3]
      end
      else
         colorName=.W3C_Colors~getColorNameFromRGB(rgb)
      say sp "  " rgb":" colorName
      say sp "  " rgb~upper":" .W3C_Colors~getColorNameFromRGB(rgb~upper) "(key: rgb~upper)"
      say
      say sp ".W3C_Colors~getMixedCaseName(name="""name"""):"
      say sp "  " name":" .W3C_Colors~getMixedCaseName(name)
      say sp "  " name~upper":" .W3C_Colors~getMixedCaseName(name~upper) "(key: name~upper)"
      say
      say sp ".W3C_Colors~getHexValue(name="""name"""):"
      say sp "  " name":" .W3C_Colors~getHexValue(name)
      say sp "  " name~upper":" .W3C_Colors~getHexValue(name~upper) "(key: name~upper)"
      say
      say sp ".W3C_Colors~getRgbValue(name="""name"""):"
      say sp "  " name":" .W3C_Colors~getRgbValue(name)
      say sp "  " name~upper":" .W3C_Colors~getRgbValue(name~upper) "(key: name~upper)"
      say
      say sp ".W3C_Colors~isSvgColorName(name="""name"""):" (name="rebeccapurple")~?("(not a SVG colorname!)","")
      say sp "  " name":" .W3C_Colors~isSvgColorName(name)
      say sp "  " name~upper":" .W3C_Colors~isSvgColorName(name~upper) "(key: name~upper)"
      say

      Say "="~copies(9)
      number="10%"
      Say "="~copies(9)
      say ".W3C_Colors~nearest(color="name", distance="number")"
      .W3C_Colors~nearest(name,number)
      Say "="~copies(79)
      say
   end

   say
   say "Usage:"
   say .resources~usage
   exit
end

Return

NumberOrPercentage:
  Parse Arg NorP
  If DataType(NorP, "NUM") Then Return 1
  If Right(NorP,1) \== "%" Then Return 0
  NorP = Left(NorP,Length(NorP)-1)
  If DataType(NorP, "NUM") Then Return 1
Return 0


/* ========================================================================= */

::Requires "sRGB.cls" -- requires 'rxmath' library, hence available to us

/** Utility routine that processes the color argument and returns its blank delimited decimal values "r g b".
 *  @param  colorArg #hex, hex, rgb(r,g,b), colorName
 *  @return blank delimited rgb decimal value
*/
::routine processColorArg
  parse upper arg colorArg

  If colorArg[1] = "#" Then colorArg = SubStr(colorArg, 2) -- Allow "abc" and "#abc", etc.
  if datatype(colorArg, 'X') then
  do
     If Length(colorArg) = 3 Then Do
       Parse Var colorArg a +1 b +1 c +1
       colorArg = Space( a a b b c c, 0 )
     End
     parse var colorArg r +2 g +2 b +2
     return r~x2d g~x2d b~x2d
  end

  rgb=.w3c_colors~getRgbValue(colorArg)   --  a colorName in hand?
  if rgb\==.nil then colorArg=rgb~upper

  if colorArg~startsWith('RGB(') then
  do
     parse caseless var colorArg 'RGB(' r ',' g ',' b ')'
     return space(r g b, 1)
  end

  -- invalid argument
  raise syntax 40.904 array ("processColorArg", 1, "#hex, hex, rgb(r,g,b), colorname", arg(1))


/** Utility class to ease conversion between colors (color name, hex or rgb values) and their
 *  nearest W3C color names.
 */
::class  W3C_Colors  public   -- maintain W3C (HTML, also SVG) color names with their hex and rgb values

/** Displays the W3C colornames for the supplied color that are within the given OKLab
 *  distance.
 *  @author Josep Maria Blasco
 *  @param color a color definition which can be a hex, an rgb or a color name value
 *  @param maxDistance the maximum OkLab distance of the resulting color names (max is 1), or a percentage ending with "%"
 */
::Method nearest Class
  Expose clrName2all
  Use Arg color, maxDistance = 0.0023 -- Minimum noticeable difference

  If Right(maxDistance,1) == "%" Then Do
    maxDistance = Left(maxDistance,Length(maxDistance)-1)
    maxDistance = maxDistance / 100
  End

  rgb=processColorArg(color)
  parse var rgb x1 y1 z1

  colorName = .w3c_colors~getColorNameFromRGB(x1, y1, z1)
  str = "Computing W3C colors nearest to '"arg(1)"'"
  if colorName \== .nil then str = str "('"colorName"')"
  Say str "with a OKLab ΔE distance of up to" maxDistance~strip
  Say

  from = .sRGB~new(x1 y1 z1)

  Do With Item item Over clrName2all
    Parse Value item[2] With +1 x2 +2 y2 +2 z2 +2
    x2 = X2D(x2)
    y2 = X2D(y2)
    z2 = X2D(z2)
    to = .sRGB~new(x2 y2 z2)

    distance = from~deltaEOK( to )

    If distance <= maxDistance Then Do
      Say "Found" Left(item[1],21)"["item[2]"]: Distance=" Format(distance,3,4)
    End
  End

/** Class constructor that initializes class attributes. */
::method init        class
  expose clrName2all hex2colorName rgb2colorName
  -- creates four StringTables to manage HTML and SVG color names
  clrName2all        = .stringTable~new   -- COLORNAME -> [properName,hex,rgb,svg_rgb]
  self~fillStringTables       -- fill the string tables

      /* create two additional utility StringTables for support hex->colorName and rgb->colorName,
         duplicate W3C colornames for same hex value:
         #00ffff -> Aqua, Cyan: return Cyan in getColorNameFromHex|Rgb()
         #ff00ff -> Fuchsia, Magenta: return Magenta in getColorNameFromHex|Rgb()
         #778899 -> LightSlateGray, LightSlateGrey: return LightSlateGrey in getColorNameFromHex|Rgb()
      */

  hex2colorName = .stringTable~new
  rgb2colorName = .stringTable~new
  do colorName over clrName2all
     mixedColorName=clrName2all[colorName][1]

     hex=clrName2all[colorName][2]
     -- hex2colorName[hex      ]=mixedColorName
     if wordPos(mixedColorName, "Aqua Fuchsia LightSlateGray")=0 then
     do
        hex2colorName[hex~upper]=mixedColorName
        rgb=clrName2all[colorName][3]
        -- rgb2colorName[rgb~space(0)      ]=mixedColorName
     end
     rgb2colorName[rgb~space(0)~upper]=mixedColorName
  end


/** Returns the colorname for the supplied hex value.
 *  @param hex a color definition defined in hex
 *  @return returns the colorname of the supplied color or <pre>.nil</pre> if there is no matching colorname
 */
::method getColorNameFromHex  class -- return color name in mixed case, or .nil if not defined
  expose hex2colorName
  parse upper arg hex .
  hex=hex~space(0)
  if hex~length=4 then     -- something like #abc instead of #aabbcc
  do
     parse var hex x +1 r +1 g +1 b +1
     hex=x || r || r || g || g || b || b
  end
  return hex2colorName[hex]

/** Returns the colorname for the supplied rgb value.
 *  @param rgb a color definition defined in rgb
 *  @return returns the colorname of the supplied color or <pre>.nil</pre> if there is no matching colorname
 */
::method getColorNameFromRGB  class -- return color name in mixed case, or .nil if not defined
  expose rgb2colorName
  if arg()=3 then
  do
     use strict arg r, g, b
     rgb="RGB("r","g","||b")"
  end
  else
     parse upper arg rgb
  return rgb2colorName[rgb~space(0)]

/** Returns the mixed case W3C colorname for the supplied W3C colorname.
 *  @param colorname the colorname to be translated to mixed case
 *  @return returns the mixed case colorname or <pre>.nil</pre> if the colorname is unknown
 */
::method getMixedCaseName  class    -- returns mixed case name for the color name, or .nil if not defined
  expose clrName2all
  parse upper arg colorName .
  arr=clrName2all[colorName]
  if arr==.nil then return .nil     -- unknown color
  return arr[1]

/** Returns the hex value for the supplied W3C colorname.
 *  @param colorname the W3C colorname to be translated into hex
 *  @return returns the hex value of the supplied colorname or <pre>.nil</pre> if the colorname is unknown
 */
::method getHexValue class          -- returns the hex value for the color name "#rrggbb", or .nil if not defined
  expose clrName2all
  parse upper arg colorName .
  arr=clrName2all[colorName]
  if arr==.nil then return .nil     -- unknown color
  return arr[2]

/** Returns the rgb value for the supplied W3C colorname.
 *  @param colorname the W3C colorname to be translated into rgb
 *  @return returns the rgb value of the supplied colorname or <pre>.nil</pre> if the colorname is unknown
 */
::method getRgbValue class          -- returns the rgb value for the color name "rgb(r, g, b)", or .nil if not defined
  expose clrName2all
  parse upper arg colorName .
  arr=clrName2all[colorName]
  if arr==.nil then return .nil     -- unknown color
  return arr[3]

/** Returns <pre>.true</pre> if the supplied W3C colorname is also a SVG name, <pre>.false</pre> else
 *  @param colorname the W3C colorname to be checked
 *  @return returns <pre>.true</pre> if the supplied W3C colorname is also a SVG name, <pre>.false</pre> else
 */
   -- note: SVG does not have the W3C color name "REBECCAPURPLE" defined
::method isSvgColorName class       -- returns .true, if color is an SVG color, .false else (has no RebeccaPurple), or .nil if not defined
  expose clrName2all
  parse upper arg colorName .
  arr=clrName2all[colorName]
  if arr==.nil then return .nil     -- unknown color
  return arr[4]

/** Class method that fills the stringTable attribute <pre>clrName2all</pre> with the
 *  HTML and SVG colorname definitions in hex and rgb, as well as their mixed case name.
 */
::method fillStringTables  class private  -- code will be created and appended by this utility, or .nil if not defined
  expose clrName2all

  -- W3C color definitions: COLORNAME -> .array~of(mixedColorName, hex, rgb, isSVGcolorname)

     clrName2all["ALICEBLUE"           ] = ("AliceBlue"           , "#f0f8ff", "rgb(240,248,255)", .true )
     clrName2all["ANTIQUEWHITE"        ] = ("AntiqueWhite"        , "#faebd7", "rgb(250,235,215)", .true )
     clrName2all["AQUA"                ] = ("Aqua"                , "#00ffff", "rgb(  0,255,255)", .true )
     clrName2all["AQUAMARINE"          ] = ("Aquamarine"          , "#7fffd4", "rgb(127,255,212)", .true )
     clrName2all["AZURE"               ] = ("Azure"               , "#f0ffff", "rgb(240,255,255)", .true )
     clrName2all["BEIGE"               ] = ("Beige"               , "#f5f5dc", "rgb(245,245,220)", .true )
     clrName2all["BISQUE"              ] = ("Bisque"              , "#ffe4c4", "rgb(255,228,196)", .true )
     clrName2all["BLACK"               ] = ("Black"               , "#000000", "rgb(  0,  0,  0)", .true )
     clrName2all["BLANCHEDALMOND"      ] = ("BlanchedAlmond"      , "#ffebcd", "rgb(255,235,205)", .true )
     clrName2all["BLUE"                ] = ("Blue"                , "#0000ff", "rgb(  0,  0,255)", .true )
     clrName2all["BLUEVIOLET"          ] = ("BlueViolet"          , "#8a2be2", "rgb(138, 43,226)", .true )
     clrName2all["BROWN"               ] = ("Brown"               , "#a52a2a", "rgb(165, 42, 42)", .true )
     clrName2all["BURLYWOOD"           ] = ("BurlyWood"           , "#deb887", "rgb(222,184,135)", .true )
     clrName2all["CADETBLUE"           ] = ("CadetBlue"           , "#5f9ea0", "rgb( 95,158,160)", .true )
     clrName2all["CHARTREUSE"          ] = ("Chartreuse"          , "#7fff00", "rgb(127,255,  0)", .true )
     clrName2all["CHOCOLATE"           ] = ("Chocolate"           , "#d2691e", "rgb(210,105, 30)", .true )
     clrName2all["CORAL"               ] = ("Coral"               , "#ff7f50", "rgb(255,127, 80)", .true )
     clrName2all["CORNFLOWERBLUE"      ] = ("CornflowerBlue"      , "#6495ed", "rgb(100,149,237)", .true )
     clrName2all["CORNSILK"            ] = ("Cornsilk"            , "#fff8dc", "rgb(255,248,220)", .true )
     clrName2all["CRIMSON"             ] = ("Crimson"             , "#dc143c", "rgb(220, 20, 60)", .true )
     clrName2all["CYAN"                ] = ("Cyan"                , "#00ffff", "rgb(  0,255,255)", .true )
     clrName2all["DARKBLUE"            ] = ("DarkBlue"            , "#00008b", "rgb(  0,  0,139)", .true )
     clrName2all["DARKCYAN"            ] = ("DarkCyan"            , "#008b8b", "rgb(  0,139,139)", .true )
     clrName2all["DARKGOLDENROD"       ] = ("DarkGoldenRod"       , "#b8860b", "rgb(184,134, 11)", .true )
     clrName2all["DARKGRAY"            ] = ("DarkGray"            , "#a9a9a9", "rgb(169,169,169)", .true )
     clrName2all["DARKGREEN"           ] = ("DarkGreen"           , "#006400", "rgb(  0,100,  0)", .true )
     clrName2all["DARKGREY"            ] = ("DarkGrey"            , "#a9a9a9", "rgb(169,169,169)", .true )
     clrName2all["DARKKHAKI"           ] = ("DarkKhaki"           , "#bdb76b", "rgb(189,183,107)", .true )
     clrName2all["DARKMAGENTA"         ] = ("DarkMagenta"         , "#8b008b", "rgb(139,  0,139)", .true )
     clrName2all["DARKOLIVEGREEN"      ] = ("DarkOliveGreen"      , "#556b2f", "rgb( 85,107, 47)", .true )
     clrName2all["DARKORANGE"          ] = ("DarkOrange"          , "#ff8c00", "rgb(255,140,  0)", .true )
     clrName2all["DARKORCHID"          ] = ("DarkOrchid"          , "#9932cc", "rgb(153, 50,204)", .true )
     clrName2all["DARKRED"             ] = ("DarkRed"             , "#8b0000", "rgb(139,  0,  0)", .true )
     clrName2all["DARKSALMON"          ] = ("DarkSalmon"          , "#e9967a", "rgb(233,150,122)", .true )
     clrName2all["DARKSEAGREEN"        ] = ("DarkSeaGreen"        , "#8fbc8f", "rgb(143,188,143)", .true )
     clrName2all["DARKSLATEBLUE"       ] = ("DarkSlateBlue"       , "#483d8b", "rgb( 72, 61,139)", .true )
     clrName2all["DARKSLATEGRAY"       ] = ("DarkSlateGray"       , "#2f4f4f", "rgb( 47, 79, 79)", .true )
     clrName2all["DARKSLATEGREY"       ] = ("DarkSlateGrey"       , "#2f4f4f", "rgb( 47, 79, 79)", .true )
     clrName2all["DARKTURQUOISE"       ] = ("DarkTurquoise"       , "#00ced1", "rgb(  0,206,209)", .true )
     clrName2all["DARKVIOLET"          ] = ("DarkViolet"          , "#9400d3", "rgb(148,  0,211)", .true )
     clrName2all["DEEPPINK"            ] = ("DeepPink"            , "#ff1493", "rgb(255, 20,147)", .true )
     clrName2all["DEEPSKYBLUE"         ] = ("DeepSkyBlue"         , "#00bfff", "rgb(  0,191,255)", .true )
     clrName2all["DIMGRAY"             ] = ("DimGray"             , "#696969", "rgb(105,105,105)", .true )
     clrName2all["DIMGREY"             ] = ("DimGrey"             , "#696969", "rgb(105,105,105)", .true )
     clrName2all["DODGERBLUE"          ] = ("DodgerBlue"          , "#1e90ff", "rgb( 30,144,255)", .true )
     clrName2all["FIREBRICK"           ] = ("FireBrick"           , "#b22222", "rgb(178, 34, 34)", .true )
     clrName2all["FLORALWHITE"         ] = ("FloralWhite"         , "#fffaf0", "rgb(255,250,240)", .true )
     clrName2all["FORESTGREEN"         ] = ("ForestGreen"         , "#228b22", "rgb( 34,139, 34)", .true )
     clrName2all["FUCHSIA"             ] = ("Fuchsia"             , "#ff00ff", "rgb(255,  0,255)", .true )
     clrName2all["GAINSBORO"           ] = ("Gainsboro"           , "#dcdcdc", "rgb(220,220,220)", .true )
     clrName2all["GHOSTWHITE"          ] = ("GhostWhite"          , "#f8f8ff", "rgb(248,248,255)", .true )
     clrName2all["GOLD"                ] = ("Gold"                , "#ffd700", "rgb(255,215,  0)", .true )
     clrName2all["GOLDENROD"           ] = ("GoldenRod"           , "#daa520", "rgb(218,165, 32)", .true )
     clrName2all["GRAY"                ] = ("Gray"                , "#808080", "rgb(128,128,128)", .true )
     clrName2all["GREEN"               ] = ("Green"               , "#008000", "rgb(  0,128,  0)", .true )
     clrName2all["GREENYELLOW"         ] = ("GreenYellow"         , "#adff2f", "rgb(173,255, 47)", .true )
     clrName2all["GREY"                ] = ("Grey"                , "#808080", "rgb(128,128,128)", .true )
     clrName2all["HONEYDEW"            ] = ("HoneyDew"            , "#f0fff0", "rgb(240,255,240)", .true )
     clrName2all["HOTPINK"             ] = ("HotPink"             , "#ff69b4", "rgb(255,105,180)", .true )
     clrName2all["INDIANRED"           ] = ("IndianRed"           , "#cd5c5c", "rgb(205, 92, 92)", .true )
     clrName2all["INDIGO"              ] = ("Indigo"              , "#4b0082", "rgb( 75,  0,130)", .true )
     clrName2all["IVORY"               ] = ("Ivory"               , "#fffff0", "rgb(255,255,240)", .true )
     clrName2all["KHAKI"               ] = ("Khaki"               , "#f0e68c", "rgb(240,230,140)", .true )
     clrName2all["LAVENDER"            ] = ("Lavender"            , "#e6e6fa", "rgb(230,230,250)", .true )
     clrName2all["LAVENDERBLUSH"       ] = ("LavenderBlush"       , "#fff0f5", "rgb(255,240,245)", .true )
     clrName2all["LAWNGREEN"           ] = ("LawnGreen"           , "#7cfc00", "rgb(124,252,  0)", .true )
     clrName2all["LEMONCHIFFON"        ] = ("LemonChiffon"        , "#fffacd", "rgb(255,250,205)", .true )
     clrName2all["LIGHTBLUE"           ] = ("LightBlue"           , "#add8e6", "rgb(173,216,230)", .true )
     clrName2all["LIGHTCORAL"          ] = ("LightCoral"          , "#f08080", "rgb(240,128,128)", .true )
     clrName2all["LIGHTCYAN"           ] = ("LightCyan"           , "#e0ffff", "rgb(224,255,255)", .true )
     clrName2all["LIGHTGOLDENRODYELLOW"] = ("LightGoldenRodYellow", "#fafad2", "rgb(250,250,210)", .true )
     clrName2all["LIGHTGRAY"           ] = ("LightGray"           , "#d3d3d3", "rgb(211,211,211)", .true )
     clrName2all["LIGHTGREEN"          ] = ("LightGreen"          , "#90ee90", "rgb(144,238,144)", .true )
     clrName2all["LIGHTGREY"           ] = ("LightGrey"           , "#d3d3d3", "rgb(211,211,211)", .true )
     clrName2all["LIGHTPINK"           ] = ("LightPink"           , "#ffb6c1", "rgb(255,182,193)", .true )
     clrName2all["LIGHTSALMON"         ] = ("LightSalmon"         , "#ffa07a", "rgb(255,160,122)", .true )
     clrName2all["LIGHTSEAGREEN"       ] = ("LightSeaGreen"       , "#20b2aa", "rgb( 32,178,170)", .true )
     clrName2all["LIGHTSKYBLUE"        ] = ("LightSkyBlue"        , "#87cefa", "rgb(135,206,250)", .true )
     clrName2all["LIGHTSLATEGRAY"      ] = ("LightSlateGray"      , "#778899", "rgb(119,136,153)", .true )
     clrName2all["LIGHTSLATEGREY"      ] = ("LightSlateGrey"      , "#778899", "rgb(119,136,153)", .true )
     clrName2all["LIGHTSTEELBLUE"      ] = ("LightSteelBlue"      , "#b0c4de", "rgb(176,196,222)", .true )
     clrName2all["LIGHTYELLOW"         ] = ("LightYellow"         , "#ffffe0", "rgb(255,255,224)", .true )
     clrName2all["LIME"                ] = ("Lime"                , "#00ff00", "rgb(  0,255,  0)", .true )
     clrName2all["LIMEGREEN"           ] = ("LimeGreen"           , "#32cd32", "rgb( 50,205, 50)", .true )
     clrName2all["LINEN"               ] = ("Linen"               , "#faf0e6", "rgb(250,240,230)", .true )
     clrName2all["MAGENTA"             ] = ("Magenta"             , "#ff00ff", "rgb(255,  0,255)", .true )
     clrName2all["MAROON"              ] = ("Maroon"              , "#800000", "rgb(128,  0,  0)", .true )
     clrName2all["MEDIUMAQUAMARINE"    ] = ("MediumAquaMarine"    , "#66cdaa", "rgb(102,205,170)", .true )
     clrName2all["MEDIUMBLUE"          ] = ("MediumBlue"          , "#0000cd", "rgb(  0,  0,205)", .true )
     clrName2all["MEDIUMORCHID"        ] = ("MediumOrchid"        , "#ba55d3", "rgb(186, 85,211)", .true )
     clrName2all["MEDIUMPURPLE"        ] = ("MediumPurple"        , "#9370db", "rgb(147,112,219)", .true )
     clrName2all["MEDIUMSEAGREEN"      ] = ("MediumSeaGreen"      , "#3cb371", "rgb( 60,179,113)", .true )
     clrName2all["MEDIUMSLATEBLUE"     ] = ("MediumSlateBlue"     , "#7b68ee", "rgb(123,104,238)", .true )
     clrName2all["MEDIUMSPRINGGREEN"   ] = ("MediumSpringGreen"   , "#00fa9a", "rgb(  0,250,154)", .true )
     clrName2all["MEDIUMTURQUOISE"     ] = ("MediumTurquoise"     , "#48d1cc", "rgb( 72,209,204)", .true )
     clrName2all["MEDIUMVIOLETRED"     ] = ("MediumVioletRed"     , "#c71585", "rgb(199, 21,133)", .true )
     clrName2all["MIDNIGHTBLUE"        ] = ("MidnightBlue"        , "#191970", "rgb( 25, 25,112)", .true )
     clrName2all["MINTCREAM"           ] = ("MintCream"           , "#f5fffa", "rgb(245,255,250)", .true )
     clrName2all["MISTYROSE"           ] = ("MistyRose"           , "#ffe4e1", "rgb(255,228,225)", .true )
     clrName2all["MOCCASIN"            ] = ("Moccasin"            , "#ffe4b5", "rgb(255,228,181)", .true )
     clrName2all["NAVAJOWHITE"         ] = ("NavajoWhite"         , "#ffdead", "rgb(255,222,173)", .true )
     clrName2all["NAVY"                ] = ("Navy"                , "#000080", "rgb(  0,  0,128)", .true )
     clrName2all["OLDLACE"             ] = ("OldLace"             , "#fdf5e6", "rgb(253,245,230)", .true )
     clrName2all["OLIVE"               ] = ("Olive"               , "#808000", "rgb(128,128,  0)", .true )
     clrName2all["OLIVEDRAB"           ] = ("OliveDrab"           , "#6b8e23", "rgb(107,142, 35)", .true )
     clrName2all["ORANGE"              ] = ("Orange"              , "#ffa500", "rgb(255,165,  0)", .true )
     clrName2all["ORANGERED"           ] = ("OrangeRed"           , "#ff4500", "rgb(255, 69,  0)", .true )
     clrName2all["ORCHID"              ] = ("Orchid"              , "#da70d6", "rgb(218,112,214)", .true )
     clrName2all["PALEGOLDENROD"       ] = ("PaleGoldenRod"       , "#eee8aa", "rgb(238,232,170)", .true )
     clrName2all["PALEGREEN"           ] = ("PaleGreen"           , "#98fb98", "rgb(152,251,152)", .true )
     clrName2all["PALETURQUOISE"       ] = ("PaleTurquoise"       , "#afeeee", "rgb(175,238,238)", .true )
     clrName2all["PALEVIOLETRED"       ] = ("PaleVioletRed"       , "#db7093", "rgb(219,112,147)", .true )
     clrName2all["PAPAYAWHIP"          ] = ("PapayaWhip"          , "#ffefd5", "rgb(255,239,213)", .true )
     clrName2all["PEACHPUFF"           ] = ("PeachPuff"           , "#ffdab9", "rgb(255,218,185)", .true )
     clrName2all["PERU"                ] = ("Peru"                , "#cd853f", "rgb(205,133, 63)", .true )
     clrName2all["PINK"                ] = ("Pink"                , "#ffc0cb", "rgb(255,192,203)", .true )
     clrName2all["PLUM"                ] = ("Plum"                , "#dda0dd", "rgb(221,160,221)", .true )
     clrName2all["POWDERBLUE"          ] = ("PowderBlue"          , "#b0e0e6", "rgb(176,224,230)", .true )
     clrName2all["PURPLE"              ] = ("Purple"              , "#800080", "rgb(128,  0,128)", .true )
     clrName2all["REBECCAPURPLE"       ] = ("RebeccaPurple"       , "#663399", "rgb(102, 51,153)", .false)
     clrName2all["RED"                 ] = ("Red"                 , "#ff0000", "rgb(255,  0,  0)", .true )
     clrName2all["ROSYBROWN"           ] = ("RosyBrown"           , "#bc8f8f", "rgb(188,143,143)", .true )
     clrName2all["ROYALBLUE"           ] = ("RoyalBlue"           , "#4169e1", "rgb( 65,105,225)", .true )
     clrName2all["SADDLEBROWN"         ] = ("SaddleBrown"         , "#8b4513", "rgb(139, 69, 19)", .true )
     clrName2all["SALMON"              ] = ("Salmon"              , "#fa8072", "rgb(250,128,114)", .true )
     clrName2all["SANDYBROWN"          ] = ("SandyBrown"          , "#f4a460", "rgb(244,164, 96)", .true )
     clrName2all["SEAGREEN"            ] = ("SeaGreen"            , "#2e8b57", "rgb( 46,139, 87)", .true )
     clrName2all["SEASHELL"            ] = ("SeaShell"            , "#fff5ee", "rgb(255,245,238)", .true )
     clrName2all["SIENNA"              ] = ("Sienna"              , "#a0522d", "rgb(160, 82, 45)", .true )
     clrName2all["SILVER"              ] = ("Silver"              , "#c0c0c0", "rgb(192,192,192)", .true )
     clrName2all["SKYBLUE"             ] = ("SkyBlue"             , "#87ceeb", "rgb(135,206,235)", .true )
     clrName2all["SLATEBLUE"           ] = ("SlateBlue"           , "#6a5acd", "rgb(106, 90,205)", .true )
     clrName2all["SLATEGRAY"           ] = ("SlateGray"           , "#708090", "rgb(112,128,144)", .true )
     clrName2all["SLATEGREY"           ] = ("SlateGrey"           , "#708090", "rgb(112,128,144)", .true )
     clrName2all["SNOW"                ] = ("Snow"                , "#fffafa", "rgb(255,250,250)", .true )
     clrName2all["SPRINGGREEN"         ] = ("SpringGreen"         , "#00ff7f", "rgb(  0,255,127)", .true )
     clrName2all["STEELBLUE"           ] = ("SteelBlue"           , "#4682b4", "rgb( 70,130,180)", .true )
     clrName2all["TAN"                 ] = ("Tan"                 , "#d2b48c", "rgb(210,180,140)", .true )
     clrName2all["TEAL"                ] = ("Teal"                , "#008080", "rgb(  0,128,128)", .true )
     clrName2all["THISTLE"             ] = ("Thistle"             , "#d8bfd8", "rgb(216,191,216)", .true )
     clrName2all["TOMATO"              ] = ("Tomato"              , "#ff6347", "rgb(255, 99, 71)", .true )
     clrName2all["TURQUOISE"           ] = ("Turquoise"           , "#40e0d0", "rgb( 64,224,208)", .true )
     clrName2all["VIOLET"              ] = ("Violet"              , "#ee82ee", "rgb(238,130,238)", .true )
     clrName2all["WHEAT"               ] = ("Wheat"               , "#f5deb3", "rgb(245,222,179)", .true )
     clrName2all["WHITE"               ] = ("White"               , "#ffffff", "rgb(255,255,255)", .true )
     clrName2all["WHITESMOKE"          ] = ("WhiteSmoke"          , "#f5f5f5", "rgb(245,245,245)", .true )
     clrName2all["YELLOW"              ] = ("Yellow"              , "#ffff00", "rgb(255,255,  0)", .true )
     clrName2all["YELLOWGREEN"         ] = ("YellowGreen"         , "#9acd32", "rgb(154,205, 50)", .true )


/** Defines the usage information for this Rexx pacakge. */
::resource usage
w3c_colors.cls ... utility for dealing with W3C colors

   usage 1 (requires directive in a program):

            ::requires "w3c_colors.cls"

     ... requires "sRGB.cls" and as a result makes the public class W3C_Colors with its class
         methods available, as well as the DeltaEOK method of the sRGB class and other conversion
         methods, for example sRGB to linear RGB, XYZ and OKLab.

   usage 2: rexx w3c_colors.cls [color percent]

     ... with no argument the .W3C_Colors' class methods get demonstrated
     ... with exactly two arguments, 'color percentOrDistance' the method DeltaEOK() of the sRGB class
         gets demonstrated, where color could be a w3c color name, hex, or rgb, e.g.

         rexx w3c_colors.cls thistle 16
::END