はじめに
Emacsのeinというパッケージを用いることで、EmacsからJupyter Notebookを編集し、表示することができる。
実行イメージは以下の通りである。
ein(emacsからjupyter)は便利なのでぜひ pic.twitter.com/yBeAucc1n7
— mat (@ballforest) August 21, 2020
Emacsから直接Jupyter Notebookが編集できるので、ブラウザにはない各種補完機能やカーソルジャンプ、undoなど充実したEmacsの編集機能を継承して使えるので便利ということである。
本記事ではその設定をメモしておく。
事前準備
1. jupyterをインストール
pip3 install jupyter
2. MELPAからeinをインストール(必須)
M-x package-install RET ein RET
設定
(eval-when-compile (require 'ein) (require 'ein-notebook) (require 'ein-notebooklist) (require 'ein-markdown-mode) (require 'smartrep)) ;; (add-hook 'ein:notebook-mode-hook 'electric-pair-mode) ;; お好みで ;; (add-hook 'ein:notebook-mode-hook 'undo-tree-mode) ;; お好みで ;; undoを有効化 (customizeから設定しておいたほうが良さげ) (setq ein:worksheet-enable-undo t) ;; 画像をインライン表示 (customizeから設定しておいたほうが良さげ) (setq ein:output-area-inlined-images t) ;; markdownパーサー ;; M-x ein:markdown →HTMLに翻訳した結果を*markdown-output*バッファに出力 (require 'ein-markdown-mode) ;; pandocと markdownコマンドは入れておく ;; brew install pandoc ;; brew install markdown (setq ein:markdown-command "pandoc --metadata pagetitle=\"markdown preview\" -f markdown -c ~/.pandoc/github-markdown.css -s --self-contained --mathjax=https://raw.githubusercontent.com/ustasb/dotfiles/b54b8f502eb94d6146c2a02bfc62ebda72b91035/pandoc/mathjax.js") ;; markdownをhtmlに出力してブラウザでプレビュー (defun ein:markdown-preview () (interactive) (ein:markdown-standalone) (browse-url-of-buffer ein:markdown-output-buffer-name)) ;; smartrepを入れておく。 ;; C-c C-n C-n C-n ... で下のセルに連続で移動、 ;; その途中でC-p C-p C-pで上のセルに連続で移動など ;; セル間の移動がスムーズになってとても便利 (declare-function smartrep-define-key "smartrep") (with-eval-after-load "ein-notebook" (smartrep-define-key ein:notebook-mode-map "C-c" '(("C-n" . 'ein:worksheet-goto-next-input-km) ("C-p" . 'ein:worksheet-goto-prev-input-km))))
実行手順
1. M-x ein:run を実行
Notebookを作成したいディレクトリを選択できるようになる。ディレクトリを決定するとJupyterがバックグラウンドで起動する。
2. カーネルを選択
要するにPythonのバージョン指定。
3. ファイル/ノートブック一覧から、ノートブックのところの[Open]をRET
既存のNotebookが起動する。
4. Notebook新規作成は[New Notebook]をRET
使い方
主なキーバインドとコマンド一覧を以下に示す。
とりあえず、セルに何か書いたらC-c C-cすれば、セルが評価される。
キーバインド/コマンド | 説明 |
---|---|
M-x ein:run | jupyterを起動 |
C-c C-t | 当該セルの評価モードをPython->MarkDown->rawの順に切り替える |
C-c C-n | 1つ下のセルに移動 |
C-c C-p | 1つ上のセルに移動 |
C-c C-e | 当該セルの表示をトグル |
C-c C-c | 当該セルを評価(Pythonのみ; Markdownは不可) →C-uをつけて実行するとすべてのセルを先頭から評価できる |
C-c C-k | 当該セルを削除 |
C-c C-a | 新規セルを当該セルの上に作成 (C-uを先につけるとMarkdownで作成) |
C-c C-b | 新規セルを当該セルの下に作成 (C-uを先につけるとMarkdownで作成) |
C-c C-s | 当該セルを分割(split) |
C-c C-m | 当該セルをマージ(merge) |
C-c C-l | 当該セルの出力をクリア |
C-c C-S-l | 全てのセルの出力をクリア |
C-x C-s | 現在のnotebookを保存 |
C-x C-w | 現在のnotebookを別名保存 |
M-x ein:notebook-save-to-command | 当該ノートのコピーを、名前を付けて保存 |
C-c C-x C-r | notebookのセッションを再起動する →番号をクリアしたいときに使う |
M-x ein:stop | jupyterを終了 |
Markdownのプレビューには、設定ファイルに書いた ein:markdown-preview を使うことでブラウザ上のプレビューが可能である。応用すればewwやemacs-w3m上で表示させ、Emacs内で完結させることもできるだろう。
おまけ:Einにおける数式表示
Markdown中にLatexで記述した数式をプレビューするための設定。インライン表示ではない。
実行イメージはこちら:
だいたいこんな感じ pic.twitter.com/nAl4nu9GlS
— mat (@ballforest) November 12, 2020
設定
M-x my-markdown-preview-latexとするとバッファがポップアップして、そこに数式が表示される。
(defun my-markdown-preview-latex () "Preview LaTeX from the current cell in a separate buffer. Handles only markdown and code cells, but both in a bit different ways: on the former, its input is being rendered, while on the latter - its output." (interactive) (let* ((cell (ein:worksheet-get-current-cell)) (text-to-render (cond ((ein:markdowncell-p cell) (slot-value cell :input)) ((ein:codecell-p cell) (plist-get (car (cl-remove-if-not (lambda (e) (string= (plist-get e :name) "stdout")) (slot-value cell :outputs))) :text)) (t (error "Unsupported cell type")))) (buffer (get-buffer-create " *ein: LaTeX preview*"))) (with-current-buffer buffer (when buffer-read-only (read-only-mode -1)) (unless (= (point-min) (point-max)) (delete-region (point-min) (point-max))) (insert text-to-render) (goto-char (point-min)) (org-mode) (org-toggle-latex-fragment 16) (special-mode) (unless buffer-read-only (read-only-mode 1)) (display-buffer buffer '((display-buffer-below-selected display-buffer-at-bottom) (inhibit-same-window . t))) (fit-window-to-buffer (window-in-direction 'below)))))
おわりに
EmacsからJupyter Notebook、一度試してみる価値はあると思う。