4 Формирование документов в Quarto
4.1 Элементы Div и Span
Если выходной формат HTML, то Quarto с помощью Pandoc преобразует Markdown в HTML-код, в частности, для базовых блочных элементов <div>
в HTML существует прообраз в Quarto. Классы Div в Quarto начинаются с ограждения, содержащего не менее трех последовательных двоеточий :::
(возможно больше) плюс некоторые атрибуты. Div должен быть отделен пустыми строками от предшествующих и последующих блоков, кроме того, Div могут быть вложенными. Пусть (например, с помощью CSS) определен некий класс .my_class
:
Quarto
::: {.my_class}
Новое форматирование. :::
Тогда Quarto преобразует разметку в HTML:
HTML
<div class="my_class">
<p>Новое форматирование.</p>
</div>
Хорошим примером применения классов такого рода являются выносные блоки, которые мы рассмотрим далее. Покажем пример сложного вложения Div:
Quarto
:::: {#special .my_class}
::: {.note}
Внутренний текст.
:::
Внешний текст. ::::
Quarto преобразует пример выше в HTML-разметку:
HTML
<div id="special" class="my_class">
<div class="note">
<p>Внутренний текст.</p>
</div>
<p>Внешний текст.</p>
</div>
Последовательность строк в квадратных скобках, которую можно использовать для начала ссылки, может рассматриваться как ссылка Span с атрибутами, если за ней сразу следуют атрибуты, например:
Quarto
*некий текст*]{.class key="val"} [Это
После рендеринга в HTML Quarto преобразует разметку в:
HTML
<span class="class" data-key="val">
<em>некий текст</em>
Это </span>
Еще один пример: определим новый CSS-класс .newtext
как это сделано ниже
CSS
.newtext {
font-size: 30px;
color: red;
}
Тогда текст
Quarto
В HTML документе есть [селекторы по CSS классу]{.newtext}.
будет преобразован в следующий:
В HTML документе есть селекторы по CSS классу.
Отметим, что данный прием с использованием стилей очень хорошо работает в Revealjs-презентациях.
В случае, если текст занимает много места или есть необходимость спрятать его под сворачивающийся комментарий, то это можно сделать с помощью тега <details>
.
Quarto
<details>
<summary>Пример скрытого текста</summary>
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.
</details>
Пример скрытого текста
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.4.2 Перекрестные ссылки
Перекрестные ссылки в Quarto позволяют связывать части документа, а читателю ориентироваться в тексте. В Quarto перекрестные ссылки представляют собой пронумерованные ссылки и гиперссылки на различные элементы текста и могут создаваться автоматически. Удобство состоит в том, что, как и в LaTeX, нумерация ссылок создается автоматически. В том месте, где создается ссылка, необходимо создать уникальный идентификатор с префиксом типа перекрестной ссылки. Все известные зарезервированные префиксы: #fig-
, #tbl-
, #lst-
, #tip-
, #nte-
, #wrn-
, #imp-
, #cau-
, #thm-
, #lem-
, #cor-
, #prp-
, #cnj-
, #def-
, #exm-
, #exr-
, #sol-
, #rem-
, #eq-
, #sec-
. Некоторые примеры показаны в таблице далее.
Префикс | Вывод |
---|---|
#fig- |
Рисунок |
#tbl- |
Таблица |
#sec- |
Глава |
#thm- |
Теорема |
#eq- |
Уравнение |
Перекрестная ссылка устроена следующим образом: внутри блока кода label: prefix-LABEL
, внутри Markdown #prefix-LABEL
, где LABEL
– уникальное имя ссылки. В тексте можно сослаться как @prefix-LABEL
. Покажем на примерах, как это работает. Мы уже видели примеры перекрестных ссылок в рисунках.
Quarto
![Рисунок](picture.png){#fig-my-picture}
См. иллюстрацию: @fig-my-picture.
Отметим, что ссылки можно кастомизировать как это показано ниже в таблице.
Тип ссылки | Синтаксис | Вывод |
---|---|---|
По умолчанию | @fig-Moscow |
Рисунок 3.2 |
Заглавные | @Fig-Moscow |
Рисунок 3.2 |
Собственный префикс | [рис. @fig-Moscow] |
рис. 3.2 |
Без префикса | [-@fig-Moscow] |
3.2 |
Quarto
[@fig-fires; @fig-wildfires]. Перекрестные ссылки можно группировать:
Перекрестные ссылки можно группировать: Рисунок 3.3 (a), Рисунок 3.3 (b).
Также можно ссылаться на таблицы.
Quarto
| пункт 1 | пункт 2 | пункт 3 |
|:--------|:--------|:--------|
| one | один | 1 |
| two | два | 2 |
: Таблица со ссылкой {#tbl-sample-table}
См. таблицу: @tbl-sample-table.
пункт 1 | пункт 2 | пункт 3 |
---|---|---|
1 | один | one |
2 | два | two |
См. таблицу: Таблица 4.2.
На разделы документа можно ссылаться с помощью #sec-
, как это сделано ниже.
Quarto
## Введение {#sec-introduction}
См. раздел @sec-introduction.
Ссылки на уравнения делаются на основе префикса eq-
.
Quarto
Линейная регрессионная модель выражается соотношением
$$
y = \beta_1 x_1 + \beta_2 x_2 + \ldots + \beta_n x_n + \varepsilon.
$$ {#eq-regression}
См. уравнение: @eq-regression.
Линейная регрессионная модель выражается соотношением \[ y = \beta_1 x_1 + \beta_2 x_2 + \ldots + \beta_n x_n + \varepsilon. \tag{4.1}\]
См. уравнение: Уравнение 4.1.
На математические конструкции (доказательства, леммы, определения и т.д.) также можно ссылаться.
Quarto
::: {#lem-Zorn}
## Лемма Цорна
Если в частично упорядоченном множестве M для всякого линейно-упорядоченного подмножества существует верхняя грань, то в M существует максимальный элемент.
См. лемму: @lem-Zorn. :::
Лемма 4.1 (Лемма Цорна) Если в частично упорядоченном множестве M для всякого линейно-упорядоченного подмножества существует верхняя грань, то в M существует максимальный элемент.
См. лемму: Лемма 4.1.
Отметим, что класс .proof
не обладает нумерацией.
Quarto
::: {.proof}
Текст доказательства. :::
Доказательство. Текст доказательства.
Списки (листинги) также могут иметь перекрестные ссылки.
Quarto
::: {#lst-customers}
```{.sql}
SELECT COUNT(CustomerID), Country
FROM Customers
GROUP BY Country;
```
Запросы клиентов :::
В Quarto можно создавать собственные перекрестные ссылки. Ниже показан пример собственного определения перекрестных ссылок, причем ссылаться на этот вариант ссылки можно будет как {#vid-LABEL}
.
_quarto.yaml
crossref:
custom:
- kind: float
reference-prefix: Video
key: vid
4.3 Выносные блоки
Интересной новинкой Quarto являются выносные блоки, которые служат способом привлечения дополнительного внимания к определенным указаниям или концепциям, например, о том, что определенное содержимое является важным или применимо только к некоторым сценариям. Выносные блоки работают в HTML, PDF, MS Word, ePub и Revealjs. Основные типы блоков: note
, warning
, important
, tip
и caution
.
Этот элемент будет использоваться для замечаний.
Этот элемент будет использоваться для предостережений.
Этот элемент будет использоваться для важных сообщений.
Этот элемент будет использоваться для рекомендаций и советов.
Этот элемент будет использоваться для предупреждений.
Ниже показан пример кода для оформления блока.
Quarto
:::{.callout-tip}## Совет
Этот элемент будет использоваться для рекомендаций и советов. :::
либо
Quarto
::: {.callout-tip title="Совет"}
Этот элемент будет использоваться для рекомендаций и советов. :::
Этот элемент будет использоваться для рекомендаций и советов.
Пример блока с развертыванием.
Quarto
::: {.callout-caution collapse="true"}## Разверните блок
Это пример *свернутого* блока. :::
Это пример свернутого блока, который может быть развернут пользователем. Вы можете управлять параметрами, указав collapse="true"
или collapse="false"
.
Пример кастомизации блока.
Quarto
::: {.callout-note icon=false}## Обратите внимание
Здесь нет иконки :::
4.4 Диаграммы
В Quarto реализована вставка диаграмм — это еще одно ноу-хау в Quarto, имеющее встроенную поддержку Mermaid и Graphviz диаграмм. Данное новшество позволяет создавать блок-схемы, диаграммы последовательностей, диаграммы состояний, диаграммы Ганта и многое другое, используя синтаксис обычного текста, мотивированный Markdown.
Mermaid — это инструмент для создания диаграмм и графиков на основе JavaScript, который преобразует текстовые определения в формат Markdown для динамического создания и изменения диаграмм с достаточно простым синтаксисом и большой вариативностью настроек. Для Mermaid существует онлайн редактор.
Ниже показан пример оформления диаграммы.
Mermaid
```{mermaid}
%%| label: fig-mermaid-example
%%| fig-cap: |
%%| Простая диаграмма Mermaid
flowchart LR
A[Прямоугольник] --> B(Скругленные края)
B --> C{Решение}
C --> D[Первый результат]
C --> E[Второй результат]
```
Еще одна возможность для построения диаграмм в Quarto — это диаграммы Graphviz, которые также преобразуют описания графиков простым текстовым языком и создают диаграммы в удобных форматах. Graphviz обладает множеством полезных функций для конкретных диаграмм, таких как варианты цветов, шрифтов, расположение узлов в виде таблиц, стили линий, гиперссылки и пользовательские формы. Для Graphviz также существует онлайн редактор.
Graphviz
```{dot}
//| label: fig-graphviz-example
//| fig-width: 5
//| fig-cap: |
//| Пример Graphviz-диаграммы
digraph {
Москва -> Минск[color=red,label="0.2",weight="0.2"];
Москва -> Казань[label="0.4",weight="0.4"];
Казань -> Минск[color=red,label="0.6",weight="0.6"];
Казань -> Воронеж[label="0.6",weight="0.6"];
Воронеж -> Воронеж[label="0.1",weight="0.1"];
Воронеж -> Минск[color=red,label="0.7",weight="0.7"];
}
```
Обратите внимание, что ячейки имеют несколько различный синтаксис: %%|
для параметров и %%
для комментариев {mermaid}
(Mermaid), и //|
для параметров и //
для комментариев в {dot}
(Graphviz).
4.5 Формулы в Quarto
Математические формулы в Quarto реализованы на основе LaTeX-синтаксиса: также как и в \(\LaTeX\) здесь используются разделители $
для встроенных математических элементов в тексте и разделители $$
для выносной математики. Пример формулы в Quarto приведен ниже.
LaTeX
$$
Y_Q(a_1, \ldots, a_n) =
(-1)^{\frac{(d-1)(d-2)}{2}} \int_{Z_f}
\Omega\wedge
Q\left(
a_1\frac{\partial}{\partial a_1},\ldots,
a_n\frac{\partial}{\partial a_n}
\right)\Omega
$$
\[ Y_Q(a_1, \ldots, a_n) = (-1)^{\frac{(d-1)(d-2)}{2}} \int_{Z_f} \Omega\wedge Q\left( a_1\frac{\partial}{\partial a_1},\ldots, a_n\frac{\partial}{\partial a_n} \right)\Omega \]
Для математической обработки HTML с использованием MathJax (по умолчанию) можно использовать команды \def
, \newcommand
, \renewcommand
, \newenvironment
, \renewenvironment
и \let
для создания собственных макросов и сред. Если необходимо определить пользовательские макросы TeX (в PDF), включите их в разделители $$
, заключенные в блок .hidden
. Например:
Quarto
::: {.hidden}
$$
\def\RR{{\bf R}}
\def\bold#1{{\bf #1}}
$$ :::
4.6 Наборы вкладок
Если вы хотите переключаться между различными визуализациями, таблицами или иными элементами, то можно использовать наборы вкладок, разделяемые с помощью ##
как это показано ниже.
::: {.panel-tabset .nav-pills}
## Диаграмма рассеяния
...
## Диаграмма размаха
...
## Данные
...
:::
library(ggplot2)
|>
mpg ggplot(aes(x = displ, y = hwy,
colour = class)) +
geom_point()
library(ggplot2)
library(dplyr)
|>
mpg mutate(class = reorder(class, displ)) |>
ggplot(aes(x = class, y = displ,
fill = class)) +
geom_boxplot()
library(dplyr)
|>
mpg head() |>
select(manufacturer, model, year,
|>
displ, hwy, class) ::kable() knitr
manufacturer | model | year | displ | hwy | class |
---|---|---|---|---|---|
audi | a4 | 1999 | 1.8 | 29 | compact |
audi | a4 | 1999 | 1.8 | 29 | compact |
audi | a4 | 2008 | 2.0 | 31 | compact |
audi | a4 | 2008 | 2.0 | 30 | compact |
audi | a4 | 1999 | 2.8 | 26 | compact |
audi | a4 | 1999 | 2.8 | 26 | compact |
4.7 Включения
Включения (includes) служат для повторного использования одного и того же фрагмента в различных документах. Это очень удобная особенность Quarto: например, можно использовать один и тот же текст и в презентации и в научной статье. Пусть элемент текста Quarto, который мы хотим включить, называется _text.qmd
, тогда его включение в файл происходит по правилу
{{< include _text.qmd >}}
Включаемые короткие коды эквивалентны копированию и вставке текста из включаемого файла в основной файл. Это означает, что относительные ссылки (ссылки, изображения и т.д.) внутри включаемого файла разрешаются на основе каталога основного, а не включаемого файла.
Обратите внимание на то, что файл начинается с префикса подчеркивания _file_name.qmd
для включаемых файлов, это позволяет автоматически игнорировать их для исполнения при выполнении quarto render
. Во избежание конфликтов, рекомендуется на использовать метаданные во включаемых файлах.
Включения позволяют делать вставки как Quarto-файлов как с ячейками с кодом, так и отдельные файлы с кодом, сохраненным в виде скриптов.
Следует отметить, что ячейки исходного и включаемого файлов должны использовать один и тот же движок — то есть knitr или jupyter, но не оба. Вычислительные функции работают только в *.qmd
-файлах, но не работают в *.ipynb
файлах Jupyter-блокнотов.
Приведем пример файла с включениями, где вычисления происходят как в основном файле, так и внутри файла-включения.
---
title: "Пример файла с включениями"
---
## Обзор
Здесь может быть текст основного файла.
{{< include _secondary.qmd >}}
## Немного кода
Включение **R**-кода...
```{r}
{{< include _demo.R >}}
```
_secondary.qmd
Небольшой включаемый текст с кодом.
```{r}
library(ggplot2)
mpg |>
ggplot(aes(x = displ, y = hwy,
colour = class)) +
geom_point()
```
Помимо include
, возможно встраивание вывода другого документа Quarto (*.qmd
или *.ipynb
) с помощью конструкции embed
. Чтобы встроить вывод блока кода или ячейки блокнота, необходимо указать путь к документу и идентификатор блока или ячейки.
Пусть hello.ipynb
это файл, из которого необходимо извлечь фрагмент кода.
hello.ipynb
---
"Пример ноутбука"
title:
jupyter: python3---
#| label: fig-polar
#| fig-cap: "Пример встроенного графика"
import numpy as np
import matplotlib.pyplot as plt
= np.arange(0, 2, 0.01)
r = 2 * np.pi * r
theta = plt.subplots(
fig, ax = {'projection': 'polar'}
subplot_kw
)
ax.plot(theta, r)0.5, 1, 1.5, 2])
ax.set_rticks([True)
ax.grid( plt.show()
Встраивание из hello.ipynb
происходит следующим образом.
Quarto
{{< embed hello.ipynb#fig-polar >}}
4.8 Переменные
В Quarto возможно вставлять переменные в виде формата «short codes» (так называемые «короткие элементы кода»), общий вид которых
{{< shortcode code >}}
В Quarto существует три варианта для «коротких элементов кода»: meta
, env
и var
.
meta
Короткий элемент кода meta
позволяет вставлять в текст содержимое из текущих YAML-метаданных Pandoc (например, из _quarto.yml
). Например, для того, получить название текущей главы можно так:
{{< meta title >}}
4 Формирование документов в Quarto
Для получения доступа к ключам метаданных можно использовать разделитель dot(.)
, например, чтобы получить название данной книги:
{{< meta book.title >}}
Научно-издательская система Quarto
env
Элементы кода env
необходимы для установки переменных окружения, которые вы хотите установить при каждом рендеринге вашего проекта, например:
- Можно определить версии R и Python, которые будут использоваться (например,
QUARTO_PYTHON
,QUARTO_R
,PY_PYTHON
). - Настроить поведение исполняемого кода (например,
OMP_NUM_THREADS
,ARROW_IO_THREADS
и т.д.). - Предоставить учетные данные для доступа к удаленному серверу, адрес прокси-сервера (например,
HTTP_PROXY
).
Значения переменных можно включать в файл _environment
на корневом уровне вашего проекта в котором находится файл _quarto.yml
, они будут прочитаны и установлены в среде при чтении конфигурации проекта.
_environment
# пример настройки окружения
# сервер баз данных
DATABASE_SERVER=https://db.example.com DATABASE_API=${DATABASE_SERVER}/api
Подробнее о возможностях env
можно прочесть на странице документации Quarto.
var
Предположим, что в документе есть изменяемые элементы, которые могут изменяться в различных версиях, тогда изменямые элементы можно хранить в файле _variables.yml
и обращаться с помощью конструкции {{< var key>}}
. Приведем пример файла _variables.yml
.
_variables.yml
version: 1.1
course:
name: Курс по языкам программирования
instructor:
name: А.А. Иванов
email: my@email.com
url: "https://site.name.com/"
mastodon: mymastodon
github: mygithub
university:
name: МГУ им. М.В. Ломоносова
url: "[университет](<https://university.site.com/>)"
Теперь чтобы включить значение переменной, можно использовать {{< var key>}}
либо {{< var key.subkey>}}
, например:
Quarto
*{{< var course.name>}}* ожидает большая переработка, в новой версии {{< var version>}} будут существенные изменения. Основной лектор нашего курса --- {{< var instructor.name>}}, {{< var university.name>}}.
Курс по языкам программирования ожидает большая переработка, в новой версии 1.1 будут существенные изменения. Основной лектор нашего курса — А.А. Иванов, МГУ им. М.В. Ломоносова.
Безусловно, короткие элементы кода в базвом Quarto позволяют делать автоматизированные шаблоны, что значительно облегчает набор документов, вместе с тем, расширения Quarto также дают возможность использовать ту же конструкцию на базе {{< shortcode code >}}
. Например, расширение now позволяет вставлять в документы текущие временные показатели, например, год, месяц, дату и прочее.
Эелемент кода | Результат | Формат |
---|---|---|
{{< now >}} |
2024-10-13 03:44:38 |
"%F %T" |
{{< now year >}} |
2024 |
"%Y" |
{{< now day >}} |
13 |
"%d" |
{{< now hour >}} |
03 |
"%I" |
{{< now minute >}} |
44 |
"%M" |
4.9 Макеты страницы
Рассмотрим расположение компонентов макета для HTML-страниц. Несмотря на то, что документы Quarto HTML по умолчанию хорошо оптимизированы для чтения, иногда возникает потребность в настройке страниц. Мы рассмотрим следующие варианты настройки:
- настройка отдельных блоков страницы:
- для содержимого, который заполняет основную область контента,
- переполняет область содержимого,
- охватывает всю страницу,
- занимает поля документа;
- настройка отдельных компонентов страницы (боковой панели, основного текста, полей и т. д.).
4.9.1 Настройка ширины блоков страницы
Ширина содержимого контролируется с помощью классов Div. Например, column-body
задает ширину по умолчанию.
.column-body
В том случае, если необходимо расширить ширину содержимого, можно использовать Div класс column-body-outset
.
Quarto
:::{.column-body-outset}
Dolor tempor cras arcu ornare quam, curae porttitor per suspendisse gravida sagittis? Tristique sed duis dictumst hendrerit dapibus dignissim mauris pharetra mattis viverra. Vitae pellentesque facilisi gravida habitasse class inceptos fames semper. Parturient euismod sem: facilisi parturient nostra et cubilia consequat. At facilisis velit? :::
Dolor tempor cras arcu ornare quam, curae porttitor per suspendisse gravida sagittis? Tristique sed duis dictumst hendrerit dapibus dignissim mauris pharetra mattis viverra. Vitae pellentesque facilisi gravida habitasse class inceptos fames semper. Parturient euismod sem: facilisi parturient nostra et cubilia consequat. At facilisis velit?
.column-body-outset
Если необходимо еще больше места для содержимого, можно использовать класс column-page
, чтобы сделать содержимое намного шире, но не распространяя его до границ страницы документа.
.column-page
Например, для широкого рисунка:
:::{.column-page}![](Elbrus.png)
:::
Аналогично с помощью класса column-screen
можно разместить содержимое на всю ширину страницы без полей.
.column-screen
Отметим, что такого рода классы применимы и к ячейкам с кодом. Например, если график шире, чем узкая область текста, это можно регулировать параметрами column
и out-width
.
R
#| column: screen
#| out-width: 100%
library(leaflet)
leaflet() |>
addTiles(options = providerTileOptions(opacity = 0.9,
minZoom=15,
maxZoom=16)) |>
addMarkers(lng = 174.768,
lat = -36.852,
popup = "Место рождения языка R")
В том случае, если содержимое выходит за пределы основной области только на левой или правой стороне документа, можно использовать версии right
и left
для компоновки переполнения как показано ниже.
.column-body-outset-right
.column-page-inset-right
.column-page-right
.column-screen-inset-right
.column-screen-right
Для переполнения слева все работает точно также, только -right
нужно заменить на -left
. Таким образом, для блоков переполнение работает как конструкция вида
Quarto
:::{.column-class}
Содержимое...
:::
в которой class
может быть: body
, body-outset
, page-inset
, page
, screen-inset
и screen
, после чего может стоять уточняющий -right
или -left
. Если переполнение осуществляется внутри ячейки с кодом, то конструкция выше заменяется на
R/Python/Julia
#| column: class
Исполняемый код...
4.9.2 Настройка отдельных компонентов страницы
Макет документов Quarto HTML организован в структуру, состоящую из трех основных частей:
- боковая панель (
sidebar
), - основная область (
body
), - поля страницы (
margin
),
а также пространства между этими элементами (gutter
).
Исходные значения по умолчанию, определяющие максимальное базовое значение, показаны в таблице ниже. Эти значения используются для вычисления размера и положения каждого компонента в различных типах макета (фиксированный или плавающий), адаптивных размерах (большой экран или мобильный размер) и содержимом страницы (поле или содержимое без полей).
Элемент страницы | Размер |
---|---|
sidebar-width |
250px |
body-width |
800px |
margin-width |
250px |
gutter-width |
1.5em |
Ширину данных элементов можно варьировать с помощью переменных YAML или SCSS.
_quarto.yml
format:
html:
grid:
sidebar-width: 200px
body-width: 750px
margin-width: 450px
gutter-width: 2em
style.scss
// левая боковая панель
$grid-sidebar-width: 200px !default;
// основная область
$grid-body-width: 750px !default;
// поля страницы справа
$grid-margin-width: 450px !default;
// пространство между элементами указанными выше
$grid-column-gutter-width: 2em !default;
Здесь sidebar-width
, body-width
, и margin-width
должны быть указаны в пикселях (px
), поскольку значения будут использоваться при вычислении других размеров, поскольку общая ширина документа обычно привязана к размеру браузера и адаптивным контрольным точкам, а не к размеру шрифта или другим относительным показателям.
Заключение
В данном разделе мы сделали обзор множества различных настроек для формирования документов Quarto:
- перекрестные ссылки,
- выносные блоки для акцентирования внимания,
- диаграммы,
- формулы,
- наборы вкладок,
- возможности повторного использования контента,
- макеты веб-страниц.
Все эти элементы существенно расширяют базовые возможности Quarto, рассмотренные в предыдущем разделе.