Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create iterm2 plist xml color preset files ready for import.
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil
import java.awt.Color
/**
* Reads in a map of color themes, each with five hex color values, and maps them to an iterm color preset plist file.
*/
assert args.size() == 1, 'The name or path to a file containing a themeMap script variable must be supplied on the command line'
def themeMapFileName = args[0]
Binding binding = new Binding()
new GroovyShell(binding).evaluate(new File(themeMapFileName))
assert binding.hasVariable('themeMap'), "${args[0]} file must contain a Map variable named themeMap"
def themeMap = binding.themeMap as TreeMap
Random random = new Random()
final Closure normalize = { value ->
value / 255
}.memoize()
final Closure padHex = { String hex ->
assert hex?.size() >= 6
hex[0] != '#' ? "#$hex" : hex
}.memoize()
final Closure extractColor = { String hex ->
final Color color = Color.decode(padHex(hex))
}.memoize()
final Closure extractRGB = { String hex ->
final Color color = extractColor(hex)
[color.red, color.green, color.blue]
}.memoize()
final Closure extractRGBNormalized = { String hex ->
extractRGB(hex).collect {normalize(it)}
}.memoize()
def colorProcessors = [
'Foreground Color': [index: 0, processor: {it}],
'Background Color': [index: 1, processor: {it}],
'Bold Color': [index: 2, processor: {it}],
'Selection Color': [index: 3, processor: {it}],
'Selected Text Color': [index: 4, processor: {it}],
'Cursor Color': [index: 1, processor: {normalize(((it * 255 + 50) as int) % 255)}],
'Cursor Text Color': [index: 0, processor: {normalize(((it * 255 + 50) as int) % 255)}]]
final Closure buildColors = { builder, Color color ->
builder.dict {
key('Blue Component')
real(normalize(color.blue))
key('Green Component')
real(normalize(color.green))
key('Red Component')
real(normalize(color.red))
}
}
final Closure buildComponentColors = { builder, colors, i ->
final hex = colors[random.nextInt(colors.size())]
//Normal
final Color color = extractColor(hex)
builder.key("Ansi $i Color")
buildColors(builder, color)
//Bright
final Color brighterColor = color.brighter()
builder.key("Ansi ${i + 8} Color")
buildColors(builder, brighterColor)
}
final File root = new File("iterm2Themes${new Date().format('yyMMddHHmmss')}")
if (root.exists()) {
root.deleteDir()
}
root.mkdir()
themeMap.each { name, colors ->
println "Processing $name"
Writer writer = new StringWriter()
xmlBuilder = new StreamingMarkupBuilder()
writer << xmlBuilder.bind { builder ->
mkp.yieldUnescaped '<?xml version="1.0" encoding="UTF-8"?>'
mkp.yieldUnescaped '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
plist(version: "1.0") {
dict {
(0..7).each { i ->
buildComponentColors(builder, colors, i)
}
colorProcessors.each {colorName, colorProcessor ->
final rgb = extractRGBNormalized(colors[colorProcessor.index])
key(colorName)
builder.dict {
key('Blue Component')
real(colorProcessor.processor(rgb[2]))
key('Green Component')
real(colorProcessor.processor(rgb[1]))
key('Red Component')
real(colorProcessor.processor(rgb[0]))
}
}
}
}
}
new File(root, "${name}.itermcolors") << XmlUtil.serialize(writer.toString())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment