Noratetsu Lab

動じないために。

タグの定義・詳細

TwoColumnOutliner

2カラム方式の自作アウトライナー。
旧題:Outline.html(仮)

アウトライナーを自分で作ることに成功した最初期のツール。
全てのノードにメタデータを持たせられる。あるノードをフォーカスすると、右側にそのノードのメタデータと子孫ノードが表示される。
ノードのドラッグアンドドロップ操作にものすごい労力を費やした。イベント処理が当時はよくわかっておらず、手探りで「こうすると動くらしい」をどうにか見つけていった。

関連記事

サンプル
https://noratetsu.deno.dev/archives/demo/TwoColumnOutliner/index.html

画像

Backlinks

他の「のらてつ製デジタルノートツール」カテゴリの語句

「TwoColumnOutliner」タグの記事一覧

2023/04/10

NTA-DIY:2ヶ月目①~アウトライナーを自作してみる~

 二ヶ月目の話に入っていきます。JavaScriptの勉強を開始して丸一ヶ月でアウトライナーの自作に挑戦しました。


 NTA-DIY:1ヶ月目⑩~初めてのノートテイキングアプリDIY~で書きましたが、一ヶ月が経つまでに多少独自性のあるメモアプリ的なものを自作するところまでたどり着きました。
 発想を具現化できる取っ掛かりをちょっと掴んだことで、色々なアイデアが思い浮かぶようになりました。少し前まで「JavaScriptって何が嬉しいの?」と思っていたNTA-DIY:前日譚②~JavaScriptを書けると何が嬉しいの?~わけですが、「超嬉しいじゃん!」という心境です。
 そんな中でふと、アイコンをクリックするとul要素が display:none; になるようにすればアウトラインの形は作れるな、と思い至ったことで、試しに作ってみようと考えました。最初から既存のアウトライナーを代替するものを作ろうと意気込んでいたとかではなく、思いついたから試さずにいられないという気持ちで取り組んでみたわけです。
 とはいえ、ただアウトライナー機能を再現しただけでは面白くないので、既存のアウトライナーに対して抱えているもやもやを解決するアイデアを実践できたら尚良いと考えました。こうして軽快な足取りで無謀な挑戦に踏み出してしまいました。

 私が普段アウトライナーを使う中でうまくいっていなかったことのひとつが、「引用をメモする」ということでした。例えば、太宰治が『正義と微笑』の中で書いた「真にカルチベートされた人間になれ」という一文をアウトライナーに書いておきたいとします。これが『正義と微笑』の読書メモの中なら話は難しくありません。「太宰治著『正義と微笑』」というような項目の下にペーストすればそれで終わりです。引用だとわかるように括弧で囲むか「> 」などを頭に入れるかすれば混乱は生じないでしょう。
 しかし引用は必ずしも読書メモのひとつとして書くわけではありません。WebページやTwitterなんかから取り出すこともあります。そうなると、然るべき親項目というのが無いパターンが発生します。形式的に「引用」とかいう項目の下位に「Twitter」などと作ってその下に貼り付けるというようなこともあり得なくはないですが、無意味に階層が深くなりますし、デイリーの項目を使っているならその中に書きたいこともあります。他のトピックの中に存在していてほしいこともあります。なんにせよ引用部分を親項目に囚われずに自由に移動させられたらその方が良いです。
 では、「真にカルチベートされた人間になれ」という項目の下に「太宰治」「『正義と微笑』」といった情報を入れてしまえばよいでしょうか。それはひとつの解決策で、それでいいと思えばそれでいいだろうと思います。ただ個人的には、それらの情報は「下位項目」なのかと考えた時に、ちょっと違和感を覚えてしまうところがあります。それらの情報が、他の「下位項目らしい下位項目」とフラットに並んでしまうことへの違和感です。これはごく個人的な感覚の問題に過ぎないことなので、その構造はおかしいとか言いたいわけではありません。単に私個人の納得いかなさを解消するために、私は自分で工夫しなければならないということです。
 もうひとつの解決策として、ノート機能を使って書くということがあります。これはとても現実的な方法です。それでも良いには良いのですが、しかし個人的にはすっかり納得できるわけでもありません。ノートを表示していると情報量が無闇に増えて煩わしく、畳むと今度はノート部分にどういう種類の情報を入れたのかがわからなくなるという問題があるのです。
 いっそのこと、全部項目に突っ込んで「「真にカルチベートされた人間になれ」(太宰治『正義と微笑』)」などとする手もあります。出典部分が短ければそれほど違和感はありません。ただ、どこかのWebページの一節みたいなことになると同梱はちょっと苦しい感じがします。普通にあり得るやり方ですが、ベストではないように感じてしまいます。

 要するに、ノードにメタデータを自由に設定できて、且つ、それらのメタデータの存在がひと目でわかるようにしたかったのです。
 それができるアウトライナーはひとつもないのでしょうか。いえ、少し前にメタデータの設定が可能なアウトライナーが誕生していました。Dave Winer氏のDrummerです。おそらくですが、メタデータを利用したスクリプトを自分で書けばメタデータの内容をアウトライン上に可視化することも可能だろうと思います。多分スクリプトによって可能になることは無数にあり、Drummerには果てしのない可能性を感じます。
 よって、自分の要求を満たすにあたり、Drummerをバリバリ使い倒すという選択肢もありえます。しかし当時はごく簡単なコードしか書けませんでしたし、Drummer用のメソッドの仕様を見ても何がなんだかわからなくて何もできませんでした。Drummerのデザインや操作感の癖に馴染むのが容易でないということもあり、とりあえずDrummerそのものを自在に活用するという道は諦めました。
 じゃあ、自分で作るしかないよね、ということになるわけです。

 ついでに、一般的なアウトライナーへの不満として「1カラムしかない」ということがあったので、その解決も試みます。画面の高さより離れた位置にあるノードを参照するにはいちいちスクロールしなければならない煩わしさをどうにかしたかったのです。なお、今なら例えばRemNoteは複数ファイルの同時編集が可能です。

 当時作ったもののスクリーンショットを貼っておきます。

画像

 実際にアウトライナーもどきを作ってみると、まあ一筋縄ではいきませんでした。
 アウトライナーっぽい動き(開閉やインデント)の再現だけなら、クリックイベントとキーボードイベントさえわかれば可能なので、それほど大変ではありません。「おお、『っぽい』ぞ」という感動は割と早く得ることができました。
 しかし、「編集したデータの管理」と「ドラッグアンドドロップ処理」を実装するのにはかなり頭を悩ませました。アウトライン操作というのは実装すると色々なイベントを実行することになるわけですが、どのタイミングでどうやってデータを更新するのかをきちんと考えなくてはなりません。
 おそらく最もシンプルなのは、DOMツリー自体をデータと見なして、それを丸ごとデータとして保存することです。アウトライン部分が入ったul要素のinnerHTMLをlocalStorageに突っ込むということです。確か最初はそうしていました。リロード時にはそのままul要素のinnerHTMLに代入し、中身のli要素などに各種イベントリスナーを設定する処理をしました。必ずしも処理が単純になるわけではありませんが、データの形式を考えずに済むという利点はあります。階層構造をどう管理したらいいのか当時はよくわかっていなかったのです。
 データの管理を複雑にしたのは、「メタデータがある」ということと「2カラムである」ということです。データの形式としてHTMLを使うとなると、メタデータの管理のためにはHTMLのカスタム属性を駆使する必要があります。そして2カラムあると片方のカラムの更新をもう一方に反映させなければなりません。一言で言うととにかく無謀だったのですが、しかしそれがモチベーションになっているわけなので、なんとか頑張って実現するしかありません。
 そこに更にドラッグアンドドロップが加わります。ドラッグアンドドロップ処理というのはなんとも複雑です。ドロップ時の処理が判別できるようにドラッグ中にスタイルを変更するようにしたのですが、そうなると「dragstart」「dragover」「dragleave」「drop」の四つのイベントをセットすることになりました。
 そして階層構造になっているもののドラッグアンドドロップなので、親要素を子要素の中にドロップするということを禁じる必要もあります。あっちもこっちも初めて知った概念の連続で、数限りないエラーと格闘する羽目になってしまいました。
 このブログは体験談として書いているので具体的なコードの説明はここではしませんが(別の機会にする可能性はあります)、とにかく沢山の試行をして無数のエラーを出しました。どれだけ失敗してもリスクはゼロなので気楽なものです。コードは最終的に1100行くらいになりました。
 一応形にはなりましたが、とても「出来の良いツール」とは言えず、処理の信用ならなさが自分でわかっているのでしっかり実用したわけでもありません。しかし「こういうものが作りたい」と思いつきさえすればある程度は脳内を再現できるという手応えを感じました。当時このツールを作ったことについて「気分としてはメタルキングを倒した感じ」と表現しましたが、今振り返ってもそうだなと思います。

 当時作ったものを全面リファクタリングしたサンプルがTwoColumnOutlinerにあります(例によってPC用です)。なお上記のスクリーンショットは当時のもので、今回のサンプルとはあちこち違っています。

 以下は「2ヶ月目」の話ではない余談です。
 コードの説明はしないと先述しましたが、サンプルはなるべくまともなコードに改めた上で公開すると決めているので、今回も頑張って書き直しました。
 これがおそろしく大変でした。「エラーの恐怖がつきまとうが一応動く」という状態から「エラーの不安なく動き、メンテナンスとカスタマイズが比較的容易である」という状態に自分なりに書き換えたわけですが、データの管理やDOM生成はどうするのが良いのか一から考え直すことになり、設計するのに想像以上に時間がかかってしまいました。
 結局、サンプル版では当初搭載した機能の半分くらいしか実装していません。いずれもこうすれば実装できるという見通しはついていますが、このツールを今後自分が使っていく予定は今のところないので、費やすに値する時間と労力の兼ね合いから再現は途中までにしました。当初作ろうとしたものは、内部処理をまともな形にするとなるとかなりの手間を生じるほど複雑だったということです。
 しかし、これをリファクタリングしようとしたことで、それまで知らなかったメソッドや思いつかなかったアイデアを様々獲得しました。この連載を書くことで読み手に何かプラスがあるかわかりませんが、私自身の得るものが非常に大きいので、この先も勝手に頑張っていこうと思います。(1ヶ月目を終えてからかなり間が空きましたが、単純にコーディングに苦労していただけでモチベーションの低下があったわけではないのでした)
 

