はしくれエンジニアもどきのメモ

情報系技術・哲学・デザインなどの勉強メモ・備忘録です。

Jupyter nbconvert(ファイル変換)メモ

Jupyter nbconvert(ファイル変換)メモ

Jupyter Notebook のファイルを別形式に変換してくれるnbconvertコマンドについてのメモ。

環境

  • Windows 10

    • conda 4.02

      • Jupyter notebook 4.1

「Download As」での変換

「File」→「Download As」からノートファイル(.ipynb)をDL(変換)できる。

.ipynb ファイルから変換できる形式は、以下の5種類である。

「Download As」から変換できる形式

  • Python(.py)

    markdown cell で書かれた部分はコメントアウトされ、 code cell の入力(In[X])部分のみが有効になっている。

  • HTML(.html)

    markdown cell で書かれたhtmlやcssの部分もそのまま有効になるので、 最も互換性の高い変換になると思われる。

    ただし、拡張機能で追加した、「目次のアンカーリンク」、「ヘッダのナンバリング」、「数式のナンバリング」あたりは無効になるので注意。

  • Markdown(.md)

    code cell の部分は、markdownのcodeブロックに変換される。

    code cell で画像を出力していた場合、zipで出力され、その画像も出力される。markdown での画像読み込みではならない模様。

    例えば、code cellでjpeg画像を表示していた場合、 以下のように変換される。

    
    # source (code cell)
    IPython.core.Image([画像ファイル名].jpg, embed=True)
    
    
    # dist(markdown)
    ![jepg](自動で割り振られる画像ファイル名.jpg)
    
  • reST(.rst)

    .rst から Sphinx を通すことで.texファイルまで持っていける(らしい)。

  • PDF via LaTeX(.pdf)

    LaTeX環境を作っておく必要と、 .texファイルを生成する際に内部で pandoc を使っているので、pandoc をインストールしておく。

    
    conda install pandoc
    

    結論から言うと、日本語を使ってない(英語)で画像を使ってない .ipynbファイルであれば、何も考えずpdf に変換できる。

    日本語を使ってる場合は、 nbconvertコマンドで、テンプレートファイルを変更がある(後述:nbconvertコマンド)。

    画像を使っていると、サイズと図表の問題が出る(後述:画像の扱い)。

nbconvertコマンドでの変換

上記の変換は実際は、 jupyter nbconvert コマンドが使われている。

github.com


$ jupyter nbconvert --help

This application is used to convert notebook files (*.ipynb) to various other formats.
...

上記のPython, HTML, Markdown, reST, pdf 以外にも latex(.tex), script, slide(Reveal JS) に変換できる。 ファイル形式を指定するには --toオプションを使う。


jupyter nbconvert --to latex [ファイル名].ipynb

LaTeXファイルに変換するときの注意

日本語ドキュメントを変換する場合

「Download As」または jupyter nbconvert --to latex [ファイル名].ipynb のまま日本語を含んだ.ipynbをlatexに変換するとエラーになる。

原因としては、デフォルトテンプレートのtexのdocumentclassが 「article」を使用しているためで、日本語に対応してない。 そのため、日本語に対応したテンプレートファイルを作る必要がある。

テンプレートファイルは、nbconvert\template\latexフォルダの中の.tplxというファイルになる。 自分の環境では、 C:\Miniconda3\Lib\site-packages\nbconvert\templates\latexのパスあった。

latexファイルに変換する際に、 デフォで使われるのが article.tplx になる。なのでこのファイルの中身を真似して日本語に対応したテンプレートをつくる。

article.tplxの中身を見ると、documentclassが「article」になっているので、これを日本語の対応した「jsarticle」や「ltjsarticle」などに変更すればいい。


# article.tplx

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

((* block docclass *))
\documentclass{article}
((* endblock docclass *))

# example new jsarticle.tplx

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

((* block docclass *))
\documentclass{jsarticle}
((* endblock docclass *))

# or new ltjsarticle.tplx

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

((* block docclass *))
\documentclass{ltjsarticle}
((* endblock docclass *))

そして、適当な名前を付けて保存すればいい。保存先は、 \nbconvert\templates\latex 直下は推奨されていなので、 パスの通っている場所か.ipynbファイルと同じ場所でいいと思われる。

テンプレートファイルを指定して変換するには、 --templateオプションをつける。


jupyter nbconvert --to latex --template jsarticle.tplx [ファイル名].ipynb

参考:iPython notebookをLaTeXに変換 - Qiita

画像関係

imgタグは無効になる

