Zennとdiff記法について
zenn.devのdiff記法についての簡単なまとめ記事です.
はじめに
kkiyama117と申します.
diff+他言語のシンタックスをzennに導入するお手伝いを少しだけさせていただきました.
ついでに、という事でこの際diffの出力についても簡単にまとめておきたいと思います.
正直新規性もなく記事にする程でもないのですが、zennには様々な分野の方がいますし、初めて記事を書きたいという方もいると思います,そんな方のお役に立てば幸いです.
不備や間違い等ありましたらコメント等でご指摘いただければと思います.
そもそも diffって
diffは簡単に言うと、unix系列のOSにおけるコマンドで、ファイル同士の差分をとるプログラムです.
転じて他の差分表示プログラムやフォーマットをdiff
と呼ぶこともあるようです.
簡単な歴史等はWikipedia 参照、
記法については後程書きますが、実際の詳しい使い方についてはmacやLinux等のUnix系の環境があればman diff
で確認する事をおすすめします.
そうではない人の為に、一応幾つかのオンラインのドキュメントを挙げておきます.
zennのdiff記法
zenn.dev 及び zenn-editor(zenn-cli)では内部でmarkdown->htmlの変換にmarkdown-it
を、コードブロックの解析にはprismjs
を組み合わせて利用しています.
diffにはいくつかの出力形式があるのですが、そのうちprismjsでは通常のものに加え、unified
,context
といわれる記法に対応しています.
(issue段階ではunified
のみに言及されていましたが、PRで他の記法に対応しています.)
unified diff の書き方
さて、肝心の diff の書き方について簡単にまとめておきます(そもそも本来は生成されるものですが).
合わせて、prismjs
からexampleを引用しておきます.
通常のもの
-
header
とhunk
(ブロック)でファイルの一部分を表す.-
a
: 追加(added) -
d
は削除(deleted) -
c
は変更(changed) - a/d/cの各文字の前には元ファイルでの行番号が書かれ、後ろに変更後ファイルでの行番号が出力される.
-
- hunkの行頭の山括弧はその行が追加されたのか、または削除されたのかを示している.
-
<
が比較された先(1つ目の引数)に存在するもの、>
が比較した先(2つ目のファイル)にのみ存在するもの - 標準では新旧両ファイルに共通する箇所は出力されない.
-
7c7
< qt: core
---
> qt: core gui
context
-
header
とhunk
(ブロック)でファイルの一部分を表す. -
header
はhunkの位置情報を表す.-
***
で始まる行が1つ目、---
ではじまる行が2つ目のファイルに対応し、hankの起点,終点の各ファイル内での行数を表す.
-
- 異なっている行の周辺の各行には先頭に2つのスペースをつける.
- 2つのファイル間で異なっている行には先頭に表示文字とスペースをつける。
-
!
: 2つのファイル間で変更された部分の各行. もう一方のファイルの対応する部分も!
でマークして表示する. -
+
: 2つめのファイルにのみ挿入された行. 1つめのファイルに対応部分はない. -
-
: 1つめのファイルから削除された行.2つめのファイルに対応部分はない.
-
*** qcli.yml 2014-12-16 11:43:41.000000000 +0800
--- /Users/uranusjr/Desktop/qcli.yml 2014-12-31 11:28:08.000000000 +0800
***************
*** 4,8 ****
project:
sources: "src/*.cpp"
headers: "src/*.h"
! qt: core
public_headers: "src/*.h"
--- 4,8 ----
project:
sources: "src/*.cpp"
headers: "src/*.h"
! qt: core gui
public_headers: "src/*.h"
unified
-
header
とhunk
(ブロック)でファイルの一部分を表す. -
header
はhunkの位置情報を表す.-
@@
~@@
で囲まれた位置情報を書く. -
***
で始まる行が1つ目、---
ではじまる行が2つ目のファイルに対応し、hankの起点,終点の各ファイル内での行数を表す.-
context
記法では起点終点の行数を表示していたが、こちらはhank自体の行の長さを表す.
-
-
- 2つのファイル間で異なっている行には先頭に表示文字とスペースをつける.
そうでない行にはスペース2つでマークする.-
+
: 1つ目のファイルのみに存在 -
-
: 2つ目のファイルのみに存在
-
--- qcli.yml 2014-12-16 11:43:41.000000000 +0800
+++ /Users/uranusjr/Desktop/qcli.yml 2014-12-31 11:28:08.000000000 +0800
@@ -4,5 +4,5 @@
project:
sources: "src/*.cpp"
headers: "src/*.h"
- qt: core
+ qt: core gui
public_headers: "src/*.h"
zennでは
zenn(および利用しているprismjs)では上にあげた記号がdiffとしてDOMに変換されます.
他の言語同様にdiff
としてcode fence に指定してあげるとこのdiff
形式が使えます.
また、最近のアップデートでdiff js
などと指定してあげることで、diffと他言語のシンタックスの両方を適応できます.
(使えるはずです、不備があったらすみません......)
今までは差分をとると言語自体のシンタックスハイライトが効きませんでしたが、これからは気兼ねなく利用できますね!
おまけ
今回zennに入った diff language
記法とcontributeについてです.
もともと zenn-editorのissueにあったもので、前々から「これならcontributeできそうかも」と思っていました.
簡単にやっていることを説明すると、
"一度生成されたdiff
のhtmlを正規表現で元の文章に戻してから同時に指定された他の言語でシンタックスを当てて、再度diffとしてhtmlのタグを付ける"
という感じになっています.
結構力技ですね......
(prismjsにdiff
にこのpluginがあるので、zennにはそれを修正して正しく読み込ませるだけでしたが......)
僕はたまに暇な時にissueを見て
- 「確かにこれがあったら便利だな」と思ったもの
-
zenn-editor
の範囲で完結しそうなもの
を見かけたらちょっとやってみる位の緩いスタンスでcommitしているのですが、memberの方々がお忙しい中でもreviewや検討をしてくださるので楽しくcontributeできています.
(memberのお二方には本当に感謝しかありません.)
まだzenn-editor
にはcontributing guideline
はないのですが、
- 開発ロードマップやzenn-editorのissue, PullRequestに類似のものがないか確認する
-
Development.md
を読む
と通常のOSSへのcontributionのマナーなどに気をつければ特に問題なくcontributeできるかと思います.
今後のzennの運営方針によってはどうなっていくかは分かりませんが、ユーザーから運営への距離が近くgithubから簡単に要望やバグ報告が出来るので皆さんも是非積極的にcontributeしてみては如何でしょうか?
Discussion
補足ですが、見た限りZennで使う場合は、CSSの当たり方的にunifiedが一番よさそうですね
参考になりました!そもそもdiffをかけることを知らなかったので、有効に使わせていただきます!