~plane1/maus/devel_624

« back to all changes in this revision

Viewing changes to third_party/google-styleguide/.svn/text-base/styleguide.xsl.svn-base

  • Committer: tunnell
  • Date: 2010-09-30 13:56:05 UTC
  • Revision ID: tunnell@itchy-20100930135605-wxbkfgy75p0sndk3
add third party

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
    <xsl:value-of select="translate($sectionname,' ()#','____')"/>
 
453
  </xsl:template>
 
454
 
 
455
  <!-- Given text, evaluates to the number of leading spaces. -->
 
456
  <!-- TODO(csilvers): deal well with leading tabs (treat as 8 spaces?) -->
 
457
  <xsl:template name="num_leading_spaces_one_line">
 
458
    <xsl:param name="text"/>
 
459
    <xsl:param name="current_count"/>
 
460
    <xsl:choose>
 
461
      <xsl:when test="starts-with($text, ' ')">
 
462
        <xsl:call-template name="num_leading_spaces_one_line">
 
463
          <xsl:with-param name="text" select="substring($text, 2)"/>
 
464
          <xsl:with-param name="current_count" select="$current_count + 1"/>
 
465
        </xsl:call-template>
 
466
      </xsl:when>
 
467
      <xsl:otherwise>
 
468
        <xsl:value-of select="$current_count"/>
 
469
      </xsl:otherwise>
 
470
    </xsl:choose>
 
471
  </xsl:template>
 
472
 
 
473
  <!-- Given a block of text, each line terminated by \n, evaluates to
 
474
       the indentation-level of that text; that is, the largest number
 
475
       n such that every non-blank line starts with at least n spaces. -->
 
476
  <xsl:template name="num_leading_spaces">
 
477
    <xsl:param name="text"/>
 
478
    <xsl:param name="max_so_far"/>
 
479
    <!-- TODO(csilvers): deal with case text doesn't end in a newline -->
 
480
    <xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
 
481
    <xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
 
482
    <xsl:variable name="num_spaces_this_line">
 
483
      <xsl:choose>
 
484
        <xsl:when test="$line=''">
 
485
           <xsl:value-of select="$max_so_far"/>
 
486
        </xsl:when>
 
487
        <xsl:otherwise>
 
488
          <xsl:call-template name="num_leading_spaces_one_line">
 
489
            <xsl:with-param name="text" select="$line"/>
 
490
            <xsl:with-param name="current_count" select="0"/>
 
491
          </xsl:call-template>
 
492
        </xsl:otherwise>
 
493
      </xsl:choose>
 
494
    </xsl:variable>
 
495
    <xsl:variable name="new_max_so_far">
 
496
       <xsl:choose>
 
497
         <xsl:when test="$num_spaces_this_line &lt; $max_so_far">
 
498
           <xsl:value-of select="$num_spaces_this_line"/>
 
499
         </xsl:when>
 
500
         <xsl:otherwise>
 
501
           <xsl:value-of select="$max_so_far"/>
 
502
         </xsl:otherwise>
 
503
       </xsl:choose>
 
504
    </xsl:variable>
 
505
    <!-- now check if we're on the last line, and if not, recurse -->
 
506
    <xsl:if test="$rest=''">
 
507
      <xsl:value-of select="$new_max_so_far"/>
 
508
    </xsl:if>
 
509
    <xsl:if test="not($rest='')">
 
510
      <xsl:call-template name="num_leading_spaces">
 
511
        <xsl:with-param name="text" select="$rest"/>
 
512
        <xsl:with-param name="max_so_far" select="$new_max_so_far"/>
 
513
      </xsl:call-template>
 
514
    </xsl:if>
 
515
  </xsl:template>
 
516
 
 
517
  <!-- Given text, determine the starting position of code.
 
518
       This similar to num_leading_spaces_one_line but treats "Yes:" and "No:" 
 
519
       as spaces. Also, if there is no code on the first line, it searches 
 
520
       subsequent lines until a non-empty line is found.
 
521
       Used to find the start of code in snippets like:
 
522
       Yes: if(foo):
 
523
       No : if(foo):
 
524
       As well as:
 
525
       Yes:
 
526
         if (foo):
 
527
  -->
 
528
  <xsl:template name="code_start_index">
 
529
    <xsl:param name="text"/>
 
530
    <xsl:param name="current_count"/>
 
531
    <xsl:choose>
 
532
      <xsl:when test="starts-with($text, ' ')">
 
533
        <xsl:call-template name="code_start_index">
 
534
          <xsl:with-param name="text" select="substring($text, 2)"/>
 
