{{ message }}

Instantly share code, notes, and snippets.

Created Apr 15, 2012
decodeMinecraftColors in 140byte.es

You can use color codes in the Minecraft chat. I tried to create a parser in 140byt.es that converts a Minecraft chat line to HTML. I found two possible solutions, both 150 bytes. One with a lookup table and another with an algorithmic aproach (which I think is very cool).

Here are some things I learned while golfing this down:

• Do you know String.slice() is the new String.substring()? It's shorter and more reliable. Be aware of the few different behaviors.
• To convert a hexadecimal string to a number (“hex2dec”) you can use parseInt('FF', 16) or eval('0x' + 'FF') or ('0x' + 'FF') * 1 or '0x' + 'FF' | 0. Take care of the operator precedence.
• The eight main colors are ordered like they are binary numbers: 0002, 0012, 0102, 0112, 1002, 1012, 1102, 1112. Thats why I can do this: 616 → 1102 → convert to a binary and parse as a hexadecimal string → 11016 → multiply with A16 → AA016 → add 55516 → FF516.
• The most reliable solution would be to use /&[\dA-F].*/i in a loop. Solutions with [^&] stop coloring on additional ampersands (I can live with this). Solutions with &. either fail (not acceptable) or go black for invalid colors (may be acceptable on a bright background).
• String.fontcolor() is a fascinating relic from the 90s. You should never use it. ;-)
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
 function f(a, b) { return b //if called from the replace function ? b.fontcolor('#' + //surround fetched string by a tag '00000A0A00AAA00A0AFA0AAA55555F5F55FFF55F5FFF5FFF' //lookup table .substr(('0x' + a[1]) * 3, 3)) //convert hex color code to dec : a.replace(/&[\dA-F]([^&]+)/gi, f) //fetch color code followed by non-ampersands }
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
 function f(a,b){return b?b.fontcolor('#'+'00000A0A00AAA00A0AFA0AAA55555F5F55FFF55F5FFF5FFF'.substr(('0x'+a[1])*3,3)):a.replace(/&[\dA-F]([^&]+)/gi,f)}
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
 DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2012 Thiemo Mättig Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO.
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
 { "name": "decodeMinecraftColors", "description": "Converts a Minecraft chat line to HTML.", "keywords": [ "color", "fontcolor", "html", "parse" ] }
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


### maettig commented Apr 17, 2012

Just for the record, here is a possible solution that relies on external CSS.

.c0{color:#000}.c1{color:#00A}.c2{color:#0A0}.c3{color:#0AA}.c4{color:#A00}.c5{color:#A0A}.c6{color:#FA0}.c7{color:#AAA}
.c8{color:#555}.c9{color:#55F}.ca{color:#5F5}.cb{color:#5FF}.cc{color:#F55}.cd{color:#F5F}.ce{color:#FF5}.cf{color:#FFF}
function(a,b){for(;b=/&([\dA-F])(.*)/i.exec(a);)a=a.replace(b[0],'<span class="c'+b[1].toLowerCase()+'">'+b[2]+'</span>');return a}

Its possible to make this even smaller by replacing span with c and removing all " and .toLowerCase() (requires .ca,.cA and so on in the CSS). But this wont make it a 140byt.es solution because of the external data.

### xpansive commented Apr 29, 2012

I've probably spent a good 3 hours trying to get a single byte off this, but nothing seems to work. Good job :)

### maettig commented Apr 30, 2012

Thanks a lot for trying. One thing we can do is to remove the case-insensitive modifier: /&[\da-f]([^&]+)/g (149 bytes). Another idea is to rely on a little bit of CSS (143 bytes + 44 bytes CSS).

font[color="#"],font[color="#5"]{color:#FFF}
function f(a,b,c){return c?c.fontcolor('#'+(('0x'+('0x1'+b|0).toString(2))*10+(b>'7')*1365).toString(16).slice(2)):a.replace(/&(.)([^&]+)/g,f)}