~macslow/unity/backported-remote-add-to-5.0

« back to all changes in this revision

Viewing changes to guides/styleguide.xsl

  • Committer: Tim Penhey
  • Date: 2011-07-19 00:32:10 UTC
  • mto: This revision was merged to the branch mainline in revision 1311.
  • Revision ID: tim.penhey@canonical.com-20110719003210-kxux222k7l9e0ty2
Add the style guide into the tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<xsl:stylesheet version="1.0"
 
2
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 
3
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 
4
xmlns:dc="http://purl.org/dc/elements/1.1/"
 
5
xmlns:dcq="http://purl.org/dc/qualifiers/1.0/"
 
6
xmlns:fo="http://www.w3.org/1999/XSL/Format"
 
7
xmlns:fn="http://www.w3.org/2005/xpath-functions">
 
8
  <xsl:output method="html"/>
 
9
  <!-- Set to 1 to show explanations by default.  Set to 0 to hide them -->
 
10
  <xsl:variable name="show_explanation_default" select="0" />
 
11
  <!-- The characters within the Webdings font that show the triangles -->
 
12
  <xsl:variable name="show_button_text" select="'&#x25B6;'" />
 
13
  <xsl:variable name="hide_button_text" select="'&#x25BD;'" />
 
14
  <!-- The suffix for names -->
 
15
  <xsl:variable name="button_suffix" select="'__button'"/>
 
16
  <xsl:variable name="body_suffix" select="'__body'"/>
 
17
  <!-- For easy reference, the name of the button -->
 
18
  <xsl:variable name="show_hide_all_button" select="'show_hide_all_button'"/>
 
19
 
 
20
  <!-- The top-level element -->
 
21
  <xsl:template match="GUIDE">
 
22
      <HTML>
 
23
          <HEAD>
 
24
              <TITLE><xsl:value-of select="@title"/></TITLE>
 
25
              <META http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 
26
              <LINK HREF="http://www.google.com/favicon.ico" type="image/x-icon"
 
27
                    rel="shortcut icon"/>
 
28
              <LINK HREF="styleguide.css"
 
29
                    type="text/css" rel="stylesheet"/>
 
30
 
 
31
              <SCRIPT language="javascript" type="text/javascript">
 
32
 
 
33
                function ShowHideByName(bodyName, buttonName) {
 
34
                  var bodyElements;
 
35
                  var linkElement;
 
36
                  if (document.getElementsByName) {
 
37
                    bodyElements = document.getElementsByName(bodyName);
 
38
                    linkElement = document.getElementsByName('link-' + buttonName)[0];
 
39
                  } else {
 
40
                    bodyElements = [document.getElementById(bodyName)];
 
41
                    linkElement = document.getElementById('link-' + buttonName);
 
42
                  }
 
43
                  if (bodyElements.length != 1) {
 
44
                    alert("ShowHideByName() got the wrong number of bodyElements:  " + bodyElements.length);
 
45
                  } else {
 
46
                    var bodyElement = bodyElements[0];
 
47
                    var buttonElement;
 
48
                    if (document.getElementsByName) {
 
49
                      var buttonElements = document.getElementsByName(buttonName);
 
50
                      buttonElement = buttonElements[0];
 
51
                    } else {
 
52
                      buttonElement = document.getElementById(buttonName);
 
53
                    }
 
54
                    if (bodyElement.style.display == "none" || bodyElement.style.display == "") {
 
55
                      bodyElement.style.display = "inline";
 
56
                      linkElement.style.display = "block";
 
57
                      buttonElement.innerHTML = '<xsl:value-of select="$hide_button_text"/>';
 
58
                    } else {
 
59
                      bodyElement.style.display = "none";
 
60
                      linkElement.style.display = "none";
 
61
                      buttonElement.innerHTML = '<xsl:value-of select="$show_button_text"/>';
 
62
                    }
 
63
                  }
 
64
                }
 
65
 
 
66
                function ShowHideAll() {
 
67
                  var allButton;
 
68
                  if (document.getElementsByName) {
 
69
                    var allButtons = document.getElementsByName("show_hide_all_button");
 
70
                    allButton = allButtons[0];
 
71
                  } else {
 
72
                    allButton = document.getElementById("show_hide_all_button");
 
73
                  }
 
74
                  if (allButton.innerHTML == '<xsl:value-of select="$hide_button_text"/>') {
 
75
                    allButton.innerHTML = '<xsl:value-of select="$show_button_text"/>';
 
76
                    SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "none", '<xsl:value-of select="$show_button_text"/>');
 
77
                  } else {
 
78
                    allButton.innerHTML = '<xsl:value-of select="$hide_button_text"/>';
 
79
                    SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "inline", '<xsl:value-of select="$hide_button_text"/>');
 
80
                  }
 
81
                }
 
82
 
 
83
                // Recursively sets state of all children
 
84
                // of a particular node.
 
85
                function SetHiddenState(root, newState, newButton) {
 
86
                  for (var i = 0; i != root.length; i++) {
 
87
                    SetHiddenState(root[i].childNodes, newState, newButton);
 
88
                    if (root[i].className == 'showhide_button')  {
 
89
                      root[i].innerHTML = newButton;
 
90
                    }
 
91
                    if (root[i].className == 'stylepoint_body' ||
 
92
                        root[i].className == 'link_button')  {
 
93
                      root[i].style.display = newState;
 
94
                    }
 
95
                  }
 
96
                }
 
97
 
 
98
 
 
99
                window.onload = function() {
 
100
                  // if the URL contains "?showall=y", expand the details of all children
 
101
                  {
 
102
                    var showHideAllRegex = new RegExp("[\\?&amp;](showall)=([^&amp;#]*)");
 
103
                    var showHideAllValue = showHideAllRegex.exec(window.location.href);
 
104
                    if (showHideAllValue != null) {
 
105
                      if (showHideAllValue[2] == "y") {
 
106
                        SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "inline", '<xsl:value-of select="$hide_button_text"/>');
 
107
                      } else {
 
108
                        SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "none", '<xsl:value-of select="$show_button_text"/>');
 
109
                      }
 
110
                    }
 
111
                    var showOneRegex = new RegExp("[\\?&amp;](showone)=([^&amp;#]*)");
 
112
                    var showOneValue = showOneRegex.exec(window.location.href);
 
113
                    if (showOneValue != null) {
 
114
                      var body_name = showOneValue[2] + '<xsl:value-of select="$body_suffix"/>';
 
115
                      var button_name = showOneValue[2] + '<xsl:value-of select="$button_suffix"/>';
 
116
                      ShowHideByName(body_name, button_name);
 
117
                    }
 
118
 
 
119
                  }
 
120
                }
 
121
              </SCRIPT>
 
122
          </HEAD>
 
123
          <BODY>
 
124
            <H1><xsl:value-of select="@title"/></H1>
 
125
              <xsl:apply-templates/>
 
126
          </BODY>
 
127
      </HTML>
 
128
  </xsl:template>
 
129
 
 
130
  <xsl:template match="OVERVIEW">
 
131
    <xsl:variable name="button_text">
 
132
      <xsl:choose>
 
133
        <xsl:when test="$show_explanation_default">
 
134
          <xsl:value-of select="$hide_button_text"/>
 
135
        </xsl:when>
 
136
        <xsl:otherwise>
 
137
          <xsl:value-of select="$show_button_text"/>
 
138
        </xsl:otherwise>
 
139
      </xsl:choose>
 
140
    </xsl:variable>
 
141
    <DIV style="margin-left: 50%; font-size: 75%;">
 
142
      <P>
 
143
        Each style point has a summary for which additional information is available
 
144
        by toggling the accompanying arrow button that looks this way:
 
145
        <SPAN class="showhide_button" style="margin-left: 0; float: none">
 
146
          <xsl:value-of select="$show_button_text"/></SPAN>.
 
147
        You may toggle all summaries with the big arrow button:
 
148
      </P>
 
149
      <DIV style=" font-size: larger; margin-left: +2em;">
 
150
        <SPAN class="showhide_button" style="font-size: 180%; float: none">
 
151
          <xsl:attribute name="onclick"><xsl:value-of select="'javascript:ShowHideAll()'"/></xsl:attribute>
 
152
          <xsl:attribute name="name"><xsl:value-of select="$show_hide_all_button"/></xsl:attribute>
 
153
          <xsl:attribute name="id"><xsl:value-of select="$show_hide_all_button"/></xsl:attribute>
 
154
          <xsl:value-of select="$button_text"/>
 
155
        </SPAN>
 
156
        Toggle all summaries
 
157
      </DIV>
 
158
    </DIV>
 
159
    <xsl:call-template name="TOC">
 
160
      <xsl:with-param name="root" select=".."/>
 
161
    </xsl:call-template>
 
162
    <xsl:apply-templates/>
 
163
  </xsl:template>
 
164
 
 
165
  <xsl:template match="PARTING_WORDS">
 
166
    <H2>Parting Words</H2>
 
167
    <xsl:apply-templates/>
 
168
  </xsl:template>
 
169
 
 
170
  <xsl:template match="CATEGORY">
 
171
    <DIV>
 
172
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
173
      <H2>
 
174
        <xsl:variable name="category_name">
 
175
          <xsl:call-template name="anchorname">
 
176
            <xsl:with-param name="sectionname" select="@title"/>
 
177
          </xsl:call-template>
 
178
        </xsl:variable>
 
179
        <xsl:attribute name="name"><xsl:value-of select="$category_name"/></xsl:attribute>
 
180
        <xsl:attribute name="id"><xsl:value-of select="$category_name"/></xsl:attribute>
 
181
        <xsl:value-of select="@title"/>
 
182
      </H2>
 
183
      <xsl:apply-templates/>
 
184
    </DIV>
 
185
  </xsl:template>
 
186
 
 
187
  <xsl:template match="STYLEPOINT">
 
188
    <DIV>
 
189
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
190
      <xsl:variable name="stylepoint_name">
 
191
        <xsl:call-template name="anchorname">
 
192
          <xsl:with-param name="sectionname" select="@title"/>
 
193
        </xsl:call-template>
 
194
      </xsl:variable>
 
195
      <xsl:variable name="button_text">
 
196
        <xsl:choose>
 
197
          <xsl:when test="$show_explanation_default">
 
198
            <xsl:value-of select="$hide_button_text"/>
 
199
          </xsl:when>
 
200
          <xsl:otherwise>
 
201
            <xsl:value-of select="$show_button_text"/>
 
202
          </xsl:otherwise>
 
203
        </xsl:choose>
 
204
      </xsl:variable>
 
205
      <H3>
 
206
        <A>
 
207
          <xsl:attribute name="name"><xsl:value-of select="$stylepoint_name"/></xsl:attribute>
 
208
          <xsl:attribute name="id"><xsl:value-of select="$stylepoint_name"/></xsl:attribute>
 
209
          <xsl:value-of select="@title"/>
 
210
        </A>
 
211
      </H3>
 
212
      <xsl:variable name="buttonName">
 
213
        <xsl:value-of select="$stylepoint_name"/><xsl:value-of select="$button_suffix"/>
 
214
      </xsl:variable>
 
215
      <xsl:variable name="onclick_definition">
 
216
        <xsl:text>javascript:ShowHideByName('</xsl:text>
 
217
        <xsl:value-of select="$stylepoint_name"/><xsl:value-of select="$body_suffix"/>
 
218
        <xsl:text>','</xsl:text>
 
219
        <xsl:value-of select="$buttonName"/>
 
220
        <xsl:text>')</xsl:text>
 
221
      </xsl:variable>
 
222
      <SPAN class="link_button" id="link-{$buttonName}" name="link-{$buttonName}">
 
223
        <A>
 
224
          <xsl:attribute name="href">?showone=<xsl:value-of select="$stylepoint_name"/>#<xsl:value-of select="$stylepoint_name"/></xsl:attribute>
 
225
          link
 
226
        </A>
 
227
      </SPAN>
 
228
      <SPAN class="showhide_button">
 
229
        <xsl:attribute name="onclick"><xsl:value-of select="$onclick_definition"/></xsl:attribute>
 
230
        <xsl:attribute name="name"><xsl:value-of select="$buttonName"/></xsl:attribute>
 
231
        <xsl:attribute name="id"><xsl:value-of select="$buttonName"/></xsl:attribute>
 
232
        <xsl:value-of select="$button_text"/>
 
233
      </SPAN>
 
234
      <xsl:apply-templates>
 
235
        <xsl:with-param name="anchor_prefix" select="$stylepoint_name" />
 
236
      </xsl:apply-templates>
 
237
    </DIV>
 
238
  </xsl:template>
 
239
 
 
240
  <xsl:template match="SUMMARY">
 
241
    <xsl:param name="anchor_prefix" />
 
242
    <DIV style="display:inline;">
 
243
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
244
      <xsl:apply-templates/>
 
245
    </DIV>
 
246
  </xsl:template>
 
247
 
 
248
  <xsl:template match="BODY">
 
249
    <xsl:param name="anchor_prefix" />
 
250
    <DIV>
 
251
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
252
      <DIV class="stylepoint_body">
 
253
        <xsl:attribute name="name"><xsl:value-of select="$anchor_prefix"/><xsl:value-of select="$body_suffix"/></xsl:attribute>
 
254
        <xsl:attribute name="id"><xsl:value-of select="$anchor_prefix"/><xsl:value-of select="$body_suffix"/></xsl:attribute>
 
255
        <xsl:attribute name="style">
 
256
          <xsl:choose>
 
257
            <xsl:when test="$show_explanation_default">display: inline</xsl:when>
 
258
            <xsl:otherwise>display: none</xsl:otherwise>
 
259
          </xsl:choose>
 
260
        </xsl:attribute>
 
261
        <xsl:apply-templates/>
 
262
      </DIV>
 
263
    </DIV>
 
264
  </xsl:template>
 
265
 
 
266
  <xsl:template match="DEFINITION">
 
267
    <P>
 
268
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
269
      <SPAN class="stylepoint_section">Definition:  </SPAN>
 
270
      <xsl:apply-templates/>
 
271
    </P>
 
272
  </xsl:template>
 
273
 
 
274
  <xsl:template match="PROS">
 
275
    <P>
 
276
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
277
      <SPAN class="stylepoint_section">Pros:  </SPAN>
 
278
      <xsl:apply-templates/>
 
279
    </P>
 
280
  </xsl:template>
 
281
 
 
282
  <xsl:template match="CONS">
 
283
    <P>
 
284
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
285
      <SPAN class="stylepoint_section">Cons: </SPAN>
 
286
      <xsl:apply-templates/>
 
287
    </P>
 
288
  </xsl:template>
 
289
 
 
290
  <xsl:template match="DECISION">
 
291
    <P>
 
292
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
293
      <SPAN class="stylepoint_section">Decision:  </SPAN>
 
294
      <xsl:apply-templates/>
 
295
    </P>
 
296
  </xsl:template>
 
297
 
 
298
  <xsl:template match="TODO">
 
299
    <P>
 
300
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
301
      <DIV style="font-size: 150%;">TODO:
 
302
        <xsl:apply-templates/>
 
303
      </DIV>
 
304
    </P>
 
305
  </xsl:template>
 
306
 
 
307
  <xsl:template match="SUBSECTION">
 
308
    <P>
 
309
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
310
      <SPAN class="stylepoint_subsection"><xsl:value-of select="@title"/>  </SPAN>
 
311
      <xsl:apply-templates/>
 
312
    </P>
 
313
  </xsl:template>
 
314
 
 
315
  <xsl:template match="SUBSUBSECTION">
 
316
    <P>
 
317
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
318
      <SPAN class="stylepoint_subsubsection"><xsl:value-of select="@title"/>  </SPAN>
 
319
      <xsl:apply-templates/>
 
320
    </P>
 
321
  </xsl:template>
 
322
 
 
323
  <xsl:template match="CODE_SNIPPET">
 
324
    <DIV>
 
325
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
326
      <PRE><xsl:call-template name="print_without_leading_chars">
 
327
           <xsl:with-param name="text" select="."/>
 
328
           <xsl:with-param name="strip" select="1"/>
 
329
           <xsl:with-param name="is_firstline" select="1"/>
 
330
           <xsl:with-param name="trim_count">
 
331
             <xsl:call-template name="num_leading_spaces">
 
332
               <xsl:with-param name="text" select="."/>
 
333
               <xsl:with-param name="max_so_far" select="1000"/>
 
334
             </xsl:call-template>
 
335
           </xsl:with-param>
 
336
         </xsl:call-template></PRE>
 
337
    </DIV>
 
338
  </xsl:template>
 
339
 
 
340
  <xsl:template match="BAD_CODE_SNIPPET">
 
341
    <DIV>
 
342
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
343
      <PRE class="badcode"><xsl:call-template name="print_without_leading_chars">
 
344
           <xsl:with-param name="text" select="."/>
 
345
           <xsl:with-param name="strip" select="1"/>
 
346
           <xsl:with-param name="is_firstline" select="1"/>
 
347
           <xsl:with-param name="trim_count">
 
348
             <xsl:call-template name="num_leading_spaces">
 
349
               <xsl:with-param name="text" select="."/>
 
350
               <xsl:with-param name="max_so_far" select="1000"/>
 
351
             </xsl:call-template>
 
352
           </xsl:with-param>
 
353
         </xsl:call-template></PRE>
 
354
    </DIV>
 
355
  </xsl:template>
 
356
 
 
357
  <xsl:template match="PY_CODE_SNIPPET">
 
358
    <DIV>
 
359
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
360
      <PRE><xsl:call-template name="print_python_code">
 
361
             <xsl:with-param name="text" select="."/>
 
362
           </xsl:call-template></PRE>
 
363
    </DIV>
 
364
  </xsl:template>
 
365
 
 
366
  <xsl:template match="BAD_PY_CODE_SNIPPET">
 
367
    <DIV>
 
368
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
369
      <PRE class="badcode"><xsl:call-template name="print_python_code">
 
370
                             <xsl:with-param name="text" select="."/>
 
371
                           </xsl:call-template></PRE>
 
372
    </DIV>
 
373
  </xsl:template>
 
374
 
 
375
  <xsl:template match="FUNCTION">
 
376
    <xsl:call-template name="print_function_name">
 
377
      <xsl:with-param name="text" select="."/>
 
378
    </xsl:call-template>
 
379
  </xsl:template>
 
380
 
 
381
  <xsl:template match="SYNTAX">
 
382
    <I>
 
383
      <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
384
      <xsl:apply-templates/>
 
385
    </I>
 
386
  </xsl:template>
 
387
 
 
388
 
 
389
  <!-- This passes through any HTML elements that the
 
390
    XML doc uses for minor formatting -->
 
391
  <xsl:template match="a|address|blockquote|br|center|cite|code|dd|div|dl|dt|em|hr|i|img|li|ol|p|pre|span|table|td|th|tr|ul|var|A|ADDRESS|BLOCKQUOTE|BR|CENTER|CITE|CODE|DD|DIV|DL|DT|EM|HR|I|LI|OL|P|PRE|SPAN|TABLE|TD|TH|TR|UL|VAR">
 
392
      <xsl:element name="{local-name()}">
 
393
          <xsl:copy-of select="@*"/>
 
394
          <xsl:apply-templates/>
 
395
      </xsl:element>
 
396
  </xsl:template>
 
397
 
 
398
    <!-- Builds the table of contents -->
 
399
  <xsl:template name="TOC">
 
400
    <xsl:param name="root"/>
 
401
    <DIV class="toc">
 
402
      <DIV class="toc_title">Table of Contents</DIV>
 
403
      <TABLE>
 
404
      <xsl:for-each select="$root/CATEGORY">
 
405
        <TR valign="top">
 
406
          <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
407
          <TD>
 
408
          <DIV class="toc_category">
 
409
            <A>
 
410
              <xsl:attribute name="href">
 
411
                <xsl:text>#</xsl:text>
 
412
                <xsl:call-template name="anchorname">
 
413
                  <xsl:with-param name="sectionname" select="@title"/>
 
414
                </xsl:call-template>
 
415
              </xsl:attribute>
 
416
              <xsl:value-of select="@title"/>
 
417
            </A>
 
418
          </DIV>
 
419
          </TD><TD>
 
420
            <DIV class="toc_stylepoint">
 
421
              <xsl:for-each select="./STYLEPOINT">
 
422
                <SPAN style="padding-right: 1em; white-space:nowrap;">
 
423
                  <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
 
424
                  <A>
 
425
                    <xsl:attribute name="href">
 
426
                      <xsl:text>#</xsl:text>
 
427
                      <xsl:call-template name="anchorname">
 
428
                        <xsl:with-param name="sectionname" select="@title"/>
 
429
                      </xsl:call-template>
 
430
                    </xsl:attribute>
 
431
                    <xsl:value-of select="@title"/>
 
432
                  </A>
 
433
                </SPAN>
 
434
                <xsl:text> </xsl:text>
 
435
              </xsl:for-each>
 
436
            </DIV>
 
437
          </TD>
 
438
        </TR>
 
439
      </xsl:for-each>
 
440
      </TABLE>
 
441
    </DIV>
 
442
  </xsl:template>
 
443
 
 
444
  <xsl:template name="TOC_one_stylepoint">
 
445
    <xsl:param name="stylepoint"/>
 
446
  </xsl:template>
 
447
 
 
448
  <!-- Creates a standard anchor given any text.
 
449
       Substitutes underscore for characters unsuitable for URLs  -->
 
450
  <xsl:template name="anchorname">
 
451
    <xsl:param name="sectionname"/>
 
452
    <!-- strange quoting necessary to strip apostrophes -->
 
453
    <xsl:variable name="bad_characters" select="&quot; ()#'&quot;"/>
 
454
    <xsl:value-of select="translate($sectionname,$bad_characters,'_____')"/>
 
455
  </xsl:template>
 
456
 
 
457
  <!-- Given text, evaluates to the number of leading spaces. -->
 
458
  <!-- TODO(csilvers): deal well with leading tabs (treat as 8 spaces?) -->
 
459
  <xsl:template name="num_leading_spaces_one_line">
 
460
    <xsl:param name="text"/>
 
461
    <xsl:param name="current_count"/>
 
462
    <xsl:choose>
 
463
      <xsl:when test="starts-with($text, ' ')">
 
464
        <xsl:call-template name="num_leading_spaces_one_line">
 
465
          <xsl:with-param name="text" select="substring($text, 2)"/>
 
466
          <xsl:with-param name="current_count" select="$current_count + 1"/>
 
467
        </xsl:call-template>
 
468
      </xsl:when>
 
469
      <xsl:otherwise>
 
470
        <xsl:value-of select="$current_count"/>
 
471
      </xsl:otherwise>
 
472
    </xsl:choose>
 
473
  </xsl:template>
 
474
 
 
475
  <!-- Given a block of text, each line terminated by \n, evaluates to
 
476
       the indentation-level of that text; that is, the largest number
 
477
       n such that every non-blank line starts with at least n spaces. -->
 
478
  <xsl:template name="num_leading_spaces">
 
479
    <xsl:param name="text"/>
 
480
    <xsl:param name="max_so_far"/>
 
481
    <!-- TODO(csilvers): deal with case text doesn't end in a newline -->
 
482
    <xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
 
483
    <xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
 
484
    <xsl:variable name="num_spaces_this_line">
 
485
      <xsl:choose>
 
486
        <xsl:when test="$line=''">
 
487
           <xsl:value-of select="$max_so_far"/>
 
488
        </xsl:when>
 
489
        <xsl:otherwise>
 
490
          <xsl:call-template name="num_leading_spaces_one_line">
 
491
            <xsl:with-param name="text" select="$line"/>
 
492
            <xsl:with-param name="current_count" select="0"/>
 
493
          </xsl:call-template>
 
494
        </xsl:otherwise>
 
495
      </xsl:choose>
 
496
    </xsl:variable>
 
497
    <xsl:variable name="new_max_so_far">
 
498
       <xsl:choose>
 
499
         <xsl:when test="$num_spaces_this_line &lt; $max_so_far">
 
500
           <xsl:value-of select="$num_spaces_this_line"/>
 
501
         </xsl:when>
 
502
         <xsl:otherwise>
 
503
           <xsl:value-of select="$max_so_far"/>
 
504
         </xsl:otherwise>
 
505
       </xsl:choose>
 
506
    </xsl:variable>
 
507
    <!-- now check if we're on the last line, and if not, recurse -->
 
508
    <xsl:if test="$rest=''">
 
509
      <xsl:value-of select="$new_max_so_far"/>
 
510
    </xsl:if>
 
511
    <xsl:if test="not($rest='')">
 
512
      <xsl:call-template name="num_leading_spaces">
 
513
        <xsl:with-param name="text" select="$rest"/>
 
514
        <xsl:with-param name="max_so_far" select="$new_max_so_far"/>
 
515
      </xsl:call-template>
 
516
    </xsl:if>
 
517
  </xsl:template>
 
518
 
 
519
  <!-- Given text, determine the starting position of code.
 
520
       This similar to num_leading_spaces_one_line but treats "Yes:" and "No:" 
 
521
       as spaces. Also, if there is no code on the first line, it searches 
 
522
       subsequent lines until a non-empty line is found.
 
523
       Used to find the start of code in snippets like:
 
524
       Yes: if(foo):
 
525
       No : if(foo):
 
526
       As well as:
 
527
       Yes:
 
528
         if (foo):
 
529
  -->
 
530
  <xsl:template name="code_start_index">
 
531
    <xsl:param name="text"/>
 
532
    <xsl:param name="current_count"/>
 
533
    <xsl:choose>
 
534
      <xsl:when test="starts-with($text, ' ')">
 
535
        <xsl:call-template name="code_start_index">
 
536
          <xsl:with-param name="text" select="substring($text, 2)"/>
 
537
          <xsl:with-param name="current_count" select="$current_count + 1"/>
 
538
        </xsl:call-template>
 
539
      </xsl:when>
 
540
      <xsl:when test="starts-with($text, 'Yes:')">
 
541
        <xsl:call-template name="code_start_index">
 
542
          <xsl:with-param name="text" select="substring($text, 5)"/>
 
543
          <xsl:with-param name="current_count" select="$current_count + 4"/>
 
544
        </xsl:call-template>
 
545
      </xsl:when>
 
546
      <xsl:when test="starts-with($text, 'No:')">
 
547
        <xsl:call-template name="code_start_index">
 
548
          <xsl:with-param name="text" select="substring($text, 4)"/>
 
549
          <xsl:with-param name="current_count" select="$current_count + 3"/>
 
550
        </xsl:call-template>
 
551
      </xsl:when>
 
552
      <!-- This is only reached if the first line is entirely whitespace or 
 
553
           contains nothing but "Yes:" or "No:"-->
 
554
      <xsl:when test="starts-with($text, '&#xA;')">
 
555
        <xsl:call-template name="code_start_index">
 
556
          <xsl:with-param name="text" select="substring($text, 2)"/>
 
557
          <xsl:with-param name="current_count" select="0"/>
 
558
        </xsl:call-template>
 
559
      </xsl:when>
 
560
      <xsl:otherwise>
 
561
        <xsl:value-of select="$current_count"/>
 
562
      </xsl:otherwise>
 
563
    </xsl:choose>
 
564
  </xsl:template>
 
565
 
 
566
  <!-- Helper for ends_with_colon. Determine whether the given line is nothing
 
567
       but spaces and python-style comments. -->
 
568
  <xsl:template name="is_blank_or_comment">
 
569
    <xsl:param name="line"/>
 
570
    <xsl:choose>
 
571
      <xsl:when test="$line = ''">
 
572
        <xsl:value-of select="1"/>
 
573
      </xsl:when>
 
574
      <xsl:when test="starts-with($line, '&#xA;')">
 
575
        <xsl:value-of select="1"/>
 
576
      </xsl:when>
 
577
      <xsl:when test="starts-with($line, '#')">
 
578
        <xsl:value-of select="1"/>
 
579
      </xsl:when>
 
580
      <xsl:when test="starts-with($line, ' ')">
 
581
        <xsl:call-template name="is_blank_or_comment">
 
582
          <xsl:with-param name="line" select="substring($line, 2)"/>
 
583
        </xsl:call-template>
 
584
      </xsl:when>
 
585
      <xsl:otherwise>
 
586
        <xsl:value-of select="0"/>
 
587
      </xsl:otherwise>
 
588
    </xsl:choose>
 
589
  </xsl:template>
 
590
 
 
591
  <!-- Determine whether the given line ends with a colon. Note that Python
 
592
       style comments are ignored so the following lines return True:
 
593
       - def foo():
 
594
       - def foo():  # Bar
 
595
       - if(foo):
 
596
 
 
597
       But some code may confuse this function. For example the following are
 
598
       also consider to "end_with_colon" even though they don't for Python
 
599
       - foo(":  #")
 
600
       - foo() # No need for :
 
601
  -->
 
602
  <xsl:template name="ends_with_colon">
 
603
    <xsl:param name="line"/>
 
604
    <xsl:param name="found_colon"/>
 
605
    <xsl:choose>
 
606
      <xsl:when test="$line = ''">
 
607
        <xsl:value-of select="$found_colon"/>
 
608
      </xsl:when>
 
609
      <xsl:when test="starts-with($line, '&#xA;')">
 
610
        <xsl:value-of select="$found_colon"/>
 
611
      </xsl:when>
 
612
      <xsl:when test="starts-with($line, ' ')">
 
613
        <xsl:call-template name="ends_with_colon">
 
614
          <xsl:with-param name="line" select="substring($line, 2)"/>
 
615
          <xsl:with-param name="found_colon" select="$found_colon"/>
 
616
        </xsl:call-template>
 
617
      </xsl:when>
 
618
      <xsl:when test="starts-with($line, ':')">
 
619
        <xsl:variable name="rest_is_comment">
 
620
          <xsl:call-template name="is_blank_or_comment">
 
621
            <xsl:with-param name="line" select="substring($line, 2)"/>
 
622
          </xsl:call-template>
 
623
        </xsl:variable>
 
624
        <xsl:choose>
 
625
          <xsl:when test="$rest_is_comment = '1'">
 
626
            <xsl:value-of select="1"/>
 
627
          </xsl:when>
 
628
          <xsl:otherwise>
 
629
            <xsl:call-template name="ends_with_colon">
 
630
              <xsl:with-param name="line" select="substring($line, 2)"/>
 
631
              <xsl:with-param name="found_colon" select="0"/>
 
632
            </xsl:call-template>
 
633
          </xsl:otherwise>
 
634
        </xsl:choose>
 
635
      </xsl:when>
 
636
      <xsl:otherwise>
 
637
        <xsl:call-template name="ends_with_colon">
 
638
          <xsl:with-param name="line" select="substring($line, 2)"/>
 
639
          <xsl:with-param name="found_colon" select="0"/>
 
640
        </xsl:call-template>
 
641
      </xsl:otherwise>
 
642
    </xsl:choose>
 
643
  </xsl:template>
 
644
 
 
645
  <!-- Prints one line of python code with proper indent and calls itself
 
646
       recursively for the rest of the text.
 
647
       This template uses "a", "b", "c" and "d" to refer to four key column
 
648
       numbers. They are:
 
649
       - a: the indentation common to all lines in a code snippet. This is
 
650
            stripped out to allow for cleaner code in the xml.
 
651
       - b: the indentation of the most out-dented line of code. This is
 
652
            different from "a" when code is labelled with "Yes:" or "No:"
 
653
       - c: the indentation of the current python block, in other words, the
 
654
            indentation of the first line of this block, which is the
 
655
            indentation of the last line we saw that ended with a colon.
 
656
       - d: the "total" indentation of the line, ignorng possible "Yes:" or
 
657
            "No:" text on the line.
 
658
 
 
659
       For example, for the last line of the following code snippet, the
 
660
       positions of a, b, c and d are indicated below:
 
661
           Yes: def Foo():
 
662
                  if bar():
 
663
                    a += 1
 
664
                    baz()
 
665
           a    b c d
 
666
 
 
667
       The algorithm is:
 
668
       1) Split the text into first line and the rest. Note that the
 