markdown cell に書かれた <img src="">は、htmlに変換する場合は問題ないが、latexファイルに変換すると無視されるので注意。 markdown書式の ![alt](path) にすれば問題ない。

拡張機能DragDrop を使って画像を挿入すると、 imgタグになるので注意。

画像の扱いが2種類ある

画像の出力をcode cell かmarkdown cell かで変わるので注意。

markdown cellvscode cell
\![alt]\(path) 入力コード IPython.core.Image("path")
pandoc どこで処理されるか nbconvert

\begin{figure}[htbp]
  \includegraphics{path}
  \caption{alt}
\end{figure}
出力texコード(デフォ)

\begin{center}
  \adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{((( filename )))}
\end{center}
なし 画像サイズの調整 \adjusimageにより調整あり
あり 図番号 デフォではないがテンプレートを変更して\begin{figure}~\end{figure}とすればいい
あり キャプション なし
不可? 出力コードの変更 テンプレート(.tplx)で変更可能
それぞれのメリット・デメリット
  • markdown cell で書いた部分は、nbconvert というより、pandoc側で処理される仕様のようで、 ![alt](path) で書かれた部分は \begin{figure}~\end{figure} に変換される。

    メリットしては、図番号、キャプションが振られる。

    デメリットして、 \includegraphics のみで描画されるので、 画像サイズを考慮する必要がある。 また、 pandoc のテンプレートを見てみると、figure についての変更部分がないので、この出力は変更できないように思える(情報求)。

  • code cell で書いた部分は、nbconvert側で処理される。 IPython側のモジュール IPython.core.Image(path) を使って画像を表示できる。

    メリットとして、nbconvert のテンプレート(.tplx) で出力を変更することができる。デフォで \ajustimageが使われるので画像サイズを気にする必要はない。また、 \begin{figure} ~ \end{figure} を追加して図番号を振ることができる。

    が、キャプションを与える術がないデメリットがある。 さらに、code cell を使って画像を読み込みと、code cell(In)が残るので不格好になる。

nbconvert のテンプレート構造

デフォで使われるテンプレート article.tplx は、以下の構造をしている。

  • article.tplx

    • style_ipython.tplx

      • base_tplx

        • display_priority.tplx

article.tplx が、style_ipython.tplx を呼び拡張している。


% article.tplx

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

style_ipython.tplx は、base.tplx を呼び拡張している。


% style_ipython.tplx

((= IPython input/output style =))

((*- extends 'base.tplx' -*))

画像(figure) の処理部分は、 base.tplx の中に書かれている。


% base.tplx

% Draw a figure using the graphicx package.
((* macro draw_figure(filename) -*))
((* set filename = filename | posix_path *))
((*- block figure scoped -*))
    \begin{center}
    \adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{((( filename )))}
    \end{center}
    { \hspace*{\fill} \\}
((*- endblock figure -*))
((*- endmacro *))

後に書いた処理で上書きされる仕様なので、 処理を変える場合は、自分で作ったテンプレートファイルに、 コピペして処理を変えればいい。 以下は、例として、\begin{figure}[htbp] ~ \end{figure} を使うように変更している。


%myTemplate.tplx

% Draw a figure using the graphicx package.
((* macro draw_figure(filename) -*))
((* set filename = filename | posix_path *))
((*- block figure scoped -*))
    \begin{figure}[htbp]
      \centering
      \adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{((( filename )))}
    \end{figure}
    { \hspace*{\fill} \\}
((*- endblock figure -*))
((*- endmacro *))

PDFを作るには

pdfファイルを生成するにはいくつかある。

印刷からpdf

手っ取り早い方法として、 ブラウザの印刷からpdf を生成する方法。 cssで指定しているような文字のカラー情報などが失われるので注意。 レイアウトも画像やテーブルがぶった切られるので注意。

texからpdf

texファイルに変換してから、texファイルをコンパイルしてpdfを生成する方法。 メリットとしては、式・図の番号が保持され、レイアウトも維持される。 しかし、上記の画像の問題があるため、 tex の完全代替として使うのはまだ難しいという印象。 生成したtexファイルをベースに、修正・書き直ししていくスタイルもありだが、 おそらく整合性とれなくなって面倒なことになると思う。 そのため、 code側が生成する画像の図表番号はあきらめて(基本放置)、 挿入する画像は、markdown cell にして、文書サイズを超えないよう前もってリサイズしておくのが1番管理しやすいと思う。

ちなみに、lualatex であればコンパイルのみでpdfを生成できる。

jupyter nbconvert [ファイル名].ipynb --to latex --template myTemplate.tplx lualatex [ファイル名].tex