Экосистема LaTeX. Быстрый старт
- TeX (произносится как «тех») – система компьютерной верстки, предназначенная для подготовки научно-технических материалов высокого полиграфического качества.
- LaTeX (произносится «латех») – это, строго говоря, набор макросов на языке разметки TeX, но в зависимости от контекста под LaTeX может пониматься макропакет, издательская система или язык, служащий для разметки документа. LaTeX 2e – наиболее полная, стабильная версия LaTeX.
- MikTеX – свободно распространяемая реализация TeX под основные операционные системы – Windows, macOS, Linux (Ubuntu, Debian, CentOS и пр.) – включающая в себя практически все наиболее значимые расширения.
Установить реализацию MikTеX под нужную операционную систему можно по инструкциям на странице проекта. При желании с системой можно взаимодействовать и без установки дистрибутива, просто запустив Docker-образ:
$ docker pull miktex/miktex
$ docker volume create --name miktex
$ docker run -it \
-v miktex:/miktex/.miktex \
-v $(pwd):/miktex/work \
miktex/miktex \
pdflatex main.tex
Здесь с помощью команды docker pull
в локальное хранилище образов скачивается Docker-образ miktex/miktex
. Затем командой docker volume
в файловой системе хоста создается директория miktex/
. Последним шагом с помощью команды docker run
остается запустить контейнер Docker на базе образа miktex/miktex
. Флаг -it
создает сеанс интерактивной работы на подключаемом терминальном устройстве, а флаг -v
отображает директорию файловой системы хоста на директорию внутри контейнера.
Контейнер ожидает получить аргументы командной строки указывающие на выбранный компилятор (в данном случае PDFLaTeX) и собственно tex-файл (размеченный документ, на основании которого позже будет создан pdf-файл).
Опорный документ LaTeX (tex-файл) представляет собой обычный текстовый файл с разметкой. Для редактирования такого рода файлов можно пользоваться и обычным текстовым Unix-редактором Vim, но практичнее использовать специальные решения, например, открытую среду разработки TeXstudio (поддерживает все основные операционные системы). Однако TeXstudio не единственный вариант. Вот наиболее распространенные альтернативы: TeXmaker, Kile, TeXCenter.
Каждый пакет репозитория содержит документацию (с описанием зависимостей, примерами и контекстом использования, деталями реализации и пр.), исходные файлы, описание синтаксических особенностей, макродемонстрацию и другие компоненты, позволяющие быстро понять устройство пакета и порядок работы с ним. С общей структурой пакетов CTAN можно познакомиться на примере пакета для оформления программного кода listings.
Итак, для запуска примеров из настоящего руководства потребуется установить дистрибутив TeX (например, MikTеX) и LaTeX-редактор (например, TeXstudio).
Введение в язык разметки LaTeX
В текстовых процессорах, которые позволяют в момент набора текста видеть его на экране дисплея точно таким, как он будет выглядеть на бумаге, используется концепция визуального проектирования (WYSIWYG – What You See Is What You Get). В LaTeX же используется концепция логического проектирования, когда внешний вид документа становится понятен только после компиляции.
Теперь рассмотрим общий синтаксис языка LaTeX и познакомимся с базовой структурой tex-документа.
- LaTeX-файл должен начинаться с команды
\documentclass
, задающей стиль оформления документа, например,\documentclass{article}
. Аргумент командыarticle
означает, что документ будет оформлен в соответствии с наиболее общими правилами оформления статей. При желании можно изменить (с незначительными оговорками) любой элемент макета документа. - Команда
\documentclass
поддерживает и другие классы, доступные «из коробки»:book
(для оформления книг),report
(для оформления отчетов – нечто среднее междуbook
иarticle
),proc
(для оформления трудов конференций) иletter
(для деловых писем со сложной структурой). - После команды
\documentclass
могут следовать команды, относящиеся ко всему документу. Далее с помощью окружения\begin{document}
…\end{document}
(условимся называть его документарным окружением) указывается тело документа. В общем случае окружением называют сложные конструкции вида\begin{}
…\end{}
. - Часть tex-файла между командой
\documentclass
и\begin{document}
…\end{document}
называют преамбулой. Команды указанные после закрывающей скобки окружения документа\end{document}
LaTeX проигнорирует.
В итоге наипростейший шаблон документа будет выглядеть так:
\documentclass{article}
% область преамбулы
\begin{document} % тело документа: начало
% текст
\end{document} % тело документа: конец
% команды в этой части документа не будут учитываться при сборке документа
Инструкции, управляющие макетом страницы и прочие настройки tex-документа, могут быть размещены и в преамбуле, но когда инструкций становится много, будет удобнее вынести их в отдельный стилевой файл с расширением *.sty
. Позже стилевой файл можно будет подключить командой \usepackage{}
, принимающей в качестве аргумента путь до этого файла.
Сам стилевой файл содержит импорты пакетов \RequirePackage{}
, пользовательские команды \newcommand{}
, псевдонимы математических операторов \DeclareMathOperator
и прочие элементы кастомизации:
% начало стилевого файла
\RequirePackage[english,russian]{babel}
\RequirePackage[utf8]{inputenc}
\RequirePackage{amsmath, amsfonts, amssymb, latexsym}
\RequirePackage[
left=2cm,
right=2cm,
top=2cm,
bottom=2cm
]{geometry}
...
\newcommand{\str}[1]{cтр.~\pageref{#1}}
\newcommand{\strbook}[1]{стр.~{#1}}
...
\DeclareMathOperator*{\argmin}{arg\,min}
\DeclareMathOperator*{\argmax}{arg\,max}
\DeclareMathOperator*{\sign}{sign}
\DeclareMathOperator*{\const}{const}
...
С подключенным стилевым файлом tex-документ будет выглядеть так:
\documentclass{article}
\usepackage{style_template} % подключаем стилевой файл style_template.sty, расположенный в той же директории, что и tex-файл
\begin{document}
% текст
\end{document}
Аргумент команды \usepackage
может включать не только имя стилевого файла, но и путь до него относительно корня проекта (без указания расширения файла).
Далее предполагается, что все настройки макета документа описаны в стилевом файле style_template.sty
, который расположен в той же директории, что и tex-файл.
Разобравшись с базовыми структурными элементами tex-файла, можно сосредоточиться на содержательной части и перейти к наполнению документа.
Наберем в документарном окружении следующие строки:
...
\begin{document}
\title{Аналитический отчет по ...} % заголовок отчета
\author{\itshape Иванов И.И.} % автор работы
\date{} % просим LaTeX не указывать дату, так как будет
% использован наш вариант оформления даты, описанный в стилевом файле
\maketitle % создает заголовок
\thispagestyle{fancy} % задает стиль страницы
В этой части можно разместить аннотацию к отчету. \TeX -- это издательская система компьютерной верстки, предназначенная для набора ...
\tableofcontents % создает оглавление
\section{Пример многострочной формулы}
Для набора сложных многострочных формул используются различные окружения, например, окружение \texttt{multline}
\begin{multline}
F_{\zeta}(z)=P[\,\zeta\leqslant z\,] = \int\!\!\!\int_{x/y\leqslant z}f_X(x;n)f_Y(y;m)\,dxdy =\\ \dfrac{1}{2^{(n+m)/2}\Gamma(n/2)\Gamma(m/2)}\int\!\!\!\int_{x/y\leqslant z}x^{n/2-1}y^{m/2-1}\exp\left( -\frac{x}{2} \right) \exp\left( -\frac{y}{2} \right) \,\mathrm{d}x \, \mathrm{d}y.
\end{multline}
\section{Пример группового размещения формул}
Несколько формул можно разместить в одной группе с помощью окружения \texttt{gather}
\begin{gather}
\sum_{j \in \mathbf{N}} b_{ij} \hat{y}_{j} = \sum_{j \in \mathbf{N}} b_{ij}^\lambda \hat{y}_j + (b_{ii} - \lambda_i)\hat{y}_i \hat{y},\notag \\
\det \mathbf{K}(t=1, t_1, \ldots, t_n) = \sum_{I \in \mathbf{n} } (-1)^{|I|} \prod_{i \in I} t_i \prod_{j \in I} (D_j + \lambda_j t_j) \det \mathbf{A}^{(\lambda)} (\, \overline{I} | \overline{I} \,) = 0,\tag{$a$} \\
\mathbb{F} = \sum_{i=1}^{\left[ \frac{n}{2}\right] } \binom{ x_{i,i+1}^{i^2}}{ \left[ \frac{i+3}{3} \right]} {{\sqrt{\mu(i)^\frac{3}{2} (i^2-1)}} \over\displaystyle {\sqrt[3]{\rho(i)-2} + \sqrt[3]{\rho(i)-1}} }, \tag{$b$}
\end{gather}
\section{Простая однострочная формула}
Теорема Хинчина-Винера утверждает, что спектральная плотность мощности стационарного в широком смысле случайного процесса представляет собой преобразование Фурье от соответствующей автокорреляционной функции
\begin{equation*} % без нумерации
S_{xx}(f) = \int\limits_{-\infty}^{\infty} \, r_{xx} (\tau) e^{-j 2 \pi f \tau} \mathrm{d} \tau,\ \text{где}\ r_{xx}(\tau) = \mathbb{E}[\,x(t) \, x^{*}(t - \tau)\,].
\end{equation*}
\end{document}
Теперь можно вызвать компилятор PDFLaTeX через командную оболочку и передать ему имя tex-файла. Результат компиляции приведен на рисунке ниже.

analyt_report_template.tex
Рассмотрим более подробно код файла analyt_report_template.tex
.
- В первых строках файла с помощью команд
\title
и\author
мы объявляем заголовок отчета и имя автора работы соответственно, а с помощью команды\maketitle
создаем заголовок. - Затем с помощью команды
\date
, вызванной без аргументов, подавляем вывод временной метки. Здесь для привязки ко времени будет использоваться специальная низкоуровневая командная вставка в стилевом файлеstyle_template.sty
(этот фрагмент кода приводится только для справки, так как конечному пользователю приложения нет необходимости вносить в стилевой файл изменения напрямую):
...
\def\@maketitle{
\begin{flushright}
\footnotesize\itshape
Дата последней сборки документа:\\ \today\ в \currenttime
\end{flushright}
\begin{center}
\let \footnote \thanks
\begin{spacing}{1.5}
{\Large\bfseries\@title}
\end{spacing}\vskip 1mm
{\normalsize
\begin{tabular}[t]{l}
\@author
\end{tabular}\par
}
\end{center}
\par
\vskip 1.5em
}
...
Команда \thispagestyle
задает стиль страницы, а команда \tableofcontents
создает оглавление документа. С помощью команды \section
создаются разделы документа высшего уровня (с учетом класса документа). Для того чтобы создать раздел более низкого уровня следующей ступени можно воспользоваться командой \subsection
.
equation
, multline
и gather
.Как должно быть понятно из приведенного выше рисунка, equation
используется для однострочных формул, multline
– для многострочных, а gather
– для группового размещения формул. Звездочка после имени окружения означает, что LaTeX не станет присваивать номера формулам, попавшим в это окружение.
При наборе формул используются специальные LaTeX-команды с названиями созвучными набираемому элементу, например, для того чтобы добавить в формулу знак суммы с нижним lowindex
и верхним upindex
индексом используется команда \sum_{lowindex}^{upindex}
, чтобы вставить символ большой омеги – \Omega
, а для вставки символа гамма потребуется \gamma
и т.д.
Прочие детали работы с издательской системой LaTeX можно выяснить из следующих работ:
Дональд Кнут «Все про TeX»: фундаментальное руководство, которое включает подробное обсуждение множества низкоуровневых технических моментов;- Сергей Львовский «Набор и верстка в пакете LaTeX»;
- Евгений Балдин «Компьютерная типография LaTeX».
Введение в Python-библиотеку Streamlit
Библиотека Streamlit – это простая, лаконичная и в тоже время очень мощная библиотека для прототипирования браузерных решений с графическим интерфейсом. Streamlit включает поддержку всех основных элементов стека, ориентированных на компьютерное зрение, машинное и глубокое обучение.
pip install streamlit
.Запускается приложение командой streamlit run
:
$ streamlit run streamlit_simple_example.py
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8502 # <--
Network URL: http://192.168.1.247:8502
После запуска сценария в браузере (http://localhost:8502
) откроется вкладка с приложением. Завершить работу приложения можно, закрыв вкладку браузера и набрав Ctrl+C
в командной оболочке.
В Streamlit реализован сравнительно небольшой набор «выразительных средств», но все элементы продуманы и покрывают значительную часть требований к «гибкому динамическому прототипу».
Ниже приводится пример использования библиотеки Streamlit для построения двух интерактивных графиков (на базе библиотеки Plotly) гауссовских процессов с автокорреляционной функцией экспоненциального типа.
import streamlit as st
import math
import pandas as pd
from pandas import Series
import plotly.graph_objects as go
import numpy as np
import numpy.random as rnd
title_app = "Простой пример использования библиотеки Streamlit"
# чтобы на вкладке браузера отображалось имя приложения, а не имя файла
st.set_page_config(
layout="wide",
page_title=title_app,
initial_sidebar_state="expanded",
)
def gauss_with_exp_acf_gen(
*,
sigma: float = 2,
w_star: float = 1.25,
delta_t: float = 0.05,
N: int = 1000,
) -> np.array:
"""
Описание
--------
Генерирует дискретную реализацию
стационарного гауссовского ПСП
с КФ экспоненциального типа
Параметры
---------
sigma : стандартное отклонение ординат ПСП.
w_star : параметр модели ПСП.
delta_t : шаг по времени.
N : число отсчетов ПСП.
Возвращает
----------
xi : массив элементов ПСП с заданной КФ
"""
gamma_star = w_star * delta_t
rho = math.exp(-gamma_star)
b1 = rho
a0 = sigma * math.sqrt(1 - rho ** 2)
xi = np.zeros(N)
xi[0] = rnd.rand()
x = rnd.randn(N)
for n in range(1, N):
xi[n] = a0 * x[n] + b1 * xi[n - 1]
return xi
def main(N: int = 100):
timestmp = np.arange(N)
# временной ряд №1
time_series_1 = gauss_with_exp_acf_gen(sigma=5, w_star=1.25, N=N)
# временной ряд №2
time_series_2 = gauss_with_exp_acf_gen(sigma=6.5, w_star=1.75, N=N)
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=timestmp,
y=time_series_1,
name="Временной ряд (объект-1)",
opacity=0.8,
mode="lines",
line=dict(
color="#E84A5F",
),
)
)
fig.add_trace(
go.Scatter(
x=timestmp,
y=Series(time_series_1).rolling(window=7).mean(),
name="Скользящее среднее (объект-1)",
mode="lines",
opacity=0.6,
line=dict(
color="#FF847C",
),
)
)
fig.add_trace(
go.Scatter(
x=timestmp,
y=time_series_2,
name="Временной ряд (объект-2)",
mode="lines",
opacity=0.8,
line=dict(
color="#5E63B6",
),
)
)
fig.add_trace(
go.Scatter(
x=timestmp,
y=Series(time_series_2).rolling(window=7).mean(),
name="Скользящее среднее (объект-2)",
mode="lines",
opacity=0.6,
line=dict(
color="#6EB6FF",
),
)
)
fig.update_layout(
title=dict(
# text="<i>Временной ряд</i>",
font=dict(
family="Arial",
size=18,
color="#07689F",
),
),
xaxis_title=dict(
text="<i>Временная метка</i>",
font=dict(
family="Arial",
size=13,
color="#537791",
),
),
yaxis_title=dict(
text="<i>Продолжительность простоя, час</i>",
font=dict(
family="Arial",
size=13,
color="#537791",
),
),
xaxis=dict(
showline=True,
),
yaxis=dict(
showline=True,
),
autosize=False,
showlegend=True,
margin=dict(
autoexpand=False,
l=70,
r=10,
t=50,
),
legend=dict(
orientation="v",
yanchor="bottom",
y=0.01,
xanchor="right",
x=0.99,
font=dict(family="Arial", size=12, color="black"),
),
plot_bgcolor="white",
)
st.plotly_chart(fig, use_container_width=True)
if __name__ == "__main__":
main(N=350)
В этом примере к библиотеке Streamlit имеет отношение только:
- функция
st.set_page_config()
, которая переопределяет имя вкладки браузера – отображается не имя файла, а имя приложения; - функция
st.plotly_chart()
, которая принимает сконфигурированный Plotly-объект и выводит его в окно браузера.

streamlit_simple_example.py
Прочие элементы сценария streamlit_simple_example.py
играют лишь вспомогательную роль.
Пример-шаблон аналитического отчета
Предлагается в качестве примера, сочетающего приемы работы с библиотекой Streamlit (браузерный интерфейс приложения) и LaTeX-разметку (опорный tex-файл), рассмотреть подготовку отчета на тему «Оценка усталостной долговечности силовых элементов транспортных машин под воздействием стационарных гауссовских процессов с автокорреляционной функцией экспоненциально-косинусного семейства».
Подробности реализации обсуждаемого решения можно узнать из github-репозитория, сейчас же кратко остановимся на нескольких нюансах.
Часто возникает необходимость выгрузить подготовленный с помощью Streamlit файл результатов (например, табличных объект Pandas), но сам Streamlit не предлагает никаких решений. Тем не менее это ограничение можно обойти с помощью следующей функции:
def text_downloader(multiline: str) -> NoReturn:
"""
Принимает LaTeX-шаблон документа в виде многострочной строки и
создает на странице ссылку для скачивания шаблона
"""
OUTPUT_TEX_FILENAME = "base_template_for_latex.tex"
b64 = base64.b64encode(multiline.encode()).decode()
# создает ссылку для скачивания файла
href = (f'<a href="data:file/txt;base64,{b64}" '
f'download="{OUTPUT_TEX_FILENAME}">Скачать ...</a>')
st.markdown(href, unsafe_allow_html=True)
Функция читает текстовый файл, переданный в виде строки, кодирует его с помощью стандарта base64 и передает тег-ссылку методу markdown
. В итоге файл можно будет скачать, кликнув на созданную ссылку.
При наборе текстового шаблона для Python (latex_template_for_python.txt
) – по сути файл представляет собой каркас документа с заглушками под строковую интерполяцию – важно помнить о синтаксических особенностях LaTeX. Дело в том, что в контексте строковой интерполяции фигурные скобки означают «место подстановки», а в контексте LaTeX – обязательный аргумент команды. То есть, чтобы Python корректно «прочитал» строку следует фигурные скобки, относящиеся к синтаксису LaTeX, удвоить.
В результате получится текстовый файл вида:
\documentclass[
11pt,
a4paper,
utf8,
]{{article}}
\usepackage{{style_template}}
\begin{{document}}
...
Усталостная долговечность по модели \eqref{{eq:miles}} составляет $ Y_{{NB}} = {Y_NB:.2f} $, сек.
\section{{Оценка усталостной долговечности по модели P.H. Wirsching и C.L.~Light}}
...
Ниже на рисунках приводится общий вид приложения.

Скачав подготовленный tex-файл в директорию проекта, останется только запустить компилятор (дважды!).
# для сборки каркаса
$ pdflatex base_template_for_latex.tex
# для вычисления конечных ссылок на страницы, формулы и пр.
$ pdflatex base_template_for_latex.tex
После сборки документа в рабочей директории проекта будет создан pdf-файл.


pdflatex base_template_for_latex.tex
. Фрагмент собранного аналитического отчетаЧтобы развернуть приложение на свободной облачной платформе Streamlit, достаточно кликнуть на Deploy this app в правой верхней части панели запущенного приложения, как изображено на рисунке. Однако предварительно необходимо зарегистрироваться на Streamlit и отправить заявку на допуск к ресурсам (обычно обработка заявки занимает несколько дней).

После успешного развертывания на платформе приложение будет доступно конечному пользователю по ссылке, как в данном случае.
Заключение
Из руководства вы узнали:
- что собой представляет система компьютерной вёрстки LaTeX, где найти ее дистрибутивы и пакеты, как правильно читать документацию, как начать работать с системой;
- как разрабатывать гибкие, масштабируемые шаблоны документов с помощью языка разметки TeX/LaTeX;
- как использовать приемы разработки приложений с помощью Python-библиотеки Streamlit;
- как может выглядеть пример связки «LaTeX + Streamlit»;
- и, наконец, как развернуть приложение на облачной платформе Streamlit.
Полезные источники:
- Github-репозиторий с кодом рассмотренного примера
- Облачная реализация рассмотренного приложения с помощью платформы Streamlit
Связные материалы с платформы Proglib:
Комментарии