テキスト書きのためのバージョン管理

単に git を使うだけではけっこう厳しい。

まず、テキストメディアは、テキストデータそれ自体は論理情報だが、表現は視覚情報と不可分であることも少なからずある。ただし脚本やボイスドラマのようなものは必ずしもそうではなくて、これらはある種のソースコード、たとえば楽譜のようなものとして扱うことができるかもしれない。それはひとまずおいておく。

ここでは視覚テキストメディアの話をしていく。視覚テキストメディアとは、

  • 字幕スーパー
    • 1〜2行、十数文字程度
  • ゲームの会話文
    • 一つのメッセージウインドウに2〜4行程度のメッセージが収まる
  • Twitter小説
    • 1メッセージ140字程度
  • 紙の小説
    • 一ページに一行40字程度、20行くらいの文章が収まる
  • Web 小説
    • 一行40字程度で数十〜百行以上連続する
    • PCとスマートフォンとで一行の表示文字数に違いがあることもある
  • 電子書籍(フローレイアウトの場合)
    • 一行、一ページの表示文字数は可変で不定

のようなものである。もちろんゲーム実況動画*1など、より複雑なケースもあるだろう。

Web小説や電子書籍のフローレイアウトのような一行の文字数が可変になりうるメディアにおいては、形式段落程度の粒度で差分を取り扱ってもそれほど不自由はない。場合によっては句点など文の終了記号単位で分割してもいい。ただし、そうであっても生のテキストデータのままで差分を作るのは難しい。一行が百文字以上になることは少なからずあり、同じ行内に複数の変更が混在しうる。そしてそれら変更にはなんら相互関連性がないこともしばしばある。コミットの粒度をちいさくすることで差分を取り扱いやすくしようという git の思想とは相容れない部分である。

どうするか。たとえばもっと小さな単位で分解して構文木を作るというやり方がある。構文木は論理情報なので差分を出すのに向いている。
現実的で低コストなのは、ある種の約物で分割してしまうというやり方である。句読点や括弧類をまたいで相互に影響するような変更というのがまったくないわけではないが、それはプログラムのソースコードにしてもそうである。関連する変更がバラバラになっても、一行に複数の変更が混在するケースを減らすほうがマシだということである。小説は作業工程の都合上、コミットの粒度をちいさくするのがむずかしい。だから変更点を細かな単位で抽出しましょうということである。欠点もある。句点の位置が変わることはあまりないが、読点の位置は変わる。約物の単位で作った構文木同士の差分では、おそらく読点の位置を変更しただけの変更がそうであるとわかりにくくなる。

文字数が可変な媒体はそれでいいとして、一行の文字数なり一ページの行数なりが固定のレイアウトにおいては、折返し位置が重要な意味を持ちうる。おおよそ編集時には自動折返しを利用し、出力時に固定位置で行分割を行うと思う。行分割後のテキストデータは編集性が著しく下がるからだ。しかし、差分としては出力時の状態で出したい。

この場合、一文字挿抜するだけで全体の見た目に影響を及ぼすことがありえる。git は単にある行の何文字目の文字が増減したことしか関知しない。差分の論理情報としては正しいが、チェックを行うにあたっては、出力結果の差分を取り扱う必要があり、それは画像の差分と同じようなものとして考えなければならない。たとえばバイナリエディタの差分機能のように位置の取り扱いが厳密に行われるものがあるが、視覚テキストメディアのソースコードもまたそのように扱うべき性質のものである。

視覚に関しては、たとえば禁則のようなルール以外に、複数行間での行頭あるいは行末の文字の重複のような見栄え上の問題もある。これをチェックするために差分を出したいわけだが、別段人間の目で検出しなくてもよく、機械的に処理可能ならそのようにすればよい。であるなら、視覚上の差分の検出にそこまでこだわる必要はなくなるかもしれない。

プリコミットフックなどで自動で構文木を作って git で管理するようにすれば、まあまあマシになるのではないかと思う。あくまでマシであって、作業プロセスにバージョン管理ツールを組み込みにくいこと自体をどうやって克服していくのかという課題は残る。どうするのがいいのかアイデアがあったら聞きたい。

こちらからは以上です。

*1:たとえばbiim式実況動画は字幕と右枠説明欄とでそれぞれに独立してテキスト表示が進行する