• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                version="1.0">
11  <xsl:import href="../lookup.xsl"/>
12
13  <!-- Set this parameter to a space-separated list of headers that
14       will be included in the output (all others are ignored). If this
15       parameter is omitted or left as the empty string, all headers will
16       be output. -->
17  <xsl:param name="boost.doxygen.headers" select="''"/>
18
19  <!-- The common prefix to all headers -->
20  <xsl:param name="boost.doxygen.header.prefix" select="'boost'"/>
21
22  <!-- The text that Doxygen places in overloaded functions. Damn them
23       for forcing us to compare TEXT just to figure out what's overloaded
24       and what isn't. -->
25  <xsl:param name="boost.doxygen.overload">
26    This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
27  </xsl:param>
28
29  <!-- The namespace used to identify code that should not be
30       processed at all. -->
31  <xsl:param name="boost.doxygen.detailns">detail</xsl:param>
32
33  <!-- The substring used to identify unspecified types that we can't
34       mask from within Doxygen. This is a hack (big surprise). -->
35  <xsl:param name="boost.doxygen.detail"><xsl:value-of select="$boost.doxygen.detailns"/>::</xsl:param>
36
37  <!-- The title that will be used for the BoostBook library reference emitted.
38       If left blank, BoostBook will assign a default title. -->
39  <xsl:param name="boost.doxygen.reftitle" select="''"/>
40
41  <!-- The id used for the library-reference. By default, it is the normalized
42       form of the reftitle. -->
43  <xsl:param name="boost.doxygen.refid" select="''"/>
44
45  <!-- The directory into which png files corresponding to LaTeX formulas will be found. -->
46  <xsl:param name="boost.doxygen.formuladir" select="'images/'"/>
47
48  <xsl:output method="xml" indent="no" standalone="yes"/>
49
50  <xsl:key name="compounds-by-kind" match="compounddef" use="@kind"/>
51  <xsl:key name="compounds-by-id" match="compounddef" use="@id"/>
52  <xsl:key name="members-by-id" match="memberdef" use="@id" />
53
54  <!-- Add trailing slash to formuladir if missing -->
55
56  <xsl:variable name="boost.doxygen.formuladir.fixed">
57    <xsl:choose>
58      <xsl:when test="substring(boost.doxygen.formuladir, string-length(boost.doxygen.formuladir) - 1) = '/'">
59        <xsl:value-of select="$boost.doxygen.formuladir" />
60      </xsl:when>
61      <xsl:otherwise>
62        <xsl:value-of select="concat($boost.doxygen.formuladir, '/')" />
63      </xsl:otherwise>
64    </xsl:choose>
65  </xsl:variable>
66
67  <xsl:strip-space elements="briefdescription detaileddescription inbodydescription"/>
68
69  <xsl:template name="kind-error-message">
70    <xsl:param name="message"/>
71
72    <xsl:variable name="location" select=".//location[1]" />
73    <xsl:variable name="name" select="./name" />
74
75    <xsl:message>
76      <xsl:if test="$location">
77        <xsl:value-of select="concat($location/@file, ':', $location/@line, ': ')" />
78      </xsl:if>
79      <xsl:value-of select="concat($message, ' with kind=', @kind)" />
80      <xsl:if test="$name">
81        <xsl:value-of select="concat(' (name=', $name, ') ')" />
82      </xsl:if>
83    </xsl:message>
84  </xsl:template>
85
86  <!-- translate-name: given a string, return a string suitable for use as a refid -->
87  <xsl:template name="translate-name">
88    <xsl:param name="name"/>
89    <xsl:value-of select="translate($name,
90                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ ~!%^&amp;*()[].,&lt;&gt;|/ +-=',
91                                    'abcdefghijklmnopqrstuvwxyz_____________________')"/>
92  </xsl:template>
93
94  <xsl:template match="/">
95    <xsl:apply-templates select="doxygen"/>
96  </xsl:template>
97
98  <xsl:template match="doxygen">
99    <library-reference>
100      <xsl:if test="string($boost.doxygen.reftitle) != ''">
101        <!-- when a reference section has a reftitle, also give it a refid. The id
102             is determined by the boost.doxygen.refid param, which defaults to a
103             normalized form of the boost.doxygen.reftitle -->
104        <xsl:attribute name="id">
105          <xsl:choose>
106            <xsl:when test="string($boost.doxygen.refid) != ''">
107              <xsl:value-of select="$boost.doxygen.refid"/>
108            </xsl:when>
109            <xsl:otherwise>
110              <xsl:call-template name="translate-name">
111                <xsl:with-param name="name" select="$boost.doxygen.reftitle"/>
112              </xsl:call-template>
113            </xsl:otherwise>
114          </xsl:choose>
115        </xsl:attribute>
116
117        <title><xsl:copy-of select="$boost.doxygen.reftitle"/></title>
118      </xsl:if>
119      <xsl:apply-templates select="key('compounds-by-kind', 'file')"/>
120    </library-reference>
121  </xsl:template>
122
123  <xsl:template match="compounddef">
124    <!-- The set of innernamespace nodes that limits our search -->
125    <xsl:param name="with-namespace-refs"/>
126    <xsl:param name="in-file"/>
127
128    <xsl:choose>
129      <!-- If the string INTERNAL ONLY is in the description, don't
130           emit this entity. This hack is necessary because Doxygen doesn't
131           tell us what is \internal and what isn't. -->
132      <xsl:when test="contains(detaileddescription/para, 'INTERNAL ONLY')"/>
133      <xsl:when test="contains(briefdescription/para, 'INTERNAL ONLY')"/>
134      <xsl:when test="contains(inbodydescription/para, 'INTERNAL ONLY')"/>
135
136      <xsl:when test="@kind='file'">
137        <xsl:call-template name="file"/>
138      </xsl:when>
139      <xsl:when test="@kind='namespace'">
140        <xsl:call-template name="namespace">
141          <xsl:with-param name="with-namespace-refs"
142            select="$with-namespace-refs"/>
143          <xsl:with-param name="in-file" select="$in-file"/>
144        </xsl:call-template>
145      </xsl:when>
146      <xsl:when test="@kind='class'">
147        <xsl:call-template name="class">
148          <xsl:with-param name="class-key" select="'class'"/>
149          <xsl:with-param name="in-file" select="$in-file"/>
150        </xsl:call-template>
151      </xsl:when>
152      <xsl:when test="@kind='struct'">
153        <xsl:call-template name="class">
154          <xsl:with-param name="class-key" select="'struct'"/>
155          <xsl:with-param name="in-file" select="$in-file"/>
156        </xsl:call-template>
157      </xsl:when>
158      <xsl:when test="@kind='union'">
159        <xsl:call-template name="class">
160          <xsl:with-param name="class-key" select="'union'"/>
161          <xsl:with-param name="in-file" select="$in-file"/>
162        </xsl:call-template>
163      </xsl:when>
164      <xsl:otherwise>
165        <xsl:call-template name="kind-error-message">
166          <xsl:with-param name="message" select="'Cannot handle compounddef'"/>
167        </xsl:call-template>
168      </xsl:otherwise>
169    </xsl:choose>
170  </xsl:template>
171
172  <xsl:template name="namespace">
173    <!-- The set of innernamespace nodes that limits our search -->
174    <xsl:param name="with-namespace-refs"/>
175    <xsl:param name="in-file"/>
176
177    <xsl:variable name="fullname" select="string(compoundname)"/>
178
179    <xsl:if test="$with-namespace-refs[string(text())=$fullname]
180                  and not(contains($fullname, $boost.doxygen.detailns))">
181      <!-- Namespace without the prefix -->
182      <xsl:variable name="rest">
183        <xsl:call-template name="strip-qualifiers">
184          <xsl:with-param name="name" select="compoundname"/>
185        </xsl:call-template>
186      </xsl:variable>
187
188      <!-- Grab only the namespace name, not any further nested namespaces -->
189      <xsl:variable name="name">
190        <xsl:choose>
191          <xsl:when
192            test="contains($rest, '::')">
193            <xsl:value-of select="substring-before($rest, '::')"/>
194          </xsl:when>
195          <xsl:otherwise>
196            <xsl:value-of select="$rest"/>
197          </xsl:otherwise>
198        </xsl:choose>
199      </xsl:variable>
200
201      <namespace>
202        <xsl:attribute name="name">
203          <xsl:value-of select="$name"/>
204        </xsl:attribute>
205        <xsl:text>&#10;</xsl:text><!-- Newline -->
206
207        <xsl:apply-templates>
208          <xsl:with-param name="with-namespace-refs"
209            select="$with-namespace-refs"/>
210          <xsl:with-param name="in-file" select="$in-file"/>
211        </xsl:apply-templates>
212      </namespace>
213      <xsl:text>&#10;</xsl:text><!-- Newline -->
214    </xsl:if>
215  </xsl:template>
216
217  <xsl:template name="class">
218    <xsl:param name="class-key"/>
219    <xsl:param name="in-file"/>
220    <xsl:param name="with-namespace-refs"/>
221
222    <xsl:if test="string(location/attribute::file)=$in-file">
223
224      <!-- The short name of this class -->
225      <xsl:variable name="name-with-spec">
226        <xsl:call-template name="strip-qualifiers">
227          <xsl:with-param name="name" select="compoundname"/>
228        </xsl:call-template>
229      </xsl:variable>
230
231      <xsl:variable name="name">
232        <xsl:choose>
233          <xsl:when test="contains($name-with-spec, '&lt;')">
234            <xsl:value-of select="substring-before($name-with-spec, '&lt;')"/>
235          </xsl:when>
236          <xsl:otherwise>
237            <xsl:value-of select="$name-with-spec"/>
238          </xsl:otherwise>
239        </xsl:choose>
240      </xsl:variable>
241
242      <xsl:variable name="specialization">
243        <xsl:if test="contains($name-with-spec, '&lt;')">
244          <xsl:variable name="spec-with-gt"
245            select="substring-after($name-with-spec, '&lt;')"/>
246          <xsl:value-of select="substring($spec-with-gt, 1,
247                                          string-length($spec-with-gt)-1)"/>
248        </xsl:if>
249      </xsl:variable>
250
251      <xsl:variable name="actual-class-key">
252        <xsl:value-of select="$class-key"/>
253        <xsl:if test="string-length($specialization) &gt; 0">
254          <xsl:text>-specialization</xsl:text>
255        </xsl:if>
256      </xsl:variable>
257
258      <xsl:element name="{$actual-class-key}">
259        <xsl:attribute name="name">
260          <xsl:value-of select="$name"/>
261        </xsl:attribute>
262
263        <xsl:apply-templates select="templateparamlist" mode="template"/>
264
265        <xsl:if test="string-length($specialization) &gt; 0">
266          <specialization>
267            <xsl:call-template name="specialization">
268              <xsl:with-param name="specialization" select="$specialization"/>
269            </xsl:call-template>
270          </specialization>
271        </xsl:if>
272
273        <xsl:apply-templates select="basecompoundref" mode="inherit"/>
274
275        <xsl:apply-templates select="briefdescription" mode="passthrough"/>
276        <xsl:apply-templates select="detaileddescription" mode="passthrough"/>
277        <xsl:apply-templates select="inbodydescription" mode="passthrough"/>
278        <xsl:apply-templates>
279          <xsl:with-param name="in-file" select="$in-file"/>
280        </xsl:apply-templates>
281      </xsl:element>
282    </xsl:if>
283  </xsl:template>
284
285  <xsl:template name="enum">
286    <xsl:param name="in-file"/>
287
288    <xsl:if test="string(location/attribute::file)=$in-file">
289      <xsl:variable name="name">
290        <xsl:call-template name="strip-qualifiers">
291          <xsl:with-param name="name" select="name"/>
292        </xsl:call-template>
293      </xsl:variable>
294
295      <enum>
296        <xsl:attribute name="name">
297          <xsl:value-of select="$name"/>
298        </xsl:attribute>
299
300        <xsl:apply-templates select="enumvalue"/>
301
302        <xsl:apply-templates select="briefdescription" mode="passthrough"/>
303        <xsl:apply-templates select="detaileddescription" mode="passthrough"/>
304        <xsl:apply-templates select="inbodydescription" mode="passthrough"/>
305      </enum>
306      <xsl:text>&#10;</xsl:text><!-- Newline -->
307    </xsl:if>
308  </xsl:template>
309
310  <xsl:template match="enumvalue">
311    <xsl:choose>
312      <!-- If the string INTERNAL ONLY is in the description, don't
313           emit this entity. This hack is necessary because Doxygen doesn't
314           tell us what is \internal and what isn't. -->
315      <xsl:when test="contains(detaileddescription/para, 'INTERNAL ONLY')"/>
316      <xsl:when test="contains(briefdescription/para, 'INTERNAL ONLY')"/>
317      <xsl:when test="contains(inbodydescription/para, 'INTERNAL ONLY')"/>
318      <xsl:otherwise>
319
320        <enumvalue>
321          <xsl:attribute name="name">
322            <xsl:value-of select="name"/>
323          </xsl:attribute>
324
325          <xsl:if test="initializer">
326            <default>
327              <xsl:apply-templates select="initializer/*|initializer/text()" mode="passthrough"/>
328            </default>
329          </xsl:if>
330
331          <xsl:apply-templates select="briefdescription" mode="passthrough"/>
332          <xsl:apply-templates select="detaileddescription" mode="passthrough"/>
333          <xsl:apply-templates select="inbodydescription" mode="passthrough"/>
334        </enumvalue>
335      </xsl:otherwise>
336    </xsl:choose>
337  </xsl:template>
338
339  <xsl:template name="doxygen.include.header.rec">
340    <xsl:param name="name"/>
341    <xsl:param name="header-list" select="$boost.doxygen.headers"/>
342
343    <xsl:choose>
344      <xsl:when test="contains($header-list, ' ')">
345        <xsl:variable name="header"
346          select="substring-before($header-list, ' ')"/>
347        <xsl:variable name="rest" select="substring-after($header-list, ' ')"/>
348
349        <xsl:choose>
350          <xsl:when test="$name=$header">
351            <xsl:text>yes</xsl:text>
352          </xsl:when>
353          <xsl:otherwise>
354            <xsl:call-template name="doxygen.include.header.rec">
355              <xsl:with-param name="name" select="$name"/>
356              <xsl:with-param name="header-list" select="$rest"/>
357            </xsl:call-template>
358          </xsl:otherwise>
359        </xsl:choose>
360      </xsl:when>
361      <xsl:when test="$name=$header-list">
362        <xsl:text>yes</xsl:text>
363      </xsl:when>
364    </xsl:choose>
365  </xsl:template>
366
367  <xsl:template name="doxygen.include.header">
368    <xsl:param name="name"/>
369
370    <xsl:if test="$boost.doxygen.headers=''">
371      <xsl:text>yes</xsl:text>
372    </xsl:if>
373    <xsl:if test="not($boost.doxygen.headers='')">
374      <xsl:call-template name="doxygen.include.header.rec">
375        <xsl:with-param name="name" select="$name"/>
376      </xsl:call-template>
377    </xsl:if>
378  </xsl:template>
379
380  <xsl:template name="file">
381    <xsl:variable name="include-header">
382      <xsl:call-template name="doxygen.include.header">
383        <xsl:with-param name="name" select="string(compoundname)"/>
384      </xsl:call-template>
385    </xsl:variable>
386    <xsl:if test="$include-header='yes'">
387      <header>
388        <xsl:attribute name="name">
389          <xsl:call-template name="shorten.header.name">
390            <xsl:with-param name="header" select="location/attribute::file"/>
391          </xsl:call-template>
392        </xsl:attribute>
393        <xsl:text>&#10;</xsl:text><!-- Newline -->
394
395        <xsl:if test="briefdescription/*|detaileddescription/*|inbodydescription/*">
396          <xsl:apply-templates select="briefdescription/*" mode="passthrough"/>
397          <xsl:apply-templates select="detaileddescription/*" mode="passthrough"/>
398          <xsl:apply-templates select="inbdoydescription/*" mode="passthrough"/>
399        </xsl:if>
400
401        <xsl:apply-templates mode="toplevel">
402          <xsl:with-param name="with-namespace-refs"
403            select="innernamespace"/>
404          <xsl:with-param name="in-file" select="location/attribute::file"/>
405        </xsl:apply-templates>
406      </header>
407      <xsl:text>&#10;</xsl:text><!-- Newline -->
408    </xsl:if>
409  </xsl:template>
410
411  <xsl:template name="shorten.header.name">
412    <xsl:param name="header"/>
413
414    <xsl:variable name="prefix">
415      <xsl:value-of select="concat($boost.doxygen.header.prefix, '/')"/>
416    </xsl:variable>
417
418    <xsl:choose>
419      <xsl:when test="contains($header, $prefix)">
420        <xsl:variable name="rest" select="substring-after($header, $prefix)"/>
421        <xsl:choose>
422          <xsl:when test="contains($rest, $prefix)">
423            <xsl:call-template name="shorten.header.name">
424              <xsl:with-param name="header" select="$rest"/>
425            </xsl:call-template>
426          </xsl:when>
427          <xsl:otherwise>
428            <xsl:value-of select="$prefix"/>
429            <xsl:value-of select="$rest"/>
430          </xsl:otherwise>
431        </xsl:choose>
432      </xsl:when>
433      <xsl:otherwise>
434        <xsl:value-of select="$header"/>
435      </xsl:otherwise>
436    </xsl:choose>
437  </xsl:template>
438
439
440  <xsl:template match="innernamespace">
441    <xsl:param name="with-namespace-refs"/>
442    <xsl:param name="in-file"/>
443
444    <xsl:apply-templates select="key('compounds-by-id', @refid)">
445      <xsl:with-param name="with-namespace-refs"
446        select="$with-namespace-refs"/>
447      <xsl:with-param name="in-file" select="$in-file"/>
448    </xsl:apply-templates>
449  </xsl:template>
450
451  <xsl:template match="innernamespace" mode="toplevel">
452    <!-- The set of innernamespace nodes that limits our search -->
453    <xsl:param name="with-namespace-refs"/>
454    <xsl:param name="in-file"/>
455
456    <!-- The full name of the namespace we are referring to -->
457    <xsl:variable name="fullname"
458      select="string(key('compounds-by-id', @refid)/compoundname)"/>
459
460    <!-- Only pass on top-level namespaces -->
461    <xsl:if test="not(contains($fullname, '::'))">
462      <xsl:apply-templates select="key('compounds-by-id', @refid)">
463        <xsl:with-param name="with-namespace-refs"
464          select="$with-namespace-refs"/>
465        <xsl:with-param name="in-file" select="$in-file"/>
466      </xsl:apply-templates>
467    </xsl:if>
468  </xsl:template>
469
470  <xsl:template match="sectiondef" mode="toplevel">
471    <xsl:param name="in-file" select="''"/>
472
473    <xsl:apply-templates mode="toplevel"
474                         select="memberdef[generate-id() =
475                                 generate-id(key('members-by-id', @id))]">
476      <xsl:with-param name="in-file" select="$in-file"/>
477    </xsl:apply-templates>
478  </xsl:template>
479
480  <xsl:template match="memberdef" mode="toplevel">
481    <xsl:param name="with-namespace-refs"/>
482    <xsl:param name="in-file"/>
483
484    <xsl:choose>
485      <!-- If the string INTERNAL ONLY is in the description, don't
486           emit this entity. This hack is necessary because Doxygen doesn't
487           tell us what is \internal and what isn't. -->
488      <xsl:when test="contains(detaileddescription/para, 'INTERNAL ONLY')"/>
489      <xsl:when test="contains(briefdescription/para, 'INTERNAL ONLY')"/>
490      <xsl:when test="contains(inbodydescription/para, 'INTERNAL ONLY')"/>
491
492      <xsl:when test="@kind='define'">
493        <macro>
494          <xsl:attribute name="name">
495            <xsl:value-of select="name/text()"/>
496          </xsl:attribute>
497
498          <xsl:if test="param">
499            <xsl:attribute name="kind">
500              <xsl:value-of select="'functionlike'"/>
501            </xsl:attribute>
502          </xsl:if>
503
504          <xsl:for-each select="param">
505            <xsl:variable name="name" select="defname/text()"/>
506            <macro-parameter>
507              <xsl:attribute name="name">
508                <xsl:value-of select="defname/text()"/>
509              </xsl:attribute>
510              <xsl:variable name="params"
511                            select="../detaileddescription/para/parameterlist"/>
512              <xsl:variable name="description" select="$params/parameteritem/
513                            parameternamelist/parametername[text() = $name]/../../parameterdescription/para"/>
514              <xsl:if test="$description">
515                <description>
516                  <xsl:apply-templates select="$description" mode="passthrough"/>
517                </description>
518              </xsl:if>
519            </macro-parameter>
520          </xsl:for-each>
521
522          <xsl:apply-templates select="briefdescription" mode="passthrough"/>
523          <xsl:apply-templates select="detaileddescription" mode="passthrough"/>
524          <xsl:apply-templates select="inbodydescription" mode="passthrough"/>
525        </macro>
526        <xsl:text>&#10;</xsl:text><!-- Newline -->
527      </xsl:when>
528
529      <xsl:when test="@kind='function'">
530        <xsl:call-template name="function">
531          <xsl:with-param name="in-file" select="$in-file"/>
532        </xsl:call-template>
533      </xsl:when>
534
535      <xsl:when test="@kind='typedef'">
536        <xsl:call-template name="typedef">
537          <xsl:with-param name="in-file" select="$in-file"/>
538        </xsl:call-template>
539      </xsl:when>
540
541      <xsl:when test="@kind='variable'">
542        <xsl:call-template name="variable" />
543      </xsl:when>
544
545      <xsl:when test="@kind='enum'">
546        <xsl:call-template name="enum" />
547      </xsl:when>
548
549      <xsl:otherwise>
550        <xsl:call-template name="kind-error-message">
551          <xsl:with-param name="message" select="'Cannot handle toplevel memberdef element'"/>
552        </xsl:call-template>
553      </xsl:otherwise>
554    </xsl:choose>
555  </xsl:template>
556
557  <xsl:template match="innerclass" mode="toplevel">
558    <xsl:param name="with-namespace-refs"/>
559    <xsl:param name="in-file"/>
560
561    <xsl:variable name="name">
562      <xsl:call-template name="strip-qualifiers">
563        <xsl:with-param name="name" select="."/>
564      </xsl:call-template>
565    </xsl:variable>
566
567    <!-- Only process this if it is indeed global -->
568    <xsl:if test=".=$name">
569      <xsl:apply-templates select="key('compounds-by-id', @refid)">
570        <xsl:with-param name="with-namespace-refs"
571          select="$with-namespace-refs"/>
572        <xsl:with-param name="in-file" select="$in-file"/>
573      </xsl:apply-templates>
574    </xsl:if>
575  </xsl:template>
576
577  <xsl:template match="innerclass">
578    <xsl:param name="with-namespace-refs"/>
579    <xsl:param name="in-file"/>
580
581    <xsl:apply-templates select="key('compounds-by-id', @refid)">
582      <xsl:with-param name="with-namespace-refs"
583        select="$with-namespace-refs"/>
584      <xsl:with-param name="in-file" select="$in-file"/>
585    </xsl:apply-templates>
586  </xsl:template>
587
588  <!-- Classes -->
589  <xsl:template match="templateparamlist" mode="template">
590    <template>
591      <xsl:apply-templates mode="template"/>
592    </template>
593  </xsl:template>
594
595  <xsl:template match="param" mode="template">
596    <xsl:choose>
597      <xsl:when test="string(type)='class' or string(type)='typename'">
598        <xsl:variable name="name" select="normalize-space(string(declname))"/>
599        <template-type-parameter>
600          <xsl:attribute name="name">
601            <xsl:value-of select="normalize-space(string(declname))"/>
602          </xsl:attribute>
603          <xsl:if test="defval">
604            <default>
605              <xsl:apply-templates select="defval/*|defval/text()"
606                mode="passthrough"/>
607            </default>
608          </xsl:if>
609          <xsl:for-each select="../../detaileddescription//parameterlist[@kind='templateparam']/parameteritem">
610            <xsl:if test="string(parameternamelist/parametername)=$name">
611              <purpose>
612                <xsl:apply-templates select="parameterdescription/para" mode="passthrough"/>
613              </purpose>
614            </xsl:if>
615          </xsl:for-each>
616        </template-type-parameter>
617      </xsl:when>
618      <!-- Doxygen 1.5.8 generates odd xml for template type parameters.
619           This deals with that -->
620      <xsl:when test="not(declname) and
621        (starts-with(string(type), 'class ') or starts-with(string(type), 'typename '))">
622        <template-type-parameter>
623          <xsl:variable name="name">
624            <xsl:value-of select="normalize-space(substring-after(string(type), ' '))"/>
625          </xsl:variable>
626          <xsl:attribute name="name">
627            <xsl:value-of select="$name"/>
628          </xsl:attribute>
629          <xsl:if test="defval">
630            <default>
631              <xsl:apply-templates select="defval/*|defval/text()"
632                mode="passthrough"/>
633            </default>
634          </xsl:if>
635          <xsl:for-each select="../../detaileddescription//parameterlist[@kind='templateparam']/parameteritem">
636            <xsl:if test="string(parameternamelist/parametername)=$name">
637              <purpose>
638                <xsl:apply-templates select="parameterdescription/para" mode="passthrough"/>
639              </purpose>
640            </xsl:if>
641          </xsl:for-each>
642        </template-type-parameter>
643      </xsl:when>
644      <xsl:otherwise>
645        <template-nontype-parameter>
646          <xsl:variable name="name">
647            <xsl:value-of select="normalize-space(string(declname))"/>
648          </xsl:variable>
649          <xsl:attribute name="name">
650            <xsl:value-of select="$name"/>
651          </xsl:attribute>
652          <type>
653            <xsl:apply-templates select="type"/>
654          </type>
655          <xsl:if test="defval">
656            <default>
657              <xsl:apply-templates select="defval/*|defval/text()"
658                mode="passthrough"/>
659            </default>
660          </xsl:if>
661          <xsl:for-each select="../../detaileddescription//parameterlist[@kind='templateparam']/parameteritem">
662            <xsl:if test="string(parameternamelist/parametername)=$name">
663              <purpose>
664                <xsl:apply-templates select="parameterdescription/para" mode="passthrough"/>
665              </purpose>
666            </xsl:if>
667          </xsl:for-each>
668        </template-nontype-parameter>
669      </xsl:otherwise>
670    </xsl:choose>
671  </xsl:template>
672
673  <xsl:template match="templateparamlist"/>
674
675  <!-- "Parse" a specialization from part of a name -->
676  <xsl:template name="specialization">
677    <xsl:param name="specialization"/>
678
679    <xsl:choose>
680      <xsl:when test="contains($specialization, ',')">
681        <template-arg>
682          <xsl:value-of
683            select="normalize-space(substring-before($specialization, ','))"/>
684        </template-arg>
685        <xsl:call-template name="specialization">
686          <xsl:with-param name="specialization"
687            select="substring-after($specialization, ',')"/>
688        </xsl:call-template>
689      </xsl:when>
690      <xsl:otherwise>
691        <template-arg>
692          <xsl:value-of select="normalize-space($specialization)"/>
693        </template-arg>
694      </xsl:otherwise>
695    </xsl:choose>
696  </xsl:template>
697
698  <!-- Inheritance -->
699  <xsl:template match="basecompoundref" mode="inherit">
700    <xsl:choose>
701      <xsl:when test="contains(string(.), $boost.doxygen.detail)"/>
702      <xsl:otherwise>
703        <inherit>
704          <!-- Access specifier for inheritance -->
705          <xsl:attribute name="access">
706            <xsl:value-of select="@prot"/>
707          </xsl:attribute>
708          <!-- TBD: virtual vs. non-virtual inheritance -->
709
710          <xsl:apply-templates mode="passthrough"/>
711        </inherit>
712      </xsl:otherwise>
713    </xsl:choose>
714  </xsl:template>
715
716  <xsl:template match="basecompoundref"/>
717
718  <!-- Skip over sections: they aren't very useful at all -->
719  <xsl:template match="sectiondef">
720    <xsl:param name="in-file" select="''"/>
721
722    <xsl:choose>
723      <xsl:when test="@kind='public-static-func'">
724        <!-- TBD: pass on the fact that these are static functions -->
725        <method-group name="public static functions">
726          <xsl:text>&#10;</xsl:text><!-- Newline -->
727          <xsl:apply-templates>
728            <xsl:with-param name="in-section" select="true()"/>
729            <xsl:with-param name="in-file" select="$in-file"/>
730          </xsl:apply-templates>
731        </method-group>
732        <xsl:text>&#10;</xsl:text><!-- Newline -->
733      </xsl:when>
734      <xsl:when test="@kind='protected-static-func'">
735        <!-- TBD: pass on the fact that these are static functions -->
736        <method-group name="protected static functions">
737          <xsl:text>&#10;</xsl:text><!-- Newline -->
738          <xsl:apply-templates>
739            <xsl:with-param name="in-section" select="true()"/>
740            <xsl:with-param name="in-file" select="$in-file"/>
741          </xsl:apply-templates>
742        </method-group>
743        <xsl:text>&#10;</xsl:text><!-- Newline -->
744      </xsl:when>
745      <xsl:when test="@kind='private-static-func'">
746        <!-- TBD: pass on the fact that these are static functions -->
747        <method-group name="private static functions">
748          <xsl:text>&#10;</xsl:text><!-- Newline -->
749          <xsl:apply-templates>
750            <xsl:with-param name="in-section" select="true()"/>
751            <xsl:with-param name="in-file" select="$in-file"/>
752          </xsl:apply-templates>
753        </method-group>
754        <xsl:text>&#10;</xsl:text><!-- Newline -->
755      </xsl:when>
756      <xsl:when test="@kind='public-func'">
757        <xsl:variable name="members" select="./memberdef"/>
758        <xsl:variable name="num-internal-only">
759          <xsl:value-of
760            select="count($members[contains(detaileddescription/para,
761                                  'INTERNAL ONLY')])"/>
762        </xsl:variable>
763        <xsl:if test="$num-internal-only &lt; count($members)">
764          <method-group name="public member functions">
765            <xsl:text>&#10;</xsl:text><!-- Newline -->
766            <xsl:apply-templates>
767              <xsl:with-param name="in-section" select="true()"/>
768              <xsl:with-param name="in-file" select="$in-file"/>
769            </xsl:apply-templates>
770          </method-group>
771          <xsl:text>&#10;</xsl:text><!-- Newline -->
772          <xsl:apply-templates/>
773        </xsl:if>
774      </xsl:when>
775      <xsl:when test="@kind='protected-func'">
776        <method-group name="protected member functions">
777          <xsl:text>&#10;</xsl:text><!-- Newline -->
778          <xsl:apply-templates>
779            <xsl:with-param name="in-section" select="true()"/>
780            <xsl:with-param name="in-file" select="$in-file"/>
781          </xsl:apply-templates>
782        </method-group>
783        <xsl:text>&#10;</xsl:text><!-- Newline -->
784        <xsl:apply-templates/>
785      </xsl:when>
786      <xsl:when test="@kind='private-func'">
787        <xsl:variable name="members" select="./memberdef"/>
788        <xsl:variable name="num-internal-only">
789          <xsl:value-of
790            select="count($members[contains(detaileddescription/para,
791                                  'INTERNAL ONLY')])"/>
792        </xsl:variable>
793        <xsl:if test="$num-internal-only &lt; count($members)">
794          <method-group name="private member functions">
795            <xsl:text>&#10;</xsl:text><!-- Newline -->
796            <xsl:apply-templates>
797              <xsl:with-param name="in-section" select="true()"/>
798              <xsl:with-param name="in-file" select="$in-file"/>
799            </xsl:apply-templates>
800          </method-group>
801          <xsl:text>&#10;</xsl:text><!-- Newline -->
802        </xsl:if>
803        <xsl:apply-templates/>
804      </xsl:when>
805      <xsl:when test="@kind='friend'">
806        <xsl:if test="./memberdef/detaileddescription/para or ./memberdef/briefdescription/para">
807          <method-group name="friend functions">
808            <xsl:text>&#10;</xsl:text><!-- Newline -->
809            <xsl:apply-templates>
810              <xsl:with-param name="in-section" select="true()"/>
811              <xsl:with-param name="in-file" select="$in-file"/>
812            </xsl:apply-templates>
813          </method-group>
814          <xsl:text>&#10;</xsl:text><!-- Newline -->
815        </xsl:if>
816      </xsl:when>
817      <xsl:when test="@kind='public-static-attrib' or @kind='public-attrib'">
818        <xsl:apply-templates>
819          <xsl:with-param name="in-file" select="$in-file"/>
820        </xsl:apply-templates>
821      </xsl:when>
822      <xsl:when test="@kind='public-type'">
823        <xsl:apply-templates>
824          <xsl:with-param name="in-file" select="$in-file"/>
825        </xsl:apply-templates>
826      </xsl:when>
827      <xsl:when test="@kind='private-type'">
828        <!--skip private members-->
829      </xsl:when>
830      <xsl:when test="@kind='private-static-attrib' or @kind='private-attrib'">
831        <!--skip private members-->
832      </xsl:when>
833      <xsl:when test="@kind='func'">
834        <xsl:apply-templates>
835          <xsl:with-param name="in-file" select="$in-file"/>
836        </xsl:apply-templates>
837      </xsl:when>
838      <xsl:when test="@kind='typedef'">
839        <xsl:apply-templates>
840          <xsl:with-param name="in-file" select="$in-file"/>
841        </xsl:apply-templates>
842      </xsl:when>
843      <xsl:when test="@kind='var'">
844        <xsl:apply-templates>
845          <xsl:with-param name="in-file" select="$in-file"/>
846        </xsl:apply-templates>
847      </xsl:when>
848      <xsl:when test="@kind='enum'">
849        <xsl:apply-templates>
850          <xsl:with-param name="in-file" select="$in-file"/>
851        </xsl:apply-templates>
852      </xsl:when>
853      <xsl:when test="@kind='user-defined'">
854        <xsl:apply-templates>
855          <xsl:with-param name="in-file" select="$in-file"/>
856        </xsl:apply-templates>
857      </xsl:when>
858      <xsl:when test="@kind=''">
859        <xsl:apply-templates select="memberdef[generate-id() =
860                                     generate-id(key('members-by-id', @id))]">
861          <xsl:with-param name="in-file" select="$in-file"/>
862        </xsl:apply-templates>
863      </xsl:when>
864      <xsl:otherwise>
865        <xsl:call-template name="kind-error-message">
866          <xsl:with-param name="message" select="'Cannot handle sectiondef'"/>
867        </xsl:call-template>
868      </xsl:otherwise>
869    </xsl:choose>
870  </xsl:template>
871
872  <!-- Handle member definitions -->
873  <xsl:template match="memberdef">
874    <!-- True when we're inside a section -->
875    <xsl:param name="in-section" select="false()"/>
876    <xsl:param name="in-file" select="''"/>
877
878    <xsl:choose>
879      <!-- If the string INTERNAL ONLY is in the description, don't
880           emit this entity. This hack is necessary because Doxygen doesn't
881           tell us what is \internal and what isn't. -->
882      <xsl:when test="contains(detaileddescription/para, 'INTERNAL ONLY')"/>
883      <xsl:when test="contains(briefdescription/para, 'INTERNAL ONLY')"/>
884      <xsl:when test="contains(inbodydescription/para, 'INTERNAL ONLY')"/>
885
886      <xsl:when test="@kind='typedef'">
887        <xsl:call-template name="typedef">
888          <xsl:with-param name="in-file" select="$in-file"/>
889        </xsl:call-template>
890      </xsl:when>
891      <xsl:when test="@kind='function'">
892        <xsl:choose>
893          <xsl:when test="ancestor::compounddef/attribute::kind='namespace'">
894            <xsl:call-template name="function">
895              <xsl:with-param name="in-file" select="$in-file"/>
896            </xsl:call-template>
897          </xsl:when>
898          <xsl:otherwise>
899            <!-- We are in a class -->
900            <!-- The name of the class we are in -->
901            <xsl:variable name="in-class-full">
902              <xsl:call-template name="strip-qualifiers">
903                <xsl:with-param name="name"
904                  select="string(ancestor::compounddef/compoundname/text())"/>
905              </xsl:call-template>
906            </xsl:variable>
907
908            <xsl:variable name ="in-class">
909              <xsl:choose>
910                <xsl:when test="contains($in-class-full, '&lt;')">
911                  <xsl:value-of select="substring-before($in-class-full, '&lt;')"/>
912                </xsl:when>
913                <xsl:otherwise>
914                  <xsl:value-of select="$in-class-full"/>
915                </xsl:otherwise>
916              </xsl:choose>
917            </xsl:variable>
918
919            <xsl:choose>
920              <xsl:when test="string(name/text())=$in-class">
921                <xsl:if test="not ($in-section)">
922                  <xsl:call-template name="constructor"/>
923                </xsl:if>
924              </xsl:when>
925              <xsl:when test="string(name/text())=concat('~',$in-class)">
926                <xsl:if test="not ($in-section)">
927                  <xsl:call-template name="destructor"/>
928                </xsl:if>
929              </xsl:when>
930              <xsl:when test="string(name/text())='operator='">
931                <xsl:if test="not ($in-section)">
932                  <xsl:call-template name="copy-assignment"/>
933                </xsl:if>
934              </xsl:when>
935              <xsl:when test="normalize-space(string(type))=''
936                              and contains(name/text(), 'operator ')">
937                <xsl:if test="$in-section">
938                  <xsl:call-template name="conversion-operator"/>
939                </xsl:if>
940              </xsl:when>
941              <xsl:otherwise>
942                <xsl:if test="$in-section">
943                  <xsl:call-template name="method"/>
944                </xsl:if>
945              </xsl:otherwise>
946            </xsl:choose>
947          </xsl:otherwise>
948        </xsl:choose>
949      </xsl:when>
950      <xsl:when test="@kind='friend'">
951        <xsl:if test="./detaileddescription/para or ./briefdescription/para">
952          <xsl:call-template name="method"/>
953        </xsl:if>
954      </xsl:when>
955      <xsl:when test="@kind='enum'">
956        <xsl:call-template name="enum">
957          <xsl:with-param name="in-file" select="$in-file"/>
958        </xsl:call-template>
959      </xsl:when>
960      <xsl:when test="@kind='variable'">
961        <xsl:call-template name="variable">
962          <xsl:with-param name="in-file" select="$in-file"/>
963        </xsl:call-template>
964      </xsl:when>
965      <xsl:otherwise>
966        <xsl:call-template name="kind-error-message">
967          <xsl:with-param name="message" select="'Cannot handle memberdef element'"/>
968        </xsl:call-template>
969      </xsl:otherwise>
970    </xsl:choose>
971  </xsl:template>
972
973  <!-- Display typedefs -->
974  <xsl:template name="typedef">
975    <xsl:param name="in-file" select="''"/>
976
977    <xsl:if test="string(location/attribute::file)=$in-file">
978      <!-- TBD: Handle public/protected/private -->
979      <typedef>
980        <!-- Name of the type -->
981        <xsl:attribute name="name">
982          <xsl:value-of select="name/text()"/>
983        </xsl:attribute>
984
985        <xsl:apply-templates select="briefdescription" mode="passthrough"/>
986        <xsl:apply-templates select="detaileddescription" mode="passthrough"/>
987        <xsl:apply-templates select="inbodydescription" mode="passthrough"/>
988
989        <type><xsl:apply-templates select="type"/></type>
990      </typedef>
991      <xsl:text>&#10;</xsl:text><!-- Newline -->
992    </xsl:if>
993  </xsl:template>
994
995  <!-- Handle function parameters -->
996  <xsl:template match="param" mode="function">
997    <parameter>
998      <!-- Parameter name -->
999      <xsl:attribute name="name">
1000        <xsl:value-of select="normalize-space(declname/text())"/>
1001      </xsl:attribute>
1002
1003      <!-- Parameter type -->
1004      <paramtype><xsl:apply-templates select="type"/></paramtype>
1005
1006      <!-- Default argument -->
1007      <xsl:if test="defval">
1008        <default>
1009          <xsl:choose>
1010            <xsl:when test="contains(string(defval), $boost.doxygen.detail)">
1011              <emphasis>unspecified</emphasis>
1012            </xsl:when>
1013            <xsl:otherwise>
1014              <xsl:apply-templates select="defval/*|defval/text()"
1015                mode="passthrough"/>
1016            </xsl:otherwise>
1017          </xsl:choose>
1018
1019        </default>
1020      </xsl:if>
1021
1022      <!-- Parameter description -->
1023      <xsl:variable name="name">
1024        <xsl:value-of select="normalize-space(declname/text())"/>
1025      </xsl:variable>
1026
1027      <xsl:apply-templates select="../*[self::detaileddescription or self::inbodydescription]//parameterlist[attribute::kind='param']/*"
1028        mode="parameter.description">
1029        <xsl:with-param name="name">
1030          <xsl:value-of select="$name"/>
1031        </xsl:with-param>
1032      </xsl:apply-templates>
1033    </parameter>
1034  </xsl:template>
1035
1036  <xsl:template match="parameteritem" mode="parameter.description">
1037    <!-- The parameter name we are looking for -->
1038    <xsl:param name="name"/>
1039
1040    <xsl:if test="string(parameternamelist/parametername) = $name">
1041      <description>
1042        <xsl:apply-templates select="parameterdescription/para" mode="passthrough"/>
1043      </description>
1044    </xsl:if>
1045  </xsl:template>
1046
1047  <!-- For older versions of Doxygen, which didn't use parameteritem -->
1048  <xsl:template match="parameterdescription" mode="parameter.description">
1049    <!-- The parameter name we are looking for -->
1050    <xsl:param name="name"/>
1051
1052    <!-- The parametername node associated with this description -->
1053    <xsl:variable name="name-node" select="preceding-sibling::*[1]"/>
1054
1055    <xsl:if test="string($name-node/text()) = $name">
1056      <description>
1057        <xsl:apply-templates select="para" mode="passthrough"/>
1058      </description>
1059    </xsl:if>
1060  </xsl:template>
1061
1062  <xsl:template name="function.attributes">
1063
1064    <!-- argsstring = '(arguments) [= delete] [= default] [constexpt]' -->
1065    <xsl:variable name="extra-qualifiers-a">
1066      <xsl:if test="contains(argsstring/text(), '(')">
1067        <xsl:call-template name="strip-brackets">
1068          <xsl:with-param name="text" select="substring-after(argsstring/text(), '(')" />
1069        </xsl:call-template>
1070      </xsl:if>
1071    </xsl:variable>
1072    <xsl:variable name="extra-qualifiers">
1073      <xsl:if test="$extra-qualifiers-a">
1074        <xsl:value-of select="concat(' ', normalize-space($extra-qualifiers-a), ' ')" />
1075      </xsl:if>
1076    </xsl:variable>
1077
1078    <!-- CV Qualifiers -->
1079    <!-- Plus deleted and defaulted function markers as they're not properly
1080         supported in boostbook -->
1081
1082    <!-- noexcept is complicated because is can have parameters.
1083         TODO: should really remove the noexcept parameters before doing
1084               anything else. -->
1085    <xsl:variable name="noexcept">
1086      <xsl:choose>
1087        <xsl:when test="contains($extra-qualifiers, ' noexcept(')">
1088          <xsl:call-template name="noexcept-if">
1089            <xsl:with-param name="condition" select="substring-after($extra-qualifiers, ' noexcept(')" />
1090          </xsl:call-template>
1091        </xsl:when>
1092
1093        <xsl:when test="contains($extra-qualifiers, ' BOOST_NOEXCEPT_IF(')">
1094          <xsl:call-template name="noexcept-if">
1095            <xsl:with-param name="condition" select="substring-after($extra-qualifiers, ' BOOST_NOEXCEPT_IF(')" />
1096          </xsl:call-template>
1097        </xsl:when>
1098
1099        <xsl:when test="contains($extra-qualifiers, ' noexcept ') or contains($extra-qualifiers, ' BOOST_NOEXCEPT ')">
1100          <xsl:value-of select="'noexcept '" />
1101        </xsl:when>
1102      </xsl:choose>
1103    </xsl:variable>
1104
1105    <!-- Calculate constexpr now, so that we can avoid it getting confused
1106         with const -->
1107    <xsl:variable name="constexpr" select="
1108        contains($extra-qualifiers, ' const expr ') or
1109        contains($extra-qualifiers, ' BOOST_CONSTEXPR ') or
1110        contains($extra-qualifiers, ' BOOST_CONSTEXPR_OR_CONST ')" />
1111
1112    <!-- The 'substring' trick includes the string if the condition is true -->
1113    <xsl:variable name="cv-qualifiers" select="normalize-space(concat(
1114        substring('constexpr ', 1, 999 * $constexpr),
1115        substring('const ', 1, 999 * (not($constexpr) and @const='yes')),
1116        substring('volatile ', 1, 999 * (@volatile='yes' or contains($extra-qualifiers, ' volatile '))),
1117        $noexcept,
1118        substring('= delete ', 1, 999 * contains($extra-qualifiers, ' =delete ')),
1119        substring('= default ', 1, 999 * contains($extra-qualifiers, ' =default ')),
1120        substring('= 0 ', 1, 999 * (@virt = 'pure-virtual')),
1121        ''))" />
1122
1123    <!-- Specifiers -->
1124    <xsl:variable name="specifiers" select="normalize-space(concat(
1125        substring('explicit ', 1, 999 * (@explicit = 'yes')),
1126        substring('virtual ', 1, 999 * (
1127            @virtual='yes' or @virt='virtual' or @virt='pure-virtual')),
1128        substring('static ', 1, 999 * (@static = 'yes')),
1129        ''))" />
1130
1131    <xsl:if test="$cv-qualifiers">
1132      <xsl:attribute name="cv">
1133        <xsl:value-of select="$cv-qualifiers" />
1134      </xsl:attribute>
1135    </xsl:if>
1136
1137    <xsl:if test="$specifiers">
1138      <xsl:attribute name="specifiers">
1139        <xsl:value-of select="$specifiers" />
1140      </xsl:attribute>
1141    </xsl:if>
1142
1143  </xsl:template>
1144
1145  <!-- $condition = string after the opening bracket of the condition -->
1146  <xsl:template name="noexcept-if">
1147    <xsl:param name="condition"/>
1148
1149    <xsl:variable name="trailing">
1150      <xsl:call-template name="strip-brackets">
1151        <xsl:with-param name="text" select="$condition" />
1152      </xsl:call-template>
1153    </xsl:variable>
1154
1155    <xsl:choose>
1156      <xsl:when test="string-length($trailing)">
1157        <xsl:value-of select="concat(
1158            'noexcept(',
1159            substring($condition, 1, string-length($condition) - string-length($trailing)),
1160            ') ')" />
1161      </xsl:when>
1162      <xsl:otherwise>
1163        <!-- Something has gone wrong so: -->
1164        <xsl:value-of select="'noexcept(condition) '" />
1165      </xsl:otherwise>
1166    </xsl:choose>
1167  </xsl:template>
1168
1169  <!-- $text = substring after the opening bracket -->
1170  <xsl:template name="strip-brackets">
1171    <xsl:param name="text"/>
1172
1173    <xsl:if test="contains($text, ')')">
1174      <xsl:variable name="prefix1" select="substring-before($text, ')')" />
1175      <xsl:variable name="prefix2" select="substring($prefix1, 1,
1176          string-length(substring-before($prefix1, '(')) +
1177          999 * not(contains($prefix1, '(')))" />
1178      <xsl:variable name="prefix3" select="substring($prefix2, 1,
1179          string-length(substring-before($prefix2, '&quot;')) +
1180          999 * not(contains($prefix2, '&quot;')))" />
1181      <xsl:variable name="prefix" select="substring($prefix3, 1,
1182          string-length(substring-before($prefix3, &quot;'&quot;)) +
1183          999 * not(contains($prefix3, &quot;'&quot;)))" />
1184
1185      <xsl:variable name="prefix-length" select="string-length($prefix)" />
1186      <xsl:variable name="char" select="substring($text, $prefix-length + 1, 1)" />
1187
1188      <xsl:choose>
1189        <xsl:when test="$char=')'">
1190          <xsl:value-of select="substring($text, $prefix-length + 2)" />
1191        </xsl:when>
1192        <xsl:when test="$char='('">
1193          <xsl:variable name="text2">
1194            <xsl:call-template name="strip-brackets">
1195              <xsl:with-param name="text" select="substring($text, $prefix-length + 2)" />
1196            </xsl:call-template>
1197          </xsl:variable>
1198          <xsl:call-template name="strip-brackets">
1199            <xsl:with-param name="text" select="$text2" />
1200          </xsl:call-template>
1201        </xsl:when>
1202        <xsl:when test="$char=&quot;'&quot;">
1203          <!-- Not bothering with escapes, because this is crazy enough as it is -->
1204          <xsl:call-template name="strip-brackets">
1205            <xsl:with-param name="text" select="substring-after(substring($text, $prefix-length + 2), &quot;'&quot;)" />
1206          </xsl:call-template>
1207        </xsl:when>
1208        <xsl:when test="$char='&quot;'">
1209          <!-- Not bothering with escapes, because this is crazy enough as it is -->
1210          <xsl:call-template name="strip-brackets">
1211            <xsl:with-param name="text" select="substring-after(substring($text, $prefix-length + 2), '&quot;')" />
1212          </xsl:call-template>
1213        </xsl:when>
1214      </xsl:choose>
1215    </xsl:if>
1216  </xsl:template>
1217
1218  <!-- Handle function children -->
1219  <xsl:template name="function.children">
1220    <xsl:param name="is-overloaded" select="false()"/>
1221
1222    <xsl:if test="not($is-overloaded)">
1223      <!-- Emit template header -->
1224      <xsl:apply-templates select="templateparamlist" mode="template"/>
1225
1226      <!-- Emit function parameters -->
1227      <xsl:apply-templates select="param" mode="function"/>
1228    </xsl:if>
1229
1230    <!-- The description -->
1231    <xsl:apply-templates select="briefdescription" mode="passthrough"/>
1232    <xsl:apply-templates select="detaileddescription" mode="passthrough"/>
1233    <xsl:apply-templates select="inbodydescription" mode="passthrough"/>
1234
1235    <xsl:apply-templates
1236      select="*[self::detaileddescription or self::inbodydescription]/para/simplesect[@kind='pre']"
1237      mode="function-clauses"/>
1238    <xsl:apply-templates
1239      select="*[self::detaileddescription or self::inbodydescription]/para/simplesect[@kind='post']"
1240      mode="function-clauses"/>
1241    <xsl:apply-templates
1242      select="*[self::detaileddescription or self::inbodydescription]/para/simplesect[@kind='return']"
1243      mode="function-clauses"/>
1244    <xsl:if test="*[self::detaileddescription or self::inbodydescription]/para/parameterlist[@kind='exception']">
1245      <throws>
1246        <xsl:apply-templates
1247          select="*[self::detaileddescription or self::inbodydescription]/para/parameterlist[@kind='exception']"
1248          mode="function-clauses"/>
1249      </throws>
1250    </xsl:if>
1251  </xsl:template>
1252
1253  <!-- Handle free functions -->
1254  <xsl:template name="function">
1255    <xsl:param name="in-file" select="''"/>
1256
1257    <xsl:variable name="firstpara"
1258      select="normalize-space(detaileddescription/para[1])"/>
1259    <xsl:if test="string(location/attribute::file)=$in-file
1260                  and
1261                  not($firstpara=normalize-space($boost.doxygen.overload))">
1262
1263      <xsl:variable name="next-node" select="following-sibling::*[1]"/>
1264      <xsl:variable name="has-overload">
1265        <xsl:if test="not(local-name($next-node)='memberdef')">
1266          false
1267        </xsl:if>
1268        <xsl:if test="not(string($next-node/name/text())=string(name/text()))">
1269          false
1270        </xsl:if>
1271        <xsl:if
1272          test="not(normalize-space($next-node/detaileddescription/para[1])
1273                    =normalize-space($boost.doxygen.overload))">
1274          false
1275        </xsl:if>
1276      </xsl:variable>
1277
1278      <xsl:choose>
1279        <xsl:when test="not(contains($has-overload, 'false'))">
1280          <overloaded-function>
1281            <xsl:attribute name="name">
1282              <xsl:call-template name="normalize-name"/>
1283            </xsl:attribute>
1284
1285            <xsl:call-template name="overload-signatures"/>
1286            <xsl:call-template name="function.children">
1287              <xsl:with-param name="is-overloaded" select="true()"/>
1288            </xsl:call-template>
1289          </overloaded-function>
1290        </xsl:when>
1291        <xsl:otherwise>
1292          <function>
1293            <xsl:attribute name="name">
1294              <xsl:call-template name="normalize-name"/>
1295            </xsl:attribute>
1296
1297            <!-- Return type -->
1298            <type><xsl:apply-templates select="type"/></type>
1299
1300            <xsl:call-template name="function.children"/>
1301          </function>
1302        </xsl:otherwise>
1303      </xsl:choose>
1304    </xsl:if>
1305    <xsl:text>&#10;</xsl:text><!-- Newline -->
1306  </xsl:template>
1307
1308  <!-- Emit overload signatures -->
1309  <xsl:template name="overload-signatures">
1310    <xsl:param name="node" select="."/>
1311    <xsl:param name="name" select="string(name/text())"/>
1312    <xsl:param name="first" select="true()"/>
1313
1314    <xsl:choose>
1315      <xsl:when test="not(local-name($node)='memberdef')"/>
1316      <xsl:when test="not(string($node/name/text())=$name)"/>
1317      <xsl:when test="not(normalize-space($node/detaileddescription/para[1])
1318                          =normalize-space($boost.doxygen.overload))
1319                      and not($first)"/>
1320      <xsl:otherwise>
1321        <signature>
1322          <type>
1323            <xsl:apply-templates select="$node/type"/>
1324          </type>
1325          <xsl:apply-templates select="$node/templateparamlist"
1326            mode="template"/>
1327          <xsl:apply-templates select="$node/param" mode="function"/>
1328        </signature>
1329
1330        <xsl:call-template name="overload-signatures">
1331          <xsl:with-param name="node" select="$node/following-sibling::*[1]"/>
1332          <xsl:with-param name="name" select="$name"/>
1333          <xsl:with-param name="first" select="false()"/>
1334        </xsl:call-template>
1335      </xsl:otherwise>
1336    </xsl:choose>
1337  </xsl:template>
1338
1339  <!-- Handle constructors -->
1340  <xsl:template name="constructor">
1341    <constructor>
1342      <xsl:if test="@explicit = 'yes'">
1343        <xsl:attribute name="specifiers">explicit</xsl:attribute>
1344      </xsl:if>
1345      <xsl:call-template name="function.attributes"/>
1346      <xsl:call-template name="function.children"/>
1347    </constructor>
1348    <xsl:text>&#10;</xsl:text><!-- Newline -->
1349  </xsl:template>
1350
1351  <!-- Handle Destructors -->
1352  <xsl:template name="destructor">
1353    <destructor>
1354      <xsl:call-template name="function.children"/>
1355    </destructor>
1356    <xsl:text>&#10;</xsl:text><!-- Newline -->
1357  </xsl:template>
1358
1359  <!-- Handle Copy Assignment -->
1360  <xsl:template name="copy-assignment">
1361    <copy-assignment>
1362      <xsl:call-template name="function.attributes"/>
1363      <!-- Return type -->
1364      <xsl:element name="type">
1365        <xsl:apply-templates select="type"/>
1366      </xsl:element>
1367
1368      <xsl:call-template name="function.children"/>
1369    </copy-assignment>
1370    <xsl:text>&#10;</xsl:text><!-- Newline -->
1371  </xsl:template>
1372
1373  <!-- Handle conversion operator -->
1374  <xsl:template name="conversion-operator">
1375    <method>
1376      <xsl:attribute name="name">
1377        <xsl:text>conversion-operator</xsl:text>
1378      </xsl:attribute>
1379      <xsl:call-template name="function.attributes"/>
1380
1381      <!-- Conversion type -->
1382      <type>
1383        <xsl:value-of select="substring-after(name/text(), 'operator ')"/>
1384      </type>
1385
1386      <xsl:call-template name="function.children"/>
1387    </method>
1388    <xsl:text>&#10;</xsl:text><!-- Newline -->
1389  </xsl:template>
1390
1391  <!-- Handle methods -->
1392  <xsl:template name="method">
1393    <method>
1394      <xsl:attribute name="name">
1395        <xsl:value-of select="name/text()"/>
1396      </xsl:attribute>
1397      <xsl:call-template name="function.attributes"/>
1398
1399      <!-- Return type -->
1400      <xsl:element name="type">
1401        <xsl:apply-templates select="type"/>
1402      </xsl:element>
1403
1404      <xsl:call-template name="function.children"/>
1405    </method>
1406    <xsl:text>&#10;</xsl:text><!-- Newline -->
1407  </xsl:template>
1408
1409  <!-- Handle member variables -->
1410  <xsl:template name="variable">
1411    <xsl:param name="in-file"/>
1412    <xsl:if test="string(location/attribute::file)=$in-file">
1413    <data-member>
1414      <xsl:attribute name="name">
1415        <xsl:value-of select="name/text()"/>
1416      </xsl:attribute>
1417
1418      <!-- Specifiers -->
1419      <xsl:if test="@static = 'yes'">
1420        <xsl:attribute name="specifiers">static</xsl:attribute>
1421      </xsl:if>
1422      <xsl:if test="@mutable = 'yes'">
1423        <xsl:attribute name="specifiers">mutable</xsl:attribute>
1424      </xsl:if>
1425
1426      <type>
1427        <xsl:apply-templates select="type"/>
1428      </type>
1429
1430      <xsl:apply-templates select="briefdescription" mode="passthrough"/>
1431      <xsl:apply-templates select="detaileddescription" mode="passthrough"/>
1432      <xsl:apply-templates select="inbodydescription" mode="passthrough"/>
1433    </data-member>
1434    <xsl:text>&#10;</xsl:text><!-- Newline -->
1435    </xsl:if>
1436  </xsl:template>
1437
1438  <!-- Things we ignore directly -->
1439  <xsl:template match="compoundname" mode="toplevel"/>
1440  <xsl:template match="includes|includedby|incdepgraph|invincdepgraph" mode="toplevel"/>
1441  <xsl:template match="programlisting" mode="toplevel"/>
1442  <xsl:template match="text()" mode="toplevel"/>
1443
1444  <xsl:template match="text()"/>
1445
1446  <!-- Passthrough of text -->
1447  <xsl:template match="text()" mode="passthrough">
1448    <xsl:value-of select="."/>
1449  </xsl:template>
1450  <xsl:template match="para" mode="passthrough">
1451    <para>
1452      <xsl:apply-templates mode="passthrough"/>
1453    </para>
1454  </xsl:template>
1455  <xsl:template match="copydoc" mode="passthrough">
1456    <xsl:apply-templates mode="passthrough"/>
1457  </xsl:template>
1458  <xsl:template match="verbatim" mode="passthrough">
1459    <xsl:copy-of select="node()"/>
1460  </xsl:template>
1461
1462  <xsl:template match="para/simplesect" mode="passthrough">
1463    <xsl:if test="not (@kind='pre') and
1464                  not (@kind='return') and
1465                  not (@kind='post') and
1466                  not (@kind='attention') and
1467                  not (@kind='see') and
1468                  not (@kind='warning')
1469                  ">
1470      <xsl:apply-templates mode="passthrough"/>
1471    </xsl:if>
1472  </xsl:template>
1473
1474  <xsl:template match="para/simplesect[@kind='note' or @kind='attention']" mode="passthrough">
1475    <note>
1476      <xsl:apply-templates mode="passthrough"/>
1477    </note>
1478  </xsl:template>
1479
1480  <xsl:template match="para/simplesect[@kind='warning']" mode="passthrough">
1481    <warning>
1482      <xsl:apply-templates mode="passthrough"/>
1483    </warning>
1484  </xsl:template>
1485
1486  <xsl:template match="para/simplesect[@kind='par']" mode="passthrough">
1487    <formalpara>
1488      <xsl:apply-templates mode="passthrough"/>
1489    </formalpara>
1490  </xsl:template>
1491
1492  <xsl:template match="para/simplesect[@kind='see']" mode="passthrough">
1493    <para>
1494      <emphasis role="bold">
1495        <xsl:text>See Also:</xsl:text>
1496      </emphasis>
1497      <xsl:apply-templates mode="passthrough"/>
1498    </para>
1499  </xsl:template>
1500
1501  <xsl:template match="simplesectsep" mode="passthrough">
1502    <xsl:apply-templates mode="passthrough"/>
1503  </xsl:template>
1504
1505  <xsl:template match="*" mode="passthrough">
1506    <xsl:copy>
1507      <xsl:copy-of select="@*"/>
1508      <xsl:apply-templates mode="passthrough"/>
1509    </xsl:copy>
1510  </xsl:template>
1511
1512  <xsl:template match="parameterlist" mode="passthrough"/>
1513
1514  <xsl:template match="bold" mode="passthrough">
1515    <emphasis role="bold">
1516      <xsl:apply-templates mode="passthrough"/>
1517    </emphasis>
1518  </xsl:template>
1519
1520  <xsl:template match="linebreak" mode="passthrough">
1521    <sbr/>
1522  </xsl:template>
1523
1524  <xsl:template match="ndash" mode="passthrough">
1525    <xsl:text>&#8211;</xsl:text>
1526  </xsl:template>
1527
1528  <xsl:template match="briefdescription" mode="passthrough">
1529    <xsl:if test="text()|*">
1530      <purpose>
1531        <xsl:apply-templates mode="purpose"/>
1532      </purpose>
1533    </xsl:if>
1534  </xsl:template>
1535
1536  <xsl:template match="detaileddescription" mode="passthrough">
1537    <xsl:if test="text()|*">
1538      <description>
1539        <xsl:apply-templates mode="passthrough"/>
1540      </description>
1541    </xsl:if>
1542  </xsl:template>
1543
1544  <xsl:template match="inbodydescription" mode="passthrough">
1545    <xsl:if test="text()|*">
1546      <description>
1547        <xsl:apply-templates mode="passthrough"/>
1548      </description>
1549    </xsl:if>
1550  </xsl:template>
1551
1552  <!-- Ignore ref elements for now, as there is a lot of documentation which
1553       will have incorrect ref elements at the moment -->
1554  <xsl:template match="ref" mode="passthrough">
1555    <xsl:variable name="as-class" select="key('compounds-by-id', @refid)[@kind='class' or @kind='struct']"/>
1556    <xsl:choose>
1557      <xsl:when test="$as-class">
1558        <classname>
1559          <xsl:attribute name="alt">
1560            <xsl:value-of select="$as-class/compoundname/text()"/>
1561          </xsl:attribute>
1562          <xsl:value-of select="text()"/>
1563        </classname>
1564      </xsl:when>
1565      <xsl:otherwise>
1566        <xsl:apply-templates mode="passthrough"/>
1567      </xsl:otherwise>
1568    </xsl:choose>
1569  </xsl:template>
1570
1571  <!-- Handle function clauses -->
1572  <xsl:template match="simplesect" mode="function-clauses">
1573    <xsl:if test="@kind='pre'">
1574      <requires>
1575        <xsl:apply-templates mode="passthrough"/>
1576      </requires>
1577    </xsl:if>
1578    <xsl:if test="@kind='return'">
1579      <returns>
1580        <xsl:apply-templates mode="passthrough"/>
1581      </returns>
1582    </xsl:if>
1583    <xsl:if test="@kind='post'">
1584      <postconditions>
1585        <xsl:apply-templates mode="passthrough"/>
1586      </postconditions>
1587    </xsl:if>
1588  </xsl:template>
1589
1590  <xsl:template match="parameterlist" mode="function-clauses">
1591    <xsl:if test="@kind='exception'">
1592      <simpara>
1593        <xsl:choose>
1594          <xsl:when test="normalize-space(.//parametername//text())='nothrow'">
1595            <xsl:text>Will not throw.</xsl:text>
1596          </xsl:when>
1597          <xsl:otherwise>
1598            <classname>
1599              <xsl:value-of select=".//parametername//text()"/>
1600            </classname>
1601            <xsl:text> </xsl:text>
1602            <xsl:apply-templates
1603              select=".//parameterdescription/para/text()
1604                      |.//parameterdescription/para/*"
1605              mode="passthrough"/>
1606          </xsl:otherwise>
1607        </xsl:choose>
1608      </simpara>
1609    </xsl:if>
1610  </xsl:template>
1611
1612  <xsl:template match="type">
1613    <xsl:choose>
1614      <xsl:when test="contains(string(.), $boost.doxygen.detail)">
1615        <emphasis>unspecified</emphasis>
1616      </xsl:when>
1617      <xsl:otherwise>
1618        <xsl:apply-templates mode="type"/>
1619      </xsl:otherwise>
1620    </xsl:choose>
1621  </xsl:template>
1622
1623  <xsl:template match="ref" mode="type">
1624    <xsl:choose>
1625      <xsl:when test="@kindref='compound'">
1626        <classname>
1627          <xsl:value-of select="text()"/>
1628        </classname>
1629      </xsl:when>
1630      <xsl:otherwise>
1631        <xsl:value-of select="text()"/>
1632      </xsl:otherwise>
1633    </xsl:choose>
1634  </xsl:template>
1635
1636  <xsl:template match="*" mode="type">
1637    <xsl:value-of select="."/>
1638  </xsl:template>
1639
1640  <!-- Normalize the names of functions, because Doxygen sometimes
1641       puts in an obnoixous space. -->
1642  <xsl:template name="normalize-name">
1643    <xsl:param name="name" select="name/text()"/>
1644
1645    <xsl:choose>
1646      <xsl:when test="contains($name, ' ')">
1647        <xsl:value-of select="substring-before($name, ' ')"/>
1648        <xsl:value-of select="substring-after($name, ' ')"/>
1649      </xsl:when>
1650      <xsl:otherwise>
1651        <xsl:value-of select="$name"/>
1652      </xsl:otherwise>
1653    </xsl:choose>
1654  </xsl:template>
1655
1656  <!-- Convert HTML tables into DocBook format -->
1657  <xsl:template match="table" mode="passthrough">
1658    <informaltable>
1659      <tgroup>
1660        <xsl:attribute name="cols">
1661          <xsl:value-of select="@cols"/>
1662        </xsl:attribute>
1663
1664        <tbody>
1665          <xsl:apply-templates mode="table"/>
1666        </tbody>
1667      </tgroup>
1668    </informaltable>
1669  </xsl:template>
1670
1671  <xsl:template match="row" mode="table">
1672    <row>
1673      <xsl:apply-templates mode="table"/>
1674    </row>
1675  </xsl:template>
1676
1677  <xsl:template match="entry" mode="table">
1678    <entry>
1679      <xsl:if test="para/center">
1680        <xsl:attribute name="valign">
1681          <xsl:value-of select="'middle'"/>
1682        </xsl:attribute>
1683        <xsl:attribute name="align">
1684          <xsl:value-of select="'center'"/>
1685        </xsl:attribute>
1686      </xsl:if>
1687
1688      <xsl:choose>
1689        <xsl:when test="@thead='yes'">
1690          <emphasis role="bold">
1691            <xsl:call-template name="table-entry"/>
1692          </emphasis>
1693        </xsl:when>
1694        <xsl:otherwise>
1695          <xsl:call-template name="table-entry"/>
1696        </xsl:otherwise>
1697      </xsl:choose>
1698    </entry>
1699  </xsl:template>
1700
1701  <xsl:template name="table-entry">
1702    <xsl:choose>
1703      <xsl:when test="para/center">
1704        <xsl:apply-templates select="para/center/*|para/center/text()"
1705          mode="passthrough"/>
1706      </xsl:when>
1707      <xsl:otherwise>
1708        <xsl:apply-templates select="para/*|para/text()" mode="passthrough"/>
1709      </xsl:otherwise>
1710    </xsl:choose>
1711  </xsl:template>
1712
1713  <!-- Handle preformatted.
1714       Doxygen generates markup such as:
1715         <para><preformatted>void foo() {</preformatted></para>
1716         <para><preformatted>}</preformatted></para>
1717       This complicated mess tries to combine that into a single
1718       programlisting element.
1719    -->
1720  <xsl:template match="para[preformatted][count(preformatted)=count(*)]" mode="passthrough">
1721    <!-- Only do this for the first of a group of paras. -->
1722    <xsl:if test="not(preceding-sibling::para[1][preformatted][count(preformatted)=count(*)])">
1723      <programlisting>
1724        <!-- This node's children. -->
1725        <xsl:apply-templates mode="passthrough" select="./preformatted/node()"/>
1726
1727        <!-- Adjacent para nodes' children.
1728             Based on code at: http://stackoverflow.com/a/2092144 -->
1729        <xsl:variable name="following-siblings" select="following-sibling::*" />
1730        <xsl:for-each select="following-sibling::para[preformatted][count(preformatted)=count(*)]">
1731          <xsl:variable name="index" select="position()"/>
1732          <xsl:if test="generate-id(.)=generate-id($following-siblings[$index])">
1733            <xsl:text>&#xa;&#xa;</xsl:text>
1734            <xsl:apply-templates mode="passthrough" select="./preformatted/node()"/>
1735          </xsl:if>
1736        </xsl:for-each>
1737      </programlisting>
1738    </xsl:if>
1739  </xsl:template>
1740
1741  <!-- Remove empty preformatted elements. -->
1742  <xsl:template match="preformatted[not(node())]" mode="passthrough"/>
1743
1744  <!-- Convert remaining to programlisting. -->
1745  <xsl:template match="preformatted" mode="passthrough">
1746    <programlisting>
1747      <xsl:apply-templates mode="passthrough"/>
1748    </programlisting>
1749  </xsl:template>
1750
1751  <!-- Handle program listings -->
1752  <xsl:template match="programlisting" mode="passthrough">
1753    <programlisting language="c++">
1754      <xsl:apply-templates mode="programlisting"/>
1755    </programlisting>
1756  </xsl:template>
1757
1758  <xsl:template match="highlight|codeline" mode="programlisting">
1759    <xsl:apply-templates mode="programlisting"/>
1760  </xsl:template>
1761
1762  <xsl:template match="sp" mode="programlisting">
1763    <xsl:text> </xsl:text>
1764  </xsl:template>
1765
1766  <xsl:template match="*" mode="programlisting">
1767    <xsl:apply-templates select="." mode="passthrough"/>
1768  </xsl:template>
1769
1770  <!-- Replace top-level "para" elements with "simpara" elements in
1771       the purpose -->
1772  <xsl:template match="*" mode="purpose">
1773    <xsl:apply-templates mode="passthrough"/>
1774  </xsl:template>
1775
1776  <xsl:template match="text()" mode="purpose">
1777    <xsl:apply-templates mode="passthrough"/>
1778  </xsl:template>
1779
1780  <xsl:template match="para" mode="purpose">
1781    <xsl:apply-templates select="*|text()" mode="passthrough"/>
1782  </xsl:template>
1783
1784  <!--
1785  Eric Niebler: Jan-8-2008
1786  Here is some 3/4-baked support for LaTeX formulas in
1787  Doxygen comments. Doxygen doesn't generate the PNG files
1788  when outputting XML. In order to use this code, you must
1789  run Doxygen first to generate HTML (and the PNG files for
1790  the formulas). You can do this in a Jamfile with
1791  "doxygen foo.html : <sources, etc...> ; ", where the ".html"
1792  is significant. Then the png files should be copied into the
1793  images/ directory (or another place relative to the html/
1794  directory, as specified by $boost.doxygen.formuladir XSL
1795  parameter). This can be done with a custom action in a
1796  Jamfile. Finally, the docs can be built as normal.
1797  See libs/accumulators/doc/Jamfile.v2 for a working example.
1798  -->
1799  <xsl:template match="formula" mode="passthrough">
1800    <xsl:choose>
1801      <xsl:when test="substring(*|text(), 1, 2) = '\['">
1802        <equation>
1803          <title/>
1804          <alt>
1805            <xsl:value-of select="*|text()"/>
1806          </alt>
1807          <mediaobject>
1808            <imageobject role="html">
1809              <imagedata format="PNG" align="center">
1810                <xsl:attribute name="fileref">
1811                  <xsl:value-of select="concat(concat(concat($boost.doxygen.formuladir.fixed, 'form_'), @id), '.png')"/>
1812                </xsl:attribute>
1813              </imagedata>
1814            </imageobject>
1815            <textobject role="tex">
1816              <phrase>
1817                <xsl:value-of select="*|text()"/>
1818              </phrase>
1819            </textobject>
1820          </mediaobject>
1821        </equation>
1822      </xsl:when>
1823      <xsl:otherwise>
1824        <inlineequation>
1825          <alt>
1826            <xsl:value-of select="*|text()"/>
1827          </alt>
1828          <inlinemediaobject>
1829            <imageobject role="html">
1830              <imagedata format="PNG">
1831                <xsl:attribute name="fileref">
1832                  <xsl:value-of select="concat(concat(concat($boost.doxygen.formuladir.fixed, 'form_'), @id), '.png')"/>
1833                </xsl:attribute>
1834              </imagedata>
1835            </imageobject>
1836            <textobject role="tex">
1837              <phrase>
1838                <xsl:value-of select="*|text()"/>
1839              </phrase>
1840            </textobject>
1841          </inlinemediaobject>
1842        </inlineequation>
1843      </xsl:otherwise>
1844    </xsl:choose>
1845  </xsl:template>
1846 </xsl:stylesheet>
1847