2022/04/23

ツール製作日誌:三ヶ月で劇的ビフォーアフター①‡‡‡自作ツール紹介編

 JavaScriptの勉強を始めておよそ三ヶ月になる(1/27スタート)。この間に自分のデジタルライフは大きく変わっていった。


 まずHTML+CSS+JavaScriptの三要素を習得したことによって、ある程度実用的な情報管理ツールを作れるようになった。
 現時点で形を成しているツール・サイトが六つある。それらについて書いていくが、ツール名が「~.html」となっているのは「名無し」と同じ意味。

①Bookmarks.html(ブラウザ上)

画像

 ブラウザのブックマーク機能にどうもしっくり来ておらず、どうしてもリスト状でない形のブックマーク管理ツールが欲しかった。既存のブックマーク管理サービスは多機能過ぎ、しかも見た目もぴたりと好みにはまらないので、自分で作るほかなかった。
 この見た目と機能はHTML+CSSだけで作れるのでJavaScriptの勉強開始以前に既に完成していたのだが、データがHTMLに手打ちだったため整理があまりにも面倒だった。そこでCSVにデータを作ってJavaScriptで読み込んで要素を構築できたらどんなにいいだろうと思ったのが、JavaScriptを勉強し始めた動機のひとつである。
 コードの長さは130行。ブラウザ上での編集機能は無し。

②Cards.html(ブラウザ上→Electron)

画像

 CSVから要素を作れることがわかると、今度は他に整理がついていないものを同じ方法でどうにかしたくなった。その頃倉下忠憲さんのTextBoxの話を見聞きしていたこともあって、「すぐには使わないがいつか使えそうな気がするメモ」を溜めてピックアップするようなツールを作ろうと思ってこれができた。
 JavaScriptの勉強の最初の方で乱数を繰り返し使っていたので、乱数でメモをランダムピックアップするというのがその時点ではごく自然な発想の展開だった。
 作り始めた時点ではローカルのCSVからデータを構築してブラウザで見るという「メモビューワ」だったが、途中でlocalStorage(ブラウザへのデータの保存)の使い方を覚えたので「メモエディタ」にクラスチェンジした。それに伴いJSONの扱いにも慣れ、カードのメタデータを細かく設定したり編集履歴を保存できるようにしたり色々な機能を盛り込んだ。
 コードの長さは500行。

③Outline.html(ブラウザ上→Electron)

