Skip to content

Instantly share code, notes, and snippets.

@davidl
Created August 15, 2012 16:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidl/3361342 to your computer and use it in GitHub Desktop.
Save davidl/3361342 to your computer and use it in GitHub Desktop.
XSLT to transform a PLIST file to HTML with illustrated color information
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" omit-xml-declaration="yes" indent="yes"/>
<!--
This file is intended to transform a ".plist" file into a HTML
document that highlights color information by illustrating it
and making the color values (hexadecimal and RGB/RGBa) easier to
select and copy.
WHY? I wanted an easy way to select the colors in
Todd Werth's IR_Black TextMate Theme (a ".plist" file) to apply
them in other editors:
http://blog.toddwerth.com/entries/show/2
NOTES:
* I've only tested this on the file linked above.
* I modified an example XSLT which I can no longer attribute.
-->
<xsl:variable name="Title">
<xsl:value-of select="//string[1]"/> - <xsl:value-of select="name(/*)"/>
</xsl:variable>
<xsl:variable name="Linebreak">
<xsl:text>
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>
<xsl:value-of select="$Linebreak"/>
<html lang="en">
<head>
<title><xsl:value-of select="$Title"/></title>
<xsl:value-of select="$Linebreak"/>
<style><![CDATA[
body { font-family: "Helvetica Neue", Arial, sans-serif; }
table { border-collapse: collapse; }
li > table { color: #444; }
li {
color: #FFF;
padding: 0 0 1em;
}
li:nth-of-type(even) { background-color: #FAFAFA; }
li:hover { color: #AAA; }
td, th {
border: 1px solid;
padding: 1ex;
vertical-align: top;
}
.color-value { padding-right: 2em; }
.color-value span {
background: rgba(255, 255, 255, 0.5);
border: 1px solid #AAA;
color: #333;
font-family: Monaco, monospace;
padding: 0 1ex;
}
.rgb { margin-left: 1em; }
]]></style>
<xsl:value-of select="$Linebreak"/>
</head>
<body>
<h1><xsl:value-of select="$Title"/></h1>
<xsl:apply-templates />
<script>
<xsl:text disable-output-escaping="yes"><![CDATA[
// To-do: use XSLT instead of JavaScript to convert hexadecimal to RGB values:
// http://www.dpawson.co.uk/xsl/sect2/colour.html
// This function converts a hexadecimal value (in the format RRGGBBAA) to RGBa format:
function hexToRgba(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
a: parseInt(result[4], 16) / 255
} : null;
}
// Append SPANs containing RGB/RGBa color values:
// We only need to convert hexadecimal values that include
// opacity since we can get the RGB value by querying
// the TD after we set the background-color (even though
// we set it with a hexadecimal value.
var tds = document.querySelectorAll('td td td+td');
for (var i = 0; i < tds.length; i++) {
var text = tds[i].textContent;
if ( text.indexOf('#') == 0 ) {
// If the string is more than "#RRGGBB" assume
// we need a RGBa value:
if ( text.length > 7 ) {
var color = hexToRgba(text);
var colorStr = 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + color.a + ')';
tds[i].style.backgroundColor = colorStr;
} else {
tds[i].style.backgroundColor = text;
}
tds[i].className += 'color-value';
var hex = document.createElement('span');
hex.innerHTML = tds[i].innerHTML;
hex.className = 'hex';
var rgb = document.createElement('span');
// The background color will give us RGB or RGBa:
rgb.textContent = tds[i].style.backgroundColor;
rgb.className = 'rgb';
tds[i].innerHTML = '';
tds[i].appendChild(hex);
tds[i].appendChild(rgb);
}
}
// If a SPAN inside a ".color-value" cell is double-clicked,
// select its text for easy copying:
if ( window.getSelection ) {
document.body.addEventListener('dblclick', function(e) {
if ( e.target && e.target.nodeName == 'SPAN' && e.target.parentNode.className == 'color-value' ) {
window.getSelection().removeAllRanges();
var range = document.createRange();
range.selectNode(e.target);
window.getSelection().addRange(range);
}
return false;
});
}
]]></xsl:text>
</script>
<xsl:value-of select="$Linebreak"/>
</body>
</html>
</xsl:template>
<xsl:template match="false">
<span class="false">false</span>
</xsl:template>
<xsl:template match="true">
<span class="true">true</span>
</xsl:template>
<xsl:template match="array">
<ol>
<xsl:for-each select="*">
<li>
<xsl:apply-templates select="."/>
</li>
</xsl:for-each>
</ol>
</xsl:template>
<xsl:template match="dict">
<table>
<thead>
<tr>
<th>key</th>
<th>value</th>
</tr>
</thead>
<tbody>
<xsl:choose>
<!-- When the value is empty -->
<xsl:when test="not(*)">
<tr>
<td colspan="2"/>
</tr>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="key">
<tr>
<td><xsl:value-of select="."/></td>
<td><xsl:apply-templates select="following-sibling::*[1]"/></td>
</tr>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment