GitBucket
4.21.2
Toggle navigation
Snippets
Sign in
Files
Branches
1
Releases
1
Issues
Pull requests
Labels
Priorities
Milestones
Wiki
Forks
nigel.stanger
/
XML
Browse code
- Added function to automatically choose valid delimiters for \verb and
\lstinline.
master
1 parent
155f09f
commit
7823ab3b74cf0ae85041d61e224c4c557e132cc2
nstanger
authored
on 23 Feb 2012
Patch
Showing
1 changed file
modules/code-formatting.xml
Ignore Space
Show notes
View
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. LaTeX uses listings to display this; delimiters for \lstinline are chosen automatically, depending on the contents. --> <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:value-of select="$code-delimiter" /> <xsl:apply-templates /> <xsl:value-of select="$code-delimiter" /> </common> <common formats="/html/xhtml/"> <code><xsl:apply-templates /></code> </common> </template> <!-- Choose a valid delimiter for a LaTeX inline verbatim macro (e.g., \verb or \lstinline). "Valid" means that the delimiter can't occur in the source text. The function thus scans through a list of possible delimiters and looking for those that don't occur in the source text. It actually finds /all/ valid delimiters for the source text because of the effective parallel execution of for-each on sequences, but it only returns the first one found. If no valid delimiter can be found, the function raises an error and terminates the transformation. $source-text: The source text to be wrapped inside a \verb macro. --> <function name="infosci:choose-delimiter" as="xs:string"> <common formats="/latex/xelatex/"> <xsl:param name="source-text" /> <xsl:variable name="valid-delimiters"> <!-- The LaTeX documentation says that you can use any character as a delimiter except * (because there is a \verb* form). To keep things simple, we've restricted the possible delimiters to punctuation that can be easily expressed in XML. --> <xsl:for-each select=" '`', '~', '!', '@', '#', '$', '%', '^', '(', ')', '-', '_', '=', '+', '[', ']', '{', '}', '\', '|', ';', ':', ',', '.', '/', '?'"> <xsl:if test="not( contains( $source-text, . ) )"> <xsl:value-of select = "." /> </xsl:if> </xsl:for-each> </xsl:variable> <!-- $valid-delimiters will be empty if none were found. --> <xsl:if test="string-length( $valid-delimiters ) = 0"> <xsl:message terminate="yes"> <xsl:text>ERROR: unable to determine a valid delimiter to use in \verb or \lstinline for the source text: </xsl:text> <xsl:value-of select="$source-text" /> </xsl:message> </xsl:if> <xsl:sequence select="substring( $valid-delimiters, 1, 1 )" /> </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). In LaTeX this equates to \verb; delimiters for this are chosen automatically, depending on the contents. --> <template name="inline-verbatim" match="inline-verbatim|verb"> <common formats="/latex/xelatex/"> <!-- 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="verb-delimiter" select="infosci:choose-delimiter( node() )" /> <xsl:value-of select="$verb-delimiter" /> <xsl:apply-templates /> <xsl:value-of select="$verb-delimiter" /> </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). --> <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>
<?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>
Show line notes below