GitHub便利です。その一つが、Compare ViewのDiffです。Pull Requestを確認するときもよく見ます。コマンドラインでgit diffと普通にやるより見やすいです。
さて、背景は省略しますが、HTMLでdiffを表示したいと思いました。AngularJSでの利用を想定しているので、JavaScriptのライブラリが欲しいです。
ところが探してもあまり見つかりません。よくまとまっているのはこちら。
http://stackoverflow.com/questions/3053587/javascript-based-diff-utility
ちょっと古い投稿ですが。一番人気なのは、これです。
https://github.com/cemerick/jsdifflib
オンラインデモはこちら。
http://cemerick.github.io/jsdifflib/demo.html
だいぶ求めているもののイメージに近いです。 コードも枯れているらしい。 HTMLが出力されるので、Angularで使うならdirectiveを書かなければいけないですが、それは仕方ないですね。
これで行こうかと思ったところでしたが、なにか物足りません。 なんというか、見た目がワクワクしないのです。 改めてGitHubのDiffと比較してみると、全体的に色が濃すぎる。 あと、単語の差分がハイライトされない。色については自分でcssを書いて調整すればよいでしょうが、単語のハイライトはそれでは済みません。
というわけで、もう一度検索しました。見つけたのがこちらです。
https://github.com/rtfpessoa/diff2html
オンラインデモはこちら。
http://rtfpessoa.github.io/diff2html/
おお、おしゃれ。これですよこれ。なんとStar数は3でした。まったく注目されていません。コードも枯れていないでしょう。まだ不具合もあります。でも、魅力的です。これを使いましょう。
ところが、使うには一つ問題がありました。diff2htmlはdiffの出力を入力としているのです。例えば、
diff --git a/foo.txt b/foo.txt
---
+++
@@ -1,4 +1,5 @@
+zero
one
two
-three
+tree
four
このようなものです。つまり、次はこれを出力するライブラリを探しました。いくつかありそうでしたが、比較的すんなり結合できたのはこちらです。
https://github.com/qiao/difflib.js
入力の行が配列になることと、出力の一行目のヘッダが付かないことなど不足点はありまして、それらは自力で対応しました。
最後にこれらを全部つなげて、angular.jsのdirectiveを書いてできあがりです。下記のような感じで使えるようになりました。
<my-diff path="foo.txt" old-content="one\ntwo\nthree\nfour\n" new-content="zero\none\ntwo\n\tree\nfour\n">
便利です。ちょっと気になることと言えば、依存javascriptが3ファイルもあって、グローバルに関数を定義するようなものであることです。なにかうまく隠蔽する方法があるのでしょうか。
コメント