1 ポイント 投稿者 GN⁺ 2024-11-19 | 1件のコメント | WhatsAppで共有
  • ブラウザが実行する単一のHTMLファイルだけで、データ探索、分析、可視化、組版、配布を1つの文書にまとめ、従来のノートブック→出版ツール→PDFという流れを短縮できる
  • 中核となる実装は、stylescriptを画面に表示するechoセルcontenteditable、Observable Runtimeを組み合わせ、編集可能なリアクティブセルを作る方式
  • cell(name, inputs, definition)はObservableの依存性モデルに従い、counter、FizzBuzzレンダリング、隠しセル、出力のない中間値セルのように相互接続された実行単位を構成する
  • 同じHTML文書内でObservable Plot、TeX、Markdown、Graphviz、WASMベースのSQLite、PyodideベースのPython、WebRベースのR、Observable Inputs、Mutable状態までデモしている
  • 成果物は別プラットフォームなしでブラウザ上で実行される科学・技術文書となり、実装はその後@celine/celineライブラリとして公開された

単一HTMLファイルでノートブックと出版の分離を縮める

  • HTMLは組版には広く使われているが、データ探索・分析・可視化プラットフォームとしては相対的にあまり活用されてこなかった
  • 一般的な作業フローは複数のツールをまたぐ
    • JupyterRStudioPluto.jlObservableのようなインタラクティブノートブックで探索・分析・可視化を行う
    • TypstOverleafLaTeX、WYSIWYGエディタのような出版プラットフォームに移して組版する
    • 配布のために.pdfとしてエクスポートする
  • 1つのHTMLファイルがこの3段階を担えば、手作業の手順、CLIツール、CI段階、サードパーティープラットフォームへの依存を減らせる
  • 実装はAnton ZhiyanovのIn-browser code playgrounds、Cristóbal SciuttoのSelf-modifying HTML notesQuartoObservable Frameworkから強い影響を受けている

編集可能なセルを作る

  • 最初の段階は、echo CSSクラスでstylescript要素を文書内にそのまま見えるようにする方式
  • シンタックスハイライトを内蔵したフォントとcontenteditable属性を加えると、基本的なコードエディタのように使える
  • contenteditableが適用されたscriptは、フォーカスを失うと再評価される
    • 既存のscriptを複製して新しいscript要素を作り、元の要素を削除する
    • evalimport文を含むコードでは動作しないため、この方式が必要になる
  • Observableベースの実行のために2つのライブラリを読み込む
  • グローバルにはlibrarycellの2つのシンボルだけを公開する

Observable Runtimeベースのリアクティブデータフロー

  • cell(name, inputs, definition, observerVisibility)関数は、Observable Runtimeのモジュールスコープを使ってセルを定義する
  • 同じ名前の変数がすでにあれば既存の変数を取得し、なければ新しい変数を作って定義する
    • この構造により、contenteditableセルを再評価すると新しい定義が接続先のセルへ伝播する
  • Observable Inspectorはセル出力をscriptブロックの上に表示するために使われる
  • counterセルは1秒ごとに数値を出力する非同期ジェネレータとして構成される
    • scriptid属性とcellname引数が同じ
    • 初期値iを変更してフォーカスを外すと、新しい値が反映される
  • counterに依存するセルも作れる
    • Hypertext Literalを読み込み、counter値をFizzBuzz形式でレンダリングする
    • htlはHTML5パーサーを実装し、自動エスケープ、イベントリスナー、スタイルオブジェクト、DOMノードのような非シリアライズ値の補間を処理する

表示セル、隠しセル、出力なしセル

  • echoクラスを付けなければ、セル定義を隠しつつ出力は観察できる
    • こうしたセルはレンダリングプリミティブとして使える
  • 出力自体を表示しないセル型も作れる
    • silent(name, inputs, definition)observerVisibilityを非表示に設定し、中間値やデータ構造の保存に使える
  • セルは宣言順序に関係なく動作できる
    • 例ではreallyNegativeセルが後から宣言されるnegativeセルに依存する
  • 同じセル値はより複雑な出力にも活用される
    • Observable Plotを読み込み、数値配列を折れ線グラフとして描き、counter % 40の位置に縦のルール線を表示する