669
          substring-before function is supposed to handle the case where the
 
670
          character is not present in the string but does not so we
 
671
          automatically ignore the last line of the snippet which is always
 
672
          empty (the closing snippet tag). This is consistent with the
 
673
          behavior or print_without_leading_chars.
 
674
       2) If the current is empty (only whitespace), print newline and call
 
675
          itself recursively on the rest of the text with the rest of the
 
676
          parameters unchanged.
 
677
       3) Otherwise, measure "d"
 
678
       4) Measure "c" by taking:
 
679
          - the value of "d" if the previous line ended with a colon or the
 
680
            current line is outdented compare to the previous line
 
681
          - the indent of the previous line otherwise
 
682
       5) Print line[a:c] (Note that we ignore line[0:a])
 
683
       6) Print line[b:c] in an external span (in order to double the block
 
684
          indent in external code).
 
685
       7) Print line[c:<end>] with function names processed to produce both 
 
686
          internal and external names.
 
687
       8) If there are more lines, recurse.
 
688
  -->
 
689
  <xsl:template name="print_python_line_recursively">
 
690
    <xsl:param name="text"/>
 
691
    <xsl:param name="a"/>
 
692
    <xsl:param name="b"/>
 
693
    <xsl:param name="previous_indent"/>
 
694
    <xsl:param name="previous_ends_with_colon"/>
 
