]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/docca/include/docca/base-extract-xml-pages.xsl
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / tools / docca / include / docca / base-extract-xml-pages.xsl
CommitLineData
f67539c2
TL
1<xsl:stylesheet version="3.0"
2 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3 xmlns:xs="http://www.w3.org/2001/XMLSchema"
4 xmlns:d="http://github.com/vinniefalco/docca"
5 exclude-result-prefixes="xs d"
6 expand-text="yes">
7
8 <!-- TODO: make sure this doesn't screw up any formatting -->
9 <!-- NEW TODO: verify we don't need/want this -->
10 <!--
11 <xsl:output indent="yes"/>
12 -->
13
14 <xsl:include href="common.xsl"/>
15
16 <xsl:key name="visible-memberdefs-by-id"
17 match="memberdef[$include-private-members or not(@prot eq 'private')]"
18 use="@id"/>
19
20 <xsl:key name="elements-by-refid" match="compound | member" use="@refid"/>
21
22 <xsl:variable name="index-xml" select="/"/>
23
24 <xsl:template match="/">
25 <index>
26 <xsl:apply-templates select="/doxygenindex/compound"/>
27 </index>
28 <!-- Testing the ID-related functions
29 <xsl:value-of select="replace(d:extract-ns('put'), '::$', '')"/>
30 <xsl:text>&#xA;</xsl:text>
31 <xsl:value-of select="replace(d:extract-ns('foobar::parser::put'), '::$', '')"/>
32 <xsl:text>&#xA;</xsl:text>
33 <xsl:value-of select="d:extract-ns('foobar::parser::put&lt;foo::bar, bat::bang>')"/>
34 <xsl:text>&#xA;</xsl:text>
35 <xsl:value-of select="d:strip-ns('boost::beast::http::parser::basic_parser&lt; foo::isRequest, bar::parser &gt;')"/>
36 <xsl:text>&#xA;</xsl:text>
37 <xsl:value-of select="d:strip-doc-ns('boost::beast::http::parser::basic_parser&lt; foo::isRequest, bar::parser &gt;')"/>
38 <xsl:text>&#xA;</xsl:text>
39 <xsl:text>&#xA;</xsl:text>
40 <xsl:value-of select="d:make-id('boost::beast::http::parser::basic_parser&lt; foo::isRequest, bar::parser &gt;')"/>
41 -->
42 </xsl:template>
43
44 <!-- Default implementation; can be customized/overridden -->
45 <xsl:function name="d:should-ignore-compound">
46 <xsl:param name="compound" as="element(compound)"/>
47 <xsl:sequence select="false()"/>
48 </xsl:function>
49
50 <xsl:template match="compound[d:should-ignore-compound(.)]"/>
51 <xsl:template match="compound">
52 <!-- Load each input file only once -->
53 <xsl:variable name="source-doc" select="d:get-source-doc(.)"/>
54 <!-- Ignore private classes unless private members are enabled -->
55 <xsl:if test="$include-private-members or not($source-doc/doxygen/compounddef/@prot eq 'private')">
56 <!-- Look up memberdefs (and constrain by visibility) only once -->
57 <xsl:variable name="memberdefs" select="key('visible-memberdefs-by-id', member/@refid, $source-doc)"/>
58 <!-- Create a filtered copy of members within their minimal context, listing only the visible ones -->
59 <xsl:variable name="visible-members" as="element(member)*">
60 <xsl:variable name="compound" as="element()">
61 <compound kind="{@kind}" refid="{@refid}">
62 <name>{name}</name>
63 <xsl:copy-of select="member[@refid = $memberdefs/@id]"/>
64 </compound>
65 </xsl:variable>
66 <xsl:sequence select="$compound/member"/>
67 </xsl:variable>
68 <xsl:apply-templates mode="create-page" select=".">
69 <xsl:with-param name="source-doc" select="$source-doc" tunnel="yes"/>
70 <xsl:with-param name="memberdefs" select="$memberdefs" tunnel="yes"/>
71 <xsl:with-param name="visible-members" select="$visible-members" tunnel="yes"/>
72 </xsl:apply-templates>
73 </xsl:if>
74 </xsl:template>
75
76 <xsl:function name="d:get-source-doc" as="document-node()">
77 <xsl:param name="compound" as="element(compound)"/>
78 <xsl:sequence select="document($compound/@refid||'.xml', $index-xml)"/>
79 </xsl:function>
80
81 <!-- Split up the content into class, struct, and member pages -->
82 <xsl:template mode="create-page" match="*"/>
83 <xsl:template mode="create-page" match="compound[@kind = 'namespace']">
84 <xsl:apply-templates mode="child-pages" select="."/>
85 </xsl:template>
86 <xsl:template mode="create-page" match="compound[@kind = ('class','struct')]
87 | compound/member">
88 <xsl:variable name="page-id" as="xs:string">
89 <xsl:apply-templates mode="page-id" select="."/>
90 </xsl:variable>
91 <page id="{$page-id}" href="{$page-id}.xml">
92 <xsl:result-document href="xml-pages/{$page-id}.xml">
93 <xsl:apply-templates mode="page-content" select=".">
94 <xsl:with-param name="page-id" select="$page-id" tunnel="yes"/>
95 </xsl:apply-templates>
96 </xsl:result-document>
97 <xsl:apply-templates mode="child-pages" select="."/>
98 </page>
99 </xsl:template>
100
101 <!-- Create the member page for each child (or, if overloaded, the overload-list page) -->
102 <xsl:template mode="child-pages" match="compound">
103 <xsl:param name="visible-members" tunnel="yes"/>
104 <!-- Create a page for each unique member name -->
105 <xsl:for-each select="$visible-members[not(name = preceding-sibling::member/name)]">
106 <xsl:apply-templates mode="create-page" select=".">
107 <xsl:with-param name="is-overload-list-page" select="d:is-overloaded(.)" tunnel="yes"/>
108 </xsl:apply-templates>
109 </xsl:for-each>
110 </xsl:template>
111
112 <!-- A member page doesn't have children, unless it is an overload-list page -->
113 <xsl:template mode="child-pages" match="compound/member">
114 <xsl:param name="is-overload-list-page" tunnel="yes"/>
115 <xsl:if test="$is-overload-list-page">
116 <xsl:apply-templates mode="create-page" select="d:overloaded-members(.)">
117 <xsl:with-param name="is-overload-list-page" select="false()" tunnel="yes"/>
118 </xsl:apply-templates>
119 </xsl:if>
120 </xsl:template>
121
122
123 <xsl:template mode="page-id" match="compound">{d:make-id(name)}</xsl:template>
124 <xsl:template mode="page-id" match="member">
125 <xsl:param name="is-overload-list-page" tunnel="yes"/>
126 <xsl:value-of>
127 <xsl:apply-templates mode="base-member-page-id" select="."/>
128 <!-- Append the overload-specific suffix, if applicable -->
129 <xsl:if test="d:is-overloaded(.) and not($is-overload-list-page)">
130 <xsl:value-of select="d:make-id('.overload'||d:overload-position(.))"/>
131 </xsl:if>
132 </xsl:value-of>
133 </xsl:template>
134
135 <xsl:function name="d:is-overloaded" as="xs:boolean">
136 <xsl:param name="member" as="element(member)"/>
137 <xsl:sequence select="exists(d:overloaded-members($member)[2])"/>
138 </xsl:function>
139
140 <xsl:function name="d:overload-position" as="xs:integer">
141 <xsl:param name="member" as="element(member)"/>
142 <xsl:sequence select="1 + count($member/preceding-sibling::member[name eq $member/name])"/>
143 </xsl:function>
144
145 <xsl:function name="d:overloaded-members" as="element(member)+">
146 <xsl:param name="member" as="element(member)"/>
147 <xsl:sequence select="$member/../member[name eq $member/name]"/>
148 </xsl:function>
149
150
151 <xsl:template mode="base-member-page-id" priority="1"
152 match="compound[@kind eq 'namespace']
153 /member">{d:make-id(../name||'::'||name)}</xsl:template>
154 <xsl:template mode="base-member-page-id" match="compound/member">{d:make-id(../name||'.' ||name)}</xsl:template>
155
156
157 <!-- The content for a class or struct is the original source document, pared down some -->
158 <xsl:template mode="page-content" match="compound">
159 <xsl:param name="source-doc" tunnel="yes"/>
160 <xsl:apply-templates mode="compound-page" select="$source-doc"/>
161 </xsl:template>
162
163 <!-- By default, copy everything -->
164 <xsl:template mode="compound-page" match="@* | node()" name="copy-in-compound-page">
165 <xsl:copy>
166 <xsl:apply-templates mode="#current" select="@*"/>
167 <xsl:apply-templates mode="compound-page-insert" select="."/>
168 <xsl:apply-templates mode="#current"/>
169 </xsl:copy>
170 </xsl:template>
171
172 <!-- By default, don't insert anything -->
173 <xsl:template mode="compound-page-insert" match="*"/>
174
175 <xsl:template mode="compound-page" match="listofallmembers"/>
176
177 <xsl:template mode="compound-page" match="memberdef/@*"/>
178
179 <!-- But directly inside <memberdef>, don't copy anything... -->
180 <xsl:template mode="compound-page" match="memberdef/node()"/>
181
182 <!-- ...except for <name>, <briefdescription>, and <type> -->
183 <xsl:template mode="compound-page" match="memberdef/name
184 | memberdef/briefdescription
185 | memberdef/type" priority="1">
186 <xsl:call-template name="copy-in-compound-page"/>
187 </xsl:template>
188
189 <!-- Insert a reference to each child member's page ID -->
190 <xsl:template mode="compound-page-insert" match="memberdef">
191 <xsl:attribute name="d:page-refid" select="d:make-id(/doxygen/compounddef/compoundname||'.'||name)"/>
192 </xsl:template>
193
194 <!-- Alternative implementation in case we need to start controlling whitespace more
195 <xsl:template mode="compound-page" match="memberdef">
196 <memberdef>
197 <xsl:text>&#xA;</xsl:text>
198 <xsl:copy-of select="name"/>
199 <xsl:text>&#xA;</xsl:text>
200 <xsl:copy-of select="briefdescription"/>
201 </memberdef>
202 </xsl:template>
203 -->
204
205 <!-- The content for a member page is a subset of the source document -->
206 <xsl:template mode="page-content" match="compound/member">
207 <xsl:param name="is-overload-list-page" tunnel="yes"/>
208 <xsl:choose>
209 <xsl:when test="$is-overload-list-page">
210 <!-- For the overload list page, include the content for every like-named member -->
211 <xsl:apply-templates mode="list-page" select=".">
212 <xsl:with-param name="applicable-members" select="d:overloaded-members(.)" tunnel="yes"/>
213 </xsl:apply-templates>
214 </xsl:when>
215 <xsl:otherwise>
216 <!-- Otherwise, this page is just for one implementation (whether overloaded or not) -->
217 <xsl:apply-templates mode="member-page" select="."/>
218 </xsl:otherwise>
219 </xsl:choose>
220 </xsl:template>
221
222 <xsl:template mode="list-page member-page" match="member" priority="2">
223 <xsl:param name="applicable-members" as="element(member)+" select="." tunnel="yes"/>
224 <xsl:param name="source-doc" tunnel="yes"/>
225 <xsl:param name="memberdefs" tunnel="yes"/>
226 <xsl:apply-templates mode="#current" select="$source-doc">
227 <xsl:with-param name="target-memberdefs"
228 select="$memberdefs[@id = $applicable-members/@refid]"
229 tunnel="yes"/>
230 <xsl:with-param name="member" select="." tunnel="yes"/>
231 </xsl:apply-templates>
232 </xsl:template>
233
234 <!-- Always copy the name of the parent compound -->
235 <xsl:template mode="list-page member-page" match="compoundname" priority="2">
236 <xsl:copy-of select="."/>
237 </xsl:template>
238
239 <!-- Otherwise, only copy an element if it's the target member or one of its ancestors -->
240 <xsl:template mode="list-page member-page" match="*" priority="1">
241 <xsl:param name="target-memberdefs" tunnel="yes"/>
242 <xsl:if test=". intersect $target-memberdefs/ancestor-or-self::*">
243 <xsl:next-match/>
244 </xsl:if>
245 </xsl:template>
246
247 <!-- By default, copy everything -->
248 <xsl:template mode="list-page" match="@* | node()">
249 <xsl:copy>
250 <xsl:apply-templates mode="#current" select="@*"/>
251 <xsl:apply-templates mode="list-page-insert" select="."/>
252 <xsl:apply-templates mode="#current"/>
253 </xsl:copy>
254 </xsl:template>
255
256 <!-- By default, don't insert anything -->
257 <xsl:template mode="list-page-insert" match="*"/>
258
259
260 <!-- By default, copy everything -->
261 <xsl:template mode="member-page
262 copy-member-content" match="@* | node()">
263 <xsl:copy>
264 <xsl:apply-templates mode="#current" select="@*"/>
265 <xsl:apply-templates mode="member-page-insert" select="."/>
266 <xsl:apply-templates mode="#current"/>
267 <xsl:apply-templates mode="member-page-append" select="."/>
268 </xsl:copy>
269 </xsl:template>
270
271 <!-- By default, don't insert or append anything -->
272 <xsl:template mode="member-page-insert
273 member-page-append" match="*"/>
274
275 <!-- Strip out extraneous whitespace -->
276 <xsl:template mode="list-page member-page" match="compounddef/text() | sectiondef/text()"/>
277
278 <!-- Switch to an unfiltered copy once we're done filtering out the undesired elements -->
279 <xsl:template mode="list-page member-page" match="memberdef/node()" priority="2">
280 <xsl:apply-templates mode="copy-member-content" select="."/>
281 </xsl:template>
282
283 <!-- Add the page ID to the top of all page types -->
284 <xsl:template mode="compound-page-insert
285 member-page-insert
286 list-page-insert" match="/doxygen" priority="2">
287 <xsl:param name="page-id" tunnel="yes"/>
288 <xsl:attribute name="d:page-id" select="$page-id"/>
289 <xsl:next-match/>
290 </xsl:template>
291
292 <!-- Also, if applicable, insert the overload position and/or base compound reference of this member -->
293 <xsl:template mode="member-page-insert" match="/doxygen" priority="1">
294 <xsl:param name="member" tunnel="yes"/>
295 <xsl:if test="d:is-overloaded($member)">
296 <xsl:attribute name="d:overload-position" select="d:overload-position($member)"/>
297 <xsl:attribute name="d:overload-size" select="count(d:overloaded-members($member))"/>
298 </xsl:if>
299 <xsl:if test="$member[not(starts-with(@refid, ../@refid))]">
300 <xsl:variable name="base-compound" select="$index-xml/*/compound[starts-with($member/@refid, @refid)]
301 [not(d:should-ignore-compound(.))]"/>
302 <xsl:apply-templates mode="base-compound-atts" select="$base-compound"/>
303 </xsl:if>
304 <xsl:next-match/>
305 </xsl:template>
306
307 <xsl:template mode="base-compound-atts" match="compound">
308 <xsl:attribute name="d:base-compound-name" select="d:strip-doc-ns(name)"/>
309 <xsl:attribute name="d:base-compound-refid">
310 <xsl:apply-templates mode="page-id" select="."/>
311 </xsl:attribute>
312 </xsl:template>
313
314 <!-- Make data available for the typedef tables, if applicable -->
315 <xsl:template mode="member-page-append" match="memberdef[@kind eq 'typedef']
316 [type/ref]
317 [not(contains(type, '*'))]">
318 <xsl:for-each select="type/ref">
319 <d:referenced-typedef-class>
320 <xsl:variable name="compound" select="d:get-target-element(.)[self::compound]"/>
321 <xsl:apply-templates mode="compound-page" select="$compound ! d:get-source-doc(.)/*/compounddef"/>
322 </d:referenced-typedef-class>
323 </xsl:for-each>
324 </xsl:template>
325
326 <!-- Finally, add the page type -->
327 <xsl:template mode="compound-page-insert" match="/doxygen">
328 <xsl:attribute name="d:page-type" select="'compound'"/>
329 </xsl:template>
330 <xsl:template mode="member-page-insert" match="/doxygen">
331 <xsl:attribute name="d:page-type" select="'member'"/>
332 </xsl:template>
333 <xsl:template mode="list-page-insert" match="/doxygen">
334 <xsl:attribute name="d:page-type" select="'overload-list'"/>
335 </xsl:template>
336
337 <!-- For overload-list pages, include the page id for each member -->
338 <xsl:template mode="list-page-insert" match="memberdef">
339 <xsl:param name="applicable-members" tunnel="yes"/>
340 <xsl:variable name="this-id" select="@id"/>
341 <xsl:variable name="original-member" select="$applicable-members[@refid eq $this-id]"/>
342 <xsl:attribute name="d:page-refid">
343 <xsl:apply-templates mode="page-id" select="$original-member">
344 <xsl:with-param name="is-overload-list-page" select="false()" tunnel="yes"/>
345 </xsl:apply-templates>
346 </xsl:attribute>
347 </xsl:template>
348
349 <!-- For public innerclasses, insert the referenced class inline -->
350 <xsl:template mode="compound-page-insert" match="innerclass[@prot eq 'public']">
351 <xsl:attribute name="d:page-refid" select="d:make-id(.)"/>
352 <d:referenced-inner-class>
353 <xsl:variable name="compound" select="d:get-target-element(.)" as="element(compound)"/>
354 <xsl:apply-templates mode="compound-page" select="d:get-source-doc($compound)/*/compounddef"/>
355 </d:referenced-inner-class>
356 </xsl:template>
357
f67539c2 358 <!-- Resolve the referenced page IDs for later link generation -->
20effc67 359 <xsl:template mode="compound-page-insert member-page-insert" match="ref">
f67539c2 360 <xsl:attribute name="d:refid">
20effc67
TL
361 <xsl:apply-templates mode="page-id" select="d:get-target-element(.)">
362 <!-- For inline links to member pages, only link to the base page id (no overloads) -->
363 <xsl:with-param name="is-overload-list-page" select="true()" tunnel="yes"/>
364 </xsl:apply-templates>
f67539c2
TL
365 </xsl:attribute>
366 </xsl:template>
367
368 <xsl:function name="d:get-target-element" as="element()?"> <!-- to allow for partial builds -->
369 <!--
370 <xsl:function name="d:get-target-element" as="element()">
371 -->
372 <xsl:param name="ref" as="element()"/> <!-- <ref> or <innerclass> or... -->
373 <xsl:variable name="referenced-elements" select="key('elements-by-refid', $ref/@refid, $index-xml)"/>
374 <xsl:variable name="result" as="element()?">
375 <xsl:choose>
376 <!-- Handle the case where the referenced element appears two or more times in index.xml -->
377 <!-- If there's no ambiguity, we're done! -->
378 <xsl:when test="count($referenced-elements) eq 1">
379 <xsl:apply-templates mode="find-target-element" select="$referenced-elements"/>
380 </xsl:when>
381 <xsl:otherwise>
382 <!-- Otherwise, see if a namespace in the link text successfully disambiguates -->
383 <xsl:variable name="qualified-reference" as="element()*">
384 <xsl:variable name="parent-in-link-text"
385 select="if (contains($ref,'::'))
386 then d:extract-ns-without-suffix($ref)
387 else ''"/>
388 <xsl:sequence select="$referenced-elements[ends-with(parent::compound/name, '::'||$parent-in-link-text)]"/>
389 </xsl:variable>
390 <xsl:choose>
391 <xsl:when test="count($qualified-reference) eq 1">
392 <xsl:apply-templates mode="find-target-element" select="$qualified-reference"/>
393 </xsl:when>
394 <xsl:otherwise>
395 <!-- Otherwise, favor the member that's in the same class or namespace as the current page -->
396 <xsl:variable name="sibling-reference" as="element()*">
397 <xsl:variable name="compound-for-current-page" select="root($ref)/doxygen/compounddef/compoundname/string()"/>
398 <xsl:sequence select="$referenced-elements[parent::compound/name eq $compound-for-current-page]"/>
399 </xsl:variable>
400 <xsl:choose>
401 <xsl:when test="count($sibling-reference) eq 1">
402 <xsl:apply-templates mode="find-target-element" select="$sibling-reference"/>
403 </xsl:when>
404 <!-- If all else fails, give up and just use the first one -->
405 <xsl:otherwise>
406 <xsl:apply-templates mode="find-target-element" select="$referenced-elements[1]"/>
407 </xsl:otherwise>
408 </xsl:choose>
409 </xsl:otherwise>
410 </xsl:choose>
411 </xsl:otherwise>
412 </xsl:choose>
413 </xsl:variable>
414 <xsl:if test="not($result)">
415 <xsl:message>Unable to find referenced ID: <xsl:value-of select="$ref/@refid"/></xsl:message>
416 </xsl:if>
417 <xsl:sequence select="$result"/>
418 </xsl:function>
419
420 <xsl:template mode="find-target-element" match="compound | member">
421 <xsl:sequence select="."/>
422 </xsl:template>
423
424 <!-- In the index XML, enumvalue "members" immediately follow the corresponding enum member -->
425 <xsl:template mode="find-target-element" match="member[@kind eq 'enumvalue']">
426 <xsl:sequence select="preceding-sibling::member[@kind eq 'enum'][1]"/>
427 </xsl:template>
428
429</xsl:stylesheet>