#lang racket/base (require net/sendurl json xml racket/string ) (provide diff->html) (define (make-js . args) (string-join args "\n")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; goal : Render a Git diff in a temporary HTML file. ; pre : diff is a unified Git diff string. ; post : The generated HTML file has been opened in the default browser. ; result : void. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (diff->html diff) (let ((highlight-css "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css") (diff2html-min-css "https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css") (diff2html-ui-min-js "https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js")) (let ((html `(html (head (meta ((charset "utf-8"))) (link ((rel "stylesheet") (href ,highlight-css))) (link ((rel "stylesheet") (href ,diff2html-min-css))) (script ((src ,diff2html-ui-min-js)) "") (script ,(format (make-js "window.do_diff = function() {" "const diff = ~a;" "const ui = new Diff2HtmlUI(" " document.getElementById('diff')," " diff," " {" " drawFileList: true," " matching: 'lines'," " outputFormat: 'side-by-side'," " });" "ui.draw();" "ui.highlightCode();" "};" ) (jsexpr->string diff)) ) ) (body (div ((id "diff"))) (script ((type "text/javascript")) "window.do_diff();") )))) (let ((tmp-file (build-path (find-system-path 'temp-dir) "racket-git-diff.html"))) (call-with-output-file tmp-file #:exists 'truncate (λ (out) (display (xexpr->string html) out))) (send-url/file tmp-file)))))