Fix documentation build under maverick (doxygen 1.7.1)
[senf.git] / site_scons / lib / html-munge.xsl
1 <?xml version="1.0" encoding="utf-8"?>
2 <xsl:stylesheet version="1.0"
3   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4   xmlns:str="http://exslt.org/strings"
5   xmlns:set="http://exslt.org/sets"
6   xmlns:exslt="http://exslt.org/common"
7   extension-element-prefixes="str">
8
9   <xsl:output 
10     method="html" 
11     encoding="html" 
12     doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
13     doctype-system="http://www.w3.org/TR/html4/loose.dtd"/>
14
15   <xsl:param name="topdir" select="''"/>
16   
17   <xsl:template match="*" name="copy">
18     <xsl:copy>
19       <xsl:call-template name="copy-attributes"/>
20       <xsl:apply-templates/>
21     </xsl:copy>
22   </xsl:template>
23
24   <xsl:template name="copy-attributes">
25     <xsl:for-each select="@*">
26       <xsl:attribute name="{name(current())}">
27         <xsl:choose>
28           <xsl:when test="contains(current(),'@TOPDIR@')">
29             <xsl:value-of select="substring-before(current(),'@TOPDIR@')"/>
30             <xsl:value-of select="$topdir"/>
31             <xsl:value-of select="substring-after(current(),'@TOPDIR@')"/>
32           </xsl:when>
33           <xsl:otherwise>
34             <xsl:value-of select="current()"/>
35           </xsl:otherwise>
36         </xsl:choose>
37       </xsl:attribute>
38     </xsl:for-each>
39   </xsl:template>
40
41   <!-- Replace @TOPDIR@ with relative top directory path -->
42
43   <xsl:template match="@*[contains(current(),'@TOPDIR@')]">
44     <xsl:value-of select="substring-before(current(),'@TOPDIR@')"/>
45     <xsl:value-of select="$topdir"/>
46     <xsl:value-of select="substring-after(current(),'@TOPDIR@')"/>
47   </xsl:template>
48   
49   <!-- Add 'class' attribute  -->
50   
51   <xsl:template name="add-class">
52     <xsl:param name="class"/>
53     <xsl:copy>
54       <xsl:call-template name="copy-attributes"/>
55       <xsl:attribute name="class"><xsl:value-of select="$class"/></xsl:attribute>
56       <xsl:apply-templates/>
57     </xsl:copy>
58   </xsl:template>
59
60   <!-- Add '<br/>' tag after every ', ' -->
61   <!-- This code is not very robust, it works with the doxygen output though -->
62
63   <xsl:template name="break-comma">
64     <xsl:copy>
65       <xsl:call-template name="copy-attributes"/>
66       <xsl:attribute name="class">commalist</xsl:attribute>
67       <xsl:apply-templates mode="break-comma"/>
68     </xsl:copy>
69   </xsl:template>
70  
71   <xsl:template match="text()[1]" mode="break-comma">
72     <xsl:value-of select="current()"/><br/>
73   </xsl:template>
74
75   <xsl:template match="*" mode="break-comma">
76     <xsl:call-template name="copy"/>
77   </xsl:template>
78
79   <xsl:template match="text()[contains(current(),' and') or contains(current(),'and ')]" mode="break-comma" priority="1">
80     <xsl:value-of select="substring-before(current(),'and')"/>
81     <br/>
82     <xsl:value-of select="substring-after(current(),'and')"/>
83   </xsl:template>
84
85   <xsl:template match="text()[contains(current(),',')]" mode="break-comma">
86     <xsl:value-of select="substring-before(current(),',')"/>
87     <xsl:text>,</xsl:text><br/>
88     <xsl:value-of select="substring-after(current(),',')"/>
89   </xsl:template>
90
91   <!-- ====================================================================== -->
92
93   <!-- Hack Glossary menu highlight -->
94
95   <xsl:template match="div[@class='tabs menu']/ul[1]">
96     <xsl:choose>
97       <xsl:when test="//h1[.//text()='Glossary']">
98         <xsl:call-template name="add-class">
99           <xsl:with-param name="class">glossary</xsl:with-param>
100         </xsl:call-template>
101       </xsl:when>
102       <xsl:otherwise>
103         <xsl:copy>
104           <xsl:call-template name="copy-attributes"/>
105           <xsl:apply-templates/>
106         </xsl:copy>
107       </xsl:otherwise>
108     </xsl:choose>
109   </xsl:template>
110
111   <!-- Autogenerate table-of-contents for a page -->
112
113   <xsl:template match="div[@id='autotoc']">
114     <xsl:copy>
115       <xsl:call-template name="copy-attributes"/>
116       <h1>Contents</h1>
117       <ul>
118         <xsl:for-each select="following::h2|following::h3|following::h4">
119           <xsl:element name="li">
120             <xsl:attribute name="class">
121               <xsl:value-of select="concat('level_',local-name())"/>
122             </xsl:attribute>
123             <b><xsl:call-template name="section-number"/><xsl:text> </xsl:text></b>
124             <xsl:element name="a">
125               <xsl:choose>
126                 <xsl:when test="a/@name">
127                   <xsl:attribute name="href">
128                     <xsl:value-of select="concat('#',a/@name)"/>
129                   </xsl:attribute>
130                 </xsl:when>
131                 <xsl:otherwise>
132                   <xsl:attribute name="href">
133                     <xsl:text>#autotoc-</xsl:text>
134                     <xsl:call-template name="section-number"/>
135                   </xsl:attribute>
136                 </xsl:otherwise>
137               </xsl:choose>
138               <xsl:value-of select="string(current())"/>
139             </xsl:element>
140           </xsl:element>
141         </xsl:for-each>
142       </ul>
143     </xsl:copy>
144   </xsl:template>
145
146   <xsl:template name="section-number">
147     <xsl:number level="any" from="div[@id='autotoc']" count="h2"/>
148     <xsl:text>.</xsl:text>
149     <xsl:if test="self::h3|self::h4">
150       <xsl:number level="any" from="h2" count="h3"/>
151       <xsl:text>.</xsl:text>
152     </xsl:if>
153     <xsl:if test="self::h4">
154       <xsl:number level="any" from="h3" count="h4"/>
155       <xsl:text>.</xsl:text>
156     </xsl:if>
157   </xsl:template>
158   
159   <xsl:template match="h2|h3|h4">
160     <xsl:copy>
161       <xsl:call-template name="copy-attributes"/>
162       <xsl:choose>
163         <xsl:when test="preceding::div[@id='autotoc']">
164           <xsl:call-template name="section-number"/>
165           <xsl:text> </xsl:text>
166           <xsl:choose>
167             <xsl:when test="a">
168               <xsl:apply-templates/>
169             </xsl:when>
170             <xsl:otherwise>
171               <xsl:element name="a">
172                 <xsl:attribute name="class"><xsl:text>anchor</xsl:text></xsl:attribute>
173                 <xsl:attribute name="name">
174                   <xsl:text>autotoc-</xsl:text>
175                   <xsl:call-template name="section-number"/>
176                 </xsl:attribute>
177                 <xsl:apply-templates/>
178               </xsl:element>
179             </xsl:otherwise>
180           </xsl:choose>
181         </xsl:when>
182         <xsl:otherwise>
183           <xsl:apply-templates/>
184         </xsl:otherwise>
185       </xsl:choose>
186     </xsl:copy>
187   </xsl:template>
188
189   <!-- Build dia image-map from special div/span elements -->
190   <xsl:template match="div[@class='diamap']">
191     <xsl:element name="map">
192       <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
193       <xsl:for-each select="span">
194         <xsl:if test="a">
195           <xsl:variable name="name" select="string(a[1])"/>
196           <xsl:element name="area">
197             <xsl:attribute name="shape">rect</xsl:attribute>
198             <xsl:attribute name="alt"><xsl:value-of select="$name"/></xsl:attribute>
199             <xsl:attribute name="title"><xsl:value-of select="$name"/></xsl:attribute>
200             <xsl:attribute name="href"><xsl:value-of select="a[1]/@href"/></xsl:attribute>
201             <xsl:attribute name="coords"><xsl:value-of select="@coords"/></xsl:attribute>
202           </xsl:element>
203         </xsl:if>
204       </xsl:for-each>
205     </xsl:element>
206   </xsl:template>
207
208   <!-- Reformat detailed member documentation -->
209
210   <xsl:template match="table[@class='memname']">
211     <xsl:variable name="name1"><xsl:value-of select="str:split(tr/td[@class='memname'],'::')[position()=last()]"/></xsl:variable>
212     <xsl:variable name="name2"><xsl:value-of select="str:split(tr/td[@class='memname'],' ')[position()=last()]"/></xsl:variable>
213     <xsl:variable name="name"><xsl:value-of select="substring($name1,string-length($name1)-string-length($name2))"/></xsl:variable>
214     <xsl:element name="table">
215       <xsl:attribute name="class">
216         <xsl:text>memname</xsl:text>
217         <xsl:if test="contains(tr/td[@class='memname'],'#define')"><xsl:text> macro</xsl:text></xsl:if>
218       </xsl:attribute>
219       <tr>
220         <td class="memtype" colspan="5">
221           <xsl:for-each select="tr/td[@class='memname']/*|tr/td[@class='memname']/text()">
222             <xsl:choose>
223               <xsl:when test="position()=last()">
224                 <xsl:value-of select="substring(.,1,string-length(.)-string-length($name))"/>
225               </xsl:when>
226               <xsl:otherwise>
227                 <xsl:copy-of select="."/>
228               </xsl:otherwise>
229             </xsl:choose>
230           </xsl:for-each>
231         </td>
232       </tr>
233
234       <xsl:choose>
235         <xsl:when test="tr/td[@class='paramtype']">
236           <tr>
237             <td class="memname"><xsl:copy-of select="$name"/></td>
238             <td class="memparen">(</td>
239             <xsl:copy-of select="tr[1]/td[@class='paramtype']"/>
240             <xsl:copy-of select="tr[1]/td[@class='paramname']"/>
241             <td class="memparen"><xsl:if test="not(tr[td[@class='paramkey']])">)</xsl:if></td>
242           </tr>
243
244           <xsl:for-each select="tr[td[@class='paramkey']]">
245             <tr>
246               <td class="memname"></td>
247               <td class="memparen"></td>
248               <xsl:copy-of select="td[@class='paramtype']"/>
249               <xsl:copy-of select="td[@class='paramname']"/>
250               <td class="memparen"><xsl:if test="position()=last()">)</xsl:if></td>
251             </tr>
252           </xsl:for-each>
253         </xsl:when>
254         <xsl:otherwise>
255           <tr>
256             <td class="memname"><xsl:copy-of select="$name"/></td>
257             <td class="memparen"><xsl:if test="tr/td[.='(']">()</xsl:if></td>
258             <td class="paramtype"></td>
259             <td class="paramname"></td>
260             <td class="memparen"></td>
261           </tr>
262         </xsl:otherwise>
263       </xsl:choose>
264       <tr>
265         <td colspan="5" class="memattrs"><xsl:copy-of select="tr/td[@width='100%']/*|tr/td[@width='100%']/text()"/></td>
266       </tr>
267     </xsl:element>
268   </xsl:template>
269
270   <!-- no idea, where these &nbsp;'s come frome ... -->
271   <xsl:template match="div[@class='memproto']/text()[.='&#160;&#x0a;']">
272   </xsl:template>
273
274   <!-- Add grouping to all-members page -->
275
276   <xsl:template match="table[preceding::h1[1][contains(text(),'Member List')]]">
277     <table class="allmembers">
278
279       <!-- We need to filter the table rows by looking for indications on the object type       -->
280       <!-- The table has 3 acolumns:                                                            -->
281       <!--    td[1] is the name of the object,                                                  -->
282       <!--    td[2] is the name of the class the object is defined in                           -->
283       <!--    td[3] contains additional flags                                                   -->
284       <!--                                                                                      -->
285       <!-- The conditions we have are:                                                          -->
286       <!--                                                                                      -->
287       <!--    contains(td[3],'static')        static member (variable or function)              -->
288       <!--    contains(td[3],'protected')     protected member of arbitrary type                -->
289       <!--    contains(td[3],'private')       private member of arbitrary type                  -->
290       <!--    contains(td{3],'friend')        friend declaration (function or class)            -->
291       <!--    contains(td[3],'pure virtual')  entry is a pure-virtual member function           -->
292       <!--    starts-with(td[1]/text(),'(')   function entry (member, static or friend)         -->
293       <!--    contains(td[1], 'typedef')      entry is a typdef                                 -->
294       <!--    contains(td[1], 'enum ')        entry is enum type or enumerator                  -->
295       <!--    contains(td[1], 'enum name')    entry is the name of an enum type                 -->
296       <!--    contains(td[1], 'enum value')   entry is an enumerator value                      -->
297       <!--    str:split(substring-before(concat(td[2]/a,'&lt;'),'&lt;'),'::')[position()=last()]==string(td[1]/a) -->
298       <!--                                    entry is a constructor                            -->
299       <!--    not(starts-with(td[1]/a,'~'))   entry is a destructor                             -->
300
301       <xsl:variable name="public-static-memfn">
302         <xsl:apply-templates select="tr[contains(td[3],'static')][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(contains(td[3],'friend'))][starts-with(td[1]/text(),'(')]"/>
303       </xsl:variable>
304       <xsl:if test="string($public-static-memfn)">
305         <tr><td colspan="3"><h2>Static Public Member Functions</h2></td></tr>
306         <xsl:copy-of select="$public-static-memfn"/>
307       </xsl:if>
308
309       <xsl:variable name="public-static-var">
310         <xsl:apply-templates select="tr[not(contains(td[1],'typedef'))][contains(td[3],'static')][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(starts-with(td[1]/text(),'('))]"/>
311       </xsl:variable>
312       <xsl:if test="string($public-static-var)">
313         <tr><td colspan="3"><h2>Static Public Attributes</h2></td></tr>
314         <xsl:copy-of select="$public-static-var"/>
315       </xsl:if>
316       
317       <xsl:variable name="public-memfn">
318         <xsl:apply-templates select="tr[not(contains(td[1],'typedef'))][not(contains(td[3],'static'))][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(contains(td[3],'friend'))][starts-with(td[1]/text(),'(')][str:split(substring-before(concat(td[2]/a,'&lt;'),'&lt;'),'::')[position()=last()]!=string(td[1]/a)][not(starts-with(td[1]/a,'~'))][not(contains(td[3],'pure virtual'))]"/>
319       </xsl:variable>
320       <xsl:if test="string($public-memfn)">
321         <tr><td colspan="3"><h2>Public Member Functions</h2></td></tr>
322         <xsl:copy-of select="set:distinct(exslt:node-set($public-memfn)/tr)"/>
323       </xsl:if>
324
325       <xsl:variable name="public-var">
326         <xsl:apply-templates select="tr[not(contains(td[1],'typedef'))][not(contains(td[1],'enum '))][not(contains(td[3],'static'))][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(starts-with(td[1]/text(),'('))]"/>
327       </xsl:variable>
328       <xsl:if test="string($public-var)">
329         <tr><td colspan="3"><h2>Public Attributes</h2></td></tr>
330         <xsl:copy-of select="$public-var"/>
331       </xsl:if>
332       
333       <xsl:variable name="public-enum">
334         <xsl:apply-templates select="tr[contains(td[1],'enum value')][not(contains(td[3],'protected'))][not(contains(td[3],'private'))]"/>
335       </xsl:variable>
336       <xsl:if test="string($public-enum)">
337         <tr><td colspan="3"><h2>Public Enumerators</h2></td></tr>
338         <xsl:copy-of select="$public-enum"/>
339       </xsl:if>
340       
341       <xsl:variable name="public-type">
342         <xsl:apply-templates select="tr[contains(td[1],'typedef') or contains(td[1],'enum name')][not(contains(td[3],'protected'))][not(contains(td[3],'private'))][not(contains(td[3],'friend'))]"/>
343       </xsl:variable>
344       <xsl:if test="string($public-type)">
345         <tr><td colspan="r"><h2>Public Types</h2></td></tr>
346         <xsl:copy-of select="$public-type"/>
347       </xsl:if>
348       
349       <xsl:variable name="non-public">
350         <xsl:apply-templates select="tr[contains(td[3],'protected') or contains(td[3],'private') or contains(td[3],'friend')][str:split(substring-before(concat(td[2]/a,'&lt;'),'&lt;'),'::')[position()=last()]!=string(td[1]/a)][not(starts-with(td[1]/a,'~'))][not(contains(td[3],'pure virtual'))]"/>
351       </xsl:variable>
352       <xsl:if test="string($non-public)">
353         <tr><td colspan="3"><h2>Non-Public Members</h2></td></tr>
354         <xsl:copy-of select="$non-public"/>
355       </xsl:if>
356
357     </table>
358   </xsl:template>
359
360   <xsl:template match="table[preceding-sibling::h1[1][contains(text(),'Member List')]]/tr/td[2]/a/text()[contains(.,'&lt;')]">
361     <!-- this removes the template args form the second column to make the table more compact -->
362     <xsl:value-of select="substring-before(.,'&lt;')"/>
363   </xsl:template>
364
365   <xsl:template match="table[preceding-sibling::h1[1][contains(text(),'Member List')]]/tr/td[1]/a/text()[contains(.,'::')]">
366     <!-- for some weird reason, some members have a fully qualified name in the first column -->
367     <!-- remove the qualification here -->
368     <xsl:value-of select="str:split(.,'::')[position()=last()]"/>
369   </xsl:template>
370
371   <!-- Remove the automatically inserted search form (we build our own) -->
372   <xsl:template match="li[form]"> 
373   </xsl:template>
374   
375   <xsl:template match="li[@id='searchli']">
376   </xsl:template>
377
378   <xsl:template match="div[@id='MSearchSelectWindow']">
379   </xsl:template>
380
381   <xsl:template match="div[@id='MSearchResultsWindow']">
382   </xsl:template>
383
384   <xsl:template match="script">
385   </xsl:template>
386
387   <!-- Add CSS class to alphabetical class index table -->
388   <xsl:template match="table[preceding-sibling::*[1][self::div][@class='qindex']]">
389     <xsl:call-template name="add-class">
390       <xsl:with-param name="class">qindextable</xsl:with-param>
391     </xsl:call-template>
392   </xsl:template>
393
394   <!-- Add CSS class to special paragraphs -->
395
396   <xsl:template match="dl[dt/b/a/text()='Bug:']">
397     <xsl:call-template name="add-class">
398       <xsl:with-param name="class">xref-bug</xsl:with-param>
399     </xsl:call-template>
400   </xsl:template>
401
402   <xsl:template match="dl[dt/b/a/text()='Fix:']">
403     <xsl:call-template name="add-class">
404       <xsl:with-param name="class">xref-fix</xsl:with-param>
405     </xsl:call-template>
406   </xsl:template>
407
408   <xsl:template match="dl[dt/b/a/text()='Todo:']">
409     <xsl:call-template name="add-class">
410       <xsl:with-param name="class">xref-todo</xsl:with-param>
411     </xsl:call-template>
412   </xsl:template>
413
414   <xsl:template match="dl[dt/b/a/text()='Idea:']">
415     <xsl:call-template name="add-class">
416       <xsl:with-param name="class">xref-idea</xsl:with-param>
417     </xsl:call-template>
418   </xsl:template>
419
420   <xsl:template match="dl[dt/b/text()='Parameters:']|dl[dt/b/text()='Template Parameters:']">
421     <xsl:call-template name="add-class">
422       <xsl:with-param name="class">parameters</xsl:with-param>
423     </xsl:call-template>
424   </xsl:template>
425
426   <xsl:template match="dl[dt/b/text()='Implementation note:']">
427     <xsl:call-template name="add-class">
428       <xsl:with-param name="class">implementation</xsl:with-param>
429     </xsl:call-template>
430   </xsl:template>
431
432   <xsl:template match="p[starts-with(text(),'Definition at line ')]">
433     <xsl:call-template name="add-class">
434       <xsl:with-param name="class">sourceline</xsl:with-param>
435     </xsl:call-template>
436   </xsl:template>
437
438   <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'References ')]">
439     <xsl:call-template name="add-class">
440       <xsl:with-param name="class">references</xsl:with-param>
441     </xsl:call-template>
442   </xsl:template>
443
444   <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Referenced by ')]">
445     <xsl:call-template name="add-class">
446       <xsl:with-param name="class">referencedby</xsl:with-param>
447     </xsl:call-template>
448   </xsl:template>
449
450   <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Reimplemented from ')]">
451     <xsl:call-template name="add-class">
452       <xsl:with-param name="class">reimplementedfrom</xsl:with-param>
453     </xsl:call-template>
454   </xsl:template>
455
456   <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Reimplemented in ')]">
457     <xsl:call-template name="add-class">
458       <xsl:with-param name="class">reimplementedin</xsl:with-param>
459     </xsl:call-template>
460   </xsl:template>
461
462   <xsl:template match="div[@class='memdoc']/p[starts-with(text(),'Implemented in ')]">
463     <xsl:call-template name="add-class">
464       <xsl:with-param name="class">implementedin</xsl:with-param>
465     </xsl:call-template>
466   </xsl:template>
467
468   <!-- Break the following lists after each komma -->
469
470   <xsl:template match="p[starts-with(text(),'Inherited by ')]">
471     <xsl:call-template name="break-comma"/>
472   </xsl:template>
473
474   <xsl:template match="p[starts-with(text(),'Inherits ')]">
475     <xsl:call-template name="break-comma"/>
476   </xsl:template>
477
478   <!-- Add CSS class to the member overview table of a class documentation -->
479   <xsl:template match="table[descendant::td[@class='memItemLeft']]">
480     <xsl:call-template name="add-class">
481       <xsl:with-param name="class">members</xsl:with-param>
482     </xsl:call-template>
483   </xsl:template>
484
485   <!-- Add CSS class to literal links (links, where link text and href attribute are the same -->
486   <xsl:template match="a[@href=string(current())]" priority="1">
487     <xsl:call-template name="add-class">
488       <xsl:with-param name="class">literal</xsl:with-param>
489     </xsl:call-template>
490   </xsl:template>
491
492   <!-- Add CSS class to external links -->
493   <xsl:template match="a[contains(@href,'http://')]">
494     <xsl:call-template name="add-class">
495       <xsl:with-param name="class">ext</xsl:with-param>
496     </xsl:call-template>
497   </xsl:template>
498
499   <!-- Add CSS class to anchor-only links -->
500   <xsl:template match="a[not(@href)]">
501     <xsl:call-template name="add-class">
502       <xsl:with-param name="class">anchor</xsl:with-param>
503     </xsl:call-template>
504   </xsl:template>
505
506   <!-- Add CSS class to the brief documentation paragraph of the member documentation -->
507   <xsl:template match="div[@class='memdoc']/p[1][not(contains(.,'Definition at line'))][not(contains(.,'Reimplemented in'))][not(contains(.,'References '))][not(contains(.,'Referenced by '))][not(contains(.,'Reimplemented from '))]">
508     <xsl:call-template name="add-class">
509       <xsl:with-param name="class">memtitle</xsl:with-param>
510     </xsl:call-template>
511   </xsl:template>
512
513   <!-- Remove external items from the namespace index -->
514   <xsl:template match="div[@id='content2']/table[contains(preceding-sibling::h1/text(),'Namespace Reference')]/tr[td[@class='memItemRight']/a[1][@class='elRef'][@doxygen]]">
515   </xsl:template>
516   
517   <!-- Remove [external] references from the modules page -->
518   <xsl:template match="div[@id='content2']/ul/li[a/@class='elRef'][a/@doxygen][code/text()='[external]'][not(ul)]">
519   </xsl:template>
520
521 </xsl:stylesheet>