[diffoscope] 06/06: presenters: html: in html-dir mode, put css/icon in separate files to avoid duplication
Ximin Luo
infinity0 at debian.org
Mon Jul 3 20:35:58 CEST 2017
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch WIP/humungous-diffs
in repository diffoscope.
commit 84664773ac5ce826ea18b246ca49a1366e8436a7
Author: Ximin Luo <infinity0 at debian.org>
Date: Mon Jun 26 16:40:57 2017 +0200
presenters: html: in html-dir mode, put css/icon in separate files to avoid duplication
---
diffoscope/presenters/html/html.py | 85 +++++++-----
diffoscope/presenters/html/templates.py | 237 ++++++++++++++++----------------
2 files changed, 171 insertions(+), 151 deletions(-)
diff --git a/diffoscope/presenters/html/html.py b/diffoscope/presenters/html/html.py
index 4d896dc..4c3ae01 100644
--- a/diffoscope/presenters/html/html.py
+++ b/diffoscope/presenters/html/html.py
@@ -31,16 +31,17 @@
# Dave Burt <dave (at) burt.id.au> (mainly for html theme)
#
-import io
-import os
-import re
-import sys
-import html
+import base64
import codecs
+import collections
import contextlib
import hashlib
+import html
+import io
import logging
-import contextlib
+import os
+import re
+import sys
from urllib.parse import urlparse
from diffoscope import VERSION
@@ -178,7 +179,7 @@ def output_node_frame(difference, path, indentstr, indentnum, body):
{1}{0[1]}</div>
{2}""", 3).pformatl(indent, header, body)
-def output_node(difference, path, indentstr, indentnum, css_url, directory):
+def output_node(ctx, difference, path, indentstr, indentnum):
"""Returns a tuple (parent, continuation) where
- parent is a PartialString representing the body of the node, including
@@ -204,8 +205,7 @@ def output_node(difference, path, indentstr, indentnum, css_url, directory):
ud_cont = None
if difference.unified_diff:
ud_cont = HTMLSideBySidePresenter().output_unified_diff(
- css_url, directory, difference.unified_diff,
- difference.has_internal_linenos)
+ ctx, difference.unified_diff, difference.has_internal_linenos)
udiff = next(ud_cont)
if isinstance(udiff, PartialString):
ud_cont = ud_cont.send
@@ -234,15 +234,24 @@ def output_node(difference, path, indentstr, indentnum, css_url, directory):
assert len(t.holes) >= len(difference.details) + 1 # there might be extra holes for the unified diff continuation
return cont(t, u""), ud_cont
-def output_header(css_url):
+def output_header(css_url, our_css_url=False, icon_url=None):
if css_url:
- css_link = '<link href="%s" type="text/css" rel="stylesheet" />' % css_url
+ css_link = u' <link href="%s" type="text/css" rel="stylesheet" />\n' % css_url
+ else:
+ css_link = u''
+ if our_css_url:
+ css_style = u' <link href="%s" type="text/css" rel="stylesheet" />\n' % our_css_url
else:
- css_link = ''
+ css_style = u'<style type="text/css">\n' + templates.STYLES + u'</style>\n'
+ if icon_url:
+ favicon = icon_url
+ else:
+ favicon = u'data:image/png;base64,' + FAVICON_BASE64
return templates.HEADER % {
'title': html.escape(' '.join(sys.argv)),
- 'favicon': FAVICON_BASE64,
+ 'favicon': favicon,
'css_link': css_link,
+ 'css_style': css_style
}
def output_footer(jquery_url=None):
@@ -268,6 +277,13 @@ def spl_file_printer(directory, filename, accum):
yield recording_print_func
+class HTMLPrintContext(collections.namedtuple("HTMLPrintContext",
+ "target single_page jquery_url css_url our_css_url icon_url")):
+ @property
+ def directory(self):
+ return None if self.single_page else self.target
+
+
class HTMLSideBySidePresenter(object):
supports_visual_diffs = True
@@ -327,9 +343,9 @@ class HTMLSideBySidePresenter(object):
# Takes ownership of print_context
self.spl_print_ctrl = print_context.__exit__, rotation_params
self.spl_print_func = print_context.__enter__()
- _, _, css_url = rotation_params
+ ctx, _ = rotation_params
# Print file and table headers
- self.spl_print_func(output_header(css_url))
+ self.spl_print_func(output_header(ctx.css_url, ctx.our_css_url, ctx.icon_url))
def spl_had_entered_child(self):
return self.spl_print_ctrl and self.spl_print_ctrl[1] and self.spl_current_page > 0
@@ -367,7 +383,7 @@ class HTMLSideBySidePresenter(object):
def new_child_page(self):
_, rotation_params = self.spl_print_ctrl
- directory, mainname, css_url = rotation_params
+ ctx, mainname = rotation_params
self.spl_current_page += 1
filename = "%s-%s.html" % (mainname, self.spl_current_page)
@@ -378,7 +394,7 @@ class HTMLSideBySidePresenter(object):
self.spl_print_exit(None, None, None)
# rotate to the next child page
- context = spl_file_printer(directory, filename, self)
+ context = spl_file_printer(ctx.directory, filename, self)
self.spl_print_enter(context, rotation_params)
self.spl_print_func(templates.UD_TABLE_HEADER)
@@ -435,12 +451,12 @@ class HTMLSideBySidePresenter(object):
self.spl_print_func(u"</table>")
yield wrote_all
- def output_unified_diff(self, css_url, directory, unified_diff, has_internal_linenos):
+ def output_unified_diff(self, ctx, unified_diff, has_internal_linenos):
self.new_unified_diff()
rotation_params = None
- if directory:
+ if ctx.directory:
mainname = hashlib.md5(unified_diff.encode('utf-8')).hexdigest()
- rotation_params = directory, mainname, css_url
+ rotation_params = ctx, mainname
try:
udiff = io.StringIO()
@@ -535,10 +551,10 @@ class HTMLPresenter(Presenter):
else:
return templates.DIFFNODE_LIMIT
- def output_difference(self, target, difference, css_url, jquery_url, single_page=False):
+ def output_difference(self, ctx, difference):
outputs = {} # nodes to their partial output
ancestors = {} # child nodes to ancestor nodes
- placeholder_len = len(self.output_node_placeholder("XXXXXXXXXXXXXXXX", not single_page))
+ placeholder_len = len(self.output_node_placeholder("XXXXXXXXXXXXXXXX", not ctx.single_page))
continuations = {} # functions to print unified diff continuations (html-dir only)
printers = {} # nodes to their printers
@@ -553,8 +569,7 @@ class HTMLPresenter(Presenter):
path = score[3]
anchor = output_anchor(path)
logger.debug('html output for %s', anchor)
- node_output, node_continuation = output_node(
- node, path, " ", len(path)-1, css_url, None if single_page else target)
+ node_output, node_continuation = output_node(ctx, node, path, " ", len(path)-1)
add_to_existing = False
if ancestor:
@@ -568,7 +583,7 @@ class HTMLPresenter(Presenter):
elif page_current + want_to_add < page_limit:
add_to_existing = True
else:
- make_new_subpage = not single_page
+ make_new_subpage = not ctx.single_page
if add_to_existing:
# under limit, add it to an existing page
@@ -592,14 +607,14 @@ class HTMLPresenter(Presenter):
else:
# unconditionally write the root node regardless of limits
assert node is difference
- footer = output_footer(jquery_url)
+ footer = output_footer(ctx.jquery_url)
anchor = "index"
outputs[node] = node_output.frame(
- output_header(css_url) + u'<div class="difference">\n',
- u'</div>\n' + footer)
- assert not single_page or node is difference
- printers[node] = (make_printer, target) if single_page else (file_printer, target, "%s.html" % anchor)
+ output_header(ctx.css_url, ctx.our_css_url, ctx.icon_url) +
+ u'<div class="difference">\n', u'</div>\n' + footer)
+ assert not ctx.single_page or node is difference
+ printers[node] = (make_printer, ctx.target) if ctx.single_page else (file_printer, ctx.target, "%s.html" % anchor)
stored = node
for child in node.details:
@@ -661,7 +676,12 @@ class HTMLPresenter(Presenter):
raise ValueError("%s is not a directory" % directory)
jquery_url = self.ensure_jquery(jquery_url, directory, "jquery.js")
- self.output_difference(directory, difference, css_url, jquery_url)
+ with open(os.path.join(directory, "common.css"), "w") as fp:
+ fp.write(templates.STYLES)
+ 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")
+ self.output_difference(ctx, difference)
def output_html(self, target, difference, css_url=None, jquery_url=None):
@@ -669,7 +689,8 @@ class HTMLPresenter(Presenter):
Default presenter, all in one HTML file
"""
jquery_url = self.ensure_jquery(jquery_url, os.getcwd(), None)
- self.output_difference(target, difference, css_url, jquery_url, single_page=True)
+ ctx = HTMLPrintContext(target, True, jquery_url, css_url, None, None)
+ self.output_difference(ctx, difference)
@classmethod
def run(cls, data, difference, parsed_args):
diff --git a/diffoscope/presenters/html/templates.py b/diffoscope/presenters/html/templates.py
index 29ad061..8ee04de 100644
--- a/diffoscope/presenters/html/templates.py
+++ b/diffoscope/presenters/html/templates.py
@@ -24,126 +24,9 @@ HEADER = u"""<!DOCTYPE html>
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="referrer" content="no-referrer" />
<meta name="generator" content="diffoscope" />
- <link rel="icon" type="image/png" href="data:image/png;base64,%(favicon)s" />
+ <link rel="icon" type="image/png" href="%(favicon)s" />
<title>%(title)s</title>
- <style type="text/css">
- body.diffoscope {
- background: white;
- color: black;
- }
- .diffoscope .footer {
- font-size: small;
- }
- .diffoscope .difference {
- border: outset #888 1px;
- background: #E8E8E8;
- background: rgba(0,0,0,.1);
- padding: 0.5em;
- margin: 0.5em 0;
- }
- .diffoscope .difference table {
- table-layout: fixed;
- width: 100%%;
- border: 0;
- }
- .diffoscope .difference th,
- .diffoscope .difference td {
- border: 0;
- }
- .diffoscope table.diff {
- border: 0;
- border-collapse:collapse;
- font-size:0.75em;
- font-family: 'Lucida Console', monospace;
- }
- .diffoscope table.diff tr:hover td {
- background: #FFFF00;
- }
- .diffoscope .line {
- color:#8080a0
- }
- .diffoscope th {
- background: black;
- color: white
- }
- .diffoscope .diffunmodified td {
- background: #D0D0E0
- }
- .diffoscope .diffhunk td {
- background: #A0A0A0
- }
- .diffoscope .diffadded td {
- background: #CCFFCC
- }
- .diffoscope .diffdeleted td {
- background: #FFCCCC
- }
- .diffoscope .diffchanged td {
- background: #FFFFA0
- }
- .diffoscope ins, del {
- background: #E0C880;
- text-decoration: none
- }
- .diffoscope .diffponct {
- color: #B08080
- }
- .diffoscope .comment {
- font-style: italic;
- }
- .diffoscope .source {
- font-weight: bold;
- }
- .diffoscope .error {
- border: solid black 1px;
- background: red;
- color: white;
- padding: 0.2em;
- }
- .diffoscope .anchor {
- margin-left: 0.5em;
- font-size: 80%%;
- color: #333;
- text-decoration: none;
- display: none;
- }
- .diffoscope .diffheader:hover .anchor {
- display: inline;
- }
- .diffoscope table.diff tr.ondemand td, .diffoscope div.ondemand-details {
- background: #f99;
- text-align: center;
- padding: 0.5em 0;
- }
- .diffoscope table.diff tr.ondemand:hover td, .diffoscope div.ondemand-details:hover {
- background: #faa;
- cursor: pointer;
- }
- .diffoscope .diffcontrol, .diffoscope .diffcontrol-nochildren {
- float: left;
- margin-right: 0.3em;
- cursor: pointer;
- display: none; /* currently, only available in html-dir output where jquery is enabled */
- }
- .diffoscope .diffheader {
- cursor: pointer;
- }
- .diffoscope .diffheader:hover .diffcontrol {
- color: #080;
- font-weight: bold;
- }
- .diffoscope .diffcontrol-double {
- line-height: 250%%;
- }
- .diffoscope .colines {
- width: 3em;
- }
- .diffoscope .coldiff {
- width: 99%%;
- }
- </style>
- %(css_link)s
-</head>
+%(css_style)s%(css_link)s</head>
<body class="diffoscope">
"""
@@ -152,6 +35,122 @@ FOOTER = u"""<div class="footer">Generated by <a href="https://diffoscope.org" r
</html>
"""
+STYLES = u"""body.diffoscope {
+ background: white;
+ color: black;
+}
+.diffoscope .footer {
+ font-size: small;
+}
+.diffoscope .difference {
+ border: outset #888 1px;
+ background: #E8E8E8;
+ background: rgba(0,0,0,.1);
+ padding: 0.5em;
+ margin: 0.5em 0;
+}
+.diffoscope .difference table {
+ table-layout: fixed;
+ width: 100%;
+ border: 0;
+}
+.diffoscope .difference th,
+.diffoscope .difference td {
+ border: 0;
+}
+.diffoscope table.diff {
+ border: 0;
+ border-collapse:collapse;
+ font-size:0.75em;
+ font-family: 'Lucida Console', monospace;
+}
+.diffoscope table.diff tr:hover td {
+ background: #FFFF00;
+}
+.diffoscope .line {
+ color:#8080a0
+}
+.diffoscope th {
+ background: black;
+ color: white
+}
+.diffoscope .diffunmodified td {
+ background: #D0D0E0
+}
+.diffoscope .diffhunk td {
+ background: #A0A0A0
+}
+.diffoscope .diffadded td {
+ background: #CCFFCC
+}
+.diffoscope .diffdeleted td {
+ background: #FFCCCC
+}
+.diffoscope .diffchanged td {
+ background: #FFFFA0
+}
+.diffoscope ins, del {
+ background: #E0C880;
+ text-decoration: none
+}
+.diffoscope .diffponct {
+ color: #B08080
+}
+.diffoscope .comment {
+ font-style: italic;
+}
+.diffoscope .source {
+ font-weight: bold;
+}
+.diffoscope .error {
+ border: solid black 1px;
+ background: red;
+ color: white;
+ padding: 0.2em;
+}
+.diffoscope .anchor {
+ margin-left: 0.5em;
+ font-size: 80%;
+ color: #333;
+ text-decoration: none;
+ display: none;
+}
+.diffoscope .diffheader:hover .anchor {
+ display: inline;
+}
+.diffoscope table.diff tr.ondemand td, .diffoscope div.ondemand-details {
+ background: #f99;
+ text-align: center;
+ padding: 0.5em 0;
+}
+.diffoscope table.diff tr.ondemand:hover td, .diffoscope div.ondemand-details:hover {
+ background: #faa;
+ cursor: pointer;
+}
+.diffoscope .diffcontrol, .diffoscope .diffcontrol-nochildren {
+ float: left;
+ margin-right: 0.3em;
+ cursor: pointer;
+ display: none; /* currently, only available in html-dir output where jquery is enabled */
+}
+.diffoscope .diffheader {
+ cursor: pointer;
+}
+.diffoscope .diffheader:hover .diffcontrol {
+ color: #080;
+ font-weight: bold;
+}
+.diffoscope .diffcontrol-double {
+ line-height: 250%;
+}
+.diffoscope .colines {
+ width: 3em;
+}
+.diffoscope .coldiff {
+ width: 99%;
+}
+"""
+
SCRIPTS = u"""<script src="%(jquery_url)s"></script>
<script type="text/javascript">
$(function() {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git
More information about the diffoscope
mailing list