見出し画像

小説のバージョン管理

こんにちは、加藤です。既存機能の紹介です。

長編小説を書いている作家様が遭遇する悩みの一つに、エピソードの大幅な改変があります。
ツンデレ路線で書いてしまった展開が気に入らず、ラブラブに書き直したら話が続かなくなってしまった!以前のツンデレに戻したい!私のツンデレ!どこへ行ったの?
という事故はよくある話です。

この問題を解決するために、多くの作家様は執筆中のファイルをコピーしてバックアップするという原始的な方法、あるいはエピソード単位で保全用の没ファイルにコピペするという手続きで回避しているようです(Twitter調べ)。

全体のバージョン管理

エンジニアが解決策を考えると、このような原始的な方法を否定して、つい自分たちと同じやり方を押し付けようとしてしまいます。つまり、全体の本文を分岐させて編集する方法です。

貸し本棚でもこれと同等の分岐管理を考えていたのですが、以下のような問題を解決することが困難であると判断しました。

  • ブランチ管理の思想をインストラクションできない。

  • diffで管理するとバグ耐性がなくなる。全文管理するとストレージ圧迫する。

  • そもそも小説は複数人で編集しないので、マージ作業とか面倒じゃね?

普通に作家様がテキストファイルでやっていることと同じことをやればいいのではないか、という結論に至り、貸し本棚ではエピソード単位で現在の本文を一時保存できるようにしました。

貸し本棚の版管理

貸し本棚ではエピソードの現在の本文を版管理サイドバーから保存できます。最大で20個まで保存でき、それ以上保存すると過去の版から消えていきます。

保存した版をクリックすると、現在の本文との差分を参照することができます。

追加・変更・削除の差分が確認できます

この画面で確認した上で、任意に指定の版に戻すことができます。部分的に戻すことはできませんが、戻す前の現在の版は自動的に保存されるので、今書いている本文を失うことはありません。これはGoogleドキュメントなどと同じですが、自動保存しないので、任意に保存する必要があります。

保存データの圧縮

版管理データはその文字数をカウントしたり、内容で検索をかけることはないので、平文で保存するより圧縮したほうが効率的です。

圧縮はModelに直接書き込むので、ロジック側ではなにも気にしません。

/**
 * 本文展開
 *
 * @param string $value
 * @return string
 */
public function getBodyAttribute($value)
{
    return gzuncompress($value);
}

/**
 * 本文圧縮
 *
 * @param string $value
 * @return void
 */
public function setBodyAttribute($value)
{
    $this->attributes["body"] = gzcompress($value, 1);
}

圧縮系の機能はgzcompress/gzdeflate/gzencodeの3種類がありますが、以下の記事で比較が行われています。

strlen original: 5022
strlen gzdeflate: 38
strlen gzcompress: 43
strlen gzencode: 56
gz de-inflate: 0.0043709278106689
gz un-compress: 0.0044679641723633
gz de-encode: 0.0048530101776123

https://gist.github.com/fruitl00p/86321d00aef0e79c1c2b9a6340525eaa

圧縮率はgzdeflate > gzcompress > gzencodeの順に優秀で、速度は反比例。今回gzdeflateを選ばなかったのは、これ何で圧縮したか書いてくれないからちょっと気持ち悪いです。gzencodeは冗長すぎるので、間をとってgzcompressにしました。

版管理とアウトラインエディタ

アウトライン化されたエディタで版管理を行うと、見る間に本文が行方不明になり、何が最新で何が古いのかがわからなくなります。gitが使えれば心強いですが、短めの中編小説にまでリポジトリを用意するのは労力の無駄です。何より、小説を書いている作家様がそういう複雑な管理を求めていないようです。

そのような事情もあって、貸し本棚では考えうる限り最も単純な方法で版管理を提供します。設定は必要ありません。書き始めた瞬間に右側に版管理のアイコンが現れます。

小説にバージョン管理は必要か?

epub界隈ではかなり昔から議論されていることで、必要派と不要派で様々な意見があります。

貸し本棚はバージョン管理を実装しておきながら、開発者自身は「いらんくね?」と思っています。過去に遡るくらいなら新しい文を紡いだ方が良いと思います。創作はやり直しの効かない選択を積み重ねていくものだと考えます。

しかしこれは「あの頃のような熱量ではもう書けない」という熟練した作家様の立ち位置では間違った考え方でもあり、新たな文を書いて初期の文との差分を確認するといった使い方もあり、作家様ご自身の判断で使う使わないを決めていただければ良いと思っています。

裏技的な全体バージョン管理

貸し本棚にはもうひとつ、裏技的なバージョン管理の方法があります。

ユーザー登録時にメールアドレスが使われている場合(メアドなしのTwitter連携以外)、メールバックアップの設定が可能です。本文を編集した場合、1日1回メールで全文のバックアップファイルを送信します。

このバックアップファイルは日単位でのバージョンになるので、誤って大量のエピソードを消してしまった場合などに、過去に遡って内容を確認することができます。


今回は簡単にあまり知られていない貸し本棚の機能について書いてみました。シンプルな機能なので、技術的に紹介できる知見があまりありません。

これ以外にも「知ってる人はたくさん使っているけど、知らない人は全く使っていない」ような知名度の低い機能がいくつかあるので、そのうち紹介しようと思います。


この記事が気に入ったらサポートをしてみませんか?