フィクション用エディター with はApp Store配布を目指して少しずつ作り込んでいます。macOS版のGitHub公開は考えたんですが、今回はPro版でアプリ内課金を予定していて、OSSライセンス版の作り方に悩んでいるところなのです。アイコンは決まりました。


そんなわけでTestFlight1でβテストを実施しようと思ってApple Store Connect2に登録すると「withは登録商標なのであなたが権利者であることを証明しなさい」と言われてしまいました。こんなSEOに弱い一般名詞をアプリケーションとして商標登録する企業があるんだなあ――とは思いましたが、とにかくブランドを戦うアプリでもないので、アプリケーション名は「with story」にしました。
with storyは一般名詞を並べたプロダクト名です。しかも空白を入れている。これは企業の製品なら絶対やりません。withを使うエディターならwithEditとか、WithWriteになるでしょう。名前だけならzenバベルの方がずっといいですね。
しかし、これから長く使うエディターなので、できるだけ透明なものにしたい。開発費ぐらいは欲しいけど儲かるほどじゃなくていい。そんな理由でマーケの中心から三光年ぐらい離れたアプリ名に決めました。どうせ私もユーザーもwithと呼ぶんだから。
マーケティングと整合性がない名前を持つwith storyは、仕様もあまり固くはありません。それが最もよく表れているのが、アウトライン機能です。

with storyはフォルダー階層とMarkdown見出しの両方を同時に使える構造化ビューを備えた、長編小説執筆対応エディターです。
テキストエディターでアウトラインビューのある執筆ソフトは珍しくありません。私が使ってきたScrivenerがそうですし、私が作っているnovel-writerにもアウトライン機能はあります。商業作家が文芸誌で長編小説の連載をする時、入稿は一話単位。そこでファイルは分かれますので、なんらかの方法でファイルを整理する必要があります。ファイルを分けてもいいのですが、第二話を書いてる時に第一話を参照したくなるとき、または先の展開を書いておきたい時に、別のファイルを開いて読んで書き込んでとやるのは面倒です。ファイルをひとまとめにするエディターは欲しい。ScrivenerもVS Codeもこの課題には見事に応えてくれました。
しかし、一つのファイルで中編を書き切りたいことはある。そして、そんな書き方をするときには、文書内のアウトラインでなければ役に立ちません。契約書のような併記と深い階層は要らないけれど、シーンの順番を入れ替えたくなることはありますし、ある場所の描写を別のシーンに引っ越したくなることもあります。もっと短いショートストーリーでも、場面ごとの枚数は知りたくなる。
だからwith storyには、長編で使うファイルベースの構造と、文字、行単位の構造を知るための見出しレベルのアウトラインの両方を用意しました。しかも混ぜて使えます。自動見出しは私がそういう作品を書くときにつけますが、それまでは自分で書くことになります。どうせ決められたスタイルで満足できなくて、作品ごとに違うスタイルで書くんですから。
現在のwith storyは、ファイルの並び順をファイル名と関係なく決められます。他のアプリからみると順番がぐちゃぐちゃになってしまうので、管理用の連番を振る機能も必要になるでしょうけどね。
ちなみにScrivenerには「テキストの子階層にフォルダーやテキストを入れる」という、結構とんでもない機能がありました。なかなか使いにくい機能で仕様が壊れてるなあと思いましたし、ユーザーも不満そうだったのに辞める気配がない。あれも、with storyと同じような理由で生まれた機能なんでしょうね。
with storyにはユニークな機能があります。今日できました。文の移動です。
文の移動
with storyには、行を前に後ろに動かす機能と、文節や選択範囲を文の前後に動かす機能を搭載しています。
行の移動はともかく、文字の塊が行の中を動くような機能を持つエディターを私は他に知りません(ご存知の方がいたら教えてください。細かな仕様決めの参考にしたい)。語順が変わると文法が壊れる言語と違って「今日私は海に行く」が「今日海に私は行く」になっても「私は今日海に行く」に変わっても成立するのは日本語ならでは。
ちなみに行の移動を初めて見たのはVS codeでした。コントロールキー(Macだとオプションキー)を押しながら上下の矢印キーを押すと、カーソルのある行が前や後ろに移動します。結果だけ見るとカットアンドペーストと変わりませんが、アクション一つで文が文書の中を動いていく体験に私は痺れました。7年使ったScrivenerから日本語の単語境界すらないVS Codeに移ったのは、簡単なキー操作で文が文書の中を泳いでいくのを体験したからです。
その時ふと、プラグインを作ったら単語をキーで移動できないかなと思ったのです。実現まで4年かかりましたが。
二週間ほどかけてkuromoji.jsの形態素解析をVS Coddに持ち込み、さらに1ヶ月ほどかけて、ショートカットで選択している文字を動かすことに成功しました。これが昨年。前例のない機能に戸惑ったGPTが何度も私の書いたコードをviやemacsにある一文字単位の入れ替えに書き直してドヤってくれたのはいい思い出です。
with storyに搭載した文節の移動は、この時書いたコードの移植版です。私が抽象化したnovel-writerの文節生成コードを渡すと、GPT 5.5はnovel-writerを「発見」して、文節移動には前例がある。これを設計の参考にすると言ってくれました。今度は私がGPTに自慢したくなりましたが、トークンの無駄なので、そのまま実装してもらいました。いろいろありましたが、with storyの文節移動はnovel-writerと同じように動きます。
二つの共有
with storyにはプロジェクトを共有する機能を二種類つけました。Appleのクラウドを使うiCloud共有と、Appleの近接通信Handoffです。どちらもApple製品同士の共有です。
iCloud共有は、プロジェクトをユーザーから見えないiCloudの管理領域にアップロードして、同じアカウントで開いているwith storyで受け取る機能です。下のスクリーンショットでは、「ガラスの下の母」をiPhone受け取っていて、blogsをiCloudに共有しています。今のところ送受信は完全上書きだけです。離れていてもデータを受け取れるのがいいところです。ネットが安心して使える環境ならこちらですね。

そしてもう一つが近距離ローカル通信のHandoff(データの受け渡しには近距離P2PのMultipeerを使います)。近くでiPhoneとMacbookを同時に開いてプロジェクトを受け取ったり、書き足した原稿を受け取ることができます。受信は上書きのみ。スナップショット保存するので前のデータがなくなるわけじゃありませんが、こちらも統合機能が欲しいところです。
こちらはWi-Fiのない場所でも使えるので、飛行機の中でデータを移したり、機内で書いた文をMacbookに戻したりするときに使うといいですね。


こんな感じで進めています。
作ってみると、縦書きが読みやすいことに驚きますが、水平スクロールには難儀します(ので、縦書きの時は縦のマウスホイールで横にスクロールするようにしてしまいました。快適!)。
TestFlightのレビューも今日か明日には終わるでしょうから、お試しいただける方は是非試してみてください。
公開にはまだまだやらなきゃいけないことがあります。原稿の連結ができなきゃいけませんし、ルビのプレビューも欲しい。検索機能だって欲しいし、内部構造はテキストから離れてASTにして、段落と文は固有IDで生まれてから消えるまで追跡したい。スナップショットやiCloud、Handoff共有のマージ差分はApple AIに説明させたい。Pro版仕様のWord出力とプロジェクトの締切設定も作らないと、アプリ内購入が準備できません。
何より連載があります。しばらくは原稿に集中します。