画像

 普段アウトライナーを使っていて、項目そのものに種類がないことが不便に感じる瞬間があり、それをなんとかできたらいいのになと前々から思っていた。例えば引用をメモする時に、引用文と引用元の情報とは見た目が明らかに違っていた方が良いといったことだ。例えばDynalistではカラー機能とCSSを組み合わせて書式を作るというようなことも不可能ではなく、色々工夫してはいたのだが、なんとなく納得しきれないところがあった。欲を言うとバレットが項目の種類ごとに別のアイコンになったらいいな、というようなことを思っていた。項目にメタデータを設定したかったのである。
 Drummerというアウトライナーが少し前に登場したのだが(アウトライナーの父、デイブ・ワイナー氏が開発)、各項目に完全に自由にメタデータを付与できることに衝撃を受けた。その上Drummerではなんとツール上でJavaScriptを操作できるので、多分勉強すればDrummer内で自分好みのデザインを作り出せるのではないかとも思うのだが、ワイナー氏の感性に最適化されたツールゆえに色々難しく、具体的に何をどうしたらいいのか見当がつかなかった。
 なので、もういっそ自分でアウトライナーを作ってしまえと思ってやってみたのがこれである。
 出来はどうかというと正直に言って微妙なのだが、とりあえずこのくらいのものは自力でなんとかなるらしいということがわかったのはものすごく大きな一歩になった。ドラッグアンドドロップ操作やショートカットキー設定、複数箇所を同期してデータ更新するといった、一段複雑な処理ができるようになった。気分としてはメタルキングを倒した感じである。
 コードの長さは1100行。倍以上に増えた。

④Fusen.html(ブラウザ上→Electron)

画像

 具体的なきっかけがあったかどうだったか忘れたが、ふと自由配置の付箋ツールを作りたくなって制作し始めたのがこれ。とにかく色々貼りたいと思った。
 アウトラインのブロックを動かせたら良いのにということはずっと前から思っていて、例えばExcel上にメモブロックとしてアウトライン機能付きのテキストボックスがあれば絶対便利だみたいなことをイメージしていた。Excel上に生み出すことはできないが、とりあえず画面上で自由に配置できたら色々使い勝手が良いだろうと思って付箋のひとつとしてアウトライン付箋を作ってみた。(なおデスクトップに貼っておけるタイプの付箋ツールとしてはsosuisenさんが開発していらっしゃるものが興味深い。)
 アウトライン付箋を作ったのは予想通り便利だったが、別にアウトライン付箋を貼りたいがためのツールではなく、他に画像、YouTube動画、mp4、mp3を付箋として貼れるようにした。お気に入りの絵画や音楽などを一度に視界に入れたかったからである。実際の画面は見せられない且つ適当なサンプルを用意するのがちょっと億劫なので見た目の紹介は省略。
 このツールを作ったときには「お気に入りのものを集める」以外の使い方はそんなに具体的にイメージできてはいなかったのだが、調べ物のメモに使ったところとても便利だった(上のスクリーンショットがその状態。なおメモの内容は誤りを含んでいる可能性がある)。「この情報をどのくらい視界に留めておきたいか」というようなことをコントロールできるのが良い。ページやカードで内容が分かれてしまうものだと、その点であまりうまくいかなかったのである。
 コードの長さは880行。

のらてつの茶の間(ミニブログサイト)

画像

 Twitter(ないしScrapbox)とブログの間の存在が欲しいと思って作った。
 ScrapboxやObsidianのリンクを参考に、「このノートでリンクにしているキーワード」「このノートに対してリンクしているノート」「他のノートではリンクにしているがこのノートではリンクにしていないキーワード」「このノートに対して言及しているがリンクはしていないノート」をガッと表示できるようにするなど色々工夫している。このサイトについては別途記事を書くと思う。
 サイトの挙動はいいのだが私の文章生産速度がそれに全く見合っていないのが目下の悩み。内容が遅々として増えていかない理由は明白で、プログラミングばっかりやっているからです。
 コードの長さは650行。エディタ機能がない割には長い。

⑥Plane Outliner(ブラウザ上) 

画像

 これについては先日記事を書いたので挙動についての言及は省略ツール製作日誌:「面のアウトライナー」
 デザインは茶の間を流用しているので、ツールの見た目としてそれまで恒例になっていた和柄からは離れたことになる。このブログや茶の間と同じ雰囲気なので特に違和感はない。3×3のマスにグレーを2段階使っているので背景はなくて正解という感じがする。
 「ここに来てやっと、初めに勉強した教材の意味がわかった」と感じる瞬間がしばしばあった。オブジェクトはこう使えばよかったんだとか、無名関数はこう使うのかとか、色々腑に落ちた。これまでのツールは馬鹿の一つ覚え的に同じやり方を繰り返していたところがあったが、ふっとそこから抜け出せるようになった感じがある。
 コードの長さは1900行。記述が圧倒的に多い。しかし多い割に随分クリアな感じがしている。

 このような感じで、プログラミング経験値ほぼゼロの状態から三ヶ月間であれこれやってきた。今回は作ったものの紹介までにして、次の記事でこの三ヶ月で起きた変化などについて書いていくことにする。
 

管理人

アイコン画像

のらてつ Noratetsu

キーワード

このブログを検索

検索

ブログ アーカイブ

2025
2024
2023
2022
2021