- PVSM.RU - https://www.pvsm.ru -

Настройка LaTeX-шаблонов для Jupyter notebook

Есть отличный инструмент для обучения/отчётов/написания умных книг про код — Jupyter Notebook [1]. Если отчёт или книга, например, пишутся на кириллице, а нужно быстро сделать из этого PDF с красивыми формулами и тире правильной длины, то сразу обнаруживается проблема: в стандартном шаблоне, который Jupyter использует для конвертации блокнотов в PDF через LaTeX, нет подключения нужных пакетов с нужными параметрами, поэтому LaTeX просто не компилируется и PDF не получить.

Постоянно действующие предположения: будем говорить о Jupyter, который отсоединился от основного проекта IPython в релизе IPython 4; если вы хотите поговорить об IPython 3.x, заменяйте в командах jupyter на ipython и проверяйте возможные несовпадения имён файлов. Для генерации PDF мы используем либо командную строку (jupyter nbconvert --to pdf myfile.ipynb), либо кнопку из веб-интерфейса Download as -> PDF via LaTeX.

Самый простой способ решить проблему с недостающими пакетами — jupyter nbconvert --to latex myfile.ipynb, открываем полученный TeX-исходник и дописываем недостающие пакеты. Компилируем исходник (pdflatex myfile.tex или что кому нравится), цель достигнута.

Если проблема не решается в одну строчку (нужно серьёзно менять шаблон и не хочется копаться в неприятном результате конвертирования в LaTeX) / у меня много блокнотов / я хочу более общее решение, то продолжаем.

Нужно объяснить конвертеру, что для конвертации блокнота в LaTeX он должен использовать не стандартный шаблон, а наш, с расширенным заголовком, самым правильным шрифтом и корпоративной темой оформления.

jupyter nbconvert --to pdf --template mytemplate.tplx myfile.ipynb

Проблемы: mytemplate.tplx успешно находится только в той директории, откуда запускается nbconvert, через веб-интерфейс это не протащить, как писать шаблон — непонятно.

Файлы настроек

Сначала про конфигурацию и местонахождение файлов. Это быстро решается написанием собственного файла настроек. Файл настроек для nbconvert  — это файл с кодом на Python. Как указать файл настроек при вызове конвертера:

jupyter nbconvert --to pdf --config cfg.py myfile.ipynb

Файл настроек выглядит примерно так:

c = get_config()
c.NbConvertApp.export_format = 'pdf'
c.TemplateExporter.template_path = ['.']
c.Exporter.template_file = 'article'

Здесь export_format — значение по умолчанию для --to, template_path — список директорий с шаблонами, здесь говорит, что файлы шаблонов должны искаться в той директории, откуда запускается nbconvert, template_file означает, что, если не указано иначе, нужно пользоваться шаблоном article.tplx.

Теперь если запустить jupyter notebook --config cfg.py, то все настройки для конвертации будут браться сначала из файла конфигурации, что нам и нужно. Если нужно, чтобы эти настройки были по умолчанию при любом запуске nbconvert этим пользователем, их нужно положить в файл ~/.jupyter/jupyter_nbconvert_config.py. Соответственно, для notebook общий файл настроек — ~/.jupyter/jupyter_notebook_config.py.

Шаблоны

Самая интересная часть — как писать шаблоны. Шаблоны пишутся с использованием шаблонизатора Jinja2 [2]; во избежание конфликтов со специальными символами LaTeX служебные последовательности шаблонизатора переопределены [3] (первая { заменена на ((, остальные { на (, с обратными скобками зеркально). Набор шаблонов, которые используются по умолчанию, находится в NBCONVERT_INSTALLATION_DIR/nbconvert/templates/latex/ [4]. Они хорошо документированы, от них имеет смысл наследоваться при создании своих шаблонов. Ещё примеры шаблонов есть в репозитории nbconvert-examples на Github [5]. Скриншоты различных вариантов оформления можно посмотреть в readme к одному из разделов [6] этого репозитория.

Как написать свой шаблон, в котором будут выполняться все необходимые лично вам вещи? Создать файл mytemplate.tplx, в котором написать несколько необходимых вещей.

Во-первых — аккуратно унаследоваться от шаблона, определяющего конкретный стиль отрисовки клеток с кодом (как в примере [7]):

% Default to the notebook output style
((* set cell_style = 'style_notebook.tplx' *))
% Inherit from the specified cell style.
((* extends cell_style *))

Здесь я наследуюсь от шаблона style_notebook.tplx, который не является стандартным, а лежит в nbconvert-examples [8]. Ещё этот шаблон написан, видимо, для старой версии nbconvert, поэтому в нём нужно будет поменять строчку ((* extends 'latex_base.tplx' *)) на ((* extends 'base.tplx' *)).

Во-вторых — определить documentclass будущего LaTeX-файла и не делать заголовка (можно вместо этого написать код, берущий заголовок из метаданных файла .ipynb или откуда-нибудь ещё):

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

((* block maketitle *))((* endblock maketitle *))

В-третьих — подключить вожделенные пакеты с поддержкой кириллицы (и ещё десяток-другой любимых):

((* block packages *))
((( super() ))) % load all other packages
usepackage[T2A]{fontenc}
usepackage[english, russian]{babel}
usepackage{mathtools}
((* endblock packages *))

Полный список блоков описан в nbconvert/templates/latex/skeleton/null.tplx [9] и nbconvert/templates/latex/base.tplx [10] (и это тоже ссылки на GitHub).

Если мы хотим использовать полученный шаблон не в конкретном проекте, но во всех блокнотах, можно положить его, например, в ~/.jupyter/templates/ и изменить соответствующую строчку в файле настроек:

c.TemplateExporter.template_path = ['.', '~/.jupyter/templates/']

После небольших исправлений в шаблоне для отрисовки клеток с кодом (мне не нравились надписи In[*]) у меня получились вот такие отчёты (скриншот из PDF-файла):

Настройка LaTeX-шаблонов для Jupyter notebook - 1

Автор: stacymiller

Источник [11]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/115424

Ссылки в тексте:

[1] Jupyter Notebook: http://jupyter.org

[2] Jinja2: http://jinja.pocoo.org

[3] переопределены: https://github.com/jupyter/nbconvert/blob/master/nbconvert/exporters/latex.py#L90

[4] NBCONVERT_INSTALLATION_DIR/nbconvert/templates/latex/: https://github.com/jupyter/nbconvert/tree/master/nbconvert/templates/latex

[5] nbconvert-examples на Github: https://github.com/jupyter/nbconvert-examples

[6] в readme к одному из разделов: https://github.com/jupyter/nbconvert-examples/tree/master/latex_cell_style

[7] как в примере: https://github.com/jupyter/nbconvert-examples/blob/master/latex_cell_style/use_cell_style.tplx

[8] nbconvert-examples: https://github.com/jupyter/nbconvert-examples/blob/master/notebook_cell_style/style_notebook.tplx

[9] nbconvert/templates/latex/skeleton/null.tplx: https://github.com/jupyter/nbconvert/blob/master/nbconvert/templates/latex/skeleton/null.tplx

[10] nbconvert/templates/latex/base.tplx: https://github.com/jupyter/nbconvert/blob/master/nbconvert/templates/latex/base.tplx

[11] Источник: https://habrahabr.ru/post/279601/