%PDF- %PDF-
Direktori : /usr/share/yelp-xsl/xslt/common/ |
Current File : //usr/share/yelp-xsl/xslt/common/html.xsl |
<?xml version='1.0' encoding='UTF-8'?><!-- -*- indent-tabs-mode: nil -*- --> <!-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/>. --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:exsl="http://exslt.org/common" xmlns:set="http://exslt.org/sets" xmlns:str="http://exslt.org/strings" xmlns:its="http://www.w3.org/2005/11/its" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="html mml set str its" extension-element-prefixes="exsl" version="1.0"> <!--!!========================================================================== HTML Output Common utilities and CSS for transformations to HTML. @revision[version=1.0 date=2010-05-26 status=final] This stylesheet contains common templates for creating HTML output. The {html.output} template creates an output file for a node in the source XML document, calling {html.page} to create the actual output. Output files can be either XHTML or HTML, depending on the {html.xhtml} parameter. This stylesheet matches `/` and calls {html.output} on the root XML element. This works for most input formats. If you need to do something different, you should override the match for `/`. --> <xsl:template match="/"> <xsl:call-template name="html.output"> <xsl:with-param name="node" select="*"/> </xsl:call-template> </xsl:template> <!--@@========================================================================== html.basename The base filename of the primary output file. @revision[version=1.0 date=2010-05-25 status=final] This parameter specifies the base filename of the primary output file, without the filename extension. This is used by {html.output} to determine the output filename, and may be used by format-specific linking code. By default, it uses the value of an `id` or `xml:id` attribute, if present. Otherwise, it uses the static string `index`. --> <xsl:param name="html.basename"> <xsl:choose> <xsl:when test="/*/@xml:id"> <xsl:value-of select="/*/@xml:id"/> </xsl:when> <xsl:when test="/*/@id"> <xsl:value-of select="/*/@id"/> </xsl:when> <xsl:otherwise> <xsl:text>index</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:param> <!--@@========================================================================== html.xhtml Whether to output XHTML. @revision[version=1.0 date=2010-05-25 status=final] If this parameter is set to true, this stylesheet will output XHTML. Otherwise, the output is assumed to be HTML. Note that for HTML output, the importing stylesheet still needs to call `xsl:namespace-alias` to map the XHTML namespace to `#default`. The {html.namespace} parameter will be set automatically based on this parameter. Stylesheets can use this parameter to check the output type, for example when using `xsl:element`. --> <xsl:param name="html.xhtml" select="true()"/> <!--@@========================================================================== html.namespace The XML namespace for the output document. @revision[version=1.0 date=2010-05-25 status=final] This parameter specifies the XML namespace of all output documents. It will be set automatically based on the {html.xhtml} parameter, either to the XHTML namespace, or to the empty namespace. Stylesheets can use this parameter when using `xsl:element`. --> <xsl:param name="html.namespace"> <xsl:choose> <xsl:when test="$html.xhtml"> <xsl:value-of select="'http://www.w3.org/1999/xhtml'"/> </xsl:when> <xsl:otherwise> <xsl:text></xsl:text> </xsl:otherwise> </xsl:choose> </xsl:param> <!--@@========================================================================== html.mathml.namespace The XML namespace for MathML in the output document. @revision[version=3.18 date=2015-05-04 status=final] This parameter specifies the XML namespace for MathML in output documents. It will be set automatically based on the {html.xhtml} parameter, either to the MathML namespace namespace, or to the empty namespace. Stylesheets can use this parameter when using `xsl:element`. --> <xsl:param name="html.mathml.namespace"> <xsl:choose> <xsl:when test="$html.xhtml"> <xsl:value-of select="'http://www.w3.org/1998/Math/MathML'"/> </xsl:when> <xsl:otherwise> <xsl:text></xsl:text> </xsl:otherwise> </xsl:choose> </xsl:param> <!--@@========================================================================== html.svg.namespace The XML namespace for SVG in the output document. @revision[version=3.18 date=2015-05-04 status=final] This parameter specifies the XML namespace for SVG in output documents. It will be set automatically based on the {html.xhtml} parameter, either to the SVG namespace namespace, or to the empty namespace. Stylesheets can use this parameter when using `xsl:element`. --> <xsl:param name="html.svg.namespace"> <xsl:choose> <xsl:when test="$html.xhtml"> <xsl:value-of select="'http://www.w3.org/2000/svg'"/> </xsl:when> <xsl:otherwise> <xsl:text></xsl:text> </xsl:otherwise> </xsl:choose> </xsl:param> <!--@@========================================================================== html.extension The filename extension for all output files. @revision[version=1.0 date=2010-05-25 status=final] This parameter specifies a filename extension for all HTML output files. It should include the leading dot. By default, `.xhtml` will be used if {html.xhtml} is true; otherwise, `.html` will be used. --> <xsl:param name="html.extension"> <xsl:choose> <xsl:when test="$html.xhtml"> <xsl:text>.xhtml</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>.html</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:param> <!--@@========================================================================== html.grid.size The width of the page for grid layouts. @revision[version=40 date=2021-01-09 status=final] This parameter sets the width of the main page content, including padding, but excluding any sidebars. These stylesheets frequently use flexible grids for layouts, and columnds are based on this parameter. This parameter should be a multiple of 12 for best results. Common grid sizes are 1200, 1080, and 960. --> <xsl:param name="html.grid.size" select="1080"/> <xsl:variable name="html.grid.col1" select="$html.grid.size - 20"/> <xsl:variable name="html.grid.col2" select="$html.grid.size div 2 - 20"/> <xsl:variable name="html.grid.col3" select="$html.grid.size div 3 - 20"/> <xsl:variable name="html.grid.col4" select="$html.grid.size div 4 - 20"/> <!--@@========================================================================== html.css.root The URI root for external CSS files. @revision[version=1.0 date=2010-12-06 status=final] This parameter provides a root URI for any external CSS files that are referenced from the output HTML file. If non-empty, it must end with a trailing slash character. --> <xsl:param name="html.css.root" select="''"/> <!--@@========================================================================== html.js.root The URI root for external JavaScript files. @revision[version=1.0 date=2010-12-06 status=final] This parameter provides a root URI for any external JavaScript files that are referenced from the output HTML file. If non-empty, it must end with a trailing slash character. --> <xsl:param name="html.js.root" select="''"/> <!--@@========================================================================== html.syntax.highlight Whether to include syntax highlighting support for code blocks. @revision[version=1.0 date=2010-12-06 status=final] This parameter specifies whether syntax highlighting should be enabled for code blocks in the output HTML. Syntax highlighting is done at document load time by JavaScript. --> <xsl:param name="html.syntax.highlight" select="true()"/> <!--@@========================================================================== html.output.prefix An optional path prefix for files output with {html.output}. @revision[version=3.28 date=2017-05-24 status=final] This parameter allows you to specify an prefix to place before the output path used by {html.output} when creating files. You can use this to override the output directory. Make sure you include a trailing slash, unless you want to prefix the base file name itself. --> <xsl:param name="html.output.prefix" select="''"/> <!--@@========================================================================== html.sidebar.left List of components to add to the left sidebar. @revision[version=3.30 date=2018-06-10 status=candidate] This parameter takes a space-separated list of tokens that specify which components to add to the stock left sidebar. These stylesheets recognize certain tokens, and you can add your own with {html.sidebar.mode}. See {html.sidebar} for further details. --> <xsl:param name="html.sidebar.left" select="''"/> <!--@@========================================================================== html.sidebar.right List of components to add to the right sidebar. @revision[version=3.30 date=2018-06-10 status=candidate] This parameter takes a space-separated list of tokens that specify which components to add to the stock right sidebar. These stylesheets recognize certain tokens, and you can add your own with {html.sidebar.mode}. See {html.sidebar} for further details. --> <xsl:param name="html.sidebar.right" select="''"/> <!--**========================================================================== html.output Create an HTML output file. @revision[version=1.0 date=2010-05-26 status=final] [xsl:params] $node: The node to create an output file for. $href: The output filename. This template creates an HTML output file for the source element $node. It uses `exsl:document` to output the file, and calls {html.page} with the $node parameter to output the actual HTML contents. If $href is not provided, this template will attempt to generate a base filename and append {html.extension} to it. The base filename is generated as follows: * If an `xml:id` attribute is present, it is used. * Otherwise, if an `id` attribute is present, it is used. * Otherwise, if $node is the root element, {html.basename} is used. * Otherwise, `generate-id()` is called. This template prepends {html.output.prefix} to the value of $href when it calls `exsl:document`, regardless of whether $href was passed in or generated automatically. After calling `exsl:document`, this template calls the {html.output.after.mode} mode on $node. Importing stylesheets that create multiple output files can use this to process output files without blocking earlier output. --> <xsl:template name="html.output"> <xsl:param name="node" select="."/> <xsl:param name="href"> <xsl:choose> <xsl:when test="$node/@xml:id"> <xsl:value-of select="concat($node/@xml:id, $html.extension)"/> </xsl:when> <xsl:when test="$node/@id"> <xsl:value-of select="concat($node/@id, $html.extension)"/> </xsl:when> <xsl:when test="set:has-same-node($node, /*)"> <xsl:value-of select="concat($html.basename, $html.extension)"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="concat(generate-id(), $html.extension)"/> </xsl:otherwise> </xsl:choose> </xsl:param> <xsl:choose> <xsl:when test="$html.xhtml"> <exsl:document href="{$html.output.prefix}{$href}"> <xsl:call-template name="html.page"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </exsl:document> </xsl:when> <xsl:otherwise> <exsl:document href="{$html.output.prefix}{$href}" method="html" doctype-system="about:legacy-compat"> <xsl:call-template name="html.page"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </exsl:document> </xsl:otherwise> </xsl:choose> <xsl:apply-templates mode="html.output.after.mode" select="$node"/> </xsl:template> <!--%%========================================================================== html.output.after.mode Process an element after its content are output. @revision[version=1.0 date=2010-05-26 status=final] This mode is called by {html.output} after `exsl:document` has finished. It can be used to create further output files without blocking the output of parent elements. --> <xsl:template mode="html.output.after.mode" match="*"/> <!--**========================================================================== html.page Create an HTML document. @revision[version=3.28 date=2017-08-04 status=final] [xsl:params] $node: The node to create HTML for. This template creates the actual HTML output for $node. It outputs top-level elements and container divs, and calls various templates and modes to output the inner content. Importing stylesheets should implement at least {html.title.mode} and {html.body.mode} for any elements that could be passed as $node to this template. Importing stylesheets should also implement {html.header.mode} to output link trails and {html.footer.mode} to output credits and other page information. This template outputs the HTML `body` element, which takes its attributes from two sources. First, it calls {html.lang.attrs}, which automatically outputs correct `lang`, `xml:lang`, and `dir` attributes. It then calls {html.body.attr.mode} on $node for additional attributes. This template also calls a number of stub templates that can be overridden by extension stylesheets. * Override the {html.head.custom} template to put custom content at the end of the HTML `head` element. * Override the {html.head.top.custom} template to put custom content at the beginning of the HTML `head` element. * Override the {html.top.custom} and {html.bottom.custom} templates to add site-specific content at the top and bottom of the page. * Override the {html.header.custom} and {html.footer.custom} templates to provide additional content directoy above and below the main content. * Use the {html.sidebar.left} and {html.sidebar.right} parameters to create stock sidebars, or override {html.sidebar.custom} to create your own. This template also calls {html.css} and {html.js} to output CSS and JavaScript elements. See those templates for further extension points. --> <xsl:template name="html.page"> <xsl:param name="node" select="."/> <html> <head> <xsl:call-template name="html.head.top.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"/> <title> <xsl:apply-templates mode="html.title.mode" select="$node"/> </title> <xsl:call-template name="html.css"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:call-template name="html.js"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:call-template name="html.head.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </head> <body> <xsl:call-template name="html.lang.attrs"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:apply-templates mode="html.body.attr.mode" select="$node"/> <xsl:call-template name="html.top.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <main> <xsl:call-template name="html.sidebar"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:call-template name="html.sidebar.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <div class="page"> <header> <div class="inner pagewide"> <xsl:call-template name="html.header.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:apply-templates mode="html.header.mode" select="$node"/> </div> </header> <article> <xsl:apply-templates mode="html.body.mode" select="$node"/> </article> <footer> <div class="inner pagewide"> <xsl:apply-templates mode="html.footer.mode" select="$node"/> <xsl:call-template name="html.footer.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </div> </footer> </div> </main> <xsl:call-template name="html.bottom.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </body> </html> </xsl:template> <!--%%========================================================================== html.title.mode Output the title of an element. @revision[version=1.0 date=2010-05-26 status=final] This mode is called by {html.page} to output the contents of the HTML `title` element inside the `head` element. Importing stylesheets should implement this mode for any element that will be passed to {html.page}. Because this is used in the `head`, the output should be text-only. --> <xsl:template mode="html.title.mode" match="*"/> <!--%%========================================================================== html.body.attr.mode Output attributes for the HTML `body` element. @revision[version=1.0 date=2010-06-08 status=final] This mode is called by {html.page} to output attributes on the HTML `body` element. No attributes are output by default. Importing stylesheets may implement this node to add attributes for styling, data, or other purposes. --> <xsl:template mode="html.body.attr.mode" match="*"/> <!--**========================================================================== html.top.custom Stub to output HTML at the top of the page. @xsl:stub @revision[version=3.28 date=2017-05-24 status=final] [xsl:params] $node: The node a page is being created for. This template is a stub, called by {html.page}. It is called before the `main` element. Override this template to provide site-specific HTML at the top of the page. --> <xsl:template name="html.top.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.bottom.custom Stub to output HTML at the bottom of the page. @xsl:stub @revision[version=3.28 date=2017-05-24 status=final] [xsl:params] $node: The node a page is being created for. This template is a stub, called by {html.page}. It is called after the `main` element. Override this template to provide site-specific HTML at the bottom of the page. --> <xsl:template name="html.bottom.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.sidebar Output stock sidebars. @revision[version=3.30 date=2018-06-10 status=candidate] [xsl:params] $node: The node a sidebar is being created for. This templates outputs left and right sidebars according to the components listed in {html.sidebar.left} and {html.sidebar.right}. It only outputs each sidebar if the corresponding parameters is not empty or the string `none`. This template is called inside the `main` element, before the `div.page` element, and before {html.sidebar.custom}. Note that even the right sidebar is placed before the `div.page` element. It is placed on the right using flexbox item reordering. To actually output the sidebar components, this template splits each parameter on whitespace using the EXSLT `str:split` function. It then applies the mode {html.sidebar.mode} to each token, passing $node and the sidebar side as parameters. Extension stylesheets can add their own sidebar components by implementing that mode and matching a pattern like [code] token[. = 'name-of-token'] You will then be able to use `name-of-token` in {html.sidebar.left} or {html.sidebar.right}. This stylesheet recognizes four tokens: `contents` and `sections`, and the special tokens `none` and `blank`. * The `contents` token provides a table of contents for the entire document. It is handled by the {html.sidebar.contents} template, which uses the {html.sidebar.contents.mode} mode to allow different input formats to implement it. * The `sections` token lists sections on the current page. It is handled by the html.sidebar.section} template, which uses the {html.sidebar.sections.mode} mode to allow different input formats to implement it. * Use the `none` token on its own, instead of the empty string, to completely turn off either sidebar. * Use the `blank` token to output a sidebar without adding any components to it. This is useful, for example, to keep consistent margins. If an empty sidebar is output from the `blank` token, it will also have the CSS class `sidebar-blank` so you can style it differently. --> <xsl:template name="html.sidebar"> <xsl:param name="node" select="."/> <xsl:if test="$html.sidebar.left != '' and $html.sidebar.left != 'none'"> <xsl:call-template name="_html.sidebar.sidebar"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="side" select="'left'"/> <xsl:with-param name="bars" select="$html.sidebar.left"/> </xsl:call-template> </xsl:if> <xsl:if test="$html.sidebar.right != '' and $html.sidebar.right != 'none'"> <xsl:call-template name="_html.sidebar.sidebar"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="side" select="'right'"/> <xsl:with-param name="bars" select="$html.sidebar.right"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="_html.sidebar.sidebar"> <xsl:param name="node"/> <xsl:param name="side"/> <xsl:param name="bars"/> <xsl:variable name="class"> <xsl:text>sidebar sidebar-</xsl:text> <xsl:value-of select="$side"/> <xsl:if test="$bars = 'blank'"> <xsl:text> sidebar-blank</xsl:text> </xsl:if> </xsl:variable> <aside class="{$class}"> <xsl:apply-templates mode="html.sidebar.mode" select="str:split($bars)"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="side" select="$side"/> </xsl:apply-templates> </aside> </xsl:template> <!--%%========================================================================== html.sidebar.mode Output a sidebar compenent for a token. @revision[version=3.30 date=2018-06-10 status=candidate] [xsl:params] $node: The node a sidebar is being created for. $side: Which sidebar, either `left` or `right`. This mode is called by {html.sidebar} for each sidebar compenent in each of {html.sidebar.left} and {html.sidebar.right}. See {html.sidebar} for full details. --> <xsl:template mode="html.sidebar.mode" match="token[. = 'blank']"/> <xsl:template mode="html.sidebar.mode" match="*"> <xsl:message> <xsl:text>Unmatched sidebar: </xsl:text> <xsl:value-of select="."/> </xsl:message> </xsl:template> <!--**========================================================================== html.sidebar.contents Output a table of contents for a sidebar. @revision[version=3.30 date=2018-06-10 status=candidate] [xsl:params] $node: The node a sidebar is being created for. $side: Which sidebar, either `left` or `right`. This template creates a table of contents for a sidebar. It applies {html.sidebar.contents.mode} to $node, passing $side as a parameter, to allow individual input formats to implement tables of contents. This named template also implements {html.sidebar.mode} on the `contents` token. See {html.sidebar} for more information on how sidebars are created. --> <xsl:template name="html.sidebar.contents" mode="html.sidebar.mode" match="token[. = 'contents']"> <xsl:param name="node"/> <xsl:param name="side"/> <xsl:apply-templates mode="html.sidebar.contents.mode" select="$node"> <xsl:with-param name="side" select="$side"/> </xsl:apply-templates> </xsl:template> <!--%%========================================================================== html.sidebar.contents.mode Output a table of contents for a sidebar. @revision[version=3.30 date=2018-06-10 status=candidate] [xsl:params] $side: Which sidebar, either `left` or `right`. This mode is called by {html.sidebar.contents} to allow different input formats to implement a table of contents for a sidebar. --> <xsl:template mode="html.sidebar.contents.mode" match="*"> <xsl:param name="side"/> <xsl:message> <xsl:text>Unmatched contents sidebar: </xsl:text> <xsl:value-of select="local-name(.)"/> </xsl:message> </xsl:template> <!--**========================================================================== html.sidebar.sections Output a list of sections for a sidebar. @revision[version=3.30 date=2018-06-10 status=candidate] [xsl:params] $node: The node a sidebar is being created for. $side: Which sidebar, either `left` or `right`. This template creates a list of sections on the current page for a sidebar. It applies {html.sidebar.sections.mode} to $node, passing $side as a parameter, to allow individual input formats to implement sections lists. This named template also implements {html.sidebar.mode} on the `sections` token. See {html.sidebar} for more information on how sidebars are created. --> <xsl:template name="html.sidebar.sections" mode="html.sidebar.mode" match="token[. = 'sections']"> <xsl:param name="node"/> <xsl:param name="side"/> <xsl:apply-templates mode="html.sidebar.sections.mode" select="$node"> <xsl:with-param name="side" select="$side"/> </xsl:apply-templates> </xsl:template> <!--%%========================================================================== html.sidebar.sections.mode Output a list of sections for a sidebar. @revision[version=3.30 date=2018-06-10 status=candidate] [xsl:params] $side: Which sidebar, either `left` or `right`. This mode is called by {html.sidebar.sections} to allow different input formats to implement a sections list for a sidebar. --> <xsl:template mode="html.sidebar.sections.mode" match="*"> <xsl:param name="side"/> <xsl:message> <xsl:text>Unmatched sections sidebar: </xsl:text> <xsl:value-of select="local-name(.)"/> </xsl:message> </xsl:template> <!--**========================================================================== html.sidebar.custom Stub to output custom sidebar content. @xsl:stub @revision[version=3.28 date=2017-05-24 status=final] [xsl:params] $node: The node a page is being created for. This template is a stub, called by {html.page}. It is called inside the `main` element, before the `div.page` element. The `main` element uses a horizontal flexbox by default. You can override this template to provide sidebar content. Note that there is only one extension point for sidebar content, and it is always placed before the main content in document order. To create a sidebar on the right, output the element here, then adjust the `order` CSS property for that element to display it after the `main` element. This template is intended for completely custom sidebars. You can also use {html.sidebar} to output sidebars with stock components. --> <xsl:template name="html.sidebar.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.header.custom Stub to output custom header content. @xsl:stub @revision[version=3.28 date=2017-05-24 status=final] [xsl:params] $node: The node a page is being created for. This template is a stub, called by {html.page}. It is called inside the `header` element, before {html.header.mode} is applied to `node`. You can override this template to provide additional content above the main content. --> <xsl:template name="html.header.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--%%========================================================================== html.header.mode Output the header content for an element. @revision[version=3.28 date=2017-05-24 status=final] This mode is called by {html.page} to output the contents of the `header` element above the main content. Importing stylesheets may implement this mode for any element that will be passed to {html.page}. If they do not, the `header` element will be empty by default. --> <xsl:template mode="html.header.mode" match="*"/> <!--**========================================================================== html.footer.custom Stub to output custom footer content. @xsl:stub @revision[version=3.28 date=2017-05-24 status=final] [xsl:params] $node: The node a page is being created for. This template is a stub, called by {html.page}. It is called inside the `footer` element, after {html.footer.mode} is applied to $node. You can override this template to provide additional content below the main content. --> <xsl:template name="html.footer.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--%%========================================================================== html.footer.mode Output the footer content for an element. @revision[version=3.28 date=2017-05-24 status=final] This mode is called by {html.page} to output the contents of the `footer` element below the main content. Importing stylesheets may implement this mode for any element that will be passed to {html.page}. If they do not, the `footer` element will be empty by default. --> <xsl:template mode="html.footer.mode" match="*"/> <!--%%========================================================================== html.body.mode Output the main contents for an element. @revision[version=1.0 date=2010-05-26 status=final] This mode is called by {html.page} to output the main contents of an HTML page, below the header content and above the footer content. Titles, block content, and sections should be output in this mode. --> <xsl:template mode="html.body.mode" match="*"/> <!--**========================================================================== html.head.top.custom Stub to output custom content at the beginning of the HTML `head` element. @xsl:stub @revision[version=3.28 date=2017-08-04 status=final] [xsl:params] $node: The node a page is being created for. This template is a stub, called by {html.page}. You can override this template to provide additional elements at the beginning of the HTML `head` element of output files. This template is called before all other head content. --> <xsl:template name="html.head.top.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.head.custom Stub to output custom content at the end of the HTML `head` element. @xsl:stub @revision[version=3.28 date=2017-08-04 status=final] [xsl:params] $node: The node a page is being created for. This template is a stub, called by {html.page}. You can override this template to provide additional elements in the HTML `head` element of output files. This template is called after all other head content. --> <xsl:template name="html.head.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.linktrails.empty Stub to output something when no link trails are present. @xsl:stub @revision[version=3.28 date=2017-05-24 status=final] [xsl:params] $node: The source element a page is bring created for. This template is a stub. It is called by templates that output link trails when there are no link trails to output. Some customizations prepend extra site links to link trails. This template allows them to output those links even when no link trails would otherwise be present. --> <xsl:template name="html.linktrails.empty"> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.linktrails.prefix Stub to output extra content before a link trail. @xsl:stub @revision[version=42 date=2021-10-30 status=final] [xsl:params] $page: The source element for which an output page is being made. $node: A source-specific element providing information about the link trail. This template is a stub. It is called by templates that output link trails before the normal links are output. This template is useful for adding extra site links at the beginning of each link trail. [note .plain] The $page parameter was added in version 42. --> <xsl:template name="html.linktrails.prefix"> <xsl:param name="page" select="."/> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.class.attr Output a `class` attribute for an HTML element. @revision[version=3.10 date=2013-07-10 status=final] [xsl:params] $node: The source node for which an HTML element is being output. $class: The value of the `class` attribute provided by the calling template. This template is called by templates that output an HTML element corresponding to a source element. This template applies {html.class.attr.mode} to $node to gather a value from extensions stylesheets. It combines this value with the value passed in the $class parameter and, if the result is non-empty, outputs a `class` attribute. --> <xsl:template name="html.class.attr"> <xsl:param name="node" select="."/> <xsl:param name="class"/> <xsl:variable name="fclass"> <xsl:value-of select="$class"/> <xsl:text> </xsl:text> <xsl:apply-templates mode="html.class.attr.mode" select="$node"/> </xsl:variable> <xsl:variable name="nclass" select="normalize-space($fclass)"/> <xsl:if test="$nclass != ''"> <xsl:attribute name="class"> <xsl:value-of select="normalize-space($nclass)"/> </xsl:attribute> </xsl:if> </xsl:template> <!--%%========================================================================== html.class.attr.mode Output additional values for an HTML `class` attribute. @revision[version=3.10 date=2013-07-10 status=final] This mode is called by {html.class.attr} on a source element. This mode is intended for extensions to have an easy way to add additional HTML class values for styling. Note that these stylesheets use CSS classes extensively for styling and for certain JavaScript functionality. Extensions should be careful to output class values that do not conflict with those used in these stylesheets. --> <xsl:template mode="html.class.attr.mode" match="*"/> <!--**========================================================================== html.content.pre Output content before the content of a page or section. @revision[version=3.28 date=2016-06-21 status=final] [xsl:params] $node: The node a page or section is being created for. $page: Whether the content is for a page. This template is called by importing stylesheets before any content of a page or section, but after the title. It calls {html.content.pre.custom}, then applies {html.content.pre.mode} to $node. If the $page parameter is true, then this template is being called on an output page. Otherwise, it is being called on a section within a page. --> <xsl:template name="html.content.pre"> <xsl:param name="node" select="."/> <xsl:param name="page" select="true()"/> <xsl:call-template name="html.content.pre.custom"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="page" select="$page"/> </xsl:call-template> <xsl:apply-templates mode="html.content.pre.mode" select="$node"> <xsl:with-param name="page" select="$page"/> </xsl:apply-templates> </xsl:template> <!--**========================================================================== html.content.pre.custom Stub to output content before the content of a page or section. @xsl:stub @revision[version=3.28 date=2016-06-21 status=final] [xsl:params] $node: The node a page or section is being created for. $page: Whether the content is for a page. This template is a stub, called by {html.content.pre.custom}. It is called before {html.content.pre.mode} is applied. Override this template to provide site-specific HTML before the content of a page or section. If the $page parameter is true, then this template is being called on an output page. Otherwise, it is being called on a section within a page. --> <xsl:template name="html.content.pre.custom"> <xsl:param name="node" select="."/> <xsl:param name="page" select="true()"/> </xsl:template> <!--%%========================================================================== html.content.pre.mode Output content before the content of a page or section. @revision[version=3.28 date=2016-06-21 status=final] [xsl:params] $page: Whether the content is for a page. This mode is applied by {html.content.pre} after calling {html.content.pre.custom}. Importing stylesheets can use this to add additional content for specific types of input elements before the content of a page or section. If the $page parameter is true, then this template is being called on an output page. Otherwise, it is being called on a section within a page. --> <xsl:template mode="html.content.pre.mode" match="*"> <xsl:param name="page" select="true()"/> </xsl:template> <!--**========================================================================== html.content.post Output content after the content of a page or section, before subsections. @revision[version=3.28 date=2016-06-21 status=final] [xsl:params] $node: The node a page or section is being created for. $page: Whether the content is for a page. This template is called by importing stylesheets after any content of a page or section, but before any subsections. It applies {html.content.post.mode} to $node, then calls {html.content.post.custom}. If the $page parameter is true, then this template is being called on an output page. Otherwise, it is being called on a section within a page. --> <xsl:template name="html.content.post"> <xsl:param name="node" select="."/> <xsl:param name="page" select="true()"/> <xsl:apply-templates mode="html.content.post.mode" select="$node"> <xsl:with-param name="page" select="$page"/> </xsl:apply-templates> <xsl:call-template name="html.content.post.custom"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="page" select="$page"/> </xsl:call-template> </xsl:template> <!--**========================================================================== html.content.post.custom Stub to output content after the content of a page or section, before subsections. @xsl:stub @revision[version=3.28 date=2016-06-21 status=final] [xsl:params] $node: The node a page or section is being created for. $page: Whether the content is for a page. This template is a stub, called by {html.content.post.custom}. It is called after {html.content.pre.mode} is applied. Override this template to provide site-specific HTML after the content of a page or section, but before any subsections. If the $page parameter is true, then this template is being called on an output page. Otherwise, it is being called on a section within a page. --> <xsl:template name="html.content.post.custom"> <xsl:param name="node" select="."/> <xsl:param name="page" select="true()"/> </xsl:template> <!--%%========================================================================== html.content.post.mode Output content after the content of a page or section, before subsections. @revision[version=3.28 date=2016-06-21 status=final] [xsl:params] $page: Whether the content is for a page. This mode is applied by {html.content.post} before calling {html.content.post.custom}. Importing stylesheets can use this to add additional content for specific types of input elements after the content of a page or section, but before any subsections. If the $page parameter is true, then this template is being called on an output page. Otherwise, it is being called on a section within a page. --> <xsl:template mode="html.content.post.mode" match="*"> <xsl:param name="page" select="true()"/> </xsl:template> <!--**========================================================================== html.css Output all CSS for an HTML output page. @revision[version=1.0 date=2010-12-23 status=final] [xsl:params] $node: The node to create CSS for. $direction: The directionality of the text, either `ltr` or `rtl`. $left: The starting alignment, either `left` or `right`. $right: The ending alignment, either `left` or `right`. This template creates the CSS for an HTML output page, including the enclosing HTML `style` element. It calls the templates {html.css.content} to output the actual CSS contents. The $direction parameter specifies the directionality of the text for the language of the document. The $left and $right parameters are based on $direction, and can be used to set beginning and ending margins or other dimensions. All parameters can be automatically computed if not provided. --> <xsl:template name="html.css"> <xsl:param name="node" select="."/> <xsl:param name="direction"> <xsl:call-template name="l10n.direction"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:param> <xsl:param name="left"> <xsl:call-template name="l10n.align.start"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:param name="right"> <xsl:call-template name="l10n.align.end"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <style type="text/css"> <xsl:call-template name="html.css.content"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:call-template> </style> </xsl:template> <!--**========================================================================== html.css.content Output actual CSS content for an HTML output page. @revision[version=1.0 date=2010-12-23 status=final] [xsl:params] $node: The node to create CSS for. $direction: The directionality of the text, either `ltr` or `rtl`. $left: The starting alignment, either `left` or `right`. $right: The ending alignment, either `left` or `right`. This template creates the CSS content for an HTML output page. It is called by {html.css}. It calls the templates {html.css.core}, {html.css.elements}, and {html.css.syntax}. It then calls the mode {html.css.mode} on $node and calls the template {html.css.custom}. --> <xsl:template name="html.css.content"> <xsl:param name="node" select="."/> <xsl:param name="direction"> <xsl:call-template name="l10n.direction"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:param> <xsl:param name="left"> <xsl:call-template name="l10n.align.start"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:param name="right"> <xsl:call-template name="l10n.align.end"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:call-template name="html.css.core"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:call-template> <xsl:call-template name="html.css.elements"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:call-template> <xsl:call-template name="html.css.syntax"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:call-template> <xsl:apply-templates mode="html.css.mode" select="$node"> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:apply-templates> <xsl:call-template name="html.css.custom"> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:call-template> </xsl:template> <!--%%========================================================================== html.css.mode Output CSS specific to the input format. @revision[version=1.0 date=2010-05-26 status=final] [xsl:params] $direction: The directionality of the text, either `ltr` or `rtl`. $left: The starting alignment, either `left` or `right`. $right: The ending alignment, either `left` or `right`. This template is called by {html.css.content} to output CSS specific to the input format. Importing stylesheets may implement this for any element that will be passed to {html.page}. If they do not, the output HTML will only have the common CSS. --> <xsl:template mode="html.css.mode" match="*"> <xsl:param name="direction"> <xsl:call-template name="l10n.direction"/> </xsl:param> <xsl:param name="left"> <xsl:call-template name="l10n.align.start"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:param name="right"> <xsl:call-template name="l10n.align.end"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> </xsl:template> <!--**========================================================================== html.css.core Output CSS that does not reference source elements. @revision[version=1.0 date=2010-05-25 status=final] [xsl:params] $node: The node to create CSS for. $direction: The directionality of the text, either `ltr` or `rtl`. $left: The starting alignment, either `left` or `right`. $right: The ending alignment, either `left` or `right`. This template outputs CSS that can be used in any HTML. It does not reference elements from DocBook, Mallard, or other source languages. It provides the common spacings for block-level elements like paragraphs and lists, defines styles for links, and defines four common wrapper divs: `header`, `side`, `body`, and `footer`. This template uses text templates to keep the actual CSS content in a separate file, `css/core.css.tmpl`, and do simple param substitutions. This makes it easier to update the CSS without working with XSLT. All parameters can be automatically computed if not provided. --> <xsl:template name="html.css.core"> <xsl:param name="node" select="."/> <xsl:param name="direction"> <xsl:call-template name="l10n.direction"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:param> <xsl:param name="left"> <xsl:call-template name="l10n.align.start"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:param name="right"> <xsl:call-template name="l10n.align.end"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:call-template name="tmpl.file"> <xsl:with-param name="file" select="'css/core.css.tmpl'"/> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:call-template> </xsl:template> <!--**========================================================================== html.css.elements Output CSS for common elements from source formats. @revision[version=1.0 date=2010-05-25 status=final] [xsl:params] $node: The node to create CSS for. $direction: The directionality of the text, either `ltr` or `rtl`. $left: The starting alignment, either `left` or `right`. $right: The ending alignment, either `left` or `right`. This template outputs CSS for elements from source languages like DocBook and Mallard. It defines them using common class names. The common names are often the simpler element names from Mallard, although there some class names which are not taken from Mallard. Stylesheets which convert to HTML should use the appropriate common classes. This template uses text templates to keep the actual CSS content in a separate file, `css/elements.css.tmpl`, and do simple param substitutions. This makes it easier to update the CSS without working with XSLT. All parameters can be automatically computed if not provided. --> <xsl:template name="html.css.elements"> <xsl:param name="node" select="."/> <xsl:param name="direction"> <xsl:call-template name="l10n.direction"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:param> <xsl:param name="left"> <xsl:call-template name="l10n.align.start"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:param name="right"> <xsl:call-template name="l10n.align.end"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <!-- Almost everything is in the text template file, except there's these two bits that aren't because XPath alone can't handle them. We could precompute and pass params, but I'm hesitant to add special-purpose params, which are API. --> <xsl:call-template name="tmpl.file"> <xsl:with-param name="file" select="'css/elements.css.tmpl'"/> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:call-template> <!-- FIXME: I don't like this at all. We use a character as the blockquote icon, which requires a whole font, and which random internet users might not have. Let's make SVGs and use the same icon embedding we use for notes. --> <xsl:variable name="quote"> <xsl:for-each select="$node[1]"> <xsl:call-template name="l10n.gettext"> <xsl:with-param name="msgid" select="'quote.format'"/> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:for-each> </xsl:variable> <xsl:variable name="quotc" select="substring(concat($quote, '“'), 1, 1)"/> <xsl:text>div.quote > div.inner:before { float: </xsl:text> <xsl:value-of select="$left"/> <xsl:text>content: '</xsl:text> <xsl:choose> <xsl:when test="contains('«‹', $quotc)"> <xsl:text>«</xsl:text> </xsl:when> <xsl:when test="contains('»›', $quotc)"> <xsl:text>»</xsl:text> </xsl:when> <xsl:when test="contains('”„’‚', $quotc)"> <xsl:text>”</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>“</xsl:text> </xsl:otherwise> </xsl:choose> <xsl:text>'; font-family: "Century Schoolbook L"; font-size: {{$icons.size.quote}}px; font-weight: bold; line-height: </xsl:text> <xsl:choose> <xsl:when test="contains('«»‹›', $quotc)"> <xsl:text>0.5</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>1</xsl:text> </xsl:otherwise> </xsl:choose><xsl:text>em; margin: 0; padding: 0; height: {{$icons.size.quote}}px; width: {{$icons.size.quote}}px; text-align: center; color: {{$color.bg.dark}}; }</xsl:text> <!-- Surely we should be able to figure out a way to conditionalize the rotation direction in the text templates, or handle this a different way. --> <xsl:text>.ui-expander-e > div.inner > div.title span.title:before, </xsl:text> <xsl:text>.ui-expander-e > div.inner > div.hgroup span.title:before {</xsl:text> <xsl:choose> <xsl:when test="$direction = 'rtl'"> <xsl:text>transform: translateY(0.2em) rotate(-180deg);</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>transform: translateY(0.2em) rotate(180deg);</xsl:text> </xsl:otherwise> </xsl:choose> <xsl:text>}</xsl:text> </xsl:template> <!--**========================================================================== html.css.syntax Output CSS for syntax highlighting. @revision[version=1.0 date=2010-12-06 status=final] [xsl:params] $node: The node to create CSS for. $direction: The directionality of the text, either `ltr` or `rtl`. $left: The starting alignment, either `left` or `right`. $right: The ending alignment, either `left` or `right`. This template outputs CSS to support syntax highlighting of code blocks. Syntax highlighting is done at document load time with JavaScript. Text in code blocks is broken up into chunks and wrapped in HTML elements with particular classes. This template outputs CSS to match those elements and style them with the built-in themeable colors from {color}. This template uses text templates to keep the actual CSS content in a separate file, `css/syntax.css.tmpl`, and do simple param substitutions. This makes it easier to update the CSS without working with XSLT. All parameters can be automatically computed if not provided. --> <xsl:template name="html.css.syntax"> <xsl:param name="node" select="."/> <xsl:param name="direction"> <xsl:call-template name="l10n.direction"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:param> <xsl:param name="left"> <xsl:call-template name="l10n.align.start"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:param name="right"> <xsl:call-template name="l10n.align.end"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:if test="$html.syntax.highlight"> <xsl:call-template name="tmpl.file"> <xsl:with-param name="file" select="'css/syntax.css.tmpl'"/> <xsl:with-param name="node" select="$node"/> <xsl:with-param name="direction" select="$direction"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="$right"/> </xsl:call-template> </xsl:if> </xsl:template> <!--**========================================================================== html.css.custom Stub to output custom CSS common to all HTML transformations. @xsl:stub @revision[version=1.0 date=2010-05-25 status=final] [xsl:params] $node: The node to create CSS for. $direction: The directionality of the text, either `ltr` or `rtl`. $left: The starting alignment, either `left` or `right`. $right: The ending alignment, either `left` or `right`. This template is a stub, called by {html.css.content}. You can override this template to provide additional CSS that will be used by all HTML output. --> <xsl:template name="html.css.custom"> <xsl:param name="node" select="."/> <xsl:param name="direction"> <xsl:call-template name="l10n.direction"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:param> <xsl:param name="left"> <xsl:call-template name="l10n.align.start"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> <xsl:param name="right"> <xsl:call-template name="l10n.align.end"> <xsl:with-param name="direction" select="$direction"/> </xsl:call-template> </xsl:param> </xsl:template> <!--**========================================================================== html.js Output all JavaScript for an HTML output page. @revision[version=3.28 date=2017-07-05 status=final] [xsl:params] $node: The node to create JavaScript for. This template creates the JavaScript for an HTML output page. It calls the templates {html.js.syntax} and {html.js.mathjax} to output references to external libraries. It then calls {html.js.custom} to output references to custom JavaScript files. Finally, it calls {html.js.script} to output local JavaScript created by {html.js.content}. --> <xsl:template name="html.js"> <xsl:param name="node" select="."/> <xsl:call-template name="html.js.syntax"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:call-template name="html.js.mathjax"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:call-template name="html.js.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:call-template name="html.js.script"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:template> <!--**========================================================================== html.js.mathjax Output a `script` element to include MathJax. @revision[version=1.0 date=2012-11-13 status=final] [xsl:params] $node: The node to create JavaScript for. This template outputs an HTML `script` tag to reference MathJax. It only outputs a `script` element if $node has MathML descendent content. By default, this template uses `cdn.mathjax.org`. If you wish to use a local copy, override this template and provide the necessary files. --> <xsl:template name="html.js.mathjax"> <xsl:param name="node" select="."/> <xsl:if test="$node//mml:*[1]"> <script type="text/javascript"> <xsl:attribute name="src"> <xsl:text>http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=MML_HTMLorMML</xsl:text> </xsl:attribute> </script> </xsl:if> </xsl:template> <!--**========================================================================== html.js.script Output a JavaScript `script` tag containing local content. @revision[version=3.28 date=2017-05-24 status=final] [xsl:params] $node: The node to create JavaScript for. This template is called by {html.js} to output JavaScript content. It outputs a `script` tag and calls {html.js.content} to output the contents. To force all JavaScript into external files, override this template to output a `script` tag referencing an external file with the `src` attribute, then output the result of {html.js.content} to that file. --> <xsl:template name="html.js.script"> <xsl:param name="node" select="."/> <script type="text/javascript"> <xsl:call-template name="html.js.content"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </script> </xsl:template> <!--**========================================================================== html.js.content Output JavaScript content for an HTML output page. @revision[version=3.28 date=2017-07-05 status=final] [xsl:params] $node: The node to create JavaScript for. This template is called by {html.js.script} to output JavaScript content. It does not output an HTML `script` tag. This template calls the templates {html.js.core}, {html.js.ui}, and {html.js.media}. It then calls the mode {html.js.mode} on $node and calls the template {html.js.content.custom}. --> <xsl:template name="html.js.content"> <xsl:param name="node" select="."/> <xsl:call-template name="html.js.core"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:call-template name="html.js.ui"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:call-template name="html.js.media"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> <xsl:apply-templates mode="html.js.mode" select="$node"/> <xsl:call-template name="html.js.content.custom"> <xsl:with-param name="node" select="$node"/> </xsl:call-template> </xsl:template> <!--**========================================================================== html.js.core Output JavaScript for core features. @revision[version=3.4 date=2011-11-04 status=final] [xsl:params] $node: The node to create JavaScript for. This template outputs JavaScript to support basic features used by all documents. Currently, it outputs code to highlight a section when `location.hash` is set. --> <xsl:template name="html.js.core"> <xsl:param name="node" select="."/> <xsl:text> document.addEventListener('DOMContentLoaded', function() { var yelp_hash_highlight = function () { if (location.hash != '') { var sect = document.querySelector(location.hash); if (sect != null) { sect.classList.add('yelp-hash-highlight'); window.setTimeout(function () { sect.classList.remove('yelp-hash-highlight'); }, 500); } } } window.addEventListener('hashchange', yelp_hash_highlight, false); yelp_hash_highlight(); }, false); </xsl:text> </xsl:template> <!--**========================================================================== html.js.ui Output JavaScript for UI extensions. @revision[version=1.0 date=2011-06-17 status=final] [xsl:params] $node: The node to create JavaScript for. This template outputs JavaScript that implements certain common UI extensions, such as expandable blocks and sections. --> <xsl:template name="html.js.ui"> <xsl:param name="node" select="."/> <xsl:text><![CDATA[ var __yelp_generate_id_counter__ = 0; function yelp_generate_id () { var ret = 'yelp--' + (++__yelp_generate_id_counter__).toString(); if (document.getElementById(ret) != null) return yelp_generate_id(); else return ret; }; function yelp_ui_expander_init (expander) { var yelpdata = null; var innerdiv = null; var region = null; var contents = null; var title = null; var title_e = null; var title_c = null; var titlespan = null; var issect = false; for (var i = 0; i < expander.children.length; i++) { var child = expander.children[i]; if (child.classList.contains('yelp-data-ui-expander')) { yelpdata = child; } else if (child.classList.contains('inner')) { innerdiv = child; } } if (innerdiv == null) { return; } for (var i = 0; i < innerdiv.children.length; i++) { var child = innerdiv.children[i]; if (child.classList.contains('region')) { region = child; } else if (child.classList.contains('title')) { title = child; } else if (child.classList.contains('hgroup')) { title = child; issect = true; } } if (region == null || title == null) { return; } if (!region.hasAttribute('id')) { region.setAttribute('id', yelp_generate_id()); } title.setAttribute('aria-controls', region.getAttribute('id')); if (yelpdata != null) { for (var i = 0; i < yelpdata.children.length; i++) { var child = yelpdata.children[i]; if (child.classList.contains('yelp-title-expanded')) { title_e = child; } else if (child.classList.contains('yelp-title-collapsed')) { title_c = child; } } } titlespan = title.querySelector('span.title'); if (titlespan == null) { return; } if (title_e == null) { var node = document.createElement('div'); node.className = 'yelp-title-expanded'; node.innerHTML = titlespan.innerHTML; yelpdata.appendChild(node); title_e = node; } if (title_c == null) { var node = document.createElement('div'); node.className = 'yelp-title-collapsed'; node.innerHTML = titlespan.innerHTML; yelpdata.appendChild(node); title_c = node; } var ui_expander_zoom_region = function (event) { if (yelpdata.getAttribute('data-yelp-expanded') != 'false') { ui_expander_toggle(); event.preventDefault(); } } if (expander.nodeName == 'section' || expander.nodeName == 'SECTION') { for (var i = 0; i < region.children.length; i++) { var child = region.children[i]; if (child.classList.contains('contents')) { contents = child; break; } } contents.addEventListener('click', ui_expander_zoom_region, true); } else { region.addEventListener('click', ui_expander_zoom_region, true); } var ui_expander_toggle = function () { if (yelpdata.getAttribute('data-yelp-expanded') == 'false') { yelpdata.setAttribute('data-yelp-expanded', 'true'); expander.classList.remove('ui-expander-e'); expander.classList.add('ui-expander-c'); region.setAttribute('aria-expanded', 'false'); if (title_c != null) titlespan.innerHTML = title_c.innerHTML; } else { yelpdata.setAttribute('data-yelp-expanded', 'false'); expander.classList.remove('ui-expander-c'); expander.classList.add('ui-expander-e'); region.setAttribute('aria-expanded', 'true'); if (title_e != null) titlespan.innerHTML = title_e.innerHTML; } }; expander.yelp_ui_expander_toggle = ui_expander_toggle; title.addEventListener('click', ui_expander_toggle, false); ui_expander_toggle(); } document.addEventListener('DOMContentLoaded', function() { var matches = document.querySelectorAll('.ui-expander'); for (var i = 0; i < matches.length; i++) { yelp_ui_expander_init(matches[i]); } var yelp_hash_ui_expand = function () { if (location.hash != '') { var sect = document.querySelector(location.hash); if (sect != null) { for (var cur = sect; cur instanceof Element; cur = cur.parentNode) { if (cur.classList.contains('ui-expander')) { if (cur.classList.contains('ui-expander-c')) { cur.yelp_ui_expander_toggle(); } } } sect.scrollIntoView(); } } }; window.addEventListener('hashchange', yelp_hash_ui_expand, false); yelp_hash_ui_expand(); }, false); ]]></xsl:text> </xsl:template> <!--**========================================================================== html.js.media Output JavaScript to control media elements. @revision[version=1.0 date=2010-01-01 status=final] [xsl:params] $node: The node to create JavaScript for. This template outputs JavaScript that controls media elements. It provides control for audio and video elements as well as support for captions. --> <xsl:template name="html.js.media"> <xsl:param name="node" select="."/> <xsl:text><![CDATA[ yelp_color_text_light = ']]></xsl:text> <xsl:value-of select="$color.fg.dark"/><xsl:text><![CDATA['; yelp_color_gray_background = ']]></xsl:text> <xsl:value-of select="$color.bg.gray"/><xsl:text><![CDATA['; yelp_color_gray_border = ']]></xsl:text> <xsl:value-of select="$color.gray"/><xsl:text><![CDATA['; function yelp_figure_init (figure) { var zoom = figure.querySelector('a.figure-zoom'); var figure_resize = function () { var zoomed = zoom.classList.contains('figure-zoomed'); var imgs = figure.querySelectorAll('img'); for (var i = 0; i < imgs.length; i++) { var img = imgs[i]; var mediaDiv = null; for (var cur = img; cur instanceof Element; cur = cur.parentNode) { if ((cur.nodeName == 'div' || cur.nodeName == 'DIV') && cur.classList.contains('media')) { mediaDiv = cur; break; } } if (mediaDiv == null) continue; if (!img.hasAttribute('data-yelp-original-width')) { var iwidth = null; if (img.hasAttribute('width')) iwidth = parseInt(img.getAttribute('width')); else iwidth = img.width; img.setAttribute('data-yelp-original-width', iwidth); var iheight = null; if (img.hasAttribute('height')) iheight = parseInt(img.getAttribute('height')); else iheight = img.height * (iwidth / img.width); img.setAttribute('data-yelp-original-height', iheight); } var owidth = img.width; var oheight = img.height; img.width = parseInt(img.getAttribute('data-yelp-original-width')); img.height = parseInt(img.getAttribute('data-yelp-original-height')); var mediaw = mediaDiv.offsetWidth; img.width = owidth; img.height = oheight; if (parseInt(img.getAttribute('data-yelp-original-width')) <= mediaw) { img.width = parseInt(img.getAttribute('data-yelp-original-width')); img.height = parseInt(img.getAttribute('data-yelp-original-height')); zoom.style.display = 'none'; } else if (zoomed) { img.width = parseInt(img.getAttribute('data-yelp-original-width')); img.height = parseInt(img.getAttribute('data-yelp-original-height')); zoom.style.display = 'block'; } else { img.width = mediaw; img.height = (parseInt(img.getAttribute('data-yelp-original-height')) * img.width / parseInt(img.getAttribute('data-yelp-original-width'))); zoom.style.display = 'block'; } } } figure.yelp_figure_resize = figure_resize; figure.yelp_figure_resize(); zoom.onclick = function (e) { var zoomed = zoom.classList.contains('figure-zoomed'); if (zoomed) zoom.classList.remove('figure-zoomed'); else zoom.classList.add('figure-zoomed'); figure.yelp_figure_resize(); return false; }; } window.addEventListener('load', function() { var figures = document.querySelectorAll('div.figure'); for (var i = 0; i < figures.length; i++) { if (figures[i].querySelector('img') != null) yelp_figure_init(figures[i]); } var timeout = null; var yelp_figures_resize = function () { if (timeout != null) return; timeout = window.setTimeout(function () { for (var i = 0; i < figures.length; i++) { if (figures[i].querySelector('img') != null) figures[i].yelp_figure_resize(); } window.clearTimeout(timeout); timeout = null; }, 100); }; window.addEventListener('resize', yelp_figures_resize, false); }, false); function yelp_media_init (media) { media.removeAttribute('controls'); if (media.parentNode.classList.contains('links-tile-img')) { return; } media.addEventListener('click', function () { if (media.paused) media.play(); else media.pause(); }, false); var controls = null; for (var cur = media.nextSibling; cur instanceof Element; cur = cur.nextSibling) { if (cur.classList.contains('media-controls')) { controls = cur; break; } } if (controls == null) { media.setAttribute('controls', 'controls'); return; } var playbutton = controls.querySelector('button.media-play'); playbutton.addEventListener('click', function () { if (media.paused || media.ended) media.play(); else media.pause(); }, false); var mediachange = function () { if (media.ended) media.pause() if (media.paused) { playbutton.setAttribute('value', playbutton.getAttribute('data-play-label')); playbutton.classList.remove('media-play-playing'); } else { playbutton.setAttribute('value', playbutton.getAttribute('data-pause-label')); playbutton.classList.add('media-play-playing'); } } media.addEventListener('play', mediachange, false); media.addEventListener('pause', mediachange, false); media.addEventListener('ended', mediachange, false); var mediarange = controls.querySelector('input.media-range'); mediarange.addEventListener('input', function () { var pct = this.value; if (pct < 0) pct = 0; if (pct > 100) pct = 100; media.currentTime = (pct / 100.0) * media.duration; }, false); var curspan = controls.querySelector('span.media-current'); var durspan = controls.querySelector('span.media-duration'); var durationUpdate = function () { if (!isNaN(media.duration)) { mins = parseInt(media.duration / 60); secs = parseInt(media.duration - (60 * mins)); durspan.textContent = (mins + (secs < 10 ? ':0' : ':') + secs); } }; media.addEventListener('durationchange', durationUpdate, false); var ttmlDiv = null; var ttmlNodes = null; for (var i = 0; i < media.parentNode.children.length; i++) { var child = media.parentNode.children[i]; if (child.classList.contains('media-ttml')) ttmlDiv = child; } if (ttmlDiv != null) { ttmlNodes = ttmlDiv.querySelectorAll('.media-ttml-node'); } var timeUpdate = function () { var pct = (media.currentTime / media.duration) * 100; mediarange.value = pct; var mins = parseInt(media.currentTime / 60); var secs = parseInt(media.currentTime - (60 * mins)) curspan.textContent = (mins + (secs < 10 ? ':0' : ':') + secs); if (ttmlNodes != null) { for (var i = 0; i < ttmlNodes.length; i++) { var ttml = ttmlNodes[i]; if (media.currentTime >= parseFloat(ttml.getAttribute('data-ttml-begin')) && (!ttml.hasAttribute('data-ttml-end') || media.currentTime < parseFloat(ttml.getAttribute('data-ttml-end')) )) { if (ttml.tagName == 'span' || ttml.tagName == 'SPAN') ttml.style.display = 'inline'; else ttml.style.display = 'block'; } else { ttml.style.display = 'none'; } } } }; media.addEventListener('timeupdate', timeUpdate, false); }; document.addEventListener('DOMContentLoaded', function() { var matches = document.querySelectorAll('video, audio'); for (var i = 0; i < matches.length; i++) { yelp_media_init(matches[i]); } }, false); ]]></xsl:text> </xsl:template> <!--**========================================================================== html.js.syntax Output `script` elements for syntax highlighting. @revision[version=3.28 date=2016-01-03 status=final] [xsl:params] $node: The node to create JavaScript for. This template outputs HTML `script` elements to enable syntax highlighting. It only outputs if {html.syntax.highlight} is `true`. It outputs one `script` element to load in `highlight.js`, and another to initialize `highlight.js` on all `code` elements with `"syntax"` in the class value. --> <xsl:template name="html.js.syntax"> <xsl:param name="node" select="."/> <xsl:if test="$html.syntax.highlight"> <script type="text/javascript" src="{$html.js.root}highlight.pack.js"></script> <script><![CDATA[ document.addEventListener('DOMContentLoaded', function() { var matches = document.querySelectorAll('code.syntax') for (var i = 0; i < matches.length; i++) { hljs.highlightBlock(matches[i]); } }, false);]]></script> </xsl:if> </xsl:template> <!--%%========================================================================== html.js.mode Output JavaScript specific to the input format. @revision[version=1.0 date=2010-01-01 status=final] This mode is called by {html.js.content} to output JavaScript specific to the input format. Importing stylesheets may implement this for any element that will be passed to {html.page}. If they do not, the output HTML will only have the common JavaScript. --> <xsl:template mode="html.js.mode" match="*"> </xsl:template> <!--**========================================================================== html.js.custom Stub to reference custom JavaScript common to all HTML transformations. @xsl:stub @revision[version=1.0 date=2010-04-16 status=final] [xsl:params] $node: The node to create JavaScript for. This template is a stub, called by {html.js}. You can override this template to reference additional external JavaScript files. If you want to include JavaScript into the main `script` tag instead, use {html.js.content.custom}. --> <xsl:template name="html.js.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.js.content.custom Stub to output custom JavaScript common to all HTML transformations. @xsl:stub @revision[version=1.0 date=2010-04-16 status=final] [xsl:params] $node: The node to create JavaScript for. This template is a stub, called by {html.js.content}. You can override this template to provide additional JavaScript that will be used by all HTML output. This template is called inside a `script` tag, and is intended to include JavaScript code in the output page. See {html.js.custom} to include a custom reference to an external JavaScript file. --> <xsl:template name="html.js.content.custom"> <xsl:param name="node" select="."/> </xsl:template> <!--**========================================================================== html.lang.attrs Output `lang` and `dir` attributes. @revision[version=1.0 date=2010-06-10 status=final] [xsl:params] $node: The current element in the input document. $parent: A parent node to take $lang and $dir from. $lang: The language for $node. $dir: The text directionality for $node. This template outputs `lang`, `xml:lang`, or `dir` attributes if necessary. If $lang is not set, it will be taken from the `xml:lang` or `lang` attribute of $node. If $dir is not set, it will be taken from the `its:dir` attribute of $node or computed based on $lang. The $parent parameter defaults to an empty node set. If it is set to a non-empty node set, this template will attempt to get $lang and $dir from $parent if they are not set on $node. This is occasionally useful when a wrapper element in a source language doesn't directly create any output elements. This template outputs either an `xml:lang` or a `lang` attribute, depending on whether {html.xhtml} is `true`. It only outputs an `xml:lang` or `lang` attribute if $lang is non-empty. This template also outputs a `dir` attribute if $dir is non-empty. --> <xsl:template name="html.lang.attrs"> <xsl:param name="node" select="."/> <xsl:param name="parent" select="/false"/> <xsl:param name="lang"> <xsl:choose> <xsl:when test="$node/@xml:lang"> <xsl:value-of select="$node/@xml:lang"/> </xsl:when> <xsl:when test="$node/@lang"> <xsl:value-of select="$node/@lang"/> </xsl:when> <xsl:when test="$parent/@xml:lang"> <xsl:value-of select="$parent/@xml:lang"/> </xsl:when> <xsl:when test="$parent/@lang"> <xsl:value-of select="$parent/@lang"/> </xsl:when> </xsl:choose> </xsl:param> <xsl:param name="dir"> <xsl:choose> <xsl:when test="$node/@its:dir"> <xsl:value-of select="$node/@its:dir"/> </xsl:when> <xsl:when test="($node/@xml:lang or $node/@lang) and (string($lang) != '')"> <xsl:call-template name="l10n.direction"> <xsl:with-param name="lang" select="$lang"/> </xsl:call-template> </xsl:when> <xsl:when test="$parent/@its:dir"> <xsl:value-of select="$node/@its:dir"/> </xsl:when> <xsl:when test="string($lang) != ''"> <xsl:call-template name="l10n.direction"> <xsl:with-param name="lang" select="$lang"/> </xsl:call-template> </xsl:when> </xsl:choose> </xsl:param> <xsl:if test="string($lang) != ''"> <xsl:choose> <xsl:when test="$html.xhtml"> <xsl:attribute name="xml:lang"> <xsl:value-of select="$lang"/> </xsl:attribute> </xsl:when> <xsl:otherwise> <xsl:attribute name="lang"> <xsl:value-of select="$lang"/> </xsl:attribute> </xsl:otherwise> </xsl:choose> </xsl:if> <xsl:if test="string($dir) != ''"> <xsl:attribute name="dir"> <xsl:value-of select="$dir"/> </xsl:attribute> </xsl:if> </xsl:template> <!--**========================================================================== html.syntax.class Output HTML class values for syntax highlighting. @revision[version=3.28 date=2016-01-03 status=final] [xsl:params] $node: The source element whose content will be syntax highlighted. This template calls {html.syntax.class.mode} on $node. If the result of that mode is a suitable language identifier, it outputs appropriate CSS class names to enable syntax highlighting. The output should be placed in the `class` attribute of a `pre` or similar output element by the calling template. Importing stylesheets should implement {html.syntax.class.mode} for any source elements that may be syntax highlighted, then call this template when building the `class` attribute for output elements. --> <xsl:template name="html.syntax.class"> <xsl:param name="node" select="."/> <xsl:variable name="class"> <xsl:apply-templates mode="html.syntax.class.mode" select="$node"/> </xsl:variable> <xsl:if test="normalize-space($class) != ''"> <xsl:text>syntax language-</xsl:text> <xsl:value-of select="$class"/> </xsl:if> </xsl:template> <!--%%========================================================================== html.syntax.class.mode Get the syntax highlighting language for a source-specific element. @revision[version=3.28 date=2016-01-03 status=final] This mode is called by {html.syntax.class} on source elements that may have syntax highlighted. This template should be implemented by importing stylesheets. It should return a simple language identifier. --> <xsl:template mode="html.syntax.class.mode" match="*"/> <!--**========================================================================== html.media.controls Output media controls for a video or audio object. @revision[version=3.38 date=2020-04-30 status=final] [xsl:params] $type: The type of media element, either 'video' or 'audio'. $ttml: Whether there are TTML subtitles for this media element. This template outputs HTML containing controls for a media play for audio or video HTML elements. To work with the built-in JavaScript binding code, it should be placed immediately after the `audio` or `video` element. --> <xsl:template name="html.media.controls"> <xsl:param name="type" select="'video'"/> <xsl:param name="ttml" select="false()"/> <div> <xsl:attribute name="class"> <xsl:text>media-controls media-controls-</xsl:text> <xsl:value-of select="$type"/> <xsl:if test="$ttml"> <xsl:text> media-controls-ttml</xsl:text> </xsl:if> </xsl:attribute> <button class="media-play"> <xsl:attribute name="data-play-label"> <xsl:call-template name="l10n.gettext"> <xsl:with-param name="msgid" select="'Play'"/> </xsl:call-template> </xsl:attribute> <xsl:attribute name="data-pause-label"> <xsl:call-template name="l10n.gettext"> <xsl:with-param name="msgid" select="'Pause'"/> </xsl:call-template> </xsl:attribute> <xsl:attribute name="value"> <xsl:call-template name="l10n.gettext"> <xsl:with-param name="msgid" select="'Play'"/> </xsl:call-template> </xsl:attribute> <xsl:call-template name="icons.svg.media.play"/> <xsl:call-template name="icons.svg.media.pause"/> </button> <input type="range" class="media-range" value="0"/> <span class="media-time"> <span class="media-current">0:00</span> <span class="media-duration">-:--</span> </span> </div> </xsl:template> </xsl:stylesheet>