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

<!--
	Inline code and code blocks (preformatted text, in HTML terms).
	
	TODO (2011-10-07):
		* Switch to listings for actual code.
		* Add an "inline-verbatim|verb" template for inline verbatim (which is what the "code" template does now).
		* Add "block-verbatim" as a match for "verbatim".
-->

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


	<!-- Inline code. -->
	<template name="code" match="code">
		<!--
			Inline code (using listings in LaTeX). In LaTeX we use `` as delimiters, as these seem the most unlikely to appear inside the inline code (unless we're doing shell script or similar).
		
			TODO (2012-02-22): Is there some way to get the template to figure out itself what delimiters to use for LaTeX, based on the content of the element? I'm thinking a list of possible delimiters, scan through it and use the first one that doesn't appear in the content. (What to do if you run out of delimiters?)
		-->
		<common formats="/latex/xelatex/">
			<xsl:text>\lstinline</xsl:text>
			<xsl:if test="@language">
				<xsl:text>[language=</xsl:text>
				<xsl:value-of select="@language" />
				<xsl:text>]</xsl:text>
			</xsl:if>
			<!--
				We could just call choose-delimiter twice, but this avoids any possibility of weird corner cases where the second call returns a different delimiter from the first call. It's also slightly more efficient to only call the function once.
			-->
<!-- 
			<xsl:variable name="code-delimiter" select="infosci:choose-delimiter( node() )" />
 -->
			<xsl:text>`</xsl:text>
<!-- 
 			<xsl:value-of select="$code-delimiter" />
 -->
			<xsl:apply-templates />
<!-- 
 			<xsl:value-of select="$code-delimiter" />
 -->
			<xsl:text>`</xsl:text>
		</common>
		<common formats="/html/xhtml/">
			<code><xsl:apply-templates /></code>
		</common>
	</template>
	
	
<!-- 
	<function name="infosci:choose-delimiter" as="xs:string">
		<common formats="/html/xhtml/">
			<xsl:param name="source-text" />
			<xsl:variable name="possible-delimiters">
				<xsl:sequence select="(	'`', '~', '!', '@', '#', '$', '%', '^',
										'&', '(', ')', '-', '_', '=', '+', '[',
										']', '{', '}', '|', ';', ':', '?' )" />
			</xsl:variable>
			
			<xsl:for-each select="$possible-delimiters">
				<xsl:if test=>
			</xsl:for-each>
			
			<xsl:variable name="sign" select="
				if ( matches( $unformatted-value, '^[-+]' ) )
				then replace( $unformatted-value, '^([-+]).*', '$1' )
				else ''" />
			<xsl:variable name="left" select="
				if ( matches( $unformatted-value, '^[-+]?\d+' ) )
				then replace( $unformatted-value, '^[-+]?(\d+).*', '$1' )
				else '0'" />
			<xsl:variable name="right" select="
				if ( matches ( $unformatted-value, '^[-+]?\d*\.\d+' ) )
				then replace ( $unformatted-value, '^[-+]?\d*\.(\d+)', '$1' )
				else ''" />
			<xsl:sequence select="
				concat(	$sign,
						if ( string-length ( $left ) > 4 ) then infosci:separate-thousands( $left, 'l' ) else $left,
						if ( $right != '' ) then '.' else '',
						if ( string-length ( $right ) > 4 ) then infosci:separate-thousands( $right, 'r' ) else $right )" />
		</common>
	</function>
 -->
	
	
	<!--
		Displayed code block. The LaTeX template uses the listings package.
		
		@allow-breaks: Whether or not to allow page breaks in the code block.
			'yes' [default]
			'no
		
		@language: Any language supported by the listings package in LaTeX. Has
			no effect in (X)HTML.
	-->
	<template name="code-block" match="code-block">
		<common formats="/latex/xelatex/">
			<xsl:call-template name="newline-internal" />
			<!--
				If the code-block specifies "allow-breaks='no'", wrap the code block inside a minipage to avoid page breaks within the code.
			-->
			<xsl:if test="@allow-breaks = 'no'">
				<xsl:call-template name="newline-internal" />
				<xsl:text>\begin{minipage}{\textwidth}</xsl:text>
			</xsl:if>
			<xsl:call-template name="newline-internal" />
			<xsl:text>\begin{lstlisting}</xsl:text>
			<xsl:if test="@language">
				<xsl:text>[language=</xsl:text>
				<xsl:value-of select="@language" />
				<xsl:text>]</xsl:text>
			</xsl:if>
			<xsl:apply-templates />
			<xsl:text>\end{lstlisting}</xsl:text>
			<xsl:call-template name="newline-internal" />
			<xsl:if test="@allow-breaks = 'no'">
				<xsl:text>\end{minipage}</xsl:text>
				<xsl:call-template name="newline-internal" />
			</xsl:if>
			<xsl:call-template name="newline-internal" />
		</common>
		<common formats="/html/xhtml/">
			<pre class="code"><xsl:apply-templates /></pre>
		</common>
	</template>
	
	
	<!--
		Inline verbatim text (as opposed to inline code, i.e., \verb in LaTeX). In LaTeX we use `` as delimiters, as these seem the most unlikely to appear inside the verbatim text.
		
		TODO (2012-02-22): Is there some way to get the template to figure out itself what delimiters to use for LaTeX, based on the content of the element? I'm thinking a list of possible delimiters, scan through it and use the first one that doesn't appear in the content. (What to do if you run out of delimiters?)
	-->
	<template name="inline-verbatim" match="inline-verbatim|verb">
		<common formats="/latex/xelatex/">
			<xsl:text>\verb`</xsl:text>
			<xsl:apply-templates />
			<xsl:text>`</xsl:text>
		</common>
		<common formats="/html/xhtml/">
			<code><xsl:apply-templates /></code>
		</common>
	</template>
	
	
	<!--
		This is for stuff that should unequivocally be treated verbatim (e.g., problem code). I'm pretty sure that previously this was distinguished from "code-block" because it (code-block) used to use listings instead of verbatim.  Now that they're both using verbatim there is probably no need for them both (but we might switch back to using listings for code-block).
	-->
	<template name="verbatim" match="verbatim|block-verbatim">
		<common formats="/latex/xelatex/">
			<xsl:call-template name="newline-internal" />
			<xsl:text>\begin{verbatim}</xsl:text>
			<xsl:call-template name="newline-internal" />
			<xsl:apply-templates />
			<xsl:call-template name="newline-internal" />
			<xsl:text>\end{verbatim}</xsl:text>
			<xsl:call-template name="newline-internal" />
		</common>
		<common formats="/html/xhtml/">
			<pre><xsl:apply-templates /></pre>
		</common>
	</template>

</stylesheet>