文書・可視化出力の拡張

  • セルは任意のDOM要素を返せる
  • TeX、Markdown、Graphvizのデモはそれぞれ異なる形の要素を返す
    • texセルはspan要素を返す
    • mdセルはtable要素を返す
    • dotセルはsvg要素を返す
  • セルはPromiseを返したり、Errorを投げたりできる
    • Observable Inspectorは実行中のセル外側のdivobservablehq--runningクラスを適用する
    • エラーのセルにはobservablehq--errorクラスを適用する
    • 文書はこの状態に合わせてスタイルを指定する

ブラウザ内のSQLite、Python、R

入力と可変状態

  • viewofセル型はObservable Inputsと併用するために作られた
  • viewofは2つのリアクティブセルを宣言する
    • NAME: 入力の値
    • viewof NAME: DOM要素そのもの
  • 入力をセルの上に表示するには、セルのidviewof NAMEに設定する
  • 例ではInputs.range([0, 100], { step: 1 })で範囲入力を作り、rangePlotセルがその値に応じて更新される
  • Observable Inputsの動作方式はやや難解で、Synchronized Inputsデモが参考になる
  • 純粋関数型のデータフローだけでは足りない場合に備えて、mutableヘルパーも作られた
    • mutableは、値が変更されたときに新しい値を出力するMutableオブジェクトを登録する

ライブラリ公開と発表用スライド

  • この実装は当初incelという名前を考えていたが、その後celineと呼ぼうとしていた
  • ライブラリは@celine/celineとして公開されている
  • この文書はSydJSでデモされた
  • 文書をスライドショーに変えるためのコードも含まれている
    • Shift+N: スライドショー開始または次のスライド
    • Shift+B: 前のスライド
    • Shift+E: スライドショー終了
  • 実装ソースはsource codeとして公開されている

1件のコメント

 
GN⁺ 2024-11-19
Hacker News の意見
  • 記事の前提には強く同意する。HTML は計算型ノートブックの優れた基盤になり得る。
    ただし、ここでの実装上の選択は好みではない。動的・リアクティブな HTML は、これよりはるかに宣言的に作れるし、Observable は素晴らしいものの、標準 JavaScript から外れる面がある。
    Heximal というリアクティブ HTML システムを作り始めていて、将来的にはノートブック対応も入れる予定だ。HTML テンプレートとカスタム要素をベースにした宣言的システムで、その上に TC39 Signals 提案に基づく式/リアクティビティの仕組みを載せる構成になっている。
    https://github.com/elematic/heximal
    HTMX、Tangle、Curvenote、Polymer を混ぜた感じに近く、HTML がもともとリアクティブだったならこういう姿だったのではと思う。グラフィック編集やノートブックのユースケースにはかなり合うと見ている。

    • 「Observable は素晴らしいが標準 JS から外れる」というのはフロントエンドには当てはまるが、下層のランタイムは単に JavaScriptを実行している。ソースコードも、MIT ライセンスの acorn パーサーに完全に収まる些細なマクロが付いた JavaScript に近い。
      そのため Observablehq では通常の JavaScript デバッグ式がきちんと動作する。
      https://github.com/observablehq/parser
      Observable ランタイムが好きなので、フロントエンドのソースとコンパイル後の純粋な JS 表現の間を双方向に変換できるデコンパイラも作った。
      https://observablehq.com/@tomlarkworthy/observablejs-toolcha...
    • ここで Observable Framework まで考慮しているのか気になる。3月に出たもので、主な特徴の一つは Observable Notebooks で作られた構文ハックではなく、標準 JavaScript を使う点だった: https://observablehq.com/blog/observable-2-0#a-better-develo...
  • 本当に素晴らしい。特に Python と SQLite のデモが良かった。Web 経由の編集ループ(TTW)から始めて、それを quine と呼んでいる点は興味深い。妥当ではあるが、最大の弱点は永続性だ。
    TiddlyWiki も実質的に同じことをしているが、作業の保存が厄介だ。何かを永続化するには、結局は別のヘッドレスサーバープロセスが必要になるからだ。
    似たようなものを作りたいと思ったときは[0]、個人的には永続性から始めた。そしてそれは当然、ファイルを意味していた。プログラマー向けエディタで編集し、ファイルシステムで保存・配布できるプレーンテキストファイルだ。こうすれば、ブラウザ内にプログラマー向けエディタを再実装しなければならない問題を避けられるが、それは簡単ではない。
    代わりに高速なサーバーを書く必要が出てくるが、それはそれでかなり面白い問題でもある[1]。ここでは基本的な contenteditable セクションを使ってその問題を回避しているが、永続性の次に大きな問題だ。
    埋め込みスクリプト内で export できない点も、同じ壁に見える。グローバルな window オブジェクトを散らかしたくないなら、こうした機能があるとよいし、私のユースケースではコード生成もより簡単になるだろう。
    0 - Literate Markdown: https://simpatico.io/lit.md
    1 - Reflector、Markdown を変換・圧縮・キャッシュし、ファイル監視による無効化を行う小さな node サーバー: https://simpatico.io/reflector

  • 注ぎ込まれた思考と努力は尊重するが、このアプローチのユーザビリティはひどい。探索的データ分析をしようとしている最中に、なぜスタイリング要素まで気にしなければならないのか分からない
    Jupyter Notebook のようなツールがうまく機能する理由はまさにここにある。それでも、好奇心を持って代替的なアイデアを実装した点は高く評価する

    • 作者: 自分でも残念だが、この方式のユーザビリティがひどいという点には同意するし、だからこそ @celine/celine を作った動機のかなりの部分はそこにあった(https://maxbo.me/celine、つまり記事をライブラリとしてパッケージ化したもの)
      探索的データ分析プラットフォームとしては、まだ十分ではない。Observable Notebooks のような完全な Web コードエディタの即時的なリアクティビティもないし、ファイル監視ベースのホットリロードを提供する Observable Framework でもない。Deno + VSCode 向けの新しい Jupyter カーネルもかなりスムーズな体験を提供している
      だから探索分析向けのユーザビリティは、うーん……悪いという点には同意するが、配布のユーザビリティはそこまで悪くないと思う。むしろ良い。単なる単一ファイルだからだ。誰かにグラフやデータ加工の結果を送りたいときに、巨大なツールチェーンを維持したり、サードパーティサービスにお金を払ったりする必要はなく、HTML ファイルを1つ Slack に投げるか、どこかにホストすればよい
      分析結果をスタイリングできる柔軟性があるおかげで、ブログや研究論文のようにスタイルが重要な環境にも公開できる
    • 一見すると、これを「探索的 DOM 分析」の方向に位置づけようとしているように見える。紹介デモは、構造と基本要素を作りながら作業していく点で Scheme/Smalltalk の雰囲気があり、ivoryred に変えると構文ハイライトがリアルタイムで変わる場面がそれを示している
      ここに至った背景は理解できるが、JavaScript フレームワークやライブラリをブラウザでもっと簡単にいじれないのは残念だ。結局はただの JS なのだから、軽量な環境で素早く実験できるべきだ。このアプローチはその点で強みがある
      HTML/JS の遊び心があり実験的な可能性を取り戻す方法だ。TS、rollup、webpack のようなものより、こういう試みがもっと増えてほしい
      追記: もう少し読んでみると、これはデータ分析用として提案されている。その用途にはあまり合わないと思う
    • 「探索的データ分析だけをしようとしている最中」とは言うが、核心は探索的データ分析を行い、その結果を簡単に公開できる統合プラットフォームを持とうということではないかと思う。使い捨ての Jupyter Notebook 向けではない
      使い捨てで終わらない Jupyter Notebook の代替には大きな価値があると思う。今のユーザー体験が本当にひどいことは改善できる。問題はこの構成が Jupyter Notebook の JSON の混沌よりましかどうかだが、個人的にはましだと思う側だ
  • Lit の元作者が最近 Google を離れており、私の知る限り、これと非常によく似たものに取り組んでいる
    https://github.com/elematic/heximal

    • 彼がその後取り組んでいるものを公開していたとは知らなかった。教えてくれてありがとう
  • この記事の形式が気に入った。土台から始めて、興味深い何かへと積み上げている。依存関係の塊や、あちこちのフレームワークをつなぎ合わせる大げさな流れではない
    追いかけるには、提示された断片をコピー&ペーストして、段階ごとにどう動くのかを理解すればよさそうだ。自分がこういうものを書くなら、org-mode のリテラルプログラミングで書いたうえで HTML にエクスポートし、ブログ記事にしたと思う
    ただし、組み込みの構文ハイライトを持つフォントについては、今でも疑問が残る

  • リアクティブ HTMLと言っているが、ほぼ全部 JavaScript ではないのか、それとも何かを誤解しているのだろうか?

    • インタラクション/リアクティブな部分は JavaScript だが、ノートブックは自己完結した HTML ファイルの中に実装されている。文書構造から編集、表示まですべて処理する
      ブラウザを除けばサードパーティソフトウェアに依存せず、HTML がそうであるように長持ちし、移植可能で、使いやすい
    • 「なぜ皆ブラウザでノートブックを動かすために Colab や Observable を使うのだろう? ともあれ、難しい部分には Observable を使う代替案を出します」という感じだ
  • 近いうちに、この種の HTML ノートブックを Raku で、あるいは Raku 向けにサポートしてみようと思っている
    現在の Raku の「ノートブックソリューション」は Jupyter ベースか Mathematica ベースだ

  • このプロセスにWeb技術を使って複雑にする理屈がよく分からない。追加された複雑さは何を解決するのか? むしろプロセスを遅くし、オートコンプリート、スニペット、拡張機能のような必要な機能をなくす方向に近い
    そのうえ、ほかの人がこの設定に慣れていない可能性が高いので、共同作業もさらに難しくなる
    環境は一度だけ設定しておき、技術の変化に合わせて小さな改善だけを加えながら使い続ければよい
    n/vimユーザーなら、次で十分できる。1- データ探索: https://github.com/untitled-ai/jupyter_ascending を使ってテキストをJupyterノートブックにつなぐ。jupytextを使うので、テキストエディタで効率よくコードを編集して実行できる
    2- 執筆: LaTeX用に https://github.com/lervag/vimtex を使える
    ここにtmuxとtmuxpを重ねれば、プロジェクトを即座に開ける。Emacsではorg mode[1][2]および/またはAuctexで滑らかなプロセスを作れる
    [1] https://sqrtminusone.xyz/posts/2021-05-01-org-python/
    [2] https://martibosch.github.io/jupyter-emacs-universe/

    • ブラウザでJupyterノートブックを起動すると、どんな技術を使っていることになるのか? OPのWebサイトを開くと、どんな技術を使っていることになるのか?
    • 概ね良い指摘だと思う
      ただ、Pythonがあまり好きではないので、Python中心ではないツールを使いたい。だからRakuとMathematicaの話をした
      ちなみに https://github.com/imbue-ai/jupyter_ascending を教えてくれてありがとう
    • 同意する。リアクティブなノートブックを望む人は、Emacsを真剣に検討すべきだ。Emacsをいくつかの用途だけに使うユーザーも多いが、リアクティブなノートブックがその一つであることはよくある
  • この記事の前提、つまり HTMLが科学的な文章の配布媒体として十分に活用されていない という点には概ね同意する
    これに関連するWill Crichtonの最近の取り組みがある
    https://willcrichton.net/nota/
    https://willcrichton.net/notes/portable-epubs/

  • 最近はノートブックが盛り上がっている。私たちも TypeScriptノートブック 版をリリースしたが[1]、トレードオフではかなり別の方向を選んだ
    私たちはバックエンドのnodeコードを実行したいので、この記事の方式やObservableとは違って、ブラウザ環境で実行しようとはしていない。それでも、多くのアプリケーションではこのアイデアのほうがより良い解決策になり得る
    作者に拍手を送りたい
    https://github.com/srcbookdev/srcbook