[Git][reproducible-builds/diffoscope][master] 4 commits: Wrap docstring across multiple lines.

Chris Lamb gitlab at salsa.debian.org
Fri May 15 14:57:15 UTC 2020



Chris Lamb pushed to branch master at Reproducible Builds / diffoscope


Commits:
05b33f42 by Chris Lamb at 2020-05-15T15:19:38+01:00
Wrap docstring across multiple lines.

- - - - -
26e57c7c by Chris Lamb at 2020-05-15T15:41:57+01:00
Never emit an empty "id" anchor as it is not possible to link to "#" (vs "#foo"). We use "#top" as the fallback so it will work with the top-level container.

- - - - -
e6ce6698 by Chris Lamb at 2020-05-15T15:46:11+01:00
Drop inline pprint import.

- - - - -
63cf7e1d by Chris Lamb at 2020-05-15T15:56:19+01:00
Never emit the same id="foo" anchor reference twice, otherwise identically-named parts will not be able to linked to via "#foo". (Closes: reproducible-builds/diffoscope#120)

- - - - -


2 changed files:

- diffoscope/presenters/html/html.py
- tests/data/output_regression_875281.html


Changes:

=====================================
diffoscope/presenters/html/html.py
=====================================
@@ -38,8 +38,10 @@ import contextlib
 import hashlib
 import html
 import io
+import itertools
 import logging
 import os
+import pprint
 import re
 import sys
 from unicodedata import normalize
@@ -77,8 +79,10 @@ re_anchor_suffix = re.compile(r'[^A-Za-z-_:\.]')
 
 
 def send_and_exhaust(iterator, arg, default):
-    """Send a single value to a coroutine, exhaust it, and return the final
-    element or a default value if it was empty."""
+    """
+    Send a single value to a coroutine, exhaust it, and return the final
+    element or a default value if it was empty.
+    """
     # Python's coroutine syntax is still a bit rough when you want to do
     # slightly more complex stuff. Watch this logic closely.
     output = default
@@ -112,8 +116,22 @@ def output_diff_path(path):
     return ' / '.join(n.source1 for n in path[1:])
 
 
-def output_anchor(path):
-    return escape_anchor(output_diff_path(path))
+def output_anchor(ctx, path):
+    val = escape_anchor(output_diff_path(path)) or "top"
+
+    # Never emit the same id="foo" anchor reference twice, otherwise
+    # identically-named parts will not be able to linked to via "#foo".
+    if val in ctx.used_anchors:
+        for x in itertools.count(1):
+            candidate = "{}-{}".format(val, x)
+
+            if candidate not in ctx.used_anchors:
+                val = candidate
+                break
+
+    ctx.used_anchors.add(val)
+
+    return val
 
 
 def convert(s, ponct=0, tag=''):
@@ -154,10 +172,10 @@ def convert(s, ponct=0, tag=''):
     return normalize('NFC', t.getvalue())
 
 
-def output_visual(visual, path, indentstr, indentnum):
+def output_visual(ctx, visual, path, indentstr, indentnum):
     logger.debug('including image for %s', visual.source)
     indent = tuple(indentstr * (indentnum + x) for x in range(3))
-    anchor = output_anchor(path)
+    anchor = output_anchor(ctx, path)
     id = 'id="{}"'.format(anchor) if anchor else ''
     return u"""{0[0]}<div class="difference">
 {0[1]}<div class="diffheader">
@@ -177,9 +195,9 @@ def output_visual(visual, path, indentstr, indentnum):
     )
 
 
-def output_node_frame(difference, path, indentstr, indentnum, body):
+def output_node_frame(ctx, difference, path, indentstr, indentnum, body):
     indent = tuple(indentstr * (indentnum + x) for x in range(3))
-    anchor = output_anchor(path)
+    anchor = output_anchor(ctx, path)
     id = 'id="{}"'.format(anchor) if anchor else ''
     dctrl_class, dctrl = (
         ("diffcontrol", u'⊟')
@@ -253,7 +271,7 @@ def output_node(ctx, difference, path, indentstr, indentnum):
 
     visuals = u""
     for visual in difference.visuals:
-        visuals += output_visual(visual, path, indentstr, indentnum + 1)
+        visuals += output_visual(ctx, visual, path, indentstr, indentnum + 1)
 
     udiff = u""
     ud_cont = None
@@ -276,13 +294,15 @@ def output_node(ctx, difference, path, indentstr, indentnum):
     )
     if len(path) == 1:
         # root node, frame it
-        body = output_node_frame(difference, path, indentstr, indentnum, body)
+        body = output_node_frame(
+            ctx, difference, path, indentstr, indentnum, body
+        )
     t = cont(t, body)
 
     # Add holes for child nodes
     for d in difference.details:
         child = output_node_frame(
-            d, path + [d], indentstr, indentnum + 1, PartialString.of(d)
+            ctx, d, path + [d], indentstr, indentnum + 1, PartialString.of(d)
         )
         child = PartialString.numl(
             u"""{0[1]}<div class="difference">
@@ -362,7 +382,7 @@ def spl_file_printer(directory, filename, accum):
 class HTMLPrintContext(
     collections.namedtuple(
         "HTMLPrintContext",
-        "target single_page jquery_url css_url our_css_url icon_url",
+        "target single_page jquery_url css_url our_css_url icon_url used_anchors",
     )
 ):
     @property
@@ -831,9 +851,8 @@ class HTMLPresenter(Presenter):
                 break
 
         if outputs:
-            import pprint
-
             pprint.pprint(outputs, indent=4)
+
         assert not outputs
 
     def ensure_jquery(self, jquery_url, basedir, default_override):
@@ -901,7 +920,13 @@ class HTMLPresenter(Presenter):
         with open(os.path.join(directory, "icon.png"), "wb") as fp:
             fp.write(base64.b64decode(FAVICON_BASE64))
         ctx = HTMLPrintContext(
-            directory, False, jquery_url, css_url, "common.css", "icon.png"
+            directory,
+            False,
+            jquery_url,
+            css_url,
+            "common.css",
+            "icon.png",
+            set(),
         )
         self.output_difference(ctx, difference)
 
@@ -910,7 +935,9 @@ class HTMLPresenter(Presenter):
         Default presenter, all in one HTML file
         """
         jquery_url = self.ensure_jquery(jquery_url, os.getcwd(), None)
-        ctx = HTMLPrintContext(target, True, jquery_url, css_url, None, None)
+        ctx = HTMLPrintContext(
+            target, True, jquery_url, css_url, None, None, set()
+        )
         self.output_difference(ctx, difference)
 
     @classmethod


=====================================
tests/data/output_regression_875281.html
=====================================
@@ -4,8 +4,8 @@
   <div class="diffcontrol diffcontrol-double">⊟</div>
   <div><span class="diffsize">4.82 MB</span></div>
   <div><span class="source">b1</span> vs.</div>
-  <div ><span class="source">b2</span>
-    <a class="anchor" href="#">¶</a>
+  <div id="top"><span class="source">b2</span>
+    <a class="anchor" href="#top">¶</a>
   </div>
   </div>
   <div class="difference">



View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/-/compare/1978f9d1d92ee3ec848d78c918967d3c2f654299...63cf7e1d50cacc046fffebb826d44d1770a47ecf

-- 
View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/-/compare/1978f9d1d92ee3ec848d78c918967d3c2f654299...63cf7e1d50cacc046fffebb826d44d1770a47ecf
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.reproducible-builds.org/pipermail/rb-commits/attachments/20200515/cbd499df/attachment.htm>


More information about the rb-commits mailing list