# Write a list from "munsell"

I have never used R before, and I am after the hex codes from library("munsell"). I have skimmed through the notes, but have resorted to the following tedious method:

mnsl(seq_mnsl("2.5R 1/2", "2.5R 9/2", 9))
mnsl(seq_mnsl("2.5R 1/4", "2.5R 8/4", 8))
mnsl(seq_mnsl("2.5R 1/6", "2.5R 8/6", 8))
mnsl(seq_mnsl("2.5R 2/8", "2.5R 7/8", 6))
mnsl(seq_mnsl("2.5R 3/10", "2.5R 7/10", 5))
mnsl(seq_mnsl("2.5R 4/12", "2.5R 6/12", 3))
mnsl(seq_mnsl("2.5R 4/14", "2.5R 6/14", 3))
mnsl("2.5R 5/16")

this is clearly not a good way to get the codes. Please could someone help me to export a full list for all 40 hues?

The tedium can be reduced, somewhat. {munsell} exposes 40 hues:

library(munsell)
mnsl_hues()
#>  [1] "2.5R"  "5R"    "7.5R"  "10R"   "2.5YR" "5YR"   "7.5YR" "10YR"  "2.5Y"
#> [10] "5Y"    "7.5Y"  "10Y"   "2.5GY" "5GY"   "7.5GY" "10GY"  "2.5G"  "5G"
#> [19] "7.5G"  "10G"   "2.5BG" "5BG"   "7.5BG" "10BG"  "2.5B"  "5B"    "7.5B"
#> [28] "10B"   "2.5PB" "5PB"   "7.5PB" "10PB"  "2.5P"  "5P"    "7.5P"  "10P"
#> [37] "2.5RP" "5RP"   "7.5RP" "10RP"

However, hues differ in the distinctions that the encoding system makes:

library(munsell)
hue_slice(hue.name = "all", back.col = "white")

As a consequence, the number of times that mnsl(seq_mnsl() can be called with different values of of the \dots parameter varies, because

Not all possible correctly formatted Munsell colours result in a colour representable in RGB space.

For example,

library(munsell)
in_gamut(c("5R 5/8","2.5R 9/28"), fix = TRUE)
#> [1] "5R 5/8"   "2.5R 9/2"

For the case in the OP example for 2.5R, there's no problem in automating

library(munsell)
by_hand <- c(mnsl(seq_mnsl("2.5R 1/2", "2.5R 9/2", 9)),
mnsl(seq_mnsl("2.5R 1/4", "2.5R 8/4", 8)),
mnsl(seq_mnsl("2.5R 1/6", "2.5R 8/6", 8)),
mnsl(seq_mnsl("2.5R 2/8", "2.5R 7/8", 6)),
mnsl(seq_mnsl("2.5R 3/10", "2.5R 7/10", 5)),
mnsl(seq_mnsl("2.5R 4/12", "2.5R 6/12", 3)),
mnsl(seq_mnsl("2.5R 4/14", "2.5R 6/14", 3)),
mnsl("2.5R 5/16"))

by_hand
#>  [1] "#2D161E" "#412C32" "#58424B" "#715C63" "#8A767A" "#A39094" "#BDABAE"
#>  [8] "#D7C6C6" "#F2E2E2" "#360E1F" "#4C2533" "#5B4246" "#7F5561" "#9A7075"
#> [15] "#B48A8F" "#D0A5A5" "#EBC0BF" "#3E0320" "#551E34" "#683B45" "#825558"
#> [22] "#A96973" "#C4848C" "#E09EA0" "#FDB9BA" "#610E2E" "#75333D" "#9B4559"
#> [29] "#B76170" "#D27D81" "#F0979A" "#8C1737" "#A73B4D" "#C55864" "#E0747C"
#> [36] "#FE8F95" "#B22D4A" "#D24C60" "#ED6B78" "#BE1547" "#DC405D" "#F96174"
#> [43] "#E72D5A"

# get list of hues

hues  <- mnsl_hues()

hues
#>  [1] "2.5R"  "5R"    "7.5R"  "10R"   "2.5YR" "5YR"   "7.5YR" "10YR"  "2.5Y"
#> [10] "5Y"    "7.5Y"  "10Y"   "2.5GY" "5GY"   "7.5GY" "10GY"  "2.5G"  "5G"
#> [19] "7.5G"  "10G"   "2.5BG" "5BG"   "7.5BG" "10BG"  "2.5B"  "5B"    "7.5B"
#> [28] "10B"   "2.5PB" "5PB"   "7.5PB" "10PB"  "2.5P"  "5P"    "7.5P"  "10P"
#> [37] "2.5RP" "5RP"   "7.5RP" "10RP"

# construct pieces for arguments to seq_mnsl

nume1 <- c(1,1,1,2,3,4,4,5)
nume2 <- c(9,8,8,7,7,6,6,5)
denom <- seq(2,16,2)

# lengths of seq_mnsl

outs   <- c(9,8,8,6,6,3,3,1)

# number of seq_mnsl call per hue

runs <- length(outs)

# create first argument to seq_mnsl

get_start <- function(x,y) paste0(hues[x]," ",nume1[y],"/",denom[y])

# create second argument to seq_mnsl

get_end   <- function(x,y) paste0(hues[x]," ",nume2[y],"/",denom[y])

# display the results for a single hue

show_hues <- function(x,y) mnsl(seq_mnsl(get_start(x,y), get_end(x,y), outs[y]), fix = TRUE)

show_hues(1,1) == by_hand[1:9]
#> [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
show_hues(1,2) == by_hand[10:17]
#> [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
show_hues(1,3) == by_hand[18:25]
#> [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
show_hues(1,4) == by_hand[26:31]
#> [1] TRUE TRUE TRUE TRUE TRUE TRUE
show_hues(1,5) == by_hand[32:36]
#> Warning in show_hues(1, 5) == by_hand[32:36]: longer object length is not a
#> multiple of shorter object length
#> [1]  TRUE  TRUE  TRUE FALSE FALSE FALSE
show_hues(1,6) == by_hand[37:39]
#> [1] TRUE TRUE TRUE
show_hues(1,7) == by_hand[40:42]
#> [1] TRUE TRUE TRUE
show_hues(1,8) == by_hand[43]
#> [1] TRUE

The problem comes when trying to feed all forty colors through the show_hue function, which assumes that the third arguments will work for each of them.

It's possible to write a chain of functions that would check each of the hues to find out how may hexes it supports, but that is probably more trouble than doing it by hand in the absence of a different use case. Doing it by hand involves the trial and error of checking each hue with a different last argument interactively until an error returned.

library(munsell)

# get list of hues

hues  <- mnsl_hues()

# construct pieces for arguments to seq_mnsl

nume1 <- c(1,1,1,2,3,4,4,5)
nume2 <- c(9,8,8,7,7,6,6,5)
denom <- seq(2,16,2)

# lengths of seq_mnsl

outs   <- c(9,8,8,6,6,3,3,1)

# number of seq_mnsl call per hue

runs <- length(outs)

# create first argument to seq_mnsl

get_start <- function(x,y) paste0(hues[x]," ",nume1[y],"/",denom[y])

# create second argument to seq_mnsl

get_end   <- function(x,y) paste0(hues[x]," ",nume2[y],"/",denom[y])

# display the results for a single hue

show_hues <- function(x,y) mnsl(seq_mnsl(get_start(x,y), get_end(x,y), outs[y]), fix = TRUE)

show_hues(10,1)
#> [1] "#241C08" "#383120" "#504834" "#696149" "#817B62" "#9D957B" "#B8AF94"