695
    <xsl:param name="is_first_line"/>
 
696
    <xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
 
697
    <xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
 
698
    <xsl:choose>
 
699
      <xsl:when test="substring($line, $b) = '' and not($rest = '')">
 
700
        <xsl:if test="not($is_first_line = '1')">
 
701
          <xsl:text>&#xA;</xsl:text>
 
702
        </xsl:if>
 
703
        <xsl:call-template name="print_python_line_recursively">
 
704
          <xsl:with-param name="text" select="$rest"/>
 
705
          <xsl:with-param name="a" select="$a"/>
 
706
          <xsl:with-param name="b" select="$b"/>
 
707
          <xsl:with-param name="previous_indent" select="$previous_indent"/>
 
708
          <xsl:with-param name="previous_ends_with_colon"
 
709
                          select="$previous_ends_with_colon"/>
 
710
          <xsl:with-param name="is_first_line" select="0"/>
 
711
        </xsl:call-template>
 
712
      </xsl:when>
 
713
      <xsl:otherwise>
 
714
        <xsl:variable name="indent_after_b">
 
715
          <xsl:call-template name="num_leading_spaces_one_line">
 
716
            <xsl:with-param name="text" select="substring($line, $b + 1)"/>
 
717
            <xsl:with-param name="current_count" select="0"/>
 
718
          </xsl:call-template>
 
719
        </xsl:variable>
 
720
        <xsl:variable name="d" select="$b + $indent_after_b"/>
 
721
        <xsl:variable name="c">
 
722
           <xsl:choose>
 
723
             <xsl:when test="$previous_ends_with_colon = '1' or
 
724
                             $previous_indent > $d">
 
725
               <xsl:value-of select="$d"/>
 
726
             </xsl:when>
 
727
             <xsl:otherwise>
 
728
               <xsl:value-of select="$previous_indent"/>
 
729
             </xsl:otherwise>
 
730
           </xsl:choose>
 
731
        </xsl:variable>
 
732
 
 
733
        <xsl:value-of select="substring($line, $a + 1, $c - $a)"/>
 
734
        <span class="external">
 
735
           <xsl:value-of select="substring($line, $b + 1, $c - $b)"/>
 
736
        </span>
 
737
        <xsl:call-template name="munge_function_names_in_text">
 
738
          <xsl:with-param name="stripped_line"
 
739
             select="substring($line, $c + 1)"/>
 
740
        </xsl:call-template>
 
741
        <xsl:if test="not(substring($rest, $a) = '')">
 
742
          <xsl:text>&#xA;</xsl:text>
 
743
          <xsl:call-template name="print_python_line_recursively">
 
744
            <xsl:with-param name="text" select="$rest"/>
 
745
            <xsl:with-param name="a" select="$a"/>
 
746
            <xsl:with-param name="b" select="$b"/>
 
747
            <xsl:with-param name="previous_indent" select="$c"/>
 
748
            <xsl:with-param name="previous_ends_with_colon">
 
749
              <xsl:call-template name="ends_with_colon">
 
750
                <xsl:with-param name="line" select="$line"/>
 
751
                <xsl:with-param name="found_colon" select="0"/>
 
752
              </xsl:call-template>
 
753
            </xsl:with-param>
 
754
            <xsl:with-param name="is_first_line" select="0"/>
 
755
          </xsl:call-template>
 
756
        </xsl:if>
 
757
      </xsl:otherwise>
 
758
    </xsl:choose>
 
759
  </xsl:template>
 
760
 
 
761
  <!-- Print python code with internal and external styles.
 
762
       In order to conform with PEP-8 externally, we identify 2-space indents
 
763
       and an external-only 4-space indent.
 
764
       Function names that are marked with $$FunctionName/$$ have an external
 
765
       lower_with_underscore version added. -->
 
766
  <xsl:template name="print_python_code">
 
767
    <xsl:param name="text"/>
 
768
 
 
769
    <xsl:variable name="a">
 
770
       <xsl:call-template name="num_leading_spaces">
 
771
         <xsl:with-param name="text" select="."/>
 
772
         <xsl:with-param name="max_so_far" select="1000"/>
 
773
       </xsl:call-template>
 
774
    </xsl:variable>
 
775
 
 
776
    <xsl:variable name="b">
 
777
      <xsl:call-template name="code_start_index">
 
778
        <xsl:with-param name="text" select="$text"/>
 
779
        <xsl:with-param name="current_count" select="0"/>
 
780
      </xsl:call-template>
 
781
    </xsl:variable>
 
782
 
 
783
    <xsl:call-template name="print_python_line_recursively">
 
784
      <xsl:with-param name="text" select="$text"/>
 
785
      <xsl:with-param name="a" select="$a"/>
 
786
      <xsl:with-param name="b" select="$b"/>
 
787
      <xsl:with-param name="previous_indent" select="$b"/>
 
788
      <xsl:with-param name="previous_ends_with_colon" select="0"/>
 
789
      <xsl:with-param name="is_first_line" select="1"/> 
 
790
    </xsl:call-template>
 
791
  </xsl:template>
 
792
 
 
793
  <!-- Given a block of text, each line terminated by \n, and a number n,
 
794
       emits the text with the first n characters of each line
 
795
       deleted.  If strip==1, then we omit blank lines at the beginning
 
796
       and end of the text (but not the middle!) -->
 
797
  <!-- TODO(csilvers): deal well with leading tabs (treat as 8 spaces?) -->
 
798
  <xsl:template name="print_without_leading_chars">
 
799
    <xsl:param name="text"/>
 
800
    <xsl:param name="trim_count"/>
 
801
    <xsl:param name="strip"/>
 
802
    <xsl:param name="is_firstline"/>
 
803
    <!-- TODO(csilvers): deal with case text doesn't end in a newline -->
 
804
    <xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
 
805
    <xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
 
806
    <xsl:variable name="stripped_line" select="substring($line, $trim_count+1)"/>
 
807
    <xsl:choose>
 
808
      <!-- $line (or $rest) is considered empty if we'd trim the entire line -->
 
809
      <xsl:when test="($strip = '1') and ($is_firstline = '1') and
 
810
                      (string-length($line) &lt;= $trim_count)">
 
811
      </xsl:when>
 
812
      <xsl:when test="($strip = '1') and
 
813
                      (string-length($rest) &lt;= $trim_count)">
 
814
        <xsl:value-of select="$stripped_line"/>
 
815
      </xsl:when>
 
816
      <xsl:otherwise>
 
817
        <xsl:value-of select="$stripped_line"/>
 
818
        <xsl:text>&#xA;</xsl:text>
 
819
      </xsl:otherwise>
 
820
    </xsl:choose>
 
821
    <xsl:if test="not($rest='')">
 
822
      <xsl:call-template name="print_without_leading_chars">
 
823
        <xsl:with-param name="text" select="$rest"/>
 
824
        <xsl:with-param name="trim_count" select="$trim_count"/>
 
825
        <xsl:with-param name="strip" select="$strip"/>
 
826
        <xsl:with-param name="is_firstline" select="0"/>
 
827
      </xsl:call-template>
 
828
    </xsl:if>
 
829
  </xsl:template>
 
830
 
 
831
  <!-- Given a line of code, find function names that are marked with $$ /$$ and
 
832
       print out the line with the internal and external versions of the
 
833
       function names.-->
 
834
  <xsl:template name="munge_function_names_in_text">
 
835
    <xsl:param name="stripped_line"/>
 
836
    <xsl:choose>
 
837
      <xsl:when test="contains($stripped_line, '$$')">
 
838
        <xsl:value-of select="substring-before($stripped_line, '$$')"/>
 
839
        <xsl:call-template name="print_function_name">
 
840
          <xsl:with-param name="text" select="substring-after(substring-before($stripped_line, '/$$'), '$$')"/>
 
841
        </xsl:call-template>
 
842
        <xsl:call-template name="munge_function_names_in_text">
 
843
          <xsl:with-param name="stripped_line" select="substring-after($stripped_line, '/$$')"/>
 
844
        </xsl:call-template>
 
845
      </xsl:when>
 
846
      <xsl:otherwise>
 
847
        <xsl:value-of select="$stripped_line"/>
 
848
     </xsl:otherwise>
 
849
   </xsl:choose>
 
850
  </xsl:template>
 
851
 
 
852
  <!-- Given a function name, print out both the internal and external version
 
853
       of the function name in their respective spans.-->
 
854
  <xsl:template name="print_function_name">
 
855
    <xsl:param name="text"/>
 
856
      <xsl:call-template name="convert_camel_case_to_lowercase_with_under">
 
857
        <xsl:with-param name="text" select="$text"/>
 
858
      </xsl:call-template>
 
859
  </xsl:template>
 
860
 
 
861
  <!-- Given a single word of text convert it from CamelCase to
 
862
       lower_with_under.
 
863
       This means replacing each uppercase character with _ followed by the
 
864
       lowercase version except for the first character which is replaced 
 
865
       without adding the _.-->
 
866
  <xsl:template name="convert_camel_case_to_lowercase_with_under">
 
867
    <xsl:param name="text"/>
 
868
    <xsl:param name="is_recursive_call"/>
 
869
    <xsl:variable name="first_char" select="substring($text, 1, 1)"/>
 
870
    <xsl:variable name="rest" select="substring($text, 2)"/>
 
871
    <xsl:choose>
 
872
      <xsl:when test="contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $first_char)">
 
873
        <xsl:if test="$is_recursive_call='1'">
 
874
           <xsl:text>_</xsl:text>
 
875
        </xsl:if>
 
876
        <xsl:value-of select="translate($first_char, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
 
877
      </xsl:when>
 
878
      <xsl:otherwise>
 
879
        <xsl:value-of select="$first_char" />
 
880
      </xsl:otherwise>
 
881
    </xsl:choose>
 
882
    <xsl:if test="not($rest='')">
 
883
      <xsl:call-template name="convert_camel_case_to_lowercase_with_under">
 
884
        <xsl:with-param name="text" select="$rest"/>
 
885
        <xsl:with-param name="is_recursive_call" select="1"/>
 
886
      </xsl:call-template>
 
887
    </xsl:if>
 
888
  </xsl:template>
 
889
</xsl:stylesheet>
 
890