1<?xml version="1.0" encoding="utf-8"?>
2<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3                xmlns:xs="http://www.w3.org/2001/XMLSchema"
4                xmlns:acrn="https://projectacrn.org"
5                xmlns:func="http://exslt.org/functions"
6                extension-element-prefixes="func"
7                version="1.0">
8  <xsl:output method="text"/>
9  <xsl:variable name="newline" select="'&#10;'"/>
10  <xsl:variable name="section_adornment" select="'#*=-%+@`'"/>
11  <xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/>
12  <xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
13  <!-- Default is to not show hidden options (acrn:views='') overridded by passing - -paramstring showHidden 'y' to xsltproc -->
14  <xsl:param name="showHidden" select="n" />
15  <!-- xslt script to autogenerate config option documentation -->
16  <!-- Get things started with the ACRNConfigType element -->
17  <xsl:template match="/xs:schema">
18    <xsl:apply-templates select="xs:complexType[@name='ACRNConfigType']">
19      <xsl:with-param name="level" select="2"/>
20      <xsl:with-param name="prefix" select="''"/>
21    </xsl:apply-templates>
22  </xsl:template>
23  <!-- Walk through all the ACRNConfigType element's children -->
24  <xsl:template match="xs:complexType[@name='ACRNConfigType']">
25    <xsl:param name="level"/>
26    <xsl:param name="prefix"/>
27    <xsl:apply-templates select="descendant::xs:element">
28      <xsl:with-param name="level" select="$level"/>
29      <xsl:with-param name="prefix" select="$prefix"/>
30      <xsl:with-param name="views-of-parent" select="'basic, advanced'"/>
31      <xsl:with-param name="applicable-vms-of-parent" select="''"/>
32    </xsl:apply-templates>
33  </xsl:template>
34  <!-- ... and process all the child elements -->
35  <xsl:template match="xs:element">
36    <xsl:param name="level"/>
37    <xsl:param name="prefix"/>
38    <xsl:param name="views-of-parent"/>
39    <xsl:param name="applicable-vms-of-parent"/>
40
41    <xsl:variable name="views" select="acrn:conditional(count(xs:annotation/@acrn:views) = 1, xs:annotation/@acrn:views, $views-of-parent)"/>
42    <xsl:variable name="applicable-vms" select="acrn:conditional(count(xs:annotation/@acrn:applicable-vms) = 1, xs:annotation/@acrn:applicable-vms, $applicable-vms-of-parent)"/>
43    <xsl:variable name="ty" select="acrn:conditional(count(@type) = 1, @type, .//xs:alternative[1]/@type)"/>
44
45    <!-- dxnamePure and dxname hold the element name with and without spaces converted to underscores -->
46    <xsl:variable name="dxnamePure">
47      <xsl:choose>
48        <xsl:when test=".//descendant::xs:annotation/@acrn:title">
49          <xsl:value-of select=".//descendant::xs:annotation/@acrn:title"/>
50        </xsl:when>
51        <xsl:otherwise>
52          <xsl:value-of select="@name"/>
53        </xsl:otherwise>
54      </xsl:choose>
55    </xsl:variable>
56    <xsl:variable name="dxname">
57      <xsl:value-of select="translate($dxnamePure,' ','_')"/>
58    </xsl:variable>
59    <!-- Only visit elements having complex types. Those having simple types are
60         described as an option -->
61    <xsl:choose>
62      <!-- don't document elements if not viewable -->
63      <xsl:when test="$views='' and $showHidden='n'"/>
64      <xsl:when test="//xs:complexType[@name=$ty] or ./xs:complexType">
65        <!-- The section header -->
66          <xsl:if test="$level &lt;= 4">
67              <xsl:if test="$dxnamePure!=''">
68              <xsl:call-template name="section-header">
69                <xsl:with-param name="title" select="$dxnamePure"/>
70                <xsl:with-param name="label" select="concat($prefix, $dxname)"/>
71                <xsl:with-param name="level" select="$level"/>
72              </xsl:call-template>
73              <!-- Description of this menu / entry -->
74              <xsl:call-template name="print-annotation">
75                <xsl:with-param name="indent" select="''"/>
76              </xsl:call-template>
77              <xsl:value-of select="$newline"/>
78              <!-- use a glossary to show a (sorted) list of config options in this section -->
79              <xsl:value-of select="concat('.. glossary::',$newline,$newline)"/>
80                      <!-- <xsl:value-of select="concat('.. glossary::',$newline,' :sorted:',$newline,$newline)"/> -->
81                  </xsl:if>
82        </xsl:if>
83        <!-- Visit the complex type to generate menus and/or entries -->
84        <xsl:apply-templates select="//xs:complexType[@name=$ty] | ./xs:complexType">
85          <xsl:with-param name="level" select="$level"/>
86          <xsl:with-param name="name" select="concat($prefix, $dxname)"/>
87          <xsl:with-param name="views-of-parent" select="$views"/>
88          <xsl:with-param name="applicable-vms-of-parent" select="$applicable-vms"/>
89        </xsl:apply-templates>
90      </xsl:when>
91      <xsl:otherwise>
92        <xsl:if test="$level = 3">
93            <!-- No longer writing a section header for elements with a simple type
94           <xsl:call-template name="section-header">
95             <xsl:with-param name="title" select="concat('S: ',$dxnamePure)"/>
96             <xsl:with-param name="label" select="concat($prefix, $dxname)"/>
97             <xsl:with-param name="level" select="$level"/>
98         </xsl:call-template> -->
99        </xsl:if>
100        <!-- print option as a glossary item -->
101        <!-- put a sortable character in front of options not available in UI -->
102        <!-- <xsl:if test="xs:annotation/@acrn:views=''">
103            <xsl:text> ~</xsl:text>
104        </xsl:if> -->
105        <xsl:value-of select="concat(' ',$dxnamePure,$newline)"/>
106        <!-- print icons for basic/advanced, hypervisor/VM applicability -->
107        <xsl:variable name="option-icons">
108          <!-- acrn:views describes if this option appears on a "basic" or "advanced" tab, or not at all
109                when the value is "".  If the acrn:views attribute is missing, then the containing parent's
110                acrn:views value is used instead. Similarly for the acrn:applicable-vms attribute.  -->
111          <xsl:choose>
112            <xsl:when test="contains($prefix,'Hypervisor')">
113              <xsl:text>|icon-hypervisor| </xsl:text>
114            </xsl:when>
115            <xsl:otherwise>
116              <xsl:if test="$applicable-vms = '' or contains($applicable-vms, 'pre-launched')">
117                <xsl:text>|icon-pre-launched-vm| </xsl:text>
118              </xsl:if>
119              <xsl:if test="$applicable-vms = '' or contains($applicable-vms, 'post-launched')">
120                <xsl:text>|icon-post-launched-vm| </xsl:text>
121              </xsl:if>
122              <xsl:if test="$applicable-vms = '' or contains($applicable-vms, 'service-vm')">
123                <xsl:text>|icon-service-vm| </xsl:text>
124              </xsl:if>
125            </xsl:otherwise>
126          </xsl:choose>
127          <xsl:text>/ </xsl:text>
128          <xsl:if test="contains($views, 'basic')">
129            <xsl:text>|icon-basic| </xsl:text>
130          </xsl:if>
131          <xsl:if test="contains($views, 'advanced')">
132            <xsl:text>|icon-advanced| </xsl:text>
133          </xsl:if>
134          <xsl:if test="$views = ''">
135            <xsl:text>|icon-not-availble| </xsl:text>
136          </xsl:if>
137        </xsl:variable>
138        <xsl:if test="$option-icons!=''">
139          <xsl:value-of select="concat('   ',$option-icons,$newline)"/>
140        </xsl:if>
141        <xsl:value-of select="$newline"/>
142        <!-- Print the description, type, and occurrence requirements -->
143        <xsl:text>   - </xsl:text>
144        <xsl:call-template name="print-annotation">
145          <xsl:with-param name="indent" select="'     '"/>
146        </xsl:call-template>
147        <xsl:choose>
148          <xsl:when test="//xs:simpleType[@name=$ty]">
149            <xsl:apply-templates select="//xs:simpleType[@name=$ty]">
150              <xsl:with-param name="level" select="$level"/>
151              <xsl:with-param name="prefix" select="''"/>
152            </xsl:apply-templates>
153          </xsl:when>
154          <xsl:when test="starts-with($ty, 'xs:')">
155            <xsl:text>   - </xsl:text>
156            <!-- if unnamed type such as xs:string or xs:integer, print that simple type name with an uppercase first letter -->
157            <xsl:value-of select="concat(translate(substring($ty, 4,1), $vLower, $vUpper), substring($ty,5),' value')"/>
158            <xsl:value-of select="$newline"/>
159          </xsl:when>
160          <xsl:otherwise>
161            <!-- element doesn't have a named type, check for an unnamed simpleType child -->
162            <xsl:apply-templates select="descendant::xs:simpleType">
163              <xsl:with-param name="level" select="$level"/>
164              <xsl:with-param name="prefix" select="''"/>
165            </xsl:apply-templates>
166          </xsl:otherwise>
167        </xsl:choose>
168        <!-- Removed printing occurrance information
169                <xsl:text>   - </xsl:text>
170        <xsl:call-template name="print-occurs">
171          <xsl:with-param name="name" select="$dxnamePure"/>
172        </xsl:call-template> -->
173        <xsl:value-of select="$newline"/>
174      </xsl:otherwise>
175    </xsl:choose>
176  </xsl:template>
177  <xsl:template match="xs:complexType">
178    <xsl:param name="level"/>
179    <xsl:param name="name"/>
180    <xsl:param name="views-of-parent"/>
181    <xsl:param name="applicable-vms-of-parent"/>
182
183        <!-- Visit the sub-menus -->
184    <xsl:variable name="newLevel">
185      <xsl:choose>
186        <xsl:when test=".//descendant::xs:annotation/@acrn:title=''">
187          <xsl:value-of select="$level"/>
188        </xsl:when>
189        <xsl:otherwise><xsl:value-of select="$level + 1"/></xsl:otherwise>
190      </xsl:choose>
191    </xsl:variable>
192    <xsl:apply-templates select="./*/xs:element">
193      <xsl:with-param name="level" select="$newLevel"/>
194      <xsl:with-param name="prefix" select="concat($name, '.')"/>
195      <xsl:with-param name="views-of-parent" select="$views-of-parent"/>
196      <xsl:with-param name="applicable-vms-of-parent" select="$applicable-vms-of-parent"/>
197    </xsl:apply-templates>
198  </xsl:template>
199  <xsl:template match="xs:simpleType">
200    <xsl:text>   - </xsl:text>
201    <xsl:choose>
202      <xsl:when test="xs:annotation/xs:documentation">
203        <xsl:call-template name="print-annotation">
204          <xsl:with-param name="indent" select="'     '"/>
205        </xsl:call-template>
206      </xsl:when>
207      <xsl:when test="starts-with(xs:restriction/@base, 'xs:')">
208        <xsl:variable name="ty" select="xs:restriction/@base"/>
209        <xsl:value-of select="concat(translate(substring($ty, 4,1), $vLower, $vUpper), substring($ty,5),' value')"/>
210        <xsl:value-of select="$newline"/>
211      </xsl:when>
212      <xsl:otherwise>
213        <xsl:text>No type annotation found</xsl:text>
214        <xsl:value-of select="$newline"/>
215      </xsl:otherwise>
216    </xsl:choose>
217  </xsl:template>
218  <xsl:template name="print-occurs">
219    <xsl:param name="name"/>
220    <!-- use the min/maxOccurs data to figure out if this is an optional
221       item, and how many occurrences are allowed -->
222    <xsl:variable name="min">
223      <xsl:choose>
224        <xsl:when test="@minOccurs">
225          <xsl:value-of select="@minOccurs"/>
226        </xsl:when>
227        <xsl:otherwise>1</xsl:otherwise>
228      </xsl:choose>
229    </xsl:variable>
230    <xsl:variable name="max">
231      <xsl:choose>
232        <xsl:when test="@maxOccurs">
233          <xsl:value-of select="@maxOccurs"/>
234        </xsl:when>
235        <xsl:otherwise>1</xsl:otherwise>
236      </xsl:choose>
237    </xsl:variable>
238    <xsl:text>The ``</xsl:text>
239    <xsl:value-of select="$name"/>
240    <xsl:text>`` option is </xsl:text>
241    <xsl:choose>
242      <xsl:when test="$min = 0">
243        <xsl:text>optional</xsl:text>
244      </xsl:when>
245      <xsl:otherwise>
246        <xsl:text>required</xsl:text>
247      </xsl:otherwise>
248    </xsl:choose>
249    <xsl:text> (</xsl:text>
250    <xsl:choose>
251      <xsl:when test="($min = $max) or ($min = 0)">
252        <xsl:value-of select="$max"/>
253        <xsl:text> occurrence</xsl:text>
254        <xsl:if test="$max &gt;  1 or $max='unbounded'">
255          <xsl:text>s</xsl:text>
256        </xsl:if>
257      </xsl:when>
258      <xsl:otherwise>
259        <xsl:value-of select="$min"/>
260        <xsl:text> to </xsl:text>
261        <xsl:value-of select="$max"/>
262        <xsl:text> occurrences</xsl:text>
263      </xsl:otherwise>
264    </xsl:choose>
265    <xsl:text>).</xsl:text>
266    <xsl:value-of select="$newline"/>
267  </xsl:template>
268  <xsl:template name="print-annotation">
269    <xsl:param name="indent"/>
270    <!-- append an (Optional) annotation if minOccurs=0) -->
271    <xsl:variable name="optional">
272      <xsl:choose>
273        <xsl:when test="@minOccurs">
274          <xsl:if test="@minOccurs = 0">
275            <xsl:text> *(Optional)*</xsl:text>
276          </xsl:if>
277          <xsl:if test="@minOccurs != 0">
278            <xsl:text> *(Required)**</xsl:text>
279          </xsl:if>
280        </xsl:when>
281        <!-- could show (Required) here instead, but it seemed too noisy -->
282        <xsl:otherwise>
283          <xsl:text/>
284        </xsl:otherwise>
285      </xsl:choose>
286    </xsl:variable>
287    <!-- append a default value annotation if default was defined -->
288    <xsl:variable name="default">
289      <xsl:choose>
290        <xsl:when test="@default">
291          <xsl:value-of select="concat(' (Default value is ``', @default, '``)')"/>
292        </xsl:when>
293        <xsl:otherwise>
294          <xsl:text/>
295        </xsl:otherwise>
296      </xsl:choose>
297    </xsl:variable>
298    <xsl:choose>
299      <xsl:when test="xs:annotation">
300        <xsl:call-template name="printIndented">
301          <xsl:with-param name="text" select="concat(xs:annotation/xs:documentation[1], $default)"/>
302          <xsl:with-param name="indent" select="$indent"/>
303        </xsl:call-template>
304        <!-- append a second xs:annotation if found.  This allows more content for the documentation that
305              won't be included in the Configurator tooltip -->
306        <xsl:call-template name="printIndented">
307          <xsl:with-param name="text" select="concat($newline, xs:annotation/xs:documentation[2])"/>
308          <xsl:with-param name="indent" select="$indent"/>
309        </xsl:call-template>
310      </xsl:when>
311      <xsl:otherwise>
312        <!-- <xsl:text>&lt;description is missing &gt;</xsl:text> -->
313        <xsl:value-of select="$newline"/>
314      </xsl:otherwise>
315    </xsl:choose>
316  </xsl:template>
317  <!--
318      Library Routines
319  -->
320  <xsl:template name="repeat">
321    <xsl:param name="string"/>
322    <xsl:param name="times"/>
323    <xsl:if test="$times &gt; 0">
324      <xsl:value-of select="$string"/>
325      <xsl:call-template name="repeat">
326        <xsl:with-param name="string" select="$string"/>
327        <xsl:with-param name="times" select="$times - 1"/>
328      </xsl:call-template>
329    </xsl:if>
330  </xsl:template>
331  <xsl:template name="section-header">
332    <xsl:param name="title"/>
333    <xsl:param name="label"/>
334    <xsl:param name="level"/>
335    <xsl:if test="$label != ''">
336      <xsl:value-of select="concat($newline, '.. _', $label, ':', $newline, $newline)"/>
337    </xsl:if>
338    <xsl:value-of select="concat($title, $newline)"/>
339    <xsl:call-template name="repeat">
340      <xsl:with-param name="string">
341        <xsl:value-of select="substring($section_adornment, $level, 1)"/>
342      </xsl:with-param>
343      <xsl:with-param name="times" select="string-length($title)"/>
344    </xsl:call-template>
345    <xsl:value-of select="concat($newline, $newline)"/>
346  </xsl:template>
347  <xsl:template name="printIndented">
348    <xsl:param name="text"/>
349    <xsl:param name="indent"/>
350    <!-- Handle multi-line documentation text and indent it properly for
351       the bullet list display we're using for node descriptions (but not for
352       heading descriptions -->
353    <xsl:if test="$text">
354      <xsl:variable name="thisLine" select="substring-before($text, $newline)"/>
355      <xsl:variable name="nextLine" select="substring-after($text, $newline)"/>
356      <xsl:choose>
357        <xsl:when test="$thisLine or $nextLine">
358          <!-- $text contains at least one newline, and there's more coming so print it -->
359          <xsl:value-of select="concat($thisLine, $newline)"/>
360          <!-- watch for two newlines in a row and avoid writing the indent -->
361          <xsl:if test="substring-before(concat($nextLine, $newline), $newline)">
362            <xsl:value-of select="$indent"/>
363          </xsl:if>
364          <!-- and recurse to process the rest -->
365          <xsl:call-template name="printIndented">
366            <xsl:with-param name="text" select="$nextLine"/>
367            <xsl:with-param name="indent" select="$indent"/>
368          </xsl:call-template>
369        </xsl:when>
370        <xsl:otherwise>
371          <xsl:value-of select="concat($text, $newline)"/>
372        </xsl:otherwise>
373      </xsl:choose>
374    </xsl:if>
375  </xsl:template>
376  <func:function name="acrn:conditional">
377    <xsl:param name="cond"/>
378    <xsl:param name="a"/>
379    <xsl:param name="b"/>
380    <xsl:choose>
381      <xsl:when test="$cond">
382        <func:result select="$a"/>
383      </xsl:when>
384      <xsl:otherwise>
385        <func:result select="$b"/>
386      </xsl:otherwise>
387    </xsl:choose>
388  </func:function>
389</xsl:stylesheet>
390