Jupyter nbextensions

JupyterNotebookのnbextensionを使ってみて覚えておくと便利な技術集を書きました。

<!-- MarkdownTOC -->

- インストール
- コンフィグ
    - コンフィグファイルの作成
    - ブラウザの指定
    - 自動保存
- nbextensions
    - インプット関連
    - アウトプット関連
    - マークダウン関連
    - jupyter設定関連
    - カーネル関連
    - 参考
- 関連
    - 参考一覧
    - 自分のページ

<!-- /MarkdownTOC -->


# インストール

[公式　ipython-contrib/jupyter_contrib_nbextensions](https://github.com/ipython-contrib/jupyter_contrib_nbextensions)

```sh
$ conda install -c conda-forge jupyter_contrib_nbextensions
```

cssとか落としてくれるので、これが一番楽

___
# コンフィグ
## コンフィグファイルの作成

```sh
$ jupyter notebook --generate-config
```


## ブラウザの指定

指定しなければデフォルトで開くブラウザでJupyterNotebookが開く。

今後キーバインドがかぶることがよくあるので、jupyter notebookを開くブラウザは「いつも使っていないもの」=「ショートカットキーがカスタマイズされていないもの」を選んでいる。

作成された`~\.jupyter\jupyter_notebook_config.py`の中の`#c.NotebookApp.browser = ''`という行を探してブラウザ指定。

* linuxであれば`c.NotebookApp.browser = u'/usr/bin/firefox %s'`
* windowsであれば`webbrowser.register`してやってから、レジスターされたブラウザを指定する。

```python:~/.jupyter/jupyter_notebook_config.py
import webbrowser
webbrowser.register('chrome', None, webbrowser.GenericBrowser('C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'))
c.NotebookApp.browser = 'chrome'
```

参考:
* [stack overflow - Launch IPython notebook with selected browser](http://stackoverflow.com/questions/15632663/launch-ipython-notebook-with-selected-browser)
* [ねこゆきのメモ - <Python, iPython> ipython notebookで起動ブラウザを指定](http://nekoyukimmm.hatenablog.com/entry/2015/12/14/132843)



## 自動保存

jupyter notebookはデフォルトで2分ごと？に保存をかけてくれる。
(以下で説明する`nbextension`の`autosavetime`で保存間隔変えられる)



`~/.jupyter/jupyter_notebook_config.py`に以下を書き込むと

* '--to script' で.pyファイル
* '--to html' で.htmlファイル
* '--to markdown' で.mdファイル
* '--to latex' でtexファイル

が作成される。


```python:~/.jupyter/jupyter_notebook_config.py
import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts
    ipynbが保存されるたびに[py, html, md, tex, pdf]を作成する。"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    base, ext = os.path.splitext(fname)
    check_call(['jupyter', 'nbconvert', '--to', 'script', fname], cwd=d)
    check_call(['jupyter', 'nbconvert', '--to', 'html', fname], cwd=d)
    check_call(['jupyter', 'nbconvert', '--to', 'markdown', fname], cwd=d)
    # check_call(['jupyter-nbconvert', '--to', 'latex', fname, '--template', 'jsarticle.tplx'], cwd=d)
    # check_call(['extractbb', base+'_files/*.png'], cwd=d)
    # check_call(['platex', '-interaction=nonstopmode', '-synctex=1', '-kanji=utf8', '-guess-input-enc' , base+'.tex'], cwd=d)
    # check_call(['dvipdfmx', base+'.dvi'], cwd=d)

c.FileContentsManager.post_save_hook = post_save
```

* TeXとかはうまくいかなかったのでコメントアウト。
* .texまでは作られるけど、環境によって.xbb作成されなかったりする。
* '--to pdf'もやってみたが、日本語pdfはスタイルの問題からpdfには直接できないみたい。
* TeXファイルだけ自動生成して、texから自分の手法でコンパイルするしかない？
* 以下の **TeXの生成** の章でTeX ->PDFやってる。
* スタイルを日本語版のjsarticleにする方法は次で説明。
* まだ英語だけの.ipynbで試してはいない。

```python
import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts
    ipynbが保存されるたびに[py, html, md, tex, pdf]を作成する。"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['jupyter', 'nbconvert', '--to', 'script', fname], cwd=d)
    check_call(['jupyter', 'nbconvert', '--to', 'html', fname], cwd=d)
    check_call(['jupyter', 'nbconvert', '--to', 'markdown', fname], cwd=d)
    check_call(['jupyter', 'nbconvert', '--to', 'latex', '--template', 'jsarticle.tplx', 'lualatex', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save
```



### TeXの生成
日本語を使う場合はメニューバーのExport as PDFは使えない。

なぜなら`\documentclass[a4paper,dvipdfmx]{jsarticle}`のdocumentclassが英語版で生成されるので。

そこでjsarticleをスタイルに適用したtexファイルを作成する

#### テンプレートファイル(jsarticle.tplx)使う

テンプレートファイル(ここではjsarticle.tplxとする)を用意すればjsarticleに書き換えて生成してくれる。

nbconvertコマンドを実行する際に、

* nbコマンドのディレクトリに`.tplx`ファイルが存在する
* nbconvertのオプションに`--template jsarticle.tplx`を指定する。
> `jupyter nbconvert --to latex --template jsarticle.tplx lualatex <filename> `を実行

具体的なやり方としては次のようにする。

~~1. `jsarticle.tplx`をtexの環境変数の通っているところ(platex.exeあるところなど)にいれておく~~
1. <...>\Anaconda3\Lib\site-packages\nbconvert\templates\latex`以下にjsarticle.tplxファイルを作成する。
> <...>は自分のAnacondaディレクトリ。僕の場合は`C:\tools\Anaconda3\`。
2. jsarticleに自動的に変えるコマンド`jupyter-nbconvert --to latex %1 --template jsarticle.tplx`をターミナルに打ち込む。%1がファイル名、%2はファイルベースネーム。
3. 画像をpngとしてエクスポートする。画像はワークディレクトリ以下のファイルベースネームをフォルダ名に下ディレクトリ以下に保存される。`extractbb %2_files/*.png`



```latex: jsarticle
% Default to the notebook output style
((* if not cell_style is defined *))
    ((* set cell_style = 'style_ipython.tplx' *))
((* endif *))

% Inherit from the specified cell style.
((* extends cell_style *))

%===============================================================================
% Latex Article
%===============================================================================

((* block docclass *))
\documentclass[a4paper,dvipdfmx]{jsarticle}
((* endblock docclass *))
```


参考:
[はしくれエンジニアもどきのメモ - Jupyter nbconvert（ファイル変換）メモ](http://cartman0.hatenablog.com/entry/2016/03/29/131903#sec-nbconvert)
[Qiita - Jupyter notebook で HTML も自動作成](http://qiita.com/junkoda/items/011d44dcc1c8bd0a936a)





#### SublimeText3でTeXのbuild
ここまではsublimetext-build形式で書いて、build(ctrl+b)で実行させた。(ゆえにファイル名が%1とか引数だったりするのである。)

```JSON:Jupyter2PDF.sublime-build
{
    "cmd":["Jupyter2PDF.bat","$file","$file_base_name"],
}
```

```batch:Jupyter2PDF.bat
@echo off
jupyter-nbconvert --to latex %1 --template jsarticle.tplx
extractbb %2_files/*.png
```

#### platex走らせる
ココより下は%1, %2を引数としてではなく、ファイル名に打ち直さないといけない。

4. platexをコマンドライン上で走らせる。`platex %2.tex`.styファイルがないとかわめきだすけど、すべてEnter押し続けて続行させる。
5. dvipdfmxをコマンドラインで走らせる。`dvipdfmx %2.dvi`

#### SumatraPDFでpdf開く
ここまででpdfが作成された。

6. pdfクリックしたときにtexソースに行きたいときはreuse-instanceでSumatraPDFを起動させる。`SumatraPDF -reuse-instance %2.pdf`









___
# nbextensions

nbextentionでチェックを入れたりすると`~/.jupyter/nbconfig/notebook.json`に設定が保存される。
僕の環境はこんな感じ

```python:~/.jupyter/nbconfig/notebook.json
{
  "code_format_hotkey": "Ctrl-Alt-D",
  "kse_rebinds": {
    "command": [
      {
        "action_name": "auto:autogenerated-function () {\n                    IPython.notebook.edit_mode();\n                    return false;\n                }",
        "from": "esc"
      }
    ],
    "edit": [
      {
        "action_name": "jupyter-notebook:run-cell-and-insert-below",
        "from": "alt-enter"
      },
      {
        "to": "alt-enter",
        "action_name": "auto:autogenerated-function () {\n                    var cell = IPython.notebook.get_selected_cell();\n                    var mode = cell.mode;\n                    cell.execute();\n                    if (mode === \"edit\") IPython.notebook.edit_mode();\n                    return false;\n                }",
        "from": "ctrl-enter"
      }
    ]
  },
  "limit_output": 1000,
  "stored_keymap": "sublime",
  "load_extensions": {
    "exercise/main": false,
    "collapsible_headings/main": true,
    "python-markdown/main": true,
    "autosavetime/main": true,
    "spellchecker/main": false,
    "dragdrop/main": true,
    "nbpresent/js/nbpresent.min": true,
    "highlighter/highlighter": true,
    "hide_input/main": true,
    "runtools/main": false,
    "hinterland/hinterland": false,
    "contrib_nbextensions_help_item/main": true,
    "keyboard_shortcut_editor/main": true,
    "init_cell/main": true,
    "splitcell/splitcell": true,
    "toggle_all_line_numbers/main": false,
    "freeze/main": true,
    "hide_input_all/main": true,
    "move_selected_cells/main": true,
    "nb_anacondacloud/main": true,
    "select_keymap/main": true,
    "nb_conda/main": true,
    "code_prettify/code_prettify": true,
    "ruler/main": false,
    "navigation-hotkeys/main": true,
    "limit_output/main": false,
    "printview/main": true,
    "nbextensions_configurator/config_menu/main": true,
    "jupyter-js-widgets/extension": true,
    "execute_time/ExecuteTime": true,
    "toc2/main": true,
    "scratchpad/main": true,
    "search-replace/main": false,
    "codefolding/main": true,
    "exercise2/main": false,
    "qtconsole/qtconsole": true
  },
  "kse_show_rebinds": true,
  "autosavetime_starting_interval": "5"
}
```


___
## JupyterNotebook設定関連


### Nbextensions edit menu item
`"nbextensions_configurator/config_menu/main": true,`
メニューバー`Edit`に`nbextension config`が追加され、それをクリックすることでnbextension画面に移れる。
通常ブラウザのアドレス欄に`localhost:8888/nbextensions/`と入力しなければならないところ、わかりやすくて便利。

<img width="300" alt="editmenuitem.png" src="https://qiita-image-store.s3.amazonaws.com/0/113494/6d96c1aa-2be7-9daa-39b5-0cf2811cb1da.png">


### Nbextensions dashboard tab
`"nbextensions_configurator/config_menu/main": true,`
JupyterNotebookホーム画面のメニューバーにnbextension設定メニューが現れる。

`Nbextensions edit menu item`とどちらかだけでも設定しておきたい。

<img width="440" alt="dashboard.png" src="https://qiita-image-store.s3.amazonaws.com/0/113494/98b6f90c-5e0f-eebc-f53f-c40c57b56e52.png">



### Select CodeMirror Keymap
`"select_keymap/main": true,`
vimやSublimetextのキーマップをデフォルトより濃く設定できる？
例えば、デフォルトでキーマップをSublimeを入れても、「カッコ内の選択」`ctrl+shift+m`や「複数行の選択」`ctrl+alt+up<down>`ができなかったが、これをTrueにすると実行可能。
便利で仕方がない「選択文字列の複数選択」`ctrl+d`はブラウザの「ブックマークを登録」とよくかぶるのでアドオンでキーを変更しちゃう。

Firefoxなら[Menu Wizard](https://addons.mozilla.org/ja/firefox/addon/s3menu-wizard/)
Chromeなら[Keyconfig](https://chrome.google.com/webstore/category/extensions?hl=ja)




### Split Cells Notebook
`"splitcell/splitcell": true,`
左右段落に分ける。
ショートカットキーは`Shift+S`



### "stored_keymap": "sublime"





### Collapsible Headings
`"collapsible_headings/main": true,`
見出し(Heading)(マークダウンセルの行頭`# `)の階層ごとに、cell を閉じることができる。

<img width="400" alt="collapsibleheading.png" src="https://qiita-image-store.s3.amazonaws.com/0/113494/3c24ebfd-2b3e-d80f-9984-d57a57014f2b.png">



___
## インプット関連

### Freeze
`"freeze/main": true,`
read-only: 実行はできるけど書き換え不可
frozen: 書き込みも実行も不可

![freeze.png](https://qiita-image-store.s3.amazonaws.com/0/113494/3f11adbe-8a56-784c-7670-00a0a818011b.png)

### Codefolding
`"codefolding/main": true,`
インデント分けしたコードを折りたたむ。
ショートカットキーは`alt+f`

![codefolding.png](https://qiita-image-store.s3.amazonaws.com/0/113494/1d41f20e-90c9-7499-b5db-080a2f82824b.png)



### Hide input
`"hide_input/main": true,`
個別にセルの入力を隠す。

<img width="400" alt="hideinput.png" src="https://qiita-image-store.s3.amazonaws.com/0/113494/ee34c499-96ae-be76-6eb2-2328654c1caa.png">


### Hide input all
`"hide_input_all/main": true,`

すべてのセルの入力を隠す。
結果だけを出力できて、pdfやプレゼンの作成には便利。


<img width="400" alt="hideinputall.png" src="https://qiita-image-store.s3.amazonaws.com/0/113494/6719f342-9d37-bc00-ea0f-b5dafc1cf96a.png">



### Move selected cells
`"move_selected_cells/main": true,`

Alt+↑ / Alt+↓でセルの移動ができるらしいが、僕の環境でなぜかできない

### Code prettify

"code_prettify/code_prettify": true,

有効にすると現れるハンマーアイコンを押すとpythonコードをpep8などに沿うように直してくれる。

pythonコードの修正はyapfを落とさないといけない。

` conda install --channel https://conda.anaconda.org/conda-forge yapf`

試していないけど、Rなら`install.packages("formatR", repos = "http://cran.rstudio.com")`

javascriptなら`npm install js-beautify`でフォーマットするモジュール落とさないといけない。


![codeprettify.gif](https://qiita-image-store.s3.amazonaws.com/0/113494/c921ace7-aa8c-b822-b359-25e72ae44f97.gif)



### "toggle_all_line_numbers/main": true,
全てのセルに行番号つける。
各セルにセル番号つけることはjupyter-notebookのデフォルト設定(ショートカット`L`)で可能だから、使わない。

<img width="400" alt="toggleallnumber.png" src="https://qiita-image-store.s3.amazonaws.com/0/113494/62da9c98-a26b-f89e-a17a-e7f854346519.png">



### Limit Output
`"limit_output/main": true,`

`~\.jupyter\jupyter_notebook_config.py`に以下の関数書き込むと、1000行以上の出力が出たとき自動的にoutputを折りたたんでくれる。


```python
from notebook.services.config import ConfigManager
cm = ConfigManager().update('notebook', {'limit_output': 1000})
```




___
## アウトプット関連



### "execute_time/ExecuteTime": true,
実行時間を表示する。
メニューバーの`Cell`から選択したセルだけ / 全てのセルで実行時間表示切替可能。

### Printview
`"printview/main": true`
`Download as...`をしなくてもhtmlやpdf形式に変換したプレビューが簡単に見れる。




___
## マークダウン関連



### "highlighter/highlighter": true,
マークダウンセルのハイライト



### "dragdrop/main": true,
画像の埋め込み。
マークダウンセルに

```
<img  src="http://127.0.0.1:8888/notebooks/myimage.png"/>
```

みたいに書いてもいいけど、D&Dで捗りたい方向け。



### Python Markdown
`"python-markdown/main": true,`
pythonコードとマークダウンのミックス。

![python-markdown-post.png](https://qiita-image-store.s3.amazonaws.com/0/113494/40cae2a1-b660-7e32-6556-19205a5ff4df.png)
![python-markdown-pre.png](https://qiita-image-store.s3.amazonaws.com/0/113494/598f4986-4a1c-2645-f2c3-d4261838dd54.png)





___
## カーネル関連


### "keyboard_shortcut_editor/main": true,

キーボードショートカット一覧にkeyboardショートカットの編集アイコンがつく。

キーボードショートカットの呼び出しは、コマンドパレット(ctrl+shift+p)から`show keyboard shortcut`で探すか、ノーマルモードで`h`を押す。

<img width="355" alt="keyboardshoetcuteditor.png" src="https://qiita-image-store.s3.amazonaws.com/0/113494/f0c6485d-0ae7-0712-267e-2ff7da68989d.png">



### Launch QTConsole
`"qtconsole/qtconsole": true,`
現在のカーネル上のオブジェクトとか引き継いでqtcosele立ち上げる。 ~~styleがデフォルトの白色のままなのが気に食わない。~~ ←解決。以下のように`jupyter_qtconsole_config.py`に書き込む

`~/.jupyter/jupyter_qtconsole_config.py`を作成して


```python
c.JupyterWidget.syntax_style = "monokai"
```

と打ち込んでおけば、qtconsole立ち上げる時に常に`monokai`スタイルで立ち上がる。

**ちょっとお試ししたいだけなら以下に挙げる`Scratchpad`がおすすめ**




### Scratchpad notebook extension
`"scratchpad/main": true,`
現在のカーネルを汚さずに、お手軽にコードを試したいときに便利。
画面右に入力画面表示して
ショートカットキーは`ctrl+b`

![scratchpad.gif](https://qiita-image-store.s3.amazonaws.com/0/113494/56523eb0-bc99-41d8-b34b-83ee8abad9a3.gif)


### Navigation-Hotkeys
`"navigation-hotkeys/main": true`

新しいショートカットキーを追加する(らしい)

```
Edit-mode hotkeys:
pageup - scroll page up
pagedown - scroll page down
Alt- + - Split cell and keep cursor position
Alt- - - Combine cell and keep cursor position
Alt-n - Toggle line number display in current codecell
Shift-Enter - Execute cell, goto next cell and stay in edit mode if next cell is a code cell or unredered markdown cell
Ctrl-Enter - Execute cell and stay in edit mode if cell is a code cell
Ctrl-y - toggle celltype between markdown and code
Command-mode hotkeys:
esc - toggle to edit mode
home - Go to top of notebook
end - Go to bottom of notebook
pageup - scroll page up
pagedown - scroll page down
```


参考
[はしくれエンジニアもどきのメモ - Jupyter Notebookの拡張機能を使ってみる](http://cartman0.hatenablog.com/entry/2016/03/28/170319#sec-enableFunction-CollapsibleHeadings)
[Qiita - extensionを追加してもっと快適なJupyter環境を構築する](http://qiita.com/sasaki77/items/30a19d2be7d94116b237)


# 関連

## 参考一覧

* [公式　ipython-contrib/jupyter_contrib_nbextensions](https://github.com/ipython-contrib/jupyter_contrib_nbextensions)
* [Jupyterのショートカット](http://qiita.com/angelapy/items/998e99b2d0dc991c99f7)
* [stack overflow - Launch IPython notebook with selected browser](http://stackoverflow.com/questions/15632663/launch-ipython-notebook-with-selected-browser)
* [ねこゆきのメモ - <Python, iPython> ipython notebookで起動ブラウザを指定](http://nekoyukimmm.hatenablog.com/entry/2015/12/14/132843)
* [はしくれエンジニアもどきのメモ - Jupyter nbconvert（ファイル変換）メモ](http://cartman0.hatenablog.com/entry/2016/03/29/131903#sec-nbconvert)
* [Qiita - Jupyter notebook で HTML も自動作成](http://qiita.com/junkoda/items/011d44dcc1c8bd0a936a)
* [はしくれエンジニアもどきのメモ - Jupyter Notebookの拡張機能を使ってみる](http://cartman0.hatenablog.com/entry/2016/03/28/170319#sec-enableFunction-CollapsibleHeadings)
* [Qiita - extensionを追加してもっと快適なJupyter環境を構築する](http://qiita.com/sasaki77/items/30a19d2be7d94116b237)


## 自分のページ

* [Jupyter Notebook メモ](http://qiita.com/u1and0/items/166ca64438287ff4c206)

> JupyterNotebookショートカットキー、TeX、画像埋め込み等、被る(コピペ)情報が多い

* [Jupyter, Ipythonの設定　~起動、グラフの日本語表示、エイリアス、インライン表示、スタートアップモジュールインポート~](http://qiita.com/u1and0/items/a926a7be5d182932a929)

> JupyterNotebookだけでなく、Jupyter, Ipythonも含めたpythonの開発環境の説明