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 mode=text option to siunitx to ensure it uses the correct maths font under fontspec.
master
1 parent
bdc7468
commit
91b032b8432f2213c355ba3a5d1156ff4887b31a
Nigel Stanger
authored
on 7 Mar 2016
Patch
Showing
1 changed file
xml2xslt.xsl
Ignore Space
Show notes
View
xml2xslt.xsl
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsl-out="[irrelevant]" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:infosci="http://info-nts-12.otago.ac.nz/infosci"> <!-- XSLT transformation for a master XML document defining how to transform elements in the course handbook source into HTML and LaTeX. Hmm, meta-stylesheet?! --> <xsl:output method="xml" encoding="utf-8" cdata-section-elements="html" /> <!-- What target format are we generating a styesheet for? Possible values: html, xhtml, latex (includes pdflatex), xelatex. --> <xsl:param name="target-format"><xsl:text>html</xsl:text></xsl:param> <!-- Define an alias for the xsl namespace to avoid confusion when generating xsl: elements in the output of this stylesheet. --> <xsl:namespace-alias stylesheet-prefix="xsl-out" result-prefix="xsl" /> <!-- Some useful variables. (Could some of these become callable templates?) --> <xsl:variable name="newline"> <xsl:text> </xsl:text> </xsl:variable> <xsl:variable name="space"><xsl:text> </xsl:text></xsl:variable> <!-- *** TEMPLATES *** --> <xsl:template match="/"> <xsl-out:stylesheet version="2.0"> <xsl-out:strip-space elements="*" /> <xsl-out:param name="subject-code"><xsl:text>INFO</xsl:text></xsl-out:param> <xsl-out:param name="paper-number" /> <xsl-out:param name="paper-year" select="year-from-date( current-date() )"/> <xsl-out:param name="period-code" /> <xsl-out:param name="showanswers"><xsl:text>no</xsl:text></xsl-out:param> <!-- This is normally the path to the current document directory. --> <xsl-out:param name="base-path"><xsl:text>.</xsl:text></xsl-out:param> <!-- This is normally the path to the root directory of the paper tree in the filesystem. --> <xsl-out:param name="paper-include-path"><xsl:text>.</xsl:text></xsl-out:param> <!-- This is normally the file paper_init.tex in the root of the paper tree. --> <xsl-out:param name="latex-initialisation-file"><xsl:text>paper_init</xsl:text></xsl-out:param> <!-- Full period string corresponding to the supplied period code. --> <xsl-out:variable name="period-string" select="infosci:expand-period-code( $period-code )" /> <!-- The date and time when the document was last built. --> <xsl-out:variable name="date-built" select="current-dateTime()" /> <!-- Get the name of the document being processed. --> <xsl-out:variable name="document-name" select="reverse( tokenize( base-uri(), '/' ) )[1]" /> <!-- Include the generated Oracle documentation code. --> <xsl-out:include href="oracle-docs.xsl" /> <!-- Boilerplate (Xe)LaTeX code for loading hyperref. If the package is already loaded (by the document class), attempting to load it again will cause an "option clash" error. To avoid this, check first whether it's already loaded. We apply the required settings afterwards regardless. --> <xsl-out:variable name="latex-hyperref-boilerplate"> <xsl-out:text> % Avoid option clash if document class already loaded it. \makeatletter \@ifpackageloaded{hyperref}{}{\usepackage{hyperref}} \makeatother % Safer to specify the hyperref options directly rather than relying on % the default hyperref.cfg, as XeLaTeX seems to ignore it :(. \hypersetup{pdfpagemode=UseNone,colorlinks,urlcolor=blue,citecolor=blue,% linkcolor=blue,breaklinks} </xsl-out:text> </xsl-out:variable> <!-- We're going to use the text encoding in a few different places, so let's work out what it should be now. --> <xsl:variable name="text-encoding"> <xsl:choose> <xsl:when test="($target-format = 'latex') or ($target-format = 'html')"> <xsl:text>iso-8859-1</xsl:text> </xsl:when> <xsl:when test="($target-format = 'xelatex') or ($target-format = 'xhtml')"> <xsl:text>utf-8</xsl:text> </xsl:when> <xsl:otherwise> <xsl:message terminate="yes"> <xsl:text>Sorry, unknown target format: </xsl:text><xsl:value-of select="$target-format" /> </xsl:message> </xsl:otherwise> </xsl:choose> </xsl:variable> <!-- First, output the document preamble according to target format. This is generally different for each target format. --> <xsl:choose> <!-- The HTML formats are fairly simple: the only things that change are the doctypes, version number and text encoding. --> <xsl:when test="$target-format = 'html'"> <xsl-out:output method="html" encoding="{$text-encoding}" version="4.01" media-type="text/html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" doctype-system="http://www.w3.org/TR/html4/loose.dtd" /> </xsl:when> <xsl:when test="$target-format = 'xhtml'"> <xsl-out:output method="xml" encoding="{$text-encoding}" byte-order-mark="no" version="1.1" media-type="text/html" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" /> </xsl:when> <!-- The LaTeX formats, however have a bunch of miscellaneous boilerplate that appears at the start of every document, and requires more complex interleaving because of hyperref. Since we need to stuff this into a template later on, we define this using a callable template, so that we can do useful things like apply-templates within it (which wouldn't work if we just used a variable). --> <xsl:when test="$target-format = 'latex'"> <xsl-out:output method="text" encoding="{$text-encoding}" media-type="text/plain" /> <!-- Set to no if you want this to be included inside another document. Appears here because it's used in the document preamble. --> <xsl-out:param name="standalone"><xsl:text>yes</xsl:text></xsl-out:param> <xsl-out:template name="latex-preamble"> <xsl-out:text> \usepackage{mathpazo} % mathpple is deprecated \usepackage[T1]{fontenc} \usepackage{textcomp} </xsl-out:text> <xsl-out:apply-templates select="environment/latex-packages" /> <xsl-out:value-of select="$latex-hyperref-boilerplate" /> <xsl-out:text> \renewcommand{\ttdefault}{blg} </xsl-out:text> </xsl-out:template> </xsl:when> <xsl:when test="$target-format = 'xelatex'"> <xsl-out:output method="text" encoding="{$text-encoding}" media-type="text/plain" /> <!-- Set to no if you want this to be included inside another document. Appears here because it's used in the document preamble. --> <xsl-out:param name="standalone"><xsl:text>yes</xsl:text></xsl-out:param> <xsl-out:template name="latex-preamble"> <xsl-out:text> \usepackage[no-math]{fontspec} \usepackage{mathspec} \usepackage{xunicode} \usepackage{xltxtra} \usepackage{textcomp} % ??? </xsl-out:text> <xsl-out:apply-templates select="environment/latex-packages" /> <xsl-out:value-of select="$latex-hyperref-boilerplate" /> <xsl-out:text> \defaultfontfeatures{Mapping=tex-text} \setmainfont{TeX Gyre Pagella} \setsansfont[Scale=MatchUppercase,BoldFont={Gill Sans}]{Gill Sans Light} \setmonofont[Scale=MatchLowercase]{Letter Gothic 12 Pitch} \setmathsfont(Latin,Digits){TeX Gyre Pagella} % Hack to prevent digits in hyperlinks from being set in the main font instead of the mono font. % From http://tex.stackexchange.com/questions/99770/problem-with-digits-in-urls-when-using-mathspec-and-hyperref % Note: doesn't matter if this is executed multiple times. \makeatletter \DeclareMathSymbol{0}{\mathalpha}{\eu@DigitsArabic@symfont}{`0} \DeclareMathSymbol{1}{\mathalpha}{\eu@DigitsArabic@symfont}{`1} \DeclareMathSymbol{2}{\mathalpha}{\eu@DigitsArabic@symfont}{`2} \DeclareMathSymbol{3}{\mathalpha}{\eu@DigitsArabic@symfont}{`3} \DeclareMathSymbol{4}{\mathalpha}{\eu@DigitsArabic@symfont}{`4} \DeclareMathSymbol{5}{\mathalpha}{\eu@DigitsArabic@symfont}{`5} \DeclareMathSymbol{6}{\mathalpha}{\eu@DigitsArabic@symfont}{`6} \DeclareMathSymbol{7}{\mathalpha}{\eu@DigitsArabic@symfont}{`7} \DeclareMathSymbol{8}{\mathalpha}{\eu@DigitsArabic@symfont}{`8} \DeclareMathSymbol{9}{\mathalpha}{\eu@DigitsArabic@symfont}{`9} \makeatother </xsl-out:text> </xsl-out:template> </xsl:when> <!-- No need for an otherwise, as weird target formats will have already been trapped by the definition of the text-encoding variable above. --> </xsl:choose> <!-- Next, output the main document body according to target format. This is generally the same across similar target formats. --> <xsl:choose> <xsl:when test="($target-format = 'html') or ($target-format = 'xhtml')"> <!-- *** (X)HTML Output *** --> <!-- Default to PNG images for web dispay. --> <xsl-out:param name="image-format"><xsl:text>png</xsl:text></xsl-out:param> <xsl-out:template match="/document"> <xsl-out:comment> THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT! </xsl-out:comment> <html> <head> <xsl-out:element name="link"> <xsl-out:attribute name="rel"> <xsl-out:text>Stylesheet</xsl-out:text> </xsl-out:attribute> <xsl-out:attribute name="href"> <xsl-out:text>https://blackboard.otago.ac.nz/bbcswebdav/courses/</xsl-out:text> <xsl-out:value-of select="$subject-code" /> <xsl-out:value-of select="$paper-number" /> <xsl-out:text>_</xsl-out:text> <xsl-out:value-of select="$period-code" /> <xsl-out:text>DNI_</xsl-out:text> <xsl-out:value-of select="$paper-year" /> <xsl-out:text>/db_styles.css</xsl-out:text> </xsl-out:attribute> <xsl-out:attribute name="type"> <xsl-out:text>text/css</xsl-out:text> </xsl-out:attribute> </xsl-out:element> <xsl-out:element name="meta"> <xsl-out:attribute name="http-equiv"> <xsl-out:text>Content-type</xsl-out:text> </xsl-out:attribute> <xsl-out:attribute name="content"> <xsl-out:text> <xsl:text>text/html;charset=</xsl:text> <xsl:value-of select="$text-encoding" /> </xsl-out:text> </xsl-out:attribute> </xsl-out:element> <title> <xsl-out:choose> <xsl-out:when test="@class = 'calendar'"> <xsl-out:value-of select="$subject-code" /> <xsl-out:value-of select="$paper-number" /> <xsl-out:text> Teaching Calendar, </xsl-out:text> <xsl-out:value-of select="$period-string" /> <xsl-out:text>, </xsl-out:text> <xsl-out:value-of select="$paper-year" /> </xsl-out:when> <xsl-out:otherwise> <xsl-out:apply-templates select="title" mode="preamble" /> </xsl-out:otherwise> </xsl-out:choose> </title> </head> <body> <xsl-out:choose> <xsl-out:when test="@class = 'calendar'" /> <xsl-out:otherwise> <xsl-out:apply-templates select="title" mode="title" /> <xsl-out:apply-templates select="date" mode="title" /> <xsl-out:apply-templates select="due-date" mode="title" /> </xsl-out:otherwise> </xsl-out:choose> <xsl-out:apply-templates /> <!-- How best to approach this - certain elements that need special handling (e.g. title, author) shouldn't be passed through here as well. --> <!-- How about we just match certain elements that we know can be handled safely, e.g. sections, paragraphs, ...? (...and their aliases?) --> <!-- Are introductions just another section, or should there be an introduction element? --> <!-- The solution is to get cleverer with our templates, e.g., multiple templates for <title> that have different match patterns (document/title, section/title). --> <!-- We also need to define an empty template for the <document-metadata> element so that its contents get ignored. --> <!-- Once these are done, we can just go apply-templates and forget about it. --> <hr /> <!-- Since HTML doesn't support footnotes as such, we instead include them as endnotes at the end of the document. --> <xsl-out:if test="count(//footnote) > 0"> <h3>Notes</h3> <xsl-out:apply-templates select="//footnote" mode="list" /> <hr /> </xsl-out:if> <xsl-out:call-template name="build-date-internal"> <xsl-out:with-param name="format">long</xsl-out:with-param> <xsl-out:with-param name="style">footer</xsl-out:with-param> </xsl-out:call-template> </body> </html> </xsl-out:template> </xsl:when> <xsl:when test="($target-format = 'latex') or ($target-format = 'xelatex')"> <!-- Set to pdf if using PDFLaTeX, otherwise eps. --> <xsl-out:param name="image-format"><xsl:text>pdf</xsl:text></xsl-out:param> <!-- Generate macro to encode the document class name. Note that if the document class loads a package that the boilerplate in this template also attempts to load, it may cause an "option clash" error. If so, the loading of that package will need to be made conditional in the boilerplate (using \@ifpackageloaded). So far this applies to the following packages: * geometry * hyperref Other packages that *might* cause similar problems (guessing here): * listings --> <xsl-out:template name="setup-document-class"> <xsl-out:text> \def\DocumentClass{</xsl-out:text> <xsl-out:value-of select="@latex-document-class" /> <xsl-out:if test="not( @latex-document-class )"> <xsl-out:text>article</xsl-out:text> </xsl-out:if> <xsl-out:text>} </xsl-out:text> </xsl-out:template> <!-- Generate macro to specify document class options. --> <xsl-out:template name="setup-class-options"> <xsl-out:text> \def\LaTeXOptions{</xsl-out:text> <xsl-out:value-of select="string-join(( if (@latex-font-size) then @latex-font-size else '12pt', if (@latex-paper-size) then @latex-paper-size else 'a4paper', @latex-class-options), ',')" /> <xsl-out:text>} </xsl-out:text> </xsl-out:template> <!-- *** (Xe)LaTeX Source Output *** --> <xsl-out:template match="/document"> <xsl-out:choose> <!-- standalone = "yes" means generate an entire valid (Xe)LaTeX source document. --> <xsl-out:when test="$standalone = 'yes'"> <xsl-out:text> % THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT! </xsl-out:text> <xsl-out:call-template name="setup-class-options" /> <xsl-out:call-template name="setup-document-class" /> <xsl-out:text> \PassOptionsToClass{\LaTeXOptions}{\DocumentClass} \documentclass{\DocumentClass} % Set up paper variables, if applicable. \makeatletter \@ifpackageloaded{lecturecommon}{\input{</xsl-out:text><xsl-out:value-of select="$paper-include-path" /><xsl-out:text>/</xsl-out:text><xsl-out:value-of select="$latex-initialisation-file" /><xsl-out:text>}} \makeatother % Avoid option clash if document class already loaded it. \makeatletter \@ifpackageloaded{geometry}{}{\usepackage[margin=1in]{geometry}} \makeatother \usepackage{multirow} \usepackage{graphicx} \usepackage{verbatim} % needed for \verbatiminput \usepackage{relalg} % needed for join operators \usepackage{pifont} \usepackage[mode=text]{siunitx} % number and SI unit formatting ([mode=text] needed to make it use the correct % maths typeface under Unicode/fontspec, otherwise it uses Computer Modern. Works % fine in non-Unicode regardless.) \usepackage{listings} % nicely formatted code listings \usepackage[normalem]{ulem} % fancy underlining, strikeout, etc. \usepackage{boxedminipage} \usepackage{parskip} % Space-separated rather than indented paragraphs. \usepackage{rotating} % Rotate stuff. </xsl-out:text> <xsl-out:call-template name="latex-preamble" /> <xsl-out:apply-templates select="environment/latex-commands" /> <xsl-out:text> \newenvironment{answer}{\par\vspace{0.5em}\itshape}{\normalfont\vspace{1.5em}} % Listings setup. We preload the most commonly used languages to speed things % up. Other languages will still work, just not quite as quickly. \lstloadlanguages{Oracle} \lstset{basicstyle=\ttfamily,basewidth=0.5em,escapeinside={(@}{@)}, showspaces=false,showstringspaces=false} </xsl-out:text> <xsl-out:apply-templates select="title" mode="preamble" /> <xsl-out:call-template name="newline-internal" /> <xsl-out:apply-templates select="author" mode="preamble" /> <xsl-out:call-template name="newline-internal" /> <xsl-out:apply-templates select="date|due-date" mode="preamble" /> <xsl-out:call-template name="newline-internal" /> <xsl-out:text> \begin{document} </xsl-out:text> <xsl-out:if test="not( @suppress-latex-title ) or ( @suppress-latex-title != 'yes' )"> <xsl-out:text> \maketitle </xsl-out:text> </xsl-out:if> <!-- Note that the generate-latex-toc attribute doesn't override anything that the document class does. If the document class generates a table of contents anyway, the value of the attribute is irrelevant. --> <xsl-out:if test="@generate-latex-toc = 'yes'"> <xsl-out:text> \tableofcontents </xsl-out:text> </xsl-out:if> <xsl-out:text> </xsl-out:text> <xsl-out:apply-templates /> <!-- If you're having problems with the build date appearing in weird or annoying locations (usually because of floating items like tables and figures), set document/@auto-latex-build-date to "no". You can then use the build-date element to insert the build date wherever you like, if necessary. This really only applies to LaTeX documents. The behaviour of HTML documents is much more predictable because they don't have elements with "minds of their own", so the build date is guaranteed to always appear at the very end. --> <xsl-out:if test="not( @auto-latex-build-date ) or ( @auto-latex-build-date != 'no' )"> <xsl-out:call-template name="build-date-internal"> <xsl-out:with-param name="format">long</xsl-out:with-param> <xsl-out:with-param name="style">footer</xsl-out:with-param> </xsl-out:call-template> </xsl-out:if> <xsl-out:text>\end{document}</xsl-out:text> </xsl-out:when> <!-- standalone = "no" means generate a (Xe)LaTeX source fragment. --> <xsl-out:otherwise> <xsl-out:apply-templates select="title" mode="chapter" /> <xsl-out:apply-templates select="*[not(self::title)]" /> <xsl-out:if test="not( @auto-latex-build-date ) or ( @auto-latex-build-date != 'no' )"> <xsl-out:call-template name="build-date-internal"> <xsl-out:with-param name="format">long</xsl-out:with-param> <xsl-out:with-param name="style">footer</xsl-out:with-param> </xsl-out:call-template> </xsl-out:if> </xsl-out:otherwise> </xsl-out:choose> </xsl-out:template> </xsl:when> <!-- No need for an otherwise, as weird formats will have already been trapped by the definition of the text-encoding variable above. --> </xsl:choose> <xsl:apply-templates /> </xsl-out:stylesheet> </xsl:template> <!-- Copy across templates according to the target format. If there's no common code for a particular format, an empty template is generated. --> <xsl:template match="template"> <xsl-out:template> <!-- Much easier to just copy all attributes across verbatim rather than copying specific named attributes, because we might want to use attributes that weren't originally anticipated. Might this be a problem in future? --> <xsl:copy-of select="@*" /> <!-- Copy across code that is common to ALL target formats. Any code not specific to a particular target format will therefore always appear FIRST in the resulting template. --> <xsl:copy-of select="common[not(@formats)]/node()" /> <!-- Copy across code that is specific to the current format. --> <xsl:copy-of select="common[contains(@formats, concat('/', $target-format, '/'))]/node()" /> <xsl:copy-of select="*[name(.) = $target-format]/node()" /> </xsl-out:template> </xsl:template> <!-- Dealing with functions is slightly more complex than templates, as functions aren't allowed to be empty. We therefore have to completely ignore function definitions that have no code for the target format. The second, more specific template will match in preference to the empty one. --> <xsl:template match="function" /> <xsl:template match="function[common[contains( @formats, concat( '/', $target-format, '/' ) )]]|function[common[not( @formats )]]"> <xsl-out:function> <!-- Much easier to just copy all attributes across verbatim rather than copying specific named attributes, because we might want to use attributes that weren't originally anticipated. Might this be a problem in future? --> <xsl:copy-of select="@*" /> <!-- Copy across code that is common to ALL target formats. Any code not specific to a particular target format will therefore always appear FIRST in the resulting template. --> <xsl:copy-of select="common[not( @formats )]/node()" /> <!-- Copy across code that is specific to the current format. --> <xsl:copy-of select="common[contains( @formats, concat( '/', $target-format, '/' ) )]/node()" /> <xsl:copy-of select="*[name( . )=$target-format]/node()" /> </xsl-out:function> </xsl:template> <!-- Include templates from a stylesheet sub-module. This enables us to modularise the master stylesheet. --> <xsl:template match="include"> <xsl:apply-templates select="document( @href )/stylesheet/*" /> </xsl:template> <!-- This template produces a template that calls another template, i.e., it implements a template alias. The generated template probably doesn't need a name, but we'll put one in anyway. --> <xsl:template match="alias"> <xsl-out:template> <xsl:attribute name="name"><xsl:value-of select="@source" /></xsl:attribute> <xsl:attribute name="match"><xsl:value-of select="@source" /></xsl:attribute> <xsl-out:call-template> <xsl:attribute name="name"><xsl:value-of select="@target" /></xsl:attribute> </xsl-out:call-template> </xsl-out:template> </xsl:template> </xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsl-out="[irrelevant]" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:infosci="http://info-nts-12.otago.ac.nz/infosci"> <!-- XSLT transformation for a master XML document defining how to transform elements in the course handbook source into HTML and LaTeX. Hmm, meta-stylesheet?! --> <xsl:output method="xml" encoding="utf-8" cdata-section-elements="html" /> <!-- What target format are we generating a styesheet for? Possible values: html, xhtml, latex (includes pdflatex), xelatex. --> <xsl:param name="target-format"><xsl:text>html</xsl:text></xsl:param> <!-- Define an alias for the xsl namespace to avoid confusion when generating xsl: elements in the output of this stylesheet. --> <xsl:namespace-alias stylesheet-prefix="xsl-out" result-prefix="xsl" /> <!-- Some useful variables. (Could some of these become callable templates?) --> <xsl:variable name="newline"> <xsl:text> </xsl:text> </xsl:variable> <xsl:variable name="space"><xsl:text> </xsl:text></xsl:variable> <!-- *** TEMPLATES *** --> <xsl:template match="/"> <xsl-out:stylesheet version="2.0"> <xsl-out:strip-space elements="*" /> <xsl-out:param name="subject-code"><xsl:text>INFO</xsl:text></xsl-out:param> <xsl-out:param name="paper-number" /> <xsl-out:param name="paper-year" select="year-from-date( current-date() )"/> <xsl-out:param name="period-code" /> <xsl-out:param name="showanswers"><xsl:text>no</xsl:text></xsl-out:param> <!-- This is normally the path to the current document directory. --> <xsl-out:param name="base-path"><xsl:text>.</xsl:text></xsl-out:param> <!-- This is normally the path to the root directory of the paper tree in the filesystem. --> <xsl-out:param name="paper-include-path"><xsl:text>.</xsl:text></xsl-out:param> <!-- This is normally the file paper_init.tex in the root of the paper tree. --> <xsl-out:param name="latex-initialisation-file"><xsl:text>paper_init</xsl:text></xsl-out:param> <!-- Full period string corresponding to the supplied period code. --> <xsl-out:variable name="period-string" select="infosci:expand-period-code( $period-code )" /> <!-- The date and time when the document was last built. --> <xsl-out:variable name="date-built" select="current-dateTime()" /> <!-- Get the name of the document being processed. --> <xsl-out:variable name="document-name" select="reverse( tokenize( base-uri(), '/' ) )[1]" /> <!-- Include the generated Oracle documentation code. --> <xsl-out:include href="oracle-docs.xsl" /> <!-- Boilerplate (Xe)LaTeX code for loading hyperref. If the package is already loaded (by the document class), attempting to load it again will cause an "option clash" error. To avoid this, check first whether it's already loaded. We apply the required settings afterwards regardless. --> <xsl-out:variable name="latex-hyperref-boilerplate"> <xsl-out:text> % Avoid option clash if document class already loaded it. \makeatletter \@ifpackageloaded{hyperref}{}{\usepackage{hyperref}} \makeatother % Safer to specify the hyperref options directly rather than relying on % the default hyperref.cfg, as XeLaTeX seems to ignore it :(. \hypersetup{pdfpagemode=UseNone,colorlinks,urlcolor=blue,citecolor=blue,% linkcolor=blue,breaklinks} </xsl-out:text> </xsl-out:variable> <!-- We're going to use the text encoding in a few different places, so let's work out what it should be now. --> <xsl:variable name="text-encoding"> <xsl:choose> <xsl:when test="($target-format = 'latex') or ($target-format = 'html')"> <xsl:text>iso-8859-1</xsl:text> </xsl:when> <xsl:when test="($target-format = 'xelatex') or ($target-format = 'xhtml')"> <xsl:text>utf-8</xsl:text> </xsl:when> <xsl:otherwise> <xsl:message terminate="yes"> <xsl:text>Sorry, unknown target format: </xsl:text><xsl:value-of select="$target-format" /> </xsl:message> </xsl:otherwise> </xsl:choose> </xsl:variable> <!-- First, output the document preamble according to target format. This is generally different for each target format. --> <xsl:choose> <!-- The HTML formats are fairly simple: the only things that change are the doctypes, version number and text encoding. --> <xsl:when test="$target-format = 'html'"> <xsl-out:output method="html" encoding="{$text-encoding}" version="4.01" media-type="text/html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" doctype-system="http://www.w3.org/TR/html4/loose.dtd" /> </xsl:when> <xsl:when test="$target-format = 'xhtml'"> <xsl-out:output method="xml" encoding="{$text-encoding}" byte-order-mark="no" version="1.1" media-type="text/html" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" /> </xsl:when> <!-- The LaTeX formats, however have a bunch of miscellaneous boilerplate that appears at the start of every document, and requires more complex interleaving because of hyperref. Since we need to stuff this into a template later on, we define this using a callable template, so that we can do useful things like apply-templates within it (which wouldn't work if we just used a variable). --> <xsl:when test="$target-format = 'latex'"> <xsl-out:output method="text" encoding="{$text-encoding}" media-type="text/plain" /> <!-- Set to no if you want this to be included inside another document. Appears here because it's used in the document preamble. --> <xsl-out:param name="standalone"><xsl:text>yes</xsl:text></xsl-out:param> <xsl-out:template name="latex-preamble"> <xsl-out:text> \usepackage{mathpazo} % mathpple is deprecated \usepackage[T1]{fontenc} \usepackage{textcomp} </xsl-out:text> <xsl-out:apply-templates select="environment/latex-packages" /> <xsl-out:value-of select="$latex-hyperref-boilerplate" /> <xsl-out:text> \renewcommand{\ttdefault}{blg} </xsl-out:text> </xsl-out:template> </xsl:when> <xsl:when test="$target-format = 'xelatex'"> <xsl-out:output method="text" encoding="{$text-encoding}" media-type="text/plain" /> <!-- Set to no if you want this to be included inside another document. Appears here because it's used in the document preamble. --> <xsl-out:param name="standalone"><xsl:text>yes</xsl:text></xsl-out:param> <xsl-out:template name="latex-preamble"> <xsl-out:text> \usepackage[no-math]{fontspec} \usepackage{mathspec} \usepackage{xunicode} \usepackage{xltxtra} \usepackage{textcomp} % ??? </xsl-out:text> <xsl-out:apply-templates select="environment/latex-packages" /> <xsl-out:value-of select="$latex-hyperref-boilerplate" /> <xsl-out:text> \defaultfontfeatures{Mapping=tex-text} \setmainfont{TeX Gyre Pagella} \setsansfont[Scale=MatchUppercase,BoldFont={Gill Sans}]{Gill Sans Light} \setmonofont[Scale=MatchLowercase]{Letter Gothic 12 Pitch} \setmathsfont(Latin,Digits){TeX Gyre Pagella} % Hack to prevent digits in hyperlinks from being set in the main font instead of the mono font. % From http://tex.stackexchange.com/questions/99770/problem-with-digits-in-urls-when-using-mathspec-and-hyperref % Note: doesn't matter if this is executed multiple times. \makeatletter \DeclareMathSymbol{0}{\mathalpha}{\eu@DigitsArabic@symfont}{`0} \DeclareMathSymbol{1}{\mathalpha}{\eu@DigitsArabic@symfont}{`1} \DeclareMathSymbol{2}{\mathalpha}{\eu@DigitsArabic@symfont}{`2} \DeclareMathSymbol{3}{\mathalpha}{\eu@DigitsArabic@symfont}{`3} \DeclareMathSymbol{4}{\mathalpha}{\eu@DigitsArabic@symfont}{`4} \DeclareMathSymbol{5}{\mathalpha}{\eu@DigitsArabic@symfont}{`5} \DeclareMathSymbol{6}{\mathalpha}{\eu@DigitsArabic@symfont}{`6} \DeclareMathSymbol{7}{\mathalpha}{\eu@DigitsArabic@symfont}{`7} \DeclareMathSymbol{8}{\mathalpha}{\eu@DigitsArabic@symfont}{`8} \DeclareMathSymbol{9}{\mathalpha}{\eu@DigitsArabic@symfont}{`9} \makeatother </xsl-out:text> </xsl-out:template> </xsl:when> <!-- No need for an otherwise, as weird target formats will have already been trapped by the definition of the text-encoding variable above. --> </xsl:choose> <!-- Next, output the main document body according to target format. This is generally the same across similar target formats. --> <xsl:choose> <xsl:when test="($target-format = 'html') or ($target-format = 'xhtml')"> <!-- *** (X)HTML Output *** --> <!-- Default to PNG images for web dispay. --> <xsl-out:param name="image-format"><xsl:text>png</xsl:text></xsl-out:param> <xsl-out:template match="/document"> <xsl-out:comment> THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT! </xsl-out:comment> <html> <head> <xsl-out:element name="link"> <xsl-out:attribute name="rel"> <xsl-out:text>Stylesheet</xsl-out:text> </xsl-out:attribute> <xsl-out:attribute name="href"> <xsl-out:text>https://blackboard.otago.ac.nz/bbcswebdav/courses/</xsl-out:text> <xsl-out:value-of select="$subject-code" /> <xsl-out:value-of select="$paper-number" /> <xsl-out:text>_</xsl-out:text> <xsl-out:value-of select="$period-code" /> <xsl-out:text>DNI_</xsl-out:text> <xsl-out:value-of select="$paper-year" /> <xsl-out:text>/db_styles.css</xsl-out:text> </xsl-out:attribute> <xsl-out:attribute name="type"> <xsl-out:text>text/css</xsl-out:text> </xsl-out:attribute> </xsl-out:element> <xsl-out:element name="meta"> <xsl-out:attribute name="http-equiv"> <xsl-out:text>Content-type</xsl-out:text> </xsl-out:attribute> <xsl-out:attribute name="content"> <xsl-out:text> <xsl:text>text/html;charset=</xsl:text> <xsl:value-of select="$text-encoding" /> </xsl-out:text> </xsl-out:attribute> </xsl-out:element> <title> <xsl-out:choose> <xsl-out:when test="@class = 'calendar'"> <xsl-out:value-of select="$subject-code" /> <xsl-out:value-of select="$paper-number" /> <xsl-out:text> Teaching Calendar, </xsl-out:text> <xsl-out:value-of select="$period-string" /> <xsl-out:text>, </xsl-out:text> <xsl-out:value-of select="$paper-year" /> </xsl-out:when> <xsl-out:otherwise> <xsl-out:apply-templates select="title" mode="preamble" /> </xsl-out:otherwise> </xsl-out:choose> </title> </head> <body> <xsl-out:choose> <xsl-out:when test="@class = 'calendar'" /> <xsl-out:otherwise> <xsl-out:apply-templates select="title" mode="title" /> <xsl-out:apply-templates select="date" mode="title" /> <xsl-out:apply-templates select="due-date" mode="title" /> </xsl-out:otherwise> </xsl-out:choose> <xsl-out:apply-templates /> <!-- How best to approach this - certain elements that need special handling (e.g. title, author) shouldn't be passed through here as well. --> <!-- How about we just match certain elements that we know can be handled safely, e.g. sections, paragraphs, ...? (...and their aliases?) --> <!-- Are introductions just another section, or should there be an introduction element? --> <!-- The solution is to get cleverer with our templates, e.g., multiple templates for <title> that have different match patterns (document/title, section/title). --> <!-- We also need to define an empty template for the <document-metadata> element so that its contents get ignored. --> <!-- Once these are done, we can just go apply-templates and forget about it. --> <hr /> <!-- Since HTML doesn't support footnotes as such, we instead include them as endnotes at the end of the document. --> <xsl-out:if test="count(//footnote) > 0"> <h3>Notes</h3> <xsl-out:apply-templates select="//footnote" mode="list" /> <hr /> </xsl-out:if> <xsl-out:call-template name="build-date-internal"> <xsl-out:with-param name="format">long</xsl-out:with-param> <xsl-out:with-param name="style">footer</xsl-out:with-param> </xsl-out:call-template> </body> </html> </xsl-out:template> </xsl:when> <xsl:when test="($target-format = 'latex') or ($target-format = 'xelatex')"> <!-- Set to pdf if using PDFLaTeX, otherwise eps. --> <xsl-out:param name="image-format"><xsl:text>pdf</xsl:text></xsl-out:param> <!-- Generate macro to encode the document class name. Note that if the document class loads a package that the boilerplate in this template also attempts to load, it may cause an "option clash" error. If so, the loading of that package will need to be made conditional in the boilerplate (using \@ifpackageloaded). So far this applies to the following packages: * geometry * hyperref Other packages that *might* cause similar problems (guessing here): * listings --> <xsl-out:template name="setup-document-class"> <xsl-out:text> \def\DocumentClass{</xsl-out:text> <xsl-out:value-of select="@latex-document-class" /> <xsl-out:if test="not( @latex-document-class )"> <xsl-out:text>article</xsl-out:text> </xsl-out:if> <xsl-out:text>} </xsl-out:text> </xsl-out:template> <!-- Generate macro to specify document class options. --> <xsl-out:template name="setup-class-options"> <xsl-out:text> \def\LaTeXOptions{</xsl-out:text> <xsl-out:value-of select="string-join(( if (@latex-font-size) then @latex-font-size else '12pt', if (@latex-paper-size) then @latex-paper-size else 'a4paper', @latex-class-options), ',')" /> <xsl-out:text>} </xsl-out:text> </xsl-out:template> <!-- *** (Xe)LaTeX Source Output *** --> <xsl-out:template match="/document"> <xsl-out:choose> <!-- standalone = "yes" means generate an entire valid (Xe)LaTeX source document. --> <xsl-out:when test="$standalone = 'yes'"> <xsl-out:text> % THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT! </xsl-out:text> <xsl-out:call-template name="setup-class-options" /> <xsl-out:call-template name="setup-document-class" /> <xsl-out:text> \PassOptionsToClass{\LaTeXOptions}{\DocumentClass} \documentclass{\DocumentClass} % Set up paper variables, if applicable. \makeatletter \@ifpackageloaded{lecturecommon}{\input{</xsl-out:text><xsl-out:value-of select="$paper-include-path" /><xsl-out:text>/</xsl-out:text><xsl-out:value-of select="$latex-initialisation-file" /><xsl-out:text>}} \makeatother % Avoid option clash if document class already loaded it. \makeatletter \@ifpackageloaded{geometry}{}{\usepackage[margin=1in]{geometry}} \makeatother \usepackage{multirow} \usepackage{graphicx} \usepackage{verbatim} % needed for \verbatiminput \usepackage{relalg} % needed for join operators \usepackage{pifont} \usepackage{siunitx} % number and SI unit formatting \usepackage{listings} % nicely formatted code listings \usepackage[normalem]{ulem} % fancy underlining, strikeout, etc. \usepackage{boxedminipage} \usepackage{parskip} % Space-separated rather than indented paragraphs. \usepackage{rotating} % Rotate stuff. </xsl-out:text> <xsl-out:call-template name="latex-preamble" /> <xsl-out:apply-templates select="environment/latex-commands" /> <xsl-out:text> \newenvironment{answer}{\par\vspace{0.5em}\itshape}{\normalfont\vspace{1.5em}} % Listings setup. We preload the most commonly used languages to speed things % up. Other languages will still work, just not quite as quickly. \lstloadlanguages{Oracle} \lstset{basicstyle=\ttfamily,basewidth=0.5em,escapeinside={(@}{@)}, showspaces=false,showstringspaces=false} </xsl-out:text> <xsl-out:apply-templates select="title" mode="preamble" /> <xsl-out:call-template name="newline-internal" /> <xsl-out:apply-templates select="author" mode="preamble" /> <xsl-out:call-template name="newline-internal" /> <xsl-out:apply-templates select="date|due-date" mode="preamble" /> <xsl-out:call-template name="newline-internal" /> <xsl-out:text> \begin{document} </xsl-out:text> <xsl-out:if test="not( @suppress-latex-title ) or ( @suppress-latex-title != 'yes' )"> <xsl-out:text> \maketitle </xsl-out:text> </xsl-out:if> <!-- Note that the generate-latex-toc attribute doesn't override anything that the document class does. If the document class generates a table of contents anyway, the value of the attribute is irrelevant. --> <xsl-out:if test="@generate-latex-toc = 'yes'"> <xsl-out:text> \tableofcontents </xsl-out:text> </xsl-out:if> <xsl-out:text> </xsl-out:text> <xsl-out:apply-templates /> <!-- If you're having problems with the build date appearing in weird or annoying locations (usually because of floating items like tables and figures), set document/@auto-latex-build-date to "no". You can then use the build-date element to insert the build date wherever you like, if necessary. This really only applies to LaTeX documents. The behaviour of HTML documents is much more predictable because they don't have elements with "minds of their own", so the build date is guaranteed to always appear at the very end. --> <xsl-out:if test="not( @auto-latex-build-date ) or ( @auto-latex-build-date != 'no' )"> <xsl-out:call-template name="build-date-internal"> <xsl-out:with-param name="format">long</xsl-out:with-param> <xsl-out:with-param name="style">footer</xsl-out:with-param> </xsl-out:call-template> </xsl-out:if> <xsl-out:text>\end{document}</xsl-out:text> </xsl-out:when> <!-- standalone = "no" means generate a (Xe)LaTeX source fragment. --> <xsl-out:otherwise> <xsl-out:apply-templates select="title" mode="chapter" /> <xsl-out:apply-templates select="*[not(self::title)]" /> <xsl-out:if test="not( @auto-latex-build-date ) or ( @auto-latex-build-date != 'no' )"> <xsl-out:call-template name="build-date-internal"> <xsl-out:with-param name="format">long</xsl-out:with-param> <xsl-out:with-param name="style">footer</xsl-out:with-param> </xsl-out:call-template> </xsl-out:if> </xsl-out:otherwise> </xsl-out:choose> </xsl-out:template> </xsl:when> <!-- No need for an otherwise, as weird formats will have already been trapped by the definition of the text-encoding variable above. --> </xsl:choose> <xsl:apply-templates /> </xsl-out:stylesheet> </xsl:template> <!-- Copy across templates according to the target format. If there's no common code for a particular format, an empty template is generated. --> <xsl:template match="template"> <xsl-out:template> <!-- Much easier to just copy all attributes across verbatim rather than copying specific named attributes, because we might want to use attributes that weren't originally anticipated. Might this be a problem in future? --> <xsl:copy-of select="@*" /> <!-- Copy across code that is common to ALL target formats. Any code not specific to a particular target format will therefore always appear FIRST in the resulting template. --> <xsl:copy-of select="common[not(@formats)]/node()" /> <!-- Copy across code that is specific to the current format. --> <xsl:copy-of select="common[contains(@formats, concat('/', $target-format, '/'))]/node()" /> <xsl:copy-of select="*[name(.) = $target-format]/node()" /> </xsl-out:template> </xsl:template> <!-- Dealing with functions is slightly more complex than templates, as functions aren't allowed to be empty. We therefore have to completely ignore function definitions that have no code for the target format. The second, more specific template will match in preference to the empty one. --> <xsl:template match="function" /> <xsl:template match="function[common[contains( @formats, concat( '/', $target-format, '/' ) )]]|function[common[not( @formats )]]"> <xsl-out:function> <!-- Much easier to just copy all attributes across verbatim rather than copying specific named attributes, because we might want to use attributes that weren't originally anticipated. Might this be a problem in future? --> <xsl:copy-of select="@*" /> <!-- Copy across code that is common to ALL target formats. Any code not specific to a particular target format will therefore always appear FIRST in the resulting template. --> <xsl:copy-of select="common[not( @formats )]/node()" /> <!-- Copy across code that is specific to the current format. --> <xsl:copy-of select="common[contains( @formats, concat( '/', $target-format, '/' ) )]/node()" /> <xsl:copy-of select="*[name( . )=$target-format]/node()" /> </xsl-out:function> </xsl:template> <!-- Include templates from a stylesheet sub-module. This enables us to modularise the master stylesheet. --> <xsl:template match="include"> <xsl:apply-templates select="document( @href )/stylesheet/*" /> </xsl:template> <!-- This template produces a template that calls another template, i.e., it implements a template alias. The generated template probably doesn't need a name, but we'll put one in anyway. --> <xsl:template match="alias"> <xsl-out:template> <xsl:attribute name="name"><xsl:value-of select="@source" /></xsl:attribute> <xsl:attribute name="match"><xsl:value-of select="@source" /></xsl:attribute> <xsl-out:call-template> <xsl:attribute name="name"><xsl:value-of select="@target" /></xsl:attribute> </xsl-out:call-template> </xsl-out:template> </xsl:template> </xsl:stylesheet>
Show line notes below