diff options
Diffstat (limited to '')
-rw-r--r-- | src/boost/tools/boostbook/xsl/lookup.xsl | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/src/boost/tools/boostbook/xsl/lookup.xsl b/src/boost/tools/boostbook/xsl/lookup.xsl new file mode 100644 index 000000000..91b4a59d4 --- /dev/null +++ b/src/boost/tools/boostbook/xsl/lookup.xsl @@ -0,0 +1,457 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com> + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) + --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:exsl="http://exslt.org/common" + version="1.0"> + + <!-- Maximum length of directory and file names is 31 characters. + '.html' uses 5 characters. + 31 - 5 = 26 --> + <xsl:param name="boost.max.id.part.length">26</xsl:param> + + <!-- Generate an ID for the entity referenced --> + <xsl:template name="generate.id"> + <xsl:param name="node" select="."/> + <xsl:apply-templates select="$node" mode="generate.id"/> + </xsl:template> + + <xsl:template match="*" mode="generate.id"> + <xsl:variable name="raw.id"><xsl:call-template name="object.id"/></xsl:variable> + <xsl:value-of select="translate($raw.id, '.', '_')"/> + <xsl:text>-bb</xsl:text> + </xsl:template> + + <xsl:template name="postfix.id"> + <xsl:variable name="raw.id"><xsl:call-template name="object.id"/></xsl:variable> + <xsl:choose> + <xsl:when test="starts-with($raw.id, 'id-')"> + <xsl:value-of select="translate(substring-after($raw.id, 'id-'), '.', '_')"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$raw.id"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="strip-qualifiers-non-template"> + <xsl:param name="name"/> + <xsl:choose> + <xsl:when test="contains($name, '>')"> + <xsl:call-template name="strip-qualifiers-non-template"> + <xsl:with-param name="name" select="substring-after($name, '>')"/> + </xsl:call-template> + </xsl:when> + <xsl:when test="contains($name, '::')"> + <xsl:call-template name="strip-qualifiers-non-template"> + <xsl:with-param name="name" select="substring-after($name, '::')"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$name"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="strip-balanced"> + <xsl:param name="name"/> + <xsl:param name="open" select="'<'"/> + <xsl:param name="close" select="'>'"/> + <xsl:param name="depth" select="0"/> + <xsl:choose> + <xsl:when test="contains($name, $open) + and not(contains(substring-before($name, $open), $close))"> + <xsl:call-template name="strip-balanced"> + <xsl:with-param name="name" select="substring-after($name, $open)"/> + <xsl:with-param name="open" select="$open"/> + <xsl:with-param name="close" select="$close"/> + <xsl:with-param name="depth" select="$depth + 1"/> + </xsl:call-template> + </xsl:when> + <xsl:when test="contains($name, $close) and ($depth > 1)"> + <xsl:call-template name="strip-balanced"> + <xsl:with-param name="name" select="substring-after($name, $close)"/> + <xsl:with-param name="open" select="$open"/> + <xsl:with-param name="close" select="$close"/> + <xsl:with-param name="depth" select="$depth - 1"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="substring-after($name, $close)"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="strip-qualifiers-template"> + <xsl:param name="name"/> + <xsl:choose> + <xsl:when test="contains($name, '::') + and not(contains(substring-before($name, '::'), '<'))"> + <xsl:call-template name="strip-qualifiers-template"> + <xsl:with-param name="name" select="substring-after($name, '::')"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="rest"> + <xsl:call-template name="strip-balanced"> + <xsl:with-param name="name" select="$name"/> + </xsl:call-template> + </xsl:variable> + <xsl:choose> + <xsl:when test="$rest != ''"> + <xsl:call-template name="strip-qualifiers-template"> + <xsl:with-param name="name" select="$rest"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$name"/> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Strip the qualifiers off a qualified name and return the unqualified + name. For instance, "boost::python::function" would become just + "function". + Must handle ns::foo -> foo + Must handle ns::foo<bar::baz> -> foo<bar::baz> + Must handle ns::foo<bar::baz>::nested -> nested + Must handle ns::foo<x>::bar<y> -> bar<y> --> + <xsl:template name="strip-qualifiers"> + <xsl:param name="name"/> + <xsl:choose> + <xsl:when test="substring($name, string-length($name)) = '>'"> + <xsl:call-template name="strip-qualifiers-template"> + <xsl:with-param name="name" select="$name"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="strip-qualifiers-non-template"> + <xsl:with-param name="name" select="$name"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Build the fully-qualified id of the given node --> + <xsl:template name="fully-qualified-id"> + <xsl:param name="node"/> + + <xsl:apply-templates select="$node" mode="fully-qualified-name"> + <xsl:with-param name="is.id" select="true()"/> + </xsl:apply-templates> + </xsl:template> + + <!-- Build the fully-qualified name of the given node --> + <xsl:template name="fully-qualified-name"> + <xsl:param name="node"/> + <xsl:apply-templates select="$node" mode="fully-qualified-name"/> + </xsl:template> + + <!-- Hack to make the node we are building the current node so that the + ancestor:: syntax will work --> + <xsl:template match="*" mode="fully-qualified-name"> + <xsl:param name="is.id" select="false()" /> + <xsl:call-template name="build-fully-qualified-name"> + <xsl:with-param name="is.id" select="$is.id"/> + </xsl:call-template> + </xsl:template> + + <!-- The real routine that builds a fully-qualified name for the current + node. --> + <xsl:template name="build-fully-qualified-name"> + <xsl:param name="is.id" select="false()" /> + + <!-- Determine the set of ancestor namespaces --> + <xsl:variable name="ancestors" + select="ancestor::namespace| + ancestor::class|ancestor::struct|ancestor::union| + ancestor::class-specialization|ancestor::struct-specialization|ancestor::union-specialization"/> + + <xsl:for-each select="$ancestors"> + <xsl:apply-templates select="." mode="fast-print-id-part"> + <xsl:with-param name="is.id" select="$is.id"/> + </xsl:apply-templates> + <xsl:choose> + <xsl:when test="$is.id"><xsl:text>.</xsl:text></xsl:when> + <xsl:otherwise><xsl:text>::</xsl:text></xsl:otherwise> + </xsl:choose> + </xsl:for-each> + <xsl:apply-templates select="." mode="fast-print-id-part"> + <xsl:with-param name="is.id" select="$is.id"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:variable name="elements-with-ids"> + <xsl:apply-templates select="namespace|class|struct|union|class-specialization|struct-specialization|union-specialization" + mode="preprocess-ids"/> + </xsl:variable> + + <xsl:variable name="fast-elements" select="exsl:node-set($elements-with-ids)"/> + + <xsl:template match="*" mode="preprocess-ids"> + <element> + <xsl:attribute name="id"> + <xsl:value-of select="generate-id()"/> + </xsl:attribute> + <xsl:attribute name="part-id"> + <xsl:call-template name="print-id-part"/> + </xsl:attribute> + </element> + </xsl:template> + + <xsl:template name="print-id-part"> + <xsl:apply-templates select="." mode="print-id-part"/> + </xsl:template> + + <xsl:template match="*" mode="fast-print-id-part"> + <xsl:param name="is.id"/> + <xsl:choose> + <xsl:when test="not($is.id)"> + <xsl:apply-templates select="." mode="print-name"/> + </xsl:when> + <xsl:when test="$fast-elements[@id=generate-id()]"> + <xsl:value-of select="$fast-elements[@id=generate-id()]/@part-id"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates select="." mode="print-id-part"> + <xsl:with-param name="is.id" select="$is.id"/> + </xsl:apply-templates> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Print the part of a fully qualified name for a single element --> + <xsl:template match="*" mode="print-id-part"> + <xsl:param name="is.id"/> + + <xsl:variable name="part"> + <xsl:apply-templates select="." mode="print-name"/> + </xsl:variable> + + <xsl:variable name="unique-name"> + <xsl:apply-templates select="." mode="unique.name"/> + </xsl:variable> + + <xsl:choose> + <xsl:when test= + "$is.id and ( + string-length($part) > $boost.max.id.part.length or + $unique-name = 0 or + translate($part, '.<>;\:*?"| ', '') != $part + )"> + <xsl:variable name="normalized" select="translate(normalize-space(translate($part, '.<>;\:*?"|_', ' ')), ' ', '_')"/> + <xsl:variable name="id"><xsl:call-template name="postfix.id"/></xsl:variable> + <xsl:value-of select = + "concat( + substring($normalized, 1, $boost.max.id.part.length - string-length($id) - 1), + concat('_', $id))"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$part"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Override this if an id might not be unique --> + <xsl:template match="*" mode="unique.name"> + <xsl:value-of select="1"/> + </xsl:template> + + <xsl:template match="function|overloaded-function" mode="unique.name"> + <xsl:variable name="func-name"> + <xsl:call-template name="fully-qualified-name"> + <xsl:with-param name="node" select="."/> + </xsl:call-template> + </xsl:variable> + + <!-- Count the number of elements with the same qualified name --> + <xsl:variable name="count-elements"> + <xsl:for-each select="key('named-entities', translate(@name, $uppercase-letters, $lowercase-letters))"> + <xsl:variable name="other-name"> + <xsl:call-template name="fully-qualified-name"> + <xsl:with-param name="node" select="."/> + </xsl:call-template> + </xsl:variable> + <xsl:if test="$func-name = $other-name"> + <xsl:text> </xsl:text> + </xsl:if> + </xsl:for-each> + </xsl:variable> + + <xsl:value-of select="number(string-length($count-elements) = 1)"/> + </xsl:template> + + <!-- Print the name of the current node --> + <xsl:template match="*" mode="print-name"> + <xsl:value-of select="@name"/> + </xsl:template> + + <xsl:template match="template-arg" mode="print-name"> + <xsl:if test="position() > 1"> + <xsl:text>, </xsl:text> + </xsl:if> + <xsl:value-of select="text()"/> + <xsl:if test="@pack=1"> + <xsl:text>...</xsl:text> + </xsl:if> + </xsl:template> + + <xsl:template + match="struct-specialization|class-specialization|union-specialization" + mode="print-name"> + <xsl:value-of select="@name"/> + <xsl:text><</xsl:text> + <xsl:apply-templates select="specialization/template-arg" mode="print-name"/> + <xsl:text>></xsl:text> + </xsl:template> + + <xsl:template name="concat-directives"> + <xsl:param name="directives"/> + <xsl:for-each select="$directives"> + <xsl:apply-templates select="." mode="print-name"/> + <xsl:text>::</xsl:text> + </xsl:for-each> + </xsl:template> + + <xsl:template name="find-nodes-matching-name"> + <!-- The name we are looking for --> + <xsl:param name="name"/> + + <!-- The context in which this name occurs --> + <xsl:param name="context"/> + + <!-- The node that we are checking against --> + <xsl:param name="nodes"/> + + <!-- The set of using directives for this context node --> + <xsl:variable name="directives" + select="$context/ancestor::*/using-namespace | + $context/ancestor::namespace | + $context/ancestor::*/using-class | + $context/ancestor::class | + $context/ancestor::struct"/> + + <xsl:variable name="directives-str"> + <xsl:call-template name="concat-directives"> + <xsl:with-param name="directives" select="$directives"/> + </xsl:call-template> + </xsl:variable> + + <xsl:apply-templates select="$nodes" mode="generate-cxx-links"> + <xsl:with-param name="name" select="$name"/> + <xsl:with-param name="directives-str" select="$directives-str"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="*" mode="generate-cxx-links"> + <xsl:param name="name"/> + <xsl:param name="directives-str"/> + + <xsl:variable name="node-name"> + <xsl:call-template name="fully-qualified-name"> + <xsl:with-param name="node" select="."/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="leading-chars" + select="string-length($node-name) - string-length($name)"/> + + <!-- Check if this node matches any visible namespace --> + <xsl:if test="string-length($node-name) >= string-length($name) and + substring($node-name, $leading-chars + 1, + string-length($name)) = $name"> + <xsl:variable name="qualifiers" + select="substring($node-name, 1, $leading-chars)"/> + <xsl:if test="contains($directives-str, $qualifiers)"> + <xsl:variable name="myid"> + <xsl:call-template name="generate.id"> + <xsl:with-param name="node" select="."/> + </xsl:call-template> + </xsl:variable> + <cxx-link-helper> + <xsl:attribute name="id"> + <xsl:value-of select="$myid"/> + </xsl:attribute> + <xsl:attribute name="namespace"> + <xsl:value-of select="$qualifiers"/> + </xsl:attribute> + <xsl:text>random text</xsl:text> + </cxx-link-helper> + </xsl:if> + </xsl:if> + </xsl:template> + + <xsl:template name="cxx-link-name"> + <!-- The actual lookup node --> + <xsl:param name="lookup"/> + + <!-- The type of name to lookup (e.g., class) --> + <xsl:param name="type"/> + + <!-- The name we are looking for --> + <xsl:param name="name"/> + + <!-- The name we will display --> + <xsl:param name="display-name"/> + + <!-- The name we are looking for (unqualified)--> + <xsl:param name="unqualified-name"/> + + <!-- The list of nodes that match the lookup node in both name and type --> + <xsl:param name="nodes"/> + + <!-- Filter the nodes to leave only the ones that are in scope. --> + <xsl:variable name="matches1"> + <xsl:call-template name="find-nodes-matching-name"> + <xsl:with-param name="name" select="$name"/> + <xsl:with-param name="nodes" select="$nodes"/> + <xsl:with-param name="context" select="$lookup"/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="matches" select="exsl:node-set($matches1)//cxx-link-helper"/> + + <xsl:choose> + <xsl:when test="count($matches) = 0"> + <xsl:message> + <xsl:text>Cannot find </xsl:text> + <xsl:value-of select="$type"/> + <xsl:text> named '</xsl:text> + <xsl:value-of select="$name"/> + <xsl:text>'</xsl:text> + </xsl:message> + <xsl:value-of select="$display-name"/> + </xsl:when> + <xsl:otherwise> + <!-- If we found more than one, print a message and take the first --> + <xsl:if test="count($matches) > 1"> + <xsl:message> + <xsl:text>Reference to </xsl:text> + <xsl:value-of select="$type"/> + <xsl:text> '</xsl:text> + <xsl:value-of select="$name"/> + <xsl:text>' is ambiguous. Found:</xsl:text> + <xsl:for-each select="$matches"> + <xsl:text> + Match in namespace ::</xsl:text> + <xsl:value-of select="@namespace"/> + </xsl:for-each> + </xsl:message> + </xsl:if> + <xsl:call-template name="internal-link"> + <xsl:with-param name="to"> + <xsl:value-of select="$matches[position() = 1]/@id"/> + </xsl:with-param> + <xsl:with-param name="text" select="$display-name"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:template> +</xsl:stylesheet> |