Newer
Older
XML / modules / hyperlinks.xml
<?xml version="1.0" encoding="utf-8"?>

<!--
	Hyperlinks and URLs. The content of the hyperlink element becomes the link text. All hyperlink elements have these attributes:
	
	@label: A label that the hyperlink links to. The value should be an acceptable label in both LaTeX and HTML. [optional]
	
	@url: A URL that the hyperlink links to. If no link text is provided, the URL is used as the link text. [optional]
	
	@target: The target tab/window to open the hyperlink in. Only applies to (X)HTML. [optional]
	
	Only one of @label and @url may be specified.
-->

<stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


	<!-- Type 1: hyperlink has both a label and content (i.e., link text). -->
	<template name="hyperlink-label" match="hyperlink[@label and node()]">
		<common formats="/latex/xelatex/">
			<!--
				Sometimes the hyperlink content may be explicitly split across multiple lines, separated by <br> elements. This isn't a problem in (X)HTML, but it breaks (Xe)LaTeX, because you can't include a \\ inside most macros. The solution is to explicitly process the sub-elements, and wrap appropriate hyperref macros around them, /except/ for any embedded <br> elements.
			-->
			<xsl:for-each select="node()">
				<xsl:if test="not( self::br )">
					<xsl:text>\hyperref[</xsl:text>
					<xsl:value-of select="../@label" />
					<xsl:text>]{</xsl:text>
				</xsl:if>
				<xsl:apply-templates select="." />
				<xsl:if test="not( self::br )">
					<xsl:text>}</xsl:text>
				</xsl:if>
			</xsl:for-each>
		</common>
		<common formats="/html/xhtml/">
			<a href="#{@label}">
				<xsl:if test="@target">
					<xsl:attribute name="target">
						<xsl:value-of select="@target" />
					</xsl:attribute>
				</xsl:if>
				<xsl:apply-templates />
			</a>
		</common>
	</template>
	
	
	<!-- Type 2: hyperlink has both a URL and content. -->
	<template name="hyperlink-url" match="hyperlink[@url and node()]">
		<common formats="/latex/xelatex/">
			<!-- See Type 1 above. -->
			<xsl:for-each select="node()">
				<xsl:if test="not( self::br )">
					<xsl:text>\href{</xsl:text>
					<xsl:value-of select="../@url" />
					<xsl:text>}{</xsl:text>
				</xsl:if>
				<xsl:apply-templates select="." />
				<xsl:if test="not( self::br )">
					<xsl:text>}</xsl:text>
				</xsl:if>
			</xsl:for-each>
		</common>
		<common formats="/html/xhtml/">
			<a href="{@url}">
				<xsl:if test="@target">
					<xsl:attribute name="target">
						<xsl:value-of select="@target" />
					</xsl:attribute>
				</xsl:if>
				<xsl:apply-templates />
			</a>
		</common>
	</template>
	
	
	<!-- Type 3: hyperlink has a URL but no content. -->
	<template name="empty-hyperlink-url" match="hyperlink[@url and not( node() )]">
		<!-- Note: not safe to use the url package here because \url{...} is fragile. -->
		<common formats="/latex/xelatex/">
			<xsl:text>\url{</xsl:text>
			<xsl:value-of select="@url" />
			<xsl:text>}</xsl:text>
		</common>
		<common formats="/html/xhtml/">
			<a href="{@url}">
				<xsl:if test="@target">
					<xsl:attribute name="target">
						<xsl:value-of select="@target" />
					</xsl:attribute>
				</xsl:if>
				<code><xsl:value-of select="@url" /></code>
			</a>
		</common>
	</template>
	
	
	<!-- ERROR: hyperlink has a label but no content. -->
	<template name="empty-hyperlink-label" match="hyperlink[@label and not( node() )]">
		<common>
			<xsl:message terminate="yes">&lt;hyperlink&gt; with @label must include link text.</xsl:message>
		</common>
	</template>
	
	
	<!-- ERROR: hyperlink has both a label and a URL. -->
	<template name="hyperlink-bogus" match="hyperlink[@url and @label]" priority="2">
		<common>
			<xsl:message terminate="yes">Cannot use both @url and @label in &lt;hyperlink&gt;.</xsl:message>
		</common>
	</template>
	
	
	<!-- Internal parameterised hyperlink templates to be called by the likes of the empty Oracle documentation elements. -->
	<template name="hyperlink-internal" match="hyperlink" mode="hyperlink-internal">
		<common>
			<xsl:param name="url" />
			<xsl:param name="label" />
		</common>
		<common formats="/latex/xelatex/">
			<xsl:text>\href{</xsl:text>
			<xsl:value-of select="$url" />
			<xsl:text>}{</xsl:text>
			<xsl:apply-templates select="exsl:node-set($label)" />
			<xsl:text>}</xsl:text>
		</common>
		<common formats="/html/xhtml/">
			<a href="{$url}"><xsl:apply-templates select="exsl:node-set($label)" /></a>
		</common>
	</template>

	<template name="empty-hyperlink-url-internal" match="hyperlink" mode="empty-hyperlink-internal">
		<common>
			<xsl:param name="url" />
		</common>
		<common formats="/latex/xelatex/">
			<xsl:text>\url{</xsl:text>
			<xsl:value-of select="$url" />
			<xsl:text>}</xsl:text>
		</common>
		<common formats="/html/xhtml/">
			<a href="{$url}"><code><xsl:value-of select="$url" /></code></a>
		</common>
	</template>
	
	
	<!-- A plain URL (i.e., not necessarily a hyperlink). -->
	<template name="url" match="url|uri|email|e-mail|email-address|e-mail-address">
		<!--
			Hmm, \url{...} appears to turn the URL into a non-functional link in PDF output (probably an interaction with hyperref). Not really what we want (as the link aspect is already dealt with by the <hyperlink> templates), so we'll use \nolinkurl{...}.
		-->
		<common formats="/latex/xelatex/">
			<xsl:text>\nolinkurl{</xsl:text>
			<xsl:apply-templates />
			<xsl:text>}</xsl:text>
		</common>
		<common formats="/html/xhtml/">
			<code><xsl:apply-templates /></code>
		</common>
	</template>


</stylesheet>