535
          <xsl:with-param name="current_count" select="$current_count + 1"/>
 
536
        </xsl:call-template>
 
537
      </xsl:when>
 
538
      <xsl:when test="starts-with($text, 'Yes:')">
 
539
        <xsl:call-template name="code_start_index">
 
540
          <xsl:with-param name="text" select="substring($text, 5)"/>
 
541
          <xsl:with-param name="current_count" select="$current_count + 4"/>
 
542
        </xsl:call-template>
 
543
      </xsl:when>
 
544
      <xsl:when test="starts-with($text, 'No:')">
 
545
        <xsl:call-template name="code_start_index">
 
546
          <xsl:with-param name="text" select="substring($text, 4)"/>
 
547
          <xsl:with-param name="current_count" select="$current_count + 3"/>
 
548
        </xsl:call-template>
 
549
      </xsl:when>
 
550
      <!-- This is only reached if the first line is entirely whitespace or 
 
551
           contains nothing but "Yes:" or "No:"-->
 
552
      <xsl:when test="starts-with($text, '&#xA;')">
 
553
        <xsl:call-template name="code_start_index">
 
554
          <xsl:with-param name="text" select="substring($text, 2)"/>
 
555
          <xsl:with-param name="current_count" select="0"/>
 
556
        </xsl:call-template>
 
557
      </xsl:when>
 
558
      <xsl:otherwise>
 
559
        <xsl:value-of select="$current_count"/>
 
560
      </xsl:otherwise>
 
561
    </xsl:choose>
 
562
  </xsl:template>
 
563
 
 
564
  <!-- Helper for ends_with_colon. Determine whether the given line is nothing
 
565
       but spaces and python-style comments. -->
 
566
  <xsl:template name="is_blank_or_comment">
 
567
    <xsl:param name="line"/>
 
568
    <xsl:choose>
 
569
      <xsl:when test="$line = ''">
 
570
        <xsl:value-of select="1"/>
 
571
      </xsl:when>
 
572
      <xsl:when test="starts-with($line, '&#xA;')">
 
573
        <xsl:value-of select="1"/>
 
574
      </xsl:when>
 
575
      <xsl:when test="starts-with($line, '#')">
 
576
        <xsl:value-of select="1"/>
 
577
      </xsl:when>
 
578
      <xsl:when test="starts-with($line, ' ')">
 
579
        <xsl:call-template name="is_blank_or_comment">
 
580
          <xsl:with-param name="line" select="substring($line, 2)"/>
 
581
        </xsl:call-template>
 
582
      </xsl:when>
 
583
      <xsl:otherwise>
 
584
        <xsl:value-of select="0"/>
 
585
      </xsl:otherwise>
 
586
    </xsl:choose>
 
587
  </xsl:template>
 
588
 
 
589
  <!-- Determine whether the given line ends with a colon. Note that Python
 
590
       style comments are ignored so the following lines return True:
 
591
       - def foo():
 
592
       - def foo():  # Bar
 
593
       - if(foo):
 
594
 
 
595
       But some code may confuse this function. For example the following are
 
596
       also consider to "end_with_colon" even though they don't for Python
 
597
       - foo(":  #")
 
598
       - foo() # No need for :
 
599
  -->
 
600
  <xsl:template name="ends_with_colon">
 
601
    <xsl:param name="line"/>
 
602
    <xsl:param name="found_colon"/>
 
603
    <xsl:choose>
 
604
      <xsl:when test="$line = ''">
 
605
        <xsl:value-of select="$found_colon"/>
 
606
      </xsl:when>
 
607
      <xsl:when test="starts-with($line, '&#xA;')">
 
608
        <xsl:value-of select="$found_colon"/>
 
609
      </xsl:when>
 
610
      <xsl:when test="starts-with($line, ' ')">
 
611
        <xsl:call-template name="ends_with_colon">
 
612
          <xsl:with-param name="line" select="substring($line, 2)"/>
 
613
          <xsl:with-param name="found_colon" select="$found_colon"/>
 
614
        </xsl:call-template>
 
615
      </xsl:when>
 
616
      <xsl:when test="starts-with($line, ':')">
 
617
        <xsl:variable name="rest_is_comment">
 
618
          <xsl:call-template name="is_blank_or_comment">
 
619
            <xsl:with-param name="line" select="substring($line, 2)"/>
 
620
          </xsl:call-template>
 
621
        </xsl:variable>
 
622
        <xsl:choose>
 
623
          <xsl:when test="$rest_is_comment = '1'">
 
624
            <xsl:value-of select="1"/>
 
625
          </xsl:when>
 
626
          <xsl:otherwise>
 
627
            <xsl:call-template name="ends_with_colon">
 
628
              <xsl:with-param name="line" select="substring($line, 2)"/>
 
629
              <xsl:with-param name="found_colon" select="0"/>
 
630
            </xsl:call-template>
 
631
          </xsl:otherwise>
 
632
        </xsl:choose>
 
633
      </xsl:when>
 
634
      <xsl:otherwise>
 
635
        <xsl:call-template name="ends_with_colon">
 
636
          <xsl:with-param name="line" select="substring($line, 2)"/>
 
637
          <xsl:with-param name="found_colon" select="0"/>
 
638
        </xsl:call-template>
 
639
      </xsl:otherwise>
 
640
    </xsl:choose>
 
641
  </xsl:template>
 
642
 
 
643
  <!-- Prints one line of python code with proper indent and calls itself
 
644
       recursively for the rest of the text.
 
645
       This template uses "a", "b", "c" and "d" to refer to four key column
 
646
       numbers. They are:
 
647
       - a: the indentation common to all lines in a code snippet. This is
 
648
            stripped out to allow for cleaner code in the xml.
 
649
       - b: the indentation of the most out-dented line of code. This is
 
650
            different from "a" when code is labelled with "Yes:" or "No:"
 
651
       - c: the indentation of the current python block, in other words, the
 
652
            indentation of the first line of this block, which is the
 
653
            indentation of the last line we saw that ended with a colon.
 
654
       - d: the "total" indentation of the line, ignorng possible "Yes:" or
 
655
            "No:" text on the line.
 
656
 
 
657
       For example, for the last line of the following code snippet, the
 
658
       positions of a, b, c and d are indicated below:
 
659
           Yes: def Foo():
 
660
                  if bar():
 
661
                    a += 1
 
662
                    baz()
 
663
           a    b c d
 
664
 
 
665
       The algorithm is:
 
666
       1) Split the text into first line and the rest. Note that the
 
667
          substring-before function is supposed to handle the case where the
 
668
          character is not present in the string but does not so we
 
669
          automatically ignore the last line of the snippet which is always
 
670
          empty (the closing snippet tag). This is consistent with the
 
671
          behavior or print_without_leading_chars.
 
672
       2) If the current is empty (only whitespace), print newline and call
 
673
          itself recursively on the rest of the text with the rest of the
 
674
          parameters unchanged.
 
675
       3) Otherwise, measure "d"
 
676
       4) Measure "c" by taking:
 
677
          - the value of "d" if the previous line ended with a colon or the
 
678
            current line is outdented compare to the previous line
 
679
          - the indent of the previous line otherwise
 
680
       5) Print line[a:c] (Note that we ignore line[0:a])
 
681
       6) Print line[b:c] in an external span (in order to double the block
 
682
          indent in external code).
 
683
       7) Print line[c:<end>] with function names processed to produce both 
 
684
          internal and external names.
 
685
       8) If there are more lines, recurse.
 
686
  -->
 
687
  <xsl:template name="print_python_line_recursively">
 
688
    <xsl:param name="text"/>
 
689
    <xsl:param name="a"/>
 
690
    <xsl:param name="b"/>
 
691
    <xsl:param name="previous_indent"/>
 
692
    <xsl:param name="previous_ends_with_colon"/>
 
693
    <xsl:param name="is_first_line"/>
 
694
    <xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
 
695
    <xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
 
696
    <xsl:choose>
 
697
      <xsl:when test="substring($line, $b) = '' and not($rest = '')">
 
698
        <xsl:if test="not($is_first_line = '1')">
 
699
          <xsl:text>&#xA;</xsl:text>
 
700
        </xsl:if>
 
701
        <xsl:call-template name="print_python_line_recursively">
 
702
          <xsl:with-param name="text" select="$rest"/>
 
703
          <xsl:with-param name="a" select="$a"/>
 
704
          <xsl:with-param name="b" select="$b"/>
 
705
          <xsl:with-param name="previous_indent" select="$previous_indent"/>
 
706
          <xsl:with-param name="previous_ends_with_colon"
 
707
                          select="$previous_ends_with_colon"/>
 
708
          <xsl:with-param name="is_first_line" select="0"/>
 
709
        </xsl:call-template>
 
710
      </xsl:when>
 
711
      <xsl:otherwise>
 
712
        <xsl:variable name="indent_after_b">
 
713
          <xsl:call-template name="num_leading_spaces_one_line">
 
714
            <xsl:with-param name="text" select="substring($line, $b + 1)"/>
 
715
            <xsl:with-param name="current_count" select="0"/>
 
716
          </xsl:call-template>
 
717
        </xsl:variable>
 
718
        <xsl:variable name="d" select="$b + $indent_after_b"/>
 
719
        <xsl:variable name="c">
 
720
           <xsl:choose>
 
721
             <xsl:when test="$previous_ends_with_colon = '1' or
 
722
                             $previous_indent > $d">
 
723
               <xsl:value-of select="$d"/>
 
724
             </xsl:when>
 
725
             <xsl:otherwise>
 
726
               <xsl:value-of select="$previous_indent"/>
 
727
             </xsl:otherwise>
 
728
           </xsl:choose>
 
729
        </xsl:variable>
 
730
 
 
731
        <xsl:value-of select="substring($line, $a + 1, $c - $a)"/>
 
732
        <span class="external">
 
733
           <xsl:value-of select="substring($line, $b + 1, $c - $b)"/>
 
734
        </span>
 
735
        <xsl:call-template name="munge_function_names_in_text">
 
736
          <xsl:with-param name="stripped_line"
 
737
             select="substring($line, $c + 1)"/>
 
738
        </xsl:call-template>
 
739
        <xsl:if test="not(substring($rest, $a) = '')">
 
740
          <xsl:text>&#xA;</xsl:text>
 
741
          <xsl:call-template name="print_python_line_recursively">
 
742
            <xsl:with-param name="text" select="$rest"/>
 
743
            <xsl:with-param name="a" select="$a"/>
 
744
            <xsl:with-param name="b" select="$b"/>
 
745
            <xsl:with-param name="previous_indent" select="$c"/>
 
746
            <xsl:with-param name="previous_ends_with_colon">
 
747
              <xsl:call-template name="ends_with_colon">
 
748
                <xsl:with-param name="line" select="$line"/>
 
749
                <xsl:with-param name="found_colon" select="0"/>
 
750
              </xsl:call-template>
 
751
            </xsl:with-param>
 
752
            <xsl:with-param name="is_first_line" select="0"/>
 
753
          </xsl:call-template>
 
754
        </xsl:if>
 
755
      </xsl:otherwise>
 
756
    </xsl:choose>
 
757
  </xsl:template>
 
758
 
 
759
  <!-- Print python code with internal and external styles.
 
760
       In order to conform with PEP-8 externally, we identify 2-space indents
 
761
       and an external-only 4-space indent.
 
762
       Function names that are marked with $$FunctionName/$$ have an external
 
763
       lower_with_underscore version added. -->
 
764
  <xsl:template name="print_python_code">
 
765
    <xsl:param name="text"/>
 
766
 
 
767
    <xsl:variable name="a">
 
768
       <xsl:call-template name="num_leading_spaces">
 
769
         <xsl:with-param name="text" select="."/>
 
770
         <xsl:with-param name="max_so_far" select="1000"/>
 
771
       </xsl:call-template>
 
772
    </xsl:variable>
 
773
 
 
774
    <xsl:variable name="b">
 
775
      <xsl:call-template name="code_start_index">
 
776
        <xsl:with-param name="text" select="$text"/>
 
777
        <xsl:with-param name="current_count" select="0"/>
 
778
      </xsl:call-template>
 
779
    </xsl:variable>
 
780
 
 
781
    <xsl:call-template name="print_python_line_recursively">
 
782
      <xsl:with-param name="text" select="$text"/>
 
783
      <xsl:with-param name="a" select="$a"/>
 
784
      <xsl:with-param name="b" select="$b"/>
 
785
      <xsl:with-param name="previous_indent" select="$b"/>
 
786
      <xsl:with-param name="previous_ends_with_colon" select="0"/>
 
787
      <xsl:with-param name="is_first_line" select="1"/> 
 
788
    </xsl:call-template>
 
789
  </xsl:template>
 
790
 
 
791
  <!-- Given a block of text, each line terminated by \n, and a number n,
 
792
       emits the text with the first n characters of each line
 
793
       deleted.  If strip==1, then we omit blank lines at the beginning
 
794
       and end of the text (but not the middle!) -->
 
795
  <!-- TODO(csilvers): deal well with leading tabs (treat as 8 spaces?) -->
 
796
  <xsl:template name="print_without_leading_chars">
 
797
    <xsl:param name="text"/>
 
798
    <xsl:param name="trim_count"/>
 
799
    <xsl:param name="strip"/>
 
800
    <xsl:param name="is_firstline"/>
 
801
    <!-- TODO(csilvers): deal with case text doesn't end in a newline -->
 
802
    <xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
 
803
    <xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
 
804
    <xsl:variable name="stripped_line" select="substring($line, $trim_count+1)"/>
 
805
    <xsl:choose>
 
806
      <!-- $line (or $rest) is considered empty if we'd trim the entire line -->
 
807
      <xsl:when test="($strip = '1') and ($is_firstline = '1') and
 
808
                      (string-length($line) &lt;= $trim_count)">
 
809
      </xsl:when>
 
810
      <xsl:when test="($strip = '1') and
 
811
                      (string-length($rest) &lt;= $trim_count)">
 
812
        <xsl:value-of select="$stripped_line"/>
 
813
      </xsl:when>
 
814
      <xsl:otherwise>
 
815
        <xsl:value-of select="$stripped_line"/>
 
816
        <xsl:text>&#xA;</xsl:text>
 
817
      </xsl:otherwise>
 
818
    </xsl:choose>
 
819
    <xsl:if test="not($rest='')">
 
820
      <xsl:call-template name="print_without_leading_chars">
 
821
        <xsl:with-param name="text" select="$rest"/>
 
822
        <xsl:with-param name="trim_count" select="$trim_count"/>
 
823
        <xsl:with-param name="strip" select="$strip"/>
 
824
        <xsl:with-param name="is_firstline" select="0"/>
 
825
      </xsl:call-template>
 
826
    </xsl:if>
 
827
  </xsl:template>
 
828
 
 
829
  <!-- Given a line of code, find function names that are marked with $$ /$$ and
 
830
       print out the line with the internal and external versions of the
 
831
       function names.-->
 
832
  <xsl:template name="munge_function_names_in_text">
 
833
    <xsl:param name="stripped_line"/>
 
834
    <xsl:choose>
 
835
      <xsl:when test="contains($stripped_line, '$$')">
 
836
        <xsl:value-of select="substring-before($stripped_line, '$$')"/>
 
837
        <xsl:call-template name="print_function_name">
 
838
          <xsl:with-param name="text" select="substring-after(substring-before($stripped_line, '/$$'), '$$')"/>
 
839
        </xsl:call-template>
 
840
        <xsl:call-template name="munge_function_names_in_text">
 
841
          <xsl:with-param name="stripped_line" select="substring-after($stripped_line, '/$$')"/>
 
842
        </xsl:call-template>
 
843
      </xsl:when>
 
844
      <xsl:otherwise>
 
845
        <xsl:value-of select="$stripped_line"/>
 
846
     </xsl:otherwise>
 
847
   </xsl:choose>
 
848
  </xsl:template>
 
849
 
 
850
  <!-- Given a function name, print out both the internal and external version
 
851
       of the function name in their respective spans.-->
 
852
  <xsl:template name="print_function_name">
 
853
    <xsl:param name="text"/>
 
854
      <xsl:call-template name="convert_camel_case_to_lowercase_with_under">
 
855
        <xsl:with-param name="text" select="$text"/>
 
856
      </xsl:call-template>
 
857
  </xsl:template>
 
858
 
 
859
  <!-- Given a single word of text convert it from CamelCase to
 
860
       lower_with_under.
 
861
       This means replacing each uppercase character with _ followed by the
 
862
       lowercase version except for the first character which is replaced 
 
863
       without adding the _.-->
 
864
  <xsl:template name="convert_camel_case_to_lowercase_with_under">
 
865
    <xsl:param name="text"/>
 
866
    <xsl:param name="is_recursive_call"/>
 
867
    <xsl:variable name="first_char" select="substring($text, 1, 1)"/>
 
868
    <xsl:variable name="rest" select="substring($text, 2)"/>
 
869
    <xsl:choose>
 
870
      <xsl:when test="contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $first_char)">
 
871
        <xsl:if test="$is_recursive_call='1'">
 
872
           <xsl:text>_</xsl:text>
 
873
        </xsl:if>
 
874
        <xsl:value-of select="translate($first_char, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
 
875
      </xsl:when>
 
876
      <xsl:otherwise>
 
877
        <xsl:value-of select="$first_char" />
 
878
      </xsl:otherwise>
 
879
    </xsl:choose>
 
880
    <xsl:if test="not($rest='')">
 
881
      <xsl:call-template name="convert_camel_case_to_lowercase_with_under">
 
882
        <xsl:with-param name="text" select="$rest"/>
 
883
        <xsl:with-param name="is_recursive_call" select="1"/>
 
884
      </xsl:call-template>
 
885
    </xsl:if>
 
886
  </xsl:template>
 
887
</xsl:stylesheet>
 
888