Документы Quarto имеют расширение *.qmd. Основными составляющими Quarto-документа являются:
Метаданные, которые хранят все форматы и настройки.
Текст документа.
Ячейки с исполняемым кодом, написанные на R, Python, Julia или Observable JS, либо ином языке, поддерживающим ядра Jupyter.
Ниже приведен пример элементов Quarto-документа.
Рисунок 3.1: Пример файла Quarto
3.1 Метаданные
Метаданные в Quarto реализованы на основе YAML и могут быть включены в Quarto-документ в преамбуле в начале файла и/или в отдельном _quarto.yml-файле (либо ином *.yaml или *.yml-файле, скажем, _extension.yml, _metadata.yml). Если данные YAML включены в документ, в этом случае YAML-часть отделяется от документа тройным дефисом ---. Например, метаданные могут содержать информацию об авторе, формате документа и визуальном режиме редактора:
---# пример YAML-метаданных: # заголовок, дата, формат документа, режим редактораtitle:"Заголовок документа"date: todayformat: htmleditor: visual---
Метаданные обрабатываются на многих этапах процесса рендеринга и могут влиять на конечный документ многими различными способами: на код, содержимое документа и процесс рендеринга. Базовый синтаксис YAML-файлов использует систему отступов и систему пар ключ-значение в формате key: value. Другие поля YAML, обычно встречающиеся в заголовках документов, включают метаданные, такие как author для автора, subtitle для подзаголовка, date для даты, а также параметры настройки, такие как theme, fontcolor, fig-width и т. д.
3.1.1 Параметры _quarto.yml
Ниже показан пример для простейшего файла конфигурации. Здесь указаны: тип проекта (параметр type), название (параметр title), формат (в данном случае html), тема веб-страницы (параметр theme), стилевой файл (параметр css) и наличие содержания на странице (параметр toc).
_quarto.yml
# параметры уровня проектаproject: # тип проекта # возможные типы: default, website, book и manuscripttype: website # папка для выходных HTML-данныхoutput-dir: docswebsite:title:"Название веб-сайта"format:html:theme: cosmocss: styles.csstoc:true
Вообще говоря, любая папка, содержащая файл _quarto.yml, считается проектом Quarto, при этом в самом _quarto.yml задаются параметры верхнего уровня проекта и позволяет выполнять рендер всего проекта без указания конкретного файла
Terminal
quarto render
и в дальнейшем публиковать проект.
3.1.2 Общие метаданные
Параметры, заданные в _quarto.yml, будут применены ко всем файлам Quarto в проекте и сократят повторение за счет указания общих параметров в одном месте. Например, пусть файл _quarto.yml имеет следующий вид
_quarto.yml
project:type: websiteauthor: Автор Фамилияformat:html:toc:true
Тогда если в документе указывает другой параметр из _quarto.yml, он переопределит значение по умолчанию.
file_0.qmd
---author: Другой Авторformat:html:toc:false---
Кроме того, вместо того, чтобы полностью расписывать YAML-преамбулу, глобальные настройки позволяют воспользоваться упрощенным вариантом.
file_1.qmd
---author: Автор Фамилияtitle: Заголовок 1format:html:toc:true---## Текст 1
file_2.qmd
---author: Автор Фамилияtitle: Заголовок 2format:html:toc:true---## Текст 2
Представление выше эквивалентно следующему
file_1.qmd
---title: Заголовок 1---## Текст 1
file_2.qmd
---title: Заголовок 2---## Текст 2
вместе с файлом _quarto.yml:
_quarto.yml
author: Автор Фамилияformat:html:toc:true
Замечание
Вид YAML-файла зависит от вида документа (веб-страница, блог и т. д.), а также формата выходного документа (HTML, MS Word, PDF и т. д.). Мы рассмотрим в последующих частях книги соответствующие YAML настройки для веб-страниц, блогов, книг и т. д. Список известных HTML-опций для полей YAML можно посмотреть на странице документации, аналогичные настройки есть и для PDF, MS Word, Typst и других форматов.
3.2 Элементы Markdown
Markdown — это достаточно простой язык разметки для форматирования текста. Quarto основан на Pandoc (см. также Pandoc User’s Guide) и использует вариацию Markdown в качестве базового синтаксиса документа. Pandoc Markdown, по сути, — это расширенная и слегка переработанная версия синтаксиса Markdown.
3.2.1 Форматирование текста
Синтаксис Markdown
Вывод
*курсив*, **полужирный**,***полужирный курсив***
курсив, полужирный, полужирный курсив
_курсив_, __полужирный__,___полужирный курсив___
курсив, полужирный, полужирный курсив
`пример кода`
пример кода
~~зачеркнутый~~
зачеркнутый
надстрочный^2^/ подстрочный~2~
надстрочный2 / подстрочный2
[малые прописные]{.smallcaps}
малые прописные
[подчеркнутый]{.underline}
подчеркнутый
[выделенный]{.mark}
выделенный
3.2.2 Заголовки
Заголовки разделов, глав, параграфов и т. д. устанавливаются с помощью символа #. Форматирование зависит от общего стиля документов. Несколько примеров показано ниже.
Синтаксис Markdown
Вывод
# Раздел 1
Раздел 1
## Раздел 2
Раздел 2
### Раздел 2
Раздел 3
3.2.3 Списки
Синтаксис Markdown
Вывод
* неупорядоченный список + элемент 1 + элемент 2 - подэлемент 1 - подэлемент 2
неупорядоченный список
элемент 1
элемент 2
подэлемент 1
подэлемент 2
- [ ] Задача 1- [x] Задача 2
1. упорядоченный список2. элемент i) подэлемент ii) подподэлемент
Форматирование таблиц в Markdown может быть более сложным.
Quarto
+---------------------+-------------------------+| Место | Температура поверхности || измерения ||| +---------+------+--------+|| min | mean | max |+=====================+=========+======+========+| Антарктика | 89,2°C | N/A | 19,8°C |+---------------------+---------+------+--------+| Земля | 89,2°C | 14°C | 56,7°C |+---------------------+---------+------+--------+
Место измерения
Температура поверхности
min
mean
max
Антарктика
89,2°C
N/A
19,8°C
Земля
89,2°C
14°C
56,7°C
Размеры ширины колонок таблиц можно изменять используя параметр tbl-colwidths="[A,B]", указав пропорции, например, в пропорции A% | B% таким образом, что A + B = 100.
Список возможных опций для работы с таблицами можно найти на странице документации. Отметим, что в Quarto также можно вставлять различные таблицы на основе библиотек языков программирования, например, статические таблицы с помощью библиотек {gt}, {gtsummary}, {gtExtras}, {tinytable}, {flextable}, {kableExtra}, {gtUtils} и других языка R, {Great Tables} языка Python, {SummaryTables.jl} языка Julia, а также интерактивные таблицы, например, {reactable}, {DT}.
R
head(mtcars) |> gt::gt()
mpg
cyl
disp
hp
drat
wt
qsec
vs
am
gear
carb
21.0
6
160
110
3.90
2.620
16.46
0
1
4
4
21.0
6
160
110
3.90
2.875
17.02
0
1
4
4
22.8
4
108
93
3.85
2.320
18.61
1
1
4
1
21.4
6
258
110
3.08
3.215
19.44
1
0
3
1
18.7
8
360
175
3.15
3.440
17.02
0
0
3
2
18.1
6
225
105
2.76
3.460
20.22
1
0
3
1
3.2.5 Сноски
Сноски представляют собой примечания к тексту, обычно помещаемые в конце страницы, это могут быть комментарий, библиографическая сноска, перевод и т. п. Сами сноски необязательно размещать в конце документа. Они могут размещаться в любом месте, кроме как внутри других текстовых элементов (списков, текстовых цитат, таблиц и т. д.). Каждая сноска должна быть отделена от окружающего содержимого (включая другие сноски) пустыми строками.
Quarto
Пример первой сноски[^1], сноски имеющей название[^named-footnote], а также сноски-блока[^longnote].[^1]: Это текст первой сноски.[^named-footnote]: Это текст второй сноски.[^longnote]: Это сноска-блок. Последующие абзацы выделены отступом, чтобы показать, что они относятся к предыдущей сноске. { some.code } Можно использовать весь абзац целиком.
Пример первой сноски1, сноски имеющей название2, а также сноски-блока3.
Для придания определенного эффекта при увеличении рисунка можно воспользоваться расширением Lightbox, которое встроено в Quarto как функция.
Quarto
{.lightbox description="Лесные пожары в РФ за период 2012-2021 гг. Более подробно можно посмотреть на странице [Графики на досуге](https://data-visualization-blog.netlify.app/posts/wildfires/)"desc-position="left"}
Пожары в РФ (нажмите для увеличения)
Рисунки можно организовывать с помощью перекрестных ссылок. При этом формула для организации ссылки {#fig-название рисунка}, а ссылка в тексте должна иметь вид @fig-название рисунка. Про организацию перекрестных ссылок будет рассказано далее.
Quarto
{#fig-Moscow}Ссылка на рисунок @fig-Moscow.
Организовать несколько рисунков можно по-разному. Например, можно указать количество строк/столбцов в итоговом рисунке с помощью параметра layout-ncol=* или layout-nrow=*.
Другой способ размещения рисунков состоит в настройке размеров/пропорций, например, как это сделано ниже, с указанием расстояния между рисунками layout="[*,*,*], вертикальным выравниванием можно управлять с помощью параметра layout-valign.
Подписи к рисункам располагаются по умолчанию под рисунками. Если требуется изменить это поведение в форматах HTML и PDF, то необходимо глобально изменить параметр fig-cap-location на top (по умолчанию сверху), bottom (внизу) или margin (на полях).
_quarto.yml
fig-cap-location: bottom
Вставка в документ рисунков на основе блоков исполняемого кода происходит автоматически. Внутри кода можно выставлять параметры рисунка: например, ширину fig.width и высоту fig.height рисунка, label для указания метки рисунка (чтобы в дальнейшем ссылаться на рисунок), а также иные параметры, которые начинаются с префикса fig- (все возможные опции описаны на странице форматов) как показано в примере ниже. Параметры внутри блока кода должны предваряться #|.
В Quarto можно вставлять элементы исполняемого кода на языках R, Python или Julia. При этом соответствующее ядро (движок Knitr или Jupyter) будет определяться автоматически. Используемое ядро определяется на основе языка первого обнаруженного исполняемого блока кода.
Расширение файла
Блок кода
Ядро
*.qmd
{r}
Knitr
*.qmd
{python}, {julia}, {bash}, и т. д.
Kupyter
*.rmd
Knitr
*.ipynb
Jupyter
Одновременное использование R и Python
В случае, если документ Quarto включает в себя блоки кода как {python}, так и {r}, то Quarto автоматически будет использовать движок Knitr и библиотеку reticulate языка R для выполнения содержимого Python.
Для файлов *.qmd можно переопределить используемый движок с помощью опции engine.
---title:"Документ Python"engine: jupyter---
---title:"Документ R"engine: knitr---
Использование опции knitr или jupyter также переопределит движок по умолчанию:
---knitr:true---
---jupyter: python3---
---jupyter: julia-1.11---
3.3.1 Ячейки с кодом
Блоки кода должны начинаться с ```{language} и завершаться ```, где {language}, в зависимости от языка:
{language}
Язык программирования
{r}
R
{python}
Python
{julia}
Julia
{ojs}
Observable JS
Внутри ячеек с кодом также могут находиться параметры, которые следуют за #|. Покажем пример блока с кодом и результат его выполнения. Таким образом выглядит код в Quarto:
```{r}# пример графика в R#| label: fig-diamonds-example#| fig-cap: "Пример графика в ggplot2"#| message: false#| warning: false#| fig.width: 6#| fig.height: 5library(tidyverse)diamonds |>ggplot(aes(x = carat, y = price, fill = clarity)) +geom_hex(alpha =0.7, bins =40) +theme(legend.position ="none")```
Ниже показан пример оформления кода и результат исполнения кода.
R
# пример графика в R#| label: fig-diamonds-example#| fig-cap: "Пример графика в ggplot2"#| message: false#| warning: false#| fig.width: 6#| fig.height: 6library(tidyverse)diamonds |>ggplot(aes(x = carat, y = price, fill = clarity)) +geom_hex(alpha =0.8, bins =40) +theme(legend.position ="bottom")
Рисунок 3.6: Пример графика в ggplot2
В том случае, если код занимает много места на веб-странице, либо в изложении материала стоит избегать вывода кода, чтобы сконцентрироваться на результатах, можно сворачивать ячейки с кодом, чтобы пользователь мог отобразить их по требованию.
R
#| eval: false#| code-fold: true#| code-line-numbers: true#| code-summary: "Нажмите, чтобы показать код"library(tidyverse)diamonds |>ggplot(aes(x = carat, y = price, fill = clarity)) +geom_hex(alpha =0.8, bins =40) +theme(legend.position ="bottom")
Результат на странице будет выглядеть следующим образом.
Нажмите, чтобы показать код
library(tidyverse)diamonds |>ggplot(aes(x = carat, y = price, fill = clarity)) +geom_hex(alpha =0.8, bins =40) +theme(legend.position ="bottom")
Если строки кода слишком широки для своего контейнера в текстовом представлении, то переполнение кода можно регулировать с помощью параметра code-overflow, используя значения scroll для прокрутки и wrap для переноса длинных строк кода.
R
#| code-overflow: wrapprint("Lorem pharetra erat bibendum pharetra, tellus metus mi mi molestie; risus natoque justo. Curabitur aliquet venenatis risus, urna, libero lobortis erat nibh? Per lectus sem dictumst nullam aliquet risus velit lacus cras tempus. Faucibus rhoncus faucibus tempus varius.")
Кроме того, значения code-line-numbers позволяют указывать в презентациях RevealJS строки для выделения и/или анимации между наборами выделенных строк. Например, диапазоны выделяются как 1,2,4-5, шаги анимации разделяются символом |, например: 1-3|1-3,5 для показа строк (сначала 1-3, потом 1-3,5).
Опция code-link позволяет создавать для HTML-документов, которые рендерятся с помощью Knitr, гиперссылки на функции внутри блоков кода. Для включения гиперссылок необходимо предварительно установить библиотеку downlit и добавить в преамбулу документа YAML-часть как показано ниже.
format:html:code-link:true
Тогда все функции будут связаны с помощью гиперссылок с соответствующими веб-страницами.
Рисунок 3.7: Пример связывания функций в ячейках с кодом с помощью гирерссылок
3.3.2 Подсветка кода
Блоки с кодом автоматически обеспечиваются соответствующей подсветкой, в зависимости от языка программирования (их можно отобразить, набрав в терминале quarto pandoc --list-highlight-languages). Стиль подсветки кода задается как highlight-style, указав казав одну из поддерживаемых тем. Например:
highlight-style: a11y
Приведем названия тем для подсветки кода, которые поддерживает Quarto:
адаптивные темы, которые разработаны для сайтов, поддерживающих темный и светлый режимы: a11y, arrow, atom-one, ayu, breeze, github, gruvbox;
В том случае, если необходимо отключить автоматическое адаптивное переключение и выбрать только темную тему, то нужно указать полное имя темы вида:
highlight-style: github-dark
3.3.3 Параметры ячеек с кодом
Внутри ячейки кодом можно задавать параметры вывода. В таблице приведены некоторые значения этих параметров по умолчанию:
Таблица 3.4: Параметры ячеек с кодом для исполняемого кода
Параметр
Значение
Описание
echo
true
false: скрыть код в выводе fenced: включить синтаксис ячейки кода в вывод (кроме echo: fenced)
eval
true
false: код не будет запускаться
warning
true
false: не включать предупреждения в выводе
include
true
false: не включать код и результаты вывода
output
true
false: не включать результаты вывода asis: интерпретировать результат как Markdown
error
false
true: в случае ошибки, ошибка будет отображена, при этом рендеринг не останавливается
Помимо параметров настройки вывода, в Quarto имеется довольно внушительный список параметров, которые зависят от ядра, используемого для их обработки. Приведем список некоторых полезных параметров для ячеек с кодом, ориентируясь на *.qmd-документы.
Таблица 3.5: Параметры ячеек с кодом
Параметр
Описание
Значения параметров
Рисунки
fig-width
ширина рисунка
fig-height
высота рисунка
fig-cap
заголовок рисунка
fig-subcap
подзаголовок рисунка
fig-link
гиперссылка рисунка
fig-align
горизонтальное выравнивание рисунка
default, left, right, center
fig-format
формат вывода для рисунков по умолчанию
retina, png, jpeg, svg, pdf
fig-dpi
DPI рисунка по умолчанию
fig-asp
соотношение сторон рисунка по умолчанию
fig-height = fig-width * fig-asp
fig-cap-location
место размещения рисунка
top, bottom, margin
Таблицы
tbl-cap
заголовок таблицы
tbl-subcap
подзаголовок таблицы
tbl-colwidths
ширина колонок таблицы
auto, true, false или явное значение в процентах: [25,45,30] и т. п.
tbl-cap-location
место размещения таблицы
top, bottom, margin
Также, отметим что для перекрестных ссылок используется параметр label, который является уникальной меткой для ячейки кода.
Для того, чтобы упростить использование параметров ячеек с кодом, можно воспользоваться расширением Quarto Wingman для Visual Studio Code, которое обеспечивает интерактивную конфигурацию ячеек кода, улучшает отображение сносок в документах и многое другое.
Рисунок 3.12: Пример работы с расширением Quarto Wingman
3.3.4 Аннотирование кода
Исполняемые блоки кода в Quarto могут включать аннотации, которые представляют собой построчные пояснения к коду. Каждая аннотированная строка должна заканчиваться пробелом, после которого следует номер аннотации, заключенный в угловые скобки, например, #<1>. Сразу после блока кода должен следовать список аннотаций с текстом пояснения.
Для вывода HTML существует три стиля аннотаций, которые можно задать с помощью параметра code-annotations задаваемого в YAML.
_quarto.yml
code-annotations: below
below Этот параметр стоит по умолчанию, текст аннотации кода будет отображаться под ячейкой кода.
hover Текст аннотации кода будет отображаться при наведении курсора на маркер аннотации строки кода (как в примере выше).
select Текст аннотации кода будет отображаться, когда пользователь нажимает на маркер аннотации (выбирает его). Текст аннотации можно убрать, нажав на маркер аннотации еще раз.
3.3.5 Встроенные вычисления
Помимо вычислений в ячейках, код можно вставлять в в рамках Markdown-разметки. Quarto предоставляет синтаксис встроенного кода, который работает во всех трех движках (Jupyter, Knitr и OJS) для автоматического использования вычислений в повествовательном тексте. Формат вставки имеет вид `{language} code`.
Quarto
В наборе данных `mtcars` содержатся данные по `{r} ncol(mtcars)` автомобилям.
В наборе данных mtcars содержатся данные по 11 автомобилям.
Совет
Помните, что ячейки с кодом должны выполняться в первую очередь, приоритет вычислений сохраняется за ними. Встроенные выражения должны быть максимально простыми, это должны быть, как правило, результаты вычислений, а не, скажем, вызовы функций, которые выполняют нетривиальную работу. Это также связано с тем, что протокол, используемый для встроенных выражений, несовместим с некоторыми библиотеками языков программирования (особенно с теми, которые используют многопоточность или многопроцессорность).
Автоматическая привязка ядра работает для блоков, но не для встроенных вычислений, поэтому если вы используете встроенные выражения в документе, который не имеет исполняемых блоков кода, то вам следует явно задать параметр engine документа, чтобы гарантировать, что встроенные выражения будут выполнены.
Для того, чтобы осуществить рендер части проекта, можно использовать инкрементный рендеринг для пошаговой обработки одного файла или подкаталога.
Terminal
quarto render one_file.qmdquarto render subdir/
Тем не менее, даже в случае рендеринга части проекта, при визуализации любой связанный с этой частью код все равно будет выполняться. Более того, для больших проектов или в том случае, если работа с документами происходит в течение длительного времени или имеется много вычислительных документов, существует необходимость в оптимизации рендера документов, например, чтобы использовать повторно результат предыдущего рендера. Такого рода оптимизация осуществляется с помощью кэширования (опция cache) или заморозки (опция freeze). Обе опции схожи по цели, но они решают несколько разные задачи.
кэширование (cache)
Опция cache позволяет сохранять результаты вычислений на основе кэширования в Knitr в R либо кэширования в Jupyter соответственно. Для этого необходимо указать в преамбуле:
execute:cache:true
В случае, если код или его параметры изменятся, кэш будет обновлен. Для обновления кэша можно выполнить рендеринг с опцией --cache-refresh:
Terminal
quarto render --cache-refresh
Иногда полезно определить локальные изменения в конфигурации проекта, которые не должны быть были зарегистрированы в системе контроля версий. Это можно сделать, создав _quarto.yml.local-файл конфигурации. Например, здесь мы указываем, что хотим использовать кэш выполнения при локальном запуске:
_quarto.yml.local
execute:cache:true
заморозка (freeze)
В том случае, если вам необходимо гарантировать полную неизменность результатов рендеринга при исполнении ячеек с кодом, даже если изменяются версии библиотек, можно использовать заморозку, которую можно включить так:
execute:freeze:true
При использовании опции freeze все вычислительные результаты будут храниться в каталоге _freeze и повторно использоваться при необходимости для выполнения рендеринга документов. Данный каталог можно удалить в корневом каталоге Quarto-проекта при необходимости.
Предупреждение
Внимательно отслеживайте содержимое каталога _freeze при использовании системы контроля версий, записав данный каталог в .gitignore для того, чтобы другим соавторам не пришлось воспроизводить вашу вычислительную среду для рендеринга в своей среде.
В том случае, если нескольким соавторам необходимо использовать набор локализованных зависимостей для документов в распределенной системе управления версиями, можно объединить freeze с использованием виртуальных сред, чтобы разделить весь проект на подкаталоги, каждый из которых имеет свой собственный набор зависимостей (см. статью).
Отметим, что можно также сделать рабочие процессы воспроизводимым, а также изолировать использование библиотек с помощью различных виртуальных сред, что помогает точно воспроизводить среду с течением времени, а также гарантирует, что обновление библиотек в одном проекте не нарушит работу других проектов.
В Quarto реализовано несколько популярных разновидностей виртуальной среды: venv (для Python 3), conda (для Anaconda/Miniconda) и renv (библиотека для создания воспроизводимых сред проектов в R). Остановимся на использовании renv, подробное описание других вариантов сред можно прочесть в статье Виртуальные среды.
1. Инициализацияrenv
Для того, чтобы использовать renv, необходимо инициализировать его в каталоге проекта:
install.packages("renv")renv::init()
Если вы планируете использовать в своем проекте и R, и Python, можно настроить renv на автоматическое создание и управление виртуальной средой Python следующим образом:
install.packages("renv")renv::use_python()
2. Добавление зависимостей
Необходимо убедиться, что все необходимые библиотеки уже установлены. Для установки библиотек R используйте стандартную команду install.packages либо renv::install для установки из GitHub. Например:
install.packages("ggplot2") # установка из CRANrenv::install("tidyverse/dplyr") # установка из GitHub
3. Фиксация окружения
Чтобы записать текущие версии всех библиотек R (и, возможно, Python), используйте функцию renv::snapshot():
renv::snapshot()
Данная команда запишет файл renv.lock для библиотек R и файл requirements.txt для библиотек Python. Отметим, что эти файлы должны быть проверены в системе контроля версий.
4. Восстановление окружения
Для воспроизведения среды на другом компьютере используйте renv::restore():
Используйте freeze: true для блогов, где мы должны быть уверенными, что старые записи не будут повторно проходить рендеринг, если только это не сделано специально, поскольку библиотеки, использованные в записях блога могут существенно измениться.
Используйте freeze: auto как повторный рендеринг кода только при изменении источника, например, если вы делаете курсы, где должны версии кода и библиотек должны быть актуальными.
Заключение
Здесь мы рассмотрели основную структуру документов Quarto: метаданные на основе YAML, элементы Markdown для формирования текста документа и каким образом в Quarto можно вставлять элементы исполняемого кода.
Лесные пожары в РФ за период 2012-2021 гг. Более подробно можно посмотреть на странице Графики на досуге