2022-11-02

アウトライナー×つぶやき×平面配置②~ツール紹介編~

 メモを雑に書いたままゾンビ化させないために、「つぶやくように書けて、アウトライナーのように操作できて、平面配置で表示されて、自然にもう一人の自分と対話できるツール」を作ろうという話のツール紹介編。ここに至る経緯は前回の記事をご参照のこと。

アウトライナー×つぶやき×平面配置①~経緯編~


 前回の最後にも貼ったが、まずメイン画面のスクリーンショットはこちら。


 なお撮影用に余計な情報が写らないようにしたため実際の画面とはレイアウトが若干違っている(実際よりちょっと窮屈な画面になっている)。

 コンセプトとしては「アウトライナー×Twitter×面」ということになるが、書き込んで操作する部分はアウトライナーである。なので名付けるとしたら○○アウトライナーということになるだろう。

 そして左右にちらっと映っているのが他のビューで、普段はこんな感じで中途半端に端っこが見えている状態で控えており、マウスオーバーするとアウトライナー部分に重なるようにスライドインするようになっている。それぞれのスクリーンショットはこんな感じ。



 動かしている様子は動画にしてTwitterに投稿したので、ご興味のある方はそちらもどうぞ。

https://twitter.com/Foam_Crab/status/1587745920329732096


 機能ごとに詳細を書いておこうと思う。(例によってツールもコードも公開していないが、考え方や所感が誰かの何かの役に立つかもと思って書いている。)


アウトライナー


 アウトライナー部分は、フォーカス以外の一通りのアウトライン操作ができるようになっている。ほぼ普通のアウトライナーである。

 違っているのは、各ノードに個別のアイコンを設定できることと、編集時に文字数カウントが表示できることだ。


 アイコンはCtrl+←/→で簡単にくるくる変更できるのだが、挙動の仕組みとしては、全てのノードが何らかの種別を持ち、その種別に対応するアイコンが自動的に表示されているということを意味する。(HTML的にどうなっているかというと、li要素にカスタム属性を設定し(data-typeとした)、その値が「topic」とか「date」とか「A」とかいうふうに変更されていくということだ。)

 前回書いたように、アウトラインに行を追加した時にはデフォルトで「二つに分けた自分の一方」を示すアイコンが表示されるようにしてある。サンプルでは「自分A」ということにして赤丸の「A」のアイコンにしてある(実際は全然違うアイコンを使っているし、自分A自分Bという呼び方でもない)。

 こうすると、とりあえず自分Aとして考えたことを書くことになり、自分A以外に他の自分がいるはずであること、自分の中でも偏った視点でしかないかもしれないこと、をなんとなく意識する。(前回詳しく書いたが、そうなるように私自身が既に訓練されていたところがある。以下、「こういうことが起きる」として書いてあるのはあくまで私の中でのことである。)

 自分A以外に人がいるのに、自分Aにしかわからない独りよがりな書き方をすると他の存在が関われなくなるので、恰も他の誰かが見ているかのようにきちんと書こうという気持ちが働く。別にきちんとさせないで自分Bをいきなり登場させてもいいのだが、そうすると対話の体を成していないという気持ち悪さに私が耐えられなくなるのである。

 自分Aが書いたものに自分Bという別の視点をぶつけてみた時、それでも納得できるのか、ツッコミどころを見つけて「いやそれはおかしいでしょ」と自分で批判することになるのか、それはその時次第だが、とりあえず自分で穴を探すというチェックが働く。自分同士である以上どうしたって完璧なチェック機能にはならないが、それでも結構な頻度で「いや、ちょっと待てよ」が発生するし、「じゃあこういうのはどうか」と新たなアイデアを閃くことも多い。必然的に、思考はどんどん拡張していく。

 自分Aと自分Bというのはどう分けているのかというと、前回の繰り返しになるが、「合理的っぽい自分」と「本音っぽい自分」という二つの軸をイメージしたものになっている。なので自分Bから話がスタートすることもある。どちらも「っぽい」であって、そんなにはっきり分かれているわけではなく、よく考えるとこれ逆だったのではということもある。どっちがどうというより、二つの軸で考えるということが肝心である。


 字数カウントも大事な要素になっている。見た目としてはこういうことになる。


 意義は前回書いたので繰り返さないが、結構馬鹿にならない影響がある。必ず100字以上140字以下で書くぞ、というようなルールを設けているわけではないし、実際その字数に至っているのはせいぜい半分くらいではないかと思うが、目安があることで常に「まだ不完全だからもうちょっと考えられるなら考えよう」という意識を持つようになっている。

 また、字数カウントによる目安というのはきちんと文章化して書いていなければ意味を成さないので、ここでも「人が読める文章」を書こうというインセンティブが働いている。


 なお、各ノードはそれぞれ作成日時と編集日時が記録されており、そのことによって次に紹介するタイムライン機能が実現されている。


タイムライン



 右側からスライドインしてくるタイムライン画面は、見た目に明らかな通りTwitterのタイムラインを参考にしたものである。

 ここで直接編集はできないが、ダブルクリックすればアウトライナーの当該ノードがフォーカス状態になってすぐ編集に取り掛かれるので、編集と閲覧の行き来は簡単である。

 タイムライン機能を考えた最初の動機は、ツリー構造とは別に「考えた順」に並べたいという気持ちが前々からあったことだ。アウトライナーは内容を基準としてツリー状に形を成していて、いつでもどこにでも書き加えられて書き加えるほど成長していくのは良いのだが、その場所から離れてしまうと「さっき考えたあれ」に戻るのがまあまあ面倒である。データの構造としては内容が基準になっていて良いのだが、それはそれとして「最近追加または編集したノード」が時系列順に並んでほしい。そういうことから、アウトライナーのノードに日時を記録し、それを元に時系列に並べたビューを作ればいいという構想が浮かんだ。そこにTwitter風にしたら面白そうというアイデアが加わってこういう形になった。

 さて今まで自分が書いたメモをずらっと並べるということは幾度となく試みたのだが、どうにもしっくりきていないところがあり、その原因は何かしばらくわからなかったのだが、多分「絵がない」ということだったのだと思う。ツイート履歴ならずっと見ていられるのだが、それはおそらく本文の隣にアイコンがあるからである。自分自身の(あるいは特定のアカウントの)ツイートを追う限り、ただ同じアイコンがひたすら並んでいるのだからアイコンに情報は何ひとつ含まれていないのだが、しかしアイコンを取り払ってしまえばいいかというとそれはそうではない。ただただ文字が並んでいるのを見ていると、内容がどうであるかには関係なく正直うんざりしてくる。私の中ではそれは文が読みやすいか否か以前の問題なのだろうと思う。

 また、今は親ノードのIDに対して@を付けてメンションを飛ばしている風の見た目にしているが、最初はそうしていなかった。メンション風にする前、タイムライン上の各書き込みはそれぞれ別の話題に対しての書き込みなのに、宛先を明示していないと続けて読もうとしてしまい、頭が混乱していた。そのことに気がついたのでこの形にしてみたのだが、そうすると、見ただけでどこ宛てかはわからなくとも、宛先を表示していれば「どこかの何かに宛てている」ということが前提となるので、文脈の混在が気にならなくなった。それは普段、Twitterのタイムラインで当たり前にやっている脳の処理であろう。


マップ


 左側の平面配置は、アウトライナー部分のアウトラインについて、日付ノードを除いたものをCSSでいい感じに整えたものだ。アウトライナーでの表示と見比べるとこんな感じ。



 各階層について、兄弟ノードは横方向、子ノードは縦方向に並んでいる。各ノードのサイズは文字数と横方向の個数に応じて適当に伸縮する。階層が深くなると背景色が濃くなる(なんとなくそうしている)。

 私が作ったものを他の人が今ぱっと見てわかりやすく思うかは微妙なところだと思うが、私にとっては自分で作ったアウトラインが変形しているので(つまり書いてある内容は既に一度頭に入っている)、ひと目で全体の構造がわかるというありがたみを感じている。平面上にみっちり敷き詰められた状態で、更に各項目について文字数が多すぎるものはスクロールするようにしているので(項目のブロックが縦長にならないようになっている)、画面にはかなりの情報量が入る。

 また、topicのノードについて背景色を変えているように、data-type属性の値(≒アイコンの種類)によってCSSを変えて見やすくすることもできる。例えば結論用のアイコンを作って背景色を赤系統にする、ということをしている。

 なお、これも各項目をダブルクリックすればアウトライナーのノードがフォーカスされるのですぐ編集に取り掛かることができる。


簡易検索

 現状、AND、OR、NOT検索はできないが、特定のキーワードを含むノードをピックアップすることはできるようにしてある。

 検索を実行すると、アウトライナー画面は該当するノードの背景色が黄色くハイライトされ、タイムライン画面は該当ノードだけ表示されるようにフィルタリングされる。タイムラインは他に期間指定とdata-type属性(≒アイコン)でフィルターできる。

 あと全データから「#」を付けた文字列を取得してオートコンプリートを設定しているので(検索欄をクリックしたり↓を押したりすれば候補が出る)、Twitterのようにハッシュタグを使うこともできる。

 必要が生じれば、AND、OR、NOT検索をはじめもっと細かい高度な検索も実装するかもしれないが、今のところは別にいいかなという感じでいる。



 細かいところまで色々書いたが、重要なのはCtrl+←/→という簡単な操作でノードの属性を変えられるようにしたことと、アウトライン構造を維持したままアウトライナー的でないビューを実現したことだ。自分Aと自分Bその他の切り替えに何クリックも必要だったら続かないだろうし、せっかくメモが捗っても書けば書くほどビューに難を感じてしまったらしょうがない。

 今までアウトライナー系のツールは色々と作っており、どれもその時点では自分の中で革新的だったのだが、今回が一番会心の出来という感じがする。データ構造や必要な操作としてはシンプルで、自力でやらなければならない処理はほとんどなく、それでいて今まで抱えていたもやもやを一度に晴らせるものになった気がしている。


 ちなみにこのツールの保存形式はOPMLなので、Dynalistなど他のアウトライナーにそのままインポートできる(ただしdata-type属性は消失する)。