Задача: требуется создать конспект лекций по R в LaTeX.
Почему в LaTeX? Потому что он мне нравится.
Обычный путь решения этой задачи: пишем текст в LaTeX, вставляя в него фрагменты кода на R и результаты его выполнения (текст и графики). Нужно держать открытыми редактор TeX-а и R и время от времени копировать в TeX нужные фрагменты.
Просто, но скучно.
Нельзя ли сделать так, чтобы с помощью одного инструмента писать и текст и код? И чтобы результаты выполнения кода вставлялись в документ "сами собой"? Оказывается, можно.
Для этого в R существует пакет R Markdown. Установим его
install.packages("rmarkdown")
Чтобы получить документ LaTeX понадобится также дистрибутив TeX-a: MiKTeX (Windows), TeX Live (Linux, Windows), MacTeX (Mac OS).
Пакет R Markdown позволяет оформлять тексты на языке Markdown и вставлять в них "живой" исполняемый код на R. Так, вставка блока
```{r}
dim(iris)
```
превращается в итоговом документе в:
dim(iris)
## [1] 150 5
Подробнее о синтаксисе Markdown смотрите здесь.
Подготовленные таким образом документы можно сохранять в форматах HTML, PDF и некоторых других. Но нас сейчас интересует LaTeX. Он является промежуточным форматом в цепочке создания PDF-документов: Markdown -> LaTeX -> PDF.
При этом можно сохранять не только окончательный PDF, но и промежуточный LaTeX — а это то, что нам нужно. Сделать это можно, указав соответствующие настройки в заголовке Markdown-документа.
Сохранение LaTeX-документа
Заголовок документа окружен сверху и снизу тройными дефисами:
---
output:
pdf_document:
---
В данном случае, в заголовке указано, что на выходе должен получиться PDF-документ. При этом промежуточный TeX-файл не сохраняется. Чтобы его сохранить, нужно добавить одну опцию keep_tex
со значением yes
в настройки PDF-документа:
---
output:
pdf_document:
keep_tex: yes
---
Однако при использовании русского языка в настроенном таким образом Markdown-документе мы, скорее всего, получим сообщение об ошибке. Дело в том, что шаблон LaTeX-овского документа, используемый пакетом по умолчанию, не поддерживает русский язык.
Настройка шаблона документа
Для настройки отображения русского языка нужно в заголовке уже LaTeX-овского документа подключить следующие пакеты:
\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
Но как сделать так, чтобы эти пакеты добавлялись туда из Markdown? Используем опцию header-includes
:
----
title: "Title"
author: "Me"
output:
pdf_document
keep_tex: yes
header-includes:
- \usepackage[T2A]{fontenc}
- \usepackage[utf8]{inputenc}
- \usepackage[russian]{babel}
----
Когда изменений в шаблоне LaTeX-овского документа накопится достаточно много, можно переделать шаблон целиком.
Путь к шаблону можно найти с помощью команды
system.file("rmd/latex/default.tex", package="rmarkdown")
или посмотрев на сообщение, выдаваемое Markdown при трансляции документа
Запишем в этот шаблон вызов указанных выше пакетов и сохраним его копию с именем mystyle.tex
в рабочем каталоге R. Последний можно узнать командой getwd()
. Предполагается, что в этом же каталоге находится Markdown-файл с которым мы сейчас работаем.
Включение файлов в заголовок документа больше не нужно, а вот что нужно — так это указать новый шаблон LaTeX-документа опцией template
:
----
title: "Title"
author: "Me"
output:
pdf_document
keep_tex: yes
template: mystyle.tex
----
Вообще, у PDF-документа множество настроек, познакомиться с которыми можно с помощью обычной справки R:
> ?pdf_document
pdf_document(toc = FALSE, toc_depth = 2, number_sections = FALSE,
fig_width = 6.5, fig_height = 4.5, fig_crop = TRUE,
fig_caption = FALSE, highlight = "default", template = "default",
keep_tex = FALSE, latex_engine = "pdflatex", includes = NULL,
pandoc_args = NULL)
Отметим лишь аргумент latex_engine
, позволяющий задавать транслятор LaTeX'а. По умолчанию это PDFTeX, но может быть и XeTeX ("xelatex") и LuaTeX ("lualatex").
Аргументы для pandoc
Итак, когда мы указываем опцию pdf_document
в заголовке Rmd-файла, мы тем самым применяем функцию pdf_document
из пакета RMarkdown. Среди её многочисленных аргументов есть pandoc_args
— список аргументов, передаваемых программе pandoc, которая и выполняет преобразование из разметки Markdown в LaTeX.
С другой стороны, в шаблоне LaTeX-документа default.tex
(как его найти мы показали выше) содержится ряд настроек, которые как раз и задаются pandoc'ом. Вот, например, первые строки шаблона:
\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$lang$,
$endif$$if(papersize)$$papersize$,$endif$$for(classoption)$$classoption$$sep$,
$endfor$]{$documentclass$}
Таким образом, передавая аргументы pandoc с помощью pandoc_args
мы можем настроить внешний вид LaTeX-документа. Например, указав в заголовке
output:
pdf_document:
toc: yes
keep_tex: yes
fig_caption: yes
template: rstyle.tex
pandoc_args: [ "--variable", "fontsize:12pt",
"--variable", "papersize:a4paper",
"--variable", "lang:russian",
"--variable", "geometry:margin=1in"
]
мы получим в сгенерированном LaTeX-файле:
\documentclass[12pt,russian,a4paper]{article}
и, кроме того, определим отступы в 1 дюйм от края страницы (TeX-пакет geometry также используется в шаблоне default.tex
).
Другой способ настройки параметров LaTeX-документа
Оказалось, что для параметры LaTeX'овского документа, вроде размера шрифта или отступов от края страницы можно передать и без использования pandoc_args
. Делается это так:
title: "Title"
author: "Me"
fontsize: 12pt
geometry: margin=1in
papersize: a4paper
lang: russian
output:
pdf_document:
toc: yes
keep_tex: yes
fig_caption: yes
template: rstyle.tex
Важно разместить fontsize
, papersize
, geometry
и т.п. до раздела output
заголовка. Подробнее — см. здесь.
Передача аргументов LaTeX
Передача аргументов командной строки текущему транслятору LaTeX осуществляется посредством аргумента pandoc: --latex-engine-opt
. Вот как выглядит запуск из pandoc транслятора latex с аргументом -shell-escape
:
pandoc_args: [
"--latex-engine-opt", "-shell-escape"
]
Подсветка синтаксиса
Чтобы отменить подсветку синтаксиса используете pandoc-опцию --no-highlight
. Если выходным документом является PDF-файл, то в промежуточном tex-файле код будет заключён в окружение verbatim
.
Рисунки
Опция fig_caption = TRUE
или
----
title: "Title"
author: "Me"
output:
pdf_document
keep_tex: yes
fig_caption: yes
template: mystyle.tex
----
позволяет отображать подпись под рисунком. Сам рисунок вставляется в документ так:

