1<?xml version="1.0" encoding="utf-8"?> 2<!-- 3 Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com> 4 5 Distributed under the Boost Software License, Version 1.0. 6 (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8 --> 9<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 10 xmlns:exsl="http://exslt.org/common" 11 version="1.0"> 12 13 <!-- Maximum length of directory and file names is 31 characters. 14 '.html' uses 5 characters. 15 31 - 5 = 26 --> 16 <xsl:param name="boost.max.id.part.length">26</xsl:param> 17 18 <!-- Generate an ID for the entity referenced --> 19 <xsl:template name="generate.id"> 20 <xsl:param name="node" select="."/> 21 <xsl:apply-templates select="$node" mode="generate.id"/> 22 </xsl:template> 23 24 <xsl:template match="*" mode="generate.id"> 25 <xsl:variable name="raw.id"><xsl:call-template name="object.id"/></xsl:variable> 26 <xsl:value-of select="translate($raw.id, '.', '_')"/> 27 <xsl:text>-bb</xsl:text> 28 </xsl:template> 29 30 <xsl:template name="postfix.id"> 31 <xsl:variable name="raw.id"><xsl:call-template name="object.id"/></xsl:variable> 32 <xsl:choose> 33 <xsl:when test="starts-with($raw.id, 'id-')"> 34 <xsl:value-of select="translate(substring-after($raw.id, 'id-'), '.', '_')"/> 35 </xsl:when> 36 <xsl:otherwise> 37 <xsl:value-of select="$raw.id"/> 38 </xsl:otherwise> 39 </xsl:choose> 40 </xsl:template> 41 42 <xsl:template name="strip-qualifiers-non-template"> 43 <xsl:param name="name"/> 44 <xsl:choose> 45 <xsl:when test="contains($name, '>')"> 46 <xsl:call-template name="strip-qualifiers-non-template"> 47 <xsl:with-param name="name" select="substring-after($name, '>')"/> 48 </xsl:call-template> 49 </xsl:when> 50 <xsl:when test="contains($name, '::')"> 51 <xsl:call-template name="strip-qualifiers-non-template"> 52 <xsl:with-param name="name" select="substring-after($name, '::')"/> 53 </xsl:call-template> 54 </xsl:when> 55 <xsl:otherwise> 56 <xsl:value-of select="$name"/> 57 </xsl:otherwise> 58 </xsl:choose> 59 </xsl:template> 60 61 <xsl:template name="strip-balanced"> 62 <xsl:param name="name"/> 63 <xsl:param name="open" select="'<'"/> 64 <xsl:param name="close" select="'>'"/> 65 <xsl:param name="depth" select="0"/> 66 <xsl:choose> 67 <xsl:when test="contains($name, $open) 68 and not(contains(substring-before($name, $open), $close))"> 69 <xsl:call-template name="strip-balanced"> 70 <xsl:with-param name="name" select="substring-after($name, $open)"/> 71 <xsl:with-param name="open" select="$open"/> 72 <xsl:with-param name="close" select="$close"/> 73 <xsl:with-param name="depth" select="$depth + 1"/> 74 </xsl:call-template> 75 </xsl:when> 76 <xsl:when test="contains($name, $close) and ($depth > 1)"> 77 <xsl:call-template name="strip-balanced"> 78 <xsl:with-param name="name" select="substring-after($name, $close)"/> 79 <xsl:with-param name="open" select="$open"/> 80 <xsl:with-param name="close" select="$close"/> 81 <xsl:with-param name="depth" select="$depth - 1"/> 82 </xsl:call-template> 83 </xsl:when> 84 <xsl:otherwise> 85 <xsl:value-of select="substring-after($name, $close)"/> 86 </xsl:otherwise> 87 </xsl:choose> 88 </xsl:template> 89 90 <xsl:template name="strip-qualifiers-template"> 91 <xsl:param name="name"/> 92 <xsl:choose> 93 <xsl:when test="contains($name, '::') 94 and not(contains(substring-before($name, '::'), '<'))"> 95 <xsl:call-template name="strip-qualifiers-template"> 96 <xsl:with-param name="name" select="substring-after($name, '::')"/> 97 </xsl:call-template> 98 </xsl:when> 99 <xsl:otherwise> 100 <xsl:variable name="rest"> 101 <xsl:call-template name="strip-balanced"> 102 <xsl:with-param name="name" select="$name"/> 103 </xsl:call-template> 104 </xsl:variable> 105 <xsl:choose> 106 <xsl:when test="$rest != ''"> 107 <xsl:call-template name="strip-qualifiers-template"> 108 <xsl:with-param name="name" select="$rest"/> 109 </xsl:call-template> 110 </xsl:when> 111 <xsl:otherwise> 112 <xsl:value-of select="$name"/> 113 </xsl:otherwise> 114 </xsl:choose> 115 </xsl:otherwise> 116 </xsl:choose> 117 </xsl:template> 118 119 <!-- Strip the qualifiers off a qualified name and return the unqualified 120 name. For instance, "boost::python::function" would become just 121 "function". 122 Must handle ns::foo -> foo 123 Must handle ns::foo<bar::baz> -> foo<bar::baz> 124 Must handle ns::foo<bar::baz>::nested -> nested 125 Must handle ns::foo<x>::bar<y> -> bar<y> --> 126 <xsl:template name="strip-qualifiers"> 127 <xsl:param name="name"/> 128 <xsl:choose> 129 <xsl:when test="substring($name, string-length($name)) = '>'"> 130 <xsl:call-template name="strip-qualifiers-template"> 131 <xsl:with-param name="name" select="$name"/> 132 </xsl:call-template> 133 </xsl:when> 134 <xsl:otherwise> 135 <xsl:call-template name="strip-qualifiers-non-template"> 136 <xsl:with-param name="name" select="$name"/> 137 </xsl:call-template> 138 </xsl:otherwise> 139 </xsl:choose> 140 </xsl:template> 141 142 <!-- Build the fully-qualified id of the given node --> 143 <xsl:template name="fully-qualified-id"> 144 <xsl:param name="node"/> 145 146 <xsl:apply-templates select="$node" mode="fully-qualified-name"> 147 <xsl:with-param name="is.id" select="true()"/> 148 </xsl:apply-templates> 149 </xsl:template> 150 151 <!-- Build the fully-qualified name of the given node --> 152 <xsl:template name="fully-qualified-name"> 153 <xsl:param name="node"/> 154 <xsl:apply-templates select="$node" mode="fully-qualified-name"/> 155 </xsl:template> 156 157 <!-- Hack to make the node we are building the current node so that the 158 ancestor:: syntax will work --> 159 <xsl:template match="*" mode="fully-qualified-name"> 160 <xsl:param name="is.id" select="false()" /> 161 <xsl:call-template name="build-fully-qualified-name"> 162 <xsl:with-param name="is.id" select="$is.id"/> 163 </xsl:call-template> 164 </xsl:template> 165 166 <!-- The real routine that builds a fully-qualified name for the current 167 node. --> 168 <xsl:template name="build-fully-qualified-name"> 169 <xsl:param name="is.id" select="false()" /> 170 171 <!-- Determine the set of ancestor namespaces --> 172 <xsl:variable name="ancestors" 173 select="ancestor::namespace| 174 ancestor::class|ancestor::struct|ancestor::union| 175 ancestor::class-specialization|ancestor::struct-specialization|ancestor::union-specialization"/> 176 177 <xsl:for-each select="$ancestors"> 178 <xsl:apply-templates select="." mode="fast-print-id-part"> 179 <xsl:with-param name="is.id" select="$is.id"/> 180 </xsl:apply-templates> 181 <xsl:choose> 182 <xsl:when test="$is.id"><xsl:text>.</xsl:text></xsl:when> 183 <xsl:otherwise><xsl:text>::</xsl:text></xsl:otherwise> 184 </xsl:choose> 185 </xsl:for-each> 186 <xsl:apply-templates select="." mode="fast-print-id-part"> 187 <xsl:with-param name="is.id" select="$is.id"/> 188 </xsl:apply-templates> 189 </xsl:template> 190 191 <xsl:variable name="elements-with-ids"> 192 <xsl:apply-templates select="namespace|class|struct|union|class-specialization|struct-specialization|union-specialization" 193 mode="preprocess-ids"/> 194 </xsl:variable> 195 196 <xsl:variable name="fast-elements" select="exsl:node-set($elements-with-ids)"/> 197 198 <xsl:template match="*" mode="preprocess-ids"> 199 <element> 200 <xsl:attribute name="id"> 201 <xsl:value-of select="generate-id()"/> 202 </xsl:attribute> 203 <xsl:attribute name="part-id"> 204 <xsl:call-template name="print-id-part"/> 205 </xsl:attribute> 206 </element> 207 </xsl:template> 208 209 <xsl:template name="print-id-part"> 210 <xsl:apply-templates select="." mode="print-id-part"/> 211 </xsl:template> 212 213 <xsl:template match="*" mode="fast-print-id-part"> 214 <xsl:param name="is.id"/> 215 <xsl:choose> 216 <xsl:when test="not($is.id)"> 217 <xsl:apply-templates select="." mode="print-name"/> 218 </xsl:when> 219 <xsl:when test="$fast-elements[@id=generate-id()]"> 220 <xsl:value-of select="$fast-elements[@id=generate-id()]/@part-id"/> 221 </xsl:when> 222 <xsl:otherwise> 223 <xsl:apply-templates select="." mode="print-id-part"> 224 <xsl:with-param name="is.id" select="$is.id"/> 225 </xsl:apply-templates> 226 </xsl:otherwise> 227 </xsl:choose> 228 </xsl:template> 229 230 <!-- Print the part of a fully qualified name for a single element --> 231 <xsl:template match="*" mode="print-id-part"> 232 <xsl:param name="is.id"/> 233 234 <xsl:variable name="part"> 235 <xsl:apply-templates select="." mode="print-name"/> 236 </xsl:variable> 237 238 <xsl:variable name="unique-name"> 239 <xsl:apply-templates select="." mode="unique.name"/> 240 </xsl:variable> 241 242 <xsl:choose> 243 <xsl:when test= 244 "$is.id and ( 245 string-length($part) > $boost.max.id.part.length or 246 $unique-name = 0 or 247 translate($part, '.<>;\:*?"| ', '') != $part 248 )"> 249 <xsl:variable name="normalized" select="translate(normalize-space(translate($part, '.<>;\:*?"|_', ' ')), ' ', '_')"/> 250 <xsl:variable name="id"><xsl:call-template name="postfix.id"/></xsl:variable> 251 <xsl:value-of select = 252 "concat( 253 substring($normalized, 1, $boost.max.id.part.length - string-length($id) - 1), 254 concat('_', $id))"/> 255 </xsl:when> 256 <xsl:otherwise> 257 <xsl:value-of select="$part"/> 258 </xsl:otherwise> 259 </xsl:choose> 260 </xsl:template> 261 262 <!-- Override this if an id might not be unique --> 263 <xsl:template match="*" mode="unique.name"> 264 <xsl:value-of select="1"/> 265 </xsl:template> 266 267 <xsl:template match="function|overloaded-function" mode="unique.name"> 268 <xsl:variable name="func-name"> 269 <xsl:call-template name="fully-qualified-name"> 270 <xsl:with-param name="node" select="."/> 271 </xsl:call-template> 272 </xsl:variable> 273 274 <!-- Count the number of elements with the same qualified name --> 275 <xsl:variable name="count-elements"> 276 <xsl:for-each select="key('named-entities', translate(@name, $uppercase-letters, $lowercase-letters))"> 277 <xsl:variable name="other-name"> 278 <xsl:call-template name="fully-qualified-name"> 279 <xsl:with-param name="node" select="."/> 280 </xsl:call-template> 281 </xsl:variable> 282 <xsl:if test="$func-name = $other-name"> 283 <xsl:text> </xsl:text> 284 </xsl:if> 285 </xsl:for-each> 286 </xsl:variable> 287 288 <xsl:value-of select="number(string-length($count-elements) = 1)"/> 289 </xsl:template> 290 291 <!-- Print the name of the current node --> 292 <xsl:template match="*" mode="print-name"> 293 <xsl:value-of select="@name"/> 294 </xsl:template> 295 296 <xsl:template match="template-arg" mode="print-name"> 297 <xsl:if test="position() > 1"> 298 <xsl:text>, </xsl:text> 299 </xsl:if> 300 <xsl:value-of select="text()"/> 301 <xsl:if test="@pack=1"> 302 <xsl:text>...</xsl:text> 303 </xsl:if> 304 </xsl:template> 305 306 <xsl:template 307 match="struct-specialization|class-specialization|union-specialization" 308 mode="print-name"> 309 <xsl:value-of select="@name"/> 310 <xsl:text><</xsl:text> 311 <xsl:apply-templates select="specialization/template-arg" mode="print-name"/> 312 <xsl:text>></xsl:text> 313 </xsl:template> 314 315 <xsl:template name="concat-directives"> 316 <xsl:param name="directives"/> 317 <xsl:for-each select="$directives"> 318 <xsl:apply-templates select="." mode="print-name"/> 319 <xsl:text>::</xsl:text> 320 </xsl:for-each> 321 </xsl:template> 322 323 <xsl:template name="find-nodes-matching-name"> 324 <!-- The name we are looking for --> 325 <xsl:param name="name"/> 326 327 <!-- The context in which this name occurs --> 328 <xsl:param name="context"/> 329 330 <!-- The node that we are checking against --> 331 <xsl:param name="nodes"/> 332 333 <!-- The set of using directives for this context node --> 334 <xsl:variable name="directives" 335 select="$context/ancestor::*/using-namespace | 336 $context/ancestor::namespace | 337 $context/ancestor::*/using-class | 338 $context/ancestor::class | 339 $context/ancestor::struct"/> 340 341 <xsl:variable name="directives-str"> 342 <xsl:call-template name="concat-directives"> 343 <xsl:with-param name="directives" select="$directives"/> 344 </xsl:call-template> 345 </xsl:variable> 346 347 <xsl:apply-templates select="$nodes" mode="generate-cxx-links"> 348 <xsl:with-param name="name" select="$name"/> 349 <xsl:with-param name="directives-str" select="$directives-str"/> 350 </xsl:apply-templates> 351 </xsl:template> 352 353 <xsl:template match="*" mode="generate-cxx-links"> 354 <xsl:param name="name"/> 355 <xsl:param name="directives-str"/> 356 357 <xsl:variable name="node-name"> 358 <xsl:call-template name="fully-qualified-name"> 359 <xsl:with-param name="node" select="."/> 360 </xsl:call-template> 361 </xsl:variable> 362 363 <xsl:variable name="leading-chars" 364 select="string-length($node-name) - string-length($name)"/> 365 366 <!-- Check if this node matches any visible namespace --> 367 <xsl:if test="string-length($node-name) >= string-length($name) and 368 substring($node-name, $leading-chars + 1, 369 string-length($name)) = $name"> 370 <xsl:variable name="qualifiers" 371 select="substring($node-name, 1, $leading-chars)"/> 372 <xsl:if test="contains($directives-str, $qualifiers)"> 373 <xsl:variable name="myid"> 374 <xsl:call-template name="generate.id"> 375 <xsl:with-param name="node" select="."/> 376 </xsl:call-template> 377 </xsl:variable> 378 <cxx-link-helper> 379 <xsl:attribute name="id"> 380 <xsl:value-of select="$myid"/> 381 </xsl:attribute> 382 <xsl:attribute name="namespace"> 383 <xsl:value-of select="$qualifiers"/> 384 </xsl:attribute> 385 <xsl:text>random text</xsl:text> 386 </cxx-link-helper> 387 </xsl:if> 388 </xsl:if> 389 </xsl:template> 390 391 <xsl:template name="cxx-link-name"> 392 <!-- The actual lookup node --> 393 <xsl:param name="lookup"/> 394 395 <!-- The type of name to lookup (e.g., class) --> 396 <xsl:param name="type"/> 397 398 <!-- The name we are looking for --> 399 <xsl:param name="name"/> 400 401 <!-- The name we will display --> 402 <xsl:param name="display-name"/> 403 404 <!-- The name we are looking for (unqualified)--> 405 <xsl:param name="unqualified-name"/> 406 407 <!-- The list of nodes that match the lookup node in both name and type --> 408 <xsl:param name="nodes"/> 409 410 <!-- Filter the nodes to leave only the ones that are in scope. --> 411 <xsl:variable name="matches1"> 412 <xsl:call-template name="find-nodes-matching-name"> 413 <xsl:with-param name="name" select="$name"/> 414 <xsl:with-param name="nodes" select="$nodes"/> 415 <xsl:with-param name="context" select="$lookup"/> 416 </xsl:call-template> 417 </xsl:variable> 418 419 <xsl:variable name="matches" select="exsl:node-set($matches1)//cxx-link-helper"/> 420 421 <xsl:choose> 422 <xsl:when test="count($matches) = 0"> 423 <xsl:message> 424 <xsl:text>Cannot find </xsl:text> 425 <xsl:value-of select="$type"/> 426 <xsl:text> named '</xsl:text> 427 <xsl:value-of select="$name"/> 428 <xsl:text>'</xsl:text> 429 </xsl:message> 430 <xsl:value-of select="$display-name"/> 431 </xsl:when> 432 <xsl:otherwise> 433 <!-- If we found more than one, print a message and take the first --> 434 <xsl:if test="count($matches) > 1"> 435 <xsl:message> 436 <xsl:text>Reference to </xsl:text> 437 <xsl:value-of select="$type"/> 438 <xsl:text> '</xsl:text> 439 <xsl:value-of select="$name"/> 440 <xsl:text>' is ambiguous. Found:</xsl:text> 441 <xsl:for-each select="$matches"> 442 <xsl:text> 443 Match in namespace ::</xsl:text> 444 <xsl:value-of select="@namespace"/> 445 </xsl:for-each> 446 </xsl:message> 447 </xsl:if> 448 <xsl:call-template name="internal-link"> 449 <xsl:with-param name="to"> 450 <xsl:value-of select="$matches[position() = 1]/@id"/> 451 </xsl:with-param> 452 <xsl:with-param name="text" select="$display-name"/> 453 </xsl:call-template> 454 </xsl:otherwise> 455 </xsl:choose> 456 </xsl:template> 457</xsl:stylesheet> 458