Create iterm2 plist xml color preset files ready for import.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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