Размер рисунка, например 640х480px, устанавливается следующим образом

Но это решение работает только в случае, когда форматом выходного документа является HTML. Если нужен PDF (или LaTeX), то можно записать непосредственно на LaTeX-е:
% Рисунок с фиксированным расположением
\begin{center}
\includegraphics[width=200pt]{image.png}
\end{center}
% Плавающий рисунок
\begin{figure}
\centering\includegraphics[width=200pt]{image.png}
\end{figure}
или с помощью функции include_graphics()
пакета knitr
:
```{r, out.width ="200pt", fig.align="center", echo=FALSE}
knitr::include_graphics("image.png")
```
Как и в LaTeX, изображение можно пометить с помощью \label
и затем сослаться на него командой \ref

См. рис. \ref{mylabel}.
И ещё одни нюанс. Если для вставки рисунков вы используете только LaTeX-овские команды (\includegraphics
), то pandoc сочтёт, что никаких рисунков в документе нет вообще — ведь там действительно нет рисунков, оформленных на Markdown. В результате не будет подключать пакет graphicx и \includegraphics
будет объявлена неизвестной командой.
Дело в том, что в текущем шаблоне, который использует R для оформления документов LaTeX стоит условие
$if(graphics)$
\usepackage{graphicx}
...
$endif$
Чтобы решить проблему, нужно либо отменить это условие, позволив графике загружаться всегда, либо добавить в заголовок Rmd-документа явное разрешение:
graphics: yes
TikZ и PGFPlots
Рисунки, созданные командами TikZ и PGFPlots, совершенно спокойно можно вставлять в RMarkdown. Вот пример для TikZ:
---
title: "Test TikZ"
author: "Me"
output:
pdf_document: default
header-includes:
- \usepackage{tikz}
---
# TikZ picture
Here is a TikZ picture:
\begin{tikzpicture}
\draw (0,0) circle (1in);
\end{tikzpicture}
Рисунки, созданные в PGFPlots, вставляются аналогично. Надо только подключить соответствующий пакет в разделе header-includes
Rmd-файла.
Таблицы
Простая и без заголовка:
Обозначение | Значение
------------|------------------
`&`, `|` | И, ИЛИ
`xor(a,b)` | Исключающее ИЛИ
С объединением столбцов и заголовком:
| First Header | Second Header | Third Header |
| :------------ | :-----------: | -------------------: |
| First row | Data | Very long data entry |
| Second row | **Cell** | *Cell* |
| Third row | Cell that spans across two columns ||
Table: My Caption
Как видно из номера таблицы, предыдущая таблица хоть и не имеет заголовка, тем не менее учтена при нумерации.
Шрифт
Имя основного шрифта можно задать в заголовке документа. Например, в данном случае это PT Serif:
---
title: "Тitle"
author: "Me"
date: \today
fontsize: 12pt
fontfamily: PT Serif
...
---
Можно также "спрятать" задание шрифта в latex-овский стилевой файл, подключаемый в заголовке, но, по сути, это будет то же самое.
Курсив и полужирный шрифты задаются разметкой Markdown:
Другие начертания шрифта можно задать командами LaTeX:
Этот подход работает при создании PDF-документов (на основе файлов LaTeX). Если нашей целью является создание HTML-документа, то и пользоваться следует командами HTML. Например:
Клавиатурные комбинации
Действие | Комбинация клавиш |
---|---|
Трансляция+просмотр готового документа | Ctrl+Shif+K |
Проверка орфографии | F7 |
Вставка фрагмента кода | Ctrl+Alt+I |
Примечание: орфография не проверяется внутри фрагментов кода.
Комментарии
comments powered by Disqus