<?xml version="1.0" encoding="utf-16"?>
<!-- 
	
	hResume2Fo.xsl
	
	By Brook Ellingwood (brook.ellingwood@gmail.com).
	
	This (totally arbitrary) version number: 1.0.
	
	Published: 2009-05-01
	
	This XSL transform takes the XHTML found at http://beaconstandard.com/brookellingwood/resume.php and replicates
	its styling as closely as possible in a PDF, using XSL:FO.
	
	This is NOT a generic transformation for any hResume implementation, although such a thing is certainly possible.
	
-->

<!-- 
	Note that the default namespace and the xhtml: namespace both need to have the same uri to avoid issues.
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
	xmlns:mscom="http://www.microsoft.com" xmlns="http://www.w3.org/1999/xhtml"
	xmlns:xhtml="http://www.w3.org/1999/xhtml">
	<xsl:variable name="color0" select="'#0000CC'"/>
	<xsl:variable name="color1" select="'#FF9C2A'"/>
	<xsl:variable name="color2" select="'#66CCCC'"/>
	<xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>
	<!-- 
		Start at the document, then only apply templates only within the declared 'resume' div. Maybe this could
		be the 'hresume' div, but I put 'hresume' on the body element instead. Hmmm.
	-->
	<xsl:template match="/">
		<xsl:apply-templates select="xhtml:html/xhtml:body/xhtml:div[@id='resume']"/>
	</xsl:template>
	<!-- 
		Begin master template. This is where all that :fo stuff for print, like margins and such gets defined. 
	-->
	<xsl:template match="xhtml:body/xhtml:div[@id='resume']">
		<!-- 
			Output fo:root. It's gotta be valid XML when it comes out or the :fo processor will complain. 
		-->
		<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
			<!-- 
				Define master page layout 
			-->
			<fo:layout-master-set>
				<fo:simple-page-master master-name="resume" page-height="11in" page-width="8.5in"
					margin-top=".5in" margin-bottom=".5in" margin-left=".75in" margin-right=".75in">
					<fo:region-body region-name="main" margin-top="48pt"/>
					<fo:region-before region-name="header" extent="48pt"/>
				</fo:simple-page-master>
				<fo:page-sequence-master master-name="page">
					<fo:repeatable-page-master-reference master-reference="resume"/>
				</fo:page-sequence-master>
			</fo:layout-master-set>
			<!-- 
				Begin page layout 
			-->
			<fo:page-sequence master-reference="page">
				<!-- 
					Header 
				-->
				<fo:static-content flow-name="header">
					<xsl:apply-templates select="xhtml:div[@class='vcard contactHeader']"/>
				</fo:static-content>
				<!-- 
					Flow (dynamic body layout) 
				-->
				<fo:flow flow-name="main">
					<fo:block font-family="Times New Roman" font-size="90%" padding="0 0 12pt 0"
						margin="12pt 0">
						<xsl:apply-templates
							select="xhtml:div[contains(@class,'section')]"
						/>
					</fo:block>
				</fo:flow>
			</fo:page-sequence>
		</fo:root>
	</xsl:template>
	<!-- 
		Turn the XHTML header info into :fo instructions.
	-->
	<xsl:template match="xhtml:div[@class='vcard contactHeader']">
		<fo:block
			font-family="Hoefler Text, Baskerville, Big Caslon, Adobe Garamond Pro, Georgia, Palatino, Times New Roman, serif"
			font-size="90%" padding="0 12pt 12pt 12pt" text-align="center">
			<!-- 
				h1 into fo:block. In the XHTML there are internal spans for hCard, but I don't care about them in the PDF, so 
				I just grab all the text nodes inside the h1 and strip the space.
			-->
			<fo:block padding="0" font-variant="small-caps" font-size="120%" width="100%">
				<xsl:value-of select="normalize-space(xhtml:h1)"/>
			</fo:block>
			<!-- 
				hCard .adr class into fo:block
			-->
			<fo:block>
				<xsl:value-of select="normalize-space(xhtml:div/xhtml:span[@class='adr'])"/>
				<xsl:text> ~ </xsl:text>
				<xsl:value-of select="normalize-space(xhtml:div/xhtml:span[@class='tel'])"/>
				<xsl:text> ~ </xsl:text>
				<xsl:for-each
					select="xhtml:div/xhtml:span[@class='email']/xhtml:span[@class='value']">
					<xsl:value-of select="normalize-space(.)"/>
				</xsl:for-each>
			</fo:block>
			<fo:block>
				<!-- 
					hCard .adr class into fo:block
				-->
				<xsl:value-of select="normalize-space(xhtml:span[@class='url'][position()=1])"/>
				<xsl:if test="xhtml:span[@class='url'][position()=2]">
					<xsl:text> ~ </xsl:text>
					<xsl:value-of select="normalize-space(xhtml:span[@class='url'][position()=2])"/>
				</xsl:if>
			</fo:block>
		</fo:block>
	</xsl:template>
	<!-- 
		If we're in a cover letter, there's a recipient address to format.
	-->
	<xsl:template match="xhtml:div[@class='vcard coverRecipient']">
		<fo:block
			font-family="Hoefler Text, Baskerville, Big Caslon, Adobe Garamond Pro, Georgia, Palatino, Times New Roman, serif"
			font-size="100%" padding="20pt 12pt 40pt 12pt" text-align="left">
			<fo:block>
				<xsl:value-of select="normalize-space(xhtml:span[contains(@class, 'fn')])"/>
			</fo:block>
			<fo:block>
				<xsl:value-of select="normalize-space(xhtml:div[@class='adr']/xhtml:div[@class='street-address'])"/>
			</fo:block>
			<fo:block>
				<xsl:value-of select="normalize-space(xhtml:div[@class='adr']/xhtml:div[@id='cityStateZip'])"/>
				<fo:block text-align="right" margin-top="-1.5em">
					<xsl:value-of select="normalize-space(xhtml:div[@class='adr']/xhtml:div[@class='date'])"/>
				</fo:block>
			</fo:block>
		</fo:block>
	</xsl:template>
	<!-- 
		h2 into fo:block
	-->
	<xsl:template match="xhtml:h2">
		<fo:block margin-top="0" margin-bottom="0" text-align="left" font-size="110%"
			margin-left="0" font-weight="bold">
			<xsl:value-of select="."/>
		</fo:block>
	</xsl:template>
	<!-- 
		h3 into fo:block. I have to account for internal spans, which are there both for the hResume microformat and
		for formatting loveliness.
	-->
	<xsl:template match="xhtml:h3">
		<fo:block margin-top="2px" text-align="left" font-size="100%" margin-left="0"
			margin-bottom="1pt" border-left-width="2px" border-left-style="solid"
			padding-left="14pt" padding-right="14pt" font-weight="bold"
			border-left-color="{$color0}">
			<xsl:value-of
				select="xhtml:span[contains(@class, 'org')] | xhtml:span[@class='activity']"/>
			<fo:inline font-weight="normal" font-size="85%" padding-left="15pt">
				<xsl:value-of select="xhtml:span[@class='adr']"/>
			</fo:inline>
			<fo:inline font-weight="normal" font-size="85%" padding-left="15pt">
				<xsl:value-of select="xhtml:span[@class='empDates']"/>
			</fo:inline>
		</fo:block>
	</xsl:template>
	<!-- 
		h4 into fo:block
	-->
	<xsl:template match="xhtml:h4">
		<fo:block text-align="left" font-size="90%" border-left-width="2px"
			border-left-color="{$color2}" border-left-style="solid" margin-left="0"
			padding-left="14pt" margin-bottom="1pt" font-weight="bold" font-style="italic">
			<xsl:value-of select="."/>
		</fo:block>
	</xsl:template>
	<!--
		Each div.section (Experience, Education, etc.) becomes an fo:block
	-->
	<xsl:template match="xhtml:div[contains(@class,'section')]">
		<fo:block margin-bottom="12pt">
			<xsl:if test="@id='cover'">
				<xsl:attribute name="break-after">
					<xsl:text>page</xsl:text>
				</xsl:attribute>
			</xsl:if>
			<xsl:apply-templates/>
		</fo:block>
	</xsl:template>
	<!-- 
		li's indicating subsections (jobs, colleges, etc.) become fo:blocks.
	-->
	<xsl:template match="xhtml:ol/xhtml:li[contains(@class,'sub')]">
		<fo:block margin-top="0" margin-bottom="1em" keep-together.within-page="always">
			<fo:block margin-top="0" text-align="left" font-size="100%" margin-left="0"
				font-weight="bold" line-height="1em" letter-spacing="8pt" color="{$color0}">
				<!-- 
					I generate a dot indicating each li's position in the list. In the XHTML right now, the dots are
					static, which makes me sad. I could do them with Javascript, but I'll probably leave them as they are
					until I redo the whole thing with a server-side transform.
				-->
				<xsl:text>· </xsl:text>
				<xsl:for-each select="preceding-sibling::xhtml:li[contains(@class,'sub')]">
					<xsl:text>· </xsl:text>
				</xsl:for-each>
			</fo:block>
			<xsl:apply-templates/>
		</fo:block>
	</xsl:template>
	<!-- 
		I suppress the static dots in the XHTML, because the generated ones in the PDF are much cooler.
	-->
	<xsl:template match="xhtml:span[@class='posCount']"/>
	<!-- 
		p into fo:block
	-->
	<xsl:template match="xhtml:p">
		<fo:block margin-top="2pt" text-align="left" font-size="100%" margin-left="0"
			margin-bottom="2pt">
			<xsl:choose>
			
			<xsl:when test="../../@id='cover'">
				<xsl:attribute name="padding-top">
					<xsl:text>7pt</xsl:text>
				</xsl:attribute>
				<xsl:attribute name="padding-bottom">
					<xsl:text>7pt</xsl:text>
				</xsl:attribute>
			</xsl:when>
			</xsl:choose>
			
			<xsl:apply-templates/>
		</fo:block>
	</xsl:template>
	<!-- 
		div.description into fo:block with a custom border treatment.
	-->
	<xsl:template match="xhtml:div[@class='description']">
		<fo:block border-left-width="2px" border-left-color="{$color1}" border-left-style="dotted"
			margin-top="4pt" margin-left="0" padding-left="25pt">
			<xsl:apply-templates/>
		</fo:block>
	</xsl:template>
	<!-- 
		I zebra stripe li's inside div.description by applying different background colors based on their position
		in the list. In the XHTML, not only is this currently hardcoded, it's actually being done with inline styling
		on the li's. Super lame. I should at least make that come from the external CSS.
	-->
	<xsl:template match="xhtml:div[@class='description']/xhtml:ul/xhtml:li[position() mod 2 =1]">
		<fo:block background-color="#EEEEEE" margin="0 0 2pt 2pt" padding="4pt 0 4pt 2pt">
			<xsl:apply-templates/>
		</fo:block>
	</xsl:template>
	<xsl:template match="xhtml:div[@class='description']/xhtml:ul/xhtml:li[position() mod 2 =0]">
		<fo:block margin="0  60pt 0t 2pt" padding="1pt 0 1pt 2pt">
			<xsl:apply-templates/>
		</fo:block>
	</xsl:template>
	<!-- 
		Preserve inline italics for publication titles.
	-->
	<xsl:template match="xhtml:a[@style='font-style:italic']">
		<fo:inline font-style="italic">
			<xsl:apply-templates/>
		</fo:inline>
	</xsl:template>
	<!-- 
		Images
	-->
	<xsl:template match="xhtml:img">
		<fo:external-graphic src="url(http://brookellingwood.com{@src})"
			content-height="50%" content-width="50%"/>
	</xsl:template>
</xsl:stylesheet>
