Curating Data – Resene and Hollasch Colors

I found some more color data that I wanted to play with. Resene paints has a whole bunch of color swatches. I found one file full of them, and the data looks like this:

Acadia                     27   20    4
Acapulco                  124  176  161
Acorn                     106   93   27
Aero Blue                 201  255  229
Affair                    113   70  147
Afghan Tan                134   86   10

When I did the SGI Colors, I used the following code, relying on the string.find() function:

parseline = function(line)
	local starting, ending, n1, n2, n3, name = line:find("%s*(%d*)%s*(%d*)%s*(%d*)%s*([%a%d%s]*)")
	return tonumber(n1), tonumber(n2), tonumber(n3), name
end

In this case, it would shift around a bit because the color name is first, rather than last on the line, but otherwise, relatively the same.

One other problem with that mechanism though is that it doesn’t deal with the space that can be found in the color’s name. So, now I have a chance to do it slightly differently. I do observe that the data is columnar. That is, all the names start at column 1, the red values start at 27, green at 32, and blue at 37. With this knowledge, I can simply use substrings:

ConvertReseneFile = function(filename)
  parseline = function(line)
    -- get name, strip whitespace
    -- make lowercase
    local name = line:sub(1,26)
    name = string.gsub(name, "%s",'')
    name = name:lower();

    -- get the numeric strings, convert to numbers
    local r = tonumber(line:sub(27,29))
    local g = tonumber(line:sub(32,34))
    local b = tonumber(line:sub(37,39))

    return name, r, g, b
  end

  io.write("local ReseneColors = {\n");
  for line in io.lines(filename) do
    local name, red,green,blue = parseline(line)
    io.write(string.format("%s = {%d, %d, %d},\n",name, red, green, blue))
  end
  io.write("}\n");
end

ConvertReseneFile("ReseneRGB.txt")

To get the name, I do the following:

    local name = line:sub(1,26)
    name = string.gsub(name, "%s",'')
    name = name:lower();

That will get 26 characters from the front of the line. Then, using ‘gsub()’, replace all the ‘space’ characters with nothing, effectively removing them. This has the effect of both trimming whitespace from the end, as well as removing intervening whitespace. Then I gratuitously convert to lowercase.

The numeric values are easy. Just get the subtext from where the number column starts, and 3 characters later. Turn it into a number explicitly, and you’re done.

Next up, Steve Hollasch colors. The raw data looks like this:

wheat             245   222   179   0.9608   0.8706   0.7020
white             255   255   255   1.0000   1.0000   1.0000
white_smoke       245   245   245   0.9608   0.9608   0.9608
zinc_white        253   248   255   0.9900   0.9700   1.0000

Greys
cold_grey         128   138   135   0.5000   0.5400   0.5300
dim_grey          105   105   105   0.4118   0.4118   0.4118

Quite similar to the Resene colors, in that it is columnar. A couple of differences though. The field names have the ‘_’ character, and the sections have a name, that I’d like to preserve as a comment. So, the conversion looks like this:

ConvertHollaschFile = function(filename)
  parseline = function(line)
    -- get name, strip whitespace
    -- make lowercase
    local name = line:sub(1,18)
    name = string.gsub(name, "%s",'')
    name = name:lower();

    -- get the numeric strings, convert to numbers
    local r = tonumber(line:sub(19,21))
    local g = tonumber(line:sub(25,27))
    local b = tonumber(line:sub(31,33))

    return name, r, g, b
  end

  io.write("local HollaschColors = {\n");
  for line in io.lines(filename) do
    local name, red,green,blue = parseline(line)
    --print(name, red, green,blue)
    if name ~= "" then
      if red and green and blue then
        io.write(string.format("%s = {%d, %d, %d},\n",name, red, green, blue))
      else
        io.write(string.format("\n-- %s\n", name);
      end
    end
  end
  io.write("}\n");
end

ConvertHollaschFile("HollaschColors.txt")

It looks almost identical to the Resene code. There’s just a little bit more in the post processing to deal with the section titles as a comment in the output.

In the end, you have tables, which can easily be converted to JSON form, or used directly as databases, or what have you, but basically you’ve curated the data and converted it into a form which is much easier to deal with programmatically.

I find this to be a strong feature of the Lua language. The string library is fairly small, but it hits just the right set of features to make it useful. There are other environments in which this small task might be equally easy to deal with, but I like this one because the whole runtime is only 300K of code. In other environments, the regular expression library alone might be that big, and the rest of the runtime might run into the multi-megabyte size. So, not bad for a few minutes of work.

Advertisements

One Comment on “Curating Data – Resene and Hollasch Colors”

  1. […] I have written about curating color data in the past: Curating Data – Resene and Hollasch Colors […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s