Skip to content

Instantly share code, notes, and snippets.

@bzerangue
Created November 3, 2011 04:54
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save bzerangue/1335801 to your computer and use it in GitHub Desktop.
Save bzerangue/1335801 to your computer and use it in GitHub Desktop.
[XSLT] iCal utility
<?xml version="1.0" encoding="utf-8"?>
<!--
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
X-WR-TIMEZONE;VALUE=TEXT:US/Central
METHOD:PUBLISH
PRODID:-//Park Cities Presbyterian Church\(PCA\)//iCal 1.0//EN
X-WR-CALNAME;VALUE=TEXT:Park Cities Presbyterian Church Events Feed
VERSION:2.0
BEGIN:VEVENT
SEQUENCE:5
DTSTART;TZID=US/Pacific:20021028T140000
DTSTAMP:20021028T011706Z
SUMMARY:Coffee with Jason
UID:EC9439B1-FF65-11D6-9973-003065F99D04
DTEND;TZID=US/Pacific:20021028T150000
BEGIN:VALARM
TRIGGER;VALUE=DURATION:-P1D
ACTION:DISPLAY
DESCRIPTION:Event reminder
END:VALARM
END:VEVENT
END:VCALENDAR
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xCal="http://www.ietf.org/rfc/rfc2445.txt" xmlns:str="http://exslt.org/strings" extension-element-prefixes="xCal str">
<xsl:strip-space elements="*"/>
<xsl:preserve-space elements="text"/>
<xsl:output method="text" media-type="text/calendar" encoding="utf-8"/>
<xsl:template match="/">
<xsl:text>BEGIN:VCALENDAR&#x0D;&#x0A;</xsl:text>
<xsl:text>PRODID:-//PCPC//NONSGML v.1.0//EN&#x0D;&#x0A;</xsl:text>
<xsl:text>VERSION:2.0&#x0D;&#x0A;</xsl:text>
<xsl:text>CALSCALE:GREGORIAN&#x0D;&#x0A;</xsl:text>
<xsl:text>METHOD:PUBLISH&#x0D;&#x0A;</xsl:text>
<xsl:text>X-WR-CALNAME:Events at Park Cities Presbyterian Church&#x0D;&#x0A;</xsl:text>
<xsl:text>X-WR-TIMEZONE:US/Central&#x0D;&#x0A;</xsl:text>
<xsl:apply-templates select="//entry" mode="VEVENTDETAIL" />
<xsl:text>END:VCALENDAR&#x0D;&#x0A;</xsl:text>
</xsl:template>
<xsl:template match="entry" mode="VEVENTDETAIL">
<xsl:param name="start-date" select="translate(event-start-date,'-','')"/>
<xsl:param name="start-time" select="translate(event-start-date/@time,':','')"/>
<xsl:param name="end-date" select="translate(event-end-date,'-','')"/>
<xsl:param name="end-time" select="translate(event-end-date/@time,':','')"/>
<xsl:param name="lat-long">
<xsl:call-template name="geocode">
<xsl:with-param name="address" select="location-full-address"/>
</xsl:call-template>
</xsl:param>
<xsl:text>BEGIN:VEVENT&#x0D;&#x0A;</xsl:text>
<xsl:text>SUMMARY:</xsl:text><xsl:value-of select="title" /><xsl:text>&#x0D;&#x0A;</xsl:text>
<xsl:text>URL;VALUE=URI:</xsl:text><xsl:value-of select="concat('http://pcpc.org/events/',@id)" /><xsl:text>&#x0D;&#x0A;</xsl:text>
<xsl:text>UID:</xsl:text><xsl:value-of select="concat($start-date,'T',$start-time,'00','-',@id)" /><xsl:text>@pcpc.org&#x0D;&#x0A;</xsl:text>
<xsl:text>DESCRIPTION:</xsl:text><xsl:value-of select="title" /><xsl:text>&#x0D;&#x0A;</xsl:text>
<!--><xsl:text>DTSTAMP:</xsl:text><xsl:value-of select="concat($start-date,'T',$start-time,'00')" /><xsl:text>&#x0D;&#x0A;</xsl:text>-->
<xsl:text>LOCATION:</xsl:text>
<xsl:call-template name="escape-commas">
<xsl:with-param name="text" select="location-full-address" />
</xsl:call-template>
<xsl:text>&#x0D;&#x0A;</xsl:text>
<xsl:text>GEO:</xsl:text><xsl:value-of select="translate($lat-long,', ',';')" /><xsl:text>&#x0D;&#x0A;</xsl:text>
<!--<xsl:text>SEQUENCE:0&#x0D;&#x0A;</xsl:text>-->
<!--><xsl:text>STATUS:CONFIRMED&#x0D;&#x0A;</xsl:text>-->
<xsl:text>TRANSP:OPAQUE&#x0D;&#x0A;</xsl:text>
<xsl:text>DTSTART;TZID=America/Chicago:</xsl:text><xsl:value-of select="concat($start-date,'T',$start-time,'00')" /><xsl:text>&#x0D;&#x0A;</xsl:text>
<xsl:text>DTEND;TZID=America/Chicago:</xsl:text><xsl:value-of select="concat($end-date,'T',$end-time,'00')" /><xsl:text>&#x0D;&#x0A;</xsl:text>
<!--><xsl:text>BEGIN:VALARM&#x0D;&#x0A;</xsl:text>
<xsl:text>TRIGGER;VALUE=DURATION:-P1D&#x0D;&#x0A;</xsl:text>
<xsl:text>ACTION:DISPLAY&#x0D;&#x0A;</xsl:text>-->
<xsl:text>END:VEVENT&#x0D;&#x0A;</xsl:text>
</xsl:template>
<xsl:template name="geocode">
<xsl:param name="address"/>
<xsl:variable name="encodedAddress">
<xsl:value-of select="translate($address,' ','+')"/>
</xsl:variable>
<xsl:variable name="urlString">http://maps.google.com/maps/geo?q=<xsl:value-of select="$encodedAddress"/>&amp;output=xml&amp;oe=utf8&amp;sensor=false</xsl:variable>
<xsl:variable name="geocoder" select="document($urlString)"/>
<xsl:for-each select="$geocoder//*[name()='coordinates']">
<xsl:if test="position() = 1">
<xsl:value-of select="substring-after(substring-before(text(),',0'),',')"/><xsl:text>, </xsl:text><xsl:value-of select="substring-before(substring-before(text(),',0'),',')"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Escape single quotes -->
<xsl:template name="escape-single-quotes">
<xsl:param name="text" />
<xsl:variable name="apos">'</xsl:variable>
<xsl:variable name="bapos">\'</xsl:variable>
<xsl:value-of select="str:replace($text, $apos, $bapos)" />
</xsl:template>
<!-- Escape double quotes -->
<xsl:template name="escape-double-quotes">
<xsl:param name="text" />
<xsl:variable name="apos">"</xsl:variable>
<xsl:variable name="bapos">\"</xsl:variable>
<xsl:value-of select="str:replace($text, $apos, $bapos)" />
</xsl:template>
<!-- Escape commas -->
<xsl:template name="escape-commas">
<xsl:param name="text" />
<xsl:variable name="apos">,</xsl:variable>
<xsl:variable name="bapos">\,</xsl:variable>
<xsl:value-of select="str:replace($text, $apos, $bapos)" />
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment