Patchwork [1,of,4,V3] hgweb: code selection without line numbers in file code view

login
register
mail settings
Submitter Alexander Plavin
Date June 1, 2013, 6:09 p.m.
Message ID <39a32bcfb6581479afb5.1370110191@debian-alexander.dolgopa>
Download mbox | patch
Permalink /patch/1692/
State Changes Requested, archived
Headers show

Comments

Alexander Plavin - June 1, 2013, 6:09 p.m.
# HG changeset patch
# User Alexander Plavin <me@aplavin.ru>
# Date 1369988709 -14400
#      Fri May 31 12:25:09 2013 +0400
# Node ID 39a32bcfb6581479afb5afc761e8ebcf5f41fbc2
# Parent  1bef6f99a12d9062e737bb623da627719a3987e6
hgweb: code selection without line numbers in file code view

File code is presented as HTML ordered list, so that line numbers
are not selected with the code itself.
Long lines are being wrapped for convenience.
Matt Mackall - June 1, 2013, 9:26 p.m.
On Sat, 2013-06-01 at 22:09 +0400, Alexander Plavin wrote:
> # HG changeset patch
> # User Alexander Plavin <me@aplavin.ru>
> # Date 1369988709 -14400
> #      Fri May 31 12:25:09 2013 +0400
> # Node ID 39a32bcfb6581479afb5afc761e8ebcf5f41fbc2
> # Parent  1bef6f99a12d9062e737bb623da627719a3987e6
> hgweb: code selection without line numbers in file code view
> 
> File code is presented as HTML ordered list, so that line numbers
> are not selected with the code itself.
> Long lines are being wrapped for convenience.
> 
> diff -r 1bef6f99a12d -r 39a32bcfb658 mercurial/templatefilters.py
> --- a/mercurial/templatefilters.py	Thu May 23 17:53:38 2013 -0500
> +++ b/mercurial/templatefilters.py	Fri May 31 12:25:09 2013 +0400
> @@ -299,6 +299,9 @@
>      """:shortdate: Date. Returns a date like "2006-09-18"."""
>      return util.shortdate(text)
>  
> +def spaceifempty(text):
> +    return text or ' '

a) the template language has if()
b) it's not clear why this hack is needed
c) this is three or four patches

Patch

diff -r 1bef6f99a12d -r 39a32bcfb658 mercurial/templatefilters.py
--- a/mercurial/templatefilters.py	Thu May 23 17:53:38 2013 -0500
+++ b/mercurial/templatefilters.py	Fri May 31 12:25:09 2013 +0400
@@ -299,6 +299,9 @@ 
     """:shortdate: Date. Returns a date like "2006-09-18"."""
     return util.shortdate(text)
 
+def spaceifempty(text):
+    return text or ' '
+
 def stringescape(text):
     return text.encode('string_escape')
 
@@ -381,6 +384,7 @@ 
     "short": short,
     "shortbisect": shortbisect,
     "shortdate": shortdate,
+    "spaceifempty": spaceifempty,
     "stringescape": stringescape,
     "stringify": stringify,
     "strip": strip,
diff -r 1bef6f99a12d -r 39a32bcfb658 mercurial/templates/paper/filerevision.tmpl
--- a/mercurial/templates/paper/filerevision.tmpl	Thu May 23 17:53:38 2013 -0500
+++ b/mercurial/templates/paper/filerevision.tmpl	Fri May 31 12:25:09 2013 +0400
@@ -67,8 +67,10 @@ 
 </table>
 
 <div class="overflow">
-<div class="sourcefirst"> line source</div>
+<div class="sourcefirst"></div>
+<ol class="sourcelines">
 {text%fileline}
+</ol>
 <div class="sourcelast"></div>
 </div>
 </div>
diff -r 1bef6f99a12d -r 39a32bcfb658 mercurial/templates/paper/footer.tmpl
--- a/mercurial/templates/paper/footer.tmpl	Thu May 23 17:53:38 2013 -0500
+++ b/mercurial/templates/paper/footer.tmpl	Fri May 31 12:25:09 2013 +0400
@@ -1,4 +1,7 @@ 
-<script type="text/javascript">process_dates()</script>
+<script type="text/javascript">
+process_dates();
+addOnclickSource();
+</script>
 {motd}
 
 </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 mercurial/templates/paper/map
--- a/mercurial/templates/paper/map	Thu May 23 17:53:38 2013 -0500
+++ b/mercurial/templates/paper/map	Fri May 31 12:25:09 2013 +0400
@@ -72,7 +72,7 @@ 
 filecomparison = filecomparison.tmpl
 filelog = filelog.tmpl
 fileline = '
-  <div class="parity{parity} source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
+  <li class="parity{parity} source" id="{lineid}"><div>{line|escape|spaceifempty}</div></li>'
 filelogentry = filelogentry.tmpl
 
 annotateline = '
diff -r 1bef6f99a12d -r 39a32bcfb658 mercurial/templates/static/mercurial.js
--- a/mercurial/templates/static/mercurial.js	Thu May 23 17:53:38 2013 -0500
+++ b/mercurial/templates/static/mercurial.js	Fri May 31 12:25:09 2013 +0400
@@ -3,6 +3,7 @@ 
 // Rendering of branch DAGs on the client side
 // Display of elapsed time
 // Show or hide diffstat
+// Link to a line when clicking on it
 //
 // Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
 // Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
@@ -274,3 +275,21 @@ 
 	document.getElementById('diffstatdetails').style.display = 'none';
 	document.getElementById('diffstatexpand').style.display = 'inline';
 }
+
+
+function addOnclickSource() {
+    var nodes = document.querySelectorAll('ol.sourcelines');
+
+    clickHandler = function (event) {
+        if (event.offsetX < 0 || event.target.tagName == 'LI') {
+            var id = event.target.id || event.target.parentNode.id;
+            if (id) {
+                window.location.hash = '#' + id;
+            }
+        }
+    };
+
+    for (i = 0; i < nodes.length; i++) {
+        nodes[i].onclick = clickHandler;
+    }
+}
diff -r 1bef6f99a12d -r 39a32bcfb658 mercurial/templates/static/style-paper.css
--- a/mercurial/templates/static/style-paper.css	Thu May 23 17:53:38 2013 -0500
+++ b/mercurial/templates/static/style-paper.css	Fri May 31 12:25:09 2013 +0400
@@ -198,10 +198,9 @@ 
 .bigtable td.annotate { font-size: smaller; }
 .bigtable td.source { font-size: inherit; }
 
-.source, .sourcefirst, .sourcelast {
+.source {
   font-family: monospace;
-  white-space: pre;
-  padding: 1px 4px;
+  white-space: pre-wrap;
   font-size: 90%;
 }
 .sourcefirst { border-bottom: 1px solid #999; font-weight: bold; }
@@ -209,6 +208,39 @@ 
 .source a { color: #999; font-size: smaller; font-family: monospace;}
 .bottomline { border-bottom: 1px solid #999; }
 
+div.source, td.source { padding: 1px 4px; }
+
+ol {
+  background-color: #eee;
+  font-size: 90%;
+  margin: 0;
+  padding-left: 50px;
+}
+
+li.source {
+  -moz-user-select: -moz-none;
+  -khtml-user-select: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  color: #999;
+  padding: 0 5px;
+}
+
+li.source div {
+  -moz-user-select: text;
+  -khtml-user-select: text;
+  -webkit-user-select: text;
+  -ms-user-select: text;
+  user-select: text;
+  padding: 1px 5px;
+  border-left: 1px solid #ccc;
+  margin: 0 0 0 -7px;
+  position: relative;
+  color: #000;
+  font-size: 111%;
+}
+
 .fileline { font-family: monospace; }
 .fileline img { border: 0; }
 
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-help.t
--- a/tests/test-help.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-help.t	Fri May 31 12:25:09 2013 +0400
@@ -1456,7 +1456,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -1622,7 +1625,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -1818,7 +1824,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -1913,7 +1922,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-hgweb-commands.t
--- a/tests/test-hgweb-commands.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-hgweb-commands.t	Fri May 31 12:25:09 2013 +0400
@@ -338,7 +338,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -465,7 +468,10 @@ 
   
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -557,7 +563,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -667,16 +676,21 @@ 
   </table>
   
   <div class="overflow">
-  <div class="sourcefirst"> line source</div>
+  <div class="sourcefirst"></div>
+  <ol class="sourcelines">
   
-  <div class="parity0 source"><a href="#l1" id="l1">     1</a> foo
-  </div>
+  <li class="parity0 source" id="l1"><div>foo
+  </div></li>
+  </ol>
   <div class="sourcelast"></div>
   </div>
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-hgweb-descend-empties.t
--- a/tests/test-hgweb-descend-empties.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-hgweb-descend-empties.t	Fri May 31 12:25:09 2013 +0400
@@ -132,7 +132,10 @@ 
   </table>
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-hgweb-diffs.t
--- a/tests/test-hgweb-diffs.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-hgweb-diffs.t	Fri May 31 12:25:09 2013 +0400
@@ -157,7 +157,10 @@ 
   
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -282,7 +285,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -420,7 +426,10 @@ 
   
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -545,7 +554,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -663,7 +675,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -789,7 +804,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -913,7 +931,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-hgweb-empty.t
--- a/tests/test-hgweb-empty.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-hgweb-empty.t	Fri May 31 12:25:09 2013 +0400
@@ -91,7 +91,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -184,7 +187,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -328,7 +334,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -401,7 +410,10 @@ 
   </table>
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-hgweb-filelog.t
--- a/tests/test-hgweb-filelog.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-hgweb-filelog.t	Fri May 31 12:25:09 2013 +0400
@@ -207,7 +207,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -314,7 +317,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -416,7 +422,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -518,7 +527,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -583,7 +595,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-hgweb-removed.t
--- a/tests/test-hgweb-removed.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-hgweb-removed.t	Fri May 31 12:25:09 2013 +0400
@@ -126,7 +126,10 @@ 
   
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -226,7 +229,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-hgweb.t
--- a/tests/test-hgweb.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-hgweb.t	Fri May 31 12:25:09 2013 +0400
@@ -96,7 +96,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -186,7 +189,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -290,7 +296,10 @@ 
   </table>
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-hgwebdir.t
--- a/tests/test-hgwebdir.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-hgwebdir.t	Fri May 31 12:25:09 2013 +0400
@@ -655,7 +655,10 @@ 
   </table>
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -722,7 +725,10 @@ 
   </table>
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -1082,7 +1088,10 @@ 
   </table>
   </div>
   </div>
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
diff -r 1bef6f99a12d -r 39a32bcfb658 tests/test-highlight.t
--- a/tests/test-highlight.t	Thu May 23 17:53:38 2013 -0500
+++ b/tests/test-highlight.t	Fri May 31 12:25:09 2013 +0400
@@ -136,46 +136,51 @@ 
   </table>
   
   <div class="overflow">
-  <div class="sourcefirst"> line source</div>
+  <div class="sourcefirst"></div>
+  <ol class="sourcelines">
   
-  <div class="parity0 source"><a href="#l1" id="l1">     1</a> <span class="c">#!/usr/bin/env python</span></div>
-  <div class="parity1 source"><a href="#l2" id="l2">     2</a> </div>
-  <div class="parity0 source"><a href="#l3" id="l3">     3</a> <span class="sd">&quot;&quot;&quot;Fun with generators. Corresponding Haskell implementation:</span></div>
-  <div class="parity1 source"><a href="#l4" id="l4">     4</a> </div>
-  <div class="parity0 source"><a href="#l5" id="l5">     5</a> <span class="sd">primes = 2 : sieve [3, 5..]</span></div>
-  <div class="parity1 source"><a href="#l6" id="l6">     6</a> <span class="sd">    where sieve (p:ns) = p : sieve [n | n &lt;- ns, mod n p /= 0]</span></div>
-  <div class="parity0 source"><a href="#l7" id="l7">     7</a> <span class="sd">&quot;&quot;&quot;</span></div>
-  <div class="parity1 source"><a href="#l8" id="l8">     8</a> </div>
-  <div class="parity0 source"><a href="#l9" id="l9">     9</a> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></div>
-  <div class="parity1 source"><a href="#l10" id="l10">    10</a> </div>
-  <div class="parity0 source"><a href="#l11" id="l11">    11</a> <span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></div>
-  <div class="parity1 source"><a href="#l12" id="l12">    12</a>     <span class="sd">&quot;&quot;&quot;Generate all primes.&quot;&quot;&quot;</span></div>
-  <div class="parity0 source"><a href="#l13" id="l13">    13</a>     <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></div>
-  <div class="parity1 source"><a href="#l14" id="l14">    14</a>         <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></div>
-  <div class="parity0 source"><a href="#l15" id="l15">    15</a>         <span class="c"># It is important to yield *here* in order to stop the</span></div>
-  <div class="parity1 source"><a href="#l16" id="l16">    16</a>         <span class="c"># infinite recursion.</span></div>
-  <div class="parity0 source"><a href="#l17" id="l17">    17</a>         <span class="kn">yield</span> <span class="n">p</span></div>
-  <div class="parity1 source"><a href="#l18" id="l18">    18</a>         <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></div>
-  <div class="parity0 source"><a href="#l19" id="l19">    19</a>         <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></div>
-  <div class="parity1 source"><a href="#l20" id="l20">    20</a>             <span class="kn">yield</span> <span class="n">n</span></div>
-  <div class="parity0 source"><a href="#l21" id="l21">    21</a> </div>
-  <div class="parity1 source"><a href="#l22" id="l22">    22</a>     <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></div>
-  <div class="parity0 source"><a href="#l23" id="l23">    23</a>     <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></div>
-  <div class="parity1 source"><a href="#l24" id="l24">    24</a> </div>
-  <div class="parity0 source"><a href="#l25" id="l25">    25</a> <span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span></div>
-  <div class="parity1 source"><a href="#l26" id="l26">    26</a>     <span class="kn">import</span> <span class="nn">sys</span></div>
-  <div class="parity0 source"><a href="#l27" id="l27">    27</a>     <span class="kn">try</span><span class="p">:</span></div>
-  <div class="parity1 source"><a href="#l28" id="l28">    28</a>         <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></div>
-  <div class="parity0 source"><a href="#l29" id="l29">    29</a>     <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></div>
-  <div class="parity1 source"><a href="#l30" id="l30">    30</a>         <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span></div>
-  <div class="parity0 source"><a href="#l31" id="l31">    31</a>     <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></div>
-  <div class="parity1 source"><a href="#l32" id="l32">    32</a>     <span class="kn">print</span> <span class="s">&quot;The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></div>
+  <li class="parity0 source" id="l1"><div><span class="c">#!/usr/bin/env python</span></div></li>
+  <li class="parity1 source" id="l2"><div> </div></li>
+  <li class="parity0 source" id="l3"><div><span class="sd">&quot;&quot;&quot;Fun with generators. Corresponding Haskell implementation:</span></div></li>
+  <li class="parity1 source" id="l4"><div> </div></li>
+  <li class="parity0 source" id="l5"><div><span class="sd">primes = 2 : sieve [3, 5..]</span></div></li>
+  <li class="parity1 source" id="l6"><div><span class="sd">    where sieve (p:ns) = p : sieve [n | n &lt;- ns, mod n p /= 0]</span></div></li>
+  <li class="parity0 source" id="l7"><div><span class="sd">&quot;&quot;&quot;</span></div></li>
+  <li class="parity1 source" id="l8"><div> </div></li>
+  <li class="parity0 source" id="l9"><div><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></div></li>
+  <li class="parity1 source" id="l10"><div> </div></li>
+  <li class="parity0 source" id="l11"><div><span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></div></li>
+  <li class="parity1 source" id="l12"><div>    <span class="sd">&quot;&quot;&quot;Generate all primes.&quot;&quot;&quot;</span></div></li>
+  <li class="parity0 source" id="l13"><div>    <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></div></li>
+  <li class="parity1 source" id="l14"><div>        <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></div></li>
+  <li class="parity0 source" id="l15"><div>        <span class="c"># It is important to yield *here* in order to stop the</span></div></li>
+  <li class="parity1 source" id="l16"><div>        <span class="c"># infinite recursion.</span></div></li>
+  <li class="parity0 source" id="l17"><div>        <span class="kn">yield</span> <span class="n">p</span></div></li>
+  <li class="parity1 source" id="l18"><div>        <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></div></li>
+  <li class="parity0 source" id="l19"><div>        <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></div></li>
+  <li class="parity1 source" id="l20"><div>            <span class="kn">yield</span> <span class="n">n</span></div></li>
+  <li class="parity0 source" id="l21"><div> </div></li>
+  <li class="parity1 source" id="l22"><div>    <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></div></li>
+  <li class="parity0 source" id="l23"><div>    <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></div></li>
+  <li class="parity1 source" id="l24"><div> </div></li>
+  <li class="parity0 source" id="l25"><div><span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span></div></li>
+  <li class="parity1 source" id="l26"><div>    <span class="kn">import</span> <span class="nn">sys</span></div></li>
+  <li class="parity0 source" id="l27"><div>    <span class="kn">try</span><span class="p">:</span></div></li>
+  <li class="parity1 source" id="l28"><div>        <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></div></li>
+  <li class="parity0 source" id="l29"><div>    <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></div></li>
+  <li class="parity1 source" id="l30"><div>        <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span></div></li>
+  <li class="parity0 source" id="l31"><div>    <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></div></li>
+  <li class="parity1 source" id="l32"><div>    <span class="kn">print</span> <span class="s">&quot;The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></div></li>
+  </ol>
   <div class="sourcelast"></div>
   </div>
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -502,7 +507,10 @@ 
   </div>
   </div>
   
-  <script type="text/javascript">process_dates()</script>
+  <script type="text/javascript">
+  process_dates();
+  addOnclickSource();
+  </script>
   
   
   </body>
@@ -586,24 +594,24 @@ 
   > 
   >     echo % hgweb filerevision, html
   >     "$TESTDIR/get-with-headers.py" localhost:$HGPORT "file/tip/$2" \
-  >         | grep '<div class="parity0 source">'
+  >         | grep '<li class="parity0 source" id="l1">'
   >     echo % errors encountered
   >     cat errors.log
   > }
   $ hgserveget euc-jp eucjp.txt
   % HGENCODING=euc-jp hg serve
   % hgweb filerevision, html
-  <div class="parity0 source"><a href="#l1" id="l1">     1</a> \xb5\xfe</div> (esc)
+  <li class="parity0 source" id="l1"><div>\xb5\xfe</div></li> (esc)
   % errors encountered
   $ hgserveget utf-8 eucjp.txt
   % HGENCODING=utf-8 hg serve
   % hgweb filerevision, html
-  <div class="parity0 source"><a href="#l1" id="l1">     1</a> \xef\xbf\xbd\xef\xbf\xbd</div> (esc)
+  <li class="parity0 source" id="l1"><div>\xef\xbf\xbd\xef\xbf\xbd</div></li> (esc)
   % errors encountered
   $ hgserveget us-ascii eucjp.txt
   % HGENCODING=us-ascii hg serve
   % hgweb filerevision, html
-  <div class="parity0 source"><a href="#l1" id="l1">     1</a> ??</div>
+  <li class="parity0 source" id="l1"><div>??</div></li>
   % errors encountered
 
   $ cd ..