-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhtml.lisp
94 lines (92 loc) · 3.13 KB
/
html.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
;;; ast-diff-html.lisp --- render ast diffs to html
(defpackage :resolve/html
(:use :gt/full
:resolve/ast-diff
:cl-who)
(:shadowing-import-from :cl-who :fmt :escape-string)
(:export :diff-to-html))
(in-package :resolve/html)
(defun diff-to-html (orig-asts edit-script &optional (stream t))
"Generate HTML which shows side-by-side diff.
Shows source text of ORIG-ASTS alongside the result of applying
EDIT-SCRIPT, with highlighting of inserts and deletes.
"
(labels
((render-ast (ast)
(let ((text (source-text ast)))
(values (escape-string text) (count #\newline text))))
(render-diff (asts script)
(if (null script)
'(nil nil)
(destructuring-bind (action . args) (car script)
(ecase action
(:recurse
(mapcar #'append
(render-diff (cdr (car asts)) args)
(render-diff (cdr asts) (cdr script))))
(:same
(mapcar #'cons
(make-list 2
:initial-element
(render-ast (car asts)))
(render-diff (cdr asts) (cdr script))))
(:delete
(multiple-value-bind (text line-count)
(render-ast (car asts))
(mapcar #'cons
(list (format nil
"<span class=\"delete\">~a</span>"
text)
(format nil "~{~a~}"
(make-list line-count
:initial-element
#\newline)))
(render-diff (cdr asts) (cdr script)))))
(:insert
(multiple-value-bind (text line-count)
(render-ast args)
(mapcar #'cons
(list (format nil "~{~a~}"
(make-list line-count
:initial-element
#\newline))
(format nil
"<span class=\"insert\">~a</span>"
text))
(render-diff asts (cdr script))))))))))
(apply #'format stream "<!DOCTYPE html>
<html>
<head>
<style>
.delete {
border: 1px solid black;
background-color: DarkSalmon;
}
.insert {
border: 1px solid black;
background-color: MediumSeaGreen;
}
.pre {
margin: 0px;
padding: 4px;
font-size: 10pt;
color: black;
background-color: white;
border: 1px solid black;
border-radius: 4px;
}
.column {
border-color: black;
border-width: 1px;
float: left;
width: 48%;
margin: 0.5%;
}
</style>
</head>
<body>
<div class=\"column\"> <pre class=\"pre\">~{~a~}</pre></div>
<div class=\"column\"> <pre class=\"pre\">~{~a~}</pre></div>
</body>
</html>"
(traced (render-diff orig-asts edit-script)))))