Jupyter Notebookのようなもの(あくまで個人の感想です)をメモ帳・ブラウザ・gitで実現する


アプリをインストールせずに、オフラインでMarkdownをhtmlに変換してみる

前回、 上記記事を書きましたが、これを発展させて Jupyter Notebook のような、プログラムを実行しながら可視化してノートを書けるものを作りました。

リポジトリからhtmlとjsファイルをダウンロードしてローカルで実行する形式ですが、デモサイトを以下に用意しています。
すぐに確認したい方はどうぞ。
サイト内のドロップダウンリストから「JS Notebook (Markdown)」を選択して、「👀View」ボタンをクリックしてください。
https://shellyln.github.io/menneu/playground.html

※デモサイトでは、ユーザー入力のJavaScriptは実行されないようになっています。

実行イメージ



(中略)

編集イメージ

タイトルにメモ帳と書きましたが、流石に見辛いのでMeryを使用しました。
(メモ帳でも無理ではないです、知らんけど)

記法について

基本はマークダウンですが、%%%( ... )でLispのスクリプトを展開します。
また、Lispのスクリプト内では、LSXの記法により、DOMツリーが表現できます。
LSXの名前からお察しかもしれませんが、これはJSXの代替記法となっており、標準のhtmlタグ以外に、コンポーネントを処理できます。
下のイメージ内のMathChartNotebookJsLispがコンポーネントです。

  • 注意: LSXが有効なのは %%%( ... ) のブロック内です。
    コードブロックのLisp(%%%(Notebook """Lisp ... """))では利用できません。


※ 実物のコードはリポジトリ、またはデモサイトから参照ください。

マークダウンのコードブロックをJsLispで囲むことで、コードを実行したうえでhtml化します。

%%%(Notebook """Js@{(module "foo")}
```javascript
const x = 12345;

module.exports = function() {
    return x;
}

return x;
&#96;&#96;&#96;   <--- バッククォート × 3 です
""")

上記のコードブロックは、Jsの属性として module: "foo" が渡されています。
このブロックで、CommonJS形式でエクスポートした値・関数などは、他のブロックから require('foo') でインポートできます。
Lispブロックでも同様にインポート・エクスポートの記述ができます。
さらに JavaScript間、Lisp間だけでなく、両者の間で相互のインポート・エクスポートが可能です。

エクスポートされた値は、コードブロック外のLispコードでもrequireが可能となっています。
この機能を使用して、コードブロック内の結果を表やグラフとして可視化しています。

保存

gitリポジトリにコミットすれば、履歴管理も完璧です。

長所

  • ダウンロードして、メモ帳で開くだけなので編集が手軽。
  • 所詮テキストでしかないので、コピペが楽。

欠点

  • 所詮テキストでしかないので、実行結果をキャッシュしておけない。
    htmlを開くたびに再計算されるので、もし、非常に長時間掛かる処理があると無理がある。
  • 可視化の方法が、今のところChart.jsのグラフとMarkdown・htmlの表しかない。
  • コードブロック内のコードはデバッグできない。

追記 (20118/10/7)

各Markdownエディタの lisp ハイライト対応があまりに酷いので、 コードブロックの言語に js と書くことができるようにしました。
VSCodeではなぜか、割ときれいにハイライトされます。(Bracketsではいまいち)
混乱するのでお勧めはしません。


%%%(Notebook """Lisp@{(module "boo")}
```js                          <--- Lispのブロックですが、ここに「lisp」ではなく「js」と書けます
($concat "abc" "def")

($defun fac (n)
    ($if (== n 0)
        1
        (* n ($self (- n 1))) ) )

($defun multipy (x y)
    (* x y) )

(multipy 4 (fac 3))
&#96;&#96;&#96;                <--- バッククォート × 3 です。
""")

CDNから利用できるようになりました (2018/10/16更新)

以下のhtmlでリポジトリからファイルをダウンロードせずにお試しできます。

Notebook.html
<!DOCTYPE html><head><meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]"></script>
</head><body><script type="text/markdown">

# JS Notebook

%%%(script (@ (src "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML") (crossorigin "anonymous") (async)))
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/articles/js/notebook.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/articles/js/menneu.min.js" onload="start({title: 'My Notebook 1'})"></script